1
0
Fork 0

media updates for v4.3-rc1

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJV6ifEAAoJEAhfPr2O5OEVn5kP/i2jM1tWcmV/ZEBKGAN0jpRk
 5Y/Q+rnXvOpIJSQC3dEkweoBymVMclSgSB/wFSWCZtp5MaB8KrH4/2uc3UvolF91
 7bqXt+fCUacMbDQyaabMCR83mz9tdOJLd5sf0ABqBgXGfwh5uXmBPaYBzmcYvKcW
 4D89MFUpaFDPARTs9rdpVyr0aPRU4GcN0R3snRO9Ly+cQnyV/RxPf9NqCgnI+yPq
 +NvA9ScUBcBt62piSIGR4egcAR8boxYC+0r57340S21/JVMvsHQ3ok9b1aT8/rtd
 Yl24FkcKrRV0ShN5S1RmW5DLH/HRGabuMjkiEz9xq52FGD2sQQda0At58dWivsa4
 XYdxS9UUfb9Z+qyeMdmCl1MUFRrV2G4H6VItP+GKyT3UZLEDcLl6hBg3SkyWxWB4
 CSO5WuRThiIB86OVcIaREftzqDy5HdvH3ZKRD7QrW0DItGVjQwV5j6gvwqO9OEXs
 99BnSohyKwUBonumE2ZtFGGhIwIomllrMSqg991bPH9+13bg/rPxUqntkPrVap/9
 cV3qKO8ZFrz5UInBnR1U83l60ZK7rV4G6AVMSMKpM9XVK9TDKryAUN9Mhj5XWRH8
 hbma89TQVdhdrITtt27uzj8F622cvZvxd1BqDBR8DjKVvtv/E2GPzJrAj7GHe3/o
 NgzP5fF6X2Si32GNb7J8
 =cIed
 -----END PGP SIGNATURE-----

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

Pull media updates from Mauro Carvalho Chehab:
 - new DVB frontend drivers: ascot2e, cxd2841er, horus3a, lnbh25
 - new HDMI capture driver: tc358743
 - new driver for NetUP DVB new boards (netup_unidvb)
 - IR support for DVBSky cards (smipcie-ir)
 - Coda driver has gain macroblock tiling support
 - Renesas R-Car gains JPEG codec driver
 - new DVB platform driver for STi boards: c8sectpfe
 - added documentation for the media core kABI to device-drivers DocBook
 - lots of driver fixups, cleanups and improvements

* tag 'media/v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (297 commits)
  [media] c8sectpfe: Remove select on undefined LIBELF_32
  [media] i2c: fix platform_no_drv_owner.cocci warnings
  [media] cx231xx: Use wake_up_interruptible() instead of wake_up_interruptible_nr()
  [media] tc358743: only queue subdev notifications if devnode is set
  [media] tc358743: add missing Kconfig dependency/select
  [media] c8sectpfe: Use %pad to print 'dma_addr_t'
  [media] DocBook media: Fix typo "the the" in xml files
  [media] tc358743: make reset gpio optional
  [media] tc358743: set direction of reset gpio using devm_gpiod_get
  [media] dvbdev: document most of the functions/data structs
  [media] dvb_frontend.h: document the struct dvb_frontend
  [media] dvb-frontend.h: document struct dtv_frontend_properties
  [media] dvb-frontend.h: document struct dvb_frontend_ops
  [media] dvb: Use DVBFE_ALGO_HW where applicable
  [media] dvb_frontend.h: document struct analog_demod_ops
  [media] dvb_frontend.h: Document struct dvb_tuner_ops
  [media] Docbook: Document struct analog_parameters
  [media] dvb_frontend.h: get rid of dvbfe_modcod
  [media] add documentation for struct dvb_tuner_info
  [media] dvb_frontend: document dvb_frontend_tune_settings
  ...
hifive-unleashed-5.1
Linus Torvalds 2015-09-05 18:21:14 -07:00
commit 9cfcc658da
277 changed files with 18659 additions and 4356 deletions

View File

@ -217,6 +217,40 @@ X!Isound/sound_firmware.c
-->
</chapter>
<chapter id="mediadev">
<title>Media Devices</title>
<sect1><title>Video2Linux devices</title>
!Iinclude/media/v4l2-async.h
!Iinclude/media/v4l2-ctrls.h
!Iinclude/media/v4l2-dv-timings.h
!Iinclude/media/v4l2-event.h
!Iinclude/media/v4l2-flash-led-class.h
!Iinclude/media/v4l2-mediabus.h
!Iinclude/media/v4l2-mem2mem.h
!Iinclude/media/v4l2-of.h
!Iinclude/media/v4l2-subdev.h
!Iinclude/media/videobuf2-core.h
!Iinclude/media/videobuf2-memops.h
</sect1>
<sect1><title>Digital TV (DVB) devices</title>
!Idrivers/media/dvb-core/dvb_ca_en50221.h
!Idrivers/media/dvb-core/dvb_frontend.h
!Idrivers/media/dvb-core/dvb_math.h
!Idrivers/media/dvb-core/dvb_ringbuffer.h
!Idrivers/media/dvb-core/dvbdev.h
</sect1>
<sect1><title>Remote Controller devices</title>
!Iinclude/media/rc-core.h
</sect1>
<sect1><title>Media Controller devices</title>
!Iinclude/media/media-device.h
!Iinclude/media/media-devnode.h
!Iinclude/media/media-entity.h
</sect1>
</chapter>
<chapter id="uart16x50">
<title>16x50 UART Driver</title>
!Edrivers/tty/serial/serial_core.c

View File

@ -199,7 +199,8 @@ DVB_DOCUMENTED = \
#
install_media_images = \
$(Q)-cp $(OBJIMGFILES) $(MEDIA_SRC_DIR)/*.svg $(MEDIA_SRC_DIR)/v4l/*.svg $(MEDIA_OBJ_DIR)/media_api
$(Q)-mkdir $(MEDIA_OBJ_DIR)/media_api; \
cp $(OBJIMGFILES) $(MEDIA_SRC_DIR)/*.svg $(MEDIA_SRC_DIR)/v4l/*.svg $(MEDIA_OBJ_DIR)/media_api
$(MEDIA_OBJ_DIR)/%: $(MEDIA_SRC_DIR)/%.b64
$(Q)base64 -d $< >$@

View File

@ -163,9 +163,8 @@ are called:</para>
<para>where N enumerates the DVB PCI cards in a system starting
from&#x00A0;0, and M enumerates the devices of each type within each
adapter, starting from&#x00A0;0, too. We will omit the &#8220;
<constant>/dev/dvb/adapterN/</constant>&#8221; in the further dicussion
of these devices. The naming scheme for the devices is the same wheter
devfs is used or not.</para>
<constant>/dev/dvb/adapterN/</constant>&#8221; in the further discussion
of these devices.</para>
<para>More details about the data structures and function calls of all
the devices are described in the following chapters.</para>

View File

@ -3414,7 +3414,7 @@ giving priority to the center of the metered area.</entry>
<row>
<entry><constant>V4L2_EXPOSURE_METERING_MATRIX</constant>&nbsp;</entry>
<entry>A multi-zone metering. The light intensity is measured
in several points of the frame and the the results are combined. The
in several points of the frame and the results are combined. The
algorithm of the zones selection and their significance in calculating the
final value is device dependent.</entry>
</row>

View File

@ -102,7 +102,7 @@
</row>
<row>
<entry>__u32</entry>
<entry><structfield>media_version</structfield></entry>
<entry><structfield>driver_version</structfield></entry>
<entry>Media device driver version, formatted with the
<constant>KERNEL_VERSION()</constant> macro. Together with the
<structfield>driver</structfield> field this identifies a particular

View File

@ -62,28 +62,28 @@ buffer as a DMABUF file at any time after buffers have been allocated with the
&VIDIOC-REQBUFS; ioctl.</para>
<para> To export a buffer, applications fill &v4l2-exportbuffer;. The
<structfield> type </structfield> field is set to the same buffer type as was
previously used with &v4l2-requestbuffers;<structfield> type </structfield>.
Applications must also set the <structfield> index </structfield> field. Valid
<structfield>type</structfield> field is set to the same buffer type as was
previously used with &v4l2-requestbuffers; <structfield>type</structfield>.
Applications must also set the <structfield>index</structfield> field. Valid
index numbers range from zero to the number of buffers allocated with
&VIDIOC-REQBUFS; (&v4l2-requestbuffers;<structfield> count </structfield>)
minus one. For the multi-planar API, applications set the <structfield> plane
</structfield> field to the index of the plane to be exported. Valid planes
&VIDIOC-REQBUFS; (&v4l2-requestbuffers; <structfield>count</structfield>)
minus one. For the multi-planar API, applications set the <structfield>plane</structfield>
field to the index of the plane to be exported. Valid planes
range from zero to the maximal number of valid planes for the currently active
format. For the single-planar API, applications must set <structfield> plane
</structfield> to zero. Additional flags may be posted in the <structfield>
flags </structfield> field. Refer to a manual for open() for details.
format. For the single-planar API, applications must set <structfield>plane</structfield>
to zero. Additional flags may be posted in the <structfield>flags</structfield>
field. Refer to a manual for open() for details.
Currently only O_CLOEXEC, O_RDONLY, O_WRONLY, and O_RDWR are supported. All
other fields must be set to zero.
In the case of multi-planar API, every plane is exported separately using
multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
multiple <constant>VIDIOC_EXPBUF</constant> calls.</para>
<para> After calling <constant>VIDIOC_EXPBUF</constant> the <structfield> fd
</structfield> field will be set by a driver. This is a DMABUF file
<para>After calling <constant>VIDIOC_EXPBUF</constant> the <structfield>fd</structfield>
field will be set by a driver. This is a DMABUF file
descriptor. The application may pass it to other DMABUF-aware devices. Refer to
<link linkend="dmabuf">DMABUF importing</link> for details about importing
DMABUF files into V4L2 nodes. It is recommended to close a DMABUF file when it
is no longer used to allow the associated memory to be reclaimed. </para>
is no longer used to allow the associated memory to be reclaimed.</para>
</refsect1>
<refsect1>
@ -170,9 +170,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>Flags for the newly created file, currently only <constant>
O_CLOEXEC </constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY
</constant>, and <constant>O_RDWR</constant> are supported, refer to the manual
<entry>Flags for the newly created file, currently only
<constant>O_CLOEXEC</constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY</constant>,
and <constant>O_RDWR</constant> are supported, refer to the manual
of open() for more details.</entry>
</row>
<row>
@ -200,9 +200,9 @@ set the array to zero.</entry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>A queue is not in MMAP mode or DMABUF exporting is not
supported or <structfield> flags </structfield> or <structfield> type
</structfield> or <structfield> index </structfield> or <structfield> plane
</structfield> fields are invalid.</para>
supported or <structfield>flags</structfield> or <structfield>type</structfield>
or <structfield>index</structfield> or <structfield>plane</structfield> fields
are invalid.</para>
</listitem>
</varlistentry>
</variablelist>

View File

@ -267,7 +267,7 @@ is intended for still imaging applications. The idea is to get the
best possible image quality that the hardware can deliver. It is not
defined how the driver writer may achieve that; it will depend on the
hardware and the ingenuity of the driver writer. High quality mode is
a different mode from the the regular motion video capture modes. In
a different mode from the regular motion video capture modes. In
high quality mode:<itemizedlist>
<listitem>
<para>The driver may be able to capture higher

View File

@ -616,7 +616,7 @@ pointer to memory containing the payload of the control.</entry>
<entry><constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant></entry>
<entry>0x0200</entry>
<entry>The value provided to the control will be propagated to the driver
even if remains constant. This is required when the control represents an action
even if it remains constant. This is required when the control represents an action
on the hardware. For example: clearing an error flag or triggering the flash. All the
controls of the type <constant>V4L2_CTRL_TYPE_BUTTON</constant> have this flag set.</entry>
</row>

View File

@ -1,15 +1,17 @@
* Analog Devices ADV7604/11 video decoder with HDMI receiver
* Analog Devices ADV7604/11/12 video decoder with HDMI receiver
The ADV7604 and ADV7611 are multiformat video decoders with an integrated HDMI
receiver. The ADV7604 has four multiplexed HDMI inputs and one analog input,
and the ADV7611 has one HDMI input and no analog input.
The ADV7604 and ADV7611/12 are multiformat video decoders with an integrated
HDMI receiver. The ADV7604 has four multiplexed HDMI inputs and one analog
input, and the ADV7611 has one HDMI input and no analog input. The 7612 is
similar to the 7611 but has 2 HDMI inputs.
These device tree bindings support the ADV7611 only at the moment.
These device tree bindings support the ADV7611/12 only at the moment.
Required Properties:
- compatible: Must contain one of the following
- "adi,adv7611" for the ADV7611
- "adi,adv7612" for the ADV7612
- reg: I2C slave address
@ -22,10 +24,10 @@ port, in accordance with the video interface bindings defined in
Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes
are numbered as follows.
Port ADV7611
Port ADV7611 ADV7612
------------------------------------------------------------
HDMI 0
Digital output 1
HDMI 0 0, 1
Digital output 1 2
The digital output port node must contain at least one endpoint.
@ -45,6 +47,7 @@ Optional Endpoint Properties:
If none of hsync-active, vsync-active and pclk-sample is specified the
endpoint will use embedded BT.656 synchronization.
- default-input: Select which input is selected after reset.
Example:
@ -58,6 +61,8 @@ Example:
#address-cells = <1>;
#size-cells = <0>;
default-input = <0>;
port@0 {
reg = <0>;
};

View File

@ -0,0 +1,48 @@
* Toshiba TC358743 HDMI-RX to MIPI CSI2-TX Bridge
The Toshiba TC358743 HDMI-RX to MIPI CSI2-TX (H2C) is a bridge that converts
a HDMI stream to MIPI CSI-2 TX. It is programmable through I2C.
Required Properties:
- compatible: value should be "toshiba,tc358743"
- clocks, clock-names: should contain a phandle link to the reference clock
source, the clock input is named "refclk".
Optional Properties:
- reset-gpios: gpio phandle GPIO connected to the reset pin
- interrupts, interrupt-parent: GPIO connected to the interrupt pin
- data-lanes: should be <1 2 3 4> for four-lane operation,
or <1 2> for two-lane operation
- clock-lanes: should be <0>
- clock-noncontinuous: Presence of this boolean property decides whether the
MIPI CSI-2 clock is continuous or non-continuous.
- link-frequencies: List of allowed link frequencies in Hz. Each frequency is
expressed as a 64-bit big-endian integer. The frequency
is half of the bps per lane due to DDR transmission.
For further information on the MIPI CSI-2 endpoint node properties, see
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
tc358743@0f {
compatible = "toshiba,tc358743";
reg = <0x0f>;
clocks = <&hdmi_osc>;
clock-names = "refclk";
reset-gpios = <&gpio6 9 GPIO_ACTIVE_LOW>;
interrupt-parent = <&gpio2>;
interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
port {
tc358743_out: endpoint {
remote-endpoint = <&mipi_csi2_in>;
data-lanes = <1 2 3 4>;
clock-lanes = <0>;
clock-noncontinuous;
link-frequencies = /bits/ 64 <297000000>;
};
};
};

View File

@ -0,0 +1,24 @@
* Renesas JPEG Processing Unit
The JPEG processing unit (JPU) incorporates the JPEG codec with an encoding
and decoding function conforming to the JPEG baseline process, so that the JPU
can encode image data and decode JPEG data quickly.
Required properties:
- compatible: should containg one of the following:
- "renesas,jpu-r8a7790" for R-Car H2
- "renesas,jpu-r8a7791" for R-Car M2-W
- "renesas,jpu-r8a7792" for R-Car V2H
- "renesas,jpu-r8a7793" for R-Car M2-N
- reg: Base address and length of the registers block for the JPU.
- interrupts: JPU interrupt specifier.
- clocks: A phandle + clock-specifier pair for the JPU functional clock.
Example: R8A7790 (R-Car H2) JPU node
jpeg-codec@fe980000 {
compatible = "renesas,jpu-r8a7790";
reg = <0 0xfe980000 0 0x10300>;
interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7790_CLK_JPU>;
};

View File

@ -0,0 +1,89 @@
STMicroelectronics STi c8sectpfe binding
============================================
This document describes the c8sectpfe device bindings that is used to get transport
stream data into the SoC on the TS pins, and into DDR for further processing.
It is typically used in conjunction with one or more demodulator and tuner devices
which converts from the RF to digital domain. Demodulators and tuners are usually
located on an external DVB frontend card connected to SoC TS input pins.
Currently 7 TS input (tsin) channels are supported on the stih407 family SoC.
Required properties (controller (parent) node):
- compatible : Should be "stih407-c8sectpfe"
- reg : Address and length of register sets for each device in
"reg-names"
- reg-names : The names of the register addresses corresponding to the
registers filled in "reg":
- c8sectpfe: c8sectpfe registers
- c8sectpfe-ram: c8sectpfe internal sram
- clocks : phandle list of c8sectpfe clocks
- clock-names : should be "c8sectpfe"
See: Documentation/devicetree/bindings/clock/clock-bindings.txt
- pinctrl-names : a pinctrl state named tsin%d-serial or tsin%d-parallel (where %d is tsin-num)
must be defined for each tsin child node.
- pinctrl-0 : phandle referencing pin configuration for this tsin configuration
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
Required properties (tsin (child) node):
- tsin-num : tsin id of the InputBlock (must be between 0 to 6)
- i2c-bus : phandle to the I2C bus DT node which the demodulators & tuners on this tsin channel are connected.
- rst-gpio : reset gpio for this tsin channel.
Optional properties (tsin (child) node):
- invert-ts-clk : Bool property to control sense of ts input clock (data stored on falling edge of clk).
- serial-not-parallel : Bool property to configure input bus width (serial on ts_data<7>).
- async-not-sync : Bool property to control if data is received in asynchronous mode
(all bits/bytes with ts_valid or ts_packet asserted are valid).
- dvb-card : Describes the NIM card connected to this tsin channel.
Example:
/* stih410 SoC b2120 + b2004a + stv0367-pll(NIMB) + stv0367-tda18212 (NIMA) DT example) */
c8sectpfe@08a20000 {
compatible = "st,stih407-c8sectpfe";
status = "okay";
reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
reg-names = "stfe", "stfe-ram";
interrupts = <0 34 0>, <0 35 0>;
interrupt-names = "stfe-error-irq", "stfe-idle-irq";
pinctrl-names = "tsin0-serial", "tsin0-parallel", "tsin3-serial",
"tsin4-serial", "tsin5-serial";
pinctrl-0 = <&pinctrl_tsin0_serial>;
pinctrl-1 = <&pinctrl_tsin0_parallel>;
pinctrl-2 = <&pinctrl_tsin3_serial>;
pinctrl-3 = <&pinctrl_tsin4_serial_alt3>;
pinctrl-4 = <&pinctrl_tsin5_serial_alt1>;
clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
clock-names = "stfe";
/* tsin0 is TSA on NIMA */
tsin0: port@0 {
tsin-num = <0>;
serial-not-parallel;
i2c-bus = <&ssc2>;
rst-gpio = <&pio15 4 0>;
dvb-card = <STV0367_TDA18212_NIMA_1>;
};
tsin3: port@3 {
tsin-num = <3>;
serial-not-parallel;
i2c-bus = <&ssc3>;
rst-gpio = <&pio15 7 0>;
dvb-card = <STV0367_TDA18212_NIMB_1>;
};
};

View File

@ -1525,6 +1525,7 @@ F: drivers/clocksource/arm_global_timer.c
F: drivers/clocksource/clksrc_st_lpc.c
F: drivers/i2c/busses/i2c-st.c
F: drivers/media/rc/st_rc.c
F: drivers/media/platform/sti/c8sectpfe/
F: drivers/mmc/host/sdhci-st.c
F: drivers/phy/phy-miphy28lp.c
F: drivers/phy/phy-miphy365x.c
@ -5819,6 +5820,12 @@ S: Maintained
F: fs/jbd2/
F: include/linux/jbd2.h
JPU V4L2 MEM2MEM DRIVER FOR RENESAS
M: Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/rcar_jpu.c
JSM Neo PCI based serial card
M: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
L: linux-serial@vger.kernel.org
@ -6662,6 +6669,51 @@ S: Supported
F: Documentation/devicetree/bindings/media/renesas,vsp1.txt
F: drivers/media/platform/vsp1/
MEDIA DRIVERS FOR ASCOT2E
M: Sergey Kozlov <serjk@netup.ru>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
F: drivers/media/dvb-frontends/ascot2e*
MEDIA DRIVERS FOR CXD2841ER
M: Sergey Kozlov <serjk@netup.ru>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
F: drivers/media/dvb-frontends/cxd2841er*
MEDIA DRIVERS FOR HORUS3A
M: Sergey Kozlov <serjk@netup.ru>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
F: drivers/media/dvb-frontends/horus3a*
MEDIA DRIVERS FOR LNBH25
M: Sergey Kozlov <serjk@netup.ru>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
F: drivers/media/dvb-frontends/lnbh25*
MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
M: Sergey Kozlov <serjk@netup.ru>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
F: drivers/media/pci/netup_unidvb/*
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
M: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
P: LinuxTV.org Project
@ -10428,6 +10480,13 @@ F: drivers/char/toshiba.c
F: include/linux/toshiba.h
F: include/uapi/linux/toshiba.h
TOSHIBA TC358743 DRIVER
M: Mats Randgaard <matrandg@cisco.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/tc358743*
F: include/media/tc358743.h
TMIO MMC DRIVER
M: Ian Molton <ian@mnementh.co.uk>
L: linux-mmc@vger.kernel.org

View File

@ -343,7 +343,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_DEV_ID("sh-vou", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU0]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]),

View File

@ -307,7 +307,7 @@ static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field
/* simple bubble-sort algorithm with duplicate elimination */
static int sort_and_eliminate(u32* values, int* count)
{
int low = 0, high = 0, top = 0, temp = 0;
int low = 0, high = 0, top = 0;
int cur = 0, next = 0;
/* sanity checks */
@ -318,11 +318,8 @@ static int sort_and_eliminate(u32* values, int* count)
/* bubble sort the first @count items of the array @values */
for( top = *count; top > 0; top--) {
for( low = 0, high = 1; high < top; low++, high++) {
if( values[low] > values[high] ) {
temp = values[low];
values[low] = values[high];
values[high] = temp;
}
if( values[low] > values[high] )
swap(values[low], values[high]);
}
}

View File

@ -169,10 +169,10 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * e
/**
* Safely find needle in haystack.
*
* @param haystack Buffer to look in.
* @param hlen Number of bytes in haystack.
* @param needle Buffer to find.
* @param nlen Number of bytes in needle.
* @haystack: Buffer to look in.
* @hlen: Number of bytes in haystack.
* @needle: Buffer to find.
* @nlen: Number of bytes in needle.
* @return Pointer into haystack needle was found at, or NULL if not found.
*/
static char *findstr(char * haystack, int hlen, char * needle, int nlen)
@ -197,7 +197,7 @@ static char *findstr(char * haystack, int hlen, char * needle, int nlen)
/**
* Check CAM status.
* dvb_ca_en50221_check_camstatus - Check CAM status.
*/
static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
{
@ -240,13 +240,13 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
/**
* Wait for flags to become set on the STATUS register on a CAM interface,
* checking for errors and timeout.
* dvb_ca_en50221_wait_if_status - Wait for flags to become set on the STATUS
* register on a CAM interface, checking for errors and timeout.
*
* @param ca CA instance.
* @param slot Slot on interface.
* @param waitfor Flags to wait for.
* @param timeout_ms Timeout in milliseconds.
* @ca: CA instance.
* @slot: Slot on interface.
* @waitfor: Flags to wait for.
* @timeout_ms: Timeout in milliseconds.
*
* @return 0 on success, nonzero on error.
*/
@ -290,10 +290,10 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
/**
* Initialise the link layer connection to a CAM.
* dvb_ca_en50221_link_init - Initialise the link layer connection to a CAM.
*
* @param ca CA instance.
* @param slot Slot id.
* @ca: CA instance.
* @slot: Slot id.
*
* @return 0 on success, nonzero on failure.
*/
@ -346,14 +346,14 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
}
/**
* Read a tuple from attribute memory.
* dvb_ca_en50221_read_tuple - Read a tuple from attribute memory.
*
* @param ca CA instance.
* @param slot Slot id.
* @param address Address to read from. Updated.
* @param tupleType Tuple id byte. Updated.
* @param tupleLength Tuple length. Updated.
* @param tuple Dest buffer for tuple (must be 256 bytes). Updated.
* @ca: CA instance.
* @slot: Slot id.
* @address: Address to read from. Updated.
* @tupleType: Tuple id byte. Updated.
* @tupleLength: Tuple length. Updated.
* @tuple: Dest buffer for tuple (must be 256 bytes). Updated.
*
* @return 0 on success, nonzero on error.
*/
@ -399,11 +399,11 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
/**
* Parse attribute memory of a CAM module, extracting Config register, and checking
* it is a DVB CAM module.
* dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module,
* extracting Config register, and checking it is a DVB CAM module.
*
* @param ca CA instance.
* @param slot Slot id.
* @ca: CA instance.
* @slot: Slot id.
*
* @return 0 on success, <0 on failure.
*/
@ -546,10 +546,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
/**
* Set CAM's configoption correctly.
* dvb_ca_en50221_set_configoption - Set CAM's configoption correctly.
*
* @param ca CA instance.
* @param slot Slot containing the CAM.
* @ca: CA instance.
* @slot: Slot containing the CAM.
*/
static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
{
@ -574,15 +574,16 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
/**
* This function talks to an EN50221 CAM control interface. It reads a buffer of
* data from the CAM. The data can either be stored in a supplied buffer, or
* automatically be added to the slot's rx_buffer.
* dvb_ca_en50221_read_data - This function talks to an EN50221 CAM control
* interface. It reads a buffer of data from the CAM. The data can either
* be stored in a supplied buffer, or automatically be added to the slot's
* rx_buffer.
*
* @param ca CA instance.
* @param slot Slot to read from.
* @param ebuf If non-NULL, the data will be written to this buffer. If NULL,
* @ca: CA instance.
* @slot: Slot to read from.
* @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
* the data will be added into the buffering system as a normal fragment.
* @param ecount Size of ebuf. Ignored if ebuf is NULL.
* @ecount: Size of ebuf. Ignored if ebuf is NULL.
*
* @return Number of bytes read, or < 0 on error
*/
@ -698,14 +699,14 @@ exit:
/**
* This function talks to an EN50221 CAM control interface. It writes a buffer of data
* to a CAM.
* dvb_ca_en50221_write_data - This function talks to an EN50221 CAM control
* interface. It writes a buffer of data to a CAM.
*
* @param ca CA instance.
* @param slot Slot to write to.
* @param ebuf The data in this buffer is treated as a complete link-level packet to
* @ca: CA instance.
* @slot: Slot to write to.
* @ebuf: The data in this buffer is treated as a complete link-level packet to
* be written.
* @param count Size of ebuf.
* @count: Size of ebuf.
*
* @return Number of bytes written, or < 0 on error.
*/
@ -790,10 +791,10 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
/**
* A CAM has been removed => shut it down.
* dvb_ca_en50221_camready_irq - A CAM has been removed => shut it down.
*
* @param ca CA instance.
* @param slot Slot to shut down.
* @ca: CA instance.
* @slot: Slot to shut down.
*/
static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
{
@ -815,11 +816,11 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
/**
* A CAMCHANGE IRQ has occurred.
* dvb_ca_en50221_camready_irq - A CAMCHANGE IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @param change_type One of the DVB_CA_CAMCHANGE_* values.
* @ca: CA instance.
* @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values.
*/
void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
{
@ -844,10 +845,10 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
/**
* A CAMREADY IRQ has occurred.
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @ca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
{
@ -865,8 +866,8 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
/**
* An FR or DA IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @ca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
{
@ -899,7 +900,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
/**
* Wake up the DVB CA thread
*
* @param ca CA instance.
* @ca: CA instance.
*/
static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
{
@ -914,7 +915,7 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
/**
* Update the delay used by the thread.
*
* @param ca CA instance.
* @ca: CA instance.
*/
static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
{
@ -1177,10 +1178,10 @@ static int dvb_ca_en50221_thread(void *data)
* Real ioctl implementation.
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
*
* @param inode Inode concerned.
* @param file File concerned.
* @param cmd IOCTL command.
* @param arg Associated argument.
* @inode: Inode concerned.
* @file: File concerned.
* @cmd: IOCTL command.
* @arg: Associated argument.
*
* @return 0 on success, <0 on error.
*/
@ -1258,10 +1259,10 @@ out_unlock:
/**
* Wrapper for ioctl implementation.
*
* @param inode Inode concerned.
* @param file File concerned.
* @param cmd IOCTL command.
* @param arg Associated argument.
* @inode: Inode concerned.
* @file: File concerned.
* @cmd: IOCTL command.
* @arg: Associated argument.
*
* @return 0 on success, <0 on error.
*/
@ -1275,10 +1276,10 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
/**
* Implementation of write() syscall.
*
* @param file File structure.
* @param buf Source buffer.
* @param count Size of source buffer.
* @param ppos Position in file (ignored).
* @file: File structure.
* @buf: Source buffer.
* @count: Size of source buffer.
* @ppos: Position in file (ignored).
*
* @return Number of bytes read, or <0 on error.
*/
@ -1416,10 +1417,10 @@ nextslot:
/**
* Implementation of read() syscall.
*
* @param file File structure.
* @param buf Destination buffer.
* @param count Size of destination buffer.
* @param ppos Position in file (ignored).
* @file: File structure.
* @buf: Destination buffer.
* @count: Size of destination buffer.
* @ppos: Position in file (ignored).
*
* @return Number of bytes read, or <0 on error.
*/
@ -1519,8 +1520,8 @@ exit:
/**
* Implementation of file open syscall.
*
* @param inode Inode concerned.
* @param file File concerned.
* @inode: Inode concerned.
* @file: File concerned.
*
* @return 0 on success, <0 on failure.
*/
@ -1564,8 +1565,8 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
/**
* Implementation of file close syscall.
*
* @param inode Inode concerned.
* @param file File concerned.
* @inode: Inode concerned.
* @file: File concerned.
*
* @return 0 on success, <0 on failure.
*/
@ -1592,8 +1593,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
/**
* Implementation of poll() syscall.
*
* @param file File concerned.
* @param wait poll wait table.
* @file: File concerned.
* @wait: poll wait table.
*
* @return Standard poll mask.
*/
@ -1656,10 +1657,10 @@ static const struct dvb_device dvbdev_ca = {
/**
* Initialise a new DVB CA EN50221 interface device.
*
* @param dvb_adapter DVB adapter to attach the new CA device to.
* @param ca The dvb_ca instance.
* @param flags Flags describing the CA device (DVB_CA_FLAG_*).
* @param slot_count Number of slots supported.
* @dvb_adapter: DVB adapter to attach the new CA device to.
* @ca: The dvb_ca instance.
* @flags: Flags describing the CA device (DVB_CA_FLAG_*).
* @slot_count: Number of slots supported.
*
* @return 0 on success, nonzero on failure
*/
@ -1743,8 +1744,8 @@ EXPORT_SYMBOL(dvb_ca_en50221_release);
/**
* Release a DVB CA EN50221 interface device.
*
* @param ca_dev The dvb_device_t instance for the CA device.
* @param ca The associated dvb_ca instance.
* @ca_dev: The dvb_device_t instance for the CA device.
* @ca: The associated dvb_ca instance.
*/
void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
{

View File

@ -83,27 +83,27 @@ struct dvb_ca_en50221 {
/* Functions for reporting IRQ events */
/**
* A CAMCHANGE IRQ has occurred.
* dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @param change_type One of the DVB_CA_CAMCHANGE_* values
* @pubca: CA instance.
* @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values
*/
void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
/**
* A CAMREADY IRQ has occurred.
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @pubca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
/**
* An FR or a DA IRQ has occurred.
* dvb_ca_en50221_frda_irq - An FR or a DA IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @ca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
@ -113,21 +113,21 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
/* Initialisation/shutdown functions */
/**
* Initialise a new DVB CA device.
* dvb_ca_en50221_init - Initialise a new DVB CA device.
*
* @param dvb_adapter DVB adapter to attach the new CA device to.
* @param ca The dvb_ca instance.
* @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
* @param slot_count Number of slots supported.
* @dvb_adapter: DVB adapter to attach the new CA device to.
* @ca: The dvb_ca instance.
* @flags: Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
* @slot_count: Number of slots supported.
*
* @return 0 on success, nonzero on failure
*/
extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
/**
* Release a DVB CA device.
* dvb_ca_en50221_release - Release a DVB CA device.
*
* @param ca The associated dvb_ca instance.
* @ca: The associated dvb_ca instance.
*/
extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);

View File

@ -81,7 +81,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
#define FE_ALGO_HW 1
/*
* FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
* FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.

View File

@ -48,6 +48,15 @@
*/
#define MAX_DELSYS 8
/**
* struct dvb_frontend_tune_settings - parameters to adjust frontend tuning
*
* @min_delay_ms: minimum delay for tuning, in ms
* @step_size: step size between two consecutive frequencies
* @max_drift: maximum drift
*
* NOTE: step_size is in Hz, for terrestrial/cable or kHz for satellite
*/
struct dvb_frontend_tune_settings {
int min_delay_ms;
int step_size;
@ -56,6 +65,20 @@ struct dvb_frontend_tune_settings {
struct dvb_frontend;
/**
* struct dvb_tuner_info - Frontend name and min/max ranges/bandwidths
*
* @name: name of the Frontend
* @frequency_min: minimal frequency supported
* @frequency_max: maximum frequency supported
* @frequency_step: frequency step
* @bandwidth_min: minimal frontend bandwidth supported
* @bandwidth_max: maximum frontend bandwidth supported
* @bandwidth_step: frontend bandwidth step
*
* NOTE: frequency parameters are in Hz, for terrestrial/cable or kHz for
* satellite.
*/
struct dvb_tuner_info {
char name[128];
@ -68,6 +91,20 @@ struct dvb_tuner_info {
u32 bandwidth_step;
};
/**
* struct analog_parameters - Parameters to tune into an analog/radio channel
*
* @frequency: Frequency used by analog TV tuner (either in 62.5 kHz step,
* for TV, or 62.5 Hz for radio)
* @mode: Tuner mode, as defined on enum v4l2_tuner_type
* @audmode: Audio mode as defined for the rxsubchans field at videodev2.h,
* e. g. V4L2_TUNER_MODE_*
* @std: TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_*
*
* Hybrid tuners should be supported by both V4L2 and DVB APIs. This
* struct contains the data that are used by the V4L2 side. To avoid
* dependencies from V4L2 headers, all enums here are declared as integers.
*/
struct analog_parameters {
unsigned int frequency;
unsigned int mode;
@ -75,42 +112,6 @@ struct analog_parameters {
u64 std;
};
enum dvbfe_modcod {
DVBFE_MODCOD_DUMMY_PLFRAME = 0,
DVBFE_MODCOD_QPSK_1_4,
DVBFE_MODCOD_QPSK_1_3,
DVBFE_MODCOD_QPSK_2_5,
DVBFE_MODCOD_QPSK_1_2,
DVBFE_MODCOD_QPSK_3_5,
DVBFE_MODCOD_QPSK_2_3,
DVBFE_MODCOD_QPSK_3_4,
DVBFE_MODCOD_QPSK_4_5,
DVBFE_MODCOD_QPSK_5_6,
DVBFE_MODCOD_QPSK_8_9,
DVBFE_MODCOD_QPSK_9_10,
DVBFE_MODCOD_8PSK_3_5,
DVBFE_MODCOD_8PSK_2_3,
DVBFE_MODCOD_8PSK_3_4,
DVBFE_MODCOD_8PSK_5_6,
DVBFE_MODCOD_8PSK_8_9,
DVBFE_MODCOD_8PSK_9_10,
DVBFE_MODCOD_16APSK_2_3,
DVBFE_MODCOD_16APSK_3_4,
DVBFE_MODCOD_16APSK_4_5,
DVBFE_MODCOD_16APSK_5_6,
DVBFE_MODCOD_16APSK_8_9,
DVBFE_MODCOD_16APSK_9_10,
DVBFE_MODCOD_32APSK_3_4,
DVBFE_MODCOD_32APSK_4_5,
DVBFE_MODCOD_32APSK_5_6,
DVBFE_MODCOD_32APSK_8_9,
DVBFE_MODCOD_32APSK_9_10,
DVBFE_MODCOD_RESERVED_1,
DVBFE_MODCOD_BPSK_1_3,
DVBFE_MODCOD_BPSK_1_4,
DVBFE_MODCOD_RESERVED_2
};
enum tuner_param {
DVBFE_TUNER_FREQUENCY = (1 << 0),
DVBFE_TUNER_TUNERSTEP = (1 << 1),
@ -121,30 +122,28 @@ enum tuner_param {
DVBFE_TUNER_DUMMY = (1 << 31)
};
/*
* ALGO_HW: (Hardware Algorithm)
* ----------------------------------------------------------------
* Devices that support this algorithm do everything in hardware
* and no software support is needed to handle them.
* Requesting these devices to LOCK is the only thing required,
* device is supposed to do everything in the hardware.
/**
* enum dvbfe_algo - defines the algorithm used to tune into a channel
*
* ALGO_SW: (Software Algorithm)
* ----------------------------------------------------------------
* @DVBFE_ALGO_HW: Hardware Algorithm -
* Devices that support this algorithm do everything in hardware
* and no software support is needed to handle them.
* Requesting these devices to LOCK is the only thing required,
* device is supposed to do everything in the hardware.
*
* @DVBFE_ALGO_SW: Software Algorithm -
* These are dumb devices, that require software to do everything
*
* ALGO_CUSTOM: (Customizable Agorithm)
* ----------------------------------------------------------------
* Devices having this algorithm can be customized to have specific
* algorithms in the frontend driver, rather than simply doing a
* software zig-zag. In this case the zigzag maybe hardware assisted
* or it maybe completely done in hardware. In all cases, usage of
* this algorithm, in conjunction with the search and track
* callbacks, utilizes the driver specific algorithm.
* @DVBFE_ALGO_CUSTOM: Customizable Agorithm -
* Devices having this algorithm can be customized to have specific
* algorithms in the frontend driver, rather than simply doing a
* software zig-zag. In this case the zigzag maybe hardware assisted
* or it maybe completely done in hardware. In all cases, usage of
* this algorithm, in conjunction with the search and track
* callbacks, utilizes the driver specific algorithm.
*
* ALGO_RECOVERY: (Recovery Algorithm)
* ----------------------------------------------------------------
* These devices have AUTO recovery capabilities from LOCK failure
* @DVBFE_ALGO_RECOVERY: Recovery Algorithm -
* These devices have AUTO recovery capabilities from LOCK failure
*/
enum dvbfe_algo {
DVBFE_ALGO_HW = (1 << 0),
@ -162,27 +161,27 @@ struct tuner_state {
u32 refclock;
};
/*
* search callback possible return status
/**
* enum dvbfe_search - search callback possible return status
*
* DVBFE_ALGO_SEARCH_SUCCESS
* The frontend search algorithm completed and returned successfully
* @DVBFE_ALGO_SEARCH_SUCCESS:
* The frontend search algorithm completed and returned successfully
*
* DVBFE_ALGO_SEARCH_ASLEEP
* The frontend search algorithm is sleeping
* @DVBFE_ALGO_SEARCH_ASLEEP:
* The frontend search algorithm is sleeping
*
* DVBFE_ALGO_SEARCH_FAILED
* The frontend search for a signal failed
* @DVBFE_ALGO_SEARCH_FAILED:
* The frontend search for a signal failed
*
* DVBFE_ALGO_SEARCH_INVALID
* The frontend search algorith was probably supplied with invalid
* parameters and the search is an invalid one
* @DVBFE_ALGO_SEARCH_INVALID:
* The frontend search algorith was probably supplied with invalid
* parameters and the search is an invalid one
*
* DVBFE_ALGO_SEARCH_ERROR
* The frontend search algorithm failed due to some error
* @DVBFE_ALGO_SEARCH_ERROR:
* The frontend search algorithm failed due to some error
*
* DVBFE_ALGO_SEARCH_AGAIN
* The frontend search algorithm was requested to search again
* @DVBFE_ALGO_SEARCH_AGAIN:
* The frontend search algorithm was requested to search again
*/
enum dvbfe_search {
DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
@ -193,7 +192,56 @@ enum dvbfe_search {
DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
};
/**
* struct dvb_tuner_ops - Tuner information and callbacks
*
* @info: embedded struct dvb_tuner_info with tuner properties
* @release: callback function called when frontend is dettached.
* drivers should free any allocated memory.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
* @suspend: callback function used to inform that the Kernel will
* suspend.
* @resume: callback function used to inform that the Kernel is
* resuming from suspend.
* @set_params: callback function used to inform the tuner to tune
* into a digital TV channel. The properties to be used
* are stored at @dvb_frontend.dtv_property_cache;. The
* tuner demod can change the parameters to reflect the
* changes needed for the channel to be tuned, and
* update statistics.
* @set_analog_params: callback function used to tune into an analog TV
* channel on hybrid tuners. It passes @analog_parameters;
* to the driver.
* @calc_regs: callback function used to pass register data settings
* for simple tuners.
* @set_config: callback function used to send some tuner-specific
* parameters.
* @get_frequency: get the actual tuned frequency
* @get_bandwidth: get the bandwitdh used by the low pass filters
* @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband,
* should return 0.
* @get_status: returns the frontend lock status
* @get_rf_strength: returns the RF signal strengh. Used mostly to support
* analog TV and radio. Digital TV should report, instead,
* via DVBv5 API (@dvb_frontend.dtv_property_cache;).
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @set_frequency: Set a new frequency. Please notice that using
* set_params is preferred.
* @set_bandwidth: Set a new frequency. Please notice that using
* set_params is preferred.
* @set_state: callback function used on some legacy drivers that
* don't implement set_params in order to set properties.
* Shouldn't be used on new drivers.
* @get_state: callback function used to get properties by some
* legacy drivers that don't implement set_params.
* Shouldn't be used on new drivers.
*
* NOTE: frequencies used on get_frequency and set_frequency are in Hz for
* terrestrial/cable or kHz for satellite.
*
*/
struct dvb_tuner_ops {
struct dvb_tuner_info info;
@ -237,10 +285,37 @@ struct dvb_tuner_ops {
int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
};
/**
* struct analog_demod_info - Information struct for analog TV part of the demod
*
* @name: Name of the analog TV demodulator
*/
struct analog_demod_info {
char *name;
};
/**
* struct analog_demod_ops - Demodulation information and callbacks for
* analog TV and radio
*
* @info: pointer to struct analog_demod_info
* @set_params: callback function used to inform the demod to set the
* demodulator parameters needed to decode an analog or
* radio channel. The properties are passed via
* struct @analog_params;.
* @has_signal: returns 0xffff if has signal, or 0 if it doesn't.
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @tuner_status: callback function that returns tuner status bits, e. g.
* TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO.
* @standby: set the tuner to standby mode.
* @release: callback function called when frontend is dettached.
* drivers should free any allocated memory.
* @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C
* mux support instead.
* @set_config: callback function used to send some tuner-specific
* parameters.
*/
struct analog_demod_ops {
struct analog_demod_info info;
@ -260,6 +335,87 @@ struct analog_demod_ops {
struct dtv_frontend_properties;
/**
* struct dvb_frontend_ops - Demodulation information and callbacks for
* ditialt TV
*
* @info: embedded struct dvb_tuner_info with tuner properties
* @delsys: Delivery systems supported by the frontend
* @release: callback function called when frontend is dettached.
* drivers should free any allocated memory.
* @release_sec: callback function requesting that the Satelite Equipment
* Control (SEC) driver to release and free any memory
* allocated by the driver.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
* @write: callback function used by some demod legacy drivers to
* allow other drivers to write data into their registers.
* Should not be used on new drivers.
* @tune: callback function used by demod drivers that use
* @DVBFE_ALGO_HW; to tune into a frequency.
* @get_frontend_algo: returns the desired hardware algorithm.
* @set_frontend: callback function used to inform the demod to set the
* parameters for demodulating a digital TV channel.
* The properties to be used are stored at
* @dvb_frontend.dtv_property_cache;. The demod can change
* the parameters to reflect the changes needed for the
* channel to be decoded, and update statistics.
* @get_tune_settings: callback function
* @get_frontend: callback function used to inform the parameters
* actuall in use. The properties to be used are stored at
* @dvb_frontend.dtv_property_cache; and update
* statistics. Please notice that it should not return
* an error code if the statistics are not available
* because the demog is not locked.
* @read_status: returns the locking status of the frontend.
* @read_ber: legacy callback function to return the bit error rate.
* Newer drivers should provide such info via DVBv5 API,
* e. g. @set_frontend;/@get_frontend;, implementing this
* callback only if DVBv3 API compatibility is wanted.
* @read_signal_strength: legacy callback function to return the signal
* strength. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_snr: legacy callback function to return the Signal/Noise
* rate. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_ucblocks: legacy callback function to return the Uncorrected Error
* Blocks. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @diseqc_reset_overload: callback function to implement the
* FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite)
* @diseqc_send_master_cmd: callback function to implement the
* FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite).
* @diseqc_recv_slave_reply: callback function to implement the
* FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite)
* @diseqc_send_burst: callback function to implement the
* FE_DISEQC_SEND_BURST ioctl (only Satellite).
* @set_tone: callback function to implement the
* FE_SET_TONE ioctl (only Satellite).
* @set_voltage: callback function to implement the
* FE_SET_VOLTAGE ioctl (only Satellite).
* @enable_high_lnb_voltage: callback function to implement the
* FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite).
* @dishnetwork_send_legacy_command: callback function to implement the
* FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite).
* @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C
* mux support instead.
* @ts_bus_ctrl: callback function used to take control of the TS bus.
* @set_lna: callback function to power on/off/auto the LNA.
* @search: callback function used on some custom algo search algos.
* @tuner_ops: pointer to struct dvb_tuner_ops
* @analog_ops: pointer to struct analog_demod_ops
* @set_property: callback function to allow the frontend to validade
* incoming properties. Should not be used on new drivers.
* @get_property: callback function to allow the frontend to override
* outcoming properties. Should not be used on new drivers.
*/
struct dvb_frontend_ops {
struct dvb_frontend_info info;
@ -280,6 +436,7 @@ struct dvb_frontend_ops {
unsigned int mode_flags,
unsigned int *delay,
enum fe_status *status);
/* get frontend tuning algorithm from the module */
enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
@ -324,6 +481,7 @@ struct dvb_frontend_ops {
#ifdef __DVB_CORE__
#define MAX_EVENT 8
/* Used only internally at dvb_frontend.c */
struct dvb_fe_events {
struct dvb_frontend_event events[MAX_EVENT];
int eventw;
@ -334,13 +492,83 @@ struct dvb_fe_events {
};
#endif
/**
* struct dtv_frontend_properties - contains a list of properties that are
* specific to a digital TV standard.
*
* @frequency: frequency in Hz for terrestrial/cable or in kHz for
* Satellite
* @modulation: Frontend modulation type
* @voltage: SEC voltage (only Satellite)
* @sectone: SEC tone mode (only Satellite)
* @inversion: Spectral inversion
* @fec_inner: Forward error correction inner Code Rate
* @transmission_mode: Transmission Mode
* @bandwidth_hz: Bandwidth, in Hz. A zero value means that userspace
* wants to autodetect.
* @guard_interval: Guard Interval
* @hierarchy: Hierarchy
* @symbol_rate: Symbol Rate
* @code_rate_HP: high priority stream code rate
* @code_rate_LP: low priority stream code rate
* @pilot: Enable/disable/autodetect pilot tones
* @rolloff: Rolloff factor (alpha)
* @delivery_system: FE delivery system (e. g. digital TV standard)
* @interleaving: interleaving
* @isdbt_partial_reception: ISDB-T partial reception (only ISDB standard)
* @isdbt_sb_mode: ISDB-T Sound Broadcast (SB) mode (only ISDB standard)
* @isdbt_sb_subchannel: ISDB-T SB subchannel (only ISDB standard)
* @isdbt_sb_segment_idx: ISDB-T SB segment index (only ISDB standard)
* @isdbt_sb_segment_count: ISDB-T SB segment count (only ISDB standard)
* @isdbt_layer_enabled: ISDB Layer enabled (only ISDB standard)
* @layer: ISDB per-layer data (only ISDB standard)
* @layer.segment_count: Segment Count;
* @layer.fec: per layer code rate;
* @layer.modulation: per layer modulation;
* @layer.interleaving: per layer interleaving.
* @stream_id: If different than zero, enable substream filtering, if
* hardware supports (DVB-S2 and DVB-T2).
* @atscmh_fic_ver: Version number of the FIC (Fast Information Channel)
* signaling data (only ATSC-M/H)
* @atscmh_parade_id: Parade identification number (only ATSC-M/H)
* @atscmh_nog: Number of MH groups per MH subframe for a designated
* parade (only ATSC-M/H)
* @atscmh_tnog: Total number of MH groups including all MH groups
* belonging to all MH parades in one MH subframe
* (only ATSC-M/H)
* @atscmh_sgn: Start group number (only ATSC-M/H)
* @atscmh_prc: Parade repetition cycle (only ATSC-M/H)
* @atscmh_rs_frame_mode: Reed Solomon (RS) frame mode (only ATSC-M/H)
* @atscmh_rs_frame_ensemble: RS frame ensemble (only ATSC-M/H)
* @atscmh_rs_code_mode_pri: RS code mode pri (only ATSC-M/H)
* @atscmh_rs_code_mode_sec: RS code mode sec (only ATSC-M/H)
* @atscmh_sccc_block_mode: Series Concatenated Convolutional Code (SCCC)
* Block Mode (only ATSC-M/H)
* @atscmh_sccc_code_mode_a: SCCC code mode A (only ATSC-M/H)
* @atscmh_sccc_code_mode_b: SCCC code mode B (only ATSC-M/H)
* @atscmh_sccc_code_mode_c: SCCC code mode C (only ATSC-M/H)
* @atscmh_sccc_code_mode_d: SCCC code mode D (only ATSC-M/H)
* @lna: Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA)
* @strength: DVBv5 API statistics: Signal Strength
* @cnr: DVBv5 API statistics: Signal to Noise ratio of the
* (main) carrier
* @pre_bit_error: DVBv5 API statistics: pre-Viterbi bit error count
* @pre_bit_count: DVBv5 API statistics: pre-Viterbi bit count
* @post_bit_error: DVBv5 API statistics: post-Viterbi bit error count
* @post_bit_count: DVBv5 API statistics: post-Viterbi bit count
* @block_error: DVBv5 API statistics: block error count
* @block_count: DVBv5 API statistics: block count
*
* NOTE: derivated statistics like Uncorrected Error blocks (UCE) are
* calculated on userspace.
*
* Only a subset of the properties are needed for a given delivery system.
* For more info, consult the media_api.html with the documentation of the
* Userspace API.
*/
struct dtv_frontend_properties {
/* Cache State */
u32 state;
u32 frequency;
enum fe_modulation modulation;
enum fe_modulation modulation;
enum fe_sec_voltage voltage;
enum fe_sec_tone_mode sectone;
@ -407,6 +635,11 @@ struct dtv_frontend_properties {
struct dtv_fe_stats post_bit_count;
struct dtv_fe_stats block_error;
struct dtv_fe_stats block_count;
/* private: */
/* Cache State */
u32 state;
};
#define DVB_FE_NO_EXIT 0
@ -414,6 +647,25 @@ struct dtv_frontend_properties {
#define DVB_FE_DEVICE_REMOVED 2
#define DVB_FE_DEVICE_RESUME 3
/**
* struct dvb_frontend - Frontend structure to be used on drivers.
*
* @ops: embedded struct dvb_frontend_ops
* @dvb: pointer to struct dvb_adapter
* @demodulator_priv: demod private data
* @tuner_priv: tuner private data
* @frontend_priv: frontend private data
* @sec_priv: SEC private data
* @analog_demod_priv: Analog demod private data
* @dtv_property_cache: embedded struct dtv_frontend_properties
* @callback: callback function used on some drivers to call
* either the tuner or the demodulator.
* @id: Frontend ID
* @exit: Used to inform the DVB core that the frontend
* thread should exit (usually, means that the hardware
* got disconnected.
*/
struct dvb_frontend {
struct dvb_frontend_ops ops;
struct dvb_adapter *dvb;

View File

@ -25,33 +25,38 @@
#include <linux/types.h>
/**
* computes log2 of a value; the result is shifted left by 24 bits
* cintlog2 - computes log2 of a value; the result is shifted left by 24 bits
*
* @value: The value (must be != 0)
*
* to use rational values you can use the following method:
* intlog2(value) = intlog2(value * 2^x) - x * 2^24
*
* example: intlog2(8) will give 3 << 24 = 3 * 2^24
* example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
* example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
* Some usecase examples:
* intlog2(8) will give 3 << 24 = 3 * 2^24
* intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
* intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
*
* @param value The value (must be != 0)
* @return log2(value) * 2^24
*
* return: log2(value) * 2^24
*/
extern unsigned int intlog2(u32 value);
/**
* computes log10 of a value; the result is shifted left by 24 bits
* intlog10 - computes log10 of a value; the result is shifted left by 24 bits
*
* @value: The value (must be != 0)
*
* to use rational values you can use the following method:
* intlog10(value) = intlog10(value * 10^x) - x * 2^24
*
* example: intlog10(1000) will give 3 << 24 = 3 * 2^24
* An usecase example:
* intlog10(1000) will give 3 << 24 = 3 * 2^24
* due to the implementation intlog10(1000) might be not exactly 3 * 2^24
*
* look at intlog2 for similar examples
*
* @param value The value (must be != 0)
* @return log10(value) * 2^24
* return: log10(value) * 2^24
*/
extern unsigned int intlog10(u32 value);

View File

@ -709,7 +709,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
if (!priv->ule_dbit) {
/* dest_addr buffer is only valid if priv->ule_dbit == 0 */
memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
memset(ethh->h_source, 0, ETH_ALEN);
eth_zero_addr(ethh->h_source);
}
else /* zeroize source and dest */
memset( ethh, 0, ETH_ALEN*2 );

View File

@ -45,33 +45,33 @@ struct dvb_ringbuffer {
/*
** Notes:
** ------
** (1) For performance reasons read and write routines don't check buffer sizes
** and/or number of bytes free/available. This has to be done before these
** routines are called. For example:
**
** *** write <buflen> bytes ***
** free = dvb_ringbuffer_free(rbuf);
** if (free >= buflen)
** count = dvb_ringbuffer_write(rbuf, buffer, buflen);
** else
** ...
**
** *** read min. 1000, max. <bufsize> bytes ***
** avail = dvb_ringbuffer_avail(rbuf);
** if (avail >= 1000)
** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
** else
** ...
**
** (2) If there is exactly one reader and one writer, there is no need
** to lock read or write operations.
** Two or more readers must be locked against each other.
** Flushing the buffer counts as a read operation.
** Resetting the buffer counts as a read and write operation.
** Two or more writers must be locked against each other.
*/
* Notes:
* ------
* (1) For performance reasons read and write routines don't check buffer sizes
* and/or number of bytes free/available. This has to be done before these
* routines are called. For example:
*
* *** write @buflen: bytes ***
* free = dvb_ringbuffer_free(rbuf);
* if (free >= buflen)
* count = dvb_ringbuffer_write(rbuf, buffer, buflen);
* else
* ...
*
* *** read min. 1000, max. @bufsize: bytes ***
* avail = dvb_ringbuffer_avail(rbuf);
* if (avail >= 1000)
* count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
* else
* ...
*
* (2) If there is exactly one reader and one writer, there is no need
* to lock read or write operations.
* Two or more readers must be locked against each other.
* Flushing the buffer counts as a read operation.
* Resetting the buffer counts as a read and write operation.
* Two or more writers must be locked against each other.
*/
/* initialize ring buffer, lock and queue */
extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);
@ -87,9 +87,9 @@ extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
/*
** Reset the read and write pointers to zero and flush the buffer
** This counts as a read and write operation
*/
* Reset the read and write pointers to zero and flush the buffer
* This counts as a read and write operation
*/
extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);
@ -101,19 +101,19 @@ extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
/* flush buffer protected by spinlock and wake-up waiting task(s) */
extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
/* peek at byte <offs> in the buffer */
/* peek at byte @offs: in the buffer */
#define DVB_RINGBUFFER_PEEK(rbuf,offs) \
(rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size]
/* advance read ptr by <num> bytes */
/* advance read ptr by @num: bytes */
#define DVB_RINGBUFFER_SKIP(rbuf,num) \
(rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
/*
** read <len> bytes from ring buffer into <buf>
** <usermem> specifies whether <buf> resides in user space
** returns number of bytes transferred or -EFAULT
*/
* read @len: bytes from ring buffer into @buf:
* @usermem: specifies whether @buf: resides in user space
* returns number of bytes transferred or -EFAULT
*/
extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
u8 __user *buf, size_t len);
extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
@ -127,9 +127,9 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
{ (rbuf)->data[(rbuf)->pwrite]=(byte); \
(rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
/*
** write <len> bytes to ring buffer
** <usermem> specifies whether <buf> resides in user space
** returns number of bytes transferred or -EFAULT
* write @len: bytes to ring buffer
* @usermem: specifies whether @buf: resides in user space
* returns number of bytes transferred or -EFAULT
*/
extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
size_t len);
@ -138,48 +138,63 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
/**
* Write a packet into the ringbuffer.
* dvb_ringbuffer_pkt_write - Write a packet into the ringbuffer.
*
* <rbuf> Ringbuffer to write to.
* <buf> Buffer to write.
* <len> Length of buffer (currently limited to 65535 bytes max).
* @rbuf: Ringbuffer to write to.
* @buf: Buffer to write.
* @len: Length of buffer (currently limited to 65535 bytes max).
* returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
*/
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
size_t len);
/**
* Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
* does NOT update the read pointer in the ringbuffer. You must use
* dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.
* dvb_ringbuffer_pkt_read_user - Read from a packet in the ringbuffer.
* Note: unlike dvb_ringbuffer_read(), this does NOT update the read pointer
* in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a
* packet as no longer required.
*
* @rbuf: Ringbuffer concerned.
* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
* @offset: Offset into packet to read from.
* @buf: Destination buffer for data.
* @len: Size of destination buffer.
*
* <rbuf> Ringbuffer concerned.
* <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
* <offset> Offset into packet to read from.
* <buf> Destination buffer for data.
* <len> Size of destination buffer.
* <usermem> Set to 1 if <buf> is in userspace.
* returns Number of bytes read, or -EFAULT.
*/
extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
int offset, u8 __user *buf, size_t len);
/**
* dvb_ringbuffer_pkt_read - Read from a packet in the ringbuffer.
* Note: unlike dvb_ringbuffer_read_user(), this DOES update the read pointer
* in the ringbuffer.
*
* @rbuf: Ringbuffer concerned.
* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
* @offset: Offset into packet to read from.
* @buf: Destination buffer for data.
* @len: Size of destination buffer.
*
* returns Number of bytes read, or -EFAULT.
*/
extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
int offset, u8 *buf, size_t len);
/**
* Dispose of a packet in the ring buffer.
* dvb_ringbuffer_pkt_dispose - Dispose of a packet in the ring buffer.
*
* <rbuf> Ring buffer concerned.
* <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
* @rbuf: Ring buffer concerned.
* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
*/
extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
/**
* Get the index of the next packet in a ringbuffer.
* dvb_ringbuffer_pkt_next - Get the index of the next packet in a ringbuffer.
*
* <rbuf> Ringbuffer concerned.
* <idx> Previous packet index, or -1 to return the first packet index.
* <pktlen> On success, will be updated to contain the length of the packet in bytes.
* @rbuf: Ringbuffer concerned.
* @idx: Previous packet index, or -1 to return the first packet index.
* @pktlen: On success, will be updated to contain the length of the packet in bytes.
* returns Packet index (if >=0), or -1 if no packets available.
*/
extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen);

View File

@ -57,6 +57,25 @@
struct dvb_frontend;
/**
* struct dvb_adapter - represents a Digital TV adapter using Linux DVB API
*
* @num: Number of the adapter
* @list_head: List with the DVB adapters
* @device_list: List with the DVB devices
* @name: Name of the adapter
* @proposed_mac: proposed MAC address for the adapter
* @priv: private data
* @device: pointer to struct device
* @module: pointer to struct module
* @mfe_shared: mfe shared: indicates mutually exclusive frontends
* Thie usage of this flag is currently deprecated
* @mfe_dvbdev: Frontend device in use, in the case of MFE
* @mfe_lock: Lock to prevent using the other frontends when MFE is
* used.
* @mdev: pointer to struct media_device, used when the media
* controller is used.
*/
struct dvb_adapter {
int num;
struct list_head list_head;
@ -78,7 +97,34 @@ struct dvb_adapter {
#endif
};
/**
* struct dvb_device - represents a DVB device node
*
* @list_head: List head with all DVB devices
* @fops: pointer to struct file_operations
* @adapter: pointer to the adapter that holds this device node
* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
* @minor: devnode minor number. Major number is always DVB_MAJOR.
* @id: device ID number, inside the adapter
* @readers: Initialized by the caller. Each call to open() in Read Only mode
* decreases this counter by one.
* @writers: Initialized by the caller. Each call to open() in Read/Write
* mode decreases this counter by one.
* @users: Initialized by the caller. Each call to open() in any mode
* decreases this counter by one.
* @wait_queue: wait queue, used to wait for certain events inside one of
* the DVB API callers
* @kernel_ioctl: callback function used to handle ioctl calls from userspace.
* @name: Name to be used for the device at the Media Controller
* @entity: pointer to struct media_entity associated with the device node
* @pads: pointer to struct media_pad associated with @entity;
* @priv: private data
*
* This structure is used by the DVB core (frontend, CA, net, demux) in
* order to create the device nodes. Usually, driver should not initialize
* this struct diretly.
*/
struct dvb_device {
struct list_head list_head;
const struct file_operations *fops;
@ -109,19 +155,55 @@ struct dvb_device {
void *priv;
};
/**
* dvb_register_adapter - Registers a new DVB adapter
*
* @adap: pointer to struct dvb_adapter
* @name: Adapter's name
* @module: initialized with THIS_MODULE at the caller
* @device: pointer to struct device that corresponds to the device driver
* @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
* to select among them. Typically, initialized with:
* DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
*/
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
struct module *module, struct device *device,
short *adapter_nums);
extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
struct module *module, struct device *device,
short *adapter_nums);
extern int dvb_unregister_adapter (struct dvb_adapter *adap);
/**
* dvb_unregister_adapter - Unregisters a DVB adapter
*
* @adap: pointer to struct dvb_adapter
*/
int dvb_unregister_adapter(struct dvb_adapter *adap);
extern int dvb_register_device (struct dvb_adapter *adap,
struct dvb_device **pdvbdev,
const struct dvb_device *template,
void *priv,
int type);
/**
* dvb_register_device - Registers a new DVB device
*
* @adap: pointer to struct dvb_adapter
* @pdvbdev: pointer to the place where the new struct dvb_device will be
* stored
* @template: Template used to create &pdvbdev;
* @device: pointer to struct device that corresponds to the device driver
* @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
* to select among them. Typically, initialized with:
* DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
* @priv: private data
* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
*/
int dvb_register_device(struct dvb_adapter *adap,
struct dvb_device **pdvbdev,
const struct dvb_device *template,
void *priv,
int type);
extern void dvb_unregister_device (struct dvb_device *dvbdev);
/**
* dvb_unregister_device - Unregisters a DVB device
*
* @dvbdev: pointer to struct dvb_device
*/
void dvb_unregister_device(struct dvb_device *dvbdev);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
void dvb_create_media_graph(struct dvb_adapter *adap);
@ -136,17 +218,17 @@ static inline void dvb_create_media_graph(struct dvb_adapter *adap) {}
#define dvb_register_media_controller(a, b) {}
#endif
extern int dvb_generic_open (struct inode *inode, struct file *file);
extern int dvb_generic_release (struct inode *inode, struct file *file);
extern long dvb_generic_ioctl (struct file *file,
int dvb_generic_open (struct inode *inode, struct file *file);
int dvb_generic_release (struct inode *inode, struct file *file);
long dvb_generic_ioctl (struct file *file,
unsigned int cmd, unsigned long arg);
/* we don't mess with video_usercopy() any more,
we simply define out own dvb_usercopy(), which will hopefully become
generic_usercopy() someday... */
extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
int (*func)(struct file *file, unsigned int cmd, void *arg));
int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
int (*func)(struct file *file, unsigned int cmd, void *arg));
/** generic DVB attach function. */
#ifdef CONFIG_MEDIA_ATTACH

View File

@ -1,5 +1,5 @@
menu "Customise DVB Frontends"
visible if !MEDIA_SUBDRV_AUTOSELECT
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@ -264,6 +264,7 @@ config DVB_MB86A16
config DVB_TDA10071
tristate "NXP TDA10071"
depends on DVB_CORE && I2C
select REGMAP
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
@ -450,6 +451,13 @@ config DVB_CXD2820R
help
Say Y when you want to support this frontend.
config DVB_CXD2841ER
tristate "Sony CXD2841ER"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2830
tristate "Realtek RTL2830 DVB-T"
depends on DVB_CORE && I2C && I2C_MUX
@ -712,6 +720,14 @@ comment "SEC control devices for DVB-S"
source "drivers/media/dvb-frontends/drx39xyj/Kconfig"
config DVB_LNBH25
tristate "LNBH25 SEC controller"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chip.
Say Y when you want to support this chip.
config DVB_LNBP21
tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
@ -815,6 +831,20 @@ config DVB_AF9033
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
config DVB_HORUS3A
tristate "Sony Horus3A tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_ASCOT2E
tristate "Sony Ascot2E tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
comment "Tools to develop new frontends"
config DVB_DUMMY_FE

View File

@ -57,6 +57,7 @@ obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o
obj-$(CONFIG_DVB_LG2160) += lg2160.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
@ -105,6 +106,7 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
obj-$(CONFIG_DVB_STV0367) += stv0367.o
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
obj-$(CONFIG_DVB_CXD2841ER) += cxd2841er.o
obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_SI2165) += si2165.o
@ -118,3 +120,5 @@ obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o
obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
obj-$(CONFIG_DVB_TC90522) += tc90522.o
obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o

View File

@ -12,163 +12,69 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dvb_frontend.h"
#include "a8293.h"
struct a8293_priv {
u8 i2c_addr;
struct i2c_adapter *i2c;
struct a8293_dev {
struct i2c_client *client;
u8 reg[2];
};
static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
{
int ret;
struct i2c_msg msg[1] = {
{
.addr = priv->i2c_addr,
.len = len,
.buf = val,
}
};
if (rd)
msg[0].flags = I2C_M_RD;
else
msg[0].flags = 0;
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret == 1) {
ret = 0;
} else {
dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
KBUILD_MODNAME, ret, rd);
ret = -EREMOTEIO;
}
return ret;
}
static int a8293_wr(struct a8293_priv *priv, u8 *val, int len)
{
return a8293_i2c(priv, val, len, 0);
}
static int a8293_rd(struct a8293_priv *priv, u8 *val, int len)
{
return a8293_i2c(priv, val, len, 1);
}
static int a8293_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage fe_sec_voltage)
enum fe_sec_voltage fe_sec_voltage)
{
struct a8293_priv *priv = fe->sec_priv;
struct a8293_dev *dev = fe->sec_priv;
struct i2c_client *client = dev->client;
int ret;
u8 reg0, reg1;
dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
fe_sec_voltage);
dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage);
switch (fe_sec_voltage) {
case SEC_VOLTAGE_OFF:
/* ENB=0 */
priv->reg[0] = 0x10;
reg0 = 0x10;
break;
case SEC_VOLTAGE_13:
/* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
priv->reg[0] = 0x31;
reg0 = 0x31;
break;
case SEC_VOLTAGE_18:
/* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
priv->reg[0] = 0x38;
reg0 = 0x38;
break;
default:
ret = -EINVAL;
goto err;
}
ret = a8293_wr(priv, &priv->reg[0], 1);
if (ret)
goto err;
usleep_range(1500, 50000);
return ret;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static void a8293_release_sec(struct dvb_frontend *fe)
{
a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
kfree(fe->sec_priv);
fe->sec_priv = NULL;
}
struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg)
{
int ret;
struct a8293_priv *priv = NULL;
u8 buf[2];
/* allocate memory for the internal priv */
priv = kzalloc(sizeof(struct a8293_priv), GFP_KERNEL);
if (priv == NULL) {
ret = -ENOMEM;
goto err;
if (reg0 != dev->reg[0]) {
ret = i2c_master_send(client, &reg0, 1);
if (ret < 0)
goto err;
dev->reg[0] = reg0;
}
/* setup the priv */
priv->i2c = i2c;
priv->i2c_addr = cfg->i2c_addr;
fe->sec_priv = priv;
/* check if the SEC is there */
ret = a8293_rd(priv, buf, 2);
if (ret)
goto err;
/* ENB=0 */
priv->reg[0] = 0x10;
ret = a8293_wr(priv, &priv->reg[0], 1);
if (ret)
goto err;
/* TMODE=0, TGATE=1 */
priv->reg[1] = 0x82;
ret = a8293_wr(priv, &priv->reg[1], 1);
if (ret)
goto err;
reg1 = 0x82;
if (reg1 != dev->reg[1]) {
ret = i2c_master_send(client, &reg1, 1);
if (ret < 0)
goto err;
dev->reg[1] = reg1;
}
fe->ops.release_sec = a8293_release_sec;
/* override frontend ops */
fe->ops.set_voltage = a8293_set_voltage;
dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
KBUILD_MODNAME);
return fe;
usleep_range(1500, 50000);
return 0;
err:
dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
kfree(priv);
return NULL;
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
}
EXPORT_SYMBOL(a8293_attach);
static int a8293_probe(struct i2c_client *client,
const struct i2c_device_id *id)
const struct i2c_device_id *id)
{
struct a8293_priv *dev;
struct a8293_dev *dev;
struct a8293_platform_data *pdata = client->dev.platform_data;
struct dvb_frontend *fe = pdata->dvb_frontend;
int ret;
@ -181,29 +87,14 @@ static int a8293_probe(struct i2c_client *client,
}
dev->client = client;
dev->i2c = client->adapter;
dev->i2c_addr = client->addr;
/* check if the SEC is there */
ret = a8293_rd(dev, buf, 2);
if (ret)
goto err_kfree;
/* ENB=0 */
dev->reg[0] = 0x10;
ret = a8293_wr(dev, &dev->reg[0], 1);
if (ret)
goto err_kfree;
/* TMODE=0, TGATE=1 */
dev->reg[1] = 0x82;
ret = a8293_wr(dev, &dev->reg[1], 1);
if (ret)
ret = i2c_master_recv(client, buf, 2);
if (ret < 0)
goto err_kfree;
/* override frontend ops */
fe->ops.set_voltage = a8293_set_voltage;
fe->sec_priv = dev;
i2c_set_clientdata(client, dev);
@ -234,7 +125,6 @@ MODULE_DEVICE_TABLE(i2c, a8293_id_table);
static struct i2c_driver a8293_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "a8293",
.suppress_bind_attrs = true,
},

View File

@ -12,17 +12,12 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef A8293_H
#define A8293_H
#include "dvb_frontend.h"
#include <linux/kconfig.h>
/*
* I2C address
@ -37,21 +32,4 @@ struct a8293_platform_data {
struct dvb_frontend *dvb_frontend;
};
struct a8293_config {
u8 i2c_addr;
};
#if IS_REACHABLE(CONFIG_DVB_A8293)
extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg);
#else
static inline struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* A8293_H */

View File

@ -1387,7 +1387,6 @@ MODULE_DEVICE_TABLE(i2c, af9033_id_table);
static struct i2c_driver af9033_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "af9033",
},
.probe = af9033_probe,

View File

@ -0,0 +1,548 @@
/*
* ascot2e.c
*
* Sony Ascot3E DVB-T/T2/C/C2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "ascot2e.h"
#include "dvb_frontend.h"
#define MAX_WRITE_REGSIZE 10
enum ascot2e_state {
STATE_UNKNOWN,
STATE_SLEEP,
STATE_ACTIVE
};
struct ascot2e_priv {
u32 frequency;
u8 i2c_address;
struct i2c_adapter *i2c;
enum ascot2e_state state;
void *set_tuner_data;
int (*set_tuner)(void *, int);
};
enum ascot2e_tv_system_t {
ASCOT2E_DTV_DVBT_5,
ASCOT2E_DTV_DVBT_6,
ASCOT2E_DTV_DVBT_7,
ASCOT2E_DTV_DVBT_8,
ASCOT2E_DTV_DVBT2_1_7,
ASCOT2E_DTV_DVBT2_5,
ASCOT2E_DTV_DVBT2_6,
ASCOT2E_DTV_DVBT2_7,
ASCOT2E_DTV_DVBT2_8,
ASCOT2E_DTV_DVBC_6,
ASCOT2E_DTV_DVBC_8,
ASCOT2E_DTV_DVBC2_6,
ASCOT2E_DTV_DVBC2_8,
ASCOT2E_DTV_UNKNOWN
};
struct ascot2e_band_sett {
u8 if_out_sel;
u8 agc_sel;
u8 mix_oll;
u8 rf_gain;
u8 if_bpf_gc;
u8 fif_offset;
u8 bw_offset;
u8 bw;
u8 rf_oldet;
u8 if_bpf_f0;
};
#define ASCOT2E_AUTO 0xff
#define ASCOT2E_OFFSET(ofs) ((u8)(ofs) & 0x1F)
#define ASCOT2E_BW_6 0x00
#define ASCOT2E_BW_7 0x01
#define ASCOT2E_BW_8 0x02
#define ASCOT2E_BW_1_7 0x03
static struct ascot2e_band_sett ascot2e_sett[] = {
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-10), ASCOT2E_OFFSET(-16), ASCOT2E_BW_1_7, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-8), ASCOT2E_BW_6, 0x09, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03,
ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(-1), ASCOT2E_BW_8, 0x09, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_6, 0x09, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01,
ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(2), ASCOT2E_BW_8, 0x09, 0x00 }
};
static void ascot2e_i2c_debug(struct ascot2e_priv *priv,
u8 reg, u8 write, const u8 *data, u32 len)
{
dev_dbg(&priv->i2c->dev, "ascot2e: I2C %s reg 0x%02x size %d\n",
(write == 0 ? "read" : "write"), reg, len);
print_hex_dump_bytes("ascot2e: I2C data: ",
DUMP_PREFIX_OFFSET, data, len);
}
static int ascot2e_write_regs(struct ascot2e_priv *priv,
u8 reg, const u8 *data, u32 len)
{
int ret;
u8 buf[MAX_WRITE_REGSIZE + 1];
struct i2c_msg msg[1] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = len + 1,
.buf = buf,
}
};
if (len + 1 >= sizeof(buf)) {
dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
reg, len + 1);
return -E2BIG;
}
ascot2e_i2c_debug(priv, reg, 1, data, len);
buf[0] = reg;
memcpy(&buf[1], data, len);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: i2c wr failed=%d reg=%02x len=%d\n",
KBUILD_MODNAME, ret, reg, len);
return ret;
}
return 0;
}
static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
{
return ascot2e_write_regs(priv, reg, &val, 1);
}
static int ascot2e_read_regs(struct ascot2e_priv *priv,
u8 reg, u8 *val, u32 len)
{
int ret;
struct i2c_msg msg[2] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = 1,
.buf = &reg,
}, {
.addr = priv->i2c_address,
.flags = I2C_M_RD,
.len = len,
.buf = val,
}
};
ret = i2c_transfer(priv->i2c, &msg[0], 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: I2C rw failed=%d addr=%02x reg=%02x\n",
KBUILD_MODNAME, ret, priv->i2c_address, reg);
return ret;
}
ret = i2c_transfer(priv->i2c, &msg[1], 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: i2c rd failed=%d addr=%02x reg=%02x\n",
KBUILD_MODNAME, ret, priv->i2c_address, reg);
return ret;
}
ascot2e_i2c_debug(priv, reg, 0, val, len);
return 0;
}
static int ascot2e_read_reg(struct ascot2e_priv *priv, u8 reg, u8 *val)
{
return ascot2e_read_regs(priv, reg, val, 1);
}
static int ascot2e_set_reg_bits(struct ascot2e_priv *priv,
u8 reg, u8 data, u8 mask)
{
int res;
u8 rdata;
if (mask != 0xff) {
res = ascot2e_read_reg(priv, reg, &rdata);
if (res != 0)
return res;
data = ((data & mask) | (rdata & (mask ^ 0xFF)));
}
return ascot2e_write_reg(priv, reg, data);
}
static int ascot2e_enter_power_save(struct ascot2e_priv *priv)
{
u8 data[2];
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_SLEEP)
return 0;
data[0] = 0x00;
data[1] = 0x04;
ascot2e_write_regs(priv, 0x14, data, 2);
ascot2e_write_reg(priv, 0x50, 0x01);
priv->state = STATE_SLEEP;
return 0;
}
static int ascot2e_leave_power_save(struct ascot2e_priv *priv)
{
u8 data[2] = { 0xFB, 0x0F };
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_ACTIVE)
return 0;
ascot2e_write_regs(priv, 0x14, data, 2);
ascot2e_write_reg(priv, 0x50, 0x00);
priv->state = STATE_ACTIVE;
return 0;
}
static int ascot2e_init(struct dvb_frontend *fe)
{
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
return ascot2e_leave_power_save(priv);
}
static int ascot2e_release(struct dvb_frontend *fe)
{
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static int ascot2e_sleep(struct dvb_frontend *fe)
{
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
ascot2e_enter_power_save(priv);
return 0;
}
static enum ascot2e_tv_system_t ascot2e_get_tv_system(struct dvb_frontend *fe)
{
enum ascot2e_tv_system_t system = ASCOT2E_DTV_UNKNOWN;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct ascot2e_priv *priv = fe->tuner_priv;
if (p->delivery_system == SYS_DVBT) {
if (p->bandwidth_hz <= 5000000)
system = ASCOT2E_DTV_DVBT_5;
else if (p->bandwidth_hz <= 6000000)
system = ASCOT2E_DTV_DVBT_6;
else if (p->bandwidth_hz <= 7000000)
system = ASCOT2E_DTV_DVBT_7;
else if (p->bandwidth_hz <= 8000000)
system = ASCOT2E_DTV_DVBT_8;
else {
system = ASCOT2E_DTV_DVBT_8;
p->bandwidth_hz = 8000000;
}
} else if (p->delivery_system == SYS_DVBT2) {
if (p->bandwidth_hz <= 5000000)
system = ASCOT2E_DTV_DVBT2_5;
else if (p->bandwidth_hz <= 6000000)
system = ASCOT2E_DTV_DVBT2_6;
else if (p->bandwidth_hz <= 7000000)
system = ASCOT2E_DTV_DVBT2_7;
else if (p->bandwidth_hz <= 8000000)
system = ASCOT2E_DTV_DVBT2_8;
else {
system = ASCOT2E_DTV_DVBT2_8;
p->bandwidth_hz = 8000000;
}
} else if (p->delivery_system == SYS_DVBC_ANNEX_A) {
if (p->bandwidth_hz <= 6000000)
system = ASCOT2E_DTV_DVBC_6;
else if (p->bandwidth_hz <= 8000000)
system = ASCOT2E_DTV_DVBC_8;
}
dev_dbg(&priv->i2c->dev,
"%s(): ASCOT2E DTV system %d (delsys %d, bandwidth %d)\n",
__func__, (int)system, p->delivery_system, p->bandwidth_hz);
return system;
}
static int ascot2e_set_params(struct dvb_frontend *fe)
{
u8 data[10];
u32 frequency;
enum ascot2e_tv_system_t tv_system;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n",
__func__, p->frequency / 1000);
tv_system = ascot2e_get_tv_system(fe);
if (tv_system == ASCOT2E_DTV_UNKNOWN) {
dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n",
__func__);
return -EINVAL;
}
if (priv->set_tuner)
priv->set_tuner(priv->set_tuner_data, 1);
frequency = roundup(p->frequency / 1000, 25);
if (priv->state == STATE_SLEEP)
ascot2e_leave_power_save(priv);
/* IF_OUT_SEL / AGC_SEL setting */
data[0] = 0x00;
if (ascot2e_sett[tv_system].agc_sel != ASCOT2E_AUTO) {
/* AGC pin setting from parameter table */
data[0] |= (u8)(
(ascot2e_sett[tv_system].agc_sel & 0x03) << 3);
}
if (ascot2e_sett[tv_system].if_out_sel != ASCOT2E_AUTO) {
/* IFOUT pin setting from parameter table */
data[0] |= (u8)(
(ascot2e_sett[tv_system].if_out_sel & 0x01) << 2);
}
/* Set bit[4:2] only */
ascot2e_set_reg_bits(priv, 0x05, data[0], 0x1c);
/* 0x06 - 0x0F */
/* REF_R setting (0x06) */
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8) {
/* xtal, xtal*2 */
data[0] = (frequency > 500000) ? 16 : 32;
} else {
/* xtal/8, xtal/4 */
data[0] = (frequency > 500000) ? 2 : 4;
}
/* XOSC_SEL=100uA */
data[1] = 0x04;
/* KBW setting (0x08), KC0 setting (0x09), KC1 setting (0x0A) */
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8) {
data[2] = 18;
data[3] = 120;
data[4] = 20;
} else {
data[2] = 48;
data[3] = 10;
data[4] = 30;
}
/* ORDER/R2_RANGE/R2_BANK/C2_BANK setting (0x0B) */
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8)
data[5] = (frequency > 500000) ? 0x08 : 0x0c;
else
data[5] = (frequency > 500000) ? 0x30 : 0x38;
/* Set MIX_OLL (0x0C) value from parameter table */
data[6] = ascot2e_sett[tv_system].mix_oll;
/* Set RF_GAIN (0x0D) setting from parameter table */
if (ascot2e_sett[tv_system].rf_gain == ASCOT2E_AUTO) {
/* RF_GAIN auto control enable */
ascot2e_write_reg(priv, 0x4E, 0x01);
/* RF_GAIN Default value */
data[7] = 0x00;
} else {
/* RF_GAIN auto control disable */
ascot2e_write_reg(priv, 0x4E, 0x00);
data[7] = ascot2e_sett[tv_system].rf_gain;
}
/* Set IF_BPF_GC/FIF_OFFSET (0x0E) value from parameter table */
data[8] = (u8)((ascot2e_sett[tv_system].fif_offset << 3) |
(ascot2e_sett[tv_system].if_bpf_gc & 0x07));
/* Set BW_OFFSET (0x0F) value from parameter table */
data[9] = ascot2e_sett[tv_system].bw_offset;
ascot2e_write_regs(priv, 0x06, data, 10);
/*
* 0x45 - 0x47
* LNA optimization setting
* RF_LNA_DIST1-5, RF_LNA_CM
*/
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8) {
data[0] = 0x0F;
data[1] = 0x00;
data[2] = 0x01;
} else {
data[0] = 0x0F;
data[1] = 0x00;
data[2] = 0x03;
}
ascot2e_write_regs(priv, 0x45, data, 3);
/* 0x49 - 0x4A
Set RF_OLDET_ENX/RF_OLDET_OLL value from parameter table */
data[0] = ascot2e_sett[tv_system].rf_oldet;
/* Set IF_BPF_F0 value from parameter table */
data[1] = ascot2e_sett[tv_system].if_bpf_f0;
ascot2e_write_regs(priv, 0x49, data, 2);
/*
* Tune now
* RFAGC fast mode / RFAGC auto control enable
* (set bit[7], bit[5:4] only)
* vco_cal = 1, set MIX_OL_CPU_EN
*/
ascot2e_set_reg_bits(priv, 0x0c, 0x90, 0xb0);
/* Logic wake up, CPU wake up */
data[0] = 0xc4;
data[1] = 0x40;
ascot2e_write_regs(priv, 0x03, data, 2);
/* 0x10 - 0x14 */
data[0] = (u8)(frequency & 0xFF); /* 0x10: FRF_L */
data[1] = (u8)((frequency >> 8) & 0xFF); /* 0x11: FRF_M */
data[2] = (u8)((frequency >> 16) & 0x0F); /* 0x12: FRF_H (bit[3:0]) */
/* 0x12: BW (bit[5:4]) */
data[2] |= (u8)(ascot2e_sett[tv_system].bw << 4);
data[3] = 0xFF; /* 0x13: VCO calibration enable */
data[4] = 0xFF; /* 0x14: Analog block enable */
/* Tune (Burst write) */
ascot2e_write_regs(priv, 0x10, data, 5);
msleep(50);
/* CPU deep sleep */
ascot2e_write_reg(priv, 0x04, 0x00);
/* Logic sleep */
ascot2e_write_reg(priv, 0x03, 0xC0);
/* RFAGC normal mode (set bit[5:4] only) */
ascot2e_set_reg_bits(priv, 0x0C, 0x00, 0x30);
priv->frequency = frequency;
return 0;
}
static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct ascot2e_priv *priv = fe->tuner_priv;
*frequency = priv->frequency * 1000;
return 0;
}
static struct dvb_tuner_ops ascot2e_tuner_ops = {
.info = {
.name = "Sony ASCOT2E",
.frequency_min = 1000000,
.frequency_max = 1200000000,
.frequency_step = 25000,
},
.init = ascot2e_init,
.release = ascot2e_release,
.sleep = ascot2e_sleep,
.set_params = ascot2e_set_params,
.get_frequency = ascot2e_get_frequency,
};
struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c)
{
u8 data[4];
struct ascot2e_priv *priv = NULL;
priv = kzalloc(sizeof(struct ascot2e_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->i2c_address = (config->i2c_address >> 1);
priv->i2c = i2c;
priv->set_tuner_data = config->set_tuner_priv;
priv->set_tuner = config->set_tuner_callback;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
/* 16 MHz xTal frequency */
data[0] = 16;
/* VCO current setting */
data[1] = 0x06;
/* Logic wake up, CPU boot */
data[2] = 0xC4;
data[3] = 0x40;
ascot2e_write_regs(priv, 0x01, data, 4);
/* RFVGA optimization setting (RF_DIST0 - RF_DIST2) */
data[0] = 0x10;
data[1] = 0x3F;
data[2] = 0x25;
ascot2e_write_regs(priv, 0x22, data, 3);
/* PLL mode setting */
ascot2e_write_reg(priv, 0x28, 0x1e);
/* RSSI setting */
ascot2e_write_reg(priv, 0x59, 0x04);
/* TODO check CPU HW error state here */
msleep(80);
/* Xtal oscillator current control setting */
ascot2e_write_reg(priv, 0x4c, 0x01);
/* XOSC_SEL=100uA */
ascot2e_write_reg(priv, 0x07, 0x04);
/* CPU deep sleep */
ascot2e_write_reg(priv, 0x04, 0x00);
/* Logic sleep */
ascot2e_write_reg(priv, 0x03, 0xc0);
/* Power save setting */
data[0] = 0x00;
data[1] = 0x04;
ascot2e_write_regs(priv, 0x14, data, 2);
ascot2e_write_reg(priv, 0x50, 0x01);
priv->state = STATE_SLEEP;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
memcpy(&fe->ops.tuner_ops, &ascot2e_tuner_ops,
sizeof(struct dvb_tuner_ops));
fe->tuner_priv = priv;
dev_info(&priv->i2c->dev,
"Sony ASCOT2E attached on addr=%x at I2C adapter %p\n",
priv->i2c_address, priv->i2c);
return fe;
}
EXPORT_SYMBOL(ascot2e_attach);
MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver");
MODULE_AUTHOR("info@netup.ru");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,58 @@
/*
* ascot2e.h
*
* Sony Ascot3E DVB-T/T2/C/C2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DVB_ASCOT2E_H__
#define __DVB_ASCOT2E_H__
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
/**
* struct ascot2e_config - the configuration of Ascot2E tuner driver
* @i2c_address: I2C address of the tuner
* @xtal_freq_mhz: Oscillator frequency, MHz
* @set_tuner_priv: Callback function private context
* @set_tuner_callback: Callback function that notifies the parent driver
* which tuner is active now
*/
struct ascot2e_config {
u8 i2c_address;
u8 xtal_freq_mhz;
void *set_tuner_priv;
int (*set_tuner_callback)(void *, int);
};
#if IS_REACHABLE(CONFIG_DVB_ASCOT2E)
extern struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View File

@ -820,7 +820,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id);
static struct i2c_driver au8522_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "au8522",
},
.probe = au8522_probe,

View File

@ -1011,7 +1011,7 @@ static int cx24123_tune(struct dvb_frontend *fe,
static int cx24123_get_algo(struct dvb_frontend *fe)
{
return 1; /* FE_ALGO_HW */
return DVBFE_ALGO_HW;
}
static void cx24123_release(struct dvb_frontend *fe)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
/*
* cxd2841er.h
*
* Sony CXD2441ER digital demodulator driver public definitions
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CXD2841ER_H
#define CXD2841ER_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct cxd2841er_config {
u8 i2c_addr;
};
#if IS_REACHABLE(CONFIG_DVB_CXD2841ER)
extern struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
struct i2c_adapter *i2c);
extern struct dvb_frontend *cxd2841er_attach_t(struct cxd2841er_config *cfg,
struct i2c_adapter *i2c);
extern struct dvb_frontend *cxd2841er_attach_c(struct cxd2841er_config *cfg,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *cxd2841er_attach_s(
struct cxd2841er_config *cfg,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend *cxd2841er_attach_t(
struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend *cxd2841er_attach_c(
struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View File

@ -0,0 +1,43 @@
/*
* cxd2841er_priv.h
*
* Sony CXD2441ER digital demodulator driver internal definitions
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CXD2841ER_PRIV_H
#define CXD2841ER_PRIV_H
#define I2C_SLVX 0
#define I2C_SLVT 1
#define CXD2841ER_CHIP_ID 0xa7
#define CXD2841ER_DVBS_POLLING_INVL 10
struct cxd2841er_cnr_data {
u32 value;
int cnr_x1000;
};
enum cxd2841er_dvbt2_profile_t {
DVBT2_PROFILE_ANY = 0,
DVBT2_PROFILE_BASE = 1,
DVBT2_PROFILE_LITE = 2
};
#endif

View File

@ -34,7 +34,7 @@ struct dvb_pll_priv {
struct i2c_adapter *i2c;
/* the PLL descriptor */
struct dvb_pll_desc *pll_desc;
const struct dvb_pll_desc *pll_desc;
/* cached frequency/bandwidth */
u32 frequency;
@ -57,7 +57,7 @@ MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
/* ----------------------------------------------------------- */
struct dvb_pll_desc {
char *name;
const char *name;
u32 min;
u32 max;
u32 iffreq;
@ -71,13 +71,13 @@ struct dvb_pll_desc {
u32 stepsize;
u8 config;
u8 cb;
} entries[12];
} entries[];
};
/* ----------------------------------------------------------- */
/* descriptions */
static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
static const struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
.name = "Thomson dtt7579",
.min = 177000000,
.max = 858000000,
@ -99,7 +99,7 @@ static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x10;
}
static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
static const struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
.name = "Thomson dtt759x",
.min = 177000000,
.max = 896000000,
@ -123,7 +123,7 @@ static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] ^= 0x10;
}
static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
static const struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
.name = "Thomson dtt7520x",
.min = 185000000,
.max = 900000000,
@ -141,7 +141,7 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
},
};
static struct dvb_pll_desc dvb_pll_lg_z201 = {
static const struct dvb_pll_desc dvb_pll_lg_z201 = {
.name = "LG z201",
.min = 174000000,
.max = 862000000,
@ -157,7 +157,7 @@ static struct dvb_pll_desc dvb_pll_lg_z201 = {
},
};
static struct dvb_pll_desc dvb_pll_unknown_1 = {
static const struct dvb_pll_desc dvb_pll_unknown_1 = {
.name = "unknown 1", /* used by dntv live dvb-t */
.min = 174000000,
.max = 862000000,
@ -179,7 +179,7 @@ static struct dvb_pll_desc dvb_pll_unknown_1 = {
/* Infineon TUA6010XS
* used in Thomson Cable Tuner
*/
static struct dvb_pll_desc dvb_pll_tua6010xs = {
static const struct dvb_pll_desc dvb_pll_tua6010xs = {
.name = "Infineon TUA6010XS",
.min = 44250000,
.max = 858000000,
@ -193,7 +193,7 @@ static struct dvb_pll_desc dvb_pll_tua6010xs = {
};
/* Panasonic env57h1xd5 (some Philips PLL ?) */
static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
static const struct dvb_pll_desc dvb_pll_env57h1xd5 = {
.name = "Panasonic ENV57H1XD5",
.min = 44250000,
.max = 858000000,
@ -217,7 +217,7 @@ static void tda665x_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x08;
}
static struct dvb_pll_desc dvb_pll_tda665x = {
static const struct dvb_pll_desc dvb_pll_tda665x = {
.name = "Philips TDA6650/TDA6651",
.min = 44250000,
.max = 858000000,
@ -251,7 +251,7 @@ static void tua6034_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x08;
}
static struct dvb_pll_desc dvb_pll_tua6034 = {
static const struct dvb_pll_desc dvb_pll_tua6034 = {
.name = "Infineon TUA6034",
.min = 44250000,
.max = 858000000,
@ -275,7 +275,7 @@ static void tded4_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x04;
}
static struct dvb_pll_desc dvb_pll_tded4 = {
static const struct dvb_pll_desc dvb_pll_tded4 = {
.name = "ALPS TDED4",
.min = 47000000,
.max = 863000000,
@ -293,7 +293,7 @@ static struct dvb_pll_desc dvb_pll_tded4 = {
/* ALPS TDHU2
* used in AverTVHD MCE A180
*/
static struct dvb_pll_desc dvb_pll_tdhu2 = {
static const struct dvb_pll_desc dvb_pll_tdhu2 = {
.name = "ALPS TDHU2",
.min = 54000000,
.max = 864000000,
@ -310,7 +310,7 @@ static struct dvb_pll_desc dvb_pll_tdhu2 = {
/* Samsung TBMV30111IN / TBMV30712IN1
* used in Air2PC ATSC - 2nd generation (nxt2002)
*/
static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
static const struct dvb_pll_desc dvb_pll_samsung_tbmv = {
.name = "Samsung TBMV30111IN / TBMV30712IN1",
.min = 54000000,
.max = 860000000,
@ -329,7 +329,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
/*
* Philips SD1878 Tuner.
*/
static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
static const struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
.name = "Philips SD1878",
.min = 950000,
.max = 2150000,
@ -395,7 +395,7 @@ static void opera1_bw(struct dvb_frontend *fe, u8 *buf)
return;
}
static struct dvb_pll_desc dvb_pll_opera1 = {
static const struct dvb_pll_desc dvb_pll_opera1 = {
.name = "Opera Tuner",
.min = 900000,
.max = 2250000,
@ -442,7 +442,7 @@ static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf)
}
/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
static const struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
.name = "Samsung DTOS403IH102A",
.min = 44250000,
.max = 858000000,
@ -462,7 +462,7 @@ static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
};
/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
static const struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
.name = "Samsung TDTC9251DH0",
.min = 48000000,
.max = 863000000,
@ -476,7 +476,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
};
/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
static const struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
.name = "Samsung TBDU18132",
.min = 950000,
.max = 2150000, /* guesses */
@ -497,7 +497,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
};
/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
static const struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
.name = "Samsung TBMU24112",
.min = 950000,
.max = 2150000, /* guesses */
@ -518,7 +518,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
* 153 - 430 0 * 0 0 0 0 1 0 0x02
* 430 - 822 0 * 0 0 1 0 0 0 0x08
* 822 - 862 1 * 0 0 1 0 0 0 0x88 */
static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
static const struct dvb_pll_desc dvb_pll_alps_tdee4 = {
.name = "ALPS TDEE4",
.min = 47000000,
.max = 862000000,
@ -534,7 +534,7 @@ static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
/* ----------------------------------------------------------- */
static struct dvb_pll_desc *pll_list[] = {
static const struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_UNDEFINED] = NULL,
[DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579,
[DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x,
@ -564,7 +564,7 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
const u32 frequency)
{
struct dvb_pll_priv *priv = fe->tuner_priv;
struct dvb_pll_desc *desc = priv->pll_desc;
const struct dvb_pll_desc *desc = priv->pll_desc;
u32 div;
int i;
@ -758,7 +758,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
.buf = b1, .len = 1 };
struct dvb_pll_priv *priv = NULL;
int ret;
struct dvb_pll_desc *desc;
const struct dvb_pll_desc *desc;
if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
(id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))

View File

@ -0,0 +1,430 @@
/*
* horus3a.h
*
* Sony Horus3A DVB-S/S2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "horus3a.h"
#include "dvb_frontend.h"
#define MAX_WRITE_REGSIZE 5
enum horus3a_state {
STATE_UNKNOWN,
STATE_SLEEP,
STATE_ACTIVE
};
struct horus3a_priv {
u32 frequency;
u8 i2c_address;
struct i2c_adapter *i2c;
enum horus3a_state state;
void *set_tuner_data;
int (*set_tuner)(void *, int);
};
static void horus3a_i2c_debug(struct horus3a_priv *priv,
u8 reg, u8 write, const u8 *data, u32 len)
{
dev_dbg(&priv->i2c->dev, "horus3a: I2C %s reg 0x%02x size %d\n",
(write == 0 ? "read" : "write"), reg, len);
print_hex_dump_bytes("horus3a: I2C data: ",
DUMP_PREFIX_OFFSET, data, len);
}
static int horus3a_write_regs(struct horus3a_priv *priv,
u8 reg, const u8 *data, u32 len)
{
int ret;
u8 buf[MAX_WRITE_REGSIZE + 1];
struct i2c_msg msg[1] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = len + 1,
.buf = buf,
}
};
if (len + 1 >= sizeof(buf)) {
dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
reg, len + 1);
return -E2BIG;
}
horus3a_i2c_debug(priv, reg, 1, data, len);
buf[0] = reg;
memcpy(&buf[1], data, len);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: i2c wr failed=%d reg=%02x len=%d\n",
KBUILD_MODNAME, ret, reg, len);
return ret;
}
return 0;
}
static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
{
return horus3a_write_regs(priv, reg, &val, 1);
}
static int horus3a_enter_power_save(struct horus3a_priv *priv)
{
u8 data[2];
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_SLEEP)
return 0;
/* IQ Generator disable */
horus3a_write_reg(priv, 0x2a, 0x79);
/* MDIV_EN = 0 */
horus3a_write_reg(priv, 0x29, 0x70);
/* VCO disable preparation */
horus3a_write_reg(priv, 0x28, 0x3e);
/* VCO buffer disable */
horus3a_write_reg(priv, 0x2a, 0x19);
/* VCO calibration disable */
horus3a_write_reg(priv, 0x1c, 0x00);
/* Power save setting (xtal is not stopped) */
data[0] = 0xC0;
/* LNA is Disabled */
data[1] = 0xA7;
/* 0x11 - 0x12 */
horus3a_write_regs(priv, 0x11, data, sizeof(data));
priv->state = STATE_SLEEP;
return 0;
}
static int horus3a_leave_power_save(struct horus3a_priv *priv)
{
u8 data[2];
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_ACTIVE)
return 0;
/* Leave power save */
data[0] = 0x00;
/* LNA is Disabled */
data[1] = 0xa7;
/* 0x11 - 0x12 */
horus3a_write_regs(priv, 0x11, data, sizeof(data));
/* VCO buffer enable */
horus3a_write_reg(priv, 0x2a, 0x79);
/* VCO calibration enable */
horus3a_write_reg(priv, 0x1c, 0xc0);
/* MDIV_EN = 1 */
horus3a_write_reg(priv, 0x29, 0x71);
usleep_range(5000, 7000);
priv->state = STATE_ACTIVE;
return 0;
}
static int horus3a_init(struct dvb_frontend *fe)
{
struct horus3a_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
return 0;
}
static int horus3a_release(struct dvb_frontend *fe)
{
struct horus3a_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static int horus3a_sleep(struct dvb_frontend *fe)
{
struct horus3a_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
horus3a_enter_power_save(priv);
return 0;
}
static int horus3a_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct horus3a_priv *priv = fe->tuner_priv;
u32 frequency = p->frequency;
u32 symbol_rate = p->symbol_rate/1000;
u8 mixdiv = 0;
u8 mdiv = 0;
u32 ms = 0;
u8 f_ctl = 0;
u8 g_ctl = 0;
u8 fc_lpf = 0;
u8 data[5];
dev_dbg(&priv->i2c->dev, "%s(): frequency %dkHz symbol_rate %dksps\n",
__func__, frequency, symbol_rate);
if (priv->set_tuner)
priv->set_tuner(priv->set_tuner_data, 0);
if (priv->state == STATE_SLEEP)
horus3a_leave_power_save(priv);
/* frequency should be X MHz (X : integer) */
frequency = DIV_ROUND_CLOSEST(frequency, 1000) * 1000;
if (frequency <= 1155000) {
mixdiv = 4;
mdiv = 1;
} else {
mixdiv = 2;
mdiv = 0;
}
/* Assumed that fREF == 1MHz (1000kHz) */
ms = DIV_ROUND_CLOSEST((frequency * mixdiv) / 2, 1000);
if (ms > 0x7FFF) { /* 15 bit */
dev_err(&priv->i2c->dev, "horus3a: invalid frequency %d\n",
frequency);
return -EINVAL;
}
if (frequency < 975000) {
/* F_CTL=11100 G_CTL=001 */
f_ctl = 0x1C;
g_ctl = 0x01;
} else if (frequency < 1050000) {
/* F_CTL=11000 G_CTL=010 */
f_ctl = 0x18;
g_ctl = 0x02;
} else if (frequency < 1150000) {
/* F_CTL=10100 G_CTL=010 */
f_ctl = 0x14;
g_ctl = 0x02;
} else if (frequency < 1250000) {
/* F_CTL=10000 G_CTL=011 */
f_ctl = 0x10;
g_ctl = 0x03;
} else if (frequency < 1350000) {
/* F_CTL=01100 G_CTL=100 */
f_ctl = 0x0C;
g_ctl = 0x04;
} else if (frequency < 1450000) {
/* F_CTL=01010 G_CTL=100 */
f_ctl = 0x0A;
g_ctl = 0x04;
} else if (frequency < 1600000) {
/* F_CTL=00111 G_CTL=101 */
f_ctl = 0x07;
g_ctl = 0x05;
} else if (frequency < 1800000) {
/* F_CTL=00100 G_CTL=010 */
f_ctl = 0x04;
g_ctl = 0x02;
} else if (frequency < 2000000) {
/* F_CTL=00010 G_CTL=001 */
f_ctl = 0x02;
g_ctl = 0x01;
} else {
/* F_CTL=00000 G_CTL=000 */
f_ctl = 0x00;
g_ctl = 0x00;
}
/* LPF cutoff frequency setting */
if (p->delivery_system == SYS_DVBS) {
/*
* rolloff = 0.35
* SR <= 4.3
* fc_lpf = 5
* 4.3 < SR <= 10
* fc_lpf = SR * (1 + rolloff) / 2 + SR / 2 =
* SR * 1.175 = SR * (47/40)
* 10 < SR
* fc_lpf = SR * (1 + rolloff) / 2 + 5 =
* SR * 0.675 + 5 = SR * (27/40) + 5
* NOTE: The result should be round up.
*/
if (symbol_rate <= 4300)
fc_lpf = 5;
else if (symbol_rate <= 10000)
fc_lpf = (u8)DIV_ROUND_UP(symbol_rate * 47, 40000);
else
fc_lpf = (u8)DIV_ROUND_UP(symbol_rate * 27, 40000) + 5;
/* 5 <= fc_lpf <= 36 */
if (fc_lpf > 36)
fc_lpf = 36;
} else if (p->delivery_system == SYS_DVBS2) {
int rolloff;
switch (p->rolloff) {
case ROLLOFF_35:
rolloff = 35;
break;
case ROLLOFF_25:
rolloff = 25;
break;
case ROLLOFF_20:
rolloff = 20;
break;
case ROLLOFF_AUTO:
default:
dev_err(&priv->i2c->dev,
"horus3a: auto roll-off is not supported\n");
return -EINVAL;
}
/*
* SR <= 4.5:
* fc_lpf = 5
* 4.5 < SR <= 10:
* fc_lpf = SR * (1 + rolloff) / 2 + SR / 2
* 10 < SR:
* fc_lpf = SR * (1 + rolloff) / 2 + 5
* NOTE: The result should be round up.
*/
if (symbol_rate <= 4500)
fc_lpf = 5;
else if (symbol_rate <= 10000)
fc_lpf = (u8)DIV_ROUND_UP(
symbol_rate * (200 + rolloff), 200000);
else
fc_lpf = (u8)DIV_ROUND_UP(
symbol_rate * (100 + rolloff), 200000) + 5;
/* 5 <= fc_lpf <= 36 is valid */
if (fc_lpf > 36)
fc_lpf = 36;
} else {
dev_err(&priv->i2c->dev,
"horus3a: invalid delivery system %d\n",
p->delivery_system);
return -EINVAL;
}
/* 0x00 - 0x04 */
data[0] = (u8)((ms >> 7) & 0xFF);
data[1] = (u8)((ms << 1) & 0xFF);
data[2] = 0x00;
data[3] = 0x00;
data[4] = (u8)(mdiv << 7);
horus3a_write_regs(priv, 0x00, data, sizeof(data));
/* Write G_CTL, F_CTL */
horus3a_write_reg(priv, 0x09, (u8)((g_ctl << 5) | f_ctl));
/* Write LPF cutoff frequency */
horus3a_write_reg(priv, 0x37, (u8)(0x80 | (fc_lpf << 1)));
/* Start Calibration */
horus3a_write_reg(priv, 0x05, 0x80);
/* IQ Generator enable */
horus3a_write_reg(priv, 0x2a, 0x7b);
/* tuner stabilization time */
msleep(60);
/* Store tuned frequency to the struct */
priv->frequency = ms * 2 * 1000 / mixdiv;
return 0;
}
static int horus3a_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct horus3a_priv *priv = fe->tuner_priv;
*frequency = priv->frequency;
return 0;
}
static struct dvb_tuner_ops horus3a_tuner_ops = {
.info = {
.name = "Sony Horus3a",
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_step = 1000,
},
.init = horus3a_init,
.release = horus3a_release,
.sleep = horus3a_sleep,
.set_params = horus3a_set_params,
.get_frequency = horus3a_get_frequency,
};
struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
const struct horus3a_config *config,
struct i2c_adapter *i2c)
{
u8 buf[3], val;
struct horus3a_priv *priv = NULL;
priv = kzalloc(sizeof(struct horus3a_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->i2c_address = (config->i2c_address >> 1);
priv->i2c = i2c;
priv->set_tuner_data = config->set_tuner_priv;
priv->set_tuner = config->set_tuner_callback;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
/* wait 4ms after power on */
usleep_range(4000, 6000);
/* IQ Generator disable */
horus3a_write_reg(priv, 0x2a, 0x79);
/* REF_R = Xtal Frequency */
buf[0] = config->xtal_freq_mhz;
buf[1] = config->xtal_freq_mhz;
buf[2] = 0;
/* 0x6 - 0x8 */
horus3a_write_regs(priv, 0x6, buf, 3);
/* IQ Out = Single Ended */
horus3a_write_reg(priv, 0x0a, 0x40);
switch (config->xtal_freq_mhz) {
case 27:
val = 0x1f;
break;
case 24:
val = 0x10;
break;
case 16:
val = 0xc;
break;
default:
val = 0;
dev_warn(&priv->i2c->dev,
"horus3a: invalid xtal frequency %dMHz\n",
config->xtal_freq_mhz);
break;
}
val <<= 2;
horus3a_write_reg(priv, 0x0e, val);
horus3a_enter_power_save(priv);
usleep_range(3000, 5000);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
memcpy(&fe->ops.tuner_ops, &horus3a_tuner_ops,
sizeof(struct dvb_tuner_ops));
fe->tuner_priv = priv;
dev_info(&priv->i2c->dev,
"Sony HORUS3A attached on addr=%x at I2C adapter %p\n",
priv->i2c_address, priv->i2c);
return fe;
}
EXPORT_SYMBOL(horus3a_attach);
MODULE_DESCRIPTION("Sony HORUS3A sattelite tuner driver");
MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,58 @@
/*
* horus3a.h
*
* Sony Horus3A DVB-S/S2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DVB_HORUS3A_H__
#define __DVB_HORUS3A_H__
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
/**
* struct horus3a_config - the configuration of Horus3A tuner driver
* @i2c_address: I2C address of the tuner
* @xtal_freq_mhz: Oscillator frequency, MHz
* @set_tuner_priv: Callback function private context
* @set_tuner_callback: Callback function that notifies the parent driver
* which tuner is active now
*/
struct horus3a_config {
u8 i2c_address;
u8 xtal_freq_mhz;
void *set_tuner_priv;
int (*set_tuner_callback)(void *, int);
};
#if IS_REACHABLE(CONFIG_DVB_HORUS3A)
extern struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
const struct horus3a_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *horus3a_attach(
const struct cxd2820r_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View File

@ -0,0 +1,189 @@
/*
* lnbh25.c
*
* Driver for LNB supply and control IC LNBH25
*
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "dvb_frontend.h"
#include "lnbh25.h"
/**
* struct lnbh25_priv - LNBH25 driver private data
* @i2c: pointer to the I2C adapter structure
* @i2c_address: I2C address of LNBH25 SEC chip
* @config: Registers configuration:
* offset 0: 1st register address, always 0x02 (DATA1)
* offset 1: DATA1 register value
* offset 2: DATA2 register value
*/
struct lnbh25_priv {
struct i2c_adapter *i2c;
u8 i2c_address;
u8 config[3];
};
#define LNBH25_STATUS_OFL 0x1
#define LNBH25_STATUS_VMON 0x4
#define LNBH25_VSEL_13 0x03
#define LNBH25_VSEL_18 0x0a
static int lnbh25_read_vmon(struct lnbh25_priv *priv)
{
int i, ret;
u8 addr = 0x00;
u8 status[6];
struct i2c_msg msg[2] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = 1,
.buf = &addr
}, {
.addr = priv->i2c_address,
.flags = I2C_M_RD,
.len = sizeof(status),
.buf = status
}
};
for (i = 0; i < 2; i++) {
ret = i2c_transfer(priv->i2c, &msg[i], 1);
if (ret >= 0 && ret != 1)
ret = -EIO;
if (ret < 0) {
dev_dbg(&priv->i2c->dev,
"%s(): I2C transfer %d failed (%d)\n",
__func__, i, ret);
return ret;
}
}
print_hex_dump_bytes("lnbh25_read_vmon: ",
DUMP_PREFIX_OFFSET, status, sizeof(status));
if ((status[0] & (LNBH25_STATUS_OFL | LNBH25_STATUS_VMON)) != 0) {
dev_err(&priv->i2c->dev,
"%s(): voltage in failure state, status reg 0x%x\n",
__func__, status[0]);
return -EIO;
}
return 0;
}
static int lnbh25_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage voltage)
{
int ret;
u8 data1_reg;
const char *vsel;
struct lnbh25_priv *priv = fe->sec_priv;
struct i2c_msg msg = {
.addr = priv->i2c_address,
.flags = 0,
.len = sizeof(priv->config),
.buf = priv->config
};
switch (voltage) {
case SEC_VOLTAGE_OFF:
data1_reg = 0x00;
vsel = "Off";
break;
case SEC_VOLTAGE_13:
data1_reg = LNBH25_VSEL_13;
vsel = "13V";
break;
case SEC_VOLTAGE_18:
data1_reg = LNBH25_VSEL_18;
vsel = "18V";
break;
default:
return -EINVAL;
}
priv->config[1] = data1_reg;
dev_dbg(&priv->i2c->dev,
"%s(): %s, I2C 0x%x write [ %02x %02x %02x ]\n",
__func__, vsel, priv->i2c_address,
priv->config[0], priv->config[1], priv->config[2]);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret >= 0 && ret != 1)
ret = -EIO;
if (ret < 0) {
dev_err(&priv->i2c->dev, "%s(): I2C transfer error (%d)\n",
__func__, ret);
return ret;
}
if (voltage != SEC_VOLTAGE_OFF) {
msleep(120);
ret = lnbh25_read_vmon(priv);
} else {
msleep(20);
ret = 0;
}
return ret;
}
static void lnbh25_release(struct dvb_frontend *fe)
{
struct lnbh25_priv *priv = fe->sec_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
lnbh25_set_voltage(fe, SEC_VOLTAGE_OFF);
kfree(fe->sec_priv);
fe->sec_priv = NULL;
}
struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c)
{
struct lnbh25_priv *priv;
dev_dbg(&i2c->dev, "%s()\n", __func__);
priv = kzalloc(sizeof(struct lnbh25_priv), GFP_KERNEL);
if (!priv)
return NULL;
priv->i2c_address = (cfg->i2c_address >> 1);
priv->i2c = i2c;
priv->config[0] = 0x02;
priv->config[1] = 0x00;
priv->config[2] = cfg->data2_config;
fe->sec_priv = priv;
if (lnbh25_set_voltage(fe, SEC_VOLTAGE_OFF)) {
dev_err(&i2c->dev,
"%s(): no LNBH25 found at I2C addr 0x%02x\n",
__func__, priv->i2c_address);
kfree(priv);
fe->sec_priv = NULL;
return NULL;
}
fe->ops.release_sec = lnbh25_release;
fe->ops.set_voltage = lnbh25_set_voltage;
dev_err(&i2c->dev, "%s(): attached at I2C addr 0x%02x\n",
__func__, priv->i2c_address);
return fe;
}
EXPORT_SYMBOL(lnbh25_attach);
MODULE_DESCRIPTION("ST LNBH25 driver");
MODULE_AUTHOR("info@netup.ru");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,56 @@
/*
* lnbh25.c
*
* Driver for LNB supply and control IC LNBH25
*
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef LNBH25_H
#define LNBH25_H
#include <linux/i2c.h>
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
/* 22 kHz tone enabled. Tone output controlled by DSQIN pin */
#define LNBH25_TEN 0x01
/* Low power mode activated (used only with 22 kHz tone output disabled) */
#define LNBH25_LPM 0x02
/* DSQIN input pin is set to receive external 22 kHz TTL signal source */
#define LNBH25_EXTM 0x04
struct lnbh25_config {
u8 i2c_address;
u8 data2_config;
};
#if IS_REACHABLE(CONFIG_DVB_LNBH25)
struct dvb_frontend *lnbh25_attach(
struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c);
#else
static inline dvb_frontend *lnbh25_attach(
struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View File

@ -1495,7 +1495,6 @@ MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);
static struct i2c_driver m88ds3103_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "m88ds3103",
.suppress_bind_attrs = true,
},

View File

@ -915,7 +915,6 @@ MODULE_DEVICE_TABLE(i2c, rtl2830_id_table);
static struct i2c_driver rtl2830_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "rtl2830",
},
.probe = rtl2830_probe,

View File

@ -1319,7 +1319,6 @@ MODULE_DEVICE_TABLE(i2c, rtl2832_id_table);
static struct i2c_driver rtl2832_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "rtl2832",
},
.probe = rtl2832_probe,

View File

@ -1538,7 +1538,6 @@ static int rtl2832_sdr_remove(struct platform_device *pdev)
static struct platform_driver rtl2832_sdr_driver = {
.driver = {
.name = "rtl2832_sdr",
.owner = THIS_MODULE,
},
.probe = rtl2832_sdr_probe,
.remove = rtl2832_sdr_remove,

View File

@ -466,7 +466,7 @@ static int s921_tune(struct dvb_frontend *fe,
static int s921_get_algo(struct dvb_frontend *fe)
{
return 1; /* FE_ALGO_HW */
return DVBFE_ALGO_HW;
}
static void s921_release(struct dvb_frontend *fe)

View File

@ -757,7 +757,6 @@ MODULE_DEVICE_TABLE(i2c, si2168_id_table);
static struct i2c_driver si2168_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "si2168",
},
.probe = si2168_probe,

View File

@ -426,7 +426,6 @@ MODULE_DEVICE_TABLE(i2c, sp2_id);
static struct i2c_driver sp2_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "sp2",
},
.probe = sp2_probe,

View File

@ -791,11 +791,13 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
memcpy(buf + 2, data, len);
if (i2cdebug)
printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
state->config->demod_address, reg, buf[2]);
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
printk(KERN_ERR "%s: i2c write error!\n", __func__);
printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n",
__func__, state->config->demod_address, reg, buf[2]);
return (ret != 1) ? -EREMOTEIO : 0;
}
@ -829,10 +831,12 @@ static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
printk(KERN_ERR "%s: i2c read error\n", __func__);
printk(KERN_ERR "%s: i2c read error ([%02x] %02x: %02x)\n",
__func__, state->config->demod_address, reg, b1[0]);
if (i2cdebug)
printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
state->config->demod_address, reg, b1[0]);
return b1[0];
}
@ -1550,6 +1554,11 @@ static int stv0367ter_init(struct dvb_frontend *fe)
switch (state->config->xtal) {
/*set internal freq to 53.125MHz */
case 16000000:
stv0367_writereg(state, R367TER_PLLMDIV, 0x2);
stv0367_writereg(state, R367TER_PLLNDIV, 0x1b);
stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
break;
case 25000000:
stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
stv0367_writereg(state, R367TER_PLLNDIV, 0x55);

File diff suppressed because it is too large Load Diff

View File

@ -21,12 +21,11 @@
#ifndef TDA10071_H
#define TDA10071_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
/*
* I2C address
* 0x55,
* 0x05, 0x55,
*/
/**
@ -53,64 +52,4 @@ struct tda10071_platform_data {
struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
};
struct tda10071_config {
/* Demodulator I2C address.
* Default: none, must set
* Values: 0x55,
*/
u8 demod_i2c_addr;
/* Tuner I2C address.
* Default: none, must set
* Values: 0x14, 0x54, ...
*/
u8 tuner_i2c_addr;
/* Max bytes I2C provider can write at once.
* Note: Buffer is taken from the stack currently!
* Default: none, must set
* Values:
*/
u16 i2c_wr_max;
/* TS output mode.
* Default: TDA10071_TS_SERIAL
* Values:
*/
#define TDA10071_TS_SERIAL 0
#define TDA10071_TS_PARALLEL 1
u8 ts_mode;
/* Input spectrum inversion.
* Default: 0
* Values: 0, 1
*/
bool spec_inv;
/* Xtal frequency Hz
* Default: none, must set
* Values:
*/
u32 xtal;
/* PLL multiplier.
* Default: none, must set
* Values:
*/
u8 pll_multiplier;
};
#if IS_REACHABLE(CONFIG_DVB_TDA10071)
extern struct dvb_frontend *tda10071_attach(
const struct tda10071_config *config, struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *tda10071_attach(
const struct tda10071_config *config, struct i2c_adapter *i2c)
{
dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* TDA10071_H */

View File

@ -24,19 +24,27 @@
#include "dvb_frontend.h"
#include "tda10071.h"
#include <linux/firmware.h>
#include <linux/regmap.h>
struct tda10071_priv {
struct i2c_adapter *i2c;
struct tda10071_dev {
struct dvb_frontend fe;
struct i2c_client *client;
struct tda10071_config cfg;
struct regmap *regmap;
struct mutex cmd_execute_mutex;
u32 clk;
u16 i2c_wr_max;
u8 ts_mode;
bool spec_inv;
u8 pll_multiplier;
u8 tuner_i2c_addr;
u8 meas_count[2];
u32 ber;
u32 ucb;
u8 meas_count;
u32 dvbv3_ber;
enum fe_status fe_status;
enum fe_delivery_system delivery_system;
bool warm; /* FW running */
u64 post_bit_error;
u64 block_error;
};
static struct tda10071_modcod {

View File

@ -726,7 +726,6 @@ MODULE_DEVICE_TABLE(i2c, ts2020_id_table);
static struct i2c_driver ts2020_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ts2020",
},
.probe = ts2020_probe,

View File

@ -22,7 +22,7 @@ config VIDEO_IR_I2C
#
menu "Encoders, decoders, sensors and other helper chips"
visible if !MEDIA_SUBDRV_AUTOSELECT
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
comment "Audio decoders, processors and mixers"
@ -196,7 +196,8 @@ config VIDEO_ADV7183
config VIDEO_ADV7604
tristate "Analog Devices ADV7604 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && GPIOLIB
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
depends on GPIOLIB || COMPILE_TEST
select HDMI
---help---
Support for the Analog Devices ADV7604 video decoder.
@ -286,6 +287,16 @@ config VIDEO_SAA711X
To compile this driver as a module, choose M here: the
module will be called saa7115.
config VIDEO_TC358743
tristate "Toshiba TC358743 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
select HDMI
---help---
Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge.
To compile this driver as a module, choose M here: the
module will be called tc358743.
config VIDEO_TVP514X
tristate "Texas Instruments TVP514x video decoder"
depends on VIDEO_V4L2 && I2C

View File

@ -78,3 +78,4 @@ obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o

View File

@ -401,7 +401,6 @@ MODULE_DEVICE_TABLE(i2c, adv7170_id);
static struct i2c_driver adv7170_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7170",
},
.probe = adv7170_probe,

View File

@ -455,7 +455,6 @@ MODULE_DEVICE_TABLE(i2c, adv7175_id);
static struct i2c_driver adv7175_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7175",
},
.probe = adv7175_probe,

View File

@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <media/v4l2-ioctl.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
@ -1324,11 +1325,20 @@ static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
#define ADV7180_PM_OPS NULL
#endif
#ifdef CONFIG_OF
static const struct of_device_id adv7180_of_id[] = {
{ .compatible = "adi,adv7180", },
{ },
};
MODULE_DEVICE_TABLE(of, adv7180_of_id);
#endif
static struct i2c_driver adv7180_driver = {
.driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
.pm = ADV7180_PM_OPS,
.of_match_table = of_match_ptr(adv7180_of_id),
},
.probe = adv7180_probe,
.remove = adv7180_remove,

View File

@ -319,13 +319,6 @@ static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv7343_core_ops = {
.log_status = adv7343_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
@ -529,7 +522,6 @@ MODULE_DEVICE_TABLE(of, adv7343_of_match);
static struct i2c_driver adv7343_driver = {
.driver = {
.of_match_table = of_match_ptr(adv7343_of_match),
.owner = THIS_MODULE,
.name = "adv7343",
},
.probe = adv7343_probe,

View File

@ -306,13 +306,6 @@ static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv7393_core_ops = {
.log_status = adv7393_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static int adv7393_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)

View File

@ -40,7 +40,7 @@ MODULE_PARM_DESC(debug, "debug level (0-2)");
MODULE_DESCRIPTION("Analog Devices ADV7511 HDMI Transmitter Device Driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
#define MASK_ADV7511_EDID_RDY_INT 0x04
#define MASK_ADV7511_MSEN_INT 0x40
@ -1576,7 +1576,6 @@ MODULE_DEVICE_TABLE(i2c, adv7511_id);
static struct i2c_driver adv7511_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7511",
},
.probe = adv7511_probe,

View File

@ -37,10 +37,12 @@
#include <linux/v4l2-dv-timings.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/regmap.h>
#include <media/adv7604.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-of.h>
@ -81,6 +83,7 @@ MODULE_LICENSE("GPL");
enum adv76xx_type {
ADV7604,
ADV7611,
ADV7612,
};
struct adv76xx_reg_seq {
@ -188,6 +191,9 @@ struct adv76xx_state {
/* i2c clients */
struct i2c_client *i2c_clients[ADV76XX_PAGE_MAX];
/* Regmaps */
struct regmap *regmap[ADV76XX_PAGE_MAX];
/* controls */
struct v4l2_ctrl *detect_tx_5v_ctrl;
struct v4l2_ctrl *analog_sampling_phase_ctrl;
@ -373,66 +379,39 @@ static inline unsigned vtotal(const struct v4l2_bt_timings *t)
/* ----------------------------------------------------------------------- */
static s32 adv_smbus_read_byte_data_check(struct i2c_client *client,
u8 command, bool check)
static int adv76xx_read_check(struct adv76xx_state *state,
int client_page, u8 reg)
{
union i2c_smbus_data data;
if (!i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_READ, command,
I2C_SMBUS_BYTE_DATA, &data))
return data.byte;
if (check)
v4l_err(client, "error reading %02x, %02x\n",
client->addr, command);
return -EIO;
}
static s32 adv_smbus_read_byte_data(struct adv76xx_state *state,
enum adv76xx_page page, u8 command)
{
return adv_smbus_read_byte_data_check(state->i2c_clients[page],
command, true);
}
static s32 adv_smbus_write_byte_data(struct adv76xx_state *state,
enum adv76xx_page page, u8 command,
u8 value)
{
struct i2c_client *client = state->i2c_clients[page];
union i2c_smbus_data data;
struct i2c_client *client = state->i2c_clients[client_page];
int err;
int i;
unsigned int val;
data.byte = value;
for (i = 0; i < 3; i++) {
err = i2c_smbus_xfer(client->adapter, client->addr,
client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, &data);
if (!err)
break;
err = regmap_read(state->regmap[client_page], reg, &val);
if (err) {
v4l_err(client, "error reading %02x, %02x\n",
client->addr, reg);
return err;
}
if (err < 0)
v4l_err(client, "error writing %02x, %02x, %02x\n",
client->addr, command, value);
return err;
return val;
}
static s32 adv_smbus_write_i2c_block_data(struct adv76xx_state *state,
enum adv76xx_page page, u8 command,
unsigned length, const u8 *values)
/* adv76xx_write_block(): Write raw data with a maximum of I2C_SMBUS_BLOCK_MAX
* size to one or more registers.
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
static int adv76xx_write_block(struct adv76xx_state *state, int client_page,
unsigned int init_reg, const void *val,
size_t val_len)
{
struct i2c_client *client = state->i2c_clients[page];
union i2c_smbus_data data;
struct regmap *regmap = state->regmap[client_page];
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
data.block[0] = length;
memcpy(data.block + 1, values, length);
return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_I2C_BLOCK_DATA, &data);
if (val_len > I2C_SMBUS_BLOCK_MAX)
val_len = I2C_SMBUS_BLOCK_MAX;
return regmap_raw_write(regmap, init_reg, val, val_len);
}
/* ----------------------------------------------------------------------- */
@ -441,14 +420,14 @@ static inline int io_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_IO, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_IO, reg);
}
static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_IO, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_IO], reg, val);
}
static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -460,71 +439,70 @@ static inline int avlink_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV7604_PAGE_AVLINK, reg);
return adv76xx_read_check(state, ADV7604_PAGE_AVLINK, reg);
}
static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV7604_PAGE_AVLINK, reg, val);
return regmap_write(state->regmap[ADV7604_PAGE_AVLINK], reg, val);
}
static inline int cec_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_CEC, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_CEC, reg);
}
static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_CEC, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_CEC], reg, val);
}
static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_INFOFRAME, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_INFOFRAME, reg);
}
static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_INFOFRAME,
reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_INFOFRAME], reg, val);
}
static inline int afe_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_AFE, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_AFE, reg);
}
static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_AFE, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_AFE], reg, val);
}
static inline int rep_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_REP, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_REP, reg);
}
static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_REP, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_REP], reg, val);
}
static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -536,28 +514,37 @@ static inline int edid_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_EDID, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_EDID, reg);
}
static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_EDID, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_EDID], reg, val);
}
static inline int edid_write_block(struct v4l2_subdev *sd,
unsigned len, const u8 *val)
unsigned int total_len, const u8 *val)
{
struct adv76xx_state *state = to_state(sd);
int err = 0;
int i;
int i = 0;
int len = 0;
v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len);
v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n",
__func__, total_len);
while (!err && i < total_len) {
len = (total_len - i) > I2C_SMBUS_BLOCK_MAX ?
I2C_SMBUS_BLOCK_MAX :
(total_len - i);
err = adv76xx_write_block(state, ADV76XX_PAGE_EDID,
i, val + i, len);
i += len;
}
for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX)
err = adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_EDID,
i, I2C_SMBUS_BLOCK_MAX, val + i);
return err;
}
@ -587,7 +574,7 @@ static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_HDMI, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_HDMI, reg);
}
static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask)
@ -599,7 +586,7 @@ static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_HDMI, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_HDMI], reg, val);
}
static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -611,14 +598,14 @@ static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_TEST, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_TEST], reg, val);
}
static inline int cp_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_CP, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_CP, reg);
}
static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask)
@ -630,7 +617,7 @@ static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_CP, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_CP], reg, val);
}
static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -642,14 +629,14 @@ static inline int vdp_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV7604_PAGE_VDP, reg);
return adv76xx_read_check(state, ADV7604_PAGE_VDP, reg);
}
static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV7604_PAGE_VDP, reg, val);
return regmap_write(state->regmap[ADV7604_PAGE_VDP], reg, val);
}
#define ADV76XX_REG(page, offset) (((page) << 8) | (offset))
@ -660,13 +647,16 @@ static int adv76xx_read_reg(struct v4l2_subdev *sd, unsigned int reg)
{
struct adv76xx_state *state = to_state(sd);
unsigned int page = reg >> 8;
unsigned int val;
int err;
if (!(BIT(page) & state->info->page_mask))
return -EINVAL;
reg &= 0xff;
err = regmap_read(state->regmap[page], reg, &val);
return adv_smbus_read_byte_data(state, page, reg);
return err ? err : val;
}
#endif
@ -680,7 +670,7 @@ static int adv76xx_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val)
reg &= 0xff;
return adv_smbus_write_byte_data(state, page, reg, val);
return regmap_write(state->regmap[page], reg, val);
}
static void adv76xx_write_reg_seq(struct v4l2_subdev *sd,
@ -766,6 +756,23 @@ static const struct adv76xx_format_info adv7611_formats[] = {
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT },
};
static const struct adv76xx_format_info adv7612_formats[] = {
{ MEDIA_BUS_FMT_RGB888_1X24, ADV76XX_OP_CH_SEL_RGB, true, false,
ADV76XX_OP_MODE_SEL_SDR_444 | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YUYV8_2X8, ADV76XX_OP_CH_SEL_RGB, false, false,
ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YVYU8_2X8, ADV76XX_OP_CH_SEL_RGB, false, true,
ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_UYVY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, false,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_VYUY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, true,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YUYV8_1X16, ADV76XX_OP_CH_SEL_RGB, false, false,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YVYU8_1X16, ADV76XX_OP_CH_SEL_RGB, false, true,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
};
static const struct adv76xx_format_info *
adv76xx_format_info(struct adv76xx_state *state, u32 code)
{
@ -870,6 +877,16 @@ static unsigned int adv7611_read_cable_det(struct v4l2_subdev *sd)
return value & 1;
}
static unsigned int adv7612_read_cable_det(struct v4l2_subdev *sd)
{
/* Reads CABLE_DET_A_RAW. For input B support, need to
* account for bit 7 [MSB] of 0x6a (ie. CABLE_DET_B_RAW)
*/
u8 value = io_read(sd, 0x6f);
return value & 1;
}
static int adv76xx_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
{
struct adv76xx_state *state = to_state(sd);
@ -976,8 +993,8 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
/* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
/* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
/* IO-map reg. 0x16 and 0x17 should be written in sequence */
if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_IO,
0x16, 2, pll))
if (regmap_raw_write(state->regmap[ADV76XX_PAGE_IO],
0x16, pll, 2))
v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
/* active video - horizontal timing */
@ -1028,8 +1045,8 @@ static void adv76xx_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 off
offset_buf[3] = offset_c & 0x0ff;
/* Registers must be written in this order with no i2c access in between */
if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_CP,
0x77, 4, offset_buf))
if (regmap_raw_write(state->regmap[ADV76XX_PAGE_CP],
0x77, offset_buf, 4))
v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__);
}
@ -1058,8 +1075,8 @@ static void adv76xx_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a,
gain_buf[3] = ((gain_c & 0x0ff));
/* Registers must be written in this order with no i2c access in between */
if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_CP,
0x73, 4, gain_buf))
if (regmap_raw_write(state->regmap[ADV76XX_PAGE_CP],
0x73, gain_buf, 4))
v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__);
}
@ -1328,7 +1345,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
}
}
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
false, timings))
@ -1760,8 +1777,8 @@ static int adv76xx_s_routing(struct v4l2_subdev *sd,
select_input(sd);
enable_input(sd);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv76xx_ev_fmt);
v4l2_subdev_notify_event(sd, &adv76xx_ev_fmt);
return 0;
}
@ -1928,8 +1945,7 @@ static int adv76xx_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
"%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n",
__func__, fmt_change, fmt_change_digital);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv76xx_ev_fmt);
v4l2_subdev_notify_event(sd, &adv76xx_ev_fmt);
if (handled)
*handled = true;
@ -2347,6 +2363,20 @@ static int adv76xx_log_status(struct v4l2_subdev *sd)
return 0;
}
static int adv76xx_subscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
switch (sub->type) {
case V4L2_EVENT_SOURCE_CHANGE:
return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
case V4L2_EVENT_CTRL:
return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
default:
return -EINVAL;
}
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops adv76xx_ctrl_ops = {
@ -2356,6 +2386,8 @@ static const struct v4l2_ctrl_ops adv76xx_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv76xx_core_ops = {
.log_status = adv76xx_log_status,
.interrupt_service_routine = adv76xx_isr,
.subscribe_event = adv76xx_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv76xx_g_register,
.s_register = adv76xx_s_register,
@ -2510,6 +2542,11 @@ static void adv7611_setup_irqs(struct v4l2_subdev *sd)
io_write(sd, 0x41, 0xd0); /* STDI irq for any change, disable INT2 */
}
static void adv7612_setup_irqs(struct v4l2_subdev *sd)
{
io_write(sd, 0x41, 0xd0); /* disable INT2 */
}
static void adv76xx_unregister_clients(struct adv76xx_state *state)
{
unsigned int i;
@ -2597,6 +2634,19 @@ static const struct adv76xx_reg_seq adv7611_recommended_settings_hdmi[] = {
{ ADV76XX_REG_SEQ_TERM, 0 },
};
static const struct adv76xx_reg_seq adv7612_recommended_settings_hdmi[] = {
{ ADV76XX_REG(ADV76XX_PAGE_CP, 0x6c), 0x00 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x9b), 0x03 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x6f), 0x08 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x85), 0x1f },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x87), 0x70 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x57), 0xda },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x58), 0x01 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x03), 0x98 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x4c), 0x44 },
{ ADV76XX_REG_SEQ_TERM, 0 },
};
static const struct adv76xx_chip_info adv76xx_chip_info[] = {
[ADV7604] = {
.type = ADV7604,
@ -2685,17 +2735,60 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = {
.field1_vsync_mask = 0x3fff,
.field1_vbackporch_mask = 0x3fff,
},
[ADV7612] = {
.type = ADV7612,
.has_afe = false,
.max_port = ADV76XX_PAD_HDMI_PORT_A, /* B not supported */
.num_dv_ports = 1, /* normally 2 */
.edid_enable_reg = 0x74,
.edid_status_reg = 0x76,
.lcf_reg = 0xa3,
.tdms_lock_mask = 0x43,
.cable_det_mask = 0x01,
.fmt_change_digital_mask = 0x03,
.cp_csc = 0xf4,
.formats = adv7612_formats,
.nformats = ARRAY_SIZE(adv7612_formats),
.set_termination = adv7611_set_termination,
.setup_irqs = adv7612_setup_irqs,
.read_hdmi_pixelclock = adv7611_read_hdmi_pixelclock,
.read_cable_det = adv7612_read_cable_det,
.recommended_settings = {
[1] = adv7612_recommended_settings_hdmi,
},
.num_recommended_settings = {
[1] = ARRAY_SIZE(adv7612_recommended_settings_hdmi),
},
.page_mask = BIT(ADV76XX_PAGE_IO) | BIT(ADV76XX_PAGE_CEC) |
BIT(ADV76XX_PAGE_INFOFRAME) | BIT(ADV76XX_PAGE_AFE) |
BIT(ADV76XX_PAGE_REP) | BIT(ADV76XX_PAGE_EDID) |
BIT(ADV76XX_PAGE_HDMI) | BIT(ADV76XX_PAGE_CP),
.linewidth_mask = 0x1fff,
.field0_height_mask = 0x1fff,
.field1_height_mask = 0x1fff,
.hfrontporch_mask = 0x1fff,
.hsync_mask = 0x1fff,
.hbackporch_mask = 0x1fff,
.field0_vfrontporch_mask = 0x3fff,
.field0_vsync_mask = 0x3fff,
.field0_vbackporch_mask = 0x3fff,
.field1_vfrontporch_mask = 0x3fff,
.field1_vsync_mask = 0x3fff,
.field1_vbackporch_mask = 0x3fff,
},
};
static const struct i2c_device_id adv76xx_i2c_id[] = {
{ "adv7604", (kernel_ulong_t)&adv76xx_chip_info[ADV7604] },
{ "adv7611", (kernel_ulong_t)&adv76xx_chip_info[ADV7611] },
{ "adv7612", (kernel_ulong_t)&adv76xx_chip_info[ADV7612] },
{ }
};
MODULE_DEVICE_TABLE(i2c, adv76xx_i2c_id);
static const struct of_device_id adv76xx_of_id[] __maybe_unused = {
{ .compatible = "adi,adv7611", .data = &adv76xx_chip_info[ADV7611] },
{ .compatible = "adi,adv7612", .data = &adv76xx_chip_info[ADV7612] },
{ }
};
MODULE_DEVICE_TABLE(of, adv76xx_of_id);
@ -2706,6 +2799,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
struct device_node *endpoint;
struct device_node *np;
unsigned int flags;
u32 v;
np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
@ -2715,6 +2809,12 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
return -EINVAL;
v4l2_of_parse_endpoint(endpoint, &bus_cfg);
if (!of_property_read_u32(endpoint, "default-input", &v))
state->pdata.default_input = v;
else
state->pdata.default_input = -1;
of_node_put(endpoint);
flags = bus_cfg.bus.parallel.flags;
@ -2753,7 +2853,6 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
/* Hardcode the remaining platform data fields. */
state->pdata.disable_pwrdnb = 0;
state->pdata.disable_cable_det_rst = 0;
state->pdata.default_input = -1;
state->pdata.blank_data = 1;
state->pdata.alt_data_sat = 1;
state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0;
@ -2762,6 +2861,148 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
return 0;
}
static const struct regmap_config adv76xx_regmap_cnf[] = {
{
.name = "io",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "avlink",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "cec",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "infoframe",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "esdp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "epp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "afe",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "rep",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "edid",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "hdmi",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "test",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "cp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "vdp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
};
static int configure_regmap(struct adv76xx_state *state, int region)
{
int err;
if (!state->i2c_clients[region])
return -ENODEV;
state->regmap[region] =
devm_regmap_init_i2c(state->i2c_clients[region],
&adv76xx_regmap_cnf[region]);
if (IS_ERR(state->regmap[region])) {
err = PTR_ERR(state->regmap[region]);
v4l_err(state->i2c_clients[region],
"Error initializing regmap %d with error %d\n",
region, err);
return -EINVAL;
}
return 0;
}
static int configure_regmaps(struct adv76xx_state *state)
{
int i, err;
for (i = ADV7604_PAGE_AVLINK ; i < ADV76XX_PAGE_MAX; i++) {
err = configure_regmap(state, i);
if (err && (err != -ENODEV))
return err;
}
return 0;
}
static int adv76xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@ -2771,7 +3012,7 @@ static int adv76xx_probe(struct i2c_client *client,
struct v4l2_ctrl_handler *hdl;
struct v4l2_subdev *sd;
unsigned int i;
u16 val;
unsigned int val, val2;
int err;
/* Check if the adapter supports the needed features */
@ -2833,28 +3074,59 @@ static int adv76xx_probe(struct i2c_client *client,
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
id->name, i2c_adapter_id(client->adapter),
client->addr);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
/* Configure IO Regmap region */
err = configure_regmap(state, ADV76XX_PAGE_IO);
if (err) {
v4l2_err(sd, "Error configuring IO regmap region\n");
return -ENODEV;
}
/*
* Verify that the chip is present. On ADV7604 the RD_INFO register only
* identifies the revision, while on ADV7611 it identifies the model as
* well. Use the HDMI slave address on ADV7604 and RD_INFO on ADV7611.
*/
if (state->info->type == ADV7604) {
val = adv_smbus_read_byte_data_check(client, 0xfb, false);
switch (state->info->type) {
case ADV7604:
err = regmap_read(state->regmap[ADV76XX_PAGE_IO], 0xfb, &val);
if (err) {
v4l2_err(sd, "Error %d reading IO Regmap\n", err);
return -ENODEV;
}
if (val != 0x68) {
v4l2_info(sd, "not an adv7604 on address 0x%x\n",
v4l2_err(sd, "not an adv7604 on address 0x%x\n",
client->addr << 1);
return -ENODEV;
}
} else {
val = (adv_smbus_read_byte_data_check(client, 0xea, false) << 8)
| (adv_smbus_read_byte_data_check(client, 0xeb, false) << 0);
if (val != 0x2051) {
v4l2_info(sd, "not an adv7611 on address 0x%x\n",
break;
case ADV7611:
case ADV7612:
err = regmap_read(state->regmap[ADV76XX_PAGE_IO],
0xea,
&val);
if (err) {
v4l2_err(sd, "Error %d reading IO Regmap\n", err);
return -ENODEV;
}
val2 = val << 8;
err = regmap_read(state->regmap[ADV76XX_PAGE_IO],
0xeb,
&val);
if (err) {
v4l2_err(sd, "Error %d reading IO Regmap\n", err);
return -ENODEV;
}
val |= val2;
if ((state->info->type == ADV7611 && val != 0x2051) ||
(state->info->type == ADV7612 && val != 0x2041)) {
v4l2_err(sd, "not an adv761x on address 0x%x\n",
client->addr << 1);
return -ENODEV;
}
break;
}
/* control handlers */
@ -2941,6 +3213,11 @@ static int adv76xx_probe(struct i2c_client *client,
if (err)
goto err_work_queues;
/* Configure regmaps */
err = configure_regmaps(state);
if (err)
goto err_entity;
err = adv76xx_core_init(sd);
if (err)
goto err_entity;
@ -2985,7 +3262,6 @@ static int adv76xx_remove(struct i2c_client *client)
static struct i2c_driver adv76xx_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7604",
.of_match_table = of_match_ptr(adv76xx_of_id),
},

View File

@ -40,6 +40,7 @@
#include <linux/v4l2-dv-timings.h>
#include <linux/hdmi.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/adv7842.h>
@ -1442,7 +1443,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
}
}
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
false, timings))
@ -1980,8 +1981,7 @@ static int adv7842_s_routing(struct v4l2_subdev *sd,
select_input(sd, state->vid_std_select);
enable_input(sd);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv7842_ev_fmt);
v4l2_subdev_notify_event(sd, &adv7842_ev_fmt);
return 0;
}
@ -2214,8 +2214,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
"%s: fmt_change_cp = 0x%x, fmt_change_digital = 0x%x, fmt_change_sdp = 0x%x\n",
__func__, fmt_change_cp, fmt_change_digital,
fmt_change_sdp);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv7842_ev_fmt);
v4l2_subdev_notify_event(sd, &adv7842_ev_fmt);
if (handled)
*handled = true;
}
@ -3005,6 +3004,20 @@ static long adv7842_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
return -ENOTTY;
}
static int adv7842_subscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
switch (sub->type) {
case V4L2_EVENT_SOURCE_CHANGE:
return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
case V4L2_EVENT_CTRL:
return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
default:
return -EINVAL;
}
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops adv7842_ctrl_ops = {
@ -3015,6 +3028,8 @@ static const struct v4l2_subdev_core_ops adv7842_core_ops = {
.log_status = adv7842_log_status,
.ioctl = adv7842_ioctl,
.interrupt_service_routine = adv7842_isr,
.subscribe_event = adv7842_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv7842_g_register,
.s_register = adv7842_s_register,
@ -3210,7 +3225,7 @@ static int adv7842_probe(struct i2c_client *client,
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv7842_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
state->mode = pdata->mode;
state->hdmi_port_a = pdata->input == ADV7842_SELECT_HDMI_PORT_A;
@ -3348,7 +3363,6 @@ MODULE_DEVICE_TABLE(i2c, adv7842_id);
static struct i2c_driver adv7842_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7842",
},
.probe = adv7842_probe,

View File

@ -156,12 +156,12 @@ static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
} else if (std == V4L2_STD_PAL_60) {
vp1 = 7;
ak881x->lines = 480;
} else if (std && !(std & ~V4L2_STD_PAL)) {
vp1 = 0xf;
ak881x->lines = 576;
} else if (std && !(std & ~V4L2_STD_NTSC)) {
} else if (std & V4L2_STD_NTSC) {
vp1 = 0;
ak881x->lines = 480;
} else if (std & V4L2_STD_PAL) {
vp1 = 0xf;
ak881x->lines = 576;
} else {
/* No SECAM or PAL_N/Nc supported */
return -EINVAL;

View File

@ -379,16 +379,6 @@ static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
.s_ctrl = bt819_s_ctrl,
};
static const struct v4l2_subdev_core_ops bt819_core_ops = {
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops bt819_video_ops = {
.s_std = bt819_s_std,
.s_routing = bt819_s_routing,
@ -398,7 +388,6 @@ static const struct v4l2_subdev_video_ops bt819_video_ops = {
};
static const struct v4l2_subdev_ops bt819_ops = {
.core = &bt819_core_ops,
.video = &bt819_video_ops,
};
@ -492,7 +481,6 @@ MODULE_DEVICE_TABLE(i2c, bt819_id);
static struct i2c_driver bt819_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "bt819",
},
.probe = bt819_probe,

View File

@ -252,7 +252,6 @@ MODULE_DEVICE_TABLE(i2c, bt856_id);
static struct i2c_driver bt856_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "bt856",
},
.probe = bt856_probe,

View File

@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE(i2c, bt866_id);
static struct i2c_driver bt866_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "bt866",
},
.probe = bt866_probe,

View File

@ -132,13 +132,6 @@ static const struct v4l2_ctrl_ops cs5345_ctrl_ops = {
static const struct v4l2_subdev_core_ops cs5345_core_ops = {
.log_status = cs5345_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cs5345_g_register,
.s_register = cs5345_s_register,
@ -218,7 +211,6 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id);
static struct i2c_driver cs5345_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cs5345",
},
.probe = cs5345_probe,

View File

@ -228,7 +228,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
static struct i2c_driver cs53l32a_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cs53l32a",
},
.probe = cs53l32a_probe,

View File

@ -5348,7 +5348,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id);
static struct i2c_driver cx25840_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cx25840",
},
.probe = cx25840_probe,

View File

@ -478,6 +478,7 @@ static const struct i2c_device_id ir_kbd_id[] = {
{ "ir_rx_z8f0811_hdpvr", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
static struct i2c_driver ir_kbd_driver = {
.driver = {

View File

@ -708,7 +708,6 @@ MODULE_DEVICE_TABLE(i2c, ks0127_id);
static struct i2c_driver ks0127_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ks0127",
},
.probe = ks0127_probe,

View File

@ -185,7 +185,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
static struct i2c_driver m52790_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "m52790",
},
.probe = m52790_probe,

View File

@ -894,7 +894,6 @@ MODULE_DEVICE_TABLE(i2c, msp_id);
static struct i2c_driver msp_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "msp3400",
.pm = &msp3400_pm_ops,
},

View File

@ -583,7 +583,6 @@ MODULE_DEVICE_TABLE(i2c, mt9v011_id);
static struct i2c_driver mt9v011_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "mt9v011",
},
.probe = mt9v011_probe,

View File

@ -882,7 +882,7 @@ static const struct regmap_config mt9v032_regmap_config = {
static struct mt9v032_platform_data *
mt9v032_get_pdata(struct i2c_client *client)
{
struct mt9v032_platform_data *pdata;
struct mt9v032_platform_data *pdata = NULL;
struct v4l2_of_endpoint endpoint;
struct device_node *np;
struct property *prop;

View File

@ -909,7 +909,6 @@ static void ov2659_pll_calc_params(struct ov2659 *ov2659)
u8 ctrl1_reg = 0, ctrl2_reg = 0, ctrl3_reg = 0;
struct i2c_client *client = ov2659->client;
unsigned int desired = pdata->link_frequency;
u32 s_prediv = 1, s_postdiv = 1, s_mult = 1;
u32 prediv, postdiv, mult;
u32 bestdelta = -1;
u32 delta, actual;
@ -929,9 +928,6 @@ static void ov2659_pll_calc_params(struct ov2659 *ov2659)
if ((delta < bestdelta) || (bestdelta == -1)) {
bestdelta = delta;
s_mult = mult;
s_prediv = prediv;
s_postdiv = postdiv;
ctrl1_reg = ctrl1[i].reg;
ctrl2_reg = mult;
ctrl3_reg = ctrl3[j].reg;

View File

@ -94,7 +94,6 @@ MODULE_DEVICE_TABLE(i2c, ov7640_id);
static struct i2c_driver ov7640_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ov7640",
},
.probe = ov7640_probe,

View File

@ -1674,7 +1674,6 @@ MODULE_DEVICE_TABLE(i2c, ov7670_id);
static struct i2c_driver ov7670_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ov7670",
},
.probe = ov7670_probe,

View File

@ -1436,7 +1436,7 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd)
int ret;
mutex_lock(&ov965x->lock);
__ov965x_set_power(ov965x, 1);
__ov965x_set_power(ov965x, 1);
usleep_range(25000, 26000);
/* Check sensor revision */

View File

@ -149,7 +149,6 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
spidrv->remove = s5c73m3_spi_remove;
spidrv->probe = s5c73m3_spi_probe;
spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
spidrv->driver.bus = &spi_bus_type;
spidrv->driver.owner = THIS_MODULE;
spidrv->driver.of_match_table = s5c73m3_spi_ids;

View File

@ -363,6 +363,7 @@ static int s5k6a3_remove(struct i2c_client *client)
static const struct i2c_device_id s5k6a3_ids[] = {
{ }
};
MODULE_DEVICE_TABLE(i2c, s5k6a3_ids);
#ifdef CONFIG_OF
static const struct of_device_id s5k6a3_of_match[] = {

View File

@ -301,9 +301,7 @@ static void saa6588_i2c_poll(struct saa6588 *s)
first and the last of the 3 bytes block.
*/
tmp = tmpbuf[2];
tmpbuf[2] = tmpbuf[0];
tmpbuf[0] = tmp;
swap(tmpbuf[2], tmpbuf[0]);
/* Map 'Invalid block E' to 'Invalid Block' */
if (blocknum == 6)
@ -520,7 +518,6 @@ MODULE_DEVICE_TABLE(i2c, saa6588_id);
static struct i2c_driver saa6588_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa6588",
},
.probe = saa6588_probe,

View File

@ -793,7 +793,6 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
static struct i2c_driver saa6752hs_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa6752hs",
},
.probe = saa6752hs_probe,

View File

@ -357,16 +357,6 @@ static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
.s_ctrl = saa7110_s_ctrl,
};
static const struct v4l2_subdev_core_ops saa7110_core_ops = {
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops saa7110_video_ops = {
.s_std = saa7110_s_std,
.s_routing = saa7110_s_routing,
@ -376,7 +366,6 @@ static const struct v4l2_subdev_video_ops saa7110_video_ops = {
};
static const struct v4l2_subdev_ops saa7110_ops = {
.core = &saa7110_core_ops,
.video = &saa7110_video_ops,
};
@ -472,7 +461,6 @@ MODULE_DEVICE_TABLE(i2c, saa7110_id);
static struct i2c_driver saa7110_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7110",
},
.probe = saa7110_probe,

View File

@ -1929,7 +1929,6 @@ MODULE_DEVICE_TABLE(i2c, saa711x_id);
static struct i2c_driver saa711x_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7115",
},
.probe = saa711x_probe,

View File

@ -822,7 +822,6 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id);
static struct i2c_driver saa7127_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7127",
},
.probe = saa7127_probe,

View File

@ -1204,13 +1204,6 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = {
.g_register = saa717x_g_register,
.s_register = saa717x_s_register,
#endif
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.log_status = saa717x_log_status,
};
@ -1363,7 +1356,6 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
static struct i2c_driver saa717x_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa717x",
},
.probe = saa717x_probe,

View File

@ -356,7 +356,6 @@ MODULE_DEVICE_TABLE(i2c, saa7185_id);
static struct i2c_driver saa7185_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7185",
},
.probe = saa7185_probe,

View File

@ -104,22 +104,22 @@ struct mt9t112_priv {
static const struct mt9t112_format mt9t112_cfmts[] = {
{
.code = MEDIA_BUS_FMT_UYVY8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 0,
}, {
.code = MEDIA_BUS_FMT_VYUY8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 1,
}, {
.code = MEDIA_BUS_FMT_YUYV8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 2,
}, {
.code = MEDIA_BUS_FMT_YVYU8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 3,
}, {

View File

@ -510,13 +510,39 @@ static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
const unsigned hact = 720;
const unsigned hdelay = 15;
unsigned vact;
unsigned vdelay;
int ret;
if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
return -EINVAL;
priv->norm = norm;
if (norm & V4L2_STD_525_60) {
vact = 240;
vdelay = 18;
ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
} else {
vact = 288;
vdelay = 24;
ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
}
if (!ret)
ret = i2c_smbus_write_byte_data(client, CROP_HI,
((vdelay >> 2) & 0xc0) |
((vact >> 4) & 0x30) |
((hdelay >> 6) & 0x0c) |
((hact >> 8) & 0x03));
if (!ret)
ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
vdelay & 0xff);
if (!ret)
ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
vact & 0xff);
return 0;
return ret;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
@ -711,7 +737,7 @@ static int tw9910_get_fmt(struct v4l2_subdev *sd,
mf->width = priv->scale->width;
mf->height = priv->scale->height;
mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
mf->field = V4L2_FIELD_INTERLACED_BT;
return 0;
@ -732,7 +758,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
return -EINVAL;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
ret = tw9910_set_frame(sd, &width, &height);
if (!ret) {
@ -762,7 +788,7 @@ static int tw9910_set_fmt(struct v4l2_subdev *sd,
}
mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
/*
* select suitable norm
@ -820,6 +846,7 @@ static int tw9910_video_probe(struct i2c_client *client)
"tw9910 Product ID %0x:%0x\n", id, priv->revision);
priv->norm = V4L2_STD_NTSC;
priv->scale = &tw9910_ntsc_scales[0];
done:
tw9910_s_power(&priv->subdev, 0);

View File

@ -388,7 +388,6 @@ MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
static struct i2c_driver sony_btf_mpx_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "sony-btf-mpx",
},
.probe = sony_btf_mpx_probe,

View File

@ -489,18 +489,14 @@ static int sr030pc30_get_fmt(struct v4l2_subdev *sd,
{
struct v4l2_mbus_framefmt *mf;
struct sr030pc30_info *info = to_sr030pc30(sd);
int ret;
if (!format || format->pad)
return -EINVAL;
mf = &format->format;
if (!info->curr_win || !info->curr_fmt) {
ret = sr030pc30_set_params(sd);
if (ret)
return ret;
}
if (!info->curr_win || !info->curr_fmt)
return -EINVAL;
mf->width = info->curr_win->width;
mf->height = info->curr_win->height;
@ -636,13 +632,6 @@ static const struct v4l2_ctrl_ops sr030pc30_ctrl_ops = {
static const struct v4l2_subdev_core_ops sr030pc30_core_ops = {
.s_power = sr030pc30_s_power,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_pad_ops sr030pc30_pad_ops = {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,681 @@
/*
* tc358743 - Toshiba HDMI to CSI-2 bridge - register names and bit masks
*
* Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights
* reserved.
*
* This program is free software; you may redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
/*
* References (c = chapter, p = page):
* REF_01 - Toshiba, TC358743XBG (H2C), Functional Specification, Rev 0.60
*/
/* Bit masks has prefix 'MASK_' and options after '_'. */
#ifndef __TC358743_REGS_H
#define __TC358743_REGS_H
#define CHIPID 0x0000
#define MASK_CHIPID 0xff00
#define MASK_REVID 0x00ff
#define SYSCTL 0x0002
#define MASK_IRRST 0x0800
#define MASK_CECRST 0x0400
#define MASK_CTXRST 0x0200
#define MASK_HDMIRST 0x0100
#define MASK_SLEEP 0x0001
#define CONFCTL 0x0004
#define MASK_PWRISO 0x8000
#define MASK_ACLKOPT 0x1000
#define MASK_AUDCHNUM 0x0c00
#define MASK_AUDCHNUM_8 0x0000
#define MASK_AUDCHNUM_6 0x0400
#define MASK_AUDCHNUM_4 0x0800
#define MASK_AUDCHNUM_2 0x0c00
#define MASK_AUDCHSEL 0x0200
#define MASK_I2SDLYOPT 0x0100
#define MASK_YCBCRFMT 0x00c0
#define MASK_YCBCRFMT_444 0x0000
#define MASK_YCBCRFMT_422_12_BIT 0x0040
#define MASK_YCBCRFMT_COLORBAR 0x0080
#define MASK_YCBCRFMT_422_8_BIT 0x00c0
#define MASK_INFRMEN 0x0020
#define MASK_AUDOUTSEL 0x0018
#define MASK_AUDOUTSEL_CSI 0x0000
#define MASK_AUDOUTSEL_I2S 0x0010
#define MASK_AUDOUTSEL_TDM 0x0018
#define MASK_AUTOINDEX 0x0004
#define MASK_ABUFEN 0x0002
#define MASK_VBUFEN 0x0001
#define FIFOCTL 0x0006
#define INTSTATUS 0x0014
#define MASK_AMUTE_INT 0x0400
#define MASK_HDMI_INT 0x0200
#define MASK_CSI_INT 0x0100
#define MASK_SYS_INT 0x0020
#define MASK_CEC_EINT 0x0010
#define MASK_CEC_TINT 0x0008
#define MASK_CEC_RINT 0x0004
#define MASK_IR_EINT 0x0002
#define MASK_IR_DINT 0x0001
#define INTMASK 0x0016
#define MASK_AMUTE_MSK 0x0400
#define MASK_HDMI_MSK 0x0200
#define MASK_CSI_MSK 0x0100
#define MASK_SYS_MSK 0x0020
#define MASK_CEC_EMSK 0x0010
#define MASK_CEC_TMSK 0x0008
#define MASK_CEC_RMSK 0x0004
#define MASK_IR_EMSK 0x0002
#define MASK_IR_DMSK 0x0001
#define INTFLAG 0x0018
#define INTSYSSTATUS 0x001A
#define PLLCTL0 0x0020
#define MASK_PLL_PRD 0xf000
#define SET_PLL_PRD(prd) ((((prd) - 1) << 12) &\
MASK_PLL_PRD)
#define MASK_PLL_FBD 0x01ff
#define SET_PLL_FBD(fbd) (((fbd) - 1) & MASK_PLL_FBD)
#define PLLCTL1 0x0022
#define MASK_PLL_FRS 0x0c00
#define SET_PLL_FRS(frs) (((frs) << 10) & MASK_PLL_FRS)
#define MASK_PLL_LBWS 0x0300
#define MASK_LFBREN 0x0040
#define MASK_BYPCKEN 0x0020
#define MASK_CKEN 0x0010
#define MASK_RESETB 0x0002
#define MASK_PLL_EN 0x0001
#define CLW_CNTRL 0x0140
#define MASK_CLW_LANEDISABLE 0x0001
#define D0W_CNTRL 0x0144
#define MASK_D0W_LANEDISABLE 0x0001
#define D1W_CNTRL 0x0148
#define MASK_D1W_LANEDISABLE 0x0001
#define D2W_CNTRL 0x014C
#define MASK_D2W_LANEDISABLE 0x0001
#define D3W_CNTRL 0x0150
#define MASK_D3W_LANEDISABLE 0x0001
#define STARTCNTRL 0x0204
#define MASK_START 0x00000001
#define LINEINITCNT 0x0210
#define LPTXTIMECNT 0x0214
#define TCLK_HEADERCNT 0x0218
#define TCLK_TRAILCNT 0x021C
#define THS_HEADERCNT 0x0220
#define TWAKEUP 0x0224
#define TCLK_POSTCNT 0x0228
#define THS_TRAILCNT 0x022C
#define HSTXVREGCNT 0x0230
#define HSTXVREGEN 0x0234
#define MASK_D3M_HSTXVREGEN 0x0010
#define MASK_D2M_HSTXVREGEN 0x0008
#define MASK_D1M_HSTXVREGEN 0x0004
#define MASK_D0M_HSTXVREGEN 0x0002
#define MASK_CLM_HSTXVREGEN 0x0001
#define TXOPTIONCNTRL 0x0238
#define MASK_CONTCLKMODE 0x00000001
#define CSI_CONTROL 0x040C
#define MASK_CSI_MODE 0x8000
#define MASK_HTXTOEN 0x0400
#define MASK_TXHSMD 0x0080
#define MASK_HSCKMD 0x0020
#define MASK_NOL 0x0006
#define MASK_NOL_1 0x0000
#define MASK_NOL_2 0x0002
#define MASK_NOL_3 0x0004
#define MASK_NOL_4 0x0006
#define MASK_EOTDIS 0x0001
#define CSI_INT 0x0414
#define MASK_INTHLT 0x00000008
#define MASK_INTER 0x00000004
#define CSI_INT_ENA 0x0418
#define MASK_IENHLT 0x00000008
#define MASK_IENER 0x00000004
#define CSI_ERR 0x044C
#define MASK_INER 0x00000200
#define MASK_WCER 0x00000100
#define MASK_QUNK 0x00000010
#define MASK_TXBRK 0x00000002
#define CSI_ERR_INTENA 0x0450
#define CSI_ERR_HALT 0x0454
#define CSI_CONFW 0x0500
#define MASK_MODE 0xe0000000
#define MASK_MODE_SET 0xa0000000
#define MASK_MODE_CLEAR 0xc0000000
#define MASK_ADDRESS 0x1f000000
#define MASK_ADDRESS_CSI_CONTROL 0x03000000
#define MASK_ADDRESS_CSI_INT_ENA 0x06000000
#define MASK_ADDRESS_CSI_ERR_INTENA 0x14000000
#define MASK_ADDRESS_CSI_ERR_HALT 0x15000000
#define MASK_DATA 0x0000ffff
#define CSI_INT_CLR 0x050C
#define MASK_ICRER 0x00000004
#define CSI_START 0x0518
#define MASK_STRT 0x00000001
#define CECEN 0x0600
#define MASK_CECEN 0x0001
#define HDMI_INT0 0x8500
#define MASK_I_KEY 0x80
#define MASK_I_MISC 0x02
#define MASK_I_PHYERR 0x01
#define HDMI_INT1 0x8501
#define MASK_I_GBD 0x80
#define MASK_I_HDCP 0x40
#define MASK_I_ERR 0x20
#define MASK_I_AUD 0x10
#define MASK_I_CBIT 0x08
#define MASK_I_PACKET 0x04
#define MASK_I_CLK 0x02
#define MASK_I_SYS 0x01
#define SYS_INT 0x8502
#define MASK_I_ACR_CTS 0x80
#define MASK_I_ACRN 0x40
#define MASK_I_DVI 0x20
#define MASK_I_HDMI 0x10
#define MASK_I_NOPMBDET 0x08
#define MASK_I_DPMBDET 0x04
#define MASK_I_TMDS 0x02
#define MASK_I_DDC 0x01
#define CLK_INT 0x8503
#define MASK_I_OUT_H_CHG 0x40
#define MASK_I_IN_DE_CHG 0x20
#define MASK_I_IN_HV_CHG 0x10
#define MASK_I_DC_CHG 0x08
#define MASK_I_PXCLK_CHG 0x04
#define MASK_I_PHYCLK_CHG 0x02
#define MASK_I_TMDSCLK_CHG 0x01
#define CBIT_INT 0x8505
#define MASK_I_AF_LOCK 0x80
#define MASK_I_AF_UNLOCK 0x40
#define MASK_I_CBIT_FS 0x02
#define AUDIO_INT 0x8506
#define ERR_INT 0x8507
#define MASK_I_EESS_ERR 0x80
#define HDCP_INT 0x8508
#define MASK_I_AVM_SET 0x80
#define MASK_I_AVM_CLR 0x40
#define MASK_I_LINKERR 0x20
#define MASK_I_SHA_END 0x10
#define MASK_I_R0_END 0x08
#define MASK_I_KM_END 0x04
#define MASK_I_AKSV_END 0x02
#define MASK_I_AN_END 0x01
#define MISC_INT 0x850B
#define MASK_I_AS_LAYOUT 0x10
#define MASK_I_NO_SPD 0x08
#define MASK_I_NO_VS 0x03
#define MASK_I_SYNC_CHG 0x02
#define MASK_I_AUDIO_MUTE 0x01
#define KEY_INT 0x850F
#define SYS_INTM 0x8512
#define MASK_M_ACR_CTS 0x80
#define MASK_M_ACR_N 0x40
#define MASK_M_DVI_DET 0x20
#define MASK_M_HDMI_DET 0x10
#define MASK_M_NOPMBDET 0x08
#define MASK_M_BPMBDET 0x04
#define MASK_M_TMDS 0x02
#define MASK_M_DDC 0x01
#define CLK_INTM 0x8513
#define MASK_M_OUT_H_CHG 0x40
#define MASK_M_IN_DE_CHG 0x20
#define MASK_M_IN_HV_CHG 0x10
#define MASK_M_DC_CHG 0x08
#define MASK_M_PXCLK_CHG 0x04
#define MASK_M_PHYCLK_CHG 0x02
#define MASK_M_TMDS_CHG 0x01
#define PACKET_INTM 0x8514
#define CBIT_INTM 0x8515
#define MASK_M_AF_LOCK 0x80
#define MASK_M_AF_UNLOCK 0x40
#define MASK_M_CBIT_FS 0x02
#define AUDIO_INTM 0x8516
#define MASK_M_BUFINIT_END 0x01
#define ERR_INTM 0x8517
#define MASK_M_EESS_ERR 0x80
#define HDCP_INTM 0x8518
#define MASK_M_AVM_SET 0x80
#define MASK_M_AVM_CLR 0x40
#define MASK_M_LINKERR 0x20
#define MASK_M_SHA_END 0x10
#define MASK_M_R0_END 0x08
#define MASK_M_KM_END 0x04
#define MASK_M_AKSV_END 0x02
#define MASK_M_AN_END 0x01
#define MISC_INTM 0x851B
#define MASK_M_AS_LAYOUT 0x10
#define MASK_M_NO_SPD 0x08
#define MASK_M_NO_VS 0x03
#define MASK_M_SYNC_CHG 0x02
#define MASK_M_AUDIO_MUTE 0x01
#define KEY_INTM 0x851F
#define SYS_STATUS 0x8520
#define MASK_S_SYNC 0x80
#define MASK_S_AVMUTE 0x40
#define MASK_S_HDCP 0x20
#define MASK_S_HDMI 0x10
#define MASK_S_PHY_SCDT 0x08
#define MASK_S_PHY_PLL 0x04
#define MASK_S_TMDS 0x02
#define MASK_S_DDC5V 0x01
#define CSI_STATUS 0x0410
#define MASK_S_WSYNC 0x0400
#define MASK_S_TXACT 0x0200
#define MASK_S_RXACT 0x0100
#define MASK_S_HLT 0x0001
#define VI_STATUS1 0x8522
#define MASK_S_V_GBD 0x08
#define MASK_S_DEEPCOLOR 0x0c
#define MASK_S_V_422 0x02
#define MASK_S_V_INTERLACE 0x01
#define AU_STATUS0 0x8523
#define MASK_S_A_SAMPLE 0x01
#define VI_STATUS3 0x8528
#define MASK_S_V_COLOR 0x1e
#define MASK_LIMITED 0x01
#define PHY_CTL0 0x8531
#define MASK_PHY_SYSCLK_IND 0x02
#define MASK_PHY_CTL 0x01
#define PHY_CTL1 0x8532 /* Not in REF_01 */
#define MASK_PHY_AUTO_RST1 0xf0
#define MASK_PHY_AUTO_RST1_OFF 0x00
#define SET_PHY_AUTO_RST1_US(us) ((((us) / 200) << 4) & \
MASK_PHY_AUTO_RST1)
#define MASK_FREQ_RANGE_MODE 0x0f
#define SET_FREQ_RANGE_MODE_CYCLES(cycles) (((cycles) - 1) & \
MASK_FREQ_RANGE_MODE)
#define PHY_CTL2 0x8533 /* Not in REF_01 */
#define MASK_PHY_AUTO_RST4 0x04
#define MASK_PHY_AUTO_RST3 0x02
#define MASK_PHY_AUTO_RST2 0x01
#define MASK_PHY_AUTO_RSTn (MASK_PHY_AUTO_RST4 | \
MASK_PHY_AUTO_RST3 | \
MASK_PHY_AUTO_RST2)
#define PHY_EN 0x8534
#define MASK_ENABLE_PHY 0x01
#define PHY_RST 0x8535
#define MASK_RESET_CTRL 0x01 /* Reset active low */
#define PHY_BIAS 0x8536 /* Not in REF_01 */
#define PHY_CSQ 0x853F /* Not in REF_01 */
#define MASK_CSQ_CNT 0x0f
#define SET_CSQ_CNT_LEVEL(n) (n & MASK_CSQ_CNT)
#define SYS_FREQ0 0x8540
#define SYS_FREQ1 0x8541
#define SYS_CLK 0x8542 /* Not in REF_01 */
#define MASK_CLK_DIFF 0x0C
#define MASK_CLK_DIV 0x03
#define DDC_CTL 0x8543
#define MASK_DDC_ACK_POL 0x08
#define MASK_DDC_ACTION 0x04
#define MASK_DDC5V_MODE 0x03
#define MASK_DDC5V_MODE_0MS 0x00
#define MASK_DDC5V_MODE_50MS 0x01
#define MASK_DDC5V_MODE_100MS 0x02
#define MASK_DDC5V_MODE_200MS 0x03
#define HPD_CTL 0x8544
#define MASK_HPD_CTL0 0x10
#define MASK_HPD_OUT0 0x01
#define ANA_CTL 0x8545
#define MASK_APPL_PCSX 0x30
#define MASK_APPL_PCSX_HIZ 0x00
#define MASK_APPL_PCSX_L_FIX 0x10
#define MASK_APPL_PCSX_H_FIX 0x20
#define MASK_APPL_PCSX_NORMAL 0x30
#define MASK_ANALOG_ON 0x01
#define AVM_CTL 0x8546
#define INIT_END 0x854A
#define MASK_INIT_END 0x01
#define HDMI_DET 0x8552 /* Not in REF_01 */
#define MASK_HDMI_DET_MOD1 0x80
#define MASK_HDMI_DET_MOD0 0x40
#define MASK_HDMI_DET_V 0x30
#define MASK_HDMI_DET_V_SYNC 0x00
#define MASK_HDMI_DET_V_ASYNC_25MS 0x10
#define MASK_HDMI_DET_V_ASYNC_50MS 0x20
#define MASK_HDMI_DET_V_ASYNC_100MS 0x30
#define MASK_HDMI_DET_NUM 0x0f
#define HDCP_MODE 0x8560
#define MASK_MODE_RST_TN 0x20
#define MASK_LINE_REKEY 0x10
#define MASK_AUTO_CLR 0x04
#define HDCP_REG1 0x8563 /* Not in REF_01 */
#define MASK_AUTH_UNAUTH_SEL 0x70
#define MASK_AUTH_UNAUTH_SEL_12_FRAMES 0x70
#define MASK_AUTH_UNAUTH_SEL_8_FRAMES 0x60
#define MASK_AUTH_UNAUTH_SEL_4_FRAMES 0x50
#define MASK_AUTH_UNAUTH_SEL_2_FRAMES 0x40
#define MASK_AUTH_UNAUTH_SEL_64_FRAMES 0x30
#define MASK_AUTH_UNAUTH_SEL_32_FRAMES 0x20
#define MASK_AUTH_UNAUTH_SEL_16_FRAMES 0x10
#define MASK_AUTH_UNAUTH_SEL_ONCE 0x00
#define MASK_AUTH_UNAUTH 0x01
#define MASK_AUTH_UNAUTH_AUTO 0x01
#define HDCP_REG2 0x8564 /* Not in REF_01 */
#define MASK_AUTO_P3_RESET 0x0F
#define SET_AUTO_P3_RESET_FRAMES(n) (n & MASK_AUTO_P3_RESET)
#define MASK_AUTO_P3_RESET_OFF 0x00
#define VI_MODE 0x8570
#define MASK_RGB_DVI 0x08 /* Not in REF_01 */
#define VOUT_SET2 0x8573
#define MASK_SEL422 0x80
#define MASK_VOUT_422FIL_100 0x40
#define MASK_VOUTCOLORMODE 0x03
#define MASK_VOUTCOLORMODE_THROUGH 0x00
#define MASK_VOUTCOLORMODE_AUTO 0x01
#define MASK_VOUTCOLORMODE_MANUAL 0x03
#define VOUT_SET3 0x8574
#define MASK_VOUT_EXTCNT 0x08
#define VI_REP 0x8576
#define MASK_VOUT_COLOR_SEL 0xe0
#define MASK_VOUT_COLOR_RGB_FULL 0x00
#define MASK_VOUT_COLOR_RGB_LIMITED 0x20
#define MASK_VOUT_COLOR_601_YCBCR_FULL 0x40
#define MASK_VOUT_COLOR_601_YCBCR_LIMITED 0x60
#define MASK_VOUT_COLOR_709_YCBCR_FULL 0x80
#define MASK_VOUT_COLOR_709_YCBCR_LIMITED 0xa0
#define MASK_VOUT_COLOR_FULL_TO_LIMITED 0xc0
#define MASK_VOUT_COLOR_LIMITED_TO_FULL 0xe0
#define MASK_IN_REP_HEN 0x10
#define MASK_IN_REP 0x0f
#define VI_MUTE 0x857F
#define MASK_AUTO_MUTE 0xc0
#define MASK_VI_MUTE 0x10
#define DE_WIDTH_H_LO 0x8582 /* Not in REF_01 */
#define DE_WIDTH_H_HI 0x8583 /* Not in REF_01 */
#define DE_WIDTH_V_LO 0x8588 /* Not in REF_01 */
#define DE_WIDTH_V_HI 0x8589 /* Not in REF_01 */
#define H_SIZE_LO 0x858A /* Not in REF_01 */
#define H_SIZE_HI 0x858B /* Not in REF_01 */
#define V_SIZE_LO 0x858C /* Not in REF_01 */
#define V_SIZE_HI 0x858D /* Not in REF_01 */
#define FV_CNT_LO 0x85A1 /* Not in REF_01 */
#define FV_CNT_HI 0x85A2 /* Not in REF_01 */
#define FH_MIN0 0x85AA /* Not in REF_01 */
#define FH_MIN1 0x85AB /* Not in REF_01 */
#define FH_MAX0 0x85AC /* Not in REF_01 */
#define FH_MAX1 0x85AD /* Not in REF_01 */
#define HV_RST 0x85AF /* Not in REF_01 */
#define MASK_H_PI_RST 0x20
#define MASK_V_PI_RST 0x10
#define EDID_MODE 0x85C7
#define MASK_EDID_SPEED 0x40
#define MASK_EDID_MODE 0x03
#define MASK_EDID_MODE_DISABLE 0x00
#define MASK_EDID_MODE_DDC2B 0x01
#define MASK_EDID_MODE_E_DDC 0x02
#define EDID_LEN1 0x85CA
#define EDID_LEN2 0x85CB
#define HDCP_REG3 0x85D1 /* Not in REF_01 */
#define KEY_RD_CMD 0x01
#define FORCE_MUTE 0x8600
#define MASK_FORCE_AMUTE 0x10
#define MASK_FORCE_DMUTE 0x01
#define CMD_AUD 0x8601
#define MASK_CMD_BUFINIT 0x04
#define MASK_CMD_LOCKDET 0x02
#define MASK_CMD_MUTE 0x01
#define AUTO_CMD0 0x8602
#define MASK_AUTO_MUTE7 0x80
#define MASK_AUTO_MUTE6 0x40
#define MASK_AUTO_MUTE5 0x20
#define MASK_AUTO_MUTE4 0x10
#define MASK_AUTO_MUTE3 0x08
#define MASK_AUTO_MUTE2 0x04
#define MASK_AUTO_MUTE1 0x02
#define MASK_AUTO_MUTE0 0x01
#define AUTO_CMD1 0x8603
#define MASK_AUTO_MUTE10 0x04
#define MASK_AUTO_MUTE9 0x02
#define MASK_AUTO_MUTE8 0x01
#define AUTO_CMD2 0x8604
#define MASK_AUTO_PLAY3 0x08
#define MASK_AUTO_PLAY2 0x04
#define BUFINIT_START 0x8606
#define SET_BUFINIT_START_MS(milliseconds) ((milliseconds) / 100)
#define FS_MUTE 0x8607
#define MASK_FS_ELSE_MUTE 0x80
#define MASK_FS22_MUTE 0x40
#define MASK_FS24_MUTE 0x20
#define MASK_FS88_MUTE 0x10
#define MASK_FS96_MUTE 0x08
#define MASK_FS176_MUTE 0x04
#define MASK_FS192_MUTE 0x02
#define MASK_FS_NO_MUTE 0x01
#define FS_IMODE 0x8620
#define MASK_NLPCM_HMODE 0x40
#define MASK_NLPCM_SMODE 0x20
#define MASK_NLPCM_IMODE 0x10
#define MASK_FS_HMODE 0x08
#define MASK_FS_AMODE 0x04
#define MASK_FS_SMODE 0x02
#define MASK_FS_IMODE 0x01
#define FS_SET 0x8621
#define MASK_FS 0x0f
#define LOCKDET_REF0 0x8630
#define LOCKDET_REF1 0x8631
#define LOCKDET_REF2 0x8632
#define ACR_MODE 0x8640
#define MASK_ACR_LOAD 0x10
#define MASK_N_MODE 0x04
#define MASK_CTS_MODE 0x01
#define ACR_MDF0 0x8641
#define MASK_ACR_L2MDF 0x70
#define MASK_ACR_L2MDF_0_PPM 0x00
#define MASK_ACR_L2MDF_61_PPM 0x10
#define MASK_ACR_L2MDF_122_PPM 0x20
#define MASK_ACR_L2MDF_244_PPM 0x30
#define MASK_ACR_L2MDF_488_PPM 0x40
#define MASK_ACR_L2MDF_976_PPM 0x50
#define MASK_ACR_L2MDF_1976_PPM 0x60
#define MASK_ACR_L2MDF_3906_PPM 0x70
#define MASK_ACR_L1MDF 0x07
#define MASK_ACR_L1MDF_0_PPM 0x00
#define MASK_ACR_L1MDF_61_PPM 0x01
#define MASK_ACR_L1MDF_122_PPM 0x02
#define MASK_ACR_L1MDF_244_PPM 0x03
#define MASK_ACR_L1MDF_488_PPM 0x04
#define MASK_ACR_L1MDF_976_PPM 0x05
#define MASK_ACR_L1MDF_1976_PPM 0x06
#define MASK_ACR_L1MDF_3906_PPM 0x07
#define ACR_MDF1 0x8642
#define MASK_ACR_L3MDF 0x07
#define MASK_ACR_L3MDF_0_PPM 0x00
#define MASK_ACR_L3MDF_61_PPM 0x01
#define MASK_ACR_L3MDF_122_PPM 0x02
#define MASK_ACR_L3MDF_244_PPM 0x03
#define MASK_ACR_L3MDF_488_PPM 0x04
#define MASK_ACR_L3MDF_976_PPM 0x05
#define MASK_ACR_L3MDF_1976_PPM 0x06
#define MASK_ACR_L3MDF_3906_PPM 0x07
#define SDO_MODE1 0x8652
#define MASK_SDO_BIT_LENG 0x70
#define MASK_SDO_FMT 0x03
#define MASK_SDO_FMT_RIGHT 0x00
#define MASK_SDO_FMT_LEFT 0x01
#define MASK_SDO_FMT_I2S 0x02
#define DIV_MODE 0x8665 /* Not in REF_01 */
#define MASK_DIV_DLY 0xf0
#define SET_DIV_DLY_MS(milliseconds) ((((milliseconds) / 100) << 4) & \
MASK_DIV_DLY)
#define MASK_DIV_MODE 0x01
#define NCO_F0_MOD 0x8670
#define MASK_NCO_F0_MOD 0x03
#define MASK_NCO_F0_MOD_42MHZ 0x00
#define MASK_NCO_F0_MOD_27MHZ 0x01
#define PK_INT_MODE 0x8709
#define MASK_ISRC2_INT_MODE 0x80
#define MASK_ISRC_INT_MODE 0x40
#define MASK_ACP_INT_MODE 0x20
#define MASK_VS_INT_MODE 0x10
#define MASK_SPD_INT_MODE 0x08
#define MASK_MS_INT_MODE 0x04
#define MASK_AUD_INT_MODE 0x02
#define MASK_AVI_INT_MODE 0x01
#define NO_PKT_LIMIT 0x870B
#define MASK_NO_ACP_LIMIT 0xf0
#define SET_NO_ACP_LIMIT_MS(milliseconds) ((((milliseconds) / 80) << 4) & \
MASK_NO_ACP_LIMIT)
#define MASK_NO_AVI_LIMIT 0x0f
#define SET_NO_AVI_LIMIT_MS(milliseconds) (((milliseconds) / 80) & \
MASK_NO_AVI_LIMIT)
#define NO_PKT_CLR 0x870C
#define MASK_NO_VS_CLR 0x40
#define MASK_NO_SPD_CLR 0x20
#define MASK_NO_ACP_CLR 0x10
#define MASK_NO_AVI_CLR1 0x02
#define MASK_NO_AVI_CLR0 0x01
#define ERR_PK_LIMIT 0x870D
#define NO_PKT_LIMIT2 0x870E
#define PK_AVI_0HEAD 0x8710
#define PK_AVI_1HEAD 0x8711
#define PK_AVI_2HEAD 0x8712
#define PK_AVI_0BYTE 0x8713
#define PK_AVI_1BYTE 0x8714
#define PK_AVI_2BYTE 0x8715
#define PK_AVI_3BYTE 0x8716
#define PK_AVI_4BYTE 0x8717
#define PK_AVI_5BYTE 0x8718
#define PK_AVI_6BYTE 0x8719
#define PK_AVI_7BYTE 0x871A
#define PK_AVI_8BYTE 0x871B
#define PK_AVI_9BYTE 0x871C
#define PK_AVI_10BYTE 0x871D
#define PK_AVI_11BYTE 0x871E
#define PK_AVI_12BYTE 0x871F
#define PK_AVI_13BYTE 0x8720
#define PK_AVI_14BYTE 0x8721
#define PK_AVI_15BYTE 0x8722
#define PK_AVI_16BYTE 0x8723
#define BKSV 0x8800
#define BCAPS 0x8840
#define MASK_HDMI_RSVD 0x80
#define MASK_REPEATER 0x40
#define MASK_READY 0x20
#define MASK_FASTI2C 0x10
#define MASK_1_1_FEA 0x02
#define MASK_FAST_REAU 0x01
#define BSTATUS1 0x8842
#define MASK_MAX_EXCED 0x08
#define EDID_RAM 0x8C00
#define NO_GDB_LIMIT 0x9007
#endif

View File

@ -331,13 +331,6 @@ static const struct v4l2_ctrl_ops tda7432_ctrl_ops = {
static const struct v4l2_subdev_core_ops tda7432_core_ops = {
.log_status = tda7432_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_ops tda7432_ops = {
@ -416,7 +409,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
static struct i2c_driver tda7432_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tda7432",
},
.probe = tda7432_probe,

View File

@ -199,7 +199,6 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id);
static struct i2c_driver tda9840_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tda9840",
},
.probe = tda9840_probe,

View File

@ -162,7 +162,6 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id);
static struct i2c_driver tea6415c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tea6415c",
},
.probe = tea6415c_probe,

View File

@ -144,7 +144,6 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
static struct i2c_driver tea6420_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tea6420",
},
.probe = tea6420_probe,

View File

@ -377,7 +377,6 @@ MODULE_DEVICE_TABLE(i2c, ths7303_id);
static struct i2c_driver ths7303_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ths73x3",
},
.probe = ths7303_probe,

View File

@ -122,13 +122,6 @@ static const struct v4l2_ctrl_ops tlv320aic23b_ctrl_ops = {
static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
.log_status = tlv320aic23b_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {

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