提交 2183a588 编写于 作者: L Linus Torvalds

Merge tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:
 - Two new dvb frontend drivers: mn88472 and mn88473
 - A new driver for some PCIe DVBSky cards
 - A new remote controller driver: meson-ir
 - One LIRC staging driver got rewritten and promoted to mainstream:
   igorplugusb
 - A new tuner driver (m88rs6000t)
 - The old omap2 media driver got removed from staging.  This driver
   uses an old DMA API and it is likely broken on recent kernels.
   Nobody cared enough to fix it
 - Media bus format moved to a separate header, as DRM will also use the
   definitions there
 - mem2mem_testdev were renamed to vim2m, in order to use the same
   naming convention taken by the other virtual test driver (vivid)
 - Added a new driver for coda SoC (coda-jpeg)
 - The cx88 driver got converted to use videobuf2 core
 - Make DMABUF export buffer to work with DMA Scatter/Gather and Vmalloc
   cores
 - Lots of other fixes, improvements and cleanups on the drivers.

* tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (384 commits)
  [media] mn88473: One function call less in mn88473_init() after error
  [media] mn88473: Remove uneeded check before release_firmware()
  [media] lirc_zilog: Deletion of unnecessary checks before vfree()
  [media] MAINTAINERS: Add myself as img-ir maintainer
  [media] img-ir: Don't set driver's module owner
  [media] img-ir: Depend on METAG or MIPS or COMPILE_TEST
  [media] img-ir/hw: Drop [un]register_decoder declarations
  [media] img-ir/hw: Fix potential deadlock stopping timer
  [media] img-ir/hw: Always read data to clear buffer
  [media] redrat3: ensure dma is setup properly
  [media] ddbridge: remove unneeded check before dvb_unregister_device()
  [media] si2157: One function call less in si2157_init() after error
  [media] tuners: remove uneeded checks before release_firmware()
  [media] arm: omap2: rx51-peripherals: fix build warning
  [media] stv090x: add an extra protetion against buffer overflow
  [media] stv090x: Remove an unreachable code
  [media] stv090x: Some whitespace cleanups
  [media] em28xx: checkpatch cleanup: whitespaces/new lines cleanups
  [media] si2168: add support for firmware files in new format
  [media] si2168: debug printout for firmware version
  ...
...@@ -120,8 +120,8 @@ struct dtv_properties { ...@@ -120,8 +120,8 @@ struct dtv_properties {
</para> </para>
<informaltable><tgroup cols="1"><tbody><row><entry <informaltable><tgroup cols="1"><tbody><row><entry
align="char"> align="char">
<para>This ioctl call sets one or more frontend properties. This call only <para>This ioctl call sets one or more frontend properties. This call
requires read-only access to the device.</para> requires read/write access to the device.</para>
</entry> </entry>
</row></tbody></tgroup></informaltable> </row></tbody></tgroup></informaltable>
<para>SYNOPSIS <para>SYNOPSIS
......
...@@ -178,6 +178,75 @@ Signal - NTSC for Studio Applications"</title> ...@@ -178,6 +178,75 @@ Signal - NTSC for Studio Applications"</title>
1125-Line High-Definition Production"</title> 1125-Line High-Definition Production"</title>
</biblioentry> </biblioentry>
<biblioentry id="srgb">
<abbrev>sRGB</abbrev>
<authorgroup>
<corpauthor>International Electrotechnical Commission
(<ulink url="http://www.iec.ch">http://www.iec.ch</ulink>)</corpauthor>
</authorgroup>
<title>IEC 61966-2-1 ed1.0 "Multimedia systems and equipment - Colour measurement
and management - Part 2-1: Colour management - Default RGB colour space - sRGB"</title>
</biblioentry>
<biblioentry id="sycc">
<abbrev>sYCC</abbrev>
<authorgroup>
<corpauthor>International Electrotechnical Commission
(<ulink url="http://www.iec.ch">http://www.iec.ch</ulink>)</corpauthor>
</authorgroup>
<title>IEC 61966-2-1-am1 ed1.0 "Amendment 1 - Multimedia systems and equipment - Colour measurement
and management - Part 2-1: Colour management - Default RGB colour space - sRGB"</title>
</biblioentry>
<biblioentry id="xvycc">
<abbrev>xvYCC</abbrev>
<authorgroup>
<corpauthor>International Electrotechnical Commission
(<ulink url="http://www.iec.ch">http://www.iec.ch</ulink>)</corpauthor>
</authorgroup>
<title>IEC 61966-2-4 ed1.0 "Multimedia systems and equipment - Colour measurement
and management - Part 2-4: Colour management - Extended-gamut YCC colour space for video
applications - xvYCC"</title>
</biblioentry>
<biblioentry id="adobergb">
<abbrev>AdobeRGB</abbrev>
<authorgroup>
<corpauthor>Adobe Systems Incorporated (<ulink url="http://www.adobe.com">http://www.adobe.com</ulink>)</corpauthor>
</authorgroup>
<title>Adobe&copy; RGB (1998) Color Image Encoding Version 2005-05</title>
</biblioentry>
<biblioentry id="oprgb">
<abbrev>opRGB</abbrev>
<authorgroup>
<corpauthor>International Electrotechnical Commission
(<ulink url="http://www.iec.ch">http://www.iec.ch</ulink>)</corpauthor>
</authorgroup>
<title>IEC 61966-2-5 "Multimedia systems and equipment - Colour measurement
and management - Part 2-5: Colour management - Optional RGB colour space - opRGB"</title>
</biblioentry>
<biblioentry id="itu2020">
<abbrev>ITU&nbsp;BT.2020</abbrev>
<authorgroup>
<corpauthor>International Telecommunication Union (<ulink
url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
</authorgroup>
<title>ITU-R Recommendation BT.2020 (08/2012) "Parameter values for ultra-high
definition television systems for production and international programme exchange"
</title>
</biblioentry>
<biblioentry id="tech3213">
<abbrev>EBU&nbsp;Tech&nbsp;3213</abbrev>
<authorgroup>
<corpauthor>European Broadcast Union (<ulink
url="http://www.ebu.ch">http://www.ebu.ch</ulink>)</corpauthor>
</authorgroup>
<title>E.B.U. Standard for Chromaticity Tolerances for Studio Monitors"</title>
</biblioentry>
<biblioentry id="iec62106"> <biblioentry id="iec62106">
<abbrev>IEC&nbsp;62106</abbrev> <abbrev>IEC&nbsp;62106</abbrev>
<authorgroup> <authorgroup>
...@@ -266,4 +335,20 @@ in the frequency range from 87,5 to 108,0 MHz</title> ...@@ -266,4 +335,20 @@ in the frequency range from 87,5 to 108,0 MHz</title>
<subtitle>Version 1, Revision 2</subtitle> <subtitle>Version 1, Revision 2</subtitle>
</biblioentry> </biblioentry>
<biblioentry id="poynton">
<abbrev>poynton</abbrev>
<authorgroup>
<corpauthor>Charles Poynton</corpauthor>
</authorgroup>
<title>Digital Video and HDTV, Algorithms and Interfaces</title>
</biblioentry>
<biblioentry id="colimg">
<abbrev>colimg</abbrev>
<authorgroup>
<corpauthor>Erik Reinhard et al.</corpauthor>
</authorgroup>
<title>Color Imaging: Fundamentals and Applications</title>
</biblioentry>
</bibliography> </bibliography>
...@@ -195,53 +195,59 @@ ...@@ -195,53 +195,59 @@
<title>Sample Pipeline Configuration</title> <title>Sample Pipeline Configuration</title>
<tgroup cols="3"> <tgroup cols="3">
<colspec colname="what"/> <colspec colname="what"/>
<colspec colname="sensor-0" /> <colspec colname="sensor-0 format" />
<colspec colname="frontend-0" /> <colspec colname="frontend-0 format" />
<colspec colname="frontend-1" /> <colspec colname="frontend-1 format" />
<colspec colname="scaler-0" /> <colspec colname="scaler-0 format" />
<colspec colname="scaler-1" /> <colspec colname="scaler-0 compose" />
<colspec colname="scaler-1 format" />
<thead> <thead>
<row> <row>
<entry></entry> <entry></entry>
<entry>Sensor/0</entry> <entry>Sensor/0 format</entry>
<entry>Frontend/0</entry> <entry>Frontend/0 format</entry>
<entry>Frontend/1</entry> <entry>Frontend/1 format</entry>
<entry>Scaler/0</entry> <entry>Scaler/0 format</entry>
<entry>Scaler/1</entry> <entry>Scaler/0 compose selection rectangle</entry>
<entry>Scaler/1 format</entry>
</row> </row>
</thead> </thead>
<tbody valign="top"> <tbody valign="top">
<row> <row>
<entry>Initial state</entry> <entry>Initial state</entry>
<entry>2048x1536</entry> <entry>2048x1536/SGRBG8_1X8</entry>
<entry>-</entry> <entry>(default)</entry>
<entry>-</entry> <entry>(default)</entry>
<entry>-</entry> <entry>(default)</entry>
<entry>-</entry> <entry>(default)</entry>
<entry>(default)</entry>
</row> </row>
<row> <row>
<entry>Configure frontend input</entry> <entry>Configure frontend sink format</entry>
<entry>2048x1536</entry> <entry>2048x1536/SGRBG8_1X8</entry>
<entry><emphasis>2048x1536</emphasis></entry> <entry><emphasis>2048x1536/SGRBG8_1X8</emphasis></entry>
<entry><emphasis>2046x1534</emphasis></entry> <entry><emphasis>2046x1534/SGRBG8_1X8</emphasis></entry>
<entry>-</entry> <entry>(default)</entry>
<entry>-</entry> <entry>(default)</entry>
<entry>(default)</entry>
</row> </row>
<row> <row>
<entry>Configure scaler input</entry> <entry>Configure scaler sink format</entry>
<entry>2048x1536</entry> <entry>2048x1536/SGRBG8_1X8</entry>
<entry>2048x1536</entry> <entry>2048x1536/SGRBG8_1X8</entry>
<entry>2046x1534</entry> <entry>2046x1534/SGRBG8_1X8</entry>
<entry><emphasis>2046x1534</emphasis></entry> <entry><emphasis>2046x1534/SGRBG8_1X8</emphasis></entry>
<entry><emphasis>2046x1534</emphasis></entry> <entry><emphasis>0,0/2046x1534</emphasis></entry>
<entry><emphasis>2046x1534/SGRBG8_1X8</emphasis></entry>
</row> </row>
<row> <row>
<entry>Configure scaler output</entry> <entry>Configure scaler sink compose selection</entry>
<entry>2048x1536</entry> <entry>2048x1536/SGRBG8_1X8</entry>
<entry>2048x1536</entry> <entry>2048x1536/SGRBG8_1X8</entry>
<entry>2046x1534</entry> <entry>2046x1534/SGRBG8_1X8</entry>
<entry>2046x1534</entry> <entry>2046x1534/SGRBG8_1X8</entry>
<entry><emphasis>1280x960</emphasis></entry> <entry><emphasis>0,0/1280x960</emphasis></entry>
<entry><emphasis>1280x960/SGRBG8_1X8</emphasis></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
...@@ -249,19 +255,30 @@ ...@@ -249,19 +255,30 @@
<para> <para>
<orderedlist> <orderedlist>
<listitem><para>Initial state. The sensor output is set to its native 3MP <listitem><para>Initial state. The sensor source pad format is
resolution. Resolutions on the host frontend and scaler input and output set to its native 3MP size and V4L2_MBUS_FMT_SGRBG8_1X8
pads are undefined.</para></listitem> media bus code. Formats on the host frontend and scaler sink
<listitem><para>The application configures the frontend input pad resolution to and source pads have the default values, as well as the
2048x1536. The driver propagates the format to the frontend output pad. compose rectangle on the scaler's sink pad.</para></listitem>
Note that the propagated output format can be different, as in this case,
than the input format, as the hardware might need to crop pixels (for <listitem><para>The application configures the frontend sink
instance when converting a Bayer filter pattern to RGB or YUV).</para></listitem> pad format's size to 2048x1536 and its media bus code to
<listitem><para>The application configures the scaler input pad resolution to V4L2_MBUS_FMT_SGRBG_1X8. The driver propagates the format to
2046x1534 to match the frontend output resolution. The driver propagates the frontend source pad.</para></listitem>
the format to the scaler output pad.</para></listitem>
<listitem><para>The application configures the scaler output pad resolution to <listitem><para>The application configures the scaler sink pad
1280x960.</para></listitem> format's size to 2046x1534 and the media bus code to
V4L2_MBUS_FMT_SGRBG_1X8 to match the frontend source size and
media bus code. The media bus code on the sink pad is set to
V4L2_MBUS_FMT_SGRBG_1X8. The driver propagates the size to the
compose selection rectangle on the scaler's sink pad, and the
format to the scaler source pad.</para></listitem>
<listitem><para>The application configures the size of the compose
selection rectangle of the scaler's sink pad 1280x960. The driver
propagates the size to the scaler's source pad
format.</para></listitem>
</orderedlist> </orderedlist>
</para> </para>
......
...@@ -1422,7 +1422,10 @@ one of the <constant>V4L2_FIELD_NONE</constant>, ...@@ -1422,7 +1422,10 @@ one of the <constant>V4L2_FIELD_NONE</constant>,
<constant>V4L2_FIELD_BOTTOM</constant>, or <constant>V4L2_FIELD_BOTTOM</constant>, or
<constant>V4L2_FIELD_INTERLACED</constant> formats is acceptable. <constant>V4L2_FIELD_INTERLACED</constant> formats is acceptable.
Drivers choose depending on hardware capabilities or e.&nbsp;g. the Drivers choose depending on hardware capabilities or e.&nbsp;g. the
requested image size, and return the actual field order. &v4l2-buffer; requested image size, and return the actual field order. Drivers must
never return <constant>V4L2_FIELD_ANY</constant>. If multiple
field orders are possible the driver must choose one of the possible
field orders during &VIDIOC-S-FMT; or &VIDIOC-TRY-FMT;. &v4l2-buffer;
<structfield>field</structfield> can never be <structfield>field</structfield> can never be
<constant>V4L2_FIELD_ANY</constant>.</entry> <constant>V4L2_FIELD_ANY</constant>.</entry>
</row> </row>
......
...@@ -62,6 +62,22 @@ ...@@ -62,6 +62,22 @@
<entry>Yes</entry> <entry>Yes</entry>
<entry>Yes</entry> <entry>Yes</entry>
</row> </row>
<row>
<entry><constant>V4L2_SEL_TGT_NATIVE_SIZE</constant></entry>
<entry>0x0003</entry>
<entry>The native size of the device, e.g. a sensor's
pixel array. <structfield>left</structfield> and
<structfield>top</structfield> fields are zero for this
target. Setting the native size will generally only make
sense for memory to memory devices where the software can
create a canvas of a given size in which for example a
video frame can be composed. In that case
V4L2_SEL_TGT_NATIVE_SIZE can be used to configure the size
of that canvas.
</entry>
<entry>Yes</entry>
<entry>Yes</entry>
</row>
<row> <row>
<entry><constant>V4L2_SEL_TGT_COMPOSE</constant></entry> <entry><constant>V4L2_SEL_TGT_COMPOSE</constant></entry>
<entry>0x0100</entry> <entry>0x0100</entry>
......
...@@ -287,6 +287,14 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009. ...@@ -287,6 +287,14 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
<entry>0x00000004</entry> <entry>0x00000004</entry>
<entry>This input supports setting the TV standard by using VIDIOC_S_STD.</entry> <entry>This input supports setting the TV standard by using VIDIOC_S_STD.</entry>
</row> </row>
<row>
<entry><constant>V4L2_IN_CAP_NATIVE_SIZE</constant></entry>
<entry>0x00000008</entry>
<entry>This input supports setting the native size using
the <constant>V4L2_SEL_TGT_NATIVE_SIZE</constant>
selection target, see <xref
linkend="v4l2-selections-common"/>.</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
......
...@@ -172,6 +172,14 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009. ...@@ -172,6 +172,14 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
<entry>0x00000004</entry> <entry>0x00000004</entry>
<entry>This output supports setting the TV standard by using VIDIOC_S_STD.</entry> <entry>This output supports setting the TV standard by using VIDIOC_S_STD.</entry>
</row> </row>
<row>
<entry><constant>V4L2_OUT_CAP_NATIVE_SIZE</constant></entry>
<entry>0x00000008</entry>
<entry>This output supports setting the native size using
the <constant>V4L2_SEL_TGT_NATIVE_SIZE</constant>
selection target, see <xref
linkend="v4l2-selections-common"/>.</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
......
* Amlogic Meson IR remote control receiver
Required properties:
- compatible : should be "amlogic,meson6-ir"
- reg : physical base address and length of the device registers
- interrupts : a single specifier for the interrupt from the device
Example:
ir-receiver@c8100480 {
compatible= "amlogic,meson6-ir";
reg = <0xc8100480 0x20>;
interrupts = <0 15 1>;
};
* Silicon Labs FM Radio transmitter
The Silicon Labs Si4713 is an FM radio transmitter with receive power scan
supporting 76-108 MHz. It includes an RDS encoder and has both, a stereo-analog
and a digital interface, which supports I2S, left-justified and a custom
DSP-mode format. It is programmable through an I2C interface.
Required Properties:
- compatible: Should contain "silabs,si4713"
- reg: the I2C address of the device
Optional Properties:
- interrupts-extended: Interrupt specifier for the chips interrupt
- reset-gpios: GPIO specifier for the chips reset line
- vdd-supply: phandle for Vdd regulator
- vio-supply: phandle for Vio regulator
Example:
&i2c2 {
fmtx: si4713@63 {
compatible = "silabs,si4713";
reg = <0x63>;
interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */
reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */
vio-supply = <&vio>;
vdd-supply = <&vaux1>;
};
};
...@@ -43,3 +43,5 @@ ...@@ -43,3 +43,5 @@
42 -> Leadtek Winfast PxPVR2200 [107d:6f21] 42 -> Leadtek Winfast PxPVR2200 [107d:6f21]
43 -> Hauppauge ImpactVCB-e [0070:7133] 43 -> Hauppauge ImpactVCB-e [0070:7133]
44 -> DViCO FusionHDTV DVB-T Dual Express2 [18ac:db98] 44 -> DViCO FusionHDTV DVB-T Dual Express2 [18ac:db98]
45 -> DVBSky T9580 [4254:9580]
46 -> DVBSky T980C [4254:980c]
...@@ -93,3 +93,4 @@ ...@@ -93,3 +93,4 @@
92 -> PCTV DVB-S2 Stick (461e) (em28178) 92 -> PCTV DVB-S2 Stick (461e) (em28178)
93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c] 93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c]
94 -> PCTV tripleStick (292e) (em28178) 94 -> PCTV tripleStick (292e) (em28178)
95 -> Leadtek VC100 (em2861) [0413:6f07]
...@@ -191,3 +191,4 @@ ...@@ -191,3 +191,4 @@
190 -> Asus My Cinema PS3-100 [1043:48cd] 190 -> Asus My Cinema PS3-100 [1043:48cd]
191 -> Hawell HW-9004V1 191 -> Hawell HW-9004V1
192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055] 192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055]
193 -> WIS Voyager or compatible [1905:7007]
...@@ -151,7 +151,7 @@ they are transferred over a media bus. Soc-camera provides support to ...@@ -151,7 +151,7 @@ they are transferred over a media bus. Soc-camera provides support to
conveniently manage these formats. A table of standard transformations is conveniently manage these formats. A table of standard transformations is
maintained by soc-camera core, which describes, what FOURCC pixel format will maintained by soc-camera core, which describes, what FOURCC pixel format will
be obtained, if a media-bus pixel format is stored in memory according to be obtained, if a media-bus pixel format is stored in memory according to
certain rules. E.g. if V4L2_MBUS_FMT_YUYV8_2X8 data is sampled with 8 bits per certain rules. E.g. if MEDIA_BUS_FMT_YUYV8_2X8 data is sampled with 8 bits per
sample and stored in memory in the little-endian order with no gaps between sample and stored in memory in the little-endian order with no gaps between
bytes, data in memory will represent the V4L2_PIX_FMT_YUYV FOURCC format. These bytes, data in memory will represent the V4L2_PIX_FMT_YUYV FOURCC format. These
standard transformations will be used by soc-camera or by camera host drivers to standard transformations will be used by soc-camera or by camera host drivers to
......
...@@ -850,6 +850,7 @@ ARM/Amlogic MesonX SoC support ...@@ -850,6 +850,7 @@ ARM/Amlogic MesonX SoC support
M: Carlo Caione <carlo@caione.org> M: Carlo Caione <carlo@caione.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: drivers/media/rc/meson-ir.c
N: meson[x68] N: meson[x68]
ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
...@@ -2512,6 +2513,13 @@ F: fs/coda/ ...@@ -2512,6 +2513,13 @@ F: fs/coda/
F: include/linux/coda*.h F: include/linux/coda*.h
F: include/uapi/linux/coda*.h F: include/uapi/linux/coda*.h
CODA V4L2 MEM2MEM DRIVER
M: Philipp Zabel <p.zabel@pengutronix.de>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/coda.txt
F: drivers/media/platform/coda/
COMMON CLK FRAMEWORK COMMON CLK FRAMEWORK
M: Mike Turquette <mturquette@linaro.org> M: Mike Turquette <mturquette@linaro.org>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
...@@ -4746,6 +4754,12 @@ F: net/mac802154/ ...@@ -4746,6 +4754,12 @@ F: net/mac802154/
F: drivers/net/ieee802154/ F: drivers/net/ieee802154/
F: Documentation/networking/ieee802154.txt F: Documentation/networking/ieee802154.txt
IGORPLUG-USB IR RECEIVER
M: Sean Young <sean@mess.org>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/rc/igorplugusb.c
IGUANAWORKS USB IR TRANSCEIVER IGUANAWORKS USB IR TRANSCEIVER
M: Sean Young <sean@mess.org> M: Sean Young <sean@mess.org>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
...@@ -4803,6 +4817,11 @@ L: linux-security-module@vger.kernel.org ...@@ -4803,6 +4817,11 @@ L: linux-security-module@vger.kernel.org
S: Supported S: Supported
F: security/integrity/ima/ F: security/integrity/ima/
IMGTEC IR DECODER DRIVER
M: James Hogan <james.hogan@imgtec.com>
S: Maintained
F: drivers/media/rc/img-ir/
IMS TWINTURBO FRAMEBUFFER DRIVER IMS TWINTURBO FRAMEBUFFER DRIVER
L: linux-fbdev@vger.kernel.org L: linux-fbdev@vger.kernel.org
S: Orphan S: Orphan
...@@ -6151,6 +6170,28 @@ S: Supported ...@@ -6151,6 +6170,28 @@ S: Supported
F: include/linux/mlx5/ F: include/linux/mlx5/
F: drivers/infiniband/hw/mlx5/ F: drivers/infiniband/hw/mlx5/
MN88472 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/staging/media/mn88472/
F: drivers/media/dvb-frontends/mn88472.h
MN88473 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/staging/media/mn88473/
F: drivers/media/dvb-frontends/mn88473.h
MODULE SUPPORT MODULE SUPPORT
M: Rusty Russell <rusty@rustcorp.com.au> M: Rusty Russell <rusty@rustcorp.com.au>
S: Maintained S: Maintained
......
...@@ -143,5 +143,12 @@ ...@@ -143,5 +143,12 @@
#size-cells = <0>; #size-cells = <0>;
status = "disabled"; status = "disabled";
}; };
ir_receiver: ir-receiver@c8100480 {
compatible= "amlogic,meson6-ir";
reg = <0xc8100480 0x20>;
interrupts = <0 15 1>;
status = "disabled";
};
}; };
}; /* end of / */ }; /* end of / */
...@@ -294,7 +294,7 @@ static struct vpbe_output dm355evm_vpbe_outputs[] = { ...@@ -294,7 +294,7 @@ static struct vpbe_output dm355evm_vpbe_outputs[] = {
.default_mode = "ntsc", .default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing), .num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing),
.modes = dm355evm_enc_preset_timing, .modes = dm355evm_enc_preset_timing,
.if_params = V4L2_MBUS_FMT_FIXED, .if_params = MEDIA_BUS_FMT_FIXED,
}, },
}; };
......
...@@ -485,7 +485,7 @@ static struct vpbe_output dm365evm_vpbe_outputs[] = { ...@@ -485,7 +485,7 @@ static struct vpbe_output dm365evm_vpbe_outputs[] = {
.default_mode = "ntsc", .default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm365evm_enc_std_timing), .num_modes = ARRAY_SIZE(dm365evm_enc_std_timing),
.modes = dm365evm_enc_std_timing, .modes = dm365evm_enc_std_timing,
.if_params = V4L2_MBUS_FMT_FIXED, .if_params = MEDIA_BUS_FMT_FIXED,
}, },
{ {
.output = { .output = {
...@@ -498,7 +498,7 @@ static struct vpbe_output dm365evm_vpbe_outputs[] = { ...@@ -498,7 +498,7 @@ static struct vpbe_output dm365evm_vpbe_outputs[] = {
.default_mode = "480p59_94", .default_mode = "480p59_94",
.num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing), .num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing),
.modes = dm365evm_enc_preset_timing, .modes = dm365evm_enc_preset_timing,
.if_params = V4L2_MBUS_FMT_FIXED, .if_params = MEDIA_BUS_FMT_FIXED,
}, },
}; };
......
...@@ -785,14 +785,13 @@ static struct resource dm355_v4l2_disp_resources[] = { ...@@ -785,14 +785,13 @@ static struct resource dm355_v4l2_disp_resources[] = {
}, },
}; };
static int dm355_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, static int dm355_vpbe_setup_pinmux(u32 if_type, int field)
int field)
{ {
switch (if_type) { switch (if_type) {
case V4L2_MBUS_FMT_SGRBG8_1X8: case MEDIA_BUS_FMT_SGRBG8_1X8:
davinci_cfg_reg(DM355_VOUT_FIELD_G70); davinci_cfg_reg(DM355_VOUT_FIELD_G70);
break; break;
case V4L2_MBUS_FMT_YUYV10_1X20: case MEDIA_BUS_FMT_YUYV10_1X20:
if (field) if (field)
davinci_cfg_reg(DM355_VOUT_FIELD); davinci_cfg_reg(DM355_VOUT_FIELD);
else else
......
...@@ -1306,16 +1306,15 @@ static struct resource dm365_v4l2_disp_resources[] = { ...@@ -1306,16 +1306,15 @@ static struct resource dm365_v4l2_disp_resources[] = {
}, },
}; };
static int dm365_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, static int dm365_vpbe_setup_pinmux(u32 if_type, int field)
int field)
{ {
switch (if_type) { switch (if_type) {
case V4L2_MBUS_FMT_SGRBG8_1X8: case MEDIA_BUS_FMT_SGRBG8_1X8:
davinci_cfg_reg(DM365_VOUT_FIELD_G81); davinci_cfg_reg(DM365_VOUT_FIELD_G81);
davinci_cfg_reg(DM365_VOUT_COUTL_EN); davinci_cfg_reg(DM365_VOUT_COUTL_EN);
davinci_cfg_reg(DM365_VOUT_COUTH_EN); davinci_cfg_reg(DM365_VOUT_COUTH_EN);
break; break;
case V4L2_MBUS_FMT_YUYV10_1X20: case MEDIA_BUS_FMT_YUYV10_1X20:
if (field) if (field)
davinci_cfg_reg(DM365_VOUT_FIELD); davinci_cfg_reg(DM365_VOUT_FIELD);
else else
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/gpio/machine.h>
#include <linux/omap-gpmc.h> #include <linux/omap-gpmc.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/power/isp1704_charger.h> #include <linux/power/isp1704_charger.h>
...@@ -38,7 +39,6 @@ ...@@ -38,7 +39,6 @@
#include <sound/tlv320aic3x.h> #include <sound/tlv320aic3x.h>
#include <sound/tpa6130a2-plat.h> #include <sound/tpa6130a2-plat.h>
#include <media/radio-si4713.h>
#include <media/si4713.h> #include <media/si4713.h>
#include <linux/platform_data/leds-lp55xx.h> #include <linux/platform_data/leds-lp55xx.h>
...@@ -756,46 +756,17 @@ static struct regulator_init_data rx51_vintdig = { ...@@ -756,46 +756,17 @@ static struct regulator_init_data rx51_vintdig = {
}, },
}; };
static const char * const si4713_supply_names[] = { static struct gpiod_lookup_table rx51_fmtx_gpios_table = {
"vio", .dev_id = "2-0063",
"vdd", .table = {
}; GPIO_LOOKUP("gpio.6", 3, "reset", GPIO_ACTIVE_HIGH), /* 163 */
{ },
static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
.supplies = ARRAY_SIZE(si4713_supply_names),
.supply_names = si4713_supply_names,
.gpio_reset = RX51_FMTX_RESET_GPIO,
};
static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
.platform_data = &rx51_si4713_i2c_data,
};
static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
.i2c_bus = 2,
.subdev_board_info = &rx51_si4713_board_info,
};
static struct platform_device rx51_si4713_dev __initdata_or_module = {
.name = "radio-si4713",
.id = -1,
.dev = {
.platform_data = &rx51_si4713_data,
}, },
}; };
static __init void rx51_init_si4713(void) static __init void rx51_gpio_init(void)
{ {
int err; gpiod_add_lookup_table(&rx51_fmtx_gpios_table);
err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
if (err) {
printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
return;
}
rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
platform_device_register(&rx51_si4713_dev);
} }
static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
...@@ -1025,7 +996,19 @@ static struct aic3x_pdata rx51_aic3x_data2 = { ...@@ -1025,7 +996,19 @@ static struct aic3x_pdata rx51_aic3x_data2 = {
.gpio_reset = 60, .gpio_reset = 60,
}; };
#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
static struct si4713_platform_data rx51_si4713_platform_data = {
.is_platform_device = true
};
#endif
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
{
I2C_BOARD_INFO("si4713", 0x63),
.platform_data = &rx51_si4713_platform_data,
},
#endif
{ {
I2C_BOARD_INFO("tlv320aic3x", 0x18), I2C_BOARD_INFO("tlv320aic3x", 0x18),
.platform_data = &rx51_aic3x_data, .platform_data = &rx51_aic3x_data,
...@@ -1066,6 +1049,10 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = { ...@@ -1066,6 +1049,10 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = {
static int __init rx51_i2c_init(void) static int __init rx51_i2c_init(void)
{ {
#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
int err;
#endif
if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) || if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
system_rev >= SYSTEM_REV_B_USES_VAUX3) { system_rev >= SYSTEM_REV_B_USES_VAUX3) {
rx51_twldata.vaux3 = &rx51_vaux3_mmc; rx51_twldata.vaux3 = &rx51_vaux3_mmc;
...@@ -1083,6 +1070,14 @@ static int __init rx51_i2c_init(void) ...@@ -1083,6 +1070,14 @@ static int __init rx51_i2c_init(void)
rx51_twldata.vdac->constraints.name = "VDAC"; rx51_twldata.vdac->constraints.name = "VDAC";
omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata); omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata);
#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
if (err) {
printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
return err;
}
rx51_peripherals_i2c_board_info_2[0].irq = gpio_to_irq(RX51_FMTX_IRQ);
#endif
omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
...@@ -1269,13 +1264,13 @@ static void __init rx51_init_omap3_rom_rng(void) ...@@ -1269,13 +1264,13 @@ static void __init rx51_init_omap3_rom_rng(void)
void __init rx51_peripherals_init(void) void __init rx51_peripherals_init(void)
{ {
rx51_gpio_init();
rx51_i2c_init(); rx51_i2c_init();
regulator_has_full_constraints(); regulator_has_full_constraints();
gpmc_onenand_init(board_onenand_data); gpmc_onenand_init(board_onenand_data);
rx51_add_gpio_keys(); rx51_add_gpio_keys();
rx51_init_wl1251(); rx51_init_wl1251();
rx51_init_tsc2005(); rx51_init_tsc2005();
rx51_init_si4713();
rx51_init_lirc(); rx51_init_lirc();
spi_register_board_info(rx51_peripherals_spi_board_info, spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info)); ARRAY_SIZE(rx51_peripherals_spi_board_info));
......
...@@ -67,28 +67,6 @@ static int __init omap3_l3_init(void) ...@@ -67,28 +67,6 @@ static int __init omap3_l3_init(void)
} }
omap_postcore_initcall(omap3_l3_init); omap_postcore_initcall(omap3_l3_init);
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
static struct resource omap2cam_resources[] = {
{
.start = OMAP24XX_CAMERA_BASE,
.end = OMAP24XX_CAMERA_BASE + 0xfff,
.flags = IORESOURCE_MEM,
},
{
.start = 24 + OMAP_INTC_START,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device omap2cam_device = {
.name = "omap24xxcam",
.id = -1,
.num_resources = ARRAY_SIZE(omap2cam_resources),
.resource = omap2cam_resources,
};
#endif
#if defined(CONFIG_IOMMU_API) #if defined(CONFIG_IOMMU_API)
#include <linux/platform_data/iommu-omap.h> #include <linux/platform_data/iommu-omap.h>
...@@ -211,14 +189,6 @@ int omap3_init_camera(struct isp_platform_data *pdata) ...@@ -211,14 +189,6 @@ int omap3_init_camera(struct isp_platform_data *pdata)
#endif #endif
static inline void omap_init_camera(void)
{
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
if (cpu_is_omap24xx())
platform_device_register(&omap2cam_device);
#endif
}
#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
static inline void __init omap_init_mbox(void) static inline void __init omap_init_mbox(void)
{ {
...@@ -397,7 +367,6 @@ static int __init omap2_init_devices(void) ...@@ -397,7 +367,6 @@ static int __init omap2_init_devices(void)
* in alphabetical order so they're easier to sort through. * in alphabetical order so they're easier to sort through.
*/ */
omap_init_audio(); omap_init_audio();
omap_init_camera();
/* If dtb is there, the devices will be created dynamically */ /* If dtb is there, the devices will be created dynamically */
if (!of_have_populated_dt()) { if (!of_have_populated_dt()) {
omap_init_mbox(); omap_init_mbox();
......
...@@ -1149,7 +1149,7 @@ static struct soc_camera_platform_info camera_info = { ...@@ -1149,7 +1149,7 @@ static struct soc_camera_platform_info camera_info = {
.format_name = "UYVY", .format_name = "UYVY",
.format_depth = 16, .format_depth = 16,
.format = { .format = {
.code = V4L2_MBUS_FMT_UYVY8_2X8, .code = MEDIA_BUS_FMT_UYVY8_2X8,
.colorspace = V4L2_COLORSPACE_SMPTE170M, .colorspace = V4L2_COLORSPACE_SMPTE170M,
.field = V4L2_FIELD_NONE, .field = V4L2_FIELD_NONE,
.width = 640, .width = 640,
......
...@@ -338,7 +338,7 @@ static struct soc_camera_platform_info camera_info = { ...@@ -338,7 +338,7 @@ static struct soc_camera_platform_info camera_info = {
.format_name = "UYVY", .format_name = "UYVY",
.format_depth = 16, .format_depth = 16,
.format = { .format = {
.code = V4L2_MBUS_FMT_UYVY8_2X8, .code = MEDIA_BUS_FMT_UYVY8_2X8,
.colorspace = V4L2_COLORSPACE_SMPTE170M, .colorspace = V4L2_COLORSPACE_SMPTE170M,
.field = V4L2_FIELD_NONE, .field = V4L2_FIELD_NONE,
.width = 640, .width = 640,
......
...@@ -227,83 +227,83 @@ static int ipu_csi_set_testgen_mclk(struct ipu_csi *csi, u32 pixel_clk, ...@@ -227,83 +227,83 @@ static int ipu_csi_set_testgen_mclk(struct ipu_csi *csi, u32 pixel_clk,
static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code) static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code)
{ {
switch (mbus_code) { switch (mbus_code) {
case V4L2_MBUS_FMT_BGR565_2X8_BE: case MEDIA_BUS_FMT_BGR565_2X8_BE:
case V4L2_MBUS_FMT_BGR565_2X8_LE: case MEDIA_BUS_FMT_BGR565_2X8_LE:
case V4L2_MBUS_FMT_RGB565_2X8_BE: case MEDIA_BUS_FMT_RGB565_2X8_BE:
case V4L2_MBUS_FMT_RGB565_2X8_LE: case MEDIA_BUS_FMT_RGB565_2X8_LE:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
cfg->mipi_dt = MIPI_DT_RGB565; cfg->mipi_dt = MIPI_DT_RGB565;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE: case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE:
case V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE: case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB444; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB444;
cfg->mipi_dt = MIPI_DT_RGB444; cfg->mipi_dt = MIPI_DT_RGB444;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555;
cfg->mipi_dt = MIPI_DT_RGB555; cfg->mipi_dt = MIPI_DT_RGB555;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY8_2X8:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
cfg->mipi_dt = MIPI_DT_YUV422; cfg->mipi_dt = MIPI_DT_YUV422;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
cfg->mipi_dt = MIPI_DT_YUV422; cfg->mipi_dt = MIPI_DT_YUV422;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_UYVY8_1X16: case MEDIA_BUS_FMT_UYVY8_1X16:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
cfg->mipi_dt = MIPI_DT_YUV422; cfg->mipi_dt = MIPI_DT_YUV422;
cfg->data_width = IPU_CSI_DATA_WIDTH_16; cfg->data_width = IPU_CSI_DATA_WIDTH_16;
break; break;
case V4L2_MBUS_FMT_YUYV8_1X16: case MEDIA_BUS_FMT_YUYV8_1X16:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
cfg->mipi_dt = MIPI_DT_YUV422; cfg->mipi_dt = MIPI_DT_YUV422;
cfg->data_width = IPU_CSI_DATA_WIDTH_16; cfg->data_width = IPU_CSI_DATA_WIDTH_16;
break; break;
case V4L2_MBUS_FMT_SBGGR8_1X8: case MEDIA_BUS_FMT_SBGGR8_1X8:
case V4L2_MBUS_FMT_SGBRG8_1X8: case MEDIA_BUS_FMT_SGBRG8_1X8:
case V4L2_MBUS_FMT_SGRBG8_1X8: case MEDIA_BUS_FMT_SGRBG8_1X8:
case V4L2_MBUS_FMT_SRGGB8_1X8: case MEDIA_BUS_FMT_SRGGB8_1X8:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
cfg->mipi_dt = MIPI_DT_RAW8; cfg->mipi_dt = MIPI_DT_RAW8;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8: case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8:
case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8: case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8:
case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8: case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8:
case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE:
case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE:
case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
cfg->mipi_dt = MIPI_DT_RAW10; cfg->mipi_dt = MIPI_DT_RAW10;
cfg->data_width = IPU_CSI_DATA_WIDTH_8; cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break; break;
case V4L2_MBUS_FMT_SBGGR10_1X10: case MEDIA_BUS_FMT_SBGGR10_1X10:
case V4L2_MBUS_FMT_SGBRG10_1X10: case MEDIA_BUS_FMT_SGBRG10_1X10:
case V4L2_MBUS_FMT_SGRBG10_1X10: case MEDIA_BUS_FMT_SGRBG10_1X10:
case V4L2_MBUS_FMT_SRGGB10_1X10: case MEDIA_BUS_FMT_SRGGB10_1X10:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
cfg->mipi_dt = MIPI_DT_RAW10; cfg->mipi_dt = MIPI_DT_RAW10;
cfg->data_width = IPU_CSI_DATA_WIDTH_10; cfg->data_width = IPU_CSI_DATA_WIDTH_10;
break; break;
case V4L2_MBUS_FMT_SBGGR12_1X12: case MEDIA_BUS_FMT_SBGGR12_1X12:
case V4L2_MBUS_FMT_SGBRG12_1X12: case MEDIA_BUS_FMT_SGBRG12_1X12:
case V4L2_MBUS_FMT_SGRBG12_1X12: case MEDIA_BUS_FMT_SGRBG12_1X12:
case V4L2_MBUS_FMT_SRGGB12_1X12: case MEDIA_BUS_FMT_SRGGB12_1X12:
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
cfg->mipi_dt = MIPI_DT_RAW12; cfg->mipi_dt = MIPI_DT_RAW12;
cfg->data_width = IPU_CSI_DATA_WIDTH_12; cfg->data_width = IPU_CSI_DATA_WIDTH_12;
break; break;
case V4L2_MBUS_FMT_JPEG_1X8: case MEDIA_BUS_FMT_JPEG_1X8:
/* TODO */ /* TODO */
cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_JPEG; cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_JPEG;
cfg->mipi_dt = MIPI_DT_RAW8; cfg->mipi_dt = MIPI_DT_RAW8;
......
...@@ -931,6 +931,35 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) ...@@ -931,6 +931,35 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
} }
} }
/* Check for correctness of the ctrl's value based on the data from
struct v4l2_queryctrl and the available menu items. Note that
menu_items may be NULL, in that case it is ignored. */
static int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
const char * const *menu_items)
{
if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
return -EINVAL;
if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
return -EBUSY;
if (qctrl->type == V4L2_CTRL_TYPE_STRING)
return 0;
if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
return 0;
if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
return -ERANGE;
if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
if (menu_items[ctrl->value] == NULL ||
menu_items[ctrl->value][0] == '\0')
return -EINVAL;
}
if (qctrl->type == V4L2_CTRL_TYPE_BITMASK &&
(ctrl->value & ~qctrl->maximum))
return -ERANGE;
return 0;
}
int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy, int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
struct v4l2_ext_controls *ctrls, unsigned int cmd) struct v4l2_ext_controls *ctrls, unsigned int cmd)
{ {
......
...@@ -71,7 +71,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, ...@@ -71,7 +71,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
if (saa7146_read(dev, MC2) & 2) if (saa7146_read(dev, MC2) & 2)
break; break;
if (err) { if (err) {
pr_err("%s: %s timed out while waiting for registers getting programmed\n", pr_debug("%s: %s timed out while waiting for registers getting programmed\n",
dev->name, __func__); dev->name, __func__);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
......
...@@ -107,8 +107,7 @@ int sms_ir_init(struct smscore_device_t *coredev) ...@@ -107,8 +107,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
void sms_ir_exit(struct smscore_device_t *coredev) void sms_ir_exit(struct smscore_device_t *coredev)
{ {
if (coredev->ir.dev) rc_unregister_device(coredev->ir.dev);
rc_unregister_device(coredev->ir.dev);
sms_log(""); sms_log("");
} }
...@@ -286,9 +286,17 @@ static const struct { ...@@ -286,9 +286,17 @@ static const struct {
{ TUNER_ABSENT, "Xceive XC5200C"}, { TUNER_ABSENT, "Xceive XC5200C"},
{ TUNER_ABSENT, "NXP 18273"}, { TUNER_ABSENT, "NXP 18273"},
{ TUNER_ABSENT, "Montage M88TS2022"}, { TUNER_ABSENT, "Montage M88TS2022"},
/* 180-189 */ /* 180-188 */
{ TUNER_ABSENT, "NXP 18272M"}, { TUNER_ABSENT, "NXP 18272M"},
{ TUNER_ABSENT, "NXP 18272S"}, { TUNER_ABSENT, "NXP 18272S"},
{ TUNER_ABSENT, "Mirics MSi003"},
{ TUNER_ABSENT, "MaxLinear MxL256"},
{ TUNER_ABSENT, "SiLabs Si2158"},
{ TUNER_ABSENT, "SiLabs Si2178"},
{ TUNER_ABSENT, "SiLabs Si2157"},
{ TUNER_ABSENT, "SiLabs Si2177"},
{ TUNER_ABSENT, "ITE IT9137FN"},
}; };
/* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are /* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are
...@@ -351,6 +359,16 @@ static const struct { ...@@ -351,6 +359,16 @@ static const struct {
{ TVEEPROM_AUDPROC_INTERNAL, "CX23887" }, { TVEEPROM_AUDPROC_INTERNAL, "CX23887" },
{ TVEEPROM_AUDPROC_INTERNAL, "SAA7164" }, { TVEEPROM_AUDPROC_INTERNAL, "SAA7164" },
{ TVEEPROM_AUDPROC_INTERNAL, "AU8522" }, { TVEEPROM_AUDPROC_INTERNAL, "AU8522" },
/* 45-49 */
{ TVEEPROM_AUDPROC_INTERNAL, "AVF4910B" },
{ TVEEPROM_AUDPROC_INTERNAL, "SAA7231" },
{ TVEEPROM_AUDPROC_INTERNAL, "CX23102" },
{ TVEEPROM_AUDPROC_INTERNAL, "SAA7163" },
{ TVEEPROM_AUDPROC_OTHER, "AK4113" },
/* 50-52 */
{ TVEEPROM_AUDPROC_OTHER, "CS5340" },
{ TVEEPROM_AUDPROC_OTHER, "CS8416" },
{ TVEEPROM_AUDPROC_OTHER, "CX20810" },
}; };
/* This list is supplied by Hauppauge. Thanks! */ /* This list is supplied by Hauppauge. Thanks! */
...@@ -371,8 +389,12 @@ static const char *decoderIC[] = { ...@@ -371,8 +389,12 @@ static const char *decoderIC[] = {
"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888", "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
/* 35-39 */ /* 35-39 */
"SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A", "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
/* 40-42 */ /* 40-44 */
"SAA7164", "CX23885B", "AU8522" "SAA7164", "CX23885B", "AU8522", "ADV7401", "AVF4910B",
/* 45-49 */
"SAA7231", "CX23102", "SAA7163", "ADV7441A", "ADV7181C",
/* 50-53 */
"CX25836", "TDA9955", "TDA19977", "ADV7842"
}; };
static int hasRadioTuner(int tunerType) static int hasRadioTuner(int tunerType)
...@@ -548,10 +570,10 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, ...@@ -548,10 +570,10 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
tvee->serial_number = tvee->serial_number =
eeprom_data[i+5] + eeprom_data[i+5] +
(eeprom_data[i+6] << 8) + (eeprom_data[i+6] << 8) +
(eeprom_data[i+7] << 16); (eeprom_data[i+7] << 16)+
(eeprom_data[i+8] << 24);
if ((eeprom_data[i + 8] & 0xf0) && if (eeprom_data[i + 8] == 0xf0) {
(tvee->serial_number < 0xffffff)) {
tvee->MAC_address[0] = 0x00; tvee->MAC_address[0] = 0x00;
tvee->MAC_address[1] = 0x0D; tvee->MAC_address[1] = 0x0D;
tvee->MAC_address[2] = 0xFE; tvee->MAC_address[2] = 0xFE;
...@@ -696,7 +718,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, ...@@ -696,7 +718,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
} }
} }
tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", tveeprom_info("Hauppauge model %d, rev %s, serial# %u\n",
tvee->model, tvee->rev_str, tvee->serial_number); tvee->model, tvee->rev_str, tvee->serial_number);
if (tvee->has_MAC_address == 1) if (tvee->has_MAC_address == 1)
tveeprom_info("MAC address is %pM\n", tvee->MAC_address); tveeprom_info("MAC address is %pM\n", tvee->MAC_address);
......
...@@ -356,6 +356,7 @@ ...@@ -356,6 +356,7 @@
#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
#define USB_PID_SONY_PLAYTV 0x0003 #define USB_PID_SONY_PLAYTV 0x0003
#define USB_PID_MYGICA_D689 0xd811 #define USB_PID_MYGICA_D689 0xd811
#define USB_PID_MYGICA_T230 0xc688
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011 #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
#define USB_PID_ELGATO_EYETV_DTT 0x0021 #define USB_PID_ELGATO_EYETV_DTT 0x0021
#define USB_PID_ELGATO_EYETV_DTT_2 0x003f #define USB_PID_ELGATO_EYETV_DTT_2 0x003f
......
...@@ -379,7 +379,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) ...@@ -379,7 +379,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
/* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */ /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */
if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) { if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) {
printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
priv->ts_count, ts[0], ts[1] & TS_TEI >> 7, ts[3] & 0xC0 >> 6); priv->ts_count, ts[0],
(ts[1] & TS_TEI) >> 7,
(ts[3] & TS_SC) >> 6);
/* Drop partly decoded SNDU, reset state, resync on PUSI. */ /* Drop partly decoded SNDU, reset state, resync on PUSI. */
if (priv->ule_skb) { if (priv->ule_skb) {
......
...@@ -648,12 +648,15 @@ config DVB_MB86A20S ...@@ -648,12 +648,15 @@ config DVB_MB86A20S
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator. A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend. Say Y when you want to support this frontend.
comment "ISDB-S (satellite) & ISDB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_TC90522 config DVB_TC90522
tristate "Toshiba TC90522" tristate "Toshiba TC90522"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT default m if !MEDIA_SUBDRV_AUTOSELECT
help help
A Toshiba TC90522 2xISDB-T + 2xISDB-S demodulator. Toshiba TC90522 2xISDB-S 8PSK + 2xISDB-T OFDM demodulator.
Say Y when you want to support this frontend. Say Y when you want to support this frontend.
comment "Digital terrestrial only tuners/PLL" comment "Digital terrestrial only tuners/PLL"
......
...@@ -291,6 +291,12 @@ static int af9033_init(struct dvb_frontend *fe) ...@@ -291,6 +291,12 @@ static int af9033_init(struct dvb_frontend *fe)
if (clock_adc_lut[i].clock == dev->cfg.clock) if (clock_adc_lut[i].clock == dev->cfg.clock)
break; break;
} }
if (i == ARRAY_SIZE(clock_adc_lut)) {
dev_err(&dev->client->dev,
"Couldn't find ADC config for clock=%d\n",
dev->cfg.clock);
goto err;
}
adc_cw = af9033_div(dev, clock_adc_lut[i].adc, 1000000ul, 19ul); adc_cw = af9033_div(dev, clock_adc_lut[i].adc, 1000000ul, 19ul);
buf[0] = (adc_cw >> 0) & 0xff; buf[0] = (adc_cw >> 0) & 0xff;
...@@ -580,7 +586,15 @@ static int af9033_set_frontend(struct dvb_frontend *fe) ...@@ -580,7 +586,15 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
break; break;
} }
} }
ret = af9033_wr_regs(dev, 0x800001, if (i == ARRAY_SIZE(coeff_lut)) {
dev_err(&dev->client->dev,
"Couldn't find LUT config for clock=%d\n",
dev->cfg.clock);
ret = -EINVAL;
goto err;
}
ret = af9033_wr_regs(dev, 0x800001,
coeff_lut[i].val, sizeof(coeff_lut[i].val)); coeff_lut[i].val, sizeof(coeff_lut[i].val));
} }
...@@ -592,6 +606,13 @@ static int af9033_set_frontend(struct dvb_frontend *fe) ...@@ -592,6 +606,13 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
if (clock_adc_lut[i].clock == dev->cfg.clock) if (clock_adc_lut[i].clock == dev->cfg.clock)
break; break;
} }
if (i == ARRAY_SIZE(clock_adc_lut)) {
dev_err(&dev->client->dev,
"Couldn't find ADC clock for clock=%d\n",
dev->cfg.clock);
ret = -EINVAL;
goto err;
}
adc_freq = clock_adc_lut[i].adc; adc_freq = clock_adc_lut[i].adc;
/* get used IF frequency */ /* get used IF frequency */
...@@ -849,29 +870,97 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr) ...@@ -849,29 +870,97 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
{ {
struct af9033_dev *dev = fe->demodulator_priv; struct af9033_dev *dev = fe->demodulator_priv;
struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache; struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
int ret;
u8 u8tmp;
/* use DVBv5 CNR */ /* use DVBv5 CNR */
if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) {
*snr = div_s64(c->cnr.stat[0].svalue, 100); /* 1000x => 10x */ /* Return 0.1 dB for AF9030 and 0-0xffff for IT9130. */
else if (dev->is_af9035) {
/* 1000x => 10x (0.1 dB) */
*snr = div_s64(c->cnr.stat[0].svalue, 100);
} else {
/* 1000x => 1x (1 dB) */
*snr = div_s64(c->cnr.stat[0].svalue, 1000);
/* read current modulation */
ret = af9033_rd_reg(dev, 0x80f903, &u8tmp);
if (ret)
goto err;
/* scale value to 0x0000-0xffff */
switch ((u8tmp >> 0) & 3) {
case 0:
*snr = *snr * 0xffff / 23;
break;
case 1:
*snr = *snr * 0xffff / 26;
break;
case 2:
*snr = *snr * 0xffff / 32;
break;
default:
goto err;
}
}
} else {
*snr = 0; *snr = 0;
}
return 0; return 0;
err:
dev_dbg(&dev->client->dev, "failed=%d\n", ret);
return ret;
} }
static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{ {
struct af9033_dev *dev = fe->demodulator_priv; struct af9033_dev *dev = fe->demodulator_priv;
int ret; struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
u8 strength2; int ret, tmp, power_real;
u8 u8tmp, gain_offset, buf[7];
/* read signal strength of 0-100 scale */ if (dev->is_af9035) {
ret = af9033_rd_reg(dev, 0x800048, &strength2); /* read signal strength of 0-100 scale */
if (ret < 0) ret = af9033_rd_reg(dev, 0x800048, &u8tmp);
goto err; if (ret < 0)
goto err;
/* scale value to 0x0000-0xffff */
*strength = u8tmp * 0xffff / 100;
} else {
ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp);
if (ret < 0)
goto err;
ret = af9033_rd_regs(dev, 0x80f900, buf, 7);
if (ret < 0)
goto err;
if (c->frequency <= 300000000)
gain_offset = 7; /* VHF */
else
gain_offset = 4; /* UHF */
power_real = (u8tmp - 100 - gain_offset) -
power_reference[((buf[3] >> 0) & 3)][((buf[6] >> 0) & 7)];
if (power_real < -15)
tmp = 0;
else if ((power_real >= -15) && (power_real < 0))
tmp = (2 * (power_real + 15)) / 3;
else if ((power_real >= 0) && (power_real < 20))
tmp = 4 * power_real + 10;
else if ((power_real >= 20) && (power_real < 35))
tmp = (2 * (power_real - 20)) / 3 + 90;
else
tmp = 100;
/* scale value to 0x0000-0xffff */ /* scale value to 0x0000-0xffff */
*strength = strength2 * 0xffff / 100; *strength = tmp * 0xffff / 100;
}
return 0; return 0;
...@@ -1011,6 +1100,33 @@ static void af9033_stat_work(struct work_struct *work) ...@@ -1011,6 +1100,33 @@ static void af9033_stat_work(struct work_struct *work)
snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0); snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
/* read superframe number */
ret = af9033_rd_reg(dev, 0x80f78b, &u8tmp);
if (ret)
goto err;
if (u8tmp)
snr_val /= u8tmp;
/* read current transmission mode */
ret = af9033_rd_reg(dev, 0x80f900, &u8tmp);
if (ret)
goto err;
switch ((u8tmp >> 0) & 3) {
case 0:
snr_val *= 4;
break;
case 1:
snr_val *= 1;
break;
case 2:
snr_val *= 2;
break;
default:
goto err_schedule_delayed_work;
}
/* read current modulation */ /* read current modulation */
ret = af9033_rd_reg(dev, 0x80f903, &u8tmp); ret = af9033_rd_reg(dev, 0x80f903, &u8tmp);
if (ret) if (ret)
......
...@@ -181,7 +181,10 @@ static const struct val_snr qam64_snr_lut[] = { ...@@ -181,7 +181,10 @@ static const struct val_snr qam64_snr_lut[] = {
{ 0x05570d, 26 }, { 0x05570d, 26 },
{ 0x059feb, 27 }, { 0x059feb, 27 },
{ 0x05bf38, 28 }, { 0x05bf38, 28 },
{ 0xffffff, 29 }, { 0x05f78f, 29 },
{ 0x0612c3, 30 },
{ 0x0626be, 31 },
{ 0xffffff, 32 },
}; };
static const struct reg_val ofsm_init[] = { static const struct reg_val ofsm_init[] = {
...@@ -2051,4 +2054,10 @@ static const struct reg_val tuner_init_it9135_62[] = { ...@@ -2051,4 +2054,10 @@ static const struct reg_val tuner_init_it9135_62[] = {
{ 0x80fd8b, 0x00 }, { 0x80fd8b, 0x00 },
}; };
/* NorDig power reference table */
static const int power_reference[][5] = {
{-93, -91, -90, -89, -88}, /* QPSK 1/2 ~ 7/8 */
{-87, -85, -84, -83, -82}, /* 16QAM 1/2 ~ 7/8 */
{-82, -80, -78, -77, -76}, /* 64QAM 1/2 ~ 7/8 */
};
#endif /* AF9033_PRIV_H */ #endif /* AF9033_PRIV_H */
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "au8522_priv.h" #include "au8522_priv.h"
static int debug; static int debug;
static int zv_mode = 1; /* default to on */
#define dprintk(arg...)\ #define dprintk(arg...)\
do { if (debug)\ do { if (debug)\
...@@ -469,6 +470,87 @@ static struct { ...@@ -469,6 +470,87 @@ static struct {
{ 0x8526, 0x01 }, { 0x8526, 0x01 },
}; };
static struct {
u16 reg;
u16 data;
} QAM256_mod_tab_zv_mode[] = {
{ 0x80a3, 0x09 },
{ 0x80a4, 0x00 },
{ 0x8081, 0xc4 },
{ 0x80a5, 0x40 },
{ 0x80b5, 0xfb },
{ 0x80b6, 0x8e },
{ 0x80b7, 0x39 },
{ 0x80aa, 0x77 },
{ 0x80ad, 0x77 },
{ 0x80a6, 0x67 },
{ 0x8262, 0x20 },
{ 0x821c, 0x30 },
{ 0x80b8, 0x3e },
{ 0x80b9, 0xf0 },
{ 0x80ba, 0x01 },
{ 0x80bb, 0x18 },
{ 0x80bc, 0x50 },
{ 0x80bd, 0x00 },
{ 0x80be, 0xea },
{ 0x80bf, 0xef },
{ 0x80c0, 0xfc },
{ 0x80c1, 0xbd },
{ 0x80c2, 0x1f },
{ 0x80c3, 0xfc },
{ 0x80c4, 0xdd },
{ 0x80c5, 0xaf },
{ 0x80c6, 0x00 },
{ 0x80c7, 0x38 },
{ 0x80c8, 0x30 },
{ 0x80c9, 0x05 },
{ 0x80ca, 0x4a },
{ 0x80cb, 0xd0 },
{ 0x80cc, 0x01 },
{ 0x80cd, 0xd9 },
{ 0x80ce, 0x6f },
{ 0x80cf, 0xf9 },
{ 0x80d0, 0x70 },
{ 0x80d1, 0xdf },
{ 0x80d2, 0xf7 },
{ 0x80d3, 0xc2 },
{ 0x80d4, 0xdf },
{ 0x80d5, 0x02 },
{ 0x80d6, 0x9a },
{ 0x80d7, 0xd0 },
{ 0x8250, 0x0d },
{ 0x8251, 0xcd },
{ 0x8252, 0xe0 },
{ 0x8253, 0x05 },
{ 0x8254, 0xa7 },
{ 0x8255, 0xff },
{ 0x8256, 0xed },
{ 0x8257, 0x5b },
{ 0x8258, 0xae },
{ 0x8259, 0xe6 },
{ 0x825a, 0x3d },
{ 0x825b, 0x0f },
{ 0x825c, 0x0d },
{ 0x825d, 0xea },
{ 0x825e, 0xf2 },
{ 0x825f, 0x51 },
{ 0x8260, 0xf5 },
{ 0x8261, 0x06 },
{ 0x821a, 0x01 },
{ 0x8546, 0x40 },
{ 0x8210, 0x26 },
{ 0x8211, 0xf6 },
{ 0x8212, 0x84 },
{ 0x8213, 0x02 },
{ 0x8502, 0x01 },
{ 0x8121, 0x04 },
{ 0x8122, 0x04 },
{ 0x852e, 0x10 },
{ 0x80a4, 0xca },
{ 0x80a7, 0x40 },
{ 0x8526, 0x01 },
};
static int au8522_enable_modulation(struct dvb_frontend *fe, static int au8522_enable_modulation(struct dvb_frontend *fe,
fe_modulation_t m) fe_modulation_t m)
{ {
...@@ -495,12 +577,23 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, ...@@ -495,12 +577,23 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_set_if(fe, state->config->qam_if); au8522_set_if(fe, state->config->qam_if);
break; break;
case QAM_256: case QAM_256:
dprintk("%s() QAM 256\n", __func__); if (zv_mode) {
for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++) dprintk("%s() QAM 256 (zv_mode)\n", __func__);
au8522_writereg(state, for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab_zv_mode); i++)
QAM256_mod_tab[i].reg, au8522_writereg(state,
QAM256_mod_tab[i].data); QAM256_mod_tab_zv_mode[i].reg,
au8522_set_if(fe, state->config->qam_if); QAM256_mod_tab_zv_mode[i].data);
au8522_set_if(fe, state->config->qam_if);
msleep(100);
au8522_writereg(state, 0x821a, 0x00);
} else {
dprintk("%s() QAM 256\n", __func__);
for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++)
au8522_writereg(state,
QAM256_mod_tab[i].reg,
QAM256_mod_tab[i].data);
au8522_set_if(fe, state->config->qam_if);
}
break; break;
default: default:
dprintk("%s() Invalid modulation\n", __func__); dprintk("%s() Invalid modulation\n", __func__);
...@@ -537,7 +630,12 @@ static int au8522_set_frontend(struct dvb_frontend *fe) ...@@ -537,7 +630,12 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
return ret; return ret;
/* Allow the tuner to settle */ /* Allow the tuner to settle */
msleep(100); if (zv_mode) {
dprintk("%s() increase tuner settling time for zv_mode\n",
__func__);
msleep(250);
} else
msleep(100);
au8522_enable_modulation(fe, c->modulation); au8522_enable_modulation(fe, c->modulation);
...@@ -823,6 +921,11 @@ static struct dvb_frontend_ops au8522_ops = { ...@@ -823,6 +921,11 @@ static struct dvb_frontend_ops au8522_ops = {
module_param(debug, int, 0644); module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Enable verbose debug messages"); MODULE_PARM_DESC(debug, "Enable verbose debug messages");
module_param(zv_mode, int, 0644);
MODULE_PARM_DESC(zv_mode, "Turn on/off ZeeVee modulator compatability mode (default:on).\n"
"\t\ton - modified AU8522 QAM256 initialization.\n"
"\t\tProvides faster lock when using ZeeVee modulator based sources");
MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
MODULE_AUTHOR("Steven Toth"); MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -169,6 +169,9 @@ static int cx22700_set_tps(struct cx22700_state *state, ...@@ -169,6 +169,9 @@ static int cx22700_set_tps(struct cx22700_state *state,
cx22700_writereg (state, 0x04, val); cx22700_writereg (state, 0x04, val);
if (p->code_rate_HP - FEC_1_2 >= sizeof(fec_tab) ||
p->code_rate_LP - FEC_1_2 >= sizeof(fec_tab))
return -EINVAL;
val = fec_tab[p->code_rate_HP - FEC_1_2] << 3; val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
val |= fec_tab[p->code_rate_LP - FEC_1_2]; val |= fec_tab[p->code_rate_LP - FEC_1_2];
......
...@@ -177,47 +177,45 @@ static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inver ...@@ -177,47 +177,45 @@ static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inver
return 0; return 0;
} }
static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec) static int cx24110_set_fec(struct cx24110_state* state, fe_code_rate_t fec)
{ {
/* fixme (low): error handling */ static const int rate[FEC_AUTO] = {-1, 1, 2, 3, 5, 7, -1};
static const int g1[FEC_AUTO] = {-1, 0x01, 0x02, 0x05, 0x15, 0x45, -1};
static const int rate[]={-1,1,2,3,5,7,-1}; static const int g2[FEC_AUTO] = {-1, 0x01, 0x03, 0x06, 0x1a, 0x7a, -1};
static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
/* Well, the AutoAcq engine of the cx24106 and 24110 automatically /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
searches all enabled viterbi rates, and can handle non-standard searches all enabled viterbi rates, and can handle non-standard
rates as well. */ rates as well. */
if (fec>FEC_AUTO) if (fec > FEC_AUTO)
fec=FEC_AUTO; fec = FEC_AUTO;
if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */ if (fec == FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf); cx24110_writereg(state, 0x37, cx24110_readreg(state, 0x37) & 0xdf);
/* clear AcqVitDis bit */ /* clear AcqVitDis bit */
cx24110_writereg(state,0x18,0xae); cx24110_writereg(state, 0x18, 0xae);
/* allow all DVB standard code rates */ /* allow all DVB standard code rates */
cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3); cx24110_writereg(state, 0x05, (cx24110_readreg(state, 0x05) & 0xf0) | 0x3);
/* set nominal Viterbi rate 3/4 */ /* set nominal Viterbi rate 3/4 */
cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3); cx24110_writereg(state, 0x22, (cx24110_readreg(state, 0x22) & 0xf0) | 0x3);
/* set current Viterbi rate 3/4 */ /* set current Viterbi rate 3/4 */
cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06); cx24110_writereg(state, 0x1a, 0x05);
cx24110_writereg(state, 0x1b, 0x06);
/* set the puncture registers for code rate 3/4 */ /* set the puncture registers for code rate 3/4 */
return 0; return 0;
} else { } else {
cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20); cx24110_writereg(state, 0x37, cx24110_readreg(state, 0x37) | 0x20);
/* set AcqVitDis bit */ /* set AcqVitDis bit */
if(rate[fec]>0) { if (rate[fec] < 0)
cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]); return -EINVAL;
/* set nominal Viterbi rate */
cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]); cx24110_writereg(state, 0x05, (cx24110_readreg(state, 0x05) & 0xf0) | rate[fec]);
/* set current Viterbi rate */ /* set nominal Viterbi rate */
cx24110_writereg(state,0x1a,g1[fec]); cx24110_writereg(state, 0x22, (cx24110_readreg(state, 0x22) & 0xf0) | rate[fec]);
cx24110_writereg(state,0x1b,g2[fec]); /* set current Viterbi rate */
/* not sure if this is the right way: I always used AutoAcq mode */ cx24110_writereg(state, 0x1a, g1[fec]);
} else cx24110_writereg(state, 0x1b, g2[fec]);
return -EOPNOTSUPP; /* not sure if this is the right way: I always used AutoAcq mode */
/* fixme (low): which is the correct return code? */
} }
return 0; return 0;
} }
......
...@@ -459,7 +459,7 @@ static int cx24117_firmware_ondemand(struct dvb_frontend *fe) ...@@ -459,7 +459,7 @@ static int cx24117_firmware_ondemand(struct dvb_frontend *fe)
if (state->priv->skip_fw_load) if (state->priv->skip_fw_load)
return 0; return 0;
/* check if firmware if already running */ /* check if firmware is already running */
if (cx24117_readreg(state, 0xeb) != 0xa) { if (cx24117_readreg(state, 0xeb) != 0xa) {
/* Load firmware */ /* Load firmware */
/* request the firmware, this will block until loaded */ /* request the firmware, this will block until loaded */
......
...@@ -1780,7 +1780,7 @@ static u32 interpolate_value(u32 value, struct linear_segments *segments, ...@@ -1780,7 +1780,7 @@ static u32 interpolate_value(u32 value, struct linear_segments *segments,
} }
/* FIXME: may require changes - this one was borrowed from dib8000 */ /* FIXME: may require changes - this one was borrowed from dib8000 */
static u32 dib7000p_get_time_us(struct dvb_frontend *demod, int layer) static u32 dib7000p_get_time_us(struct dvb_frontend *demod)
{ {
struct dtv_frontend_properties *c = &demod->dtv_property_cache; struct dtv_frontend_properties *c = &demod->dtv_property_cache;
u64 time_us, tmp64; u64 time_us, tmp64;
...@@ -1881,7 +1881,6 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) ...@@ -1881,7 +1881,6 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
{ {
struct dib7000p_state *state = demod->demodulator_priv; struct dib7000p_state *state = demod->demodulator_priv;
struct dtv_frontend_properties *c = &demod->dtv_property_cache; struct dtv_frontend_properties *c = &demod->dtv_property_cache;
int i;
int show_per_stats = 0; int show_per_stats = 0;
u32 time_us = 0, val, snr; u32 time_us = 0, val, snr;
u64 blocks, ucb; u64 blocks, ucb;
...@@ -1935,7 +1934,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) ...@@ -1935,7 +1934,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
/* Estimate the number of packets based on bitrate */ /* Estimate the number of packets based on bitrate */
if (!time_us) if (!time_us)
time_us = dib7000p_get_time_us(demod, -1); time_us = dib7000p_get_time_us(demod);
if (time_us) { if (time_us) {
blocks = 1250000ULL * 1000000ULL; blocks = 1250000ULL * 1000000ULL;
...@@ -1949,7 +1948,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) ...@@ -1949,7 +1948,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
/* Get post-BER measures */ /* Get post-BER measures */
if (time_after(jiffies, state->ber_jiffies_stats)) { if (time_after(jiffies, state->ber_jiffies_stats)) {
time_us = dib7000p_get_time_us(demod, -1); time_us = dib7000p_get_time_us(demod);
state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
dprintk("Next all layers stats available in %u us.", time_us); dprintk("Next all layers stats available in %u us.", time_us);
...@@ -1969,7 +1968,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) ...@@ -1969,7 +1968,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
c->block_error.stat[0].scale = FE_SCALE_COUNTER; c->block_error.stat[0].scale = FE_SCALE_COUNTER;
c->block_error.stat[0].uvalue += val; c->block_error.stat[0].uvalue += val;
time_us = dib7000p_get_time_us(demod, i); time_us = dib7000p_get_time_us(demod);
if (time_us) { if (time_us) {
blocks = 1250000ULL * 1000000ULL; blocks = 1250000ULL * 1000000ULL;
do_div(blocks, time_us * 8 * 204); do_div(blocks, time_us * 8 * 204);
......
...@@ -12255,8 +12255,7 @@ static void drx39xxj_release(struct dvb_frontend *fe) ...@@ -12255,8 +12255,7 @@ static void drx39xxj_release(struct dvb_frontend *fe)
kfree(demod->my_ext_attr); kfree(demod->my_ext_attr);
kfree(demod->my_common_attr); kfree(demod->my_common_attr);
kfree(demod->my_i2c_dev_addr); kfree(demod->my_i2c_dev_addr);
if (demod->firmware) release_firmware(demod->firmware);
release_firmware(demod->firmware);
kfree(demod); kfree(demod);
kfree(state); kfree(state);
} }
......
...@@ -166,9 +166,9 @@ static unsigned int debug; ...@@ -166,9 +166,9 @@ static unsigned int debug;
module_param(debug, int, 0644); module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages"); MODULE_PARM_DESC(debug, "enable debug messages");
#define dprintk(level, fmt, arg...) do { \ #define dprintk(level, fmt, arg...) do { \
if (debug >= level) \ if (debug >= level) \
pr_debug(fmt, ##arg); \ printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \
} while (0) } while (0)
...@@ -6310,8 +6310,7 @@ static void drxk_release(struct dvb_frontend *fe) ...@@ -6310,8 +6310,7 @@ static void drxk_release(struct dvb_frontend *fe)
struct drxk_state *state = fe->demodulator_priv; struct drxk_state *state = fe->demodulator_priv;
dprintk(1, "\n"); dprintk(1, "\n");
if (state->fw) release_firmware(state->fw);
release_firmware(state->fw);
kfree(state); kfree(state);
} }
......
/* /*
* Montage M88DS3103 demodulator driver * Montage M88DS3103/M88RS6000 demodulator driver
* *
* Copyright (C) 2013 Antti Palosaari <crope@iki.fi> * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
* *
...@@ -162,7 +162,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv, ...@@ -162,7 +162,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv,
dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len); dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
if (tab_len > 83) { if (tab_len > 86) {
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
...@@ -245,9 +245,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -245,9 +245,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, len; int ret, len;
const struct m88ds3103_reg_val *init; const struct m88ds3103_reg_val *init;
u8 u8tmp, u8tmp1, u8tmp2; u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */
u8 buf[2]; u8 buf[3];
u16 u16tmp, divide_ratio; u16 u16tmp, divide_ratio = 0;
u32 tuner_frequency, target_mclk; u32 tuner_frequency, target_mclk;
s32 s32tmp; s32 s32tmp;
...@@ -262,6 +262,22 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -262,6 +262,22 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
goto err; goto err;
} }
/* reset */
ret = m88ds3103_wr_reg(priv, 0x07, 0x80);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
if (ret)
goto err;
/* Disable demod clock path */
if (priv->chip_id == M88RS6000_CHIP_ID) {
ret = m88ds3103_wr_reg(priv, 0x06, 0xe0);
if (ret)
goto err;
}
/* program tuner */ /* program tuner */
if (fe->ops.tuner_ops.set_params) { if (fe->ops.tuner_ops.set_params) {
ret = fe->ops.tuner_ops.set_params(fe); ret = fe->ops.tuner_ops.set_params(fe);
...@@ -282,49 +298,44 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -282,49 +298,44 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
tuner_frequency = c->frequency; tuner_frequency = c->frequency;
} }
/* reset */ /* select M88RS6000 demod main mclk and ts mclk from tuner die. */
ret = m88ds3103_wr_reg(priv, 0x07, 0x80); if (priv->chip_id == M88RS6000_CHIP_ID) {
if (ret) if (c->symbol_rate > 45010000)
goto err; priv->mclk_khz = 110250;
else
ret = m88ds3103_wr_reg(priv, 0x07, 0x00); priv->mclk_khz = 96000;
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0x00, 0x01); if (c->delivery_system == SYS_DVBS)
if (ret) target_mclk = 96000;
goto err; else
target_mclk = 144000;
switch (c->delivery_system) { /* Enable demod clock path */
case SYS_DVBS: ret = m88ds3103_wr_reg(priv, 0x06, 0x00);
len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals); if (ret)
init = m88ds3103_dvbs_init_reg_vals; goto err;
target_mclk = 96000; usleep_range(10000, 20000);
break; } else {
case SYS_DVBS2: /* set M88DS3103 mclk and ts mclk. */
len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals); priv->mclk_khz = 96000;
init = m88ds3103_dvbs2_init_reg_vals;
switch (priv->cfg->ts_mode) { switch (priv->cfg->ts_mode) {
case M88DS3103_TS_SERIAL: case M88DS3103_TS_SERIAL:
case M88DS3103_TS_SERIAL_D7: case M88DS3103_TS_SERIAL_D7:
if (c->symbol_rate < 18000000) target_mclk = priv->cfg->ts_clk;
target_mclk = 96000;
else
target_mclk = 144000;
break; break;
case M88DS3103_TS_PARALLEL: case M88DS3103_TS_PARALLEL:
case M88DS3103_TS_CI: case M88DS3103_TS_CI:
if (c->symbol_rate < 18000000) if (c->delivery_system == SYS_DVBS)
target_mclk = 96000; target_mclk = 96000;
else if (c->symbol_rate < 28000000) else {
target_mclk = 144000; if (c->symbol_rate < 18000000)
else target_mclk = 96000;
target_mclk = 192000; else if (c->symbol_rate < 28000000)
target_mclk = 144000;
else
target_mclk = 192000;
}
break; break;
default: default:
dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n",
...@@ -332,6 +343,55 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -332,6 +343,55 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
switch (target_mclk) {
case 96000:
u8tmp1 = 0x02; /* 0b10 */
u8tmp2 = 0x01; /* 0b01 */
break;
case 144000:
u8tmp1 = 0x00; /* 0b00 */
u8tmp2 = 0x01; /* 0b01 */
break;
case 192000:
u8tmp1 = 0x03; /* 0b11 */
u8tmp2 = 0x00; /* 0b00 */
break;
}
ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0);
if (ret)
goto err;
ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0);
if (ret)
goto err;
}
ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0x00, 0x01);
if (ret)
goto err;
switch (c->delivery_system) {
case SYS_DVBS:
if (priv->chip_id == M88RS6000_CHIP_ID) {
len = ARRAY_SIZE(m88rs6000_dvbs_init_reg_vals);
init = m88rs6000_dvbs_init_reg_vals;
} else {
len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals);
init = m88ds3103_dvbs_init_reg_vals;
}
break;
case SYS_DVBS2:
if (priv->chip_id == M88RS6000_CHIP_ID) {
len = ARRAY_SIZE(m88rs6000_dvbs2_init_reg_vals);
init = m88rs6000_dvbs2_init_reg_vals;
} else {
len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals);
init = m88ds3103_dvbs2_init_reg_vals;
}
break; break;
default: default:
dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
...@@ -347,7 +407,30 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -347,7 +407,30 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
goto err; goto err;
} }
u8tmp1 = 0; /* silence compiler warning */ if (priv->chip_id == M88RS6000_CHIP_ID) {
if ((c->delivery_system == SYS_DVBS2)
&& ((c->symbol_rate / 1000) <= 5000)) {
ret = m88ds3103_wr_reg(priv, 0xc0, 0x04);
if (ret)
goto err;
buf[0] = 0x09;
buf[1] = 0x22;
buf[2] = 0x88;
ret = m88ds3103_wr_regs(priv, 0x8a, buf, 3);
if (ret)
goto err;
}
ret = m88ds3103_wr_reg_mask(priv, 0x9d, 0x08, 0x08);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xf1, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg_mask(priv, 0x30, 0x80, 0x80);
if (ret)
goto err;
}
switch (priv->cfg->ts_mode) { switch (priv->cfg->ts_mode) {
case M88DS3103_TS_SERIAL: case M88DS3103_TS_SERIAL:
u8tmp1 = 0x00; u8tmp1 = 0x00;
...@@ -383,16 +466,15 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -383,16 +466,15 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
ret = m88ds3103_wr_reg_mask(priv, 0x29, u8tmp1, 0x20); ret = m88ds3103_wr_reg_mask(priv, 0x29, u8tmp1, 0x20);
if (ret) if (ret)
goto err; goto err;
}
if (priv->cfg->ts_clk) {
divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk);
u8tmp1 = divide_ratio / 2;
u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
} else {
divide_ratio = 0;
u8tmp1 = 0; u8tmp1 = 0;
u8tmp2 = 0; u8tmp2 = 0;
break;
default:
if (priv->cfg->ts_clk) {
divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk);
u8tmp1 = divide_ratio / 2;
u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
}
} }
dev_dbg(&priv->i2c->dev, dev_dbg(&priv->i2c->dev,
...@@ -420,29 +502,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -420,29 +502,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
if (ret) if (ret)
goto err; goto err;
switch (target_mclk) {
case 96000:
u8tmp1 = 0x02; /* 0b10 */
u8tmp2 = 0x01; /* 0b01 */
break;
case 144000:
u8tmp1 = 0x00; /* 0b00 */
u8tmp2 = 0x01; /* 0b01 */
break;
case 192000:
u8tmp1 = 0x03; /* 0b11 */
u8tmp2 = 0x00; /* 0b00 */
break;
}
ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0);
if (ret)
goto err;
ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0);
if (ret)
goto err;
if (c->symbol_rate <= 3000000) if (c->symbol_rate <= 3000000)
u8tmp = 0x20; u8tmp = 0x20;
else if (c->symbol_rate <= 10000000) else if (c->symbol_rate <= 10000000)
...@@ -466,7 +525,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -466,7 +525,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
if (ret) if (ret)
goto err; goto err;
u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, M88DS3103_MCLK_KHZ / 2); u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, priv->mclk_khz / 2);
buf[0] = (u16tmp >> 0) & 0xff; buf[0] = (u16tmp >> 0) & 0xff;
buf[1] = (u16tmp >> 8) & 0xff; buf[1] = (u16tmp >> 8) & 0xff;
ret = m88ds3103_wr_regs(priv, 0x61, buf, 2); ret = m88ds3103_wr_regs(priv, 0x61, buf, 2);
...@@ -489,7 +548,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ...@@ -489,7 +548,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
(tuner_frequency - c->frequency)); (tuner_frequency - c->frequency));
s32tmp = 0x10000 * (tuner_frequency - c->frequency); s32tmp = 0x10000 * (tuner_frequency - c->frequency);
s32tmp = DIV_ROUND_CLOSEST(s32tmp, M88DS3103_MCLK_KHZ); s32tmp = DIV_ROUND_CLOSEST(s32tmp, priv->mclk_khz);
if (s32tmp < 0) if (s32tmp < 0)
s32tmp += 0x10000; s32tmp += 0x10000;
...@@ -520,7 +579,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) ...@@ -520,7 +579,7 @@ static int m88ds3103_init(struct dvb_frontend *fe)
struct m88ds3103_priv *priv = fe->demodulator_priv; struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret, len, remaining; int ret, len, remaining;
const struct firmware *fw = NULL; const struct firmware *fw = NULL;
u8 *fw_file = M88DS3103_FIRMWARE; u8 *fw_file;
u8 u8tmp; u8 u8tmp;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__); dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
...@@ -541,15 +600,6 @@ static int m88ds3103_init(struct dvb_frontend *fe) ...@@ -541,15 +600,6 @@ static int m88ds3103_init(struct dvb_frontend *fe)
if (ret) if (ret)
goto err; goto err;
/* reset */
ret = m88ds3103_wr_reg(priv, 0x07, 0x60);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
if (ret)
goto err;
/* firmware status */ /* firmware status */
ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp); ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp);
if (ret) if (ret)
...@@ -560,10 +610,23 @@ static int m88ds3103_init(struct dvb_frontend *fe) ...@@ -560,10 +610,23 @@ static int m88ds3103_init(struct dvb_frontend *fe)
if (u8tmp) if (u8tmp)
goto skip_fw_download; goto skip_fw_download;
/* global reset, global diseqc reset, golbal fec reset */
ret = m88ds3103_wr_reg(priv, 0x07, 0xe0);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
if (ret)
goto err;
/* cold state - try to download firmware */ /* cold state - try to download firmware */
dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state\n", dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state\n",
KBUILD_MODNAME, m88ds3103_ops.info.name); KBUILD_MODNAME, m88ds3103_ops.info.name);
if (priv->chip_id == M88RS6000_CHIP_ID)
fw_file = M88RS6000_FIRMWARE;
else
fw_file = M88DS3103_FIRMWARE;
/* request the firmware, this will block and timeout */ /* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
if (ret) { if (ret) {
...@@ -577,7 +640,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) ...@@ -577,7 +640,7 @@ static int m88ds3103_init(struct dvb_frontend *fe)
ret = m88ds3103_wr_reg(priv, 0xb2, 0x01); ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
if (ret) if (ret)
goto err; goto error_fw_release;
for (remaining = fw->size; remaining > 0; for (remaining = fw->size; remaining > 0;
remaining -= (priv->cfg->i2c_wr_max - 1)) { remaining -= (priv->cfg->i2c_wr_max - 1)) {
...@@ -591,13 +654,13 @@ static int m88ds3103_init(struct dvb_frontend *fe) ...@@ -591,13 +654,13 @@ static int m88ds3103_init(struct dvb_frontend *fe)
dev_err(&priv->i2c->dev, dev_err(&priv->i2c->dev,
"%s: firmware download failed=%d\n", "%s: firmware download failed=%d\n",
KBUILD_MODNAME, ret); KBUILD_MODNAME, ret);
goto err; goto error_fw_release;
} }
} }
ret = m88ds3103_wr_reg(priv, 0xb2, 0x00); ret = m88ds3103_wr_reg(priv, 0xb2, 0x00);
if (ret) if (ret)
goto err; goto error_fw_release;
release_firmware(fw); release_firmware(fw);
fw = NULL; fw = NULL;
...@@ -623,10 +686,10 @@ static int m88ds3103_init(struct dvb_frontend *fe) ...@@ -623,10 +686,10 @@ static int m88ds3103_init(struct dvb_frontend *fe)
priv->warm = true; priv->warm = true;
return 0; return 0;
err:
if (fw)
release_firmware(fw);
error_fw_release:
release_firmware(fw);
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret; return ret;
} }
...@@ -635,13 +698,18 @@ static int m88ds3103_sleep(struct dvb_frontend *fe) ...@@ -635,13 +698,18 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
{ {
struct m88ds3103_priv *priv = fe->demodulator_priv; struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret; int ret;
u8 u8tmp;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__); dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
priv->delivery_system = SYS_UNDEFINED; priv->delivery_system = SYS_UNDEFINED;
/* TS Hi-Z */ /* TS Hi-Z */
ret = m88ds3103_wr_reg_mask(priv, 0x27, 0x00, 0x01); if (priv->chip_id == M88RS6000_CHIP_ID)
u8tmp = 0x29;
else
u8tmp = 0x27;
ret = m88ds3103_wr_reg_mask(priv, u8tmp, 0x00, 0x01);
if (ret) if (ret)
goto err; goto err;
...@@ -830,7 +898,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) ...@@ -830,7 +898,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
goto err; goto err;
c->symbol_rate = 1ull * ((buf[1] << 8) | (buf[0] << 0)) * c->symbol_rate = 1ull * ((buf[1] << 8) | (buf[0] << 0)) *
M88DS3103_MCLK_KHZ * 1000 / 0x10000; priv->mclk_khz * 1000 / 0x10000;
return 0; return 0;
err: err:
...@@ -1310,18 +1378,22 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, ...@@ -1310,18 +1378,22 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
priv->i2c = i2c; priv->i2c = i2c;
mutex_init(&priv->i2c_mutex); mutex_init(&priv->i2c_mutex);
ret = m88ds3103_rd_reg(priv, 0x01, &chip_id); /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */
ret = m88ds3103_rd_reg(priv, 0x00, &chip_id);
if (ret) if (ret)
goto err; goto err;
dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); chip_id >>= 1;
dev_info(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
switch (chip_id) { switch (chip_id) {
case 0xd0: case M88RS6000_CHIP_ID:
case M88DS3103_CHIP_ID:
break; break;
default: default:
goto err; goto err;
} }
priv->chip_id = chip_id;
switch (priv->cfg->clock_out) { switch (priv->cfg->clock_out) {
case M88DS3103_CLOCK_OUT_DISABLED: case M88DS3103_CLOCK_OUT_DISABLED:
...@@ -1337,6 +1409,11 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, ...@@ -1337,6 +1409,11 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
goto err; goto err;
} }
/* 0x29 register is defined differently for m88rs6000. */
/* set internal tuner address to 0x21 */
if (chip_id == M88RS6000_CHIP_ID)
u8tmp = 0x00;
ret = m88ds3103_wr_reg(priv, 0x29, u8tmp); ret = m88ds3103_wr_reg(priv, 0x29, u8tmp);
if (ret) if (ret)
goto err; goto err;
...@@ -1364,6 +1441,9 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, ...@@ -1364,6 +1441,9 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
/* create dvb_frontend */ /* create dvb_frontend */
memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
if (priv->chip_id == M88RS6000_CHIP_ID)
strncpy(priv->fe.ops.info.name,
"Montage M88RS6000", sizeof(priv->fe.ops.info.name));
priv->fe.demodulator_priv = priv; priv->fe.demodulator_priv = priv;
return &priv->fe; return &priv->fe;
...@@ -1423,3 +1503,4 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); ...@@ -1423,3 +1503,4 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver"); MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_FIRMWARE(M88DS3103_FIRMWARE); MODULE_FIRMWARE(M88DS3103_FIRMWARE);
MODULE_FIRMWARE(M88RS6000_FIRMWARE);
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
#include <linux/math64.h> #include <linux/math64.h>
#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw" #define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"
#define M88RS6000_FIRMWARE "dvb-demod-m88rs6000.fw"
#define M88DS3103_MCLK_KHZ 96000 #define M88DS3103_MCLK_KHZ 96000
#define M88RS6000_CHIP_ID 0x74
#define M88DS3103_CHIP_ID 0x70
struct m88ds3103_priv { struct m88ds3103_priv {
struct i2c_adapter *i2c; struct i2c_adapter *i2c;
...@@ -38,6 +41,10 @@ struct m88ds3103_priv { ...@@ -38,6 +41,10 @@ struct m88ds3103_priv {
u32 ber; u32 ber;
bool warm; /* FW running */ bool warm; /* FW running */
struct i2c_adapter *i2c_adapter; struct i2c_adapter *i2c_adapter;
/* auto detect chip id to do different config */
u8 chip_id;
/* main mclk is calculated for M88RS6000 dynamically */
u32 mclk_khz;
}; };
struct m88ds3103_reg_val { struct m88ds3103_reg_val {
...@@ -214,4 +221,178 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs2_init_reg_vals[] = { ...@@ -214,4 +221,178 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs2_init_reg_vals[] = {
{0xb8, 0x00}, {0xb8, 0x00},
}; };
static const struct m88ds3103_reg_val m88rs6000_dvbs_init_reg_vals[] = {
{0x23, 0x07},
{0x08, 0x03},
{0x0c, 0x02},
{0x20, 0x00},
{0x21, 0x54},
{0x25, 0x82},
{0x27, 0x31},
{0x30, 0x08},
{0x31, 0x40},
{0x32, 0x32},
{0x33, 0x35},
{0x35, 0xff},
{0x3a, 0x00},
{0x37, 0x10},
{0x38, 0x10},
{0x39, 0x02},
{0x42, 0x60},
{0x4a, 0x80},
{0x4b, 0x04},
{0x4d, 0x91},
{0x5d, 0xc8},
{0x50, 0x36},
{0x51, 0x36},
{0x52, 0x36},
{0x53, 0x36},
{0x63, 0x0f},
{0x64, 0x30},
{0x65, 0x40},
{0x68, 0x26},
{0x69, 0x4c},
{0x70, 0x20},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x40},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x60},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x80},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0xa0},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x1f},
{0x76, 0x38},
{0x77, 0xa6},
{0x78, 0x0c},
{0x79, 0x80},
{0x7f, 0x14},
{0x7c, 0x00},
{0xae, 0x82},
{0x80, 0x64},
{0x81, 0x66},
{0x82, 0x44},
{0x85, 0x04},
{0xcd, 0xf4},
{0x90, 0x33},
{0xa0, 0x44},
{0xbe, 0x00},
{0xc0, 0x08},
{0xc3, 0x10},
{0xc4, 0x08},
{0xc5, 0xf0},
{0xc6, 0xff},
{0xc7, 0x00},
{0xc8, 0x1a},
{0xc9, 0x80},
{0xe0, 0xf8},
{0xe6, 0x8b},
{0xd0, 0x40},
{0xf8, 0x20},
{0xfa, 0x0f},
{0x00, 0x00},
{0xbd, 0x01},
{0xb8, 0x00},
{0x29, 0x11},
};
static const struct m88ds3103_reg_val m88rs6000_dvbs2_init_reg_vals[] = {
{0x23, 0x07},
{0x08, 0x07},
{0x0c, 0x02},
{0x20, 0x00},
{0x21, 0x54},
{0x25, 0x82},
{0x27, 0x31},
{0x30, 0x08},
{0x32, 0x32},
{0x33, 0x35},
{0x35, 0xff},
{0x3a, 0x00},
{0x37, 0x10},
{0x38, 0x10},
{0x39, 0x02},
{0x42, 0x60},
{0x4a, 0x80},
{0x4b, 0x04},
{0x4d, 0x91},
{0x5d, 0xc8},
{0x50, 0x36},
{0x51, 0x36},
{0x52, 0x36},
{0x53, 0x36},
{0x63, 0x0f},
{0x64, 0x10},
{0x65, 0x20},
{0x68, 0x46},
{0x69, 0xcd},
{0x70, 0x20},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x40},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x60},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x80},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0xa0},
{0x71, 0x70},
{0x72, 0x04},
{0x73, 0x00},
{0x70, 0x1f},
{0x76, 0x38},
{0x77, 0xa6},
{0x78, 0x0c},
{0x79, 0x80},
{0x7f, 0x14},
{0x85, 0x08},
{0xcd, 0xf4},
{0x90, 0x33},
{0x86, 0x00},
{0x87, 0x0f},
{0x89, 0x00},
{0x8b, 0x44},
{0x8c, 0x66},
{0x9d, 0xc1},
{0x8a, 0x10},
{0xad, 0x40},
{0xa0, 0x44},
{0xbe, 0x00},
{0xc0, 0x08},
{0xc1, 0x10},
{0xc2, 0x08},
{0xc3, 0x10},
{0xc4, 0x08},
{0xc5, 0xf0},
{0xc6, 0xff},
{0xc7, 0x00},
{0xc8, 0x1a},
{0xc9, 0x80},
{0xca, 0x23},
{0xcb, 0x24},
{0xcc, 0xf4},
{0xce, 0x74},
{0x00, 0x00},
{0xbd, 0x01},
{0xb8, 0x00},
{0x29, 0x01},
};
#endif #endif
/*
* Panasonic MN88472 DVB-T/T2/C demodulator driver
*
* Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
*
* 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 MN88472_H
#define MN88472_H
#include <linux/dvb/frontend.h>
struct mn88472_config {
/*
* Max num of bytes given I2C adapter could write at once.
* Default: none
*/
u16 i2c_wr_max;
/* Everything after that is returned by the driver. */
/*
* DVB frontend.
*/
struct dvb_frontend **fe;
};
#endif
/*
* Panasonic MN88473 DVB-T/T2/C demodulator driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
* 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 MN88473_H
#define MN88473_H
#include <linux/dvb/frontend.h>
struct mn88473_config {
/*
* Max num of bytes given I2C adapter could write at once.
* Default: none
*/
u16 i2c_wr_max;
/* Everything after that is returned by the driver. */
/*
* DVB frontend.
*/
struct dvb_frontend **fe;
};
#endif
...@@ -258,13 +258,11 @@ static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val, ...@@ -258,13 +258,11 @@ static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
return rtl2832_rd(priv, reg, val, len); return rtl2832_rd(priv, reg, val, len);
} }
#if 0 /* currently not used */
/* write single register */ /* write single register */
static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val) static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
{ {
return rtl2832_wr_regs(priv, reg, page, &val, 1); return rtl2832_wr_regs(priv, reg, page, &val, 1);
} }
#endif
/* read single register */ /* read single register */
static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val) static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
...@@ -599,6 +597,11 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) ...@@ -599,6 +597,11 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
if (fe->ops.tuner_ops.set_params) if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe); fe->ops.tuner_ops.set_params(fe);
/* PIP mode related */
ret = rtl2832_wr_regs(priv, 0x92, 1, "\x00\x0f\xff", 3);
if (ret)
goto err;
/* If the frontend has get_if_frequency(), use it */ /* If the frontend has get_if_frequency(), use it */
if (fe->ops.tuner_ops.get_if_frequency) { if (fe->ops.tuner_ops.get_if_frequency) {
u32 if_freq; u32 if_freq;
...@@ -661,7 +664,6 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) ...@@ -661,7 +664,6 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
if (ret) if (ret)
goto err; goto err;
/* soft reset */ /* soft reset */
ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1); ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
if (ret) if (ret)
...@@ -1020,6 +1022,58 @@ static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv, ...@@ -1020,6 +1022,58 @@ static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv,
return 0; return 0;
} }
int rtl2832_enable_external_ts_if(struct dvb_frontend *fe)
{
struct rtl2832_priv *priv = fe->demodulator_priv;
int ret;
dev_dbg(&priv->i2c->dev, "%s: setting PIP mode\n", __func__);
ret = rtl2832_wr_regs(priv, 0x0c, 1, "\x5f\xff", 2);
if (ret)
goto err;
ret = rtl2832_wr_demod_reg(priv, DVBT_PIP_ON, 0x1);
if (ret)
goto err;
ret = rtl2832_wr_reg(priv, 0xbc, 0, 0x18);
if (ret)
goto err;
ret = rtl2832_wr_reg(priv, 0x22, 0, 0x01);
if (ret)
goto err;
ret = rtl2832_wr_reg(priv, 0x26, 0, 0x1f);
if (ret)
goto err;
ret = rtl2832_wr_reg(priv, 0x27, 0, 0xff);
if (ret)
goto err;
ret = rtl2832_wr_regs(priv, 0x92, 1, "\x7f\xf7\xff", 3);
if (ret)
goto err;
/* soft reset */
ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
if (ret)
goto err;
ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
if (ret)
goto err;
return 0;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
EXPORT_SYMBOL(rtl2832_enable_external_ts_if);
struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe) struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe)
{ {
struct rtl2832_priv *priv = fe->demodulator_priv; struct rtl2832_priv *priv = fe->demodulator_priv;
......
...@@ -64,6 +64,10 @@ extern struct i2c_adapter *rtl2832_get_private_i2c_adapter( ...@@ -64,6 +64,10 @@ extern struct i2c_adapter *rtl2832_get_private_i2c_adapter(
struct dvb_frontend *fe struct dvb_frontend *fe
); );
extern int rtl2832_enable_external_ts_if(
struct dvb_frontend *fe
);
#else #else
static inline struct dvb_frontend *rtl2832_attach( static inline struct dvb_frontend *rtl2832_attach(
...@@ -89,6 +93,13 @@ static inline struct i2c_adapter *rtl2832_get_private_i2c_adapter( ...@@ -89,6 +93,13 @@ static inline struct i2c_adapter *rtl2832_get_private_i2c_adapter(
return NULL; return NULL;
} }
static inline int rtl2832_enable_external_ts_if(
struct dvb_frontend *fe
)
{
return -ENODEV;
}
#endif #endif
......
...@@ -1013,6 +1013,10 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count) ...@@ -1013,6 +1013,10 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
if (s->d->props->power_ctrl) if (s->d->props->power_ctrl)
s->d->props->power_ctrl(s->d, 1); s->d->props->power_ctrl(s->d, 1);
/* enable ADC */
if (s->d->props->frontend_ctrl)
s->d->props->frontend_ctrl(s->fe, 1);
set_bit(POWER_ON, &s->flags); set_bit(POWER_ON, &s->flags);
ret = rtl2832_sdr_set_tuner(s); ret = rtl2832_sdr_set_tuner(s);
...@@ -1064,6 +1068,10 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq) ...@@ -1064,6 +1068,10 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
clear_bit(POWER_ON, &s->flags); clear_bit(POWER_ON, &s->flags);
/* disable ADC */
if (s->d->props->frontend_ctrl)
s->d->props->frontend_ctrl(s->fe, 0);
if (s->d->props->power_ctrl) if (s->d->props->power_ctrl)
s->d->props->power_ctrl(s->d, 0); s->d->props->power_ctrl(s->d, 0);
......
...@@ -308,14 +308,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe) ...@@ -308,14 +308,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret) if (ret)
goto err; goto err;
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6); memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6);
cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10;
cmd.wlen = 6; cmd.wlen = 6;
cmd.rlen = 4; cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd); ret = si2168_cmd_execute(s, &cmd);
if (ret) if (ret)
goto err; goto err;
memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6); memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6);
cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10;
cmd.wlen = 6; cmd.wlen = 6;
cmd.rlen = 4; cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd); ret = si2168_cmd_execute(s, &cmd);
...@@ -453,27 +455,45 @@ static int si2168_init(struct dvb_frontend *fe) ...@@ -453,27 +455,45 @@ static int si2168_init(struct dvb_frontend *fe)
dev_err(&s->client->dev, dev_err(&s->client->dev,
"firmware file '%s' not found\n", "firmware file '%s' not found\n",
fw_file); fw_file);
goto err; goto error_fw_release;
} }
} }
dev_info(&s->client->dev, "downloading firmware from file '%s'\n", dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
fw_file); fw_file);
for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) { if ((fw->size % 17 == 0) && (fw->data[0] > 5)) {
len = remaining; /* firmware is in the new format */
if (len > i2c_wr_max) for (remaining = fw->size; remaining > 0; remaining -= 17) {
len = i2c_wr_max; len = fw->data[fw->size - remaining];
memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
memcpy(cmd.args, &fw->data[fw->size - remaining], len); cmd.wlen = len;
cmd.wlen = len; cmd.rlen = 1;
cmd.rlen = 1; ret = si2168_cmd_execute(s, &cmd);
ret = si2168_cmd_execute(s, &cmd); if (ret) {
if (ret) { dev_err(&s->client->dev,
dev_err(&s->client->dev, "firmware download failed=%d\n",
"firmware download failed=%d\n", ret);
ret); goto error_fw_release;
goto err; }
}
} else {
/* firmware is in the old format */
for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
len = remaining;
if (len > i2c_wr_max)
len = i2c_wr_max;
memcpy(cmd.args, &fw->data[fw->size - remaining], len);
cmd.wlen = len;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret) {
dev_err(&s->client->dev,
"firmware download failed=%d\n",
ret);
goto error_fw_release;
}
} }
} }
...@@ -487,6 +507,17 @@ static int si2168_init(struct dvb_frontend *fe) ...@@ -487,6 +507,17 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret) if (ret)
goto err; goto err;
/* query firmware version */
memcpy(cmd.args, "\x11", 1);
cmd.wlen = 1;
cmd.rlen = 10;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
dev_dbg(&s->client->dev, "firmware version: %c.%c.%d\n",
cmd.args[6], cmd.args[7], cmd.args[8]);
/* set ts mode */ /* set ts mode */
memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
cmd.args[4] |= s->ts_mode; cmd.args[4] |= s->ts_mode;
...@@ -498,17 +529,16 @@ static int si2168_init(struct dvb_frontend *fe) ...@@ -498,17 +529,16 @@ static int si2168_init(struct dvb_frontend *fe)
s->fw_loaded = true; s->fw_loaded = true;
warm:
dev_info(&s->client->dev, "found a '%s' in warm state\n", dev_info(&s->client->dev, "found a '%s' in warm state\n",
si2168_ops.info.name); si2168_ops.info.name);
warm:
s->active = true; s->active = true;
return 0; return 0;
err:
if (fw)
release_firmware(fw);
error_fw_release:
release_firmware(fw);
err:
dev_dbg(&s->client->dev, "failed=%d\n", ret); dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret; return ret;
} }
...@@ -670,6 +700,7 @@ static int si2168_probe(struct i2c_client *client, ...@@ -670,6 +700,7 @@ static int si2168_probe(struct i2c_client *client,
*config->i2c_adapter = s->adapter; *config->i2c_adapter = s->adapter;
*config->fe = &s->fe; *config->fe = &s->fe;
s->ts_mode = config->ts_mode; s->ts_mode = config->ts_mode;
s->ts_clock_inv = config->ts_clock_inv;
s->fw_loaded = false; s->fw_loaded = false;
i2c_set_clientdata(client, s); i2c_set_clientdata(client, s);
......
...@@ -37,6 +37,10 @@ struct si2168_config { ...@@ -37,6 +37,10 @@ struct si2168_config {
/* TS mode */ /* TS mode */
u8 ts_mode; u8 ts_mode;
/* TS clock inverted */
bool ts_clock_inv;
}; };
#define SI2168_TS_PARALLEL 0x06 #define SI2168_TS_PARALLEL 0x06
......
...@@ -38,6 +38,7 @@ struct si2168 { ...@@ -38,6 +38,7 @@ struct si2168 {
bool active; bool active;
bool fw_loaded; bool fw_loaded;
u8 ts_mode; u8 ts_mode;
bool ts_clock_inv;
}; };
/* firmare command struct */ /* firmare command struct */
......
...@@ -92,6 +92,9 @@ static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len) ...@@ -92,6 +92,9 @@ static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
return -EIO; return -EIO;
} }
dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n",
client->addr, reg, len, buf);
return 0; return 0;
} }
...@@ -103,9 +106,6 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs, ...@@ -103,9 +106,6 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
int mem, ret; int mem, ret;
int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control; int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x",
slot, acs, addr, data);
if (slot != 0) if (slot != 0)
return -EINVAL; return -EINVAL;
...@@ -140,13 +140,16 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs, ...@@ -140,13 +140,16 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
if (ret) if (ret)
return ret; return ret;
if (read) { dev_dbg(&s->client->dev, "%s: slot=%d, addr=0x%04x, %s, data=%x",
dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x", (read) ? "read" : "write", slot, addr,
addr, mem); (acs == SP2_CI_ATTR_ACS) ? "attr" : "io",
(read) ? mem : data);
if (read)
return mem; return mem;
} else { else
return 0; return 0;
}
} }
int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
...@@ -407,7 +410,7 @@ static int sp2_probe(struct i2c_client *client, ...@@ -407,7 +410,7 @@ static int sp2_probe(struct i2c_client *client,
static int sp2_remove(struct i2c_client *client) static int sp2_remove(struct i2c_client *client)
{ {
struct si2157 *s = i2c_get_clientdata(client); struct sp2 *s = i2c_get_clientdata(client);
dev_dbg(&client->dev, "\n"); dev_dbg(&client->dev, "\n");
......
...@@ -705,7 +705,7 @@ static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma ...@@ -705,7 +705,7 @@ static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma
struct stb0899_state *state = fe->demodulator_priv; struct stb0899_state *state = fe->demodulator_priv;
u8 reg, i; u8 reg, i;
if (cmd->msg_len > 8) if (cmd->msg_len > sizeof(cmd->msg))
return -EINVAL; return -EINVAL;
/* enable FIFO precharge */ /* enable FIFO precharge */
......
...@@ -2146,7 +2146,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) ...@@ -2146,7 +2146,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
u32 reg; u32 reg;
s32 car_step, steps, cur_step, dir, freq, timeout_lock; s32 car_step, steps, cur_step, dir, freq, timeout_lock;
int lock = 0; int lock;
if (state->srate >= 10000000) if (state->srate >= 10000000)
timeout_lock = timeout_dmd / 3; timeout_lock = timeout_dmd / 3;
...@@ -2154,98 +2154,96 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) ...@@ -2154,98 +2154,96 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
timeout_lock = timeout_dmd / 2; timeout_lock = timeout_dmd / 2;
lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */ lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
if (!lock) { if (lock)
if (state->srate >= 10000000) { return lock;
if (stv090x_chk_tmg(state)) {
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
goto err;
lock = stv090x_get_dmdlock(state, timeout_dmd);
} else {
lock = 0;
}
} else {
if (state->srate <= 4000000)
car_step = 1000;
else if (state->srate <= 7000000)
car_step = 2000;
else if (state->srate <= 10000000)
car_step = 3000;
else
car_step = 5000;
steps = (state->search_range / 1000) / car_step;
steps /= 2;
steps = 2 * (steps + 1);
if (steps < 0)
steps = 2;
else if (steps > 12)
steps = 12;
cur_step = 1;
dir = 1;
if (!lock) {
freq = state->frequency;
state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
while ((cur_step <= steps) && (!lock)) {
if (dir > 0)
freq += cur_step * car_step;
else
freq -= cur_step * car_step;
/* Setup tuner */
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
goto err;
if (state->config->tuner_set_frequency) { if (state->srate >= 10000000) {
if (state->config->tuner_set_frequency(fe, freq) < 0) if (stv090x_chk_tmg(state)) {
goto err_gateoff; if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
} goto err;
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
goto err;
return stv090x_get_dmdlock(state, timeout_dmd);
}
return 0;
}
if (state->config->tuner_set_bandwidth) { if (state->srate <= 4000000)
if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) car_step = 1000;
goto err_gateoff; else if (state->srate <= 7000000)
} car_step = 2000;
else if (state->srate <= 10000000)
car_step = 3000;
else
car_step = 5000;
if (stv090x_i2c_gate_ctrl(state, 0) < 0) steps = (state->search_range / 1000) / car_step;
goto err; steps /= 2;
steps = 2 * (steps + 1);
if (steps < 0)
steps = 2;
else if (steps > 12)
steps = 12;
msleep(50); cur_step = 1;
dir = 1;
if (stv090x_i2c_gate_ctrl(state, 1) < 0) freq = state->frequency;
goto err; state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
while ((cur_step <= steps) && (!lock)) {
if (dir > 0)
freq += cur_step * car_step;
else
freq -= cur_step * car_step;
if (state->config->tuner_get_status) { /* Setup tuner */
if (state->config->tuner_get_status(fe, &reg) < 0) if (stv090x_i2c_gate_ctrl(state, 1) < 0)
goto err_gateoff; goto err;
}
if (reg) if (state->config->tuner_set_frequency) {
dprintk(FE_DEBUG, 1, "Tuner phase locked"); if (state->config->tuner_set_frequency(fe, freq) < 0)
else goto err_gateoff;
dprintk(FE_DEBUG, 1, "Tuner unlocked"); }
if (stv090x_i2c_gate_ctrl(state, 0) < 0) if (state->config->tuner_set_bandwidth) {
goto err; if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
goto err_gateoff;
}
STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); if (stv090x_i2c_gate_ctrl(state, 0) < 0)
if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) goto err;
goto err;
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
goto err;
lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
dir *= -1; msleep(50);
cur_step++;
} if (stv090x_i2c_gate_ctrl(state, 1) < 0)
} goto err;
if (state->config->tuner_get_status) {
if (state->config->tuner_get_status(fe, &reg) < 0)
goto err_gateoff;
} }
if (reg)
dprintk(FE_DEBUG, 1, "Tuner phase locked");
else
dprintk(FE_DEBUG, 1, "Tuner unlocked");
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
goto err;
STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
goto err;
lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
dir *= -1;
cur_step++;
} }
return lock; return lock;
...@@ -2663,13 +2661,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st ...@@ -2663,13 +2661,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
return STV090x_RANGEOK; return STV090x_RANGEOK;
else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000)) else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
return STV090x_RANGEOK; return STV090x_RANGEOK;
else
return STV090x_OUTOFRANGE; /* Out of Range */
} else { } else {
if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
return STV090x_RANGEOK; return STV090x_RANGEOK;
else
return STV090x_OUTOFRANGE;
} }
return STV090x_OUTOFRANGE; return STV090x_OUTOFRANGE;
...@@ -2789,6 +2783,12 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod ...@@ -2789,6 +2783,12 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
aclc = car_loop[i].crl_pilots_off_30; aclc = car_loop[i].crl_pilots_off_30;
} }
} else { /* 16APSK and 32APSK */ } else { /* 16APSK and 32APSK */
/*
* This should never happen in practice, except if
* something is really wrong at the car_loop table.
*/
if (i >= 11)
i = 10;
if (state->srate <= 3000000) if (state->srate <= 3000000)
aclc = car_loop_apsk_low[i].crl_pilots_on_2; aclc = car_loop_apsk_low[i].crl_pilots_on_2;
else if (state->srate <= 7000000) else if (state->srate <= 7000000)
...@@ -3470,7 +3470,20 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe) ...@@ -3470,7 +3470,20 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
if (props->frequency == 0) if (props->frequency == 0)
return DVBFE_ALGO_SEARCH_INVALID; return DVBFE_ALGO_SEARCH_INVALID;
state->delsys = props->delivery_system; switch (props->delivery_system) {
case SYS_DSS:
state->delsys = STV090x_DSS;
break;
case SYS_DVBS:
state->delsys = STV090x_DVBS1;
break;
case SYS_DVBS2:
state->delsys = STV090x_DVBS2;
break;
default:
return DVBFE_ALGO_SEARCH_INVALID;
}
state->frequency = props->frequency; state->frequency = props->frequency;
state->srate = props->symbol_rate; state->srate = props->symbol_rate;
state->search_mode = STV090x_SEARCH_AUTO; state->search_mode = STV090x_SEARCH_AUTO;
...@@ -4859,8 +4872,8 @@ static int stv090x_setup(struct dvb_frontend *fe) ...@@ -4859,8 +4872,8 @@ static int stv090x_setup(struct dvb_frontend *fe)
return -1; return -1;
} }
int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
u8 xor_value) u8 value, u8 xor_value)
{ {
struct stv090x_state *state = fe->demodulator_priv; struct stv090x_state *state = fe->demodulator_priv;
u8 reg = 0; u8 reg = 0;
...@@ -4871,7 +4884,6 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, ...@@ -4871,7 +4884,6 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg); return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
} }
EXPORT_SYMBOL(stv090x_set_gpio);
static struct dvb_frontend_ops stv090x_ops = { static struct dvb_frontend_ops stv090x_ops = {
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
...@@ -4908,7 +4920,7 @@ static struct dvb_frontend_ops stv090x_ops = { ...@@ -4908,7 +4920,7 @@ static struct dvb_frontend_ops stv090x_ops = {
}; };
struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
struct i2c_adapter *i2c, struct i2c_adapter *i2c,
enum stv090x_demodulator demod) enum stv090x_demodulator demod)
{ {
...@@ -4969,6 +4981,8 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, ...@@ -4969,6 +4981,8 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
if (config->diseqc_envelope_mode) if (config->diseqc_envelope_mode)
stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A); stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
config->set_gpio = stv090x_set_gpio;
dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
state->device == STV0900 ? "STV0900" : "STV0903", state->device == STV0900 ? "STV0900" : "STV0903",
demod, demod,
......
...@@ -89,29 +89,29 @@ struct stv090x_config { ...@@ -89,29 +89,29 @@ struct stv090x_config {
bool diseqc_envelope_mode; bool diseqc_envelope_mode;
int (*tuner_init) (struct dvb_frontend *fe); int (*tuner_init)(struct dvb_frontend *fe);
int (*tuner_sleep) (struct dvb_frontend *fe); int (*tuner_sleep)(struct dvb_frontend *fe);
int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); int (*tuner_set_mode)(struct dvb_frontend *fe, enum tuner_mode mode);
int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); int (*tuner_set_bbgain)(struct dvb_frontend *fe, u32 gain);
int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); int (*tuner_get_bbgain)(struct dvb_frontend *fe, u32 *gain);
int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); int (*tuner_set_refclk)(struct dvb_frontend *fe, u32 refclk);
int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); int (*tuner_get_status)(struct dvb_frontend *fe, u32 *status);
void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock); void (*tuner_i2c_lock)(struct dvb_frontend *fe, int lock);
/* dir = 0 -> output, dir = 1 -> input/open-drain */
int (*set_gpio)(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
u8 xor_value);
}; };
#if IS_ENABLED(CONFIG_DVB_STV090x) #if IS_ENABLED(CONFIG_DVB_STV090x)
extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
struct i2c_adapter *i2c, struct i2c_adapter *i2c,
enum stv090x_demodulator demod); enum stv090x_demodulator demod);
/* dir = 0 -> output, dir = 1 -> input/open-drain */
extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
u8 dir, u8 value, u8 xor_value);
#else #else
...@@ -123,12 +123,6 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c ...@@ -123,12 +123,6 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c
return NULL; return NULL;
} }
static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
u8 opd, u8 value, u8 xor_value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
#endif /* CONFIG_DVB_STV090x */ #endif /* CONFIG_DVB_STV090x */
#endif /* __STV090x_H */ #endif /* __STV090x_H */
...@@ -253,6 +253,5 @@ int fdtv_ca_register(struct firedtv *fdtv) ...@@ -253,6 +253,5 @@ int fdtv_ca_register(struct firedtv *fdtv)
void fdtv_ca_release(struct firedtv *fdtv) void fdtv_ca_release(struct firedtv *fdtv)
{ {
if (fdtv->cadev) dvb_unregister_device(fdtv->cadev);
dvb_unregister_device(fdtv->cadev);
} }
...@@ -96,7 +96,7 @@ struct firedtv { ...@@ -96,7 +96,7 @@ struct firedtv {
enum model_type type; enum model_type type;
char subunit; char subunit;
char isochannel; s8 isochannel;
struct fdtv_ir_context *ir_context; struct fdtv_ir_context *ir_context;
fe_sec_voltage_t voltage; fe_sec_voltage_t voltage;
......
...@@ -63,9 +63,9 @@ static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd) ...@@ -63,9 +63,9 @@ static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd)
static char *inputs[] = { "pass_through", "play_back" }; static char *inputs[] = { "pass_through", "play_back" };
static enum v4l2_mbus_pixelcode adv7170_codes[] = { static u32 adv7170_codes[] = {
V4L2_MBUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_UYVY8_2X8,
V4L2_MBUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16,
}; };
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
...@@ -263,7 +263,7 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, ...@@ -263,7 +263,7 @@ static int adv7170_s_routing(struct v4l2_subdev *sd,
} }
static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index, static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code) u32 *code)
{ {
if (index >= ARRAY_SIZE(adv7170_codes)) if (index >= ARRAY_SIZE(adv7170_codes))
return -EINVAL; return -EINVAL;
...@@ -278,9 +278,9 @@ static int adv7170_g_fmt(struct v4l2_subdev *sd, ...@@ -278,9 +278,9 @@ static int adv7170_g_fmt(struct v4l2_subdev *sd,
u8 val = adv7170_read(sd, 0x7); u8 val = adv7170_read(sd, 0x7);
if ((val & 0x40) == (1 << 6)) if ((val & 0x40) == (1 << 6))
mf->code = V4L2_MBUS_FMT_UYVY8_1X16; mf->code = MEDIA_BUS_FMT_UYVY8_1X16;
else else
mf->code = V4L2_MBUS_FMT_UYVY8_2X8; mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M; mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
mf->width = 0; mf->width = 0;
...@@ -297,11 +297,11 @@ static int adv7170_s_fmt(struct v4l2_subdev *sd, ...@@ -297,11 +297,11 @@ static int adv7170_s_fmt(struct v4l2_subdev *sd,
int ret; int ret;
switch (mf->code) { switch (mf->code) {
case V4L2_MBUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY8_2X8:
val &= ~0x40; val &= ~0x40;
break; break;
case V4L2_MBUS_FMT_UYVY8_1X16: case MEDIA_BUS_FMT_UYVY8_1X16:
val |= 0x40; val |= 0x40;
break; break;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -464,8 +464,7 @@ static int ir_remove(struct i2c_client *client) ...@@ -464,8 +464,7 @@ static int ir_remove(struct i2c_client *client)
cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&ir->work);
/* unregister device */ /* unregister device */
if (ir->rc) rc_unregister_device(ir->rc);
rc_unregister_device(ir->rc);
/* free memory */ /* free memory */
return 0; return 0;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册