Commit df462b3d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (247 commits)
  [media] gspca - sunplus: Fix some warnings and simplify code
  [media] gspca: Fix some warnings tied to 'no debug'
  [media] gspca: Unset debug by default
  [media] gspca - cpia1: Remove a bad conditional compilation instruction
  [media] gspca - main: Remove USB traces
  [media] gspca - main: Version change to 2.13
  [media] gspca - stk014 / t613: Accept the index 0 in querymenu
  [media] gspca - kinect: Remove __devinitdata
  [media] gspca - cpia1: Fix some warnings
  [media] video/Kconfig: Fix mis-classified devices
  [media] support for medion dvb stick 1660:1921
  [media] tm6000: fix uninitialized field, change prink to dprintk
  [media] cx231xx: Add support for Iconbit U100
  [media] saa7134 add new TV cards
  [media] Use a more consistent value for RC repeat period
  [media] cx18: Move spinlock and vb_type initialisation into stream_init
  [media] tm6000: remove tm6010 sif audio start and stop
  [media] tm6000: remove unused exports
  [media] tm6000: add pts logging
  [media] tm6000: change from ioctl to unlocked_ioctl
  ...
parents 343800e7 cf252206
......@@ -8,3 +8,4 @@
*.dvi
*.log
*.out
media/
......@@ -34,6 +34,14 @@
<revhistory>
<!-- Put document revisions here, newest first. -->
<revision>
<revnumber>2.0.4</revnumber>
<date>2011-05-06</date>
<authorinitials>mcc</authorinitials>
<revremark>
Add more information about DVB APIv5, better describing the frontend GET/SET props ioctl's.
</revremark>
</revision>
<revision>
<revnumber>2.0.3</revnumber>
<date>2010-07-03</date>
......
This diff is collapsed.
......@@ -176,14 +176,20 @@ typedef enum fe_transmit_mode {
TRANSMISSION_MODE_2K,
TRANSMISSION_MODE_8K,
TRANSMISSION_MODE_AUTO,
TRANSMISSION_MODE_4K
TRANSMISSION_MODE_4K,
TRANSMISSION_MODE_1K,
TRANSMISSION_MODE_16K,
TRANSMISSION_MODE_32K,
} fe_transmit_mode_t;
typedef enum fe_bandwidth {
BANDWIDTH_8_MHZ,
BANDWIDTH_7_MHZ,
BANDWIDTH_6_MHZ,
BANDWIDTH_AUTO
BANDWIDTH_AUTO,
BANDWIDTH_5_MHZ,
BANDWIDTH_10_MHZ,
BANDWIDTH_1_712_MHZ,
} fe_bandwidth_t;
......@@ -192,7 +198,10 @@ typedef enum fe_guard_interval {
GUARD_INTERVAL_1_16,
GUARD_INTERVAL_1_8,
GUARD_INTERVAL_1_4,
GUARD_INTERVAL_AUTO
GUARD_INTERVAL_AUTO,
GUARD_INTERVAL_1_128,
GUARD_INTERVAL_19_128,
GUARD_INTERVAL_19_256,
} fe_guard_interval_t;
......@@ -306,7 +315,9 @@ struct dvb_frontend_event {
#define DTV_ISDBS_TS_ID 42
#define DTV_MAX_COMMAND DTV_ISDBS_TS_ID
#define DTV_DVBT2_PLP_ID 43
#define DTV_MAX_COMMAND DTV_DVBT2_PLP_ID
typedef enum fe_pilot {
PILOT_ON,
......@@ -338,6 +349,7 @@ typedef enum fe_delivery_system {
SYS_DMBTH,
SYS_CMMB,
SYS_DAB,
SYS_DVBT2,
} fe_delivery_system_t;
struct dtv_cmds_h {
......
......@@ -270,6 +270,7 @@
<!ENTITY sub-write SYSTEM "v4l/func-write.xml">
<!ENTITY sub-io SYSTEM "v4l/io.xml">
<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
<!ENTITY sub-m420 SYSTEM "v4l/pixfmt-m420.xml">
<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
<!ENTITY sub-nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
<!ENTITY sub-nv12mt SYSTEM "v4l/pixfmt-nv12mt.xml">
......@@ -295,6 +296,7 @@
<!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
<!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml">
<!ENTITY sub-y12 SYSTEM "v4l/pixfmt-y12.xml">
<!ENTITY sub-y10b SYSTEM "v4l/pixfmt-y10b.xml">
<!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
<!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
<!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
......
<refentry id="V4L2-PIX-FMT-M420">
<refmeta>
<refentrytitle>V4L2_PIX_FMT_M420 ('M420')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname><constant>V4L2_PIX_FMT_M420</constant></refname>
<refpurpose>Format with &frac12; horizontal and vertical chroma
resolution, also known as YUV 4:2:0. Hybrid plane line-interleaved
layout.</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>M420 is a YUV format with &frac12; horizontal and vertical chroma
subsampling (YUV 4:2:0). Pixels are organized as interleaved luma and
chroma planes. Two lines of luma data are followed by one line of chroma
data.</para>
<para>The luma plane has one byte per pixel. The chroma plane contains
interleaved CbCr pixels subsampled by &frac12; in the horizontal and
vertical directions. Each CbCr pair belongs to four pixels. For example,
Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.</para>
<para>All line lengths are identical: if the Y lines include pad bytes
so do the CbCr lines.</para>
<example>
<title><constant>V4L2_PIX_FMT_M420</constant> 4 &times; 4
pixel image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="5" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>Y'<subscript>00</subscript></entry>
<entry>Y'<subscript>01</subscript></entry>
<entry>Y'<subscript>02</subscript></entry>
<entry>Y'<subscript>03</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;4:</entry>
<entry>Y'<subscript>10</subscript></entry>
<entry>Y'<subscript>11</subscript></entry>
<entry>Y'<subscript>12</subscript></entry>
<entry>Y'<subscript>13</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;8:</entry>
<entry>Cb<subscript>00</subscript></entry>
<entry>Cr<subscript>00</subscript></entry>
<entry>Cb<subscript>01</subscript></entry>
<entry>Cr<subscript>01</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;16:</entry>
<entry>Y'<subscript>20</subscript></entry>
<entry>Y'<subscript>21</subscript></entry>
<entry>Y'<subscript>22</subscript></entry>
<entry>Y'<subscript>23</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;20:</entry>
<entry>Y'<subscript>30</subscript></entry>
<entry>Y'<subscript>31</subscript></entry>
<entry>Y'<subscript>32</subscript></entry>
<entry>Y'<subscript>33</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;24:</entry>
<entry>Cb<subscript>10</subscript></entry>
<entry>Cr<subscript>10</subscript></entry>
<entry>Cb<subscript>11</subscript></entry>
<entry>Cr<subscript>11</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
<formalpara>
<title>Color Sample Location.</title>
<para>
<informaltable frame="none">
<tgroup cols="7" align="center">
<tbody valign="top">
<row>
<entry></entry>
<entry>0</entry><entry></entry><entry>1</entry><entry></entry>
<entry>2</entry><entry></entry><entry>3</entry>
</row>
<row>
<entry>0</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
<entry></entry><entry>C</entry><entry></entry><entry></entry>
<entry></entry><entry>C</entry><entry></entry>
</row>
<row>
<entry>1</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
</row>
<row>
<entry>2</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
<entry></entry><entry>C</entry><entry></entry><entry></entry>
<entry></entry><entry>C</entry><entry></entry>
</row>
<row>
<entry>3</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>
<!--
Local Variables:
mode: sgml
sgml-parent-document: "pixfmt.sgml"
indent-tabs-mode: nil
End:
-->
<refentry id="V4L2-PIX-FMT-Y10BPACK">
<refmeta>
<refentrytitle>V4L2_PIX_FMT_Y10BPACK ('Y10B')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname><constant>V4L2_PIX_FMT_Y10BPACK</constant></refname>
<refpurpose>Grey-scale image as a bit-packed array</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>This is a packed grey-scale image format with a depth of 10 bits per
pixel. Pixels are stored in a bit-packed array of 10bit bits per pixel,
with no padding between them and with the most significant bits coming
first from the left.</para>
<example>
<title><constant>V4L2_PIX_FMT_Y10BPACK</constant> 4 pixel data stream taking 5 bytes</title>
<formalpara>
<title>Bit-packed representation</title>
<para>pixels cross the byte boundary and have a ratio of 5 bytes for each 4
pixels.
<informaltable frame="all">
<tgroup cols="5" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>Y'<subscript>00[9:2]</subscript></entry>
<entry>Y'<subscript>00[1:0]</subscript>Y'<subscript>01[9:4]</subscript></entry>
<entry>Y'<subscript>01[3:0]</subscript>Y'<subscript>02[9:6]</subscript></entry>
<entry>Y'<subscript>02[5:0]</subscript>Y'<subscript>03[9:8]</subscript></entry>
<entry>Y'<subscript>03[7:0]</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>
......@@ -697,6 +697,7 @@ information.</para>
&sub-grey;
&sub-y10;
&sub-y12;
&sub-y10b;
&sub-y16;
&sub-yuyv;
&sub-uyvy;
......@@ -712,6 +713,7 @@ information.</para>
&sub-nv12m;
&sub-nv12mt;
&sub-nv16;
&sub-m420;
</section>
<section>
......
......@@ -2522,5 +2522,51 @@
</tgroup>
</table>
</section>
<section>
<title>JPEG Compressed Formats</title>
<para>Those data formats consist of an ordered sequence of 8-bit bytes
obtained from JPEG compression process. Additionally to the
<constant>_JPEG</constant> prefix the format code is made of
the following information.
<itemizedlist>
<listitem>The number of bus samples per entropy encoded byte.</listitem>
<listitem>The bus width.</listitem>
</itemizedlist>
<para>For instance, for a JPEG baseline process and an 8-bit bus width
the format will be named <constant>V4L2_MBUS_FMT_JPEG_1X8</constant>.
</para>
</para>
<para>The following table lists existing JPEG compressed formats.</para>
<table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-jpeg">
<title>JPEG Formats</title>
<tgroup cols="3">
<colspec colname="id" align="left" />
<colspec colname="code" align="left"/>
<colspec colname="remarks" align="left"/>
<thead>
<row>
<entry>Identifier</entry>
<entry>Code</entry>
<entry>Remarks</entry>
</row>
</thead>
<tbody valign="top">
<row id="V4L2-MBUS-FMT-JPEG-1X8">
<entry>V4L2_MBUS_FMT_JPEG_1X8</entry>
<entry>0x4001</entry>
<entry>Besides of its usage for the parallel bus this format is
recommended for transmission of JPEG data over MIPI CSI bus
using the User Defined 8-bit Data types.
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
</section>
......@@ -311,6 +311,9 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
#define <link linkend="V4L2-PIX-FMT-Y10">V4L2_PIX_FMT_Y10</link> v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
#define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link> v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
/* Grey bit-packed formats */
#define <link linkend="V4L2-PIX-FMT-Y10BPACK">V4L2_PIX_FMT_Y10BPACK</link> v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */
/* Palette formats */
#define <link linkend="V4L2-PIX-FMT-PAL8">V4L2_PIX_FMT_PAL8</link> v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */
......@@ -333,6 +336,7 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
#define <link linkend="V4L2-PIX-FMT-YUV420">V4L2_PIX_FMT_YUV420</link> v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
#define <link linkend="V4L2-PIX-FMT-HI240">V4L2_PIX_FMT_HI240</link> v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */
#define <link linkend="V4L2-PIX-FMT-HM12">V4L2_PIX_FMT_HM12</link> v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */
#define <link linkend="V4L2-PIX-FMT-M420">V4L2_PIX_FMT_M420</link> v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */
/* two planes -- one Y, one Cr + Cb interleaved */
#define <link linkend="V4L2-PIX-FMT-NV12">V4L2_PIX_FMT_NV12</link> v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
......
......@@ -551,3 +551,26 @@ Why: These legacy callbacks should no longer be used as i2c-core offers
Who: Jean Delvare <khali@linux-fr.org>
----------------------------
What: Support for UVCIOC_CTRL_ADD in the uvcvideo driver
When: 2.6.42
Why: The information passed to the driver by this ioctl is now queried
dynamically from the device.
Who: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
----------------------------
What: Support for UVCIOC_CTRL_MAP_OLD in the uvcvideo driver
When: 2.6.42
Why: Used only by applications compiled against older driver versions.
Superseded by UVCIOC_CTRL_MAP which supports V4L2 menu controls.
Who: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
----------------------------
What: Support for UVCIOC_CTRL_GET and UVCIOC_CTRL_SET in the uvcvideo driver
When: 2.6.42
Why: Superseded by the UVCIOC_CTRL_QUERY ioctl.
Who: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
----------------------------
......@@ -166,7 +166,6 @@ Code Seq#(hex) Include File Comments
'T' all arch/x86/include/asm/ioctls.h conflict!
'T' C0-DF linux/if_tun.h conflict!
'U' all sound/asound.h conflict!
'U' 00-0F drivers/media/video/uvc/uvcvideo.h conflict!
'U' 00-CF linux/uinput.h conflict!
'U' 00-EF linux/usbdevice_fs.h
'U' C0-CF drivers/bluetooth/hci_uart.h
......@@ -259,6 +258,7 @@ Code Seq#(hex) Include File Comments
't' 80-8F linux/isdn_ppp.h
't' 90 linux/toshiba.h
'u' 00-1F linux/smb_fs.h gone
'u' 20-3F linux/uvcvideo.h USB video class host driver
'v' 00-1F linux/ext2_fs.h conflict!
'v' 00-1F linux/fs.h conflict!
'v' 00-0F linux/sonypi.h conflict!
......
......@@ -54,7 +54,7 @@
53 -> Pinnacle Hybrid Pro (em2881)
54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323]
55 -> Terratec Cinnergy Hybrid T USB XS (em2882) (em2882) [0ccd:005e,0ccd:0042]
56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
56 -> Pinnacle Hybrid Pro (330e) (em2882) [2304:0226]
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f]
......
......@@ -130,7 +130,6 @@ Card number: 4
Note: No module for the mse3000 is available yet
Note: No module for the vpx3224 is available yet
Note: use encoder=X or decoder=X for non-default i2c chips
===========================
......
......@@ -275,6 +275,7 @@ pac7302 093a:2629 Genious iSlim 300
pac7302 093a:262a Webcam 300k
pac7302 093a:262c Philips SPC 230 NC
jeilinj 0979:0280 Sakar 57379
jeilinj 0979:0280 Sportscam DV15
zc3xx 0ac8:0302 Z-star Vimicro zc0302
vc032x 0ac8:0321 Vimicro generic vc0321
vc032x 0ac8:0323 Vimicro Vc0323
......
Linux USB Video Class (UVC) driver
==================================
This file documents some driver-specific aspects of the UVC driver, such as
driver-specific ioctls and implementation notes.
Questions and remarks can be sent to the Linux UVC development mailing list at
linux-uvc-devel@lists.berlios.de.
Extension Unit (XU) support
---------------------------
1. Introduction
The UVC specification allows for vendor-specific extensions through extension
units (XUs). The Linux UVC driver supports extension unit controls (XU controls)
through two separate mechanisms:
- through mappings of XU controls to V4L2 controls
- through a driver-specific ioctl interface
The first one allows generic V4L2 applications to use XU controls by mapping
certain XU controls onto V4L2 controls, which then show up during ordinary
control enumeration.
The second mechanism requires uvcvideo-specific knowledge for the application to
access XU controls but exposes the entire UVC XU concept to user space for
maximum flexibility.
Both mechanisms complement each other and are described in more detail below.
2. Control mappings
The UVC driver provides an API for user space applications to define so-called
control mappings at runtime. These allow for individual XU controls or byte
ranges thereof to be mapped to new V4L2 controls. Such controls appear and
function exactly like normal V4L2 controls (i.e. the stock controls, such as
brightness, contrast, etc.). However, reading or writing of such a V4L2 controls
triggers a read or write of the associated XU control.
The ioctl used to create these control mappings is called UVCIOC_CTRL_MAP.
Previous driver versions (before 0.2.0) required another ioctl to be used
beforehand (UVCIOC_CTRL_ADD) to pass XU control information to the UVC driver.
This is no longer necessary as newer uvcvideo versions query the information
directly from the device.
For details on the UVCIOC_CTRL_MAP ioctl please refer to the section titled
"IOCTL reference" below.
3. Driver specific XU control interface
For applications that need to access XU controls directly, e.g. for testing
purposes, firmware upload, or accessing binary controls, a second mechanism to
access XU controls is provided in the form of a driver-specific ioctl, namely
UVCIOC_CTRL_QUERY.
A call to this ioctl allows applications to send queries to the UVC driver that
directly map to the low-level UVC control requests.
In order to make such a request the UVC unit ID of the control's extension unit
and the control selector need to be known. This information either needs to be
hardcoded in the application or queried using other ways such as by parsing the
UVC descriptor or, if available, using the media controller API to enumerate a
device's entities.
Unless the control size is already known it is necessary to first make a
UVC_GET_LEN requests in order to be able to allocate a sufficiently large buffer
and set the buffer size to the correct value. Similarly, to find out whether
UVC_GET_CUR or UVC_SET_CUR are valid requests for a given control, a
UVC_GET_INFO request should be made. The bits 0 (GET supported) and 1 (SET
supported) of the resulting byte indicate which requests are valid.
With the addition of the UVCIOC_CTRL_QUERY ioctl the UVCIOC_CTRL_GET and
UVCIOC_CTRL_SET ioctls have become obsolete since their functionality is a
subset of the former ioctl. For the time being they are still supported but
application developers are encouraged to use UVCIOC_CTRL_QUERY instead.
For details on the UVCIOC_CTRL_QUERY ioctl please refer to the section titled
"IOCTL reference" below.
4. Security
The API doesn't currently provide a fine-grained access control facility. The
UVCIOC_CTRL_ADD and UVCIOC_CTRL_MAP ioctls require super user permissions.
Suggestions on how to improve this are welcome.
5. Debugging
In order to debug problems related to XU controls or controls in general it is
recommended to enable the UVC_TRACE_CONTROL bit in the module parameter 'trace'.
This causes extra output to be written into the system log.
6. IOCTL reference
---- UVCIOC_CTRL_MAP - Map a UVC control to a V4L2 control ----
Argument: struct uvc_xu_control_mapping
Description:
This ioctl creates a mapping between a UVC control or part of a UVC
control and a V4L2 control. Once mappings are defined, userspace
applications can access vendor-defined UVC control through the V4L2
control API.
To create a mapping, applications fill the uvc_xu_control_mapping
structure with information about an existing UVC control defined with
UVCIOC_CTRL_ADD and a new V4L2 control.
A UVC control can be mapped to several V4L2 controls. For instance,
a UVC pan/tilt control could be mapped to separate pan and tilt V4L2
controls. The UVC control is divided into non overlapping fields using
the 'size' and 'offset' fields and are then independantly mapped to
V4L2 control.
For signed integer V4L2 controls the data_type field should be set to
UVC_CTRL_DATA_TYPE_SIGNED. Other values are currently ignored.
Return value:
On success 0 is returned. On error -1 is returned and errno is set
appropriately.
ENOMEM
Not enough memory to perform the operation.
EPERM
Insufficient privileges (super user privileges are required).
EINVAL
No such UVC control.
EOVERFLOW
The requested offset and size would overflow the UVC control.
EEXIST
Mapping already exists.
Data types:
* struct uvc_xu_control_mapping
__u32 id V4L2 control identifier
__u8 name[32] V4L2 control name
__u8 entity[16] UVC extension unit GUID
__u8 selector UVC control selector
__u8 size V4L2 control size (in bits)
__u8 offset V4L2 control offset (in bits)
enum v4l2_ctrl_type
v4l2_type V4L2 control type
enum uvc_control_data_type
data_type UVC control data type
struct uvc_menu_info
*menu_info Array of menu entries (for menu controls only)
__u32 menu_count Number of menu entries (for menu controls only)
* struct uvc_menu_info
__u32 value Menu entry value used by the device
__u8 name[32] Menu entry name
* enum uvc_control_data_type
UVC_CTRL_DATA_TYPE_RAW Raw control (byte array)
UVC_CTRL_DATA_TYPE_SIGNED Signed integer
UVC_CTRL_DATA_TYPE_UNSIGNED Unsigned integer
UVC_CTRL_DATA_TYPE_BOOLEAN Boolean
UVC_CTRL_DATA_TYPE_ENUM Enumeration
UVC_CTRL_DATA_TYPE_BITMASK Bitmask
---- UVCIOC_CTRL_QUERY - Query a UVC XU control ----
Argument: struct uvc_xu_control_query
Description:
This ioctl queries a UVC XU control identified by its extension unit ID
and control selector.
There are a number of different queries available that closely
correspond to the low-level control requests described in the UVC
specification. These requests are:
UVC_GET_CUR
Obtain the current value of the control.
UVC_GET_MIN
Obtain the minimum value of the control.
UVC_GET_MAX
Obtain the maximum value of the control.
UVC_GET_DEF
Obtain the default value of the control.
UVC_GET_RES
Query the resolution of the control, i.e. the step size of the
allowed control values.
UVC_GET_LEN
Query the size of the control in bytes.
UVC_GET_INFO
Query the control information bitmap, which indicates whether
get/set requests are supported.
UVC_SET_CUR
Update the value of the control.
Applications must set the 'size' field to the correct length for the
control. Exceptions are the UVC_GET_LEN and UVC_GET_INFO queries, for
which the size must be set to 2 and 1, respectively. The 'data' field
must point to a valid writable buffer big enough to hold the indicated
number of data bytes.
Data is copied directly from the device without any driver-side
processing. Applications are responsible for data buffer formatting,
including little-endian/big-endian conversion. This is particularly
important for the result of the UVC_GET_LEN requests, which is always
returned as a little-endian 16-bit integer by the device.
Return value:
On success 0 is returned. On error -1 is returned and errno is set
appropriately.
ENOENT
The device does not support the given control or the specified
extension unit could not be found.
ENOBUFS
The specified buffer size is incorrect (too big or too small).
EINVAL
An invalid request code was passed.
EBADRQC
The given request is not supported by the given control.
EFAULT
The data pointer references an inaccessible memory area.
Data types:
* struct uvc_xu_control_query
__u8 unit Extension unit ID
__u8 selector Control selector
__u8 query Request code to send to the device
__u16 size Control data size (in bytes)
__u8 *data Control value
......@@ -378,12 +378,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
dev->pci = pci;
/* get chip-revision; this is needed to enable bug-fixes */
err = pci_read_config_dword(pci, PCI_CLASS_REVISION, &dev->revision);
if (err < 0) {
ERR(("pci_read_config_dword() failed.\n"));
goto err_disable;
}
dev->revision &= 0xf;
dev->revision = pci->revision;
/* remap the memory from virtual to physical address */
......
......@@ -186,4 +186,12 @@ config MEDIA_TUNER_TDA18218
default m if MEDIA_TUNER_CUSTOMISE
help
NXP TDA18218 silicon tuner driver.
config MEDIA_TUNER_TDA18212
tristate "NXP TDA18212 silicon tuner"
depends on VIDEO_MEDIA && I2C
default m if MEDIA_TUNER_CUSTOMISE
help
NXP TDA18212 silicon tuner driver.
endmenu
......@@ -25,6 +25,7 @@ obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
......@@ -4024,6 +4024,8 @@ static int mxl5005s_set_params(struct dvb_frontend *fe,
case BANDWIDTH_8_MHZ:
req_bw = MXL5005S_BANDWIDTH_8MHZ;
break;
default:
return -EINVAL;
}
}
......
/*
* NXP TDA18212HN silicon tuner driver
*
* Copyright (C) 2011 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "tda18212_priv.h"
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
/* write multiple registers */
static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
int len)
{
int ret;
u8 buf[len+1];
struct i2c_msg msg[1] = {
{
.addr = priv->cfg->i2c_address,
.flags = 0,
.len = sizeof(buf),
.buf = buf,
}
};
buf[0] = reg;
memcpy(&buf[1], val, len);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret == 1) {
ret = 0;
} else {
warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
/* read multiple registers */
static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
int len)
{
int ret;
u8 buf[len];
struct i2c_msg msg[2] = {
{
.addr = priv->cfg->i2c_address,
.flags = 0,
.len = 1,
.buf = &reg,
}, {
.addr = priv->cfg->i2c_address,
.flags = I2C_M_RD,
.len = sizeof(buf),
.buf = buf,
}
};
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret == 2) {
memcpy(val, buf, len);
ret = 0;
} else {
warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
/* write single register */
static int tda18212_wr_reg(struct tda18212_priv *priv, u8 reg, u8 val)
{
return tda18212_wr_regs(priv, reg, &val, 1);
}
/* read single register */
static int tda18212_rd_reg(struct tda18212_priv *priv, u8 reg, u8 *val)
{
return tda18212_rd_regs(priv, reg, val, 1);
}
#if 0 /* keep, useful when developing driver */
static void tda18212_dump_regs(struct tda18212_priv *priv)
{
int i;
u8 buf[256];
#define TDA18212_RD_LEN 32
for (i = 0; i < sizeof(buf); i += TDA18212_RD_LEN)
tda18212_rd_regs(priv, i, &buf[i], TDA18212_RD_LEN);
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 32, 1, buf,
sizeof(buf), true);
return;
}
#endif
static int tda18212_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct tda18212_priv *priv = fe->tuner_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i;
u32 if_khz;
u8 buf[9];
static const u8 bw_params[][3] = {
/* 0f 13 23 */
{ 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */
{ 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */
{ 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */
{ 0x92, 0x53, 0x03 }, /* DVB-C */
};
dbg("%s: delsys=%d RF=%d BW=%d", __func__,
c->delivery_system, c->frequency, c->bandwidth_hz);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
switch (c->delivery_system) {
case SYS_DVBT:
switch (c->bandwidth_hz) {
case 6000000:
if_khz = priv->cfg->if_dvbt_6;
i = 0;
break;
case 7000000:
if_khz = priv->cfg->if_dvbt_7;
i = 1;
break;
case 8000000:
if_khz = priv->cfg->if_dvbt_8;
i = 2;
break;
default:
ret = -EINVAL;
goto error;
}
break;
case SYS_DVBC_ANNEX_AC:
if_khz = priv->cfg->if_dvbc;
i = 3;
break;
default:
ret = -EINVAL;
goto error;
}
ret = tda18212_wr_reg(priv, 0x23, bw_params[i][2]);
if (ret)
goto error;
ret = tda18212_wr_reg(priv, 0x06, 0x00);
if (ret)
goto error;
ret = tda18212_wr_reg(priv, 0x0f, bw_params[i][0]);
if (ret)
goto error;
buf[0] = 0x02;
buf[1] = bw_params[i][1];
buf[2] = 0x03; /* default value */
buf[3] = if_khz / 50;
buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
buf[5] = ((c->frequency / 1000) >> 8) & 0xff;
buf[6] = ((c->frequency / 1000) >> 0) & 0xff;
buf[7] = 0xc1;
buf[8] = 0x01;
ret = tda18212_wr_regs(priv, 0x12, buf, sizeof(buf));
if (ret)
goto error;
exit:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
return ret;
error:
dbg("%s: failed:%d", __func__, ret);
goto exit;
}
static int tda18212_release(struct dvb_frontend *fe)
{
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static const struct dvb_tuner_ops tda18212_tuner_ops = {
.info = {
.name = "NXP TDA18212",
.frequency_min = 48000000,
.frequency_max = 864000000,
.frequency_step = 1000,
},
.release = tda18212_release,
.set_params = tda18212_set_params,
};
struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18212_config *cfg)
{
struct tda18212_priv *priv = NULL;
int ret;
u8 val;
priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->cfg = cfg;
priv->i2c = i2c;
fe->tuner_priv = priv;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
/* check if the tuner is there */
ret = tda18212_rd_reg(priv, 0x00, &val);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
if (ret || val != 0xc7) {
kfree(priv);
return NULL;
}
info("NXP TDA18212HN successfully identified.");
memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
sizeof(struct dvb_tuner_ops));
return fe;
}
EXPORT_SYMBOL(tda18212_attach);
MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_LICENSE("GPL");
/*
* NXP TDA18212HN silicon tuner driver
*
* Copyright (C) 2011 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef TDA18212_H
#define TDA18212_H
#include "dvb_frontend.h"
struct tda18212_config {
u8 i2c_address;
u16 if_dvbt_6;
u16 if_dvbt_7;
u16 if_dvbt_8;
u16 if_dvbc;
};
#if defined(CONFIG_MEDIA_TUNER_TDA18212) || \
(defined(CONFIG_MEDIA_TUNER_TDA18212_MODULE) && defined(MODULE))
extern struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18212_config *cfg);
#else
static inline struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18212_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif
/*
* NXP TDA18212HN silicon tuner driver
*
* Copyright (C) 2011 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef TDA18212_PRIV_H
#define TDA18212_PRIV_H
#include "tda18212.h"
#define LOG_PREFIX "tda18212"
#undef dbg
#define dbg(f, arg...) \
if (debug) \
printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
#undef err
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
#undef info
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
#undef warn
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
struct tda18212_priv {
struct tda18212_config *cfg;
struct i2c_adapter *i2c;
};
#endif
......@@ -976,6 +976,10 @@ static int tda18271_set_params(struct dvb_frontend *fe,
tda_warn("bandwidth not set!\n");
return -EINVAL;
}
} else if (fe->ops.info.type == FE_QAM) {
/* DVB-C */
map = &std_map->qam_8;
bw = 8000000;
} else {
tda_warn("modulation type not supported!\n");
return -EINVAL;
......
......@@ -628,6 +628,15 @@ static void xc_debug_dump(struct xc5000_priv *priv)
dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
}
/*
* As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
* So, the amount of the needed bandwith is given by:
* Bw = Symbol_rate * (1 + 0.15)
* As such, the maximum symbol rate supported by 6 MHz is given by:
* max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
*/
#define MAX_SYMBOL_RATE_6MHz 5217391
static int xc5000_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
......@@ -688,21 +697,32 @@ static int xc5000_set_params(struct dvb_frontend *fe,
}
priv->rf_mode = XC_RF_MODE_AIR;
} else if (fe->ops.info.type == FE_QAM) {
dprintk(1, "%s() QAM\n", __func__);
switch (params->u.qam.modulation) {
case QAM_256:
case QAM_AUTO:
case QAM_16:
case QAM_32:
case QAM_64:
case QAM_128:
case QAM_256:
case QAM_AUTO:
dprintk(1, "%s() QAM modulation\n", __func__);
priv->bandwidth = BANDWIDTH_8_MHZ;
priv->video_standard = DTV7_8;
priv->freq_hz = params->frequency - 2750000;
priv->rf_mode = XC_RF_MODE_CABLE;
/*
* Using a 8MHz bandwidth sometimes fail
* with 6MHz-spaced channels, due to inter-carrier
* interference. So, use DTV6 firmware
*/
if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) {
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->video_standard = DTV6;
priv->freq_hz = params->frequency - 1750000;
} else {
priv->bandwidth = BANDWIDTH_8_MHZ;
priv->video_standard = DTV7_8;
priv->freq_hz = params->frequency - 2750000;
}
break;
default:
dprintk(1, "%s() Unsupported QAM type\n", __func__);
return -EINVAL;
}
} else {
......
......@@ -290,10 +290,8 @@ static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
static int flexcop_pci_init(struct flexcop_pci *fc_pci)
{
int ret;
u8 card_rev;
pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev);
info("card revision %x", card_rev);
info("card revision %x", fc_pci->pdev->revision);
if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
return ret;
......
......@@ -460,7 +460,7 @@ static int __devinit bt878_probe(struct pci_dev *dev,
goto fail0;
}
pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
bt->revision = dev->revision;
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
......
......@@ -478,97 +478,94 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
static inline int find_next_packet(const u8 *buf, int pos, size_t count,
const int pktsize)
{
int p = 0, i, j;
int start = pos, lost;
spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
j = 188 - i;
if (count < j) {
memcpy(&demux->tsbuf[i], buf, count);
demux->tsbufp += count;
goto bailout;
}
memcpy(&demux->tsbuf[i], buf, j);
if (demux->tsbuf[0] == 0x47)
dvb_dmx_swfilter_packet(demux, demux->tsbuf);
demux->tsbufp = 0;
p += j;
while (pos < count) {
if (buf[pos] == 0x47 ||
(pktsize == 204 && buf[pos] == 0xB8))
break;
pos++;
}
while (p < count) {
if (buf[p] == 0x47) {
if (count - p >= 188) {
dvb_dmx_swfilter_packet(demux, &buf[p]);
p += 188;
} else {
i = count - p;
memcpy(demux->tsbuf, &buf[p], i);
demux->tsbufp = i;
goto bailout;
}
} else
p++;
lost = pos - start;
if (lost) {
/* This garbage is part of a valid packet? */
int backtrack = pos - pktsize;
if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
(pktsize == 204 && buf[backtrack] == 0xB8)))
return backtrack;
}
bailout:
spin_unlock(&demux->lock);
return pos;
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
size_t count, const int pktsize)
{
int p = 0, i, j;
u8 tmppack[188];
const u8 *q;
spin_lock(&demux->lock);
if (demux->tsbufp) {
if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
i = demux->tsbufp;
j = 204 - i;
j = pktsize - i;
if (count < j) {
memcpy(&demux->tsbuf[i], buf, count);
demux->tsbufp += count;
goto bailout;
}
memcpy(&demux->tsbuf[i], buf, j);
if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) {
memcpy(tmppack, demux->tsbuf, 188);
if (tmppack[0] == 0xB8)
tmppack[0] = 0x47;
dvb_dmx_swfilter_packet(demux, tmppack);
}
if (demux->tsbuf[0] == 0x47) /* double check */
dvb_dmx_swfilter_packet(demux, demux->tsbuf);
demux->tsbufp = 0;
p += j;
}
while (p < count) {
if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
if (count - p >= 204) {
memcpy(tmppack, &buf[p], 188);
if (tmppack[0] == 0xB8)
tmppack[0] = 0x47;
dvb_dmx_swfilter_packet(demux, tmppack);
p += 204;
} else {
i = count - p;
memcpy(demux->tsbuf, &buf[p], i);
demux->tsbufp = i;
goto bailout;
}
} else {
p++;
while (1) {
p = find_next_packet(buf, p, count, pktsize);
if (p >= count)
break;
if (count - p < pktsize)
break;
q = &buf[p];
if (pktsize == 204 && (*q == 0xB8)) {
memcpy(demux->tsbuf, q, 188);
demux->tsbuf[0] = 0x47;
q = demux->tsbuf;
}
dvb_dmx_swfilter_packet(demux, q);
p += pktsize;
}
i = count - p;
if (i) {
memcpy(demux->tsbuf, &buf[p], i);
demux->tsbufp = i;
if (pktsize == 204 && demux->tsbuf[0] == 0xB8)
demux->tsbuf[0] = 0x47;
}
bailout:
spin_unlock(&demux->lock);
}
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
_dvb_dmx_swfilter(demux, buf, count, 188);
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
_dvb_dmx_swfilter(demux, buf, count, 204);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_204);
static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
......
This diff is collapsed.
......@@ -358,6 +358,9 @@ struct dtv_frontend_properties {
/* ISDB-T specifics */
u32 isdbs_ts_id;
/* DVB-T2 specifics */
u32 dvbt2_plp_id;
};
struct dvb_frontend {
......
......@@ -292,6 +292,11 @@ config DVB_USB_ANYSEE
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_STV0900 if !DVB_FE_CUSTOMISE
select DVB_STV6110 if !DVB_FE_CUSTOMISE
select DVB_ISL6423 if !DVB_FE_CUSTOMISE
help
Say Y here to support the Anysee E30, Anysee E30 Plus or
Anysee E30 C Plus DVB USB2.0 receiver.
......
......@@ -78,17 +78,26 @@ static struct rc_map_table rc_map_a800_table[] = {
static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
u8 key[5];
int ret;
u8 *key = kmalloc(5, GFP_KERNEL);
if (!key)
return -ENOMEM;
if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
2000) != 5)
return -ENODEV;
2000) != 5) {
ret = -ENODEV;
goto out;
}
/* call the universal NEC remote processor, to find out the key's state and event */
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
return 0;
ret = 0;
out:
kfree(key);
return ret;
}
/* USB Driver stuff */
......
This diff is collapsed.
......@@ -57,10 +57,29 @@ enum cmd {
};
struct anysee_state {
u8 tuner;
u8 hw; /* PCB ID */
u8 seq;
};
#define ANYSEE_HW_02 2 /* E30 */
#define ANYSEE_HW_507CD 6 /* E30 Plus */
#define ANYSEE_HW_507DC 10 /* E30 C Plus */
#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */
#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */
#define ANYSEE_HW_508TC 18 /* E7 TC */
#define ANYSEE_HW_508S2 19 /* E7 S2 */
#define REG_IOA 0x80 /* Port A (bit addressable) */
#define REG_IOB 0x90 /* Port B (bit addressable) */
#define REG_IOC 0xa0 /* Port C (bit addressable) */
#define REG_IOD 0xb0 /* Port D (bit addressable) */
#define REG_IOE 0xb1 /* Port E (NOT bit addressable) */
#define REG_OEA 0xb2 /* Port A Output Enable */
#define REG_OEB 0xb3 /* Port B Output Enable */
#define REG_OEC 0xb4 /* Port C Output Enable */
#define REG_OED 0xb5 /* Port D Output Enable */
#define REG_OEE 0xb6 /* Port E Output Enable */
#endif
/***************************************************************************
......@@ -136,7 +155,7 @@ General reply packet(s) are always used if not own reply defined.
----------------------------------------------------------------------------
| 04 | 0x00
----------------------------------------------------------------------------
| 05 | 0x01
| 05 | data length
----------------------------------------------------------------------------
| 06-59 | don't care
----------------------------------------------------------------------------
......
......@@ -33,8 +33,16 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
{
int ret;
u16 index;
u8 usb_buf[6]; /* enough for all known requests,
read returns 5 and write 6 bytes */
u8 *usb_buf;
/*
* allocate enough for all known requests,
* read returns 5 and write 6 bytes
*/
usb_buf = kmalloc(6, GFP_KERNEL);
if (!usb_buf)
return -ENOMEM;
switch (wlen) {
case 1:
index = wbuf[0] << 8;
......@@ -45,14 +53,15 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
break;
default:
warn("wlen = %x, aborting.", wlen);
return -EINVAL;
ret = -EINVAL;
goto error;
}
ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT);
usb_buf, 6, AU6610_USB_TIMEOUT);
if (ret < 0)
return ret;
goto error;
switch (operation) {
case AU6610_REQ_I2C_READ:
......@@ -60,7 +69,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
/* requested value is always 5th byte in buffer */
rbuf[0] = usb_buf[4];
}
error:
kfree(usb_buf);
return ret;
}
......
......@@ -39,7 +39,7 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
u8 requesttype;
u16 value;
u16 index;
u8 buf[req->data_len];
u8 *buf;
request = req->cmd;
value = req->value;
......@@ -62,6 +62,12 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
goto error;
}
buf = kmalloc(req->data_len, GFP_KERNEL);
if (!buf) {
ret = -ENOMEM;
goto error;
}
if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
/* write */
memcpy(buf, req->data, req->data_len);
......@@ -74,7 +80,7 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
msleep(1); /* avoid I2C errors */
ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
buf, sizeof(buf), CE6230_USB_TIMEOUT);
buf, req->data_len, CE6230_USB_TIMEOUT);
ce6230_debug_dump(request, requesttype, value, index, buf,
req->data_len, deb_xfer);
......@@ -88,6 +94,7 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
memcpy(req->data, buf, req->data_len);
kfree(buf);
error:
return ret;
}
......
......@@ -46,8 +46,9 @@ struct dib0700_state {
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
u32 fw_version;
u32 nb_packet_buffer_size;
u32 fw_version;
u32 nb_packet_buffer_size;
u8 buf[255];
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
......
This diff is collapsed.
......@@ -2439,7 +2439,6 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
dib0700_set_i2c_speed(adap->dev, 340);
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
if (adap->fe == NULL)
return -ENODEV;
......@@ -2802,6 +2801,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
......@@ -3411,7 +3411,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
.num_device_descs = 3,
.num_device_descs = 4,
.devices = {
{ "DiBcom STK7770P reference design",
{ &dib0700_usb_id_table[59], NULL },
......@@ -3427,6 +3427,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[74], NULL },
{ NULL },
},
{ "Medion CTX1921 DVB-T USB",
{ &dib0700_usb_id_table[75], NULL },
{ NULL },
},
},
.rc.core = {
......
......@@ -408,7 +408,7 @@ struct rc_map_table rc_map_dibusb_table[] = {
{ 0x8008, KEY_DVD },
{ 0x8009, KEY_AUDIO },
{ 0x800a, KEY_MEDIA }, /* Pictures */
{ 0x800a, KEY_IMAGES }, /* Pictures */
{ 0x800b, KEY_VIDEO },
{ 0x800c, KEY_BACK },
......
......@@ -12,7 +12,7 @@
static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
{
struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
int newfeedcount,ret;
int newfeedcount, ret;
if (adap == NULL)
return -ENODEV;
......@@ -24,9 +24,13 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
deb_ts("stop feeding\n");
usb_urb_kill(&adap->stream);
if (adap->props.streaming_ctrl != NULL)
if ((ret = adap->props.streaming_ctrl(adap,0)))
if (adap->props.streaming_ctrl != NULL) {
ret = adap->props.streaming_ctrl(adap, 0);
if (ret < 0) {
err("error while stopping stream.");
return ret;
}
}
}
adap->feedcount = newfeedcount;
......@@ -49,17 +53,24 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
deb_ts("controlling pid parser\n");
if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
adap->props.caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
adap->props.pid_filter_ctrl != NULL)
if (adap->props.pid_filter_ctrl(adap,adap->pid_filtering) < 0)
adap->props.caps &
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
adap->props.pid_filter_ctrl != NULL) {
ret = adap->props.pid_filter_ctrl(adap,
adap->pid_filtering);
if (ret < 0) {
err("could not handle pid_parser");
return ret;
}
}
deb_ts("start feeding\n");
if (adap->props.streaming_ctrl != NULL)
if (adap->props.streaming_ctrl(adap,1)) {
if (adap->props.streaming_ctrl != NULL) {
ret = adap->props.streaming_ctrl(adap, 1);
if (ret < 0) {
err("error while enabling fifo.");
return -ENODEV;
return ret;
}
}
}
return 0;
......
......@@ -91,6 +91,7 @@
#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397
#define USB_PID_CONEXANT_D680_DMB 0x86d6
#define USB_PID_CREATIX_CTX1921 0x1921
#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
......
......@@ -121,12 +121,16 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
u16 index, u8 * data, u16 len, int flags)
{
int ret;
u8 u8buf[len];
u8 *u8buf;
unsigned int pipe = (flags == DW210X_READ_MSG) ?
usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
u8buf = kmalloc(len, GFP_KERNEL);
if (!u8buf)
return -ENOMEM;
if (flags == DW210X_WRITE_MSG)
memcpy(u8buf, data, len);
ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
......@@ -134,6 +138,8 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
if (flags == DW210X_READ_MSG)
memcpy(data, u8buf, len);
kfree(u8buf);
return ret;
}
......
......@@ -36,7 +36,9 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
int ret;
unsigned int pipe;
u8 request, requesttype;
u8 buf[req->size];
u8 *buf;
switch (req->cmd) {
case DOWNLOAD_FIRMWARE:
......@@ -72,6 +74,12 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
goto error;
}
buf = kmalloc(req->size, GFP_KERNEL);
if (!buf) {
ret = -ENOMEM;
goto error;
}
if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
/* write */
memcpy(buf, req->data, req->size);
......@@ -84,13 +92,13 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
msleep(1); /* avoid I2C errors */
ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
req->index, buf, sizeof(buf), EC168_USB_TIMEOUT);
req->index, buf, req->size, EC168_USB_TIMEOUT);
ec168_debug_dump(request, requesttype, req->value, req->index, buf,
req->size, deb_xfer);
if (ret < 0)
goto error;
goto err_dealloc;
else
ret = 0;
......@@ -98,7 +106,11 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
memcpy(req->data, buf, req->size);
kfree(buf);
return ret;
err_dealloc:
kfree(buf);
error:
deb_info("%s: failed:%d\n", __func__, ret);
return ret;
......
......@@ -142,17 +142,20 @@ static u32 gl861_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
static int friio_ext_ctl(struct dvb_usb_adapter *adap,
u32 sat_color, int lnb_on)
{
int i;
int ret;
struct i2c_msg msg;
u8 buf[2];
u8 *buf;
u32 mask;
u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
buf = kmalloc(2, GFP_KERNEL);
if (!buf)
return -ENOMEM;
msg.addr = 0x00;
msg.flags = 0;
msg.len = 2;
......@@ -189,6 +192,7 @@ static int friio_ext_ctl(struct dvb_usb_adapter *adap,
buf[1] |= FRIIO_CTL_CLK;
ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
kfree(buf);
return (ret == 70);
}
......@@ -219,11 +223,20 @@ static int friio_initialize(struct dvb_usb_device *d)
int ret;
int i;
int retry = 0;
u8 rbuf[2];
u8 wbuf[3];
u8 *rbuf, *wbuf;
deb_info("%s called.\n", __func__);
wbuf = kmalloc(3, GFP_KERNEL);
if (!wbuf)
return -ENOMEM;
rbuf = kmalloc(2, GFP_KERNEL);
if (!rbuf) {
kfree(wbuf);
return -ENOMEM;
}
/* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
/* because the i2c device is not set up yet. */
wbuf[0] = 0x11;
......@@ -358,6 +371,8 @@ static int friio_initialize(struct dvb_usb_device *d)
return 0;
error:
kfree(wbuf);
kfree(rbuf);
deb_info("%s:ret == %d\n", __func__, ret);
return -EIO;
}
......
......@@ -62,8 +62,6 @@
* LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
* with other tuners. After a cold reset streaming will not start.
*
* PID functions have been removed from this driver version due to
* problems with different firmware and application versions.
*/
#define DVB_USB_LOG_PREFIX "LME2510(C)"
#include <linux/usb.h>
......@@ -104,6 +102,10 @@ static int dvb_usb_lme2510_firmware;
module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
static int pid_filter;
module_param_named(pid, pid_filter, int, 0644);
MODULE_PARM_DESC(pid, "set default 0=on 1=off");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
......@@ -125,6 +127,7 @@ struct lme2510_state {
u8 i2c_tuner_gate_r;
u8 i2c_tuner_addr;
u8 stream_on;
u8 pid_size;
void *buffer;
struct urb *lme_urb;
void *usb_buffer;
......@@ -167,14 +170,14 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
}
buff = st->usb_buffer;
/* the read/write capped at 512 */
memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
ret = mutex_lock_interruptible(&d->usb_mutex);
if (ret < 0)
return -EAGAIN;
/* the read/write capped at 512 */
memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
......@@ -216,6 +219,37 @@ static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress)
return 0;
}
static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
{
struct lme2510_state *st = d->priv;
static u8 pid_buff[] = LME_ZERO_PID;
static u8 rbuf[1];
u8 pid_no = index * 2;
u8 pid_len = pid_no + 2;
int ret = 0;
deb_info(1, "PID Setting Pid %04x", pid_out);
if (st->pid_size == 0)
ret |= lme2510_stream_restart(d);
pid_buff[2] = pid_no;
pid_buff[3] = (u8)pid_out & 0xff;
pid_buff[4] = pid_no + 1;
pid_buff[5] = (u8)(pid_out >> 8);
if (pid_len > st->pid_size)
st->pid_size = pid_len;
pid_buff[7] = 0x80 + st->pid_size;
ret |= lme2510_usb_talk(d, pid_buff ,
sizeof(pid_buff) , rbuf, sizeof(rbuf));
if (st->stream_on)
ret |= lme2510_stream_restart(d);
return ret;
}
static void lme2510_int_response(struct urb *lme_urb)
{
struct dvb_usb_adapter *adap = lme_urb->context;
......@@ -326,16 +360,68 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap)
return 0;
}
static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct lme2510_state *st = adap->dev->priv;
static u8 clear_pid_reg[] = LME_CLEAR_PID;
static u8 rbuf[1];
int ret;
deb_info(1, "PID Clearing Filter");
ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
if (ret < 0)
return -EAGAIN;
if (!onoff)
ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
st->pid_size = 0;
mutex_unlock(&adap->dev->i2c_mutex);
return 0;
}
static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
int onoff)
{
int ret = 0;
deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
pid, index, onoff);
if (onoff)
if (!pid_filter) {
ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
if (ret < 0)
return -EAGAIN;
ret |= lme2510_enable_pid(adap->dev, index, pid);
mutex_unlock(&adap->dev->i2c_mutex);
}
return ret;
}
static int lme2510_return_status(struct usb_device *dev)
{
int ret = 0;
u8 data[10] = {0};
u8 *data;
data = kzalloc(10, GFP_KERNEL);
if (!data)
return -ENOMEM;
ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
info("Firmware Status: %x (%x)", ret , data[2]);
return (ret < 0) ? -ENODEV : data[2];
ret = (ret < 0) ? -ENODEV : data[2];
kfree(data);
return ret;
}
static int lme2510_msg(struct dvb_usb_device *d,
......@@ -591,9 +677,10 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
else {
deb_info(1, "STM Steam Off");
/* mutex is here only to avoid collision with I2C */
ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
ret = lme2510_usb_talk(adap->dev, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
st->stream_on = 0;
st->i2c_talk_onoff = 1;
......@@ -655,7 +742,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
const struct firmware *fw)
{
int ret = 0;
u8 data[512] = {0};
u8 *data;
u16 j, wlen, len_in, start, end;
u8 packet_size, dlen, i;
u8 *fw_data;
......@@ -663,6 +750,11 @@ static int lme2510_download_firmware(struct usb_device *dev,
packet_size = 0x31;
len_in = 1;
data = kzalloc(512, GFP_KERNEL);
if (!data) {
info("FRM Could not start Firmware Download (Buffer allocation failed)");
return -ENOMEM;
}
info("FRM Starting Firmware Download");
......@@ -678,15 +770,15 @@ static int lme2510_download_firmware(struct usb_device *dev,
data[0] = i | 0x80;
dlen = (u8)(end - j)-1;
}
data[1] = dlen;
memcpy(&data[2], fw_data, dlen+1);
wlen = (u8) dlen + 4;
data[wlen-1] = check_sum(fw_data, dlen+1);
deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
data[1] = dlen;
memcpy(&data[2], fw_data, dlen+1);
wlen = (u8) dlen + 4;
data[wlen-1] = check_sum(fw_data, dlen+1);
deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
data[dlen+2], data[dlen+3]);
ret |= lme2510_bulk_write(dev, data, wlen, 1);
ret |= lme2510_bulk_read(dev, data, len_in , 1);
ret |= (data[0] == 0x88) ? 0 : -1;
ret |= lme2510_bulk_write(dev, data, wlen, 1);
ret |= lme2510_bulk_read(dev, data, len_in , 1);
ret |= (data[0] == 0x88) ? 0 : -1;
}
}
......@@ -706,7 +798,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
else
info("FRM Firmware Download Completed - Resetting Device");
kfree(data);
return (ret < 0) ? -ENODEV : 0;
}
......@@ -747,7 +839,7 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
fw_lme = fw_s0194;
ret = request_firmware(&fw, fw_lme, &udev->dev);
if (ret == 0) {
cold = 0;/*lme2510-s0194 cannot cold reset*/
cold = 0;
break;
}
dvb_usb_lme2510_firmware = TUNER_LG;
......@@ -769,8 +861,10 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
case TUNER_S7395:
fw_lme = fw_c_s7395;
ret = request_firmware(&fw, fw_lme, &udev->dev);
if (ret == 0)
if (ret == 0) {
cold = 0;
break;
}
dvb_usb_lme2510_firmware = TUNER_LG;
case TUNER_LG:
fw_lme = fw_c_lg;
......@@ -796,14 +890,14 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
ret = lme2510_download_firmware(udev, fw);
}
release_firmware(fw);
if (cold) {
info("FRM Changing to %s firmware", fw_lme);
lme_coldreset(udev);
return -ENODEV;
}
release_firmware(fw);
return ret;
}
......@@ -1017,12 +1111,13 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
static u8 rbuf[1];
int ret, len = 3, rlen = 1;
ret = mutex_lock_interruptible(&d->i2c_mutex);
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (onoff)
ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
else
ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
st->i2c_talk_onoff = 1;
......@@ -1086,7 +1181,13 @@ static struct dvb_usb_device_properties lme2510_properties = {
.num_adapters = 1,
.adapter = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER|
DVB_USB_ADAP_NEED_PID_FILTERING|
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.streaming_ctrl = lme2510_streaming_ctrl,
.pid_filter_count = 15,
.pid_filter = lme2510_pid_filter,
.pid_filter_ctrl = lme2510_pid_filter_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
.tuner_attach = dm04_lme2510_tuner,
/* parameter for the MPEG2-data transfer */
......@@ -1122,7 +1223,13 @@ static struct dvb_usb_device_properties lme2510c_properties = {
.num_adapters = 1,
.adapter = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER|
DVB_USB_ADAP_NEED_PID_FILTERING|
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.streaming_ctrl = lme2510_streaming_ctrl,
.pid_filter_count = 15,
.pid_filter = lme2510_pid_filter,
.pid_filter_ctrl = lme2510_pid_filter_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
.tuner_attach = dm04_lme2510_tuner,
/* parameter for the MPEG2-data transfer */
......@@ -1151,7 +1258,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
}
};
void *lme2510_exit_int(struct dvb_usb_device *d)
static void *lme2510_exit_int(struct dvb_usb_device *d)
{
struct lme2510_state *st = d->priv;
struct dvb_usb_adapter *adap = &d->adapter[0];
......@@ -1178,7 +1285,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d)
return buffer;
}
void lme2510_exit(struct usb_interface *intf)
static void lme2510_exit(struct usb_interface *intf)
{
struct dvb_usb_device *d = usb_get_intfdata(intf);
void *usb_buffer;
......@@ -1220,5 +1327,5 @@ module_exit(lme2510_module_exit);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
MODULE_VERSION("1.80");
MODULE_VERSION("1.86");
MODULE_LICENSE("GPL");
......@@ -40,6 +40,7 @@
*/
#define LME_ST_ON_W {0x06, 0x00}
#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
/* LNB Voltage
* 07 XX XX
......@@ -108,14 +109,14 @@ static u8 s7395_inittab[] = {
0x3d, 0x30,
0x40, 0x63,
0x41, 0x04,
0x42, 0x60,
0x42, 0x20,
0x43, 0x00,
0x44, 0x00,
0x45, 0x00,
0x46, 0x00,
0x47, 0x00,
0x4a, 0x00,
0x50, 0x12,
0x50, 0x10,
0x51, 0x36,
0x52, 0x21,
0x53, 0x94,
......
......@@ -134,13 +134,17 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct m920x_state *m = d->priv;
int i, ret = 0;
u8 rc_state[2];
u8 *rc_state;
rc_state = kmalloc(2, GFP_KERNEL);
if (!rc_state)
return -ENOMEM;
if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
goto unlock;
goto out;
if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
goto unlock;
goto out;
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
......@@ -149,7 +153,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
switch(rc_state[0]) {
case 0x80:
*state = REMOTE_NO_KEY_PRESSED;
goto unlock;
goto out;
case 0x88: /* framing error or "invalid code" */
case 0x99:
......@@ -157,7 +161,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
case 0xd8:
*state = REMOTE_NO_KEY_PRESSED;
m->rep_count = 0;
goto unlock;
goto out;
case 0x93:
case 0x92:
......@@ -165,7 +169,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
case 0x82:
m->rep_count = 0;
*state = REMOTE_KEY_PRESSED;
goto unlock;
goto out;
case 0x91:
case 0x81: /* pinnacle PCTV310e */
......@@ -174,12 +178,12 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*state = REMOTE_KEY_REPEAT;
else
*state = REMOTE_NO_KEY_PRESSED;
goto unlock;
goto out;
default:
deb("Unexpected rc state %02x\n", rc_state[0]);
*state = REMOTE_NO_KEY_PRESSED;
goto unlock;
goto out;
}
}
......@@ -188,8 +192,8 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*state = REMOTE_NO_KEY_PRESSED;
unlock:
out:
kfree(rc_state);
return ret;
}
......@@ -339,13 +343,19 @@ static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, in
static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
{
u16 value, index, size;
u8 read[4], *buff;
u8 *read, *buff;
int i, pass, ret = 0;
buff = kmalloc(65536, GFP_KERNEL);
if (buff == NULL)
return -ENOMEM;
read = kmalloc(4, GFP_KERNEL);
if (!read) {
kfree(buff);
return -ENOMEM;
}
if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
goto done;
deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
......@@ -396,6 +406,7 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar
deb("firmware uploaded!\n");
done:
kfree(read);
kfree(buff);
return ret;
......@@ -632,9 +643,9 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = {
{ 0x16, KEY_POWER },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
{ 0x48, KEY_MEDIA }, /* preview */
{ 0x48, KEY_PROGRAM }, /* preview */
{ 0x1c, KEY_EPG },
{ 0x04, KEY_LIST }, /* record list */
{ 0x04, KEY_LIST }, /* record list */
{ 0x03, KEY_1 },
{ 0x01, KEY_2 },
{ 0x06, KEY_3 },
......@@ -674,14 +685,14 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = {
{ 0x0e, KEY_MUTE },
/* { 0x49, KEY_LR }, */ /* L/R */
{ 0x07, KEY_SLEEP }, /* Hibernate */
{ 0x08, KEY_MEDIA }, /* A/V */
{ 0x0e, KEY_MENU }, /* Recall */
{ 0x08, KEY_VIDEO }, /* A/V */
{ 0x0e, KEY_MENU }, /* Recall */
{ 0x45, KEY_ZOOMIN },
{ 0x46, KEY_ZOOMOUT },
{ 0x18, KEY_TV }, /* Red */
{ 0x53, KEY_VCR }, /* Green */
{ 0x5e, KEY_SAT }, /* Yellow */
{ 0x5f, KEY_PLAYER }, /* Blue */
{ 0x18, KEY_RED }, /* Red */
{ 0x53, KEY_GREEN }, /* Green */
{ 0x5e, KEY_YELLOW }, /* Yellow */
{ 0x5f, KEY_BLUE }, /* Blue */
};
/* DVB USB Driver stuff */
......
......@@ -47,7 +47,7 @@ static struct rc_map_table rc_map_haupp_table[] = {
{ 0x1e17, KEY_RIGHT },
{ 0x1e18, KEY_VIDEO },
{ 0x1e19, KEY_AUDIO },
{ 0x1e1a, KEY_MEDIA },
{ 0x1e1a, KEY_IMAGES },
{ 0x1e1b, KEY_EPG },
{ 0x1e1c, KEY_TV },
{ 0x1e1e, KEY_NEXT },
......
......@@ -53,27 +53,36 @@ static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
u8 * data, u16 len, int flags)
{
int ret;
u8 r;
u8 u8buf[len];
u8 tmp;
u8 *buf;
unsigned int pipe = (flags == OPERA_READ_MSG) ?
usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (flags == OPERA_WRITE_MSG)
memcpy(u8buf, data, len);
ret =
usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
value, 0x0, u8buf, len, 2000);
memcpy(buf, data, len);
ret = usb_control_msg(dev, pipe, request,
request_type | USB_TYPE_VENDOR, value, 0x0,
buf, len, 2000);
if (request == OPERA_TUNER_REQ) {
tmp = buf[0];
if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
return 0;
OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
ret = 0;
goto out;
}
buf[0] = tmp;
}
if (flags == OPERA_READ_MSG)
memcpy(data, u8buf, len);
memcpy(data, buf, len);
out:
kfree(buf);
return ret;
}
......@@ -189,7 +198,7 @@ static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
static u8 opera1_inittab[] = {
0x00, 0xa1,
0x01, 0x15,
0x02, 0x00,
0x02, 0x30,
0x03, 0x00,
0x04, 0x7d,
0x05, 0x05,
......
......@@ -41,14 +41,23 @@ struct vp702x_fe_state {
static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
{
u8 buf[10];
if (time_after(jiffies,st->next_status_check)) {
vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10);
struct vp702x_device_state *dst = st->d->priv;
u8 *buf;
if (time_after(jiffies, st->next_status_check)) {
mutex_lock(&dst->buf_mutex);
buf = dst->buf;
vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
st->lock = buf[4];
vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1);
vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1);
vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
st->snr = buf[0];
vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
st->sig = buf[0];
mutex_unlock(&dst->buf_mutex);
st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
}
return 0;
......@@ -130,11 +139,17 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep)
{
struct vp702x_fe_state *st = fe->demodulator_priv;
struct vp702x_device_state *dst = st->d->priv;
u32 freq = fep->frequency/1000;
/*CalFrequency*/
/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
u64 sr;
u8 cmd[8] = { 0 },ibuf[10];
u8 *cmd;
mutex_lock(&dst->buf_mutex);
cmd = dst->buf;
memset(cmd, 0, 10);
cmd[0] = (freq >> 8) & 0x7f;
cmd[1] = freq & 0xff;
......@@ -170,13 +185,15 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
st->status_check_interval = 250;
st->next_status_check = jiffies;
vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
if (ibuf[2] == 0 && ibuf[3] == 0)
if (cmd[2] == 0 && cmd[3] == 0)
deb_fe("tuning failed.\n");
else
deb_fe("tuning succeeded.\n");
mutex_unlock(&dst->buf_mutex);
return 0;
}
......@@ -204,27 +221,32 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd *m)
{
u8 *cmd;
struct vp702x_fe_state *st = fe->demodulator_priv;
u8 cmd[8],ibuf[10];
memset(cmd,0,8);
struct vp702x_device_state *dst = st->d->priv;
deb_fe("%s\n",__func__);
if (m->msg_len > 4)
return -EINVAL;
mutex_lock(&dst->buf_mutex);
cmd = dst->buf;
cmd[1] = SET_DISEQC_CMD;
cmd[2] = m->msg_len;
memcpy(&cmd[3], m->msg, m->msg_len);
cmd[7] = vp702x_chksum(cmd,0,7);
cmd[7] = vp702x_chksum(cmd, 0, 7);
vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
if (ibuf[2] == 0 && ibuf[3] == 0)
if (cmd[2] == 0 && cmd[3] == 0)
deb_fe("diseqc cmd failed.\n");
else
deb_fe("diseqc cmd succeeded.\n");
mutex_unlock(&dst->buf_mutex);
return 0;
}
......@@ -237,7 +259,9 @@ static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd
static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
struct vp702x_fe_state *st = fe->demodulator_priv;
u8 ibuf[10];
struct vp702x_device_state *dst = st->d->priv;
u8 *buf;
deb_fe("%s\n",__func__);
st->tone_mode = tone;
......@@ -247,14 +271,21 @@ static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
else
st->lnb_buf[2] = 0x00;
st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
mutex_lock(&dst->buf_mutex);
buf = dst->buf;
memcpy(buf, st->lnb_buf, 8);
vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
if (ibuf[2] == 0 && ibuf[3] == 0)
vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
if (buf[2] == 0 && buf[3] == 0)
deb_fe("set_tone cmd failed.\n");
else
deb_fe("set_tone cmd succeeded.\n");
mutex_unlock(&dst->buf_mutex);
return 0;
}
......@@ -262,7 +293,8 @@ static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
voltage)
{
struct vp702x_fe_state *st = fe->demodulator_priv;
u8 ibuf[10];
struct vp702x_device_state *dst = st->d->priv;
u8 *buf;
deb_fe("%s\n",__func__);
st->voltage = voltage;
......@@ -272,14 +304,20 @@ static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
else
st->lnb_buf[4] = 0x00;
st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
mutex_lock(&dst->buf_mutex);
buf = dst->buf;
memcpy(buf, st->lnb_buf, 8);
vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
if (ibuf[2] == 0 && ibuf[3] == 0)
vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
if (buf[2] == 0 && buf[3] == 0)
deb_fe("set_voltage cmd failed.\n");
else
deb_fe("set_voltage cmd succeeded.\n");
mutex_unlock(&dst->buf_mutex);
return 0;
}
......
This diff is collapsed.
......@@ -98,6 +98,13 @@ extern int dvb_usb_vp702x_debug;
#define RESET_TUNER 0xBE
/* IN i: 0, v: 0, no extra buffer */
struct vp702x_device_state {
struct mutex buf_mutex;
int buf_len;
u8 *buf;
};
extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
......
......@@ -28,9 +28,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
{
int ret = 0;
u8 inbuf[12] = { 0 }, outbuf[20] = { 0 };
u8 *buf = d->priv;
outbuf[0] = cmd;
buf[0] = cmd;
if (outlen > 19)
outlen = 19;
......@@ -38,19 +38,21 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
if (inlen > 11)
inlen = 11;
ret = mutex_lock_interruptible(&d->usb_mutex);
if (ret)
return ret;
if (out != NULL && outlen > 0)
memcpy(&outbuf[1], out, outlen);
memcpy(&buf[1], out, outlen);
deb_xfer("out buffer: ");
debug_dump(outbuf,outlen+1,deb_xfer);
debug_dump(buf, outlen+1, deb_xfer);
if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
return ret;
if (usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev,0),
TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
outbuf, 20, 2000) != 20) {
buf, 20, 2000) != 20) {
err("USB control message 'out' went wrong.");
ret = -EIO;
goto unlock;
......@@ -61,17 +63,17 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
if (usb_control_msg(d->udev,
usb_rcvctrlpipe(d->udev,0),
TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
inbuf, 12, 2000) != 12) {
buf, 12, 2000) != 12) {
err("USB control message 'in' went wrong.");
ret = -EIO;
goto unlock;
}
deb_xfer("in buffer: ");
debug_dump(inbuf,12,deb_xfer);
debug_dump(buf, 12, deb_xfer);
if (in != NULL && inlen > 0)
memcpy(in,&inbuf[1],inlen);
memcpy(in, &buf[1], inlen);
unlock:
mutex_unlock(&d->usb_mutex);
......@@ -222,8 +224,26 @@ static struct dvb_usb_device_properties vp7045_properties;
static int vp7045_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return dvb_usb_device_init(intf, &vp7045_properties,
THIS_MODULE, NULL, adapter_nr);
struct dvb_usb_device *d;
int ret = dvb_usb_device_init(intf, &vp7045_properties,
THIS_MODULE, &d, adapter_nr);
if (ret)
return ret;
d->priv = kmalloc(20, GFP_KERNEL);
if (!d->priv) {
dvb_usb_device_exit(intf);
return -ENOMEM;
}
return ret;
}
static void vp7045_usb_disconnect(struct usb_interface *intf)
{
struct dvb_usb_device *d = usb_get_intfdata(intf);
kfree(d->priv);
dvb_usb_device_exit(intf);
}
static struct usb_device_id vp7045_usb_table [] = {
......@@ -238,6 +258,7 @@ MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
static struct dvb_usb_device_properties vp7045_properties = {
.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-vp7045-01.fw",
.size_of_priv = sizeof(u8 *),
.num_adapters = 1,
.adapter = {
......@@ -284,7 +305,7 @@ static struct dvb_usb_device_properties vp7045_properties = {
static struct usb_driver vp7045_usb_driver = {
.name = "dvb_usb_vp7045",
.probe = vp7045_usb_probe,
.disconnect = dvb_usb_device_exit,
.disconnect = vp7045_usb_disconnect,
.id_table = vp7045_usb_table,
};
......
......@@ -263,18 +263,16 @@ config DVB_S5H1432
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DRX397XD
tristate "Micronas DRX3975D/DRX3977D based"
config DVB_DRXD
tristate "Micronas DRXD driver"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
TODO:
This driver needs external firmware. Please use the command
"<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to
download/extract them, and then copy them to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
Note: this driver was based on vendor driver reference code (released
under the GPL) as opposed to the existing drx397xd driver, which
was written via reverse engineering.
config DVB_L64781
tristate "LSI L64781"
......@@ -385,6 +383,13 @@ config DVB_STV0367
help
A DVB-T/C tuner module. Say Y when you want to support this frontend.
config DVB_CXD2820R
tristate "Sony CXD2820R"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
Say Y when you want to support this frontend.
comment "DVB-C (cable) frontends"
depends on DVB_CORE
......
......@@ -8,6 +8,8 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
stb0899-objs = stb0899_drv.o stb0899_algo.o
stv0900-objs = stv0900_core.o stv0900_sw.o
au8522-objs = au8522_dig.o au8522_decoder.o
drxd-objs = drxd_firm.o drxd_hard.o
cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
......@@ -36,7 +38,7 @@ obj-$(CONFIG_DVB_ZL10036) += zl10036.o
obj-$(CONFIG_DVB_ZL10039) += zl10039.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
obj-$(CONFIG_DVB_DRXD) += drxd.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
......@@ -85,3 +87,5 @@ obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
obj-$(CONFIG_DVB_STV0367) += stv0367.o
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
This diff is collapsed.
......@@ -27,7 +27,7 @@
static u8 alps_bsru6_inittab[] = {
0x01, 0x15,
0x02, 0x00,
0x02, 0x30,
0x03, 0x00,
0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
......
......@@ -137,7 +137,7 @@ MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
/* SNR measurements */
static int esno_snr;
module_param(esno_snr, int, 0644);
MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\
MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
"1=ESNO(db * 10) (default:0)");
enum cmds {
......@@ -566,7 +566,7 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
{
struct cx24116_state *state = fe->demodulator_priv;
struct cx24116_cmd cmd;
int i, ret;
int i, ret, len, max, remaining;
unsigned char vers[4];
dprintk("%s\n", __func__);
......@@ -603,8 +603,21 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
cx24116_writereg(state, 0xF5, 0x00);
cx24116_writereg(state, 0xF6, 0x00);
/* write the entire firmware as one transaction */
cx24116_writeregN(state, 0xF7, fw->data, fw->size);
/* Split firmware to the max I2C write len and write.
* Writes whole firmware as one write when i2c_wr_max is set to 0. */
if (state->config->i2c_wr_max)
max = state->config->i2c_wr_max;
else
max = INT_MAX; /* enough for 32k firmware */
for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
len = remaining;
if (len > max - 1)
len = max - 1;
cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
len);
}
cx24116_writereg(state, 0xF4, 0x10);
cx24116_writereg(state, 0xF0, 0x00);
......
......@@ -35,6 +35,9 @@ struct cx24116_config {
/* Need to set MPEG parameters */
u8 mpg_clk_pos_pol:0x02;
/* max bytes I2C provider can write at once */
u16 i2c_wr_max;
};
#if defined(CONFIG_DVB_CX24116) || \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -73,27 +73,47 @@ struct dib0070_state {
u8 wbd_gain_current;
u16 wbd_offset_3_3[2];
/* for the I2C transfer */
struct i2c_msg msg[2];
u8 i2c_write_buffer[3];
u8 i2c_read_buffer[2];
};
static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
{
u8 b[2];
struct i2c_msg msg[2] = {
{ .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 },
};
if (i2c_transfer(state->i2c, msg, 2) != 2) {
state->i2c_write_buffer[0] = reg;
memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
state->msg[0].addr = state->cfg->i2c_address;
state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 1;
state->msg[1].addr = state->cfg->i2c_address;
state->msg[1].flags = I2C_M_RD;
state->msg[1].buf = state->i2c_read_buffer;
state->msg[1].len = 2;
if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
printk(KERN_WARNING "DiB0070 I2C read failed\n");
return 0;
}
return (b[0] << 8) | b[1];
return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
}
static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
{
u8 b[3] = { reg, val >> 8, val & 0xff };
struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
if (i2c_transfer(state->i2c, &msg, 1) != 1) {
state->i2c_write_buffer[0] = reg;
state->i2c_write_buffer[1] = val >> 8;
state->i2c_write_buffer[2] = val & 0xff;
memset(state->msg, 0, sizeof(struct i2c_msg));
state->msg[0].addr = state->cfg->i2c_address;
state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 3;
if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
printk(KERN_WARNING "DiB0070 I2C write failed\n");
return -EREMOTEIO;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -28,6 +28,11 @@ struct dibx000_i2c_master {
u8 i2c_addr;
u16 base_reg;
/* for the I2C transfer */
struct i2c_msg msg[34];
u8 i2c_write_buffer[8];
u8 i2c_read_buffer[2];
};
extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment