diff options
292 files changed, 11545 insertions, 5591 deletions
diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml index 3bc8a61efe30..ffee1fbbc001 100644 --- a/Documentation/DocBook/media/dvb/dvbproperty.xml +++ b/Documentation/DocBook/media/dvb/dvbproperty.xml | |||
@@ -334,9 +334,10 @@ typedef enum fe_rolloff { | |||
334 | <title>fe_delivery_system type</title> | 334 | <title>fe_delivery_system type</title> |
335 | <para>Possible values: </para> | 335 | <para>Possible values: </para> |
336 | <programlisting> | 336 | <programlisting> |
337 | |||
337 | typedef enum fe_delivery_system { | 338 | typedef enum fe_delivery_system { |
338 | SYS_UNDEFINED, | 339 | SYS_UNDEFINED, |
339 | SYS_DVBC_ANNEX_AC, | 340 | SYS_DVBC_ANNEX_A, |
340 | SYS_DVBC_ANNEX_B, | 341 | SYS_DVBC_ANNEX_B, |
341 | SYS_DVBT, | 342 | SYS_DVBT, |
342 | SYS_DSS, | 343 | SYS_DSS, |
@@ -353,6 +354,7 @@ typedef enum fe_delivery_system { | |||
353 | SYS_DAB, | 354 | SYS_DAB, |
354 | SYS_DVBT2, | 355 | SYS_DVBT2, |
355 | SYS_TURBO, | 356 | SYS_TURBO, |
357 | SYS_DVBC_ANNEX_C, | ||
356 | } fe_delivery_system_t; | 358 | } fe_delivery_system_t; |
357 | </programlisting> | 359 | </programlisting> |
358 | </section> | 360 | </section> |
@@ -647,6 +649,18 @@ typedef enum fe_hierarchy { | |||
647 | many data types via a single multiplex. The API will soon support this | 649 | many data types via a single multiplex. The API will soon support this |
648 | at which point this section will be expanded.</para> | 650 | at which point this section will be expanded.</para> |
649 | </section> | 651 | </section> |
652 | <section id="DTV_ENUM_DELSYS"> | ||
653 | <title><constant>DTV_ENUM_DELSYS</constant></title> | ||
654 | <para>A Multi standard frontend needs to advertise the delivery systems provided. | ||
655 | Applications need to enumerate the provided delivery systems, before using | ||
656 | any other operation with the frontend. Prior to it's introduction, | ||
657 | FE_GET_INFO was used to determine a frontend type. A frontend which | ||
658 | provides more than a single delivery system, FE_GET_INFO doesn't help much. | ||
659 | Applications which intends to use a multistandard frontend must enumerate | ||
660 | the delivery systems associated with it, rather than trying to use | ||
661 | FE_GET_INFO. In the case of a legacy frontend, the result is just the same | ||
662 | as with FE_GET_INFO, but in a more structured format </para> | ||
663 | </section> | ||
650 | </section> | 664 | </section> |
651 | <section id="frontend-property-terrestrial-systems"> | 665 | <section id="frontend-property-terrestrial-systems"> |
652 | <title>Properties used on terrestrial delivery systems</title> | 666 | <title>Properties used on terrestrial delivery systems</title> |
@@ -767,7 +781,8 @@ typedef enum fe_hierarchy { | |||
767 | <title>Properties used on cable delivery systems</title> | 781 | <title>Properties used on cable delivery systems</title> |
768 | <section id="dvbc-params"> | 782 | <section id="dvbc-params"> |
769 | <title>DVB-C delivery system</title> | 783 | <title>DVB-C delivery system</title> |
770 | <para>The DVB-C Annex-A/C is the widely used cable standard. Transmission uses QAM modulation.</para> | 784 | <para>The DVB-C Annex-A is the widely used cable standard. Transmission uses QAM modulation.</para> |
785 | <para>The DVB-C Annex-C is optimized for 6MHz, and is used in Japan. It supports a subset of the Annex A modulation types, and a roll-off of 0.13, instead of 0.15</para> | ||
771 | <para>The following parameters are valid for DVB-C Annex A/C:</para> | 786 | <para>The following parameters are valid for DVB-C Annex A/C:</para> |
772 | <itemizedlist mark='opencircle'> | 787 | <itemizedlist mark='opencircle'> |
773 | <listitem><para><link linkend="DTV-API-VERSION"><constant>DTV_API_VERSION</constant></link></para></listitem> | 788 | <listitem><para><link linkend="DTV-API-VERSION"><constant>DTV_API_VERSION</constant></link></para></listitem> |
diff --git a/Documentation/DocBook/media/dvb/frontend.xml b/Documentation/DocBook/media/dvb/frontend.xml index 61407eaba020..28d7ea5d5e73 100644 --- a/Documentation/DocBook/media/dvb/frontend.xml +++ b/Documentation/DocBook/media/dvb/frontend.xml | |||
@@ -45,8 +45,8 @@ transmission. The fontend types are given by fe_type_t type, defined as:</para> | |||
45 | </row> | 45 | </row> |
46 | <row> | 46 | <row> |
47 | <entry id="FE_QAM"><constant>FE_QAM</constant></entry> | 47 | <entry id="FE_QAM"><constant>FE_QAM</constant></entry> |
48 | <entry>For DVB-C annex A/C standard</entry> | 48 | <entry>For DVB-C annex A standard</entry> |
49 | <entry><constant>SYS_DVBC_ANNEX_AC</constant></entry> | 49 | <entry><constant>SYS_DVBC_ANNEX_A</constant></entry> |
50 | </row> | 50 | </row> |
51 | <row> | 51 | <row> |
52 | <entry id="FE_OFDM"><constant>FE_OFDM</constant></entry> | 52 | <entry id="FE_OFDM"><constant>FE_OFDM</constant></entry> |
diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml index afc8a0dd2601..cea6fd3ed428 100644 --- a/Documentation/DocBook/media/v4l/biblio.xml +++ b/Documentation/DocBook/media/v4l/biblio.xml | |||
@@ -178,11 +178,3 @@ in the frequency range from 87,5 to 108,0 MHz</title> | |||
178 | </biblioentry> | 178 | </biblioentry> |
179 | 179 | ||
180 | </bibliography> | 180 | </bibliography> |
181 | |||
182 | <!-- | ||
183 | Local Variables: | ||
184 | mode: sgml | ||
185 | sgml-parent-document: "v4l2.sgml" | ||
186 | indent-tabs-mode: nil | ||
187 | End: | ||
188 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/common.xml b/Documentation/DocBook/media/v4l/common.xml index a86f7a045529..9d3919831eba 100644 --- a/Documentation/DocBook/media/v4l/common.xml +++ b/Documentation/DocBook/media/v4l/common.xml | |||
@@ -1195,11 +1195,3 @@ separate parameters for input and output devices.</para> | |||
1195 | <para>These ioctls are optional, drivers need not implement | 1195 | <para>These ioctls are optional, drivers need not implement |
1196 | them. If so, they return the &EINVAL;.</para> | 1196 | them. If so, they return the &EINVAL;.</para> |
1197 | </section> | 1197 | </section> |
1198 | |||
1199 | <!-- | ||
1200 | Local Variables: | ||
1201 | mode: sgml | ||
1202 | sgml-parent-document: "v4l2.sgml" | ||
1203 | indent-tabs-mode: nil | ||
1204 | End: | ||
1205 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index b68698f96e7f..8b44a43f4542 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml | |||
@@ -1082,7 +1082,7 @@ until the time in the timestamp field has arrived. I would like to | |||
1082 | follow SGI's lead, and adopt a multimedia timestamping system like | 1082 | follow SGI's lead, and adopt a multimedia timestamping system like |
1083 | their UST (Unadjusted System Time). See | 1083 | their UST (Unadjusted System Time). See |
1084 | http://web.archive.org/web/*/http://reality.sgi.com | 1084 | http://web.archive.org/web/*/http://reality.sgi.com |
1085 | /cpirazzi_engr/lg/time/intro.html. | 1085 | /cpirazzi_engr/lg/time/intro.html. |
1086 | UST uses timestamps that are 64-bit signed integers | 1086 | UST uses timestamps that are 64-bit signed integers |
1087 | (not struct timeval's) and given in nanosecond units. The UST clock | 1087 | (not struct timeval's) and given in nanosecond units. The UST clock |
1088 | starts at zero when the system is booted and runs continuously and | 1088 | starts at zero when the system is booted and runs continuously and |
@@ -2507,11 +2507,3 @@ interfaces and should not be implemented in new drivers.</para> | |||
2507 | </itemizedlist> | 2507 | </itemizedlist> |
2508 | </section> | 2508 | </section> |
2509 | </section> | 2509 | </section> |
2510 | |||
2511 | <!-- | ||
2512 | Local Variables: | ||
2513 | mode: sgml | ||
2514 | sgml-parent-document: "v4l2.sgml" | ||
2515 | indent-tabs-mode: nil | ||
2516 | End: | ||
2517 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8b2c74..c0422c622337 100644 --- a/Documentation/DocBook/media/v4l/controls.xml +++ b/Documentation/DocBook/media/v4l/controls.xml | |||
@@ -3329,6 +3329,16 @@ interface and may change in the future.</para> | |||
3329 | <entry>The short circuit protection of the flash | 3329 | <entry>The short circuit protection of the flash |
3330 | controller has been triggered.</entry> | 3330 | controller has been triggered.</entry> |
3331 | </row> | 3331 | </row> |
3332 | <row> | ||
3333 | <entry><constant>V4L2_FLASH_FAULT_OVER_CURRENT</constant></entry> | ||
3334 | <entry>Current in the LED power supply has exceeded the limit | ||
3335 | specific to the flash controller.</entry> | ||
3336 | </row> | ||
3337 | <row> | ||
3338 | <entry><constant>V4L2_FLASH_FAULT_INDICATOR</constant></entry> | ||
3339 | <entry>The flash controller has detected a short or open | ||
3340 | circuit condition on the indicator LED.</entry> | ||
3341 | </row> | ||
3332 | </tbody> | 3342 | </tbody> |
3333 | </entrytbl> | 3343 | </entrytbl> |
3334 | </row> | 3344 | </row> |
@@ -3357,11 +3367,3 @@ interface and may change in the future.</para> | |||
3357 | 3367 | ||
3358 | </section> | 3368 | </section> |
3359 | </section> | 3369 | </section> |
3360 | |||
3361 | <!-- | ||
3362 | Local Variables: | ||
3363 | mode: sgml | ||
3364 | sgml-parent-document: "common.sgml" | ||
3365 | indent-tabs-mode: nil | ||
3366 | End: | ||
3367 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-capture.xml b/Documentation/DocBook/media/v4l/dev-capture.xml index 2237c661f26a..e1c5f9406d6a 100644 --- a/Documentation/DocBook/media/v4l/dev-capture.xml +++ b/Documentation/DocBook/media/v4l/dev-capture.xml | |||
@@ -108,11 +108,3 @@ linkend="mmap">memory mapping</link> or <link | |||
108 | linkend="userp">user pointer</link>) I/O. See <xref | 108 | linkend="userp">user pointer</link>) I/O. See <xref |
109 | linkend="io" /> for details.</para> | 109 | linkend="io" /> for details.</para> |
110 | </section> | 110 | </section> |
111 | |||
112 | <!-- | ||
113 | Local Variables: | ||
114 | mode: sgml | ||
115 | sgml-parent-document: "v4l2.sgml" | ||
116 | indent-tabs-mode: nil | ||
117 | End: | ||
118 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-codec.xml b/Documentation/DocBook/media/v4l/dev-codec.xml index 6e156dc45b94..dca0ecd54dc6 100644 --- a/Documentation/DocBook/media/v4l/dev-codec.xml +++ b/Documentation/DocBook/media/v4l/dev-codec.xml | |||
@@ -16,11 +16,3 @@ Applications send data to be converted to the driver through a | |||
16 | I/O.</para> | 16 | I/O.</para> |
17 | 17 | ||
18 | <para>[to do]</para> | 18 | <para>[to do]</para> |
19 | |||
20 | <!-- | ||
21 | Local Variables: | ||
22 | mode: sgml | ||
23 | sgml-parent-document: "v4l2.sgml" | ||
24 | indent-tabs-mode: nil | ||
25 | End: | ||
26 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-effect.xml b/Documentation/DocBook/media/v4l/dev-effect.xml index 9c243beba0e6..2350a67c0710 100644 --- a/Documentation/DocBook/media/v4l/dev-effect.xml +++ b/Documentation/DocBook/media/v4l/dev-effect.xml | |||
@@ -15,11 +15,3 @@ receive the result data either with &func-read; and &func-write; | |||
15 | functions, or through the streaming I/O mechanism.</para> | 15 | functions, or through the streaming I/O mechanism.</para> |
16 | 16 | ||
17 | <para>[to do]</para> | 17 | <para>[to do]</para> |
18 | |||
19 | <!-- | ||
20 | Local Variables: | ||
21 | mode: sgml | ||
22 | sgml-parent-document: "v4l2.sgml" | ||
23 | indent-tabs-mode: nil | ||
24 | End: | ||
25 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-event.xml b/Documentation/DocBook/media/v4l/dev-event.xml index f14ae3fe107c..19f4becfae34 100644 --- a/Documentation/DocBook/media/v4l/dev-event.xml +++ b/Documentation/DocBook/media/v4l/dev-event.xml | |||
@@ -41,11 +41,3 @@ intermediate step leading up to that information. See the documentation for the | |||
41 | event you want to subscribe to whether this is applicable for that event or not.</para> | 41 | event you want to subscribe to whether this is applicable for that event or not.</para> |
42 | </listitem> | 42 | </listitem> |
43 | </orderedlist></para> | 43 | </orderedlist></para> |
44 | |||
45 | <!-- | ||
46 | Local Variables: | ||
47 | mode: sgml | ||
48 | sgml-parent-document: "v4l2.sgml" | ||
49 | indent-tabs-mode: nil | ||
50 | End: | ||
51 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-osd.xml b/Documentation/DocBook/media/v4l/dev-osd.xml index c9a68a2ccd33..479d9433869a 100644 --- a/Documentation/DocBook/media/v4l/dev-osd.xml +++ b/Documentation/DocBook/media/v4l/dev-osd.xml | |||
@@ -154,11 +154,3 @@ data flow. For more information see <xref linkend="crop" />.</para> | |||
154 | however the framebuffer interface of the driver may support the | 154 | however the framebuffer interface of the driver may support the |
155 | <constant>FBIOBLANK</constant> ioctl.</para> | 155 | <constant>FBIOBLANK</constant> ioctl.</para> |
156 | </section> | 156 | </section> |
157 | |||
158 | <!-- | ||
159 | Local Variables: | ||
160 | mode: sgml | ||
161 | sgml-parent-document: "v4l2.sgml" | ||
162 | indent-tabs-mode: nil | ||
163 | End: | ||
164 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-output.xml b/Documentation/DocBook/media/v4l/dev-output.xml index 919e22c53854..9130a3dc7880 100644 --- a/Documentation/DocBook/media/v4l/dev-output.xml +++ b/Documentation/DocBook/media/v4l/dev-output.xml | |||
@@ -104,11 +104,3 @@ linkend="mmap">memory mapping</link> or <link | |||
104 | linkend="userp">user pointer</link>) I/O. See <xref | 104 | linkend="userp">user pointer</link>) I/O. See <xref |
105 | linkend="io" /> for details.</para> | 105 | linkend="io" /> for details.</para> |
106 | </section> | 106 | </section> |
107 | |||
108 | <!-- | ||
109 | Local Variables: | ||
110 | mode: sgml | ||
111 | sgml-parent-document: "v4l2.sgml" | ||
112 | indent-tabs-mode: nil | ||
113 | End: | ||
114 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-overlay.xml b/Documentation/DocBook/media/v4l/dev-overlay.xml index 92513cf79150..40d1d7681439 100644 --- a/Documentation/DocBook/media/v4l/dev-overlay.xml +++ b/Documentation/DocBook/media/v4l/dev-overlay.xml | |||
@@ -369,11 +369,3 @@ reasons. <!-- video4linux-list@redhat.com on 22 Oct 2002 subject | |||
369 | <para>To start or stop the frame buffer overlay applications call | 369 | <para>To start or stop the frame buffer overlay applications call |
370 | the &VIDIOC-OVERLAY; ioctl.</para> | 370 | the &VIDIOC-OVERLAY; ioctl.</para> |
371 | </section> | 371 | </section> |
372 | |||
373 | <!-- | ||
374 | Local Variables: | ||
375 | mode: sgml | ||
376 | sgml-parent-document: "v4l2.sgml" | ||
377 | indent-tabs-mode: nil | ||
378 | End: | ||
379 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-radio.xml b/Documentation/DocBook/media/v4l/dev-radio.xml index 73aa90b45b34..3e6ac73b36af 100644 --- a/Documentation/DocBook/media/v4l/dev-radio.xml +++ b/Documentation/DocBook/media/v4l/dev-radio.xml | |||
@@ -47,11 +47,3 @@ depending on the selected frequency. The &VIDIOC-G-TUNER; or | |||
47 | &VIDIOC-G-MODULATOR; ioctl | 47 | &VIDIOC-G-MODULATOR; ioctl |
48 | reports the supported frequency range.</para> | 48 | reports the supported frequency range.</para> |
49 | </section> | 49 | </section> |
50 | |||
51 | <!-- | ||
52 | Local Variables: | ||
53 | mode: sgml | ||
54 | sgml-parent-document: "v4l2.sgml" | ||
55 | indent-tabs-mode: nil | ||
56 | End: | ||
57 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-raw-vbi.xml b/Documentation/DocBook/media/v4l/dev-raw-vbi.xml index c5a70bdfaf27..b788c72c885e 100644 --- a/Documentation/DocBook/media/v4l/dev-raw-vbi.xml +++ b/Documentation/DocBook/media/v4l/dev-raw-vbi.xml | |||
@@ -337,11 +337,3 @@ an &EBUSY; if the required hardware resources are temporarily | |||
337 | unavailable, for example the device is already in use by another | 337 | unavailable, for example the device is already in use by another |
338 | process.</para> | 338 | process.</para> |
339 | </section> | 339 | </section> |
340 | |||
341 | <!-- | ||
342 | Local Variables: | ||
343 | mode: sgml | ||
344 | sgml-parent-document: "v4l2.sgml" | ||
345 | indent-tabs-mode: nil | ||
346 | End: | ||
347 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-rds.xml b/Documentation/DocBook/media/v4l/dev-rds.xml index 2427f54397e7..38883a419e65 100644 --- a/Documentation/DocBook/media/v4l/dev-rds.xml +++ b/Documentation/DocBook/media/v4l/dev-rds.xml | |||
@@ -29,10 +29,10 @@ returned by the &VIDIOC-QUERYCAP; ioctl. Any tuner that supports RDS | |||
29 | will set the <constant>V4L2_TUNER_CAP_RDS</constant> flag in | 29 | will set the <constant>V4L2_TUNER_CAP_RDS</constant> flag in |
30 | the <structfield>capability</structfield> field of &v4l2-tuner;. If | 30 | the <structfield>capability</structfield> field of &v4l2-tuner;. If |
31 | the driver only passes RDS blocks without interpreting the data | 31 | the driver only passes RDS blocks without interpreting the data |
32 | the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be | 32 | the <constant>V4L2_TUNER_CAP_RDS_BLOCK_IO</constant> flag has to be |
33 | set, see <link linkend="reading-rds-data">Reading RDS data</link>. | 33 | set, see <link linkend="reading-rds-data">Reading RDS data</link>. |
34 | For future use the | 34 | For future use the |
35 | flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> has also been | 35 | flag <constant>V4L2_TUNER_CAP_RDS_CONTROLS</constant> has also been |
36 | defined. However, a driver for a radio tuner with this capability does | 36 | defined. However, a driver for a radio tuner with this capability does |
37 | not yet exist, so if you are planning to write such a driver you | 37 | not yet exist, so if you are planning to write such a driver you |
38 | should discuss this on the linux-media mailing list: &v4l-ml;.</para> | 38 | should discuss this on the linux-media mailing list: &v4l-ml;.</para> |
@@ -52,9 +52,9 @@ field of &v4l2-modulator;. | |||
52 | In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant> | 52 | In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant> |
53 | bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;. | 53 | bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;. |
54 | If the driver only passes RDS blocks without interpreting the data | 54 | If the driver only passes RDS blocks without interpreting the data |
55 | the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be set. If the | 55 | the <constant>V4L2_TUNER_CAP_RDS_BLOCK_IO</constant> flag has to be set. If the |
56 | tuner is capable of handling RDS entities like program identification codes and radio | 56 | tuner is capable of handling RDS entities like program identification codes and radio |
57 | text, the flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> should be set, | 57 | text, the flag <constant>V4L2_TUNER_CAP_RDS_CONTROLS</constant> should be set, |
58 | see <link linkend="writing-rds-data">Writing RDS data</link> and | 58 | see <link linkend="writing-rds-data">Writing RDS data</link> and |
59 | <link linkend="fm-tx-controls">FM Transmitter Control Reference</link>.</para> | 59 | <link linkend="fm-tx-controls">FM Transmitter Control Reference</link>.</para> |
60 | </section> | 60 | </section> |
@@ -194,11 +194,3 @@ as follows:</para> | |||
194 | </tgroup> | 194 | </tgroup> |
195 | </table> | 195 | </table> |
196 | </section> | 196 | </section> |
197 | |||
198 | <!-- | ||
199 | Local Variables: | ||
200 | mode: sgml | ||
201 | sgml-parent-document: "v4l2.sgml" | ||
202 | indent-tabs-mode: nil | ||
203 | End: | ||
204 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml b/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml index 69e789fa7f7b..548f8ea28dee 100644 --- a/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml +++ b/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml | |||
@@ -697,12 +697,3 @@ Sliced VBI services</link> for a description of the line payload.</entry> | |||
697 | 697 | ||
698 | </section> | 698 | </section> |
699 | </section> | 699 | </section> |
700 | |||
701 | |||
702 | <!-- | ||
703 | Local Variables: | ||
704 | mode: sgml | ||
705 | sgml-parent-document: "v4l2.sgml" | ||
706 | indent-tabs-mode: nil | ||
707 | End: | ||
708 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/dev-teletext.xml b/Documentation/DocBook/media/v4l/dev-teletext.xml index 414b1cfff9f4..bd21c64d70f3 100644 --- a/Documentation/DocBook/media/v4l/dev-teletext.xml +++ b/Documentation/DocBook/media/v4l/dev-teletext.xml | |||
@@ -27,11 +27,3 @@ kernel 2.6.37.</para> | |||
27 | 27 | ||
28 | <para>Modern devices all use the <link linkend="raw-vbi">raw</link> or | 28 | <para>Modern devices all use the <link linkend="raw-vbi">raw</link> or |
29 | <link linkend="sliced">sliced</link> VBI API.</para> | 29 | <link linkend="sliced">sliced</link> VBI API.</para> |
30 | |||
31 | <!-- | ||
32 | Local Variables: | ||
33 | mode: sgml | ||
34 | sgml-parent-document: "v4l2.sgml" | ||
35 | indent-tabs-mode: nil | ||
36 | End: | ||
37 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/driver.xml b/Documentation/DocBook/media/v4l/driver.xml index 1f7eea5c4ec3..eacafe312cd2 100644 --- a/Documentation/DocBook/media/v4l/driver.xml +++ b/Documentation/DocBook/media/v4l/driver.xml | |||
@@ -198,11 +198,3 @@ devices with the videodev module.</para> | |||
198 | <para>to do</para> | 198 | <para>to do</para> |
199 | </section> | 199 | </section> |
200 | --> | 200 | --> |
201 | |||
202 | <!-- | ||
203 | Local Variables: | ||
204 | mode: sgml | ||
205 | sgml-parent-document: "v4l2.sgml" | ||
206 | indent-tabs-mode: nil | ||
207 | End: | ||
208 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-close.xml b/Documentation/DocBook/media/v4l/func-close.xml index dfb41cbbbec3..232920d2f3c6 100644 --- a/Documentation/DocBook/media/v4l/func-close.xml +++ b/Documentation/DocBook/media/v4l/func-close.xml | |||
@@ -60,11 +60,3 @@ descriptor.</para> | |||
60 | </variablelist> | 60 | </variablelist> |
61 | </refsect1> | 61 | </refsect1> |
62 | </refentry> | 62 | </refentry> |
63 | |||
64 | <!-- | ||
65 | Local Variables: | ||
66 | mode: sgml | ||
67 | sgml-parent-document: "v4l2.sgml" | ||
68 | indent-tabs-mode: nil | ||
69 | End: | ||
70 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-ioctl.xml b/Documentation/DocBook/media/v4l/func-ioctl.xml index 2de64be706f5..4394184a1a6d 100644 --- a/Documentation/DocBook/media/v4l/func-ioctl.xml +++ b/Documentation/DocBook/media/v4l/func-ioctl.xml | |||
@@ -69,11 +69,3 @@ their respective function and parameters are specified in <xref | |||
69 | the parameter remains unmodified.</para> | 69 | the parameter remains unmodified.</para> |
70 | </refsect1> | 70 | </refsect1> |
71 | </refentry> | 71 | </refentry> |
72 | |||
73 | <!-- | ||
74 | Local Variables: | ||
75 | mode: sgml | ||
76 | sgml-parent-document: "v4l2.sgml" | ||
77 | indent-tabs-mode: nil | ||
78 | End: | ||
79 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-mmap.xml b/Documentation/DocBook/media/v4l/func-mmap.xml index 786732b64bbd..f31ad71bf301 100644 --- a/Documentation/DocBook/media/v4l/func-mmap.xml +++ b/Documentation/DocBook/media/v4l/func-mmap.xml | |||
@@ -181,11 +181,3 @@ complete the request.</para> | |||
181 | </variablelist> | 181 | </variablelist> |
182 | </refsect1> | 182 | </refsect1> |
183 | </refentry> | 183 | </refentry> |
184 | |||
185 | <!-- | ||
186 | Local Variables: | ||
187 | mode: sgml | ||
188 | sgml-parent-document: "v4l2.sgml" | ||
189 | indent-tabs-mode: nil | ||
190 | End: | ||
191 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-munmap.xml b/Documentation/DocBook/media/v4l/func-munmap.xml index e2c4190f9bb6..860d49ca54a5 100644 --- a/Documentation/DocBook/media/v4l/func-munmap.xml +++ b/Documentation/DocBook/media/v4l/func-munmap.xml | |||
@@ -74,11 +74,3 @@ mapped yet.</para> | |||
74 | </variablelist> | 74 | </variablelist> |
75 | </refsect1> | 75 | </refsect1> |
76 | </refentry> | 76 | </refentry> |
77 | |||
78 | <!-- | ||
79 | Local Variables: | ||
80 | mode: sgml | ||
81 | sgml-parent-document: "v4l2.sgml" | ||
82 | indent-tabs-mode: nil | ||
83 | End: | ||
84 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-open.xml b/Documentation/DocBook/media/v4l/func-open.xml index 7595d07a8c72..cf64e207c3ee 100644 --- a/Documentation/DocBook/media/v4l/func-open.xml +++ b/Documentation/DocBook/media/v4l/func-open.xml | |||
@@ -111,11 +111,3 @@ system has been reached.</para> | |||
111 | </variablelist> | 111 | </variablelist> |
112 | </refsect1> | 112 | </refsect1> |
113 | </refentry> | 113 | </refentry> |
114 | |||
115 | <!-- | ||
116 | Local Variables: | ||
117 | mode: sgml | ||
118 | sgml-parent-document: "v4l2.sgml" | ||
119 | indent-tabs-mode: nil | ||
120 | End: | ||
121 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-poll.xml b/Documentation/DocBook/media/v4l/func-poll.xml index ec3c718f5963..85cad8bff5ba 100644 --- a/Documentation/DocBook/media/v4l/func-poll.xml +++ b/Documentation/DocBook/media/v4l/func-poll.xml | |||
@@ -117,11 +117,3 @@ than <constant>OPEN_MAX</constant>.</para> | |||
117 | </variablelist> | 117 | </variablelist> |
118 | </refsect1> | 118 | </refsect1> |
119 | </refentry> | 119 | </refentry> |
120 | |||
121 | <!-- | ||
122 | Local Variables: | ||
123 | mode: sgml | ||
124 | sgml-parent-document: "v4l2.sgml" | ||
125 | indent-tabs-mode: nil | ||
126 | End: | ||
127 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-read.xml b/Documentation/DocBook/media/v4l/func-read.xml index a5089bf8873d..e218bbfbd362 100644 --- a/Documentation/DocBook/media/v4l/func-read.xml +++ b/Documentation/DocBook/media/v4l/func-read.xml | |||
@@ -179,11 +179,3 @@ type of device.</para> | |||
179 | </variablelist> | 179 | </variablelist> |
180 | </refsect1> | 180 | </refsect1> |
181 | </refentry> | 181 | </refentry> |
182 | |||
183 | <!-- | ||
184 | Local Variables: | ||
185 | mode: sgml | ||
186 | sgml-parent-document: "v4l2.sgml" | ||
187 | indent-tabs-mode: nil | ||
188 | End: | ||
189 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-select.xml b/Documentation/DocBook/media/v4l/func-select.xml index b6713623181f..e12a60d9bd85 100644 --- a/Documentation/DocBook/media/v4l/func-select.xml +++ b/Documentation/DocBook/media/v4l/func-select.xml | |||
@@ -128,11 +128,3 @@ zero or greater than <constant>FD_SETSIZE</constant>.</para> | |||
128 | </variablelist> | 128 | </variablelist> |
129 | </refsect1> | 129 | </refsect1> |
130 | </refentry> | 130 | </refentry> |
131 | |||
132 | <!-- | ||
133 | Local Variables: | ||
134 | mode: sgml | ||
135 | sgml-parent-document: "v4l2.sgml" | ||
136 | indent-tabs-mode: nil | ||
137 | End: | ||
138 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/func-write.xml b/Documentation/DocBook/media/v4l/func-write.xml index 2c09c09371c3..575207885726 100644 --- a/Documentation/DocBook/media/v4l/func-write.xml +++ b/Documentation/DocBook/media/v4l/func-write.xml | |||
@@ -126,11 +126,3 @@ type of device.</para> | |||
126 | </variablelist> | 126 | </variablelist> |
127 | </refsect1> | 127 | </refsect1> |
128 | </refentry> | 128 | </refentry> |
129 | |||
130 | <!-- | ||
131 | Local Variables: | ||
132 | mode: sgml | ||
133 | sgml-parent-document: "v4l2.sgml" | ||
134 | indent-tabs-mode: nil | ||
135 | End: | ||
136 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index 3f47df1aa54a..b815929b5bba 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml | |||
@@ -1282,11 +1282,3 @@ line, top field first. The bottom field is transmitted first.</entry> | |||
1282 | </mediaobject> | 1282 | </mediaobject> |
1283 | </figure> | 1283 | </figure> |
1284 | </section> | 1284 | </section> |
1285 | |||
1286 | <!-- | ||
1287 | Local Variables: | ||
1288 | mode: sgml | ||
1289 | sgml-parent-document: "v4l2.sgml" | ||
1290 | indent-tabs-mode: nil | ||
1291 | End: | ||
1292 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/libv4l.xml b/Documentation/DocBook/media/v4l/libv4l.xml index 3cb10ec51929..d3b71e20003c 100644 --- a/Documentation/DocBook/media/v4l/libv4l.xml +++ b/Documentation/DocBook/media/v4l/libv4l.xml | |||
@@ -158,10 +158,3 @@ still don't use libv4l.</para> | |||
158 | </section> | 158 | </section> |
159 | 159 | ||
160 | </section> | 160 | </section> |
161 | <!-- | ||
162 | Local Variables: | ||
163 | mode: sgml | ||
164 | sgml-parent-document: "v4l2.sgml" | ||
165 | indent-tabs-mode: nil | ||
166 | End: | ||
167 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-grey.xml b/Documentation/DocBook/media/v4l/pixfmt-grey.xml index 3b72bc6b2de7..bee970d3f76d 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-grey.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-grey.xml | |||
@@ -60,11 +60,3 @@ pixel image</title> | |||
60 | </example> | 60 | </example> |
61 | </refsect1> | 61 | </refsect1> |
62 | </refentry> | 62 | </refentry> |
63 | |||
64 | <!-- | ||
65 | Local Variables: | ||
66 | mode: sgml | ||
67 | sgml-parent-document: "pixfmt.sgml" | ||
68 | indent-tabs-mode: nil | ||
69 | End: | ||
70 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-m420.xml b/Documentation/DocBook/media/v4l/pixfmt-m420.xml index ce4bc019e5c0..aadae92c5d04 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-m420.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-m420.xml | |||
@@ -137,11 +137,3 @@ pixel image</title> | |||
137 | </example> | 137 | </example> |
138 | </refsect1> | 138 | </refsect1> |
139 | </refentry> | 139 | </refentry> |
140 | |||
141 | <!-- | ||
142 | Local Variables: | ||
143 | mode: sgml | ||
144 | sgml-parent-document: "pixfmt.sgml" | ||
145 | indent-tabs-mode: nil | ||
146 | End: | ||
147 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12.xml index 873f67035181..84dd4fd7cb80 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-nv12.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-nv12.xml | |||
@@ -141,11 +141,3 @@ pixel image</title> | |||
141 | </example> | 141 | </example> |
142 | </refsect1> | 142 | </refsect1> |
143 | </refentry> | 143 | </refentry> |
144 | |||
145 | <!-- | ||
146 | Local Variables: | ||
147 | mode: sgml | ||
148 | sgml-parent-document: "pixfmt.sgml" | ||
149 | indent-tabs-mode: nil | ||
150 | End: | ||
151 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml index c9e166d9ded8..3fd3ce5df270 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml | |||
@@ -144,11 +144,3 @@ CbCr plane has as many pad bytes after its rows.</para> | |||
144 | </example> | 144 | </example> |
145 | </refsect1> | 145 | </refsect1> |
146 | </refentry> | 146 | </refentry> |
147 | |||
148 | <!-- | ||
149 | Local Variables: | ||
150 | mode: sgml | ||
151 | sgml-parent-document: "pixfmt.sgml" | ||
152 | indent-tabs-mode: nil | ||
153 | End: | ||
154 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml index 7a2855a526c1..2f82b1da8dfe 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml | |||
@@ -64,11 +64,3 @@ layout of macroblocks</title> | |||
64 | </example> | 64 | </example> |
65 | </refsect1> | 65 | </refsect1> |
66 | </refentry> | 66 | </refentry> |
67 | |||
68 | <!-- | ||
69 | Local Variables: | ||
70 | mode: sgml | ||
71 | sgml-parent-document: "pixfmt.sgml" | ||
72 | indent-tabs-mode: nil | ||
73 | End: | ||
74 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv16.xml b/Documentation/DocBook/media/v4l/pixfmt-nv16.xml index 26094035fc04..8ae1f8a810d0 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-nv16.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-nv16.xml | |||
@@ -164,11 +164,3 @@ pixel image</title> | |||
164 | </example> | 164 | </example> |
165 | </refsect1> | 165 | </refsect1> |
166 | </refentry> | 166 | </refentry> |
167 | |||
168 | <!-- | ||
169 | Local Variables: | ||
170 | mode: sgml | ||
171 | sgml-parent-document: "pixfmt.sgml" | ||
172 | indent-tabs-mode: nil | ||
173 | End: | ||
174 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml b/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml index 4db272b8a0d3..ba56536622f2 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml | |||
@@ -930,11 +930,3 @@ See &v4l-dvb; for access instructions.</para> | |||
930 | 930 | ||
931 | </refsect1> | 931 | </refsect1> |
932 | </refentry> | 932 | </refentry> |
933 | |||
934 | <!-- | ||
935 | Local Variables: | ||
936 | mode: sgml | ||
937 | sgml-parent-document: "pixfmt.sgml" | ||
938 | indent-tabs-mode: nil | ||
939 | End: | ||
940 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml b/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml index 3cab5d0ca75d..33fa5a47a865 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml | |||
@@ -234,11 +234,3 @@ linkend="osd">Video Output Overlay</link>.</para> | |||
234 | 234 | ||
235 | </refsect1> | 235 | </refsect1> |
236 | </refentry> | 236 | </refentry> |
237 | |||
238 | <!-- | ||
239 | Local Variables: | ||
240 | mode: sgml | ||
241 | sgml-parent-document: "pixfmt.sgml" | ||
242 | indent-tabs-mode: nil | ||
243 | End: | ||
244 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml b/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml index 519a9efbac10..6494b05d84a1 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml | |||
@@ -81,11 +81,3 @@ pixel image</title> | |||
81 | </example> | 81 | </example> |
82 | </refsect1> | 82 | </refsect1> |
83 | </refentry> | 83 | </refentry> |
84 | |||
85 | <!-- | ||
86 | Local Variables: | ||
87 | mode: sgml | ||
88 | sgml-parent-document: "pixfmt.sgml" | ||
89 | indent-tabs-mode: nil | ||
90 | End: | ||
91 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml b/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml index 5fe84ecc2ebe..5eaf2b42d3f7 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml | |||
@@ -65,11 +65,3 @@ pixel image</title> | |||
65 | </example> | 65 | </example> |
66 | </refsect1> | 66 | </refsect1> |
67 | </refentry> | 67 | </refentry> |
68 | |||
69 | <!-- | ||
70 | Local Variables: | ||
71 | mode: sgml | ||
72 | sgml-parent-document: "pixfmt.sgml" | ||
73 | indent-tabs-mode: nil | ||
74 | End: | ||
75 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml b/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml index d67a472b0880..fee65dca79c5 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml | |||
@@ -65,11 +65,3 @@ pixel image</title> | |||
65 | </example> | 65 | </example> |
66 | </refsect1> | 66 | </refsect1> |
67 | </refentry> | 67 | </refentry> |
68 | |||
69 | <!-- | ||
70 | Local Variables: | ||
71 | mode: sgml | ||
72 | sgml-parent-document: "pixfmt.sgml" | ||
73 | indent-tabs-mode: nil | ||
74 | End: | ||
75 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml b/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml index 0cdf13b8ac1c..19727ab4c757 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml | |||
@@ -65,11 +65,3 @@ columns and rows.</para> | |||
65 | </example> | 65 | </example> |
66 | </refsect1> | 66 | </refsect1> |
67 | </refentry> | 67 | </refentry> |
68 | |||
69 | <!-- | ||
70 | Local Variables: | ||
71 | mode: sgml | ||
72 | sgml-parent-document: "pixfmt.sgml" | ||
73 | indent-tabs-mode: nil | ||
74 | End: | ||
75 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml b/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml index 816c8d467c16..b1f6801a17ff 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml | |||
@@ -118,11 +118,3 @@ pixel image</title> | |||
118 | </example> | 118 | </example> |
119 | </refsect1> | 119 | </refsect1> |
120 | </refentry> | 120 | </refentry> |
121 | |||
122 | <!-- | ||
123 | Local Variables: | ||
124 | mode: sgml | ||
125 | sgml-parent-document: "pixfmt.sgml" | ||
126 | indent-tabs-mode: nil | ||
127 | End: | ||
128 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml b/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml index 61f12a5e68d9..82803408b389 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml | |||
@@ -118,11 +118,3 @@ pixel image</title> | |||
118 | </example> | 118 | </example> |
119 | </refsect1> | 119 | </refsect1> |
120 | </refentry> | 120 | </refentry> |
121 | |||
122 | <!-- | ||
123 | Local Variables: | ||
124 | mode: sgml | ||
125 | sgml-parent-document: "pixfmt.sgml" | ||
126 | indent-tabs-mode: nil | ||
127 | End: | ||
128 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-y16.xml b/Documentation/DocBook/media/v4l/pixfmt-y16.xml index d58404015078..ff4f727d5624 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-y16.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-y16.xml | |||
@@ -79,11 +79,3 @@ pixel image</title> | |||
79 | </example> | 79 | </example> |
80 | </refsect1> | 80 | </refsect1> |
81 | </refentry> | 81 | </refentry> |
82 | |||
83 | <!-- | ||
84 | Local Variables: | ||
85 | mode: sgml | ||
86 | sgml-parent-document: "pixfmt.sgml" | ||
87 | indent-tabs-mode: nil | ||
88 | End: | ||
89 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-y41p.xml b/Documentation/DocBook/media/v4l/pixfmt-y41p.xml index 73c8536efb05..98dcb91d2917 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-y41p.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-y41p.xml | |||
@@ -147,11 +147,3 @@ pixel image</title> | |||
147 | </example> | 147 | </example> |
148 | </refsect1> | 148 | </refsect1> |
149 | </refentry> | 149 | </refentry> |
150 | |||
151 | <!-- | ||
152 | Local Variables: | ||
153 | mode: sgml | ||
154 | sgml-parent-document: "pixfmt.sgml" | ||
155 | indent-tabs-mode: nil | ||
156 | End: | ||
157 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml index 8eb4a193d770..0869dce5f92c 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml | |||
@@ -131,11 +131,3 @@ pixel image</title> | |||
131 | </example> | 131 | </example> |
132 | </refsect1> | 132 | </refsect1> |
133 | </refentry> | 133 | </refentry> |
134 | |||
135 | <!-- | ||
136 | Local Variables: | ||
137 | mode: sgml | ||
138 | sgml-parent-document: "pixfmt.sgml" | ||
139 | indent-tabs-mode: nil | ||
140 | End: | ||
141 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml index 00e0960a9869..086dc731bf02 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml | |||
@@ -145,11 +145,3 @@ pixel image</title> | |||
145 | </example> | 145 | </example> |
146 | </refsect1> | 146 | </refsect1> |
147 | </refentry> | 147 | </refentry> |
148 | |||
149 | <!-- | ||
150 | Local Variables: | ||
151 | mode: sgml | ||
152 | sgml-parent-document: "v4l2.sgml" | ||
153 | indent-tabs-mode: nil | ||
154 | End: | ||
155 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml index 42d7de5e456d..48649fac1596 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml | |||
@@ -147,11 +147,3 @@ pixel image</title> | |||
147 | </example> | 147 | </example> |
148 | </refsect1> | 148 | </refsect1> |
149 | </refentry> | 149 | </refentry> |
150 | |||
151 | <!-- | ||
152 | Local Variables: | ||
153 | mode: sgml | ||
154 | sgml-parent-document: "pixfmt.sgml" | ||
155 | indent-tabs-mode: nil | ||
156 | End: | ||
157 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index f5d8f57495c8..9957863daf18 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml | |||
@@ -152,11 +152,3 @@ pixel image</title> | |||
152 | </example> | 152 | </example> |
153 | </refsect1> | 153 | </refsect1> |
154 | </refentry> | 154 | </refentry> |
155 | |||
156 | <!-- | ||
157 | Local Variables: | ||
158 | mode: sgml | ||
159 | sgml-parent-document: "pixfmt.sgml" | ||
160 | indent-tabs-mode: nil | ||
161 | End: | ||
162 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml index 4348bd9f0d01..4ce6463fe0a5 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml | |||
@@ -151,11 +151,3 @@ pixel image</title> | |||
151 | </example> | 151 | </example> |
152 | </refsect1> | 152 | </refsect1> |
153 | </refentry> | 153 | </refentry> |
154 | |||
155 | <!-- | ||
156 | Local Variables: | ||
157 | mode: sgml | ||
158 | sgml-parent-document: "pixfmt.sgml" | ||
159 | indent-tabs-mode: nil | ||
160 | End: | ||
161 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml b/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml index bdb2ffacbbcc..58384092251a 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml | |||
@@ -118,11 +118,3 @@ pixel image</title> | |||
118 | </example> | 118 | </example> |
119 | </refsect1> | 119 | </refsect1> |
120 | </refentry> | 120 | </refentry> |
121 | |||
122 | <!-- | ||
123 | Local Variables: | ||
124 | mode: sgml | ||
125 | sgml-parent-document: "pixfmt.sgml" | ||
126 | indent-tabs-mode: nil | ||
127 | End: | ||
128 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml b/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml index 40d17ae39dde..bfffdc76d3da 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml | |||
@@ -118,11 +118,3 @@ pixel image</title> | |||
118 | </example> | 118 | </example> |
119 | </refsect1> | 119 | </refsect1> |
120 | </refentry> | 120 | </refentry> |
121 | |||
122 | <!-- | ||
123 | Local Variables: | ||
124 | mode: sgml | ||
125 | sgml-parent-document: "pixfmt.sgml" | ||
126 | indent-tabs-mode: nil | ||
127 | End: | ||
128 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml index 2ff6b7776d7f..a33a4b22173b 100644 --- a/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt.xml | |||
@@ -997,11 +997,3 @@ the other bits are set to 0.</entry> | |||
997 | </tgroup> | 997 | </tgroup> |
998 | </table> | 998 | </table> |
999 | </section> | 999 | </section> |
1000 | |||
1001 | <!-- | ||
1002 | Local Variables: | ||
1003 | mode: sgml | ||
1004 | sgml-parent-document: "v4l2.sgml" | ||
1005 | indent-tabs-mode: nil | ||
1006 | End: | ||
1007 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml index 1d31427edd1b..0be17c232d3a 100644 --- a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml +++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml | |||
@@ -228,11 +228,3 @@ is out of bounds.</para> | |||
228 | </variablelist> | 228 | </variablelist> |
229 | </refsect1> | 229 | </refsect1> |
230 | </refentry> | 230 | </refentry> |
231 | |||
232 | <!-- | ||
233 | Local Variables: | ||
234 | mode: sgml | ||
235 | sgml-parent-document: "v4l2.sgml" | ||
236 | indent-tabs-mode: nil | ||
237 | End: | ||
238 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml index 71d373b6d36a..347d142e7431 100644 --- a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml +++ b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml | |||
@@ -156,11 +156,3 @@ bounds.</para> | |||
156 | </variablelist> | 156 | </variablelist> |
157 | </refsect1> | 157 | </refsect1> |
158 | </refentry> | 158 | </refentry> |
159 | |||
160 | <!-- | ||
161 | Local Variables: | ||
162 | mode: sgml | ||
163 | sgml-parent-document: "v4l2.sgml" | ||
164 | indent-tabs-mode: nil | ||
165 | End: | ||
166 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml index 476fe1d2bba0..9b8efcd6e947 100644 --- a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml +++ b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml | |||
@@ -311,11 +311,3 @@ out of bounds.</para> | |||
311 | </variablelist> | 311 | </variablelist> |
312 | </refsect1> | 312 | </refsect1> |
313 | </refentry> | 313 | </refentry> |
314 | |||
315 | <!-- | ||
316 | Local Variables: | ||
317 | mode: sgml | ||
318 | sgml-parent-document: "v4l2.sgml" | ||
319 | indent-tabs-mode: nil | ||
320 | End: | ||
321 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml index a281d26a195f..a64d5ef103fa 100644 --- a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml +++ b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml | |||
@@ -196,11 +196,3 @@ is out of bounds.</para> | |||
196 | </variablelist> | 196 | </variablelist> |
197 | </refsect1> | 197 | </refsect1> |
198 | </refentry> | 198 | </refentry> |
199 | |||
200 | <!-- | ||
201 | Local Variables: | ||
202 | mode: sgml | ||
203 | sgml-parent-document: "v4l2.sgml" | ||
204 | indent-tabs-mode: nil | ||
205 | End: | ||
206 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumstd.xml b/Documentation/DocBook/media/v4l/vidioc-enumstd.xml index 95803fe2c8e4..3a5fc5405f96 100644 --- a/Documentation/DocBook/media/v4l/vidioc-enumstd.xml +++ b/Documentation/DocBook/media/v4l/vidioc-enumstd.xml | |||
@@ -381,11 +381,3 @@ is out of bounds.</para> | |||
381 | </variablelist> | 381 | </variablelist> |
382 | </refsect1> | 382 | </refsect1> |
383 | </refentry> | 383 | </refentry> |
384 | |||
385 | <!-- | ||
386 | Local Variables: | ||
387 | mode: sgml | ||
388 | sgml-parent-document: "v4l2.sgml" | ||
389 | indent-tabs-mode: nil | ||
390 | End: | ||
391 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml b/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml index 5146d00782e3..12b1d0503e26 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml | |||
@@ -127,11 +127,3 @@ this control belongs to.</para> | |||
127 | </variablelist> | 127 | </variablelist> |
128 | </refsect1> | 128 | </refsect1> |
129 | </refentry> | 129 | </refentry> |
130 | |||
131 | <!-- | ||
132 | Local Variables: | ||
133 | mode: sgml | ||
134 | sgml-parent-document: "v4l2.sgml" | ||
135 | indent-tabs-mode: nil | ||
136 | End: | ||
137 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 5122ce87e0b8..6f1f9a629dc3 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml | |||
@@ -312,10 +312,3 @@ to store the payload and this error code is returned.</para> | |||
312 | </refsect1> | 312 | </refsect1> |
313 | </refentry> | 313 | </refentry> |
314 | 314 | ||
315 | <!-- | ||
316 | Local Variables: | ||
317 | mode: sgml | ||
318 | sgml-parent-document: "v4l2.sgml" | ||
319 | indent-tabs-mode: nil | ||
320 | End: | ||
321 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml index 055718231bc1..93817f337033 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml | |||
@@ -295,7 +295,8 @@ set this field to zero.</entry> | |||
295 | <entry>The device is capable of non-destructive overlays. | 295 | <entry>The device is capable of non-destructive overlays. |
296 | When the driver clears this flag, only destructive overlays are | 296 | When the driver clears this flag, only destructive overlays are |
297 | supported. There are no drivers yet which support both destructive and | 297 | supported. There are no drivers yet which support both destructive and |
298 | non-destructive overlays.</entry> | 298 | non-destructive overlays. Video Output Overlays are in practice always |
299 | non-destructive.</entry> | ||
299 | </row> | 300 | </row> |
300 | <row> | 301 | <row> |
301 | <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry> | 302 | <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry> |
@@ -339,8 +340,8 @@ blending makes no sense for destructive overlays.</entry> | |||
339 | <row> | 340 | <row> |
340 | <entry><constant>V4L2_FBUF_CAP_SRC_CHROMAKEY</constant></entry> | 341 | <entry><constant>V4L2_FBUF_CAP_SRC_CHROMAKEY</constant></entry> |
341 | <entry>0x0080</entry> | 342 | <entry>0x0080</entry> |
342 | <entry>The device supports Source Chroma-keying. Framebuffer pixels | 343 | <entry>The device supports Source Chroma-keying. Video pixels |
343 | with the chroma-key colors are replaced by video pixels, which is exactly opposite of | 344 | with the chroma-key colors are replaced by framebuffer pixels, which is exactly opposite of |
344 | <constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry> | 345 | <constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry> |
345 | </row> | 346 | </row> |
346 | </tbody> | 347 | </tbody> |
@@ -356,7 +357,9 @@ with the chroma-key colors are replaced by video pixels, which is exactly opposi | |||
356 | <entry><constant>V4L2_FBUF_FLAG_PRIMARY</constant></entry> | 357 | <entry><constant>V4L2_FBUF_FLAG_PRIMARY</constant></entry> |
357 | <entry>0x0001</entry> | 358 | <entry>0x0001</entry> |
358 | <entry>The framebuffer is the primary graphics surface. | 359 | <entry>The framebuffer is the primary graphics surface. |
359 | In other words, the overlay is destructive. [?]</entry> | 360 | In other words, the overlay is destructive. This flag is typically set by any |
361 | driver that doesn't have the <constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant> | ||
362 | capability and it is cleared otherwise.</entry> | ||
360 | </row> | 363 | </row> |
361 | <row> | 364 | <row> |
362 | <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry> | 365 | <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry> |
@@ -366,9 +369,8 @@ size as the capture. [?]</entry> | |||
366 | </row> | 369 | </row> |
367 | <row> | 370 | <row> |
368 | <entry spanname="hspan">The purpose of | 371 | <entry spanname="hspan">The purpose of |
369 | <constant>V4L2_FBUF_FLAG_PRIMARY</constant> and | ||
370 | <constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear. | 372 | <constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear. |
371 | Most drivers seem to ignore these flags. For compatibility with the | 373 | Most drivers seem to ignore this flag. For compatibility with the |
372 | <wordasword>bttv</wordasword> driver applications should set the | 374 | <wordasword>bttv</wordasword> driver applications should set the |
373 | <constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry> | 375 | <constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry> |
374 | </row> | 376 | </row> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml index 062d72069090..16431813bebd 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml | |||
@@ -135,11 +135,3 @@ wrong.</para> | |||
135 | </variablelist> | 135 | </variablelist> |
136 | </refsect1> | 136 | </refsect1> |
137 | </refentry> | 137 | </refentry> |
138 | |||
139 | <!-- | ||
140 | Local Variables: | ||
141 | mode: sgml | ||
142 | sgml-parent-document: "v4l2.sgml" | ||
143 | indent-tabs-mode: nil | ||
144 | End: | ||
145 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml b/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml index 15ce660f0f5a..7f4ac7e41fa8 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml | |||
@@ -236,11 +236,3 @@ mode.</entry> | |||
236 | </variablelist> | 236 | </variablelist> |
237 | </refsect1> | 237 | </refsect1> |
238 | </refentry> | 238 | </refentry> |
239 | |||
240 | <!-- | ||
241 | Local Variables: | ||
242 | mode: sgml | ||
243 | sgml-parent-document: "v4l2.sgml" | ||
244 | indent-tabs-mode: nil | ||
245 | End: | ||
246 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-priority.xml b/Documentation/DocBook/media/v4l/vidioc-g-priority.xml index 8f5e3da7002f..6a81b4fe9538 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-priority.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-priority.xml | |||
@@ -133,11 +133,3 @@ priority.</para> | |||
133 | </variablelist> | 133 | </variablelist> |
134 | </refsect1> | 134 | </refsect1> |
135 | </refentry> | 135 | </refentry> |
136 | |||
137 | <!-- | ||
138 | Local Variables: | ||
139 | mode: sgml | ||
140 | sgml-parent-document: "v4l2.sgml" | ||
141 | indent-tabs-mode: nil | ||
142 | End: | ||
143 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-std.xml b/Documentation/DocBook/media/v4l/vidioc-g-std.xml index 37996f25b5d4..99ff1a016220 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-std.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-std.xml | |||
@@ -88,11 +88,3 @@ standards.</para> | |||
88 | </variablelist> | 88 | </variablelist> |
89 | </refsect1> | 89 | </refsect1> |
90 | </refentry> | 90 | </refentry> |
91 | |||
92 | <!-- | ||
93 | Local Variables: | ||
94 | mode: sgml | ||
95 | sgml-parent-document: "v4l2.sgml" | ||
96 | indent-tabs-mode: nil | ||
97 | End: | ||
98 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml index bd98c734c06b..91ec2fb658f8 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml | |||
@@ -318,6 +318,16 @@ standard.</para><!-- FIXME what if PAL+NTSC and Bi but not SAP? --></entry> | |||
318 | <entry>RDS capture is supported. This capability is only valid for | 318 | <entry>RDS capture is supported. This capability is only valid for |
319 | radio tuners.</entry> | 319 | radio tuners.</entry> |
320 | </row> | 320 | </row> |
321 | <row> | ||
322 | <entry><constant>V4L2_TUNER_CAP_RDS_BLOCK_IO</constant></entry> | ||
323 | <entry>0x0100</entry> | ||
324 | <entry>The RDS data is passed as unparsed RDS blocks.</entry> | ||
325 | </row> | ||
326 | <row> | ||
327 | <entry><constant>V4L2_TUNER_CAP_RDS_CONTROLS</constant></entry> | ||
328 | <entry>0x0200</entry> | ||
329 | <entry>The RDS data is parsed by the hardware and set via controls.</entry> | ||
330 | </row> | ||
321 | </tbody> | 331 | </tbody> |
322 | </tgroup> | 332 | </tgroup> |
323 | </table> | 333 | </table> |
@@ -525,11 +535,3 @@ out of bounds.</para> | |||
525 | </variablelist> | 535 | </variablelist> |
526 | </refsect1> | 536 | </refsect1> |
527 | </refentry> | 537 | </refentry> |
528 | |||
529 | <!-- | ||
530 | Local Variables: | ||
531 | mode: sgml | ||
532 | sgml-parent-document: "v4l2.sgml" | ||
533 | indent-tabs-mode: nil | ||
534 | End: | ||
535 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-querybuf.xml b/Documentation/DocBook/media/v4l/vidioc-querybuf.xml index 5c104d42d31c..6e414d7b6df7 100644 --- a/Documentation/DocBook/media/v4l/vidioc-querybuf.xml +++ b/Documentation/DocBook/media/v4l/vidioc-querybuf.xml | |||
@@ -100,11 +100,3 @@ supported, or the <structfield>index</structfield> is out of bounds.</para> | |||
100 | </variablelist> | 100 | </variablelist> |
101 | </refsect1> | 101 | </refsect1> |
102 | </refentry> | 102 | </refentry> |
103 | |||
104 | <!-- | ||
105 | Local Variables: | ||
106 | mode: sgml | ||
107 | sgml-parent-document: "v4l2.sgml" | ||
108 | indent-tabs-mode: nil | ||
109 | End: | ||
110 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml index 0ac0057a51c4..36660d311b51 100644 --- a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml +++ b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml | |||
@@ -443,11 +443,3 @@ or this particular menu item is not supported by the driver.</para> | |||
443 | </variablelist> | 443 | </variablelist> |
444 | </refsect1> | 444 | </refsect1> |
445 | </refentry> | 445 | </refentry> |
446 | |||
447 | <!-- | ||
448 | Local Variables: | ||
449 | mode: sgml | ||
450 | sgml-parent-document: "v4l2.sgml" | ||
451 | indent-tabs-mode: nil | ||
452 | End: | ||
453 | --> | ||
diff --git a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml index c30dcc4232c0..e013da845b11 100644 --- a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml +++ b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml | |||
@@ -125,11 +125,3 @@ wrong.</para> | |||
125 | </variablelist> | 125 | </variablelist> |
126 | </refsect1> | 126 | </refsect1> |
127 | </refentry> | 127 | </refentry> |
128 | |||
129 | <!-- | ||
130 | Local Variables: | ||
131 | mode: sgml | ||
132 | sgml-parent-document: "v4l2.sgml" | ||
133 | indent-tabs-mode: nil | ||
134 | End: | ||
135 | --> | ||
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index e67be7afc78b..d1d4a179a382 100755 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware | |||
@@ -27,8 +27,8 @@ use IO::Handle; | |||
27 | "or51211", "or51132_qam", "or51132_vsb", "bluebird", | 27 | "or51211", "or51132_qam", "or51132_vsb", "bluebird", |
28 | "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", | 28 | "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", |
29 | "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", | 29 | "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", |
30 | "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", "tda10071", | 30 | "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", |
31 | "it9135" ); | 31 | "drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137"); |
32 | 32 | ||
33 | # Check args | 33 | # Check args |
34 | syntax() if (scalar(@ARGV) != 1); | 34 | syntax() if (scalar(@ARGV) != 1); |
@@ -644,6 +644,24 @@ sub drxk { | |||
644 | "$fwfile" | 644 | "$fwfile" |
645 | } | 645 | } |
646 | 646 | ||
647 | sub drxk_hauppauge_hvr930c { | ||
648 | my $url = "http://www.wintvcd.co.uk/drivers/"; | ||
649 | my $zipfile = "HVR-9x0_5_10_325_28153_SIGNED.zip"; | ||
650 | my $hash = "83ab82e7e9480ec8bf1ae0155ca63c88"; | ||
651 | my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); | ||
652 | my $drvfile = "HVR-900/emOEM.sys"; | ||
653 | my $fwfile = "dvb-usb-hauppauge-hvr930c-drxk.fw"; | ||
654 | |||
655 | checkstandard(); | ||
656 | |||
657 | wgetfile($zipfile, $url . $zipfile); | ||
658 | verify($zipfile, $hash); | ||
659 | unzip($zipfile, $tmpdir); | ||
660 | extract("$tmpdir/$drvfile", 0x117b0, 42692, "$fwfile"); | ||
661 | |||
662 | "$fwfile" | ||
663 | } | ||
664 | |||
647 | sub drxk_terratec_h5 { | 665 | sub drxk_terratec_h5 { |
648 | my $url = "http://www.linuxtv.org/downloads/firmware/"; | 666 | my $url = "http://www.linuxtv.org/downloads/firmware/"; |
649 | my $hash = "19000dada8e2741162ccc50cc91fa7f1"; | 667 | my $hash = "19000dada8e2741162ccc50cc91fa7f1"; |
@@ -658,6 +676,26 @@ sub drxk_terratec_h5 { | |||
658 | } | 676 | } |
659 | 677 | ||
660 | sub it9135 { | 678 | sub it9135 { |
679 | my $sourcefile = "dvb-usb-it9135.zip"; | ||
680 | my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile"; | ||
681 | my $hash = "1e55f6c8833f1d0ae067c2bb2953e6a9"; | ||
682 | my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0); | ||
683 | my $outfile = "dvb-usb-it9135.fw"; | ||
684 | my $fwfile1 = "dvb-usb-it9135-01.fw"; | ||
685 | my $fwfile2 = "dvb-usb-it9135-02.fw"; | ||
686 | |||
687 | checkstandard(); | ||
688 | |||
689 | wgetfile($sourcefile, $url); | ||
690 | unzip($sourcefile, $tmpdir); | ||
691 | verify("$tmpdir/$outfile", $hash); | ||
692 | extract("$tmpdir/$outfile", 64, 8128, "$fwfile1"); | ||
693 | extract("$tmpdir/$outfile", 12866, 5817, "$fwfile2"); | ||
694 | |||
695 | "$fwfile1 $fwfile2" | ||
696 | } | ||
697 | |||
698 | sub it9137 { | ||
661 | my $url = "http://kworld.server261.com/kworld/CD/ITE_TiVme/V1.00/"; | 699 | my $url = "http://kworld.server261.com/kworld/CD/ITE_TiVme/V1.00/"; |
662 | my $zipfile = "Driver_V10.323.1.0412.100412.zip"; | 700 | my $zipfile = "Driver_V10.323.1.0412.100412.zip"; |
663 | my $hash = "79b597dc648698ed6820845c0c9d0d37"; | 701 | my $hash = "79b597dc648698ed6820845c0c9d0d37"; |
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv index 4739d5684305..8948da46a254 100644 --- a/Documentation/video4linux/CARDLIST.bttv +++ b/Documentation/video4linux/CARDLIST.bttv | |||
@@ -71,7 +71,7 @@ | |||
71 | 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E) | 71 | 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E) |
72 | 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851] | 72 | 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851] |
73 | 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011] | 73 | 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011] |
74 | 73 -> Sensoray 311 [6000:0311] | 74 | 73 -> Sensoray 311/611 [6000:0311,6000:0611] |
75 | 74 -> RemoteVision MX (RV605) | 75 | 74 -> RemoteVision MX (RV605) |
76 | 75 -> Powercolor MTV878/ MTV878R/ MTV878F | 76 | 75 -> Powercolor MTV878/ MTV878R/ MTV878F |
77 | 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079] | 77 | 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079] |
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index 8910449d23a8..99acaa344fea 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 | |||
@@ -29,3 +29,5 @@ | |||
29 | 28 -> LEADTEK WinFast PxTV1200 [107d:6f22] | 29 | 28 -> LEADTEK WinFast PxTV1200 [107d:6f22] |
30 | 29 -> GoTView X5 3D Hybrid [5654:2390] | 30 | 29 -> GoTView X5 3D Hybrid [5654:2390] |
31 | 30 -> NetUP Dual DVB-T/C-CI RF [1b55:e2e4] | 31 | 30 -> NetUP Dual DVB-T/C-CI RF [1b55:e2e4] |
32 | 31 -> Leadtek Winfast PxDVR3200 H XC4000 [107d:6f39] | ||
33 | 32 -> MPX-885 | ||
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index d9c0f119196d..eee18e6962b6 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 | |||
@@ -85,3 +85,5 @@ | |||
85 | 84 -> Samsung SMT 7020 DVB-S [18ac:dc00,18ac:dccd] | 85 | 84 -> Samsung SMT 7020 DVB-S [18ac:dc00,18ac:dccd] |
86 | 85 -> Twinhan VP-1027 DVB-S [1822:0023] | 86 | 85 -> Twinhan VP-1027 DVB-S [1822:0023] |
87 | 86 -> TeVii S464 DVB-S/S2 [d464:9022] | 87 | 86 -> TeVii S464 DVB-S/S2 [d464:9022] |
88 | 87 -> Leadtek WinFast DTV2000 H PLUS [107d:6f42] | ||
89 | 88 -> Leadtek WinFast DTV1800 H (XC4000) [107d:6f38] | ||
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 4a7b3df6d8bd..7734b2cf0810 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx | |||
@@ -11,7 +11,7 @@ | |||
11 | 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] | 11 | 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] |
12 | 11 -> Terratec Hybrid XS (em2880) | 12 | 11 -> Terratec Hybrid XS (em2880) |
13 | 12 -> Kworld PVR TV 2800 RF (em2820/em2840) | 13 | 12 -> Kworld PVR TV 2800 RF (em2820/em2840) |
14 | 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] | 14 | 13 -> Terratec Prodigy XS (em2880) |
15 | 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) | 15 | 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) |
16 | 15 -> V-Gear PocketTV (em2800) | 16 | 15 -> V-Gear PocketTV (em2800) |
17 | 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b] | 17 | 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b] |
@@ -64,7 +64,7 @@ | |||
64 | 64 -> Easy Cap Capture DC-60 (em2860) | 64 | 64 -> Easy Cap Capture DC-60 (em2860) |
65 | 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515] | 65 | 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515] |
66 | 66 -> Empire dual TV (em2880) | 66 | 66 -> Empire dual TV (em2880) |
67 | 67 -> Terratec Grabby (em2860) [0ccd:0096] | 67 | 67 -> Terratec Grabby (em2860) [0ccd:0096,0ccd:10AF] |
68 | 68 -> Terratec AV350 (em2860) [0ccd:0084] | 68 | 68 -> Terratec AV350 (em2860) [0ccd:0084] |
69 | 69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313] | 69 | 69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313] |
70 | 70 -> Evga inDtube (em2882) | 70 | 70 -> Evga inDtube (em2882) |
@@ -76,3 +76,5 @@ | |||
76 | 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] | 76 | 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] |
77 | 77 -> EM2874 Leadership ISDBT (em2874) | 77 | 77 -> EM2874 Leadership ISDBT (em2874) |
78 | 78 -> PCTV nanoStick T2 290e (em28174) | 78 | 78 -> PCTV nanoStick T2 290e (em28174) |
79 | 79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad] | ||
80 | 80 -> PCTV DVB-S2 Stick (460e) (em28174) | ||
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 7efae9bd73ed..e7ef38a19859 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 | |||
@@ -186,3 +186,4 @@ | |||
186 | 185 -> MagicPro ProHDTV Pro2 DMB-TH/Hybrid [17de:d136] | 186 | 185 -> MagicPro ProHDTV Pro2 DMB-TH/Hybrid [17de:d136] |
187 | 186 -> Beholder BeholdTV 501 [5ace:5010] | 187 | 186 -> Beholder BeholdTV 501 [5ace:5010] |
188 | 187 -> Beholder BeholdTV 503 FM [5ace:5030] | 188 | 187 -> Beholder BeholdTV 503 FM [5ace:5030] |
189 | 188 -> Sensoray 811/911 [6000:0811,6000:0911] | ||
diff --git a/Documentation/video4linux/CARDLIST.saa7164 b/Documentation/video4linux/CARDLIST.saa7164 index 152bd7b781ca..2205e8d55537 100644 --- a/Documentation/video4linux/CARDLIST.saa7164 +++ b/Documentation/video4linux/CARDLIST.saa7164 | |||
@@ -7,3 +7,5 @@ | |||
7 | 6 -> Hauppauge WinTV-HVR2200 [0070:8901] | 7 | 6 -> Hauppauge WinTV-HVR2200 [0070:8901] |
8 | 7 -> Hauppauge WinTV-HVR2250 [0070:8891,0070:8851] | 8 | 7 -> Hauppauge WinTV-HVR2250 [0070:8891,0070:8851] |
9 | 8 -> Hauppauge WinTV-HVR2250 [0070:88A1] | 9 | 8 -> Hauppauge WinTV-HVR2250 [0070:88A1] |
10 | 9 -> Hauppauge WinTV-HVR2200 [0070:8940] | ||
11 | 10 -> Hauppauge WinTV-HVR2200 [0070:8953] | ||
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index f8dcabf7852c..659b2ba12a4f 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt | |||
@@ -612,6 +612,12 @@ You can set a pointer to a mutex_lock in struct video_device. Usually this | |||
612 | will be either a top-level mutex or a mutex per device node. If you want | 612 | will be either a top-level mutex or a mutex per device node. If you want |
613 | finer-grained locking then you have to set it to NULL and do you own locking. | 613 | finer-grained locking then you have to set it to NULL and do you own locking. |
614 | 614 | ||
615 | It is up to the driver developer to decide which method to use. However, if | ||
616 | your driver has high-latency operations (for example, changing the exposure | ||
617 | of a USB webcam might take a long time), then you might be better off with | ||
618 | doing your own locking if you want to allow the user to do other things with | ||
619 | the device while waiting for the high-latency command to finish. | ||
620 | |||
615 | If a lock is specified then all file operations will be serialized on that | 621 | If a lock is specified then all file operations will be serialized on that |
616 | lock. If you use videobuf then you must pass the same lock to the videobuf | 622 | lock. If you use videobuf then you must pass the same lock to the videobuf |
617 | queue initialize function: if videobuf has to wait for a frame to arrive, then | 623 | queue initialize function: if videobuf has to wait for a frame to arrive, then |
@@ -619,6 +625,11 @@ it will temporarily unlock the lock and relock it afterwards. If your driver | |||
619 | also waits in the code, then you should do the same to allow other processes | 625 | also waits in the code, then you should do the same to allow other processes |
620 | to access the device node while the first process is waiting for something. | 626 | to access the device node while the first process is waiting for something. |
621 | 627 | ||
628 | In the case of videobuf2 you will need to implement the wait_prepare and | ||
629 | wait_finish callbacks to unlock/lock if applicable. In particular, if you use | ||
630 | the lock in struct video_device then you must unlock/lock this mutex in | ||
631 | wait_prepare and wait_finish. | ||
632 | |||
622 | The implementation of a hotplug disconnect should also take the lock before | 633 | The implementation of a hotplug disconnect should also take the lock before |
623 | calling v4l2_device_disconnect. | 634 | calling v4l2_device_disconnect. |
624 | 635 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 6afba60c3904..39723f1a375b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2837,6 +2837,14 @@ L: platform-driver-x86@vger.kernel.org | |||
2837 | S: Maintained | 2837 | S: Maintained |
2838 | F: drivers/platform/x86/fujitsu-laptop.c | 2838 | F: drivers/platform/x86/fujitsu-laptop.c |
2839 | 2839 | ||
2840 | FUJITSU M-5MO LS CAMERA ISP DRIVER | ||
2841 | M: Kyungmin Park <kyungmin.park@samsung.com> | ||
2842 | M: Heungjun Kim <riverful.kim@samsung.com> | ||
2843 | L: linux-media@vger.kernel.org | ||
2844 | S: Maintained | ||
2845 | F: drivers/media/video/m5mols/ | ||
2846 | F: include/media/m5mols.h | ||
2847 | |||
2840 | FUSE: FILESYSTEM IN USERSPACE | 2848 | FUSE: FILESYSTEM IN USERSPACE |
2841 | M: Miklos Szeredi <miklos@szeredi.hu> | 2849 | M: Miklos Szeredi <miklos@szeredi.hu> |
2842 | L: fuse-devel@lists.sourceforge.net | 2850 | L: fuse-devel@lists.sourceforge.net |
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c index 2d0e7689c6a2..2ecaa53d1449 100644 --- a/drivers/media/common/tuners/mt2060.c +++ b/drivers/media/common/tuners/mt2060.c | |||
@@ -300,6 +300,12 @@ static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
302 | 302 | ||
303 | static int mt2060_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
304 | { | ||
305 | *frequency = IF2 * 1000; | ||
306 | return 0; | ||
307 | } | ||
308 | |||
303 | static int mt2060_init(struct dvb_frontend *fe) | 309 | static int mt2060_init(struct dvb_frontend *fe) |
304 | { | 310 | { |
305 | struct mt2060_priv *priv = fe->tuner_priv; | 311 | struct mt2060_priv *priv = fe->tuner_priv; |
@@ -356,7 +362,8 @@ static const struct dvb_tuner_ops mt2060_tuner_ops = { | |||
356 | 362 | ||
357 | .set_params = mt2060_set_params, | 363 | .set_params = mt2060_set_params, |
358 | .get_frequency = mt2060_get_frequency, | 364 | .get_frequency = mt2060_get_frequency, |
359 | .get_bandwidth = mt2060_get_bandwidth | 365 | .get_bandwidth = mt2060_get_bandwidth, |
366 | .get_if_frequency = mt2060_get_if_frequency, | ||
360 | }; | 367 | }; |
361 | 368 | ||
362 | /* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */ | 369 | /* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */ |
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 5d02221e99dd..67bccde1f816 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c | |||
@@ -165,6 +165,8 @@ struct mxl5007t_state { | |||
165 | struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)]; | 165 | struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)]; |
166 | struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)]; | 166 | struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)]; |
167 | 167 | ||
168 | enum mxl5007t_if_freq if_freq; | ||
169 | |||
168 | u32 frequency; | 170 | u32 frequency; |
169 | u32 bandwidth; | 171 | u32 bandwidth; |
170 | }; | 172 | }; |
@@ -286,6 +288,8 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, | |||
286 | /* set inverted IF or normal IF */ | 288 | /* set inverted IF or normal IF */ |
287 | set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00); | 289 | set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00); |
288 | 290 | ||
291 | state->if_freq = if_freq; | ||
292 | |||
289 | return; | 293 | return; |
290 | } | 294 | } |
291 | 295 | ||
@@ -738,6 +742,50 @@ static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
738 | return 0; | 742 | return 0; |
739 | } | 743 | } |
740 | 744 | ||
745 | static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
746 | { | ||
747 | struct mxl5007t_state *state = fe->tuner_priv; | ||
748 | |||
749 | *frequency = 0; | ||
750 | |||
751 | switch (state->if_freq) { | ||
752 | case MxL_IF_4_MHZ: | ||
753 | *frequency = 4000000; | ||
754 | break; | ||
755 | case MxL_IF_4_5_MHZ: | ||
756 | *frequency = 4500000; | ||
757 | break; | ||
758 | case MxL_IF_4_57_MHZ: | ||
759 | *frequency = 4570000; | ||
760 | break; | ||
761 | case MxL_IF_5_MHZ: | ||
762 | *frequency = 5000000; | ||
763 | break; | ||
764 | case MxL_IF_5_38_MHZ: | ||
765 | *frequency = 5380000; | ||
766 | break; | ||
767 | case MxL_IF_6_MHZ: | ||
768 | *frequency = 6000000; | ||
769 | break; | ||
770 | case MxL_IF_6_28_MHZ: | ||
771 | *frequency = 6280000; | ||
772 | break; | ||
773 | case MxL_IF_9_1915_MHZ: | ||
774 | *frequency = 9191500; | ||
775 | break; | ||
776 | case MxL_IF_35_25_MHZ: | ||
777 | *frequency = 35250000; | ||
778 | break; | ||
779 | case MxL_IF_36_15_MHZ: | ||
780 | *frequency = 36150000; | ||
781 | break; | ||
782 | case MxL_IF_44_MHZ: | ||
783 | *frequency = 44000000; | ||
784 | break; | ||
785 | } | ||
786 | return 0; | ||
787 | } | ||
788 | |||
741 | static int mxl5007t_release(struct dvb_frontend *fe) | 789 | static int mxl5007t_release(struct dvb_frontend *fe) |
742 | { | 790 | { |
743 | struct mxl5007t_state *state = fe->tuner_priv; | 791 | struct mxl5007t_state *state = fe->tuner_priv; |
@@ -767,6 +815,7 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = { | |||
767 | .get_frequency = mxl5007t_get_frequency, | 815 | .get_frequency = mxl5007t_get_frequency, |
768 | .get_bandwidth = mxl5007t_get_bandwidth, | 816 | .get_bandwidth = mxl5007t_get_bandwidth, |
769 | .release = mxl5007t_release, | 817 | .release = mxl5007t_release, |
818 | .get_if_frequency = mxl5007t_get_if_frequency, | ||
770 | }; | 819 | }; |
771 | 820 | ||
772 | static int mxl5007t_get_chip_id(struct mxl5007t_state *state) | 821 | static int mxl5007t_get_chip_id(struct mxl5007t_state *state) |
diff --git a/drivers/media/common/tuners/qt1010.c b/drivers/media/common/tuners/qt1010.c index 9f5dba244cb8..cd461c2a4c38 100644 --- a/drivers/media/common/tuners/qt1010.c +++ b/drivers/media/common/tuners/qt1010.c | |||
@@ -423,6 +423,12 @@ static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
423 | return 0; | 423 | return 0; |
424 | } | 424 | } |
425 | 425 | ||
426 | static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
427 | { | ||
428 | *frequency = 36125000; | ||
429 | return 0; | ||
430 | } | ||
431 | |||
426 | static const struct dvb_tuner_ops qt1010_tuner_ops = { | 432 | static const struct dvb_tuner_ops qt1010_tuner_ops = { |
427 | .info = { | 433 | .info = { |
428 | .name = "Quantek QT1010", | 434 | .name = "Quantek QT1010", |
@@ -437,7 +443,8 @@ static const struct dvb_tuner_ops qt1010_tuner_ops = { | |||
437 | 443 | ||
438 | .set_params = qt1010_set_params, | 444 | .set_params = qt1010_set_params, |
439 | .get_frequency = qt1010_get_frequency, | 445 | .get_frequency = qt1010_get_frequency, |
440 | .get_bandwidth = qt1010_get_bandwidth | 446 | .get_bandwidth = qt1010_get_bandwidth, |
447 | .get_if_frequency = qt1010_get_if_frequency, | ||
441 | }; | 448 | }; |
442 | 449 | ||
443 | struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, | 450 | struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c index e29cc2bc113a..f52282e6c8bb 100644 --- a/drivers/media/common/tuners/tda18212.c +++ b/drivers/media/common/tuners/tda18212.c | |||
@@ -25,6 +25,8 @@ | |||
25 | struct tda18212_priv { | 25 | struct tda18212_priv { |
26 | struct tda18212_config *cfg; | 26 | struct tda18212_config *cfg; |
27 | struct i2c_adapter *i2c; | 27 | struct i2c_adapter *i2c; |
28 | |||
29 | u32 if_frequency; | ||
28 | }; | 30 | }; |
29 | 31 | ||
30 | #define dbg(fmt, arg...) \ | 32 | #define dbg(fmt, arg...) \ |
@@ -136,12 +138,24 @@ static int tda18212_set_params(struct dvb_frontend *fe, | |||
136 | int ret, i; | 138 | int ret, i; |
137 | u32 if_khz; | 139 | u32 if_khz; |
138 | u8 buf[9]; | 140 | u8 buf[9]; |
141 | #define DVBT_6 0 | ||
142 | #define DVBT_7 1 | ||
143 | #define DVBT_8 2 | ||
144 | #define DVBT2_6 3 | ||
145 | #define DVBT2_7 4 | ||
146 | #define DVBT2_8 5 | ||
147 | #define DVBC_6 6 | ||
148 | #define DVBC_8 7 | ||
139 | static const u8 bw_params[][3] = { | 149 | static const u8 bw_params[][3] = { |
140 | /* 0f 13 23 */ | 150 | /* reg: 0f 13 23 */ |
141 | { 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */ | 151 | [DVBT_6] = { 0xb3, 0x20, 0x03 }, |
142 | { 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */ | 152 | [DVBT_7] = { 0xb3, 0x31, 0x01 }, |
143 | { 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */ | 153 | [DVBT_8] = { 0xb3, 0x22, 0x01 }, |
144 | { 0x92, 0x53, 0x03 }, /* DVB-C */ | 154 | [DVBT2_6] = { 0xbc, 0x20, 0x03 }, |
155 | [DVBT2_7] = { 0xbc, 0x72, 0x03 }, | ||
156 | [DVBT2_8] = { 0xbc, 0x22, 0x01 }, | ||
157 | [DVBC_6] = { 0x92, 0x50, 0x03 }, | ||
158 | [DVBC_8] = { 0x92, 0x53, 0x03 }, | ||
145 | }; | 159 | }; |
146 | 160 | ||
147 | dbg("delsys=%d RF=%d BW=%d\n", | 161 | dbg("delsys=%d RF=%d BW=%d\n", |
@@ -155,15 +169,34 @@ static int tda18212_set_params(struct dvb_frontend *fe, | |||
155 | switch (c->bandwidth_hz) { | 169 | switch (c->bandwidth_hz) { |
156 | case 6000000: | 170 | case 6000000: |
157 | if_khz = priv->cfg->if_dvbt_6; | 171 | if_khz = priv->cfg->if_dvbt_6; |
158 | i = 0; | 172 | i = DVBT_6; |
159 | break; | 173 | break; |
160 | case 7000000: | 174 | case 7000000: |
161 | if_khz = priv->cfg->if_dvbt_7; | 175 | if_khz = priv->cfg->if_dvbt_7; |
162 | i = 1; | 176 | i = DVBT_7; |
163 | break; | 177 | break; |
164 | case 8000000: | 178 | case 8000000: |
165 | if_khz = priv->cfg->if_dvbt_8; | 179 | if_khz = priv->cfg->if_dvbt_8; |
166 | i = 2; | 180 | i = DVBT_8; |
181 | break; | ||
182 | default: | ||
183 | ret = -EINVAL; | ||
184 | goto error; | ||
185 | } | ||
186 | break; | ||
187 | case SYS_DVBT2: | ||
188 | switch (c->bandwidth_hz) { | ||
189 | case 6000000: | ||
190 | if_khz = priv->cfg->if_dvbt2_6; | ||
191 | i = DVBT2_6; | ||
192 | break; | ||
193 | case 7000000: | ||
194 | if_khz = priv->cfg->if_dvbt2_7; | ||
195 | i = DVBT2_7; | ||
196 | break; | ||
197 | case 8000000: | ||
198 | if_khz = priv->cfg->if_dvbt2_8; | ||
199 | i = DVBT2_8; | ||
167 | break; | 200 | break; |
168 | default: | 201 | default: |
169 | ret = -EINVAL; | 202 | ret = -EINVAL; |
@@ -172,7 +205,7 @@ static int tda18212_set_params(struct dvb_frontend *fe, | |||
172 | break; | 205 | break; |
173 | case SYS_DVBC_ANNEX_AC: | 206 | case SYS_DVBC_ANNEX_AC: |
174 | if_khz = priv->cfg->if_dvbc; | 207 | if_khz = priv->cfg->if_dvbc; |
175 | i = 3; | 208 | i = DVBC_8; |
176 | break; | 209 | break; |
177 | default: | 210 | default: |
178 | ret = -EINVAL; | 211 | ret = -EINVAL; |
@@ -194,7 +227,7 @@ static int tda18212_set_params(struct dvb_frontend *fe, | |||
194 | buf[0] = 0x02; | 227 | buf[0] = 0x02; |
195 | buf[1] = bw_params[i][1]; | 228 | buf[1] = bw_params[i][1]; |
196 | buf[2] = 0x03; /* default value */ | 229 | buf[2] = 0x03; /* default value */ |
197 | buf[3] = if_khz / 50; | 230 | buf[3] = DIV_ROUND_CLOSEST(if_khz, 50); |
198 | buf[4] = ((c->frequency / 1000) >> 16) & 0xff; | 231 | buf[4] = ((c->frequency / 1000) >> 16) & 0xff; |
199 | buf[5] = ((c->frequency / 1000) >> 8) & 0xff; | 232 | buf[5] = ((c->frequency / 1000) >> 8) & 0xff; |
200 | buf[6] = ((c->frequency / 1000) >> 0) & 0xff; | 233 | buf[6] = ((c->frequency / 1000) >> 0) & 0xff; |
@@ -204,6 +237,9 @@ static int tda18212_set_params(struct dvb_frontend *fe, | |||
204 | if (ret) | 237 | if (ret) |
205 | goto error; | 238 | goto error; |
206 | 239 | ||
240 | /* actual IF rounded as it is on register */ | ||
241 | priv->if_frequency = buf[3] * 50 * 1000; | ||
242 | |||
207 | exit: | 243 | exit: |
208 | if (fe->ops.i2c_gate_ctrl) | 244 | if (fe->ops.i2c_gate_ctrl) |
209 | fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ | 245 | fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ |
@@ -215,6 +251,15 @@ error: | |||
215 | goto exit; | 251 | goto exit; |
216 | } | 252 | } |
217 | 253 | ||
254 | static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
255 | { | ||
256 | struct tda18212_priv *priv = fe->tuner_priv; | ||
257 | |||
258 | *frequency = priv->if_frequency; | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
218 | static int tda18212_release(struct dvb_frontend *fe) | 263 | static int tda18212_release(struct dvb_frontend *fe) |
219 | { | 264 | { |
220 | kfree(fe->tuner_priv); | 265 | kfree(fe->tuner_priv); |
@@ -234,6 +279,7 @@ static const struct dvb_tuner_ops tda18212_tuner_ops = { | |||
234 | .release = tda18212_release, | 279 | .release = tda18212_release, |
235 | 280 | ||
236 | .set_params = tda18212_set_params, | 281 | .set_params = tda18212_set_params, |
282 | .get_if_frequency = tda18212_get_if_frequency, | ||
237 | }; | 283 | }; |
238 | 284 | ||
239 | struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe, | 285 | struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/common/tuners/tda18212.h b/drivers/media/common/tuners/tda18212.h index 83b497f59e1b..9bd5da4aabb7 100644 --- a/drivers/media/common/tuners/tda18212.h +++ b/drivers/media/common/tuners/tda18212.h | |||
@@ -29,6 +29,10 @@ struct tda18212_config { | |||
29 | u16 if_dvbt_6; | 29 | u16 if_dvbt_6; |
30 | u16 if_dvbt_7; | 30 | u16 if_dvbt_7; |
31 | u16 if_dvbt_8; | 31 | u16 if_dvbt_8; |
32 | u16 if_dvbt2_5; | ||
33 | u16 if_dvbt2_6; | ||
34 | u16 if_dvbt2_7; | ||
35 | u16 if_dvbt2_8; | ||
32 | u16 if_dvbc; | 36 | u16 if_dvbc; |
33 | }; | 37 | }; |
34 | 38 | ||
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c index 4fc29730a12c..d099501566a1 100644 --- a/drivers/media/common/tuners/tda18218.c +++ b/drivers/media/common/tuners/tda18218.c | |||
@@ -141,19 +141,21 @@ static int tda18218_set_params(struct dvb_frontend *fe, | |||
141 | switch (params->u.ofdm.bandwidth) { | 141 | switch (params->u.ofdm.bandwidth) { |
142 | case BANDWIDTH_6_MHZ: | 142 | case BANDWIDTH_6_MHZ: |
143 | LP_Fc = 0; | 143 | LP_Fc = 0; |
144 | LO_Frac = params->frequency + 3000000; | 144 | priv->if_frequency = 3000000; |
145 | break; | 145 | break; |
146 | case BANDWIDTH_7_MHZ: | 146 | case BANDWIDTH_7_MHZ: |
147 | LP_Fc = 1; | 147 | LP_Fc = 1; |
148 | LO_Frac = params->frequency + 3500000; | 148 | priv->if_frequency = 3500000; |
149 | break; | 149 | break; |
150 | case BANDWIDTH_8_MHZ: | 150 | case BANDWIDTH_8_MHZ: |
151 | default: | 151 | default: |
152 | LP_Fc = 2; | 152 | LP_Fc = 2; |
153 | LO_Frac = params->frequency + 4000000; | 153 | priv->if_frequency = 4000000; |
154 | break; | 154 | break; |
155 | } | 155 | } |
156 | 156 | ||
157 | LO_Frac = params->frequency + priv->if_frequency; | ||
158 | |||
157 | /* band-pass filter */ | 159 | /* band-pass filter */ |
158 | if (LO_Frac < 188000000) | 160 | if (LO_Frac < 188000000) |
159 | BP_Filter = 3; | 161 | BP_Filter = 3; |
@@ -206,6 +208,14 @@ error: | |||
206 | return ret; | 208 | return ret; |
207 | } | 209 | } |
208 | 210 | ||
211 | static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
212 | { | ||
213 | struct tda18218_priv *priv = fe->tuner_priv; | ||
214 | *frequency = priv->if_frequency; | ||
215 | dbg("%s: if=%d", __func__, *frequency); | ||
216 | return 0; | ||
217 | } | ||
218 | |||
209 | static int tda18218_sleep(struct dvb_frontend *fe) | 219 | static int tda18218_sleep(struct dvb_frontend *fe) |
210 | { | 220 | { |
211 | struct tda18218_priv *priv = fe->tuner_priv; | 221 | struct tda18218_priv *priv = fe->tuner_priv; |
@@ -268,6 +278,8 @@ static const struct dvb_tuner_ops tda18218_tuner_ops = { | |||
268 | .sleep = tda18218_sleep, | 278 | .sleep = tda18218_sleep, |
269 | 279 | ||
270 | .set_params = tda18218_set_params, | 280 | .set_params = tda18218_set_params, |
281 | |||
282 | .get_if_frequency = tda18218_get_if_frequency, | ||
271 | }; | 283 | }; |
272 | 284 | ||
273 | struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, | 285 | struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/common/tuners/tda18218_priv.h index 904e5365c78c..dc52b72e1407 100644 --- a/drivers/media/common/tuners/tda18218_priv.h +++ b/drivers/media/common/tuners/tda18218_priv.h | |||
@@ -100,6 +100,8 @@ struct tda18218_priv { | |||
100 | struct tda18218_config *cfg; | 100 | struct tda18218_config *cfg; |
101 | struct i2c_adapter *i2c; | 101 | struct i2c_adapter *i2c; |
102 | 102 | ||
103 | u32 if_frequency; | ||
104 | |||
103 | u8 regs[TDA18218_NUM_REGS]; | 105 | u8 regs[TDA18218_NUM_REGS]; |
104 | }; | 106 | }; |
105 | 107 | ||
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 63cc4004e211..3347c5b488dd 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c | |||
@@ -994,6 +994,7 @@ static int tda18271_set_params(struct dvb_frontend *fe, | |||
994 | if (tda_fail(ret)) | 994 | if (tda_fail(ret)) |
995 | goto fail; | 995 | goto fail; |
996 | 996 | ||
997 | priv->if_freq = map->if_freq; | ||
997 | priv->frequency = freq; | 998 | priv->frequency = freq; |
998 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? | 999 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? |
999 | params->u.ofdm.bandwidth : 0; | 1000 | params->u.ofdm.bandwidth : 0; |
@@ -1050,6 +1051,7 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe, | |||
1050 | if (tda_fail(ret)) | 1051 | if (tda_fail(ret)) |
1051 | goto fail; | 1052 | goto fail; |
1052 | 1053 | ||
1054 | priv->if_freq = map->if_freq; | ||
1053 | priv->frequency = freq; | 1055 | priv->frequency = freq; |
1054 | priv->bandwidth = 0; | 1056 | priv->bandwidth = 0; |
1055 | fail: | 1057 | fail: |
@@ -1086,6 +1088,13 @@ static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
1086 | return 0; | 1088 | return 0; |
1087 | } | 1089 | } |
1088 | 1090 | ||
1091 | static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
1092 | { | ||
1093 | struct tda18271_priv *priv = fe->tuner_priv; | ||
1094 | *frequency = (u32)priv->if_freq * 1000; | ||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1089 | /* ------------------------------------------------------------------ */ | 1098 | /* ------------------------------------------------------------------ */ |
1090 | 1099 | ||
1091 | #define tda18271_update_std(std_cfg, name) do { \ | 1100 | #define tda18271_update_std(std_cfg, name) do { \ |
@@ -1245,6 +1254,7 @@ static const struct dvb_tuner_ops tda18271_tuner_ops = { | |||
1245 | .set_config = tda18271_set_config, | 1254 | .set_config = tda18271_set_config, |
1246 | .get_frequency = tda18271_get_frequency, | 1255 | .get_frequency = tda18271_get_frequency, |
1247 | .get_bandwidth = tda18271_get_bandwidth, | 1256 | .get_bandwidth = tda18271_get_bandwidth, |
1257 | .get_if_frequency = tda18271_get_if_frequency, | ||
1248 | }; | 1258 | }; |
1249 | 1259 | ||
1250 | struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, | 1260 | struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, |
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 94340f47562b..454c152ccaa0 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h | |||
@@ -122,6 +122,8 @@ struct tda18271_priv { | |||
122 | 122 | ||
123 | struct mutex lock; | 123 | struct mutex lock; |
124 | 124 | ||
125 | u16 if_freq; | ||
126 | |||
125 | u32 frequency; | 127 | u32 frequency; |
126 | u32 bandwidth; | 128 | u32 bandwidth; |
127 | }; | 129 | }; |
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index f8ee29e6059c..4092200c148e 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
@@ -751,6 +751,17 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
751 | if (4 != rc) | 751 | if (4 != rc) |
752 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); | 752 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); |
753 | 753 | ||
754 | /* Write AUX byte */ | ||
755 | switch (priv->type) { | ||
756 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
757 | buffer[2] = 0x98; | ||
758 | buffer[3] = 0x20; /* set TOP AGC */ | ||
759 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); | ||
760 | if (4 != rc) | ||
761 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); | ||
762 | break; | ||
763 | } | ||
764 | |||
754 | return 0; | 765 | return 0; |
755 | } | 766 | } |
756 | 767 | ||
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 3acbaa04e1b3..e531267babce 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -891,7 +891,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
891 | 891 | ||
892 | /* Frequency is locked */ | 892 | /* Frequency is locked */ |
893 | if (frq_lock == 1) | 893 | if (frq_lock == 1) |
894 | signal = 32768; | 894 | signal = 1 << 11; |
895 | 895 | ||
896 | /* Get SNR of the video signal */ | 896 | /* Get SNR of the video signal */ |
897 | rc = xc2028_get_reg(priv, 0x0040, &signal); | 897 | rc = xc2028_get_reg(priv, 0x0040, &signal); |
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index aa1b2e844d32..5c56d3cc030b 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -628,20 +628,14 @@ static void xc_debug_dump(struct xc5000_priv *priv) | |||
628 | dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); | 628 | dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); |
629 | } | 629 | } |
630 | 630 | ||
631 | /* | ||
632 | * As defined on EN 300 429, the DVB-C roll-off factor is 0.15. | ||
633 | * So, the amount of the needed bandwith is given by: | ||
634 | * Bw = Symbol_rate * (1 + 0.15) | ||
635 | * As such, the maximum symbol rate supported by 6 MHz is given by: | ||
636 | * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds | ||
637 | */ | ||
638 | #define MAX_SYMBOL_RATE_6MHz 5217391 | ||
639 | |||
640 | static int xc5000_set_params(struct dvb_frontend *fe, | 631 | static int xc5000_set_params(struct dvb_frontend *fe, |
641 | struct dvb_frontend_parameters *params) | 632 | struct dvb_frontend_parameters *params) |
642 | { | 633 | { |
634 | int ret, b; | ||
643 | struct xc5000_priv *priv = fe->tuner_priv; | 635 | struct xc5000_priv *priv = fe->tuner_priv; |
644 | int ret; | 636 | u32 bw = fe->dtv_property_cache.bandwidth_hz; |
637 | u32 freq = fe->dtv_property_cache.frequency; | ||
638 | u32 delsys = fe->dtv_property_cache.delivery_system; | ||
645 | 639 | ||
646 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { | 640 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { |
647 | if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { | 641 | if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { |
@@ -650,88 +644,77 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
650 | } | 644 | } |
651 | } | 645 | } |
652 | 646 | ||
653 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); | 647 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, freq); |
654 | 648 | ||
655 | if (fe->ops.info.type == FE_ATSC) { | 649 | switch (delsys) { |
656 | dprintk(1, "%s() ATSC\n", __func__); | 650 | case SYS_ATSC: |
657 | switch (params->u.vsb.modulation) { | 651 | dprintk(1, "%s() VSB modulation\n", __func__); |
658 | case VSB_8: | 652 | priv->rf_mode = XC_RF_MODE_AIR; |
659 | case VSB_16: | 653 | priv->freq_hz = freq - 1750000; |
660 | dprintk(1, "%s() VSB modulation\n", __func__); | 654 | priv->bandwidth = BANDWIDTH_6_MHZ; |
661 | priv->rf_mode = XC_RF_MODE_AIR; | 655 | priv->video_standard = DTV6; |
662 | priv->freq_hz = params->frequency - 1750000; | 656 | break; |
663 | priv->bandwidth = BANDWIDTH_6_MHZ; | 657 | case SYS_DVBC_ANNEX_B: |
664 | priv->video_standard = DTV6; | 658 | dprintk(1, "%s() QAM modulation\n", __func__); |
665 | break; | 659 | priv->rf_mode = XC_RF_MODE_CABLE; |
666 | case QAM_64: | 660 | priv->freq_hz = freq - 1750000; |
667 | case QAM_256: | 661 | priv->bandwidth = BANDWIDTH_6_MHZ; |
668 | case QAM_AUTO: | 662 | priv->video_standard = DTV6; |
669 | dprintk(1, "%s() QAM modulation\n", __func__); | 663 | break; |
670 | priv->rf_mode = XC_RF_MODE_CABLE; | 664 | case SYS_DVBT: |
671 | priv->freq_hz = params->frequency - 1750000; | 665 | case SYS_DVBT2: |
672 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
673 | priv->video_standard = DTV6; | ||
674 | break; | ||
675 | default: | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | } else if (fe->ops.info.type == FE_OFDM) { | ||
679 | dprintk(1, "%s() OFDM\n", __func__); | 666 | dprintk(1, "%s() OFDM\n", __func__); |
680 | switch (params->u.ofdm.bandwidth) { | 667 | switch (bw) { |
681 | case BANDWIDTH_6_MHZ: | 668 | case 6000000: |
682 | priv->bandwidth = BANDWIDTH_6_MHZ; | 669 | priv->bandwidth = BANDWIDTH_6_MHZ; |
683 | priv->video_standard = DTV6; | 670 | priv->video_standard = DTV6; |
684 | priv->freq_hz = params->frequency - 1750000; | 671 | priv->freq_hz = freq - 1750000; |
685 | break; | 672 | break; |
686 | case BANDWIDTH_7_MHZ: | 673 | case 7000000: |
687 | printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n"); | 674 | priv->bandwidth = BANDWIDTH_7_MHZ; |
688 | return -EINVAL; | 675 | priv->video_standard = DTV7; |
689 | case BANDWIDTH_8_MHZ: | 676 | priv->freq_hz = freq - 2250000; |
677 | break; | ||
678 | case 8000000: | ||
690 | priv->bandwidth = BANDWIDTH_8_MHZ; | 679 | priv->bandwidth = BANDWIDTH_8_MHZ; |
691 | priv->video_standard = DTV8; | 680 | priv->video_standard = DTV8; |
692 | priv->freq_hz = params->frequency - 2750000; | 681 | priv->freq_hz = freq - 2750000; |
693 | break; | 682 | break; |
694 | default: | 683 | default: |
695 | printk(KERN_ERR "xc5000 bandwidth not set!\n"); | 684 | printk(KERN_ERR "xc5000 bandwidth not set!\n"); |
696 | return -EINVAL; | 685 | return -EINVAL; |
697 | } | 686 | } |
698 | priv->rf_mode = XC_RF_MODE_AIR; | 687 | priv->rf_mode = XC_RF_MODE_AIR; |
699 | } else if (fe->ops.info.type == FE_QAM) { | 688 | case SYS_DVBC_ANNEX_A: |
700 | switch (params->u.qam.modulation) { | 689 | case SYS_DVBC_ANNEX_C: |
701 | case QAM_256: | 690 | dprintk(1, "%s() QAM modulation\n", __func__); |
702 | case QAM_AUTO: | 691 | priv->rf_mode = XC_RF_MODE_CABLE; |
703 | case QAM_16: | 692 | if (bw <= 6000000) { |
704 | case QAM_32: | 693 | priv->bandwidth = BANDWIDTH_6_MHZ; |
705 | case QAM_64: | 694 | priv->video_standard = DTV6; |
706 | case QAM_128: | 695 | priv->freq_hz = freq - 1750000; |
707 | dprintk(1, "%s() QAM modulation\n", __func__); | 696 | b = 6; |
708 | priv->rf_mode = XC_RF_MODE_CABLE; | 697 | } else if (bw <= 7000000) { |
709 | /* | 698 | priv->bandwidth = BANDWIDTH_7_MHZ; |
710 | * Using a 8MHz bandwidth sometimes fail | 699 | priv->video_standard = DTV7; |
711 | * with 6MHz-spaced channels, due to inter-carrier | 700 | priv->freq_hz = freq - 2250000; |
712 | * interference. So, use DTV6 firmware | 701 | b = 7; |
713 | */ | 702 | } else { |
714 | if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) { | 703 | priv->bandwidth = BANDWIDTH_8_MHZ; |
715 | priv->bandwidth = BANDWIDTH_6_MHZ; | 704 | priv->video_standard = DTV7_8; |
716 | priv->video_standard = DTV6; | 705 | priv->freq_hz = freq - 2750000; |
717 | priv->freq_hz = params->frequency - 1750000; | 706 | b = 8; |
718 | } else { | ||
719 | priv->bandwidth = BANDWIDTH_8_MHZ; | ||
720 | priv->video_standard = DTV7_8; | ||
721 | priv->freq_hz = params->frequency - 2750000; | ||
722 | } | ||
723 | break; | ||
724 | default: | ||
725 | dprintk(1, "%s() Unsupported QAM type\n", __func__); | ||
726 | return -EINVAL; | ||
727 | } | 707 | } |
728 | } else { | 708 | dprintk(1, "%s() Bandwidth %dMHz (%d)\n", __func__, |
729 | printk(KERN_ERR "xc5000 modulation type not supported!\n"); | 709 | b, bw); |
710 | break; | ||
711 | default: | ||
712 | printk(KERN_ERR "xc5000: delivery system is not supported!\n"); | ||
730 | return -EINVAL; | 713 | return -EINVAL; |
731 | } | 714 | } |
732 | 715 | ||
733 | dprintk(1, "%s() frequency=%d (compensated)\n", | 716 | dprintk(1, "%s() frequency=%d (compensated to %d)\n", |
734 | __func__, priv->freq_hz); | 717 | __func__, freq, priv->freq_hz); |
735 | 718 | ||
736 | ret = xc_SetSignalSource(priv, priv->rf_mode); | 719 | ret = xc_SetSignalSource(priv, priv->rf_mode); |
737 | if (ret != XC_RESULT_SUCCESS) { | 720 | if (ret != XC_RESULT_SUCCESS) { |
@@ -968,6 +951,14 @@ static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) | |||
968 | return 0; | 951 | return 0; |
969 | } | 952 | } |
970 | 953 | ||
954 | static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq) | ||
955 | { | ||
956 | struct xc5000_priv *priv = fe->tuner_priv; | ||
957 | dprintk(1, "%s()\n", __func__); | ||
958 | *freq = priv->if_khz * 1000; | ||
959 | return 0; | ||
960 | } | ||
961 | |||
971 | static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw) | 962 | static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw) |
972 | { | 963 | { |
973 | struct xc5000_priv *priv = fe->tuner_priv; | 964 | struct xc5000_priv *priv = fe->tuner_priv; |
@@ -1108,6 +1099,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { | |||
1108 | .set_params = xc5000_set_params, | 1099 | .set_params = xc5000_set_params, |
1109 | .set_analog_params = xc5000_set_analog_params, | 1100 | .set_analog_params = xc5000_set_analog_params, |
1110 | .get_frequency = xc5000_get_frequency, | 1101 | .get_frequency = xc5000_get_frequency, |
1102 | .get_if_frequency = xc5000_get_if_frequency, | ||
1111 | .get_bandwidth = xc5000_get_bandwidth, | 1103 | .get_bandwidth = xc5000_get_bandwidth, |
1112 | .get_status = xc5000_get_status | 1104 | .get_status = xc5000_get_status |
1113 | }; | 1105 | }; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 2c0acdb4d811..66537b10132c 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -876,6 +876,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) | |||
876 | c->symbol_rate = QAM_AUTO; | 876 | c->symbol_rate = QAM_AUTO; |
877 | c->code_rate_HP = FEC_AUTO; | 877 | c->code_rate_HP = FEC_AUTO; |
878 | c->code_rate_LP = FEC_AUTO; | 878 | c->code_rate_LP = FEC_AUTO; |
879 | c->rolloff = ROLLOFF_AUTO; | ||
879 | 880 | ||
880 | c->isdbt_partial_reception = -1; | 881 | c->isdbt_partial_reception = -1; |
881 | c->isdbt_sb_mode = -1; | 882 | c->isdbt_sb_mode = -1; |
@@ -973,6 +974,8 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { | |||
973 | _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0), | 974 | _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0), |
974 | _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0), | 975 | _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0), |
975 | _DTV_CMD(DTV_HIERARCHY, 0, 0), | 976 | _DTV_CMD(DTV_HIERARCHY, 0, 0), |
977 | |||
978 | _DTV_CMD(DTV_ENUM_DELSYS, 0, 0), | ||
976 | }; | 979 | }; |
977 | 980 | ||
978 | static void dtv_property_dump(struct dtv_property *tvp) | 981 | static void dtv_property_dump(struct dtv_property *tvp) |
@@ -1008,7 +1011,7 @@ static void dtv_property_dump(struct dtv_property *tvp) | |||
1008 | 1011 | ||
1009 | static int is_legacy_delivery_system(fe_delivery_system_t s) | 1012 | static int is_legacy_delivery_system(fe_delivery_system_t s) |
1010 | { | 1013 | { |
1011 | if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || | 1014 | if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_A) || |
1012 | (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) || | 1015 | (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) || |
1013 | (s == SYS_ATSC)) | 1016 | (s == SYS_ATSC)) |
1014 | return 1; | 1017 | return 1; |
@@ -1029,7 +1032,7 @@ static void dtv_property_cache_init(struct dvb_frontend *fe, | |||
1029 | c->delivery_system = SYS_DVBS; | 1032 | c->delivery_system = SYS_DVBS; |
1030 | break; | 1033 | break; |
1031 | case FE_QAM: | 1034 | case FE_QAM: |
1032 | c->delivery_system = SYS_DVBC_ANNEX_AC; | 1035 | c->delivery_system = SYS_DVBC_ANNEX_A; |
1033 | break; | 1036 | break; |
1034 | case FE_OFDM: | 1037 | case FE_OFDM: |
1035 | c->delivery_system = SYS_DVBT; | 1038 | c->delivery_system = SYS_DVBT; |
@@ -1140,9 +1143,10 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe) | |||
1140 | */ | 1143 | */ |
1141 | static void dtv_property_adv_params_sync(struct dvb_frontend *fe) | 1144 | static void dtv_property_adv_params_sync(struct dvb_frontend *fe) |
1142 | { | 1145 | { |
1143 | const struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1146 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
1144 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1147 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1145 | struct dvb_frontend_parameters *p = &fepriv->parameters_in; | 1148 | struct dvb_frontend_parameters *p = &fepriv->parameters_in; |
1149 | u32 rolloff = 0; | ||
1146 | 1150 | ||
1147 | p->frequency = c->frequency; | 1151 | p->frequency = c->frequency; |
1148 | p->inversion = c->inversion; | 1152 | p->inversion = c->inversion; |
@@ -1174,6 +1178,23 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe) | |||
1174 | else | 1178 | else |
1175 | p->u.ofdm.bandwidth = BANDWIDTH_AUTO; | 1179 | p->u.ofdm.bandwidth = BANDWIDTH_AUTO; |
1176 | } | 1180 | } |
1181 | |||
1182 | /* | ||
1183 | * On DVB-C, the bandwidth is a function of roll-off and symbol rate. | ||
1184 | * The bandwidth is required for DVB-C tuners, in order to avoid | ||
1185 | * inter-channel noise. Instead of estimating the minimal required | ||
1186 | * bandwidth on every single driver, calculates it here and fills | ||
1187 | * it at the cache bandwidth parameter. | ||
1188 | * While not officially supported, a side effect of handling it at | ||
1189 | * the cache level is that a program could retrieve the bandwidth | ||
1190 | * via DTV_BANDWIDTH_HZ, wich may be useful for test programs. | ||
1191 | */ | ||
1192 | if (c->delivery_system == SYS_DVBC_ANNEX_A) | ||
1193 | rolloff = 115; | ||
1194 | if (c->delivery_system == SYS_DVBC_ANNEX_C) | ||
1195 | rolloff = 113; | ||
1196 | if (rolloff) | ||
1197 | c->bandwidth_hz = (c->symbol_rate * rolloff) / 100; | ||
1177 | } | 1198 | } |
1178 | 1199 | ||
1179 | static void dtv_property_cache_submit(struct dvb_frontend *fe) | 1200 | static void dtv_property_cache_submit(struct dvb_frontend *fe) |
@@ -1207,6 +1228,37 @@ static int dvb_frontend_ioctl_legacy(struct file *file, | |||
1207 | static int dvb_frontend_ioctl_properties(struct file *file, | 1228 | static int dvb_frontend_ioctl_properties(struct file *file, |
1208 | unsigned int cmd, void *parg); | 1229 | unsigned int cmd, void *parg); |
1209 | 1230 | ||
1231 | static void dtv_set_default_delivery_caps(const struct dvb_frontend *fe, struct dtv_property *p) | ||
1232 | { | ||
1233 | const struct dvb_frontend_info *info = &fe->ops.info; | ||
1234 | u32 ncaps = 0; | ||
1235 | |||
1236 | switch (info->type) { | ||
1237 | case FE_QPSK: | ||
1238 | p->u.buffer.data[ncaps++] = SYS_DVBS; | ||
1239 | if (info->caps & FE_CAN_2G_MODULATION) | ||
1240 | p->u.buffer.data[ncaps++] = SYS_DVBS2; | ||
1241 | if (info->caps & FE_CAN_TURBO_FEC) | ||
1242 | p->u.buffer.data[ncaps++] = SYS_TURBO; | ||
1243 | break; | ||
1244 | case FE_QAM: | ||
1245 | p->u.buffer.data[ncaps++] = SYS_DVBC_ANNEX_AC; | ||
1246 | break; | ||
1247 | case FE_OFDM: | ||
1248 | p->u.buffer.data[ncaps++] = SYS_DVBT; | ||
1249 | if (info->caps & FE_CAN_2G_MODULATION) | ||
1250 | p->u.buffer.data[ncaps++] = SYS_DVBT2; | ||
1251 | break; | ||
1252 | case FE_ATSC: | ||
1253 | if (info->caps & (FE_CAN_8VSB | FE_CAN_16VSB)) | ||
1254 | p->u.buffer.data[ncaps++] = SYS_ATSC; | ||
1255 | if (info->caps & (FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256)) | ||
1256 | p->u.buffer.data[ncaps++] = SYS_DVBC_ANNEX_B; | ||
1257 | break; | ||
1258 | } | ||
1259 | p->u.buffer.len = ncaps; | ||
1260 | } | ||
1261 | |||
1210 | static int dtv_property_process_get(struct dvb_frontend *fe, | 1262 | static int dtv_property_process_get(struct dvb_frontend *fe, |
1211 | struct dtv_property *tvp, | 1263 | struct dtv_property *tvp, |
1212 | struct file *file) | 1264 | struct file *file) |
@@ -1227,6 +1279,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe, | |||
1227 | } | 1279 | } |
1228 | 1280 | ||
1229 | switch(tvp->cmd) { | 1281 | switch(tvp->cmd) { |
1282 | case DTV_ENUM_DELSYS: | ||
1283 | dtv_set_default_delivery_caps(fe, tvp); | ||
1284 | break; | ||
1230 | case DTV_FREQUENCY: | 1285 | case DTV_FREQUENCY: |
1231 | tvp->u.data = c->frequency; | 1286 | tvp->u.data = c->frequency; |
1232 | break; | 1287 | break; |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 58257165761e..9f203c6767a6 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -311,6 +311,7 @@ config DVB_USB_ANYSEE | |||
311 | select DVB_STV0900 if !DVB_FE_CUSTOMISE | 311 | select DVB_STV0900 if !DVB_FE_CUSTOMISE |
312 | select DVB_STV6110 if !DVB_FE_CUSTOMISE | 312 | select DVB_STV6110 if !DVB_FE_CUSTOMISE |
313 | select DVB_ISL6423 if !DVB_FE_CUSTOMISE | 313 | select DVB_ISL6423 if !DVB_FE_CUSTOMISE |
314 | select DVB_CXD2820R if !DVB_FE_CUSTOMISE | ||
314 | help | 315 | help |
315 | Say Y here to support the Anysee E30, Anysee E30 Plus or | 316 | Say Y here to support the Anysee E30, Anysee E30 Plus or |
316 | Anysee E30 C Plus DVB USB2.0 receiver. | 317 | Anysee E30 C Plus DVB USB2.0 receiver. |
@@ -340,7 +341,7 @@ config DVB_USB_AF9015 | |||
340 | 341 | ||
341 | config DVB_USB_CE6230 | 342 | config DVB_USB_CE6230 |
342 | tristate "Intel CE6230 DVB-T USB2.0 support" | 343 | tristate "Intel CE6230 DVB-T USB2.0 support" |
343 | depends on DVB_USB && EXPERIMENTAL | 344 | depends on DVB_USB |
344 | select DVB_ZL10353 | 345 | select DVB_ZL10353 |
345 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 346 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
346 | help | 347 | help |
@@ -354,7 +355,7 @@ config DVB_USB_FRIIO | |||
354 | 355 | ||
355 | config DVB_USB_EC168 | 356 | config DVB_USB_EC168 |
356 | tristate "E3C EC168 DVB-T USB2.0 support" | 357 | tristate "E3C EC168 DVB-T USB2.0 support" |
357 | depends on DVB_USB && EXPERIMENTAL | 358 | depends on DVB_USB |
358 | select DVB_EC100 | 359 | select DVB_EC100 |
359 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 360 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
360 | help | 361 | help |
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 5f2278b73ee9..df46015d077a 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "stv0900.h" | 41 | #include "stv0900.h" |
42 | #include "stv6110.h" | 42 | #include "stv6110.h" |
43 | #include "isl6423.h" | 43 | #include "isl6423.h" |
44 | #include "cxd2820r.h" | ||
44 | 45 | ||
45 | /* debug */ | 46 | /* debug */ |
46 | static int dvb_usb_anysee_debug; | 47 | static int dvb_usb_anysee_debug; |
@@ -66,10 +67,12 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, | |||
66 | if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) | 67 | if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) |
67 | return -EAGAIN; | 68 | return -EAGAIN; |
68 | 69 | ||
70 | deb_xfer(">>> "); | ||
71 | debug_dump(buf, slen, deb_xfer); | ||
72 | |||
69 | /* We need receive one message more after dvb_usb_generic_rw due | 73 | /* We need receive one message more after dvb_usb_generic_rw due |
70 | to weird transaction flow, which is 1 x send + 2 x receive. */ | 74 | to weird transaction flow, which is 1 x send + 2 x receive. */ |
71 | ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); | 75 | ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); |
72 | |||
73 | if (!ret) { | 76 | if (!ret) { |
74 | /* receive 2nd answer */ | 77 | /* receive 2nd answer */ |
75 | ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, | 78 | ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, |
@@ -79,7 +82,10 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, | |||
79 | err("%s: recv bulk message failed: %d", __func__, ret); | 82 | err("%s: recv bulk message failed: %d", __func__, ret); |
80 | else { | 83 | else { |
81 | deb_xfer("<<< "); | 84 | deb_xfer("<<< "); |
82 | debug_dump(buf, act_len, deb_xfer); | 85 | debug_dump(buf, rlen, deb_xfer); |
86 | |||
87 | if (buf[63] != 0x4f) | ||
88 | deb_info("%s: cmd failed\n", __func__); | ||
83 | } | 89 | } |
84 | } | 90 | } |
85 | 91 | ||
@@ -129,6 +135,29 @@ static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val, | |||
129 | return anysee_write_reg(d, reg, val); | 135 | return anysee_write_reg(d, reg, val); |
130 | } | 136 | } |
131 | 137 | ||
138 | /* read single register with mask */ | ||
139 | static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val, | ||
140 | u8 mask) | ||
141 | { | ||
142 | int ret, i; | ||
143 | u8 tmp; | ||
144 | |||
145 | ret = anysee_read_reg(d, reg, &tmp); | ||
146 | if (ret) | ||
147 | return ret; | ||
148 | |||
149 | tmp &= mask; | ||
150 | |||
151 | /* find position of the first bit */ | ||
152 | for (i = 0; i < 8; i++) { | ||
153 | if ((mask >> i) & 0x01) | ||
154 | break; | ||
155 | } | ||
156 | *val = tmp >> i; | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
132 | static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) | 161 | static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) |
133 | { | 162 | { |
134 | u8 buf[] = {CMD_GET_HW_INFO}; | 163 | u8 buf[] = {CMD_GET_HW_INFO}; |
@@ -156,22 +185,6 @@ static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff) | |||
156 | return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); | 185 | return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); |
157 | } | 186 | } |
158 | 187 | ||
159 | static int anysee_init(struct dvb_usb_device *d) | ||
160 | { | ||
161 | int ret; | ||
162 | /* LED light */ | ||
163 | ret = anysee_led_ctrl(d, 0x01, 0x03); | ||
164 | if (ret) | ||
165 | return ret; | ||
166 | |||
167 | /* enable IR */ | ||
168 | ret = anysee_ir_ctrl(d, 1); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | /* I2C */ | 188 | /* I2C */ |
176 | static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, | 189 | static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, |
177 | int num) | 190 | int num) |
@@ -297,7 +310,7 @@ static struct tda10023_config anysee_tda10023_tda18212_config = { | |||
297 | .pll_m = 12, | 310 | .pll_m = 12, |
298 | .pll_p = 3, | 311 | .pll_p = 3, |
299 | .pll_n = 1, | 312 | .pll_n = 1, |
300 | .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, | 313 | .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B, |
301 | .deltaf = 0xba02, | 314 | .deltaf = 0xba02, |
302 | }; | 315 | }; |
303 | 316 | ||
@@ -309,6 +322,17 @@ static struct tda18212_config anysee_tda18212_config = { | |||
309 | .if_dvbc = 5000, | 322 | .if_dvbc = 5000, |
310 | }; | 323 | }; |
311 | 324 | ||
325 | static struct tda18212_config anysee_tda18212_config2 = { | ||
326 | .i2c_address = 0x60 /* (0xc0 >> 1) */, | ||
327 | .if_dvbt_6 = 3550, | ||
328 | .if_dvbt_7 = 3700, | ||
329 | .if_dvbt_8 = 4150, | ||
330 | .if_dvbt2_6 = 3250, | ||
331 | .if_dvbt2_7 = 4000, | ||
332 | .if_dvbt2_8 = 4000, | ||
333 | .if_dvbc = 5000, | ||
334 | }; | ||
335 | |||
312 | static struct cx24116_config anysee_cx24116_config = { | 336 | static struct cx24116_config anysee_cx24116_config = { |
313 | .demod_address = (0xaa >> 1), | 337 | .demod_address = (0xaa >> 1), |
314 | .mpg_clk_pos_pol = 0x00, | 338 | .mpg_clk_pos_pol = 0x00, |
@@ -339,6 +363,11 @@ static struct isl6423_config anysee_isl6423_config = { | |||
339 | .addr = (0x10 >> 1), | 363 | .addr = (0x10 >> 1), |
340 | }; | 364 | }; |
341 | 365 | ||
366 | static struct cxd2820r_config anysee_cxd2820r_config = { | ||
367 | .i2c_address = 0x6d, /* (0xda >> 1) */ | ||
368 | .ts_mode = 0x38, | ||
369 | }; | ||
370 | |||
342 | /* | 371 | /* |
343 | * New USB device strings: Mfr=1, Product=2, SerialNumber=0 | 372 | * New USB device strings: Mfr=1, Product=2, SerialNumber=0 |
344 | * Manufacturer: AMT.CO.KR | 373 | * Manufacturer: AMT.CO.KR |
@@ -421,6 +450,14 @@ static struct isl6423_config anysee_isl6423_config = { | |||
421 | * IOA[7] TS 1=enabled | 450 | * IOA[7] TS 1=enabled |
422 | * IOE[5] STV0903 1=enabled | 451 | * IOE[5] STV0903 1=enabled |
423 | * | 452 | * |
453 | * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)" | ||
454 | * PCB: 508T2C (rev0.3) | ||
455 | * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024 | ||
456 | * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff | ||
457 | * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 | ||
458 | * IOA[7] TS 1=enabled | ||
459 | * IOE[5] CXD2820R 1=enabled | ||
460 | * | ||
424 | * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" | 461 | * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" |
425 | * PCB: 508PTC (rev0.5) | 462 | * PCB: 508PTC (rev0.5) |
426 | * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) | 463 | * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) |
@@ -437,7 +474,7 @@ static struct isl6423_config anysee_isl6423_config = { | |||
437 | * IOD[6] ZL10353 1=enabled | 474 | * IOD[6] ZL10353 1=enabled |
438 | * IOE[0] IF 0=enabled | 475 | * IOE[0] IF 0=enabled |
439 | * | 476 | * |
440 | * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" | 477 | * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" |
441 | * PCB: 508PS2 (rev0.4) | 478 | * PCB: 508PS2 (rev0.4) |
442 | * parts: DNBU10512IST(STV0903, STV6110), ISL6423 | 479 | * parts: DNBU10512IST(STV0903, STV6110), ISL6423 |
443 | * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff | 480 | * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff |
@@ -446,6 +483,16 @@ static struct isl6423_config anysee_isl6423_config = { | |||
446 | * IOE[5] STV0903 1=enabled | 483 | * IOE[5] STV0903 1=enabled |
447 | */ | 484 | */ |
448 | 485 | ||
486 | |||
487 | /* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */ | ||
488 | static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
489 | { | ||
490 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
491 | |||
492 | /* enable / disable tuner access on IOE[4] */ | ||
493 | return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10); | ||
494 | } | ||
495 | |||
449 | static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) | 496 | static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) |
450 | { | 497 | { |
451 | struct dvb_usb_adapter *adap = fe->dvb->priv; | 498 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
@@ -577,7 +624,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
577 | /* detect hardware only once */ | 624 | /* detect hardware only once */ |
578 | if (adap->fe_adap[0].fe == NULL) { | 625 | if (adap->fe_adap[0].fe == NULL) { |
579 | /* Check which hardware we have. | 626 | /* Check which hardware we have. |
580 | * We must do this call two times to get reliable values (hw bug). | 627 | * We must do this call two times to get reliable values |
628 | * (hw/fw bug). | ||
581 | */ | 629 | */ |
582 | ret = anysee_get_hw_info(adap->dev, hw_info); | 630 | ret = anysee_get_hw_info(adap->dev, hw_info); |
583 | if (ret) | 631 | if (ret) |
@@ -606,14 +654,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
606 | break; | 654 | break; |
607 | 655 | ||
608 | /* attach demod */ | 656 | /* attach demod */ |
609 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config, | 657 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, |
610 | &adap->dev->i2c_adap); | 658 | &anysee_mt352_config, &adap->dev->i2c_adap); |
611 | if (adap->fe_adap[0].fe) | 659 | if (adap->fe_adap[0].fe) |
612 | break; | 660 | break; |
613 | 661 | ||
614 | /* attach demod */ | 662 | /* attach demod */ |
615 | adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, | 663 | adap->fe_adap[0].fe = dvb_attach(zl10353_attach, |
616 | &adap->dev->i2c_adap); | 664 | &anysee_zl10353_config, &adap->dev->i2c_adap); |
617 | 665 | ||
618 | break; | 666 | break; |
619 | case ANYSEE_HW_507CD: /* 6 */ | 667 | case ANYSEE_HW_507CD: /* 6 */ |
@@ -665,8 +713,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
665 | goto error; | 713 | goto error; |
666 | 714 | ||
667 | /* attach demod */ | 715 | /* attach demod */ |
668 | adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, | 716 | adap->fe_adap[0].fe = dvb_attach(cx24116_attach, |
669 | &adap->dev->i2c_adap); | 717 | &anysee_cx24116_config, &adap->dev->i2c_adap); |
670 | 718 | ||
671 | break; | 719 | break; |
672 | case ANYSEE_HW_507FA: /* 15 */ | 720 | case ANYSEE_HW_507FA: /* 15 */ |
@@ -747,17 +795,19 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
747 | } | 795 | } |
748 | } | 796 | } |
749 | 797 | ||
798 | /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ | ||
799 | if (tmp == 0xc7) { | ||
800 | if (adap->fe_adap[state->fe_id].fe) | ||
801 | adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = | ||
802 | anysee_i2c_gate_ctrl; | ||
803 | } | ||
804 | |||
750 | break; | 805 | break; |
751 | case ANYSEE_HW_508TC: /* 18 */ | 806 | case ANYSEE_HW_508TC: /* 18 */ |
752 | case ANYSEE_HW_508PTC: /* 21 */ | 807 | case ANYSEE_HW_508PTC: /* 21 */ |
753 | /* E7 TC */ | 808 | /* E7 TC */ |
754 | /* E7 PTC */ | 809 | /* E7 PTC */ |
755 | 810 | ||
756 | /* enable transport stream on IOA[7] */ | ||
757 | ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); | ||
758 | if (ret) | ||
759 | goto error; | ||
760 | |||
761 | if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { | 811 | if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { |
762 | /* disable DVB-T demod on IOD[6] */ | 812 | /* disable DVB-T demod on IOD[6] */ |
763 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), | 813 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), |
@@ -772,7 +822,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
772 | goto error; | 822 | goto error; |
773 | 823 | ||
774 | /* attach demod */ | 824 | /* attach demod */ |
775 | adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach, | 825 | adap->fe_adap[state->fe_id].fe = |
826 | dvb_attach(tda10023_attach, | ||
776 | &anysee_tda10023_tda18212_config, | 827 | &anysee_tda10023_tda18212_config, |
777 | &adap->dev->i2c_adap, 0x48); | 828 | &adap->dev->i2c_adap, 0x48); |
778 | } else { | 829 | } else { |
@@ -789,11 +840,19 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
789 | goto error; | 840 | goto error; |
790 | 841 | ||
791 | /* attach demod */ | 842 | /* attach demod */ |
792 | adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach, | 843 | adap->fe_adap[state->fe_id].fe = |
844 | dvb_attach(zl10353_attach, | ||
793 | &anysee_zl10353_tda18212_config, | 845 | &anysee_zl10353_tda18212_config, |
794 | &adap->dev->i2c_adap); | 846 | &adap->dev->i2c_adap); |
795 | } | 847 | } |
796 | 848 | ||
849 | /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ | ||
850 | if (adap->fe_adap[state->fe_id].fe) | ||
851 | adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = | ||
852 | anysee_i2c_gate_ctrl; | ||
853 | |||
854 | state->has_ci = true; | ||
855 | |||
797 | break; | 856 | break; |
798 | case ANYSEE_HW_508S2: /* 19 */ | 857 | case ANYSEE_HW_508S2: /* 19 */ |
799 | case ANYSEE_HW_508PS2: /* 22 */ | 858 | case ANYSEE_HW_508PS2: /* 22 */ |
@@ -803,19 +862,41 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
803 | if (state->fe_id) | 862 | if (state->fe_id) |
804 | break; | 863 | break; |
805 | 864 | ||
806 | /* enable transport stream on IOA[7] */ | 865 | /* enable DVB-S/S2 demod on IOE[5] */ |
807 | ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); | 866 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); |
808 | if (ret) | 867 | if (ret) |
809 | goto error; | 868 | goto error; |
810 | 869 | ||
811 | /* enable DVB-S/S2 demod on IOE[5] */ | 870 | /* attach demod */ |
871 | adap->fe_adap[0].fe = dvb_attach(stv0900_attach, | ||
872 | &anysee_stv0900_config, &adap->dev->i2c_adap, 0); | ||
873 | |||
874 | state->has_ci = true; | ||
875 | |||
876 | break; | ||
877 | case ANYSEE_HW_508T2C: /* 20 */ | ||
878 | /* E7 T2C */ | ||
879 | |||
880 | /* enable DVB-T/T2/C demod on IOE[5] */ | ||
812 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); | 881 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); |
813 | if (ret) | 882 | if (ret) |
814 | goto error; | 883 | goto error; |
815 | 884 | ||
816 | /* attach demod */ | 885 | if (state->fe_id == 0) { |
817 | adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, | 886 | /* DVB-T/T2 */ |
818 | &adap->dev->i2c_adap, 0); | 887 | adap->fe_adap[state->fe_id].fe = |
888 | dvb_attach(cxd2820r_attach, | ||
889 | &anysee_cxd2820r_config, | ||
890 | &adap->dev->i2c_adap, NULL); | ||
891 | } else { | ||
892 | /* DVB-C */ | ||
893 | adap->fe_adap[state->fe_id].fe = | ||
894 | dvb_attach(cxd2820r_attach, | ||
895 | &anysee_cxd2820r_config, | ||
896 | &adap->dev->i2c_adap, adap->fe_adap[0].fe); | ||
897 | } | ||
898 | |||
899 | state->has_ci = true; | ||
819 | 900 | ||
820 | break; | 901 | break; |
821 | } | 902 | } |
@@ -842,24 +923,26 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | |||
842 | /* E30 */ | 923 | /* E30 */ |
843 | 924 | ||
844 | /* attach tuner */ | 925 | /* attach tuner */ |
845 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), | 926 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, |
846 | NULL, DVB_PLL_THOMSON_DTT7579); | 927 | (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579); |
847 | 928 | ||
848 | break; | 929 | break; |
849 | case ANYSEE_HW_507CD: /* 6 */ | 930 | case ANYSEE_HW_507CD: /* 6 */ |
850 | /* E30 Plus */ | 931 | /* E30 Plus */ |
851 | 932 | ||
852 | /* attach tuner */ | 933 | /* attach tuner */ |
853 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), | 934 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, |
854 | &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); | 935 | (0xc2 >> 1), &adap->dev->i2c_adap, |
936 | DVB_PLL_THOMSON_DTT7579); | ||
855 | 937 | ||
856 | break; | 938 | break; |
857 | case ANYSEE_HW_507DC: /* 10 */ | 939 | case ANYSEE_HW_507DC: /* 10 */ |
858 | /* E30 C Plus */ | 940 | /* E30 C Plus */ |
859 | 941 | ||
860 | /* attach tuner */ | 942 | /* attach tuner */ |
861 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1), | 943 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, |
862 | &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); | 944 | (0xc0 >> 1), &adap->dev->i2c_adap, |
945 | DVB_PLL_SAMSUNG_DTOS403IH102A); | ||
863 | 946 | ||
864 | break; | 947 | break; |
865 | case ANYSEE_HW_507SI: /* 11 */ | 948 | case ANYSEE_HW_507SI: /* 11 */ |
@@ -877,22 +960,12 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | |||
877 | /* Try first attach TDA18212 silicon tuner on IOE[4], if that | 960 | /* Try first attach TDA18212 silicon tuner on IOE[4], if that |
878 | * fails attach old simple PLL. */ | 961 | * fails attach old simple PLL. */ |
879 | 962 | ||
880 | /* enable tuner on IOE[4] */ | ||
881 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); | ||
882 | if (ret) | ||
883 | goto error; | ||
884 | |||
885 | /* attach tuner */ | 963 | /* attach tuner */ |
886 | fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, | 964 | fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, |
887 | &adap->dev->i2c_adap, &anysee_tda18212_config); | 965 | &adap->dev->i2c_adap, &anysee_tda18212_config); |
888 | if (fe) | 966 | if (fe) |
889 | break; | 967 | break; |
890 | 968 | ||
891 | /* disable tuner on IOE[4] */ | ||
892 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10); | ||
893 | if (ret) | ||
894 | goto error; | ||
895 | |||
896 | /* attach tuner */ | 969 | /* attach tuner */ |
897 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, | 970 | fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, |
898 | (0xc0 >> 1), &adap->dev->i2c_adap, | 971 | (0xc0 >> 1), &adap->dev->i2c_adap, |
@@ -904,11 +977,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | |||
904 | /* E7 TC */ | 977 | /* E7 TC */ |
905 | /* E7 PTC */ | 978 | /* E7 PTC */ |
906 | 979 | ||
907 | /* enable tuner on IOE[4] */ | ||
908 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); | ||
909 | if (ret) | ||
910 | goto error; | ||
911 | |||
912 | /* attach tuner */ | 980 | /* attach tuner */ |
913 | fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, | 981 | fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, |
914 | &adap->dev->i2c_adap, &anysee_tda18212_config); | 982 | &adap->dev->i2c_adap, &anysee_tda18212_config); |
@@ -930,6 +998,15 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | |||
930 | } | 998 | } |
931 | 999 | ||
932 | break; | 1000 | break; |
1001 | |||
1002 | case ANYSEE_HW_508T2C: /* 20 */ | ||
1003 | /* E7 T2C */ | ||
1004 | |||
1005 | /* attach tuner */ | ||
1006 | fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, | ||
1007 | &adap->dev->i2c_adap, &anysee_tda18212_config2); | ||
1008 | |||
1009 | break; | ||
933 | default: | 1010 | default: |
934 | fe = NULL; | 1011 | fe = NULL; |
935 | } | 1012 | } |
@@ -939,7 +1016,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | |||
939 | else | 1016 | else |
940 | ret = -ENODEV; | 1017 | ret = -ENODEV; |
941 | 1018 | ||
942 | error: | ||
943 | return ret; | 1019 | return ret; |
944 | } | 1020 | } |
945 | 1021 | ||
@@ -969,6 +1045,201 @@ static int anysee_rc_query(struct dvb_usb_device *d) | |||
969 | return 0; | 1045 | return 0; |
970 | } | 1046 | } |
971 | 1047 | ||
1048 | static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot, | ||
1049 | int addr) | ||
1050 | { | ||
1051 | struct dvb_usb_device *d = ci->data; | ||
1052 | int ret; | ||
1053 | u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1}; | ||
1054 | u8 val; | ||
1055 | |||
1056 | ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); | ||
1057 | if (ret) | ||
1058 | return ret; | ||
1059 | |||
1060 | return val; | ||
1061 | } | ||
1062 | |||
1063 | static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot, | ||
1064 | int addr, u8 val) | ||
1065 | { | ||
1066 | struct dvb_usb_device *d = ci->data; | ||
1067 | int ret; | ||
1068 | u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val}; | ||
1069 | |||
1070 | ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); | ||
1071 | if (ret) | ||
1072 | return ret; | ||
1073 | |||
1074 | return 0; | ||
1075 | } | ||
1076 | |||
1077 | static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot, | ||
1078 | u8 addr) | ||
1079 | { | ||
1080 | struct dvb_usb_device *d = ci->data; | ||
1081 | int ret; | ||
1082 | u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1}; | ||
1083 | u8 val; | ||
1084 | |||
1085 | ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); | ||
1086 | if (ret) | ||
1087 | return ret; | ||
1088 | |||
1089 | return val; | ||
1090 | } | ||
1091 | |||
1092 | static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot, | ||
1093 | u8 addr, u8 val) | ||
1094 | { | ||
1095 | struct dvb_usb_device *d = ci->data; | ||
1096 | int ret; | ||
1097 | u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val}; | ||
1098 | |||
1099 | ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); | ||
1100 | if (ret) | ||
1101 | return ret; | ||
1102 | |||
1103 | return 0; | ||
1104 | } | ||
1105 | |||
1106 | static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot) | ||
1107 | { | ||
1108 | struct dvb_usb_device *d = ci->data; | ||
1109 | int ret; | ||
1110 | struct anysee_state *state = d->priv; | ||
1111 | |||
1112 | state->ci_cam_ready = jiffies + msecs_to_jiffies(1000); | ||
1113 | |||
1114 | ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); | ||
1115 | if (ret) | ||
1116 | return ret; | ||
1117 | |||
1118 | msleep(300); | ||
1119 | |||
1120 | ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); | ||
1121 | if (ret) | ||
1122 | return ret; | ||
1123 | |||
1124 | return 0; | ||
1125 | } | ||
1126 | |||
1127 | static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot) | ||
1128 | { | ||
1129 | struct dvb_usb_device *d = ci->data; | ||
1130 | int ret; | ||
1131 | |||
1132 | ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); | ||
1133 | if (ret) | ||
1134 | return ret; | ||
1135 | |||
1136 | msleep(30); | ||
1137 | |||
1138 | ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); | ||
1139 | if (ret) | ||
1140 | return ret; | ||
1141 | |||
1142 | return 0; | ||
1143 | } | ||
1144 | |||
1145 | static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot) | ||
1146 | { | ||
1147 | struct dvb_usb_device *d = ci->data; | ||
1148 | int ret; | ||
1149 | |||
1150 | ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02); | ||
1151 | if (ret) | ||
1152 | return ret; | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot, | ||
1158 | int open) | ||
1159 | { | ||
1160 | struct dvb_usb_device *d = ci->data; | ||
1161 | struct anysee_state *state = d->priv; | ||
1162 | int ret; | ||
1163 | u8 tmp; | ||
1164 | |||
1165 | ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40); | ||
1166 | if (ret) | ||
1167 | return ret; | ||
1168 | |||
1169 | if (tmp == 0) { | ||
1170 | ret = DVB_CA_EN50221_POLL_CAM_PRESENT; | ||
1171 | if (time_after(jiffies, state->ci_cam_ready)) | ||
1172 | ret |= DVB_CA_EN50221_POLL_CAM_READY; | ||
1173 | } | ||
1174 | |||
1175 | return ret; | ||
1176 | } | ||
1177 | |||
1178 | static int anysee_ci_init(struct dvb_usb_device *d) | ||
1179 | { | ||
1180 | struct anysee_state *state = d->priv; | ||
1181 | int ret; | ||
1182 | |||
1183 | state->ci.owner = THIS_MODULE; | ||
1184 | state->ci.read_attribute_mem = anysee_ci_read_attribute_mem; | ||
1185 | state->ci.write_attribute_mem = anysee_ci_write_attribute_mem; | ||
1186 | state->ci.read_cam_control = anysee_ci_read_cam_control; | ||
1187 | state->ci.write_cam_control = anysee_ci_write_cam_control; | ||
1188 | state->ci.slot_reset = anysee_ci_slot_reset; | ||
1189 | state->ci.slot_shutdown = anysee_ci_slot_shutdown; | ||
1190 | state->ci.slot_ts_enable = anysee_ci_slot_ts_enable; | ||
1191 | state->ci.poll_slot_status = anysee_ci_poll_slot_status; | ||
1192 | state->ci.data = d; | ||
1193 | |||
1194 | ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); | ||
1195 | if (ret) | ||
1196 | return ret; | ||
1197 | |||
1198 | ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1); | ||
1199 | if (ret) | ||
1200 | return ret; | ||
1201 | |||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | static void anysee_ci_release(struct dvb_usb_device *d) | ||
1206 | { | ||
1207 | struct anysee_state *state = d->priv; | ||
1208 | |||
1209 | /* detach CI */ | ||
1210 | if (state->has_ci) | ||
1211 | dvb_ca_en50221_release(&state->ci); | ||
1212 | |||
1213 | return; | ||
1214 | } | ||
1215 | |||
1216 | static int anysee_init(struct dvb_usb_device *d) | ||
1217 | { | ||
1218 | struct anysee_state *state = d->priv; | ||
1219 | int ret; | ||
1220 | |||
1221 | /* LED light */ | ||
1222 | ret = anysee_led_ctrl(d, 0x01, 0x03); | ||
1223 | if (ret) | ||
1224 | return ret; | ||
1225 | |||
1226 | /* enable IR */ | ||
1227 | ret = anysee_ir_ctrl(d, 1); | ||
1228 | if (ret) | ||
1229 | return ret; | ||
1230 | |||
1231 | /* attach CI */ | ||
1232 | if (state->has_ci) { | ||
1233 | ret = anysee_ci_init(d); | ||
1234 | if (ret) { | ||
1235 | state->has_ci = false; | ||
1236 | return ret; | ||
1237 | } | ||
1238 | } | ||
1239 | |||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
972 | /* DVB USB Driver stuff */ | 1243 | /* DVB USB Driver stuff */ |
973 | static struct dvb_usb_device_properties anysee_properties; | 1244 | static struct dvb_usb_device_properties anysee_properties; |
974 | 1245 | ||
@@ -1010,6 +1281,16 @@ static int anysee_probe(struct usb_interface *intf, | |||
1010 | return anysee_init(d); | 1281 | return anysee_init(d); |
1011 | } | 1282 | } |
1012 | 1283 | ||
1284 | static void anysee_disconnect(struct usb_interface *intf) | ||
1285 | { | ||
1286 | struct dvb_usb_device *d = usb_get_intfdata(intf); | ||
1287 | |||
1288 | anysee_ci_release(d); | ||
1289 | dvb_usb_device_exit(intf); | ||
1290 | |||
1291 | return; | ||
1292 | } | ||
1293 | |||
1013 | static struct usb_device_id anysee_table[] = { | 1294 | static struct usb_device_id anysee_table[] = { |
1014 | { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, | 1295 | { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, |
1015 | { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, | 1296 | { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, |
@@ -1029,7 +1310,7 @@ static struct dvb_usb_device_properties anysee_properties = { | |||
1029 | { | 1310 | { |
1030 | .num_frontends = 2, | 1311 | .num_frontends = 2, |
1031 | .frontend_ctrl = anysee_frontend_ctrl, | 1312 | .frontend_ctrl = anysee_frontend_ctrl, |
1032 | .fe = {{ | 1313 | .fe = { { |
1033 | .streaming_ctrl = anysee_streaming_ctrl, | 1314 | .streaming_ctrl = anysee_streaming_ctrl, |
1034 | .frontend_attach = anysee_frontend_attach, | 1315 | .frontend_attach = anysee_frontend_attach, |
1035 | .tuner_attach = anysee_tuner_attach, | 1316 | .tuner_attach = anysee_tuner_attach, |
@@ -1057,7 +1338,7 @@ static struct dvb_usb_device_properties anysee_properties = { | |||
1057 | } | 1338 | } |
1058 | } | 1339 | } |
1059 | }, | 1340 | }, |
1060 | }}, | 1341 | } }, |
1061 | } | 1342 | } |
1062 | }, | 1343 | }, |
1063 | 1344 | ||
@@ -1087,7 +1368,7 @@ static struct dvb_usb_device_properties anysee_properties = { | |||
1087 | static struct usb_driver anysee_driver = { | 1368 | static struct usb_driver anysee_driver = { |
1088 | .name = "dvb_usb_anysee", | 1369 | .name = "dvb_usb_anysee", |
1089 | .probe = anysee_probe, | 1370 | .probe = anysee_probe, |
1090 | .disconnect = dvb_usb_device_exit, | 1371 | .disconnect = anysee_disconnect, |
1091 | .id_table = anysee_table, | 1372 | .id_table = anysee_table, |
1092 | }; | 1373 | }; |
1093 | 1374 | ||
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index 57ee500b8c0e..8ac879431540 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #define DVB_USB_LOG_PREFIX "anysee" | 37 | #define DVB_USB_LOG_PREFIX "anysee" |
38 | #include "dvb-usb.h" | 38 | #include "dvb-usb.h" |
39 | #include "dvb_ca_en50221.h" | ||
39 | 40 | ||
40 | #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) | 41 | #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) |
41 | #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) | 42 | #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) |
@@ -54,12 +55,16 @@ enum cmd { | |||
54 | CMD_GET_IR_CODE = 0x41, | 55 | CMD_GET_IR_CODE = 0x41, |
55 | CMD_GET_HW_INFO = 0x19, | 56 | CMD_GET_HW_INFO = 0x19, |
56 | CMD_SMARTCARD = 0x34, | 57 | CMD_SMARTCARD = 0x34, |
58 | CMD_CI = 0x37, | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | struct anysee_state { | 61 | struct anysee_state { |
60 | u8 hw; /* PCB ID */ | 62 | u8 hw; /* PCB ID */ |
61 | u8 seq; | 63 | u8 seq; |
62 | u8 fe_id:1; /* frondend ID */ | 64 | u8 fe_id:1; /* frondend ID */ |
65 | u8 has_ci:1; | ||
66 | struct dvb_ca_en50221 ci; | ||
67 | unsigned long ci_cam_ready; /* jiffies */ | ||
63 | }; | 68 | }; |
64 | 69 | ||
65 | #define ANYSEE_HW_507T 2 /* E30 */ | 70 | #define ANYSEE_HW_507T 2 /* E30 */ |
@@ -69,6 +74,7 @@ struct anysee_state { | |||
69 | #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ | 74 | #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ |
70 | #define ANYSEE_HW_508TC 18 /* E7 TC */ | 75 | #define ANYSEE_HW_508TC 18 /* E7 TC */ |
71 | #define ANYSEE_HW_508S2 19 /* E7 S2 */ | 76 | #define ANYSEE_HW_508S2 19 /* E7 S2 */ |
77 | #define ANYSEE_HW_508T2C 20 /* E7 T2C */ | ||
72 | #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ | 78 | #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ |
73 | #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ | 79 | #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ |
74 | 80 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f313182eb9d5..d0174fd9a087 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -1279,7 +1279,7 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) | |||
1279 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 1279 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
1280 | 1280 | ||
1281 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, | 1281 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, |
1282 | 0x80); | 1282 | 0x80, 0); |
1283 | 1283 | ||
1284 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, | 1284 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, |
1285 | &dib807x_dib8000_config[0]); | 1285 | &dib807x_dib8000_config[0]); |
@@ -1308,7 +1308,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) | |||
1308 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 1308 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
1309 | 1309 | ||
1310 | /* initialize IC 0 */ | 1310 | /* initialize IC 0 */ |
1311 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); | 1311 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); |
1312 | 1312 | ||
1313 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, | 1313 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, |
1314 | &dib807x_dib8000_config[0]); | 1314 | &dib807x_dib8000_config[0]); |
@@ -1319,7 +1319,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) | |||
1319 | static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) | 1319 | static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) |
1320 | { | 1320 | { |
1321 | /* initialize IC 1 */ | 1321 | /* initialize IC 1 */ |
1322 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); | 1322 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); |
1323 | 1323 | ||
1324 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, | 1324 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, |
1325 | &dib807x_dib8000_config[1]); | 1325 | &dib807x_dib8000_config[1]); |
@@ -1328,7 +1328,7 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) | |||
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | /* STK8096GP */ | 1330 | /* STK8096GP */ |
1331 | struct dibx000_agc_config dib8090_agc_config[2] = { | 1331 | static struct dibx000_agc_config dib8090_agc_config[2] = { |
1332 | { | 1332 | { |
1333 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, | 1333 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, |
1334 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, | 1334 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, |
@@ -1518,7 +1518,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe, | |||
1518 | if (ret < 0) | 1518 | if (ret < 0) |
1519 | return ret; | 1519 | return ret; |
1520 | 1520 | ||
1521 | target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; | 1521 | target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; |
1522 | dib8000_set_wbd_ref(fe, target); | 1522 | dib8000_set_wbd_ref(fe, target); |
1523 | 1523 | ||
1524 | 1524 | ||
@@ -1578,7 +1578,7 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) | |||
1578 | msleep(10); | 1578 | msleep(10); |
1579 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 1579 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
1580 | 1580 | ||
1581 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); | 1581 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); |
1582 | 1582 | ||
1583 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); | 1583 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); |
1584 | 1584 | ||
@@ -1629,7 +1629,7 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) | |||
1629 | msleep(20); | 1629 | msleep(20); |
1630 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 1630 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
1631 | 1631 | ||
1632 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); | 1632 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); |
1633 | 1633 | ||
1634 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); | 1634 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); |
1635 | if (adap->fe_adap[0].fe == NULL) | 1635 | if (adap->fe_adap[0].fe == NULL) |
@@ -1641,6 +1641,261 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) | |||
1641 | return fe_slave == NULL ? -ENODEV : 0; | 1641 | return fe_slave == NULL ? -ENODEV : 0; |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | /* TFE8096P */ | ||
1645 | static struct dibx000_agc_config dib8096p_agc_config[2] = { | ||
1646 | { | ||
1647 | .band_caps = BAND_UHF, | ||
1648 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, | ||
1649 | P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, | ||
1650 | P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | ||
1651 | P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, | ||
1652 | P_agc_write=0 */ | ||
1653 | .setup = (0 << 15) | (0 << 14) | (5 << 11) | ||
1654 | | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | ||
1655 | | (0 << 4) | (5 << 1) | (0 << 0), | ||
1656 | |||
1657 | .inv_gain = 684, | ||
1658 | .time_stabiliz = 10, | ||
1659 | |||
1660 | .alpha_level = 0, | ||
1661 | .thlock = 118, | ||
1662 | |||
1663 | .wbd_inv = 0, | ||
1664 | .wbd_ref = 1200, | ||
1665 | .wbd_sel = 3, | ||
1666 | .wbd_alpha = 5, | ||
1667 | |||
1668 | .agc1_max = 65535, | ||
1669 | .agc1_min = 0, | ||
1670 | |||
1671 | .agc2_max = 32767, | ||
1672 | .agc2_min = 0, | ||
1673 | |||
1674 | .agc1_pt1 = 0, | ||
1675 | .agc1_pt2 = 0, | ||
1676 | .agc1_pt3 = 105, | ||
1677 | .agc1_slope1 = 0, | ||
1678 | .agc1_slope2 = 156, | ||
1679 | .agc2_pt1 = 105, | ||
1680 | .agc2_pt2 = 255, | ||
1681 | .agc2_slope1 = 54, | ||
1682 | .agc2_slope2 = 0, | ||
1683 | |||
1684 | .alpha_mant = 28, | ||
1685 | .alpha_exp = 26, | ||
1686 | .beta_mant = 31, | ||
1687 | .beta_exp = 51, | ||
1688 | |||
1689 | .perform_agc_softsplit = 0, | ||
1690 | } , { | ||
1691 | .band_caps = BAND_FM | BAND_VHF | BAND_CBAND, | ||
1692 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, | ||
1693 | P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, | ||
1694 | P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | ||
1695 | P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, | ||
1696 | P_agc_write=0 */ | ||
1697 | .setup = (0 << 15) | (0 << 14) | (5 << 11) | ||
1698 | | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | ||
1699 | | (0 << 4) | (5 << 1) | (0 << 0), | ||
1700 | |||
1701 | .inv_gain = 732, | ||
1702 | .time_stabiliz = 10, | ||
1703 | |||
1704 | .alpha_level = 0, | ||
1705 | .thlock = 118, | ||
1706 | |||
1707 | .wbd_inv = 0, | ||
1708 | .wbd_ref = 1200, | ||
1709 | .wbd_sel = 3, | ||
1710 | .wbd_alpha = 5, | ||
1711 | |||
1712 | .agc1_max = 65535, | ||
1713 | .agc1_min = 0, | ||
1714 | |||
1715 | .agc2_max = 32767, | ||
1716 | .agc2_min = 0, | ||
1717 | |||
1718 | .agc1_pt1 = 0, | ||
1719 | .agc1_pt2 = 0, | ||
1720 | .agc1_pt3 = 98, | ||
1721 | .agc1_slope1 = 0, | ||
1722 | .agc1_slope2 = 167, | ||
1723 | .agc2_pt1 = 98, | ||
1724 | .agc2_pt2 = 255, | ||
1725 | .agc2_slope1 = 52, | ||
1726 | .agc2_slope2 = 0, | ||
1727 | |||
1728 | .alpha_mant = 28, | ||
1729 | .alpha_exp = 26, | ||
1730 | .beta_mant = 31, | ||
1731 | .beta_exp = 51, | ||
1732 | |||
1733 | .perform_agc_softsplit = 0, | ||
1734 | } | ||
1735 | }; | ||
1736 | |||
1737 | static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = { | ||
1738 | 108000, 13500, | ||
1739 | 1, 9, 1, 0, 0, | ||
1740 | 0, 0, 0, 0, 2, | ||
1741 | (3 << 14) | (1 << 12) | (524 << 0), | ||
1742 | (0 << 25) | 0, | ||
1743 | 20199729, | ||
1744 | 12000000, | ||
1745 | }; | ||
1746 | |||
1747 | static struct dib8000_config tfe8096p_dib8000_config = { | ||
1748 | .output_mpeg2_in_188_bytes = 1, | ||
1749 | .hostbus_diversity = 1, | ||
1750 | .update_lna = NULL, | ||
1751 | |||
1752 | .agc_config_count = 2, | ||
1753 | .agc = dib8096p_agc_config, | ||
1754 | .pll = &dib8096p_clock_config_12_mhz, | ||
1755 | |||
1756 | .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, | ||
1757 | .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, | ||
1758 | .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, | ||
1759 | |||
1760 | .agc_control = NULL, | ||
1761 | .diversity_delay = 48, | ||
1762 | .output_mode = OUTMODE_MPEG2_FIFO, | ||
1763 | .enMpegOutput = 1, | ||
1764 | }; | ||
1765 | |||
1766 | static struct dib0090_wbd_slope dib8096p_wbd_table[] = { | ||
1767 | { 380, 81, 850, 64, 540, 4}, | ||
1768 | { 860, 51, 866, 21, 375, 4}, | ||
1769 | {1700, 0, 250, 0, 100, 6}, | ||
1770 | {2600, 0, 250, 0, 100, 6}, | ||
1771 | { 0xFFFF, 0, 0, 0, 0, 0}, | ||
1772 | }; | ||
1773 | |||
1774 | static const struct dib0090_config tfe8096p_dib0090_config = { | ||
1775 | .io.clock_khz = 12000, | ||
1776 | .io.pll_bypass = 0, | ||
1777 | .io.pll_range = 0, | ||
1778 | .io.pll_prediv = 3, | ||
1779 | .io.pll_loopdiv = 6, | ||
1780 | .io.adc_clock_ratio = 0, | ||
1781 | .io.pll_int_loop_filt = 0, | ||
1782 | .reset = dib8096p_tuner_sleep, | ||
1783 | .sleep = dib8096p_tuner_sleep, | ||
1784 | |||
1785 | .freq_offset_khz_uhf = -143, | ||
1786 | .freq_offset_khz_vhf = -143, | ||
1787 | |||
1788 | .get_adc_power = dib8090_get_adc_power, | ||
1789 | |||
1790 | .clkouttobamse = 1, | ||
1791 | .analog_output = 0, | ||
1792 | |||
1793 | .wbd_vhf_offset = 0, | ||
1794 | .wbd_cband_offset = 0, | ||
1795 | .use_pwm_agc = 1, | ||
1796 | .clkoutdrive = 0, | ||
1797 | |||
1798 | .fref_clock_ratio = 1, | ||
1799 | |||
1800 | .wbd = dib8096p_wbd_table, | ||
1801 | |||
1802 | .ls_cfg_pad_drv = 0, | ||
1803 | .data_tx_drv = 0, | ||
1804 | .low_if = NULL, | ||
1805 | .in_soc = 1, | ||
1806 | .force_cband_input = 0, | ||
1807 | }; | ||
1808 | |||
1809 | struct dibx090p_adc { | ||
1810 | u32 freq; /* RF freq MHz */ | ||
1811 | u32 timf; /* New Timf */ | ||
1812 | u32 pll_loopdiv; /* New prediv */ | ||
1813 | u32 pll_prediv; /* New loopdiv */ | ||
1814 | }; | ||
1815 | |||
1816 | struct dibx090p_adc dib8090p_adc_tab[] = { | ||
1817 | { 50000, 17043521, 16, 3}, /* 64 MHz */ | ||
1818 | {878000, 20199729, 9, 1}, /* 60 MHz */ | ||
1819 | {0xffffffff, 0, 0, 0}, /* 60 MHz */ | ||
1820 | }; | ||
1821 | |||
1822 | static int dib8096p_agc_startup(struct dvb_frontend *fe, | ||
1823 | struct dvb_frontend_parameters *fep) | ||
1824 | { | ||
1825 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
1826 | struct dib0700_adapter_state *state = adap->priv; | ||
1827 | struct dibx000_bandwidth_config pll; | ||
1828 | u16 target; | ||
1829 | int better_sampling_freq = 0, ret; | ||
1830 | struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0]; | ||
1831 | |||
1832 | ret = state->set_param_save(fe, fep); | ||
1833 | if (ret < 0) | ||
1834 | return ret; | ||
1835 | memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); | ||
1836 | |||
1837 | dib0090_pwm_gain_reset(fe); | ||
1838 | /* dib0090_get_wbd_target is returning any possible | ||
1839 | temperature compensated wbd-target */ | ||
1840 | target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; | ||
1841 | dib8000_set_wbd_ref(fe, target); | ||
1842 | |||
1843 | |||
1844 | while (fep->frequency / 1000 > adc_table->freq) { | ||
1845 | better_sampling_freq = 1; | ||
1846 | adc_table++; | ||
1847 | } | ||
1848 | |||
1849 | if ((adc_table->freq != 0xffffffff) && better_sampling_freq) { | ||
1850 | pll.pll_ratio = adc_table->pll_loopdiv; | ||
1851 | pll.pll_prediv = adc_table->pll_prediv; | ||
1852 | dib8000_update_pll(fe, &pll); | ||
1853 | dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf); | ||
1854 | } | ||
1855 | return 0; | ||
1856 | } | ||
1857 | |||
1858 | static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) | ||
1859 | { | ||
1860 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
1861 | msleep(20); | ||
1862 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
1863 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
1864 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
1865 | |||
1866 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
1867 | |||
1868 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
1869 | |||
1870 | msleep(20); | ||
1871 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
1872 | msleep(20); | ||
1873 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
1874 | |||
1875 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); | ||
1876 | |||
1877 | adap->fe_adap[0].fe = dvb_attach(dib8000_attach, | ||
1878 | &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config); | ||
1879 | |||
1880 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; | ||
1881 | } | ||
1882 | |||
1883 | static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap) | ||
1884 | { | ||
1885 | struct dib0700_adapter_state *st = adap->priv; | ||
1886 | struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe); | ||
1887 | |||
1888 | if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, | ||
1889 | &tfe8096p_dib0090_config) == NULL) | ||
1890 | return -ENODEV; | ||
1891 | |||
1892 | dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); | ||
1893 | |||
1894 | st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; | ||
1895 | adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup; | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1644 | /* STK9090M */ | 1899 | /* STK9090M */ |
1645 | static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) | 1900 | static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) |
1646 | { | 1901 | { |
@@ -1883,7 +2138,7 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) | |||
1883 | i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); | 2138 | i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); |
1884 | if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) | 2139 | if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) |
1885 | return -ENODEV; | 2140 | return -ENODEV; |
1886 | dib0700_set_i2c_speed(adap->dev, 2000); | 2141 | dib0700_set_i2c_speed(adap->dev, 1500); |
1887 | if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) | 2142 | if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) |
1888 | return -ENODEV; | 2143 | return -ENODEV; |
1889 | release_firmware(state->frontend_firmware); | 2144 | release_firmware(state->frontend_firmware); |
@@ -1962,7 +2217,8 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) | |||
1962 | i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); | 2217 | i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); |
1963 | if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) | 2218 | if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) |
1964 | return -ENODEV; | 2219 | return -ENODEV; |
1965 | dib0700_set_i2c_speed(adap->dev, 2000); | 2220 | |
2221 | dib0700_set_i2c_speed(adap->dev, 1500); | ||
1966 | if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) | 2222 | if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) |
1967 | return -ENODEV; | 2223 | return -ENODEV; |
1968 | 2224 | ||
@@ -1975,7 +2231,7 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) | |||
1975 | if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) | 2231 | if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) |
1976 | return -ENODEV; | 2232 | return -ENODEV; |
1977 | fe_slave->dvb = adap->fe_adap[0].fe->dvb; | 2233 | fe_slave->dvb = adap->fe_adap[0].fe->dvb; |
1978 | dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 2000); | 2234 | dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500); |
1979 | if (dib9000_firmware_post_pll_init(fe_slave) < 0) | 2235 | if (dib9000_firmware_post_pll_init(fe_slave) < 0) |
1980 | return -ENODEV; | 2236 | return -ENODEV; |
1981 | } | 2237 | } |
@@ -2079,7 +2335,7 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para | |||
2079 | 2335 | ||
2080 | memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); | 2336 | memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); |
2081 | dib0090_pwm_gain_reset(fe); | 2337 | dib0090_pwm_gain_reset(fe); |
2082 | target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; | 2338 | target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; |
2083 | dib7000p_set_wbd_ref(fe, target); | 2339 | dib7000p_set_wbd_ref(fe, target); |
2084 | 2340 | ||
2085 | if (dib7090p_get_best_sampling(fe, &adc) == 0) { | 2341 | if (dib7090p_get_best_sampling(fe, &adc) == 0) { |
@@ -2092,6 +2348,49 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para | |||
2092 | return 0; | 2348 | return 0; |
2093 | } | 2349 | } |
2094 | 2350 | ||
2351 | static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) | ||
2352 | { | ||
2353 | deb_info("AGC restart callback: %d", restart); | ||
2354 | if (restart == 0) /* before AGC startup */ | ||
2355 | dib0090_set_dc_servo(fe, 1); | ||
2356 | return 0; | ||
2357 | } | ||
2358 | |||
2359 | static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global) | ||
2360 | { | ||
2361 | u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1; | ||
2362 | s16 wbd_delta; | ||
2363 | |||
2364 | if ((fe->dtv_property_cache.frequency) < 400000000) | ||
2365 | threshold_agc1 = 25000; | ||
2366 | else | ||
2367 | threshold_agc1 = 30000; | ||
2368 | |||
2369 | wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2; | ||
2370 | wbd_offset = dib0090_get_wbd_offset(fe); | ||
2371 | dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd); | ||
2372 | wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ; | ||
2373 | |||
2374 | deb_info("update lna, agc_global=%d agc1=%d agc2=%d", | ||
2375 | agc_global, agc1, agc2); | ||
2376 | deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d", | ||
2377 | wbd, wbd_target, wbd_offset, wbd_delta); | ||
2378 | |||
2379 | if ((agc1 < threshold_agc1) && (wbd_delta > 0)) { | ||
2380 | dib0090_set_switch(fe, 1, 1, 1); | ||
2381 | dib0090_set_vga(fe, 0); | ||
2382 | dib0090_update_rframp_7090(fe, 0); | ||
2383 | dib0090_update_tuning_table_7090(fe, 0); | ||
2384 | } else { | ||
2385 | dib0090_set_vga(fe, 1); | ||
2386 | dib0090_update_rframp_7090(fe, 1); | ||
2387 | dib0090_update_tuning_table_7090(fe, 1); | ||
2388 | dib0090_set_switch(fe, 0, 0, 0); | ||
2389 | } | ||
2390 | |||
2391 | return 0; | ||
2392 | } | ||
2393 | |||
2095 | static struct dib0090_wbd_slope dib7090_wbd_table[] = { | 2394 | static struct dib0090_wbd_slope dib7090_wbd_table[] = { |
2096 | { 380, 81, 850, 64, 540, 4}, | 2395 | { 380, 81, 850, 64, 540, 4}, |
2097 | { 860, 51, 866, 21, 375, 4}, | 2396 | { 860, 51, 866, 21, 375, 4}, |
@@ -2100,7 +2399,16 @@ static struct dib0090_wbd_slope dib7090_wbd_table[] = { | |||
2100 | { 0xFFFF, 0, 0, 0, 0, 0}, | 2399 | { 0xFFFF, 0, 0, 0, 0, 0}, |
2101 | }; | 2400 | }; |
2102 | 2401 | ||
2103 | struct dibx000_agc_config dib7090_agc_config[2] = { | 2402 | static struct dib0090_wbd_slope dib7090e_wbd_table[] = { |
2403 | { 380, 81, 850, 64, 540, 4}, | ||
2404 | { 700, 51, 866, 21, 320, 4}, | ||
2405 | { 860, 48, 666, 18, 330, 6}, | ||
2406 | {1700, 0, 250, 0, 100, 6}, | ||
2407 | {2600, 0, 250, 0, 100, 6}, | ||
2408 | { 0xFFFF, 0, 0, 0, 0, 0}, | ||
2409 | }; | ||
2410 | |||
2411 | static struct dibx000_agc_config dib7090_agc_config[2] = { | ||
2104 | { | 2412 | { |
2105 | .band_caps = BAND_UHF, | 2413 | .band_caps = BAND_UHF, |
2106 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, | 2414 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, |
@@ -2278,6 +2586,34 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { | |||
2278 | } | 2586 | } |
2279 | }; | 2587 | }; |
2280 | 2588 | ||
2589 | static struct dib7000p_config tfe7090e_dib7000p_config = { | ||
2590 | .output_mpeg2_in_188_bytes = 1, | ||
2591 | .hostbus_diversity = 1, | ||
2592 | .tuner_is_baseband = 1, | ||
2593 | .update_lna = dib7090e_update_lna, | ||
2594 | |||
2595 | .agc_config_count = 2, | ||
2596 | .agc = dib7090_agc_config, | ||
2597 | |||
2598 | .bw = &dib7090_clock_config_12_mhz, | ||
2599 | |||
2600 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
2601 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
2602 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
2603 | |||
2604 | .pwm_freq_div = 0, | ||
2605 | |||
2606 | .agc_control = dib7090_agc_restart, | ||
2607 | |||
2608 | .spur_protect = 0, | ||
2609 | .disable_sample_and_hold = 0, | ||
2610 | .enable_current_mirror = 0, | ||
2611 | .diversity_delay = 0, | ||
2612 | |||
2613 | .output_mode = OUTMODE_MPEG2_FIFO, | ||
2614 | .enMpegOutput = 1, | ||
2615 | }; | ||
2616 | |||
2281 | static const struct dib0090_config nim7090_dib0090_config = { | 2617 | static const struct dib0090_config nim7090_dib0090_config = { |
2282 | .io.clock_khz = 12000, | 2618 | .io.clock_khz = 12000, |
2283 | .io.pll_bypass = 0, | 2619 | .io.pll_bypass = 0, |
@@ -2312,6 +2648,107 @@ static const struct dib0090_config nim7090_dib0090_config = { | |||
2312 | .in_soc = 1, | 2648 | .in_soc = 1, |
2313 | }; | 2649 | }; |
2314 | 2650 | ||
2651 | static const struct dib0090_config tfe7090e_dib0090_config = { | ||
2652 | .io.clock_khz = 12000, | ||
2653 | .io.pll_bypass = 0, | ||
2654 | .io.pll_range = 0, | ||
2655 | .io.pll_prediv = 3, | ||
2656 | .io.pll_loopdiv = 6, | ||
2657 | .io.adc_clock_ratio = 0, | ||
2658 | .io.pll_int_loop_filt = 0, | ||
2659 | .reset = dib7090_tuner_sleep, | ||
2660 | .sleep = dib7090_tuner_sleep, | ||
2661 | |||
2662 | .freq_offset_khz_uhf = 0, | ||
2663 | .freq_offset_khz_vhf = 0, | ||
2664 | |||
2665 | .get_adc_power = dib7090_get_adc_power, | ||
2666 | |||
2667 | .clkouttobamse = 1, | ||
2668 | .analog_output = 0, | ||
2669 | |||
2670 | .wbd_vhf_offset = 0, | ||
2671 | .wbd_cband_offset = 0, | ||
2672 | .use_pwm_agc = 1, | ||
2673 | .clkoutdrive = 0, | ||
2674 | |||
2675 | .fref_clock_ratio = 0, | ||
2676 | |||
2677 | .wbd = dib7090e_wbd_table, | ||
2678 | |||
2679 | .ls_cfg_pad_drv = 0, | ||
2680 | .data_tx_drv = 0, | ||
2681 | .low_if = NULL, | ||
2682 | .in_soc = 1, | ||
2683 | .force_cband_input = 1, | ||
2684 | .is_dib7090e = 1, | ||
2685 | }; | ||
2686 | |||
2687 | static struct dib7000p_config tfe7790e_dib7000p_config = { | ||
2688 | .output_mpeg2_in_188_bytes = 1, | ||
2689 | .hostbus_diversity = 1, | ||
2690 | .tuner_is_baseband = 1, | ||
2691 | .update_lna = dib7090e_update_lna, | ||
2692 | |||
2693 | .agc_config_count = 2, | ||
2694 | .agc = dib7090_agc_config, | ||
2695 | |||
2696 | .bw = &dib7090_clock_config_12_mhz, | ||
2697 | |||
2698 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
2699 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
2700 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
2701 | |||
2702 | .pwm_freq_div = 0, | ||
2703 | |||
2704 | .agc_control = dib7090_agc_restart, | ||
2705 | |||
2706 | .spur_protect = 0, | ||
2707 | .disable_sample_and_hold = 0, | ||
2708 | .enable_current_mirror = 0, | ||
2709 | .diversity_delay = 0, | ||
2710 | |||
2711 | .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, | ||
2712 | .enMpegOutput = 1, | ||
2713 | }; | ||
2714 | |||
2715 | static const struct dib0090_config tfe7790e_dib0090_config = { | ||
2716 | .io.clock_khz = 12000, | ||
2717 | .io.pll_bypass = 0, | ||
2718 | .io.pll_range = 0, | ||
2719 | .io.pll_prediv = 3, | ||
2720 | .io.pll_loopdiv = 6, | ||
2721 | .io.adc_clock_ratio = 0, | ||
2722 | .io.pll_int_loop_filt = 0, | ||
2723 | .reset = dib7090_tuner_sleep, | ||
2724 | .sleep = dib7090_tuner_sleep, | ||
2725 | |||
2726 | .freq_offset_khz_uhf = 0, | ||
2727 | .freq_offset_khz_vhf = 0, | ||
2728 | |||
2729 | .get_adc_power = dib7090_get_adc_power, | ||
2730 | |||
2731 | .clkouttobamse = 1, | ||
2732 | .analog_output = 0, | ||
2733 | |||
2734 | .wbd_vhf_offset = 0, | ||
2735 | .wbd_cband_offset = 0, | ||
2736 | .use_pwm_agc = 1, | ||
2737 | .clkoutdrive = 0, | ||
2738 | |||
2739 | .fref_clock_ratio = 0, | ||
2740 | |||
2741 | .wbd = dib7090e_wbd_table, | ||
2742 | |||
2743 | .ls_cfg_pad_drv = 0, | ||
2744 | .data_tx_drv = 0, | ||
2745 | .low_if = NULL, | ||
2746 | .in_soc = 1, | ||
2747 | .force_cband_input = 1, | ||
2748 | .is_dib7090e = 1, | ||
2749 | .force_crystal_mode = 1, | ||
2750 | }; | ||
2751 | |||
2315 | static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { | 2752 | static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { |
2316 | { | 2753 | { |
2317 | .io.clock_khz = 12000, | 2754 | .io.clock_khz = 12000, |
@@ -2504,6 +2941,97 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) | |||
2504 | return 0; | 2941 | return 0; |
2505 | } | 2942 | } |
2506 | 2943 | ||
2944 | static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap) | ||
2945 | { | ||
2946 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
2947 | msleep(20); | ||
2948 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
2949 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
2950 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
2951 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
2952 | |||
2953 | msleep(20); | ||
2954 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
2955 | msleep(20); | ||
2956 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
2957 | |||
2958 | if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, | ||
2959 | 1, 0x10, &tfe7090e_dib7000p_config) != 0) { | ||
2960 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", | ||
2961 | __func__); | ||
2962 | return -ENODEV; | ||
2963 | } | ||
2964 | adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, | ||
2965 | 0x80, &tfe7090e_dib7000p_config); | ||
2966 | |||
2967 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; | ||
2968 | } | ||
2969 | |||
2970 | static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap) | ||
2971 | { | ||
2972 | struct dib0700_state *st = adap->dev->priv; | ||
2973 | |||
2974 | /* The TFE7790E requires the dib0700 to not be in master mode */ | ||
2975 | st->disable_streaming_master_mode = 1; | ||
2976 | |||
2977 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
2978 | msleep(20); | ||
2979 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
2980 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
2981 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
2982 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
2983 | msleep(20); | ||
2984 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
2985 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
2986 | msleep(20); | ||
2987 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
2988 | |||
2989 | if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, | ||
2990 | 1, 0x10, &tfe7790e_dib7000p_config) != 0) { | ||
2991 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", | ||
2992 | __func__); | ||
2993 | return -ENODEV; | ||
2994 | } | ||
2995 | adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, | ||
2996 | 0x80, &tfe7790e_dib7000p_config); | ||
2997 | |||
2998 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; | ||
2999 | } | ||
3000 | |||
3001 | static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap) | ||
3002 | { | ||
3003 | struct dib0700_adapter_state *st = adap->priv; | ||
3004 | struct i2c_adapter *tun_i2c = | ||
3005 | dib7090_get_i2c_tuner(adap->fe_adap[0].fe); | ||
3006 | |||
3007 | if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, | ||
3008 | &tfe7790e_dib0090_config) == NULL) | ||
3009 | return -ENODEV; | ||
3010 | |||
3011 | dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); | ||
3012 | |||
3013 | st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; | ||
3014 | adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; | ||
3015 | return 0; | ||
3016 | } | ||
3017 | |||
3018 | static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap) | ||
3019 | { | ||
3020 | struct dib0700_adapter_state *st = adap->priv; | ||
3021 | struct i2c_adapter *tun_i2c = | ||
3022 | dib7090_get_i2c_tuner(adap->fe_adap[0].fe); | ||
3023 | |||
3024 | if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, | ||
3025 | &tfe7090e_dib0090_config) == NULL) | ||
3026 | return -ENODEV; | ||
3027 | |||
3028 | dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); | ||
3029 | |||
3030 | st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; | ||
3031 | adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; | ||
3032 | return 0; | ||
3033 | } | ||
3034 | |||
2507 | /* STK7070PD */ | 3035 | /* STK7070PD */ |
2508 | static struct dib7000p_config stk7070pd_dib7000p_config[2] = { | 3036 | static struct dib7000p_config stk7070pd_dib7000p_config[2] = { |
2509 | { | 3037 | { |
@@ -2960,6 +3488,9 @@ struct usb_device_id dib0700_usb_id_table[] = { | |||
2960 | /* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, | 3488 | /* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, |
2961 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, | 3489 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, |
2962 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, | 3490 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, |
3491 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, | ||
3492 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) }, | ||
3493 | /* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) }, | ||
2963 | { 0 } /* Terminating entry */ | 3494 | { 0 } /* Terminating entry */ |
2964 | }; | 3495 | }; |
2965 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); | 3496 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); |
@@ -4025,6 +4556,127 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
4025 | RC_TYPE_NEC, | 4556 | RC_TYPE_NEC, |
4026 | .change_protocol = dib0700_change_protocol, | 4557 | .change_protocol = dib0700_change_protocol, |
4027 | }, | 4558 | }, |
4559 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
4560 | .num_adapters = 1, | ||
4561 | .adapter = { | ||
4562 | { | ||
4563 | .num_frontends = 1, | ||
4564 | .fe = {{ | ||
4565 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
4566 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
4567 | .pid_filter_count = 32, | ||
4568 | .pid_filter = stk70x0p_pid_filter, | ||
4569 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
4570 | .frontend_attach = tfe7090e_frontend_attach, | ||
4571 | .tuner_attach = tfe7090e_tuner_attach, | ||
4572 | |||
4573 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
4574 | } }, | ||
4575 | |||
4576 | .size_of_priv = | ||
4577 | sizeof(struct dib0700_adapter_state), | ||
4578 | }, | ||
4579 | }, | ||
4580 | |||
4581 | .num_device_descs = 1, | ||
4582 | .devices = { | ||
4583 | { "DiBcom TFE7090E reference design", | ||
4584 | { &dib0700_usb_id_table[78], NULL }, | ||
4585 | { NULL }, | ||
4586 | }, | ||
4587 | }, | ||
4588 | |||
4589 | .rc.core = { | ||
4590 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
4591 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
4592 | .module_name = "dib0700", | ||
4593 | .rc_query = dib0700_rc_query_old_firmware, | ||
4594 | .allowed_protos = RC_TYPE_RC5 | | ||
4595 | RC_TYPE_RC6 | | ||
4596 | RC_TYPE_NEC, | ||
4597 | .change_protocol = dib0700_change_protocol, | ||
4598 | }, | ||
4599 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
4600 | .num_adapters = 1, | ||
4601 | .adapter = { | ||
4602 | { | ||
4603 | .num_frontends = 1, | ||
4604 | .fe = {{ | ||
4605 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
4606 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
4607 | .pid_filter_count = 32, | ||
4608 | .pid_filter = stk70x0p_pid_filter, | ||
4609 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
4610 | .frontend_attach = tfe7790e_frontend_attach, | ||
4611 | .tuner_attach = tfe7790e_tuner_attach, | ||
4612 | |||
4613 | DIB0700_DEFAULT_STREAMING_CONFIG(0x03), | ||
4614 | } }, | ||
4615 | |||
4616 | .size_of_priv = | ||
4617 | sizeof(struct dib0700_adapter_state), | ||
4618 | }, | ||
4619 | }, | ||
4620 | |||
4621 | .num_device_descs = 1, | ||
4622 | .devices = { | ||
4623 | { "DiBcom TFE7790E reference design", | ||
4624 | { &dib0700_usb_id_table[79], NULL }, | ||
4625 | { NULL }, | ||
4626 | }, | ||
4627 | }, | ||
4628 | |||
4629 | .rc.core = { | ||
4630 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
4631 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
4632 | .module_name = "dib0700", | ||
4633 | .rc_query = dib0700_rc_query_old_firmware, | ||
4634 | .allowed_protos = RC_TYPE_RC5 | | ||
4635 | RC_TYPE_RC6 | | ||
4636 | RC_TYPE_NEC, | ||
4637 | .change_protocol = dib0700_change_protocol, | ||
4638 | }, | ||
4639 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
4640 | .num_adapters = 1, | ||
4641 | .adapter = { | ||
4642 | { | ||
4643 | .num_frontends = 1, | ||
4644 | .fe = {{ | ||
4645 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
4646 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
4647 | .pid_filter_count = 32, | ||
4648 | .pid_filter = stk80xx_pid_filter, | ||
4649 | .pid_filter_ctrl = stk80xx_pid_filter_ctrl, | ||
4650 | .frontend_attach = tfe8096p_frontend_attach, | ||
4651 | .tuner_attach = tfe8096p_tuner_attach, | ||
4652 | |||
4653 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
4654 | |||
4655 | } }, | ||
4656 | |||
4657 | .size_of_priv = | ||
4658 | sizeof(struct dib0700_adapter_state), | ||
4659 | }, | ||
4660 | }, | ||
4661 | |||
4662 | .num_device_descs = 1, | ||
4663 | .devices = { | ||
4664 | { "DiBcom TFE8096P reference design", | ||
4665 | { &dib0700_usb_id_table[80], NULL }, | ||
4666 | { NULL }, | ||
4667 | }, | ||
4668 | }, | ||
4669 | |||
4670 | .rc.core = { | ||
4671 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
4672 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
4673 | .module_name = "dib0700", | ||
4674 | .rc_query = dib0700_rc_query_old_firmware, | ||
4675 | .allowed_protos = RC_TYPE_RC5 | | ||
4676 | RC_TYPE_RC6 | | ||
4677 | RC_TYPE_NEC, | ||
4678 | .change_protocol = dib0700_change_protocol, | ||
4679 | }, | ||
4028 | }, | 4680 | }, |
4029 | }; | 4681 | }; |
4030 | 4682 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 2d08c9b5128a..3cce13bb5242 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -109,10 +109,13 @@ | |||
109 | #define USB_PID_DIBCOM_STK807XPVR 0x1f98 | 109 | #define USB_PID_DIBCOM_STK807XPVR 0x1f98 |
110 | #define USB_PID_DIBCOM_STK8096GP 0x1fa0 | 110 | #define USB_PID_DIBCOM_STK8096GP 0x1fa0 |
111 | #define USB_PID_DIBCOM_NIM8096MD 0x1fa8 | 111 | #define USB_PID_DIBCOM_NIM8096MD 0x1fa8 |
112 | #define USB_PID_DIBCOM_TFE8096P 0x1f9C | ||
112 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 | 113 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 |
113 | #define USB_PID_DIBCOM_STK7770P 0x1e80 | 114 | #define USB_PID_DIBCOM_STK7770P 0x1e80 |
114 | #define USB_PID_DIBCOM_NIM7090 0x1bb2 | 115 | #define USB_PID_DIBCOM_NIM7090 0x1bb2 |
115 | #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 | 116 | #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 |
117 | #define USB_PID_DIBCOM_TFE7090E 0x1bb7 | ||
118 | #define USB_PID_DIBCOM_TFE7790E 0x1e6e | ||
116 | #define USB_PID_DIBCOM_NIM9090M 0x2383 | 119 | #define USB_PID_DIBCOM_NIM9090M 0x2383 |
117 | #define USB_PID_DIBCOM_NIM9090MD 0x2384 | 120 | #define USB_PID_DIBCOM_NIM9090MD 0x2384 |
118 | #define USB_PID_DPOSH_M9206_COLD 0x9206 | 121 | #define USB_PID_DPOSH_M9206_COLD 0x9206 |
@@ -128,6 +131,7 @@ | |||
128 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 | 131 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 |
129 | #define USB_PID_INTEL_CE9500 0x9500 | 132 | #define USB_PID_INTEL_CE9500 0x9500 |
130 | #define USB_PID_ITETECH_IT9135 0x9135 | 133 | #define USB_PID_ITETECH_IT9135 0x9135 |
134 | #define USB_PID_ITETECH_IT9135_9005 0x9005 | ||
131 | #define USB_PID_KWORLD_399U 0xe399 | 135 | #define USB_PID_KWORLD_399U 0xe399 |
132 | #define USB_PID_KWORLD_399U_2 0xe400 | 136 | #define USB_PID_KWORLD_399U_2 0xe400 |
133 | #define USB_PID_KWORLD_395U 0xe396 | 137 | #define USB_PID_KWORLD_395U 0xe396 |
@@ -322,6 +326,7 @@ | |||
322 | #define USB_PID_TVWAY_PLUS 0x0002 | 326 | #define USB_PID_TVWAY_PLUS 0x0002 |
323 | #define USB_PID_SVEON_STV20 0xe39d | 327 | #define USB_PID_SVEON_STV20 0xe39d |
324 | #define USB_PID_SVEON_STV22 0xe401 | 328 | #define USB_PID_SVEON_STV22 0xe401 |
329 | #define USB_PID_SVEON_STV22_IT9137 0xe411 | ||
325 | #define USB_PID_AZUREWAVE_AZ6027 0x3275 | 330 | #define USB_PID_AZUREWAVE_AZ6027 0x3275 |
326 | #define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4 | 331 | #define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4 |
327 | #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac | 332 | #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index f103ec1fe82e..41cff377587b 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -1859,12 +1859,11 @@ static struct dvb_usb_device_properties su3000_properties = { | |||
1859 | static int dw2102_probe(struct usb_interface *intf, | 1859 | static int dw2102_probe(struct usb_interface *intf, |
1860 | const struct usb_device_id *id) | 1860 | const struct usb_device_id *id) |
1861 | { | 1861 | { |
1862 | p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | 1862 | p1100 = kmemdup(&s6x0_properties, |
1863 | sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||
1863 | if (!p1100) | 1864 | if (!p1100) |
1864 | return -ENOMEM; | 1865 | return -ENOMEM; |
1865 | /* copy default structure */ | 1866 | /* copy default structure */ |
1866 | memcpy(p1100, &s6x0_properties, | ||
1867 | sizeof(struct dvb_usb_device_properties)); | ||
1868 | /* fill only different fields */ | 1867 | /* fill only different fields */ |
1869 | p1100->firmware = "dvb-usb-p1100.fw"; | 1868 | p1100->firmware = "dvb-usb-p1100.fw"; |
1870 | p1100->devices[0] = d1100; | 1869 | p1100->devices[0] = d1100; |
@@ -1872,13 +1871,12 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1872 | p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); | 1871 | p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); |
1873 | p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; | 1872 | p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; |
1874 | 1873 | ||
1875 | s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | 1874 | s660 = kmemdup(&s6x0_properties, |
1875 | sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||
1876 | if (!s660) { | 1876 | if (!s660) { |
1877 | kfree(p1100); | 1877 | kfree(p1100); |
1878 | return -ENOMEM; | 1878 | return -ENOMEM; |
1879 | } | 1879 | } |
1880 | memcpy(s660, &s6x0_properties, | ||
1881 | sizeof(struct dvb_usb_device_properties)); | ||
1882 | s660->firmware = "dvb-usb-s660.fw"; | 1880 | s660->firmware = "dvb-usb-s660.fw"; |
1883 | s660->num_device_descs = 3; | 1881 | s660->num_device_descs = 3; |
1884 | s660->devices[0] = d660; | 1882 | s660->devices[0] = d660; |
@@ -1886,14 +1884,13 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1886 | s660->devices[2] = d480_2; | 1884 | s660->devices[2] = d480_2; |
1887 | s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; | 1885 | s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; |
1888 | 1886 | ||
1889 | p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | 1887 | p7500 = kmemdup(&s6x0_properties, |
1888 | sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||
1890 | if (!p7500) { | 1889 | if (!p7500) { |
1891 | kfree(p1100); | 1890 | kfree(p1100); |
1892 | kfree(s660); | 1891 | kfree(s660); |
1893 | return -ENOMEM; | 1892 | return -ENOMEM; |
1894 | } | 1893 | } |
1895 | memcpy(p7500, &s6x0_properties, | ||
1896 | sizeof(struct dvb_usb_device_properties)); | ||
1897 | p7500->firmware = "dvb-usb-p7500.fw"; | 1894 | p7500->firmware = "dvb-usb-p7500.fw"; |
1898 | p7500->devices[0] = d7500; | 1895 | p7500->devices[0] = d7500; |
1899 | p7500->rc.legacy.rc_map_table = rc_map_tbs_table; | 1896 | p7500->rc.legacy.rc_map_table = rc_map_tbs_table; |
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index c46226187143..47317e9faa41 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c | |||
@@ -52,42 +52,59 @@ static int pid_filter; | |||
52 | module_param_named(pid, pid_filter, int, 0644); | 52 | module_param_named(pid, pid_filter, int, 0644); |
53 | MODULE_PARM_DESC(pid, "set default 0=on 1=off"); | 53 | MODULE_PARM_DESC(pid, "set default 0=on 1=off"); |
54 | 54 | ||
55 | static int dvb_usb_it913x_firmware; | ||
56 | module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644); | ||
57 | MODULE_PARM_DESC(firmware, "set firmware 0=auto 1=IT9137 2=IT9135V1"); | ||
58 | |||
59 | |||
55 | int cmd_counter; | 60 | int cmd_counter; |
56 | 61 | ||
57 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 62 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
58 | 63 | ||
59 | struct it913x_state { | 64 | struct it913x_state { |
60 | u8 id; | 65 | u8 id; |
61 | }; | 66 | struct ite_config it913x_config; |
62 | |||
63 | struct ite_config { | ||
64 | u8 chip_ver; | ||
65 | u16 chip_type; | ||
66 | u32 firmware; | ||
67 | u8 tuner_id_0; | ||
68 | u8 tuner_id_1; | ||
69 | u8 dual_mode; | ||
70 | }; | 67 | }; |
71 | 68 | ||
72 | struct ite_config it913x_config; | 69 | struct ite_config it913x_config; |
73 | 70 | ||
71 | #define IT913X_RETRY 10 | ||
72 | #define IT913X_SND_TIMEOUT 100 | ||
73 | #define IT913X_RCV_TIMEOUT 200 | ||
74 | |||
74 | static int it913x_bulk_write(struct usb_device *dev, | 75 | static int it913x_bulk_write(struct usb_device *dev, |
75 | u8 *snd, int len, u8 pipe) | 76 | u8 *snd, int len, u8 pipe) |
76 | { | 77 | { |
77 | int ret, actual_l; | 78 | int ret, actual_l, i; |
79 | |||
80 | for (i = 0; i < IT913X_RETRY; i++) { | ||
81 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), | ||
82 | snd, len , &actual_l, IT913X_SND_TIMEOUT); | ||
83 | if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) | ||
84 | break; | ||
85 | } | ||
86 | |||
87 | if (len != actual_l && ret == 0) | ||
88 | ret = -EAGAIN; | ||
78 | 89 | ||
79 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), | ||
80 | snd, len , &actual_l, 100); | ||
81 | return ret; | 90 | return ret; |
82 | } | 91 | } |
83 | 92 | ||
84 | static int it913x_bulk_read(struct usb_device *dev, | 93 | static int it913x_bulk_read(struct usb_device *dev, |
85 | u8 *rev, int len, u8 pipe) | 94 | u8 *rev, int len, u8 pipe) |
86 | { | 95 | { |
87 | int ret, actual_l; | 96 | int ret, actual_l, i; |
97 | |||
98 | for (i = 0; i < IT913X_RETRY; i++) { | ||
99 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), | ||
100 | rev, len , &actual_l, IT913X_RCV_TIMEOUT); | ||
101 | if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | if (len != actual_l && ret == 0) | ||
106 | ret = -EAGAIN; | ||
88 | 107 | ||
89 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), | ||
90 | rev, len , &actual_l, 200); | ||
91 | return ret; | 108 | return ret; |
92 | } | 109 | } |
93 | 110 | ||
@@ -100,7 +117,7 @@ static u16 check_sum(u8 *p, u8 len) | |||
100 | return ~sum; | 117 | return ~sum; |
101 | } | 118 | } |
102 | 119 | ||
103 | static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, | 120 | static int it913x_usb_talk(struct usb_device *udev, u8 mode, u8 pro, |
104 | u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) | 121 | u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) |
105 | { | 122 | { |
106 | int ret = 0, i, buf_size = 1; | 123 | int ret = 0, i, buf_size = 1; |
@@ -159,22 +176,41 @@ static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, | |||
159 | buff[buf_size++] = (chk_sum & 0xff); | 176 | buff[buf_size++] = (chk_sum & 0xff); |
160 | 177 | ||
161 | ret = it913x_bulk_write(udev, buff, buf_size , 0x02); | 178 | ret = it913x_bulk_write(udev, buff, buf_size , 0x02); |
179 | if (ret < 0) | ||
180 | goto error; | ||
162 | 181 | ||
163 | ret |= it913x_bulk_read(udev, buff, (mode & 1) ? | 182 | ret = it913x_bulk_read(udev, buff, (mode & 1) ? |
164 | 5 : len + 5 , 0x01); | 183 | 5 : len + 5 , 0x01); |
184 | if (ret < 0) | ||
185 | goto error; | ||
165 | 186 | ||
166 | rlen = (mode & 0x1) ? 0x1 : len; | 187 | rlen = (mode & 0x1) ? 0x1 : len; |
167 | 188 | ||
168 | if (mode & 1) | 189 | if (mode & 1) |
169 | ret |= buff[2]; | 190 | ret = buff[2]; |
170 | else | 191 | else |
171 | memcpy(data, &buff[3], rlen); | 192 | memcpy(data, &buff[3], rlen); |
172 | 193 | ||
173 | cmd_counter++; | 194 | cmd_counter++; |
174 | 195 | ||
175 | kfree(buff); | 196 | error: kfree(buff); |
176 | 197 | ||
177 | return (ret < 0) ? -ENODEV : 0; | 198 | return ret; |
199 | } | ||
200 | |||
201 | static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, | ||
202 | u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) | ||
203 | { | ||
204 | int ret, i; | ||
205 | |||
206 | for (i = 0; i < IT913X_RETRY; i++) { | ||
207 | ret = it913x_usb_talk(udev, mode, pro, | ||
208 | cmd, reg, addr, data, len); | ||
209 | if (ret != -EAGAIN) | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | return ret; | ||
178 | } | 214 | } |
179 | 215 | ||
180 | static int it913x_wr_reg(struct usb_device *udev, u8 pro, u32 reg , u8 data) | 216 | static int it913x_wr_reg(struct usb_device *udev, u8 pro, u32 reg , u8 data) |
@@ -337,15 +373,62 @@ static int it913x_rc_query(struct dvb_usb_device *d) | |||
337 | 373 | ||
338 | if ((ibuf[2] + ibuf[3]) == 0xff) { | 374 | if ((ibuf[2] + ibuf[3]) == 0xff) { |
339 | key = ibuf[2]; | 375 | key = ibuf[2]; |
340 | key += ibuf[0] << 8; | 376 | key += ibuf[0] << 16; |
341 | deb_info(1, "INT Key =%08x", key); | 377 | key += ibuf[1] << 8; |
378 | deb_info(1, "NEC Extended Key =%08x", key); | ||
342 | if (d->rc_dev != NULL) | 379 | if (d->rc_dev != NULL) |
343 | rc_keydown(d->rc_dev, key, 0); | 380 | rc_keydown(d->rc_dev, key, 0); |
344 | } | 381 | } |
382 | |||
345 | mutex_unlock(&d->i2c_mutex); | 383 | mutex_unlock(&d->i2c_mutex); |
346 | 384 | ||
347 | return ret; | 385 | return ret; |
348 | } | 386 | } |
387 | |||
388 | /* Firmware sets raw */ | ||
389 | const char fw_it9135_v1[] = "dvb-usb-it9135-01.fw"; | ||
390 | const char fw_it9137[] = "dvb-usb-it9137-01.fw"; | ||
391 | |||
392 | static int ite_firmware_select(struct usb_device *udev, | ||
393 | struct dvb_usb_device_properties *props) | ||
394 | { | ||
395 | int sw; | ||
396 | /* auto switch */ | ||
397 | if (le16_to_cpu(udev->descriptor.idProduct) == | ||
398 | USB_PID_ITETECH_IT9135) | ||
399 | sw = IT9135_V1_FW; | ||
400 | else if (le16_to_cpu(udev->descriptor.idProduct) == | ||
401 | USB_PID_ITETECH_IT9135_9005) | ||
402 | sw = IT9135_V1_FW; | ||
403 | else | ||
404 | sw = IT9137_FW; | ||
405 | |||
406 | /* force switch */ | ||
407 | if (dvb_usb_it913x_firmware != IT9135_AUTO) | ||
408 | sw = dvb_usb_it913x_firmware; | ||
409 | |||
410 | switch (sw) { | ||
411 | case IT9135_V1_FW: | ||
412 | it913x_config.firmware_ver = 1; | ||
413 | it913x_config.adc_x2 = 1; | ||
414 | props->firmware = fw_it9135_v1; | ||
415 | break; | ||
416 | case IT9137_FW: | ||
417 | default: | ||
418 | it913x_config.firmware_ver = 0; | ||
419 | it913x_config.adc_x2 = 0; | ||
420 | props->firmware = fw_it9137; | ||
421 | } | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | #define TS_MPEG_PKT_SIZE 188 | ||
427 | #define EP_LOW 21 | ||
428 | #define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE) | ||
429 | #define EP_HIGH 348 | ||
430 | #define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE) | ||
431 | |||
349 | static int it913x_identify_state(struct usb_device *udev, | 432 | static int it913x_identify_state(struct usb_device *udev, |
350 | struct dvb_usb_device_properties *props, | 433 | struct dvb_usb_device_properties *props, |
351 | struct dvb_usb_device_description **desc, | 434 | struct dvb_usb_device_description **desc, |
@@ -359,6 +442,19 @@ static int it913x_identify_state(struct usb_device *udev, | |||
359 | /* checnk for dual mode */ | 442 | /* checnk for dual mode */ |
360 | it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); | 443 | it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); |
361 | 444 | ||
445 | if (udev->speed != USB_SPEED_HIGH) { | ||
446 | props->adapter[0].fe[0].pid_filter_count = 5; | ||
447 | info("USB 1 low speed mode - connect to USB 2 port"); | ||
448 | if (pid_filter > 0) | ||
449 | pid_filter = 0; | ||
450 | if (it913x_config.dual_mode) { | ||
451 | it913x_config.dual_mode = 0; | ||
452 | info("Dual mode not supported in USB 1"); | ||
453 | } | ||
454 | } else /* For replugging */ | ||
455 | if(props->adapter[0].fe[0].pid_filter_count == 5) | ||
456 | props->adapter[0].fe[0].pid_filter_count = 31; | ||
457 | |||
362 | /* TODO different remotes */ | 458 | /* TODO different remotes */ |
363 | remote = it913x_read_reg(udev, 0x49ac); /* Remote */ | 459 | remote = it913x_read_reg(udev, 0x49ac); /* Remote */ |
364 | if (remote == 0) | 460 | if (remote == 0) |
@@ -370,6 +466,19 @@ static int it913x_identify_state(struct usb_device *udev, | |||
370 | info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode | 466 | info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode |
371 | , remote, it913x_config.tuner_id_0); | 467 | , remote, it913x_config.tuner_id_0); |
372 | 468 | ||
469 | /* Select Stream Buffer Size */ | ||
470 | if (pid_filter) | ||
471 | props->adapter[0].fe[0].stream.u.bulk.buffersize = | ||
472 | TS_BUFFER_SIZE_MAX; | ||
473 | else | ||
474 | props->adapter[0].fe[0].stream.u.bulk.buffersize = | ||
475 | TS_BUFFER_SIZE_PID; | ||
476 | if (it913x_config.dual_mode) | ||
477 | props->adapter[1].fe[0].stream.u.bulk.buffersize = | ||
478 | props->adapter[0].fe[0].stream.u.bulk.buffersize; | ||
479 | |||
480 | ret = ite_firmware_select(udev, props); | ||
481 | |||
373 | if (firm_no > 0) { | 482 | if (firm_no > 0) { |
374 | *cold = 0; | 483 | *cold = 0; |
375 | return 0; | 484 | return 0; |
@@ -390,8 +499,8 @@ static int it913x_identify_state(struct usb_device *udev, | |||
390 | if (ret != 0) | 499 | if (ret != 0) |
391 | ret = it913x_wr_reg(udev, DEV_0, | 500 | ret = it913x_wr_reg(udev, DEV_0, |
392 | GPIOH1_O, 0x0); | 501 | GPIOH1_O, 0x0); |
502 | props->num_adapters = 2; | ||
393 | } | 503 | } |
394 | props->num_adapters = 2; | ||
395 | } else | 504 | } else |
396 | props->num_adapters = 1; | 505 | props->num_adapters = 1; |
397 | 506 | ||
@@ -399,10 +508,16 @@ static int it913x_identify_state(struct usb_device *udev, | |||
399 | 508 | ||
400 | if (it913x_config.dual_mode) { | 509 | if (it913x_config.dual_mode) { |
401 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); | 510 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); |
402 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); | 511 | if (it913x_config.firmware_ver == 1) |
512 | ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x1); | ||
513 | else | ||
514 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); | ||
403 | } else { | 515 | } else { |
404 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0); | 516 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0); |
405 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); | 517 | if (it913x_config.firmware_ver == 1) |
518 | ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x0); | ||
519 | else | ||
520 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); | ||
406 | } | 521 | } |
407 | 522 | ||
408 | *cold = 1; | 523 | *cold = 1; |
@@ -428,35 +543,40 @@ static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
428 | return ret; | 543 | return ret; |
429 | } | 544 | } |
430 | 545 | ||
431 | |||
432 | static int it913x_download_firmware(struct usb_device *udev, | 546 | static int it913x_download_firmware(struct usb_device *udev, |
433 | const struct firmware *fw) | 547 | const struct firmware *fw) |
434 | { | 548 | { |
435 | int ret = 0, i; | 549 | int ret = 0, i = 0, pos = 0; |
436 | u8 packet_size, dlen; | 550 | u8 packet_size; |
437 | u8 *fw_data; | 551 | u8 *fw_data; |
438 | 552 | ||
439 | packet_size = 0x29; | ||
440 | |||
441 | ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); | 553 | ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); |
442 | 554 | ||
443 | info("FRM Starting Firmware Download"); | 555 | info("FRM Starting Firmware Download"); |
444 | /* This uses scatter write firmware headers follow */ | 556 | |
445 | /* 03 XX 00 XX = chip number? */ | 557 | /* Multi firmware loader */ |
446 | 558 | /* This uses scatter write firmware headers */ | |
447 | for (i = 0; i < fw->size; i += packet_size) { | 559 | /* The firmware must start with 03 XX 00 */ |
448 | if (i > 0) | 560 | /* and be the extact firmware length */ |
449 | packet_size = 0x39; | 561 | |
450 | fw_data = (u8 *)(fw->data + i); | 562 | while (i <= fw->size) { |
451 | dlen = ((i + packet_size) > fw->size) | 563 | if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0)) |
452 | ? (fw->size - i) : packet_size; | 564 | || (i == fw->size)) { |
453 | ret |= it913x_io(udev, WRITE_DATA, DEV_0, | 565 | packet_size = i - pos; |
454 | CMD_SCATTER_WRITE, 0, 0, fw_data, dlen); | 566 | if ((packet_size > 0x19) || (i == fw->size)) { |
455 | udelay(1000); | 567 | fw_data = (u8 *)(fw->data + pos); |
568 | pos += packet_size; | ||
569 | if (packet_size > 0) | ||
570 | ret |= it913x_io(udev, WRITE_DATA, | ||
571 | DEV_0, CMD_SCATTER_WRITE, 0, | ||
572 | 0, fw_data, packet_size); | ||
573 | udelay(1000); | ||
574 | } | ||
575 | } | ||
576 | i++; | ||
456 | } | 577 | } |
457 | 578 | ||
458 | ret |= it913x_io(udev, WRITE_CMD, DEV_0, | 579 | ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); |
459 | CMD_BOOT, 0, 0, NULL, 0); | ||
460 | 580 | ||
461 | msleep(100); | 581 | msleep(100); |
462 | 582 | ||
@@ -474,12 +594,17 @@ static int it913x_download_firmware(struct usb_device *udev, | |||
474 | /* Tuner function */ | 594 | /* Tuner function */ |
475 | if (it913x_config.dual_mode) | 595 | if (it913x_config.dual_mode) |
476 | ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); | 596 | ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); |
477 | 597 | else | |
478 | ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); | 598 | ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0x68); |
479 | ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); | 599 | |
480 | if (it913x_config.dual_mode) { | 600 | if ((it913x_config.chip_ver == 1) && |
481 | ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); | 601 | (it913x_config.chip_type == 0x9135)) { |
482 | ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); | 602 | ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); |
603 | ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); | ||
604 | if (it913x_config.dual_mode) { | ||
605 | ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); | ||
606 | ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); | ||
607 | } | ||
483 | } | 608 | } |
484 | 609 | ||
485 | return (ret < 0) ? -ENODEV : 0; | 610 | return (ret < 0) ? -ENODEV : 0; |
@@ -500,32 +625,23 @@ static int it913x_name(struct dvb_usb_adapter *adap) | |||
500 | static int it913x_frontend_attach(struct dvb_usb_adapter *adap) | 625 | static int it913x_frontend_attach(struct dvb_usb_adapter *adap) |
501 | { | 626 | { |
502 | struct usb_device *udev = adap->dev->udev; | 627 | struct usb_device *udev = adap->dev->udev; |
628 | struct it913x_state *st = adap->dev->priv; | ||
503 | int ret = 0; | 629 | int ret = 0; |
504 | u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); | ||
505 | u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); | 630 | u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); |
506 | u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; | 631 | u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize / 4; |
507 | u8 tuner_id, tuner_type; | 632 | u8 pkt_size = 0x80; |
633 | |||
634 | if (adap->dev->udev->speed != USB_SPEED_HIGH) | ||
635 | pkt_size = 0x10; | ||
636 | |||
637 | it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); | ||
508 | 638 | ||
509 | if (adap->id == 0) | 639 | if (adap->id == 0) |
510 | tuner_id = it913x_config.tuner_id_0; | 640 | memcpy(&st->it913x_config, &it913x_config, |
511 | else | 641 | sizeof(struct ite_config)); |
512 | tuner_id = it913x_config.tuner_id_1; | ||
513 | |||
514 | /* TODO we always use IT9137 possible references here*/ | ||
515 | /* Documentation suggests don't care */ | ||
516 | switch (tuner_id) { | ||
517 | case 0x51: | ||
518 | case 0x52: | ||
519 | case 0x60: | ||
520 | case 0x61: | ||
521 | case 0x62: | ||
522 | default: | ||
523 | case 0x38: | ||
524 | tuner_type = IT9137; | ||
525 | } | ||
526 | 642 | ||
527 | adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, | 643 | adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, |
528 | &adap->dev->i2c_adap, adap_addr, adf, tuner_type); | 644 | &adap->dev->i2c_adap, adap_addr, &st->it913x_config); |
529 | 645 | ||
530 | if (adap->id == 0 && adap->fe_adap[0].fe) { | 646 | if (adap->id == 0 && adap->fe_adap[0].fe) { |
531 | ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); | 647 | ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); |
@@ -536,13 +652,13 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) | |||
536 | ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB, | 652 | ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB, |
537 | ep_size & 0xff); | 653 | ep_size & 0xff); |
538 | ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8); | 654 | ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8); |
539 | ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, 0x80); | 655 | ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, pkt_size); |
540 | } else if (adap->id == 1 && adap->fe_adap[0].fe) { | 656 | } else if (adap->id == 1 && adap->fe_adap[0].fe) { |
541 | ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f); | 657 | ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f); |
542 | ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB, | 658 | ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB, |
543 | ep_size & 0xff); | 659 | ep_size & 0xff); |
544 | ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8); | 660 | ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8); |
545 | ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, 0x80); | 661 | ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, pkt_size); |
546 | ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1); | 662 | ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1); |
547 | ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1); | 663 | ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1); |
548 | ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1); | 664 | ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1); |
@@ -582,6 +698,8 @@ static int it913x_probe(struct usb_interface *intf, | |||
582 | static struct usb_device_id it913x_table[] = { | 698 | static struct usb_device_id it913x_table[] = { |
583 | { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, | 699 | { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, |
584 | { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, | 700 | { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, |
701 | { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137) }, | ||
702 | { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005) }, | ||
585 | {} /* Terminating entry */ | 703 | {} /* Terminating entry */ |
586 | }; | 704 | }; |
587 | 705 | ||
@@ -614,8 +732,8 @@ static struct dvb_usb_device_properties it913x_properties = { | |||
614 | .endpoint = 0x04, | 732 | .endpoint = 0x04, |
615 | .u = {/* Keep Low if PID filter on */ | 733 | .u = {/* Keep Low if PID filter on */ |
616 | .bulk = { | 734 | .bulk = { |
617 | .buffersize = 3584, | 735 | .buffersize = |
618 | 736 | TS_BUFFER_SIZE_PID, | |
619 | } | 737 | } |
620 | } | 738 | } |
621 | } | 739 | } |
@@ -639,8 +757,8 @@ static struct dvb_usb_device_properties it913x_properties = { | |||
639 | .endpoint = 0x05, | 757 | .endpoint = 0x05, |
640 | .u = { | 758 | .u = { |
641 | .bulk = { | 759 | .bulk = { |
642 | .buffersize = 3584, | 760 | .buffersize = |
643 | 761 | TS_BUFFER_SIZE_PID, | |
644 | } | 762 | } |
645 | } | 763 | } |
646 | } | 764 | } |
@@ -654,10 +772,10 @@ static struct dvb_usb_device_properties it913x_properties = { | |||
654 | .rc_query = it913x_rc_query, | 772 | .rc_query = it913x_rc_query, |
655 | .rc_interval = IT913X_POLL, | 773 | .rc_interval = IT913X_POLL, |
656 | .allowed_protos = RC_TYPE_NEC, | 774 | .allowed_protos = RC_TYPE_NEC, |
657 | .rc_codes = RC_MAP_KWORLD_315U, | 775 | .rc_codes = RC_MAP_MSI_DIGIVOX_III, |
658 | }, | 776 | }, |
659 | .i2c_algo = &it913x_i2c_algo, | 777 | .i2c_algo = &it913x_i2c_algo, |
660 | .num_device_descs = 2, | 778 | .num_device_descs = 3, |
661 | .devices = { | 779 | .devices = { |
662 | { "Kworld UB499-2T T09(IT9137)", | 780 | { "Kworld UB499-2T T09(IT9137)", |
663 | { &it913x_table[0], NULL }, | 781 | { &it913x_table[0], NULL }, |
@@ -665,6 +783,12 @@ static struct dvb_usb_device_properties it913x_properties = { | |||
665 | { "ITE 9135 Generic", | 783 | { "ITE 9135 Generic", |
666 | { &it913x_table[1], NULL }, | 784 | { &it913x_table[1], NULL }, |
667 | }, | 785 | }, |
786 | { "Sveon STV22 Dual DVB-T HDTV(IT9137)", | ||
787 | { &it913x_table[2], NULL }, | ||
788 | }, | ||
789 | { "ITE 9135(9005) Generic", | ||
790 | { &it913x_table[3], NULL }, | ||
791 | }, | ||
668 | } | 792 | } |
669 | }; | 793 | }; |
670 | 794 | ||
@@ -698,5 +822,5 @@ module_exit(it913x_module_exit); | |||
698 | 822 | ||
699 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); | 823 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); |
700 | MODULE_DESCRIPTION("it913x USB 2 Driver"); | 824 | MODULE_DESCRIPTION("it913x USB 2 Driver"); |
701 | MODULE_VERSION("1.07"); | 825 | MODULE_VERSION("1.14"); |
702 | MODULE_LICENSE("GPL"); | 826 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c index a6341058c4e7..3bfc6d8368a8 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c | |||
@@ -38,6 +38,8 @@ struct mxl111sf_tuner_state { | |||
38 | 38 | ||
39 | struct mxl111sf_tuner_config *cfg; | 39 | struct mxl111sf_tuner_config *cfg; |
40 | 40 | ||
41 | enum mxl_if_freq if_freq; | ||
42 | |||
41 | u32 frequency; | 43 | u32 frequency; |
42 | u32 bandwidth; | 44 | u32 bandwidth; |
43 | }; | 45 | }; |
@@ -186,7 +188,10 @@ static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state) | |||
186 | ctrl = iffcw & 0x00ff; | 188 | ctrl = iffcw & 0x00ff; |
187 | #endif | 189 | #endif |
188 | ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl); | 190 | ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl); |
189 | mxl_fail(ret); | 191 | if (mxl_fail(ret)) |
192 | goto fail; | ||
193 | |||
194 | state->if_freq = state->cfg->if_freq; | ||
190 | fail: | 195 | fail: |
191 | return ret; | 196 | return ret; |
192 | } | 197 | } |
@@ -407,6 +412,54 @@ static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
407 | return 0; | 412 | return 0; |
408 | } | 413 | } |
409 | 414 | ||
415 | static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe, | ||
416 | u32 *frequency) | ||
417 | { | ||
418 | struct mxl111sf_tuner_state *state = fe->tuner_priv; | ||
419 | |||
420 | *frequency = 0; | ||
421 | |||
422 | switch (state->if_freq) { | ||
423 | case MXL_IF_4_0: /* 4.0 MHz */ | ||
424 | *frequency = 4000000; | ||
425 | break; | ||
426 | case MXL_IF_4_5: /* 4.5 MHz */ | ||
427 | *frequency = 4500000; | ||
428 | break; | ||
429 | case MXL_IF_4_57: /* 4.57 MHz */ | ||
430 | *frequency = 4570000; | ||
431 | break; | ||
432 | case MXL_IF_5_0: /* 5.0 MHz */ | ||
433 | *frequency = 5000000; | ||
434 | break; | ||
435 | case MXL_IF_5_38: /* 5.38 MHz */ | ||
436 | *frequency = 5380000; | ||
437 | break; | ||
438 | case MXL_IF_6_0: /* 6.0 MHz */ | ||
439 | *frequency = 6000000; | ||
440 | break; | ||
441 | case MXL_IF_6_28: /* 6.28 MHz */ | ||
442 | *frequency = 6280000; | ||
443 | break; | ||
444 | case MXL_IF_7_2: /* 7.2 MHz */ | ||
445 | *frequency = 7200000; | ||
446 | break; | ||
447 | case MXL_IF_35_25: /* 35.25 MHz */ | ||
448 | *frequency = 35250000; | ||
449 | break; | ||
450 | case MXL_IF_36: /* 36 MHz */ | ||
451 | *frequency = 36000000; | ||
452 | break; | ||
453 | case MXL_IF_36_15: /* 36.15 MHz */ | ||
454 | *frequency = 36150000; | ||
455 | break; | ||
456 | case MXL_IF_44: /* 44 MHz */ | ||
457 | *frequency = 44000000; | ||
458 | break; | ||
459 | } | ||
460 | return 0; | ||
461 | } | ||
462 | |||
410 | static int mxl111sf_tuner_release(struct dvb_frontend *fe) | 463 | static int mxl111sf_tuner_release(struct dvb_frontend *fe) |
411 | { | 464 | { |
412 | struct mxl111sf_tuner_state *state = fe->tuner_priv; | 465 | struct mxl111sf_tuner_state *state = fe->tuner_priv; |
@@ -436,6 +489,7 @@ static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = { | |||
436 | .get_rf_strength = mxl111sf_get_rf_strength, | 489 | .get_rf_strength = mxl111sf_get_rf_strength, |
437 | .get_frequency = mxl111sf_tuner_get_frequency, | 490 | .get_frequency = mxl111sf_tuner_get_frequency, |
438 | .get_bandwidth = mxl111sf_tuner_get_bandwidth, | 491 | .get_bandwidth = mxl111sf_tuner_get_bandwidth, |
492 | .get_if_frequency = mxl111sf_tuner_get_if_frequency, | ||
439 | .release = mxl111sf_tuner_release, | 493 | .release = mxl111sf_tuner_release, |
440 | }; | 494 | }; |
441 | 495 | ||
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c index b5c98da5d9e2..34e6f8d94dc2 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf.c | |||
@@ -758,6 +758,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); | |||
758 | 758 | ||
759 | 759 | ||
760 | #define MXL111SF_EP4_BULK_STREAMING_CONFIG \ | 760 | #define MXL111SF_EP4_BULK_STREAMING_CONFIG \ |
761 | .size_of_priv = sizeof(struct mxl111sf_adap_state), \ | ||
761 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ | 762 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ |
762 | .stream = { \ | 763 | .stream = { \ |
763 | .type = USB_BULK, \ | 764 | .type = USB_BULK, \ |
@@ -772,6 +773,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); | |||
772 | 773 | ||
773 | /* FIXME: works for v6 but not v8 silicon */ | 774 | /* FIXME: works for v6 but not v8 silicon */ |
774 | #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \ | 775 | #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \ |
776 | .size_of_priv = sizeof(struct mxl111sf_adap_state), \ | ||
775 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ | 777 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ |
776 | .stream = { \ | 778 | .stream = { \ |
777 | .type = USB_ISOC, \ | 779 | .type = USB_ISOC, \ |
@@ -788,6 +790,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); | |||
788 | } | 790 | } |
789 | 791 | ||
790 | #define MXL111SF_EP6_BULK_STREAMING_CONFIG \ | 792 | #define MXL111SF_EP6_BULK_STREAMING_CONFIG \ |
793 | .size_of_priv = sizeof(struct mxl111sf_adap_state), \ | ||
791 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ | 794 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ |
792 | .stream = { \ | 795 | .stream = { \ |
793 | .type = USB_BULK, \ | 796 | .type = USB_BULK, \ |
@@ -802,6 +805,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); | |||
802 | 805 | ||
803 | /* FIXME */ | 806 | /* FIXME */ |
804 | #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \ | 807 | #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \ |
808 | .size_of_priv = sizeof(struct mxl111sf_adap_state), \ | ||
805 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ | 809 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ |
806 | .stream = { \ | 810 | .stream = { \ |
807 | .type = USB_ISOC, \ | 811 | .type = USB_ISOC, \ |
@@ -839,8 +843,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = { | |||
839 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | 843 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, |
840 | .num_frontends = 1, | 844 | .num_frontends = 1, |
841 | .fe = {{ | 845 | .fe = {{ |
842 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
843 | |||
844 | .frontend_attach = mxl111sf_attach_demod, | 846 | .frontend_attach = mxl111sf_attach_demod, |
845 | .tuner_attach = mxl111sf_attach_tuner, | 847 | .tuner_attach = mxl111sf_attach_tuner, |
846 | 848 | ||
@@ -883,8 +885,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = { | |||
883 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | 885 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, |
884 | .num_frontends = 1, | 886 | .num_frontends = 1, |
885 | .fe = {{ | 887 | .fe = {{ |
886 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
887 | |||
888 | .frontend_attach = mxl111sf_attach_demod, | 888 | .frontend_attach = mxl111sf_attach_demod, |
889 | .tuner_attach = mxl111sf_attach_tuner, | 889 | .tuner_attach = mxl111sf_attach_tuner, |
890 | 890 | ||
@@ -927,16 +927,12 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { | |||
927 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | 927 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, |
928 | .num_frontends = 2, | 928 | .num_frontends = 2, |
929 | .fe = {{ | 929 | .fe = {{ |
930 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
931 | |||
932 | .frontend_attach = mxl111sf_lgdt3305_frontend_attach, | 930 | .frontend_attach = mxl111sf_lgdt3305_frontend_attach, |
933 | .tuner_attach = mxl111sf_attach_tuner, | 931 | .tuner_attach = mxl111sf_attach_tuner, |
934 | 932 | ||
935 | MXL111SF_EP6_BULK_STREAMING_CONFIG, | 933 | MXL111SF_EP6_BULK_STREAMING_CONFIG, |
936 | }, | 934 | }, |
937 | { | 935 | { |
938 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
939 | |||
940 | .frontend_attach = mxl111sf_attach_demod, | 936 | .frontend_attach = mxl111sf_attach_demod, |
941 | .tuner_attach = mxl111sf_attach_tuner, | 937 | .tuner_attach = mxl111sf_attach_tuner, |
942 | 938 | ||
@@ -992,16 +988,12 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { | |||
992 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | 988 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, |
993 | .num_frontends = 2, | 989 | .num_frontends = 2, |
994 | .fe = {{ | 990 | .fe = {{ |
995 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
996 | |||
997 | .frontend_attach = mxl111sf_lgdt3305_frontend_attach, | 991 | .frontend_attach = mxl111sf_lgdt3305_frontend_attach, |
998 | .tuner_attach = mxl111sf_attach_tuner, | 992 | .tuner_attach = mxl111sf_attach_tuner, |
999 | 993 | ||
1000 | MXL111SF_EP6_ISOC_STREAMING_CONFIG, | 994 | MXL111SF_EP6_ISOC_STREAMING_CONFIG, |
1001 | }, | 995 | }, |
1002 | { | 996 | { |
1003 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
1004 | |||
1005 | .frontend_attach = mxl111sf_attach_demod, | 997 | .frontend_attach = mxl111sf_attach_demod, |
1006 | .tuner_attach = mxl111sf_attach_tuner, | 998 | .tuner_attach = mxl111sf_attach_tuner, |
1007 | 999 | ||
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index ea4eab8b3965..bc50356c5fb6 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c | |||
@@ -75,10 +75,18 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, | |||
75 | u8 *wbuf, int wlen, u8 *rbuf, int rlen) | 75 | u8 *wbuf, int wlen, u8 *rbuf, int rlen) |
76 | { | 76 | { |
77 | struct ttusb2_state *st = d->priv; | 77 | struct ttusb2_state *st = d->priv; |
78 | u8 s[wlen+4],r[64] = { 0 }; | 78 | u8 *s, *r = NULL; |
79 | int ret = 0; | 79 | int ret = 0; |
80 | 80 | ||
81 | memset(s,0,wlen+4); | 81 | s = kzalloc(wlen+4, GFP_KERNEL); |
82 | if (!s) | ||
83 | return -ENOMEM; | ||
84 | |||
85 | r = kzalloc(64, GFP_KERNEL); | ||
86 | if (!r) { | ||
87 | kfree(s); | ||
88 | return -ENOMEM; | ||
89 | } | ||
82 | 90 | ||
83 | s[0] = 0xaa; | 91 | s[0] = 0xaa; |
84 | s[1] = ++st->id; | 92 | s[1] = ++st->id; |
@@ -94,12 +102,17 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, | |||
94 | r[2] != cmd || | 102 | r[2] != cmd || |
95 | (rlen > 0 && r[3] != rlen)) { | 103 | (rlen > 0 && r[3] != rlen)) { |
96 | warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); | 104 | warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); |
105 | kfree(s); | ||
106 | kfree(r); | ||
97 | return -EIO; | 107 | return -EIO; |
98 | } | 108 | } |
99 | 109 | ||
100 | if (rlen > 0) | 110 | if (rlen > 0) |
101 | memcpy(rbuf, &r[4], rlen); | 111 | memcpy(rbuf, &r[4], rlen); |
102 | 112 | ||
113 | kfree(s); | ||
114 | kfree(r); | ||
115 | |||
103 | return 0; | 116 | return 0; |
104 | } | 117 | } |
105 | 118 | ||
@@ -384,7 +397,7 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
384 | 397 | ||
385 | memcpy(&obuf[3], msg[i].buf, msg[i].len); | 398 | memcpy(&obuf[3], msg[i].buf, msg[i].len); |
386 | 399 | ||
387 | if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { | 400 | if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) { |
388 | err("i2c transfer failed."); | 401 | err("i2c transfer failed."); |
389 | break; | 402 | break; |
390 | } | 403 | } |
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 489ae8245867..9debf0f9a137 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c | |||
@@ -392,10 +392,11 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, | |||
392 | default: c->operand[13] = 0x2; break; | 392 | default: c->operand[13] = 0x2; break; |
393 | } | 393 | } |
394 | switch (fdtv->fe.dtv_property_cache.rolloff) { | 394 | switch (fdtv->fe.dtv_property_cache.rolloff) { |
395 | case ROLLOFF_AUTO: c->operand[14] = 0x2; break; | ||
396 | case ROLLOFF_35: c->operand[14] = 0x2; break; | 395 | case ROLLOFF_35: c->operand[14] = 0x2; break; |
397 | case ROLLOFF_20: c->operand[14] = 0x0; break; | 396 | case ROLLOFF_20: c->operand[14] = 0x0; break; |
398 | case ROLLOFF_25: c->operand[14] = 0x1; break; | 397 | case ROLLOFF_25: c->operand[14] = 0x1; break; |
398 | case ROLLOFF_AUTO: | ||
399 | default: c->operand[14] = 0x2; break; | ||
399 | /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */ | 400 | /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */ |
400 | } | 401 | } |
401 | switch (fdtv->fe.dtv_property_cache.pilot) { | 402 | switch (fdtv->fe.dtv_property_cache.pilot) { |
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 345311c33383..f4276e471d38 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -303,7 +303,8 @@ error: | |||
303 | return ret; | 303 | return ret; |
304 | } | 304 | } |
305 | 305 | ||
306 | static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) | 306 | static int af9013_set_freq_ctrl(struct af9013_state *state, |
307 | struct dvb_frontend *fe) | ||
307 | { | 308 | { |
308 | int ret; | 309 | int ret; |
309 | u16 addr; | 310 | u16 addr; |
@@ -324,37 +325,13 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) | |||
324 | bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; | 325 | bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; |
325 | } | 326 | } |
326 | 327 | ||
327 | adc_freq = state->config.adc_clock * 1000; | 328 | adc_freq = state->config.adc_clock * 1000; |
328 | if_sample_freq = state->config.tuner_if * 1000; | ||
329 | 329 | ||
330 | /* TDA18271 uses different sampling freq for every bw */ | 330 | /* get used IF frequency */ |
331 | if (state->config.tuner == AF9013_TUNER_TDA18271) { | 331 | if (fe->ops.tuner_ops.get_if_frequency) |
332 | switch (bw) { | 332 | fe->ops.tuner_ops.get_if_frequency(fe, &if_sample_freq); |
333 | case BANDWIDTH_6_MHZ: | 333 | else |
334 | if_sample_freq = 3300000; /* 3.3 MHz */ | 334 | if_sample_freq = state->config.tuner_if * 1000; |
335 | break; | ||
336 | case BANDWIDTH_7_MHZ: | ||
337 | if_sample_freq = 3500000; /* 3.5 MHz */ | ||
338 | break; | ||
339 | case BANDWIDTH_8_MHZ: | ||
340 | default: | ||
341 | if_sample_freq = 4000000; /* 4.0 MHz */ | ||
342 | break; | ||
343 | } | ||
344 | } else if (state->config.tuner == AF9013_TUNER_TDA18218) { | ||
345 | switch (bw) { | ||
346 | case BANDWIDTH_6_MHZ: | ||
347 | if_sample_freq = 3000000; /* 3 MHz */ | ||
348 | break; | ||
349 | case BANDWIDTH_7_MHZ: | ||
350 | if_sample_freq = 3500000; /* 3.5 MHz */ | ||
351 | break; | ||
352 | case BANDWIDTH_8_MHZ: | ||
353 | default: | ||
354 | if_sample_freq = 4000000; /* 4 MHz */ | ||
355 | break; | ||
356 | } | ||
357 | } | ||
358 | 335 | ||
359 | while (if_sample_freq > (adc_freq / 2)) | 336 | while (if_sample_freq > (adc_freq / 2)) |
360 | if_sample_freq = if_sample_freq - adc_freq; | 337 | if_sample_freq = if_sample_freq - adc_freq; |
@@ -639,7 +616,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe, | |||
639 | goto error; | 616 | goto error; |
640 | 617 | ||
641 | /* program frequency control */ | 618 | /* program frequency control */ |
642 | ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); | 619 | ret = af9013_set_freq_ctrl(state, fe); |
643 | if (ret) | 620 | if (ret) |
644 | goto error; | 621 | goto error; |
645 | 622 | ||
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 1d572940e243..5c0d3989f5bd 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c | |||
@@ -862,7 +862,36 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
862 | static int au8522_read_signal_strength(struct dvb_frontend *fe, | 862 | static int au8522_read_signal_strength(struct dvb_frontend *fe, |
863 | u16 *signal_strength) | 863 | u16 *signal_strength) |
864 | { | 864 | { |
865 | return au8522_read_snr(fe, signal_strength); | 865 | /* borrowed from lgdt330x.c |
866 | * | ||
867 | * Calculate strength from SNR up to 35dB | ||
868 | * Even though the SNR can go higher than 35dB, | ||
869 | * there is some comfort factor in having a range of | ||
870 | * strong signals that can show at 100% | ||
871 | */ | ||
872 | u16 snr; | ||
873 | u32 tmp; | ||
874 | int ret = au8522_read_snr(fe, &snr); | ||
875 | |||
876 | *signal_strength = 0; | ||
877 | |||
878 | if (0 == ret) { | ||
879 | /* The following calculation method was chosen | ||
880 | * purely for the sake of code re-use from the | ||
881 | * other demod drivers that use this method */ | ||
882 | |||
883 | /* Convert from SNR in dB * 10 to 8.24 fixed-point */ | ||
884 | tmp = (snr * ((1 << 24) / 10)); | ||
885 | |||
886 | /* Convert from 8.24 fixed-point to | ||
887 | * scale the range 0 - 35*2^24 into 0 - 65535*/ | ||
888 | if (tmp >= 8960 * 0x10000) | ||
889 | *signal_strength = 0xffff; | ||
890 | else | ||
891 | *signal_strength = tmp / 8960; | ||
892 | } | ||
893 | |||
894 | return ret; | ||
866 | } | 895 | } |
867 | 896 | ||
868 | static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 897 | static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h index 03cab7b547fb..cf0f546aa1d1 100644 --- a/drivers/media/dvb/frontends/cxd2820r.h +++ b/drivers/media/dvb/frontends/cxd2820r.h | |||
@@ -63,19 +63,6 @@ struct cxd2820r_config { | |||
63 | */ | 63 | */ |
64 | bool spec_inv; | 64 | bool spec_inv; |
65 | 65 | ||
66 | /* IFs for all used modes. | ||
67 | * Default: none, must set | ||
68 | * Values: <kHz> | ||
69 | */ | ||
70 | u16 if_dvbt_6; | ||
71 | u16 if_dvbt_7; | ||
72 | u16 if_dvbt_8; | ||
73 | u16 if_dvbt2_5; | ||
74 | u16 if_dvbt2_6; | ||
75 | u16 if_dvbt2_7; | ||
76 | u16 if_dvbt2_8; | ||
77 | u16 if_dvbc; | ||
78 | |||
79 | /* GPIOs for all used modes. | 66 | /* GPIOs for all used modes. |
80 | * Default: none, disabled | 67 | * Default: none, disabled |
81 | * Values: <see above> | 68 | * Values: <see above> |
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index b85f5011e344..c4128773f2ee 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c | |||
@@ -28,6 +28,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe, | |||
28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
29 | int ret, i; | 29 | int ret, i; |
30 | u8 buf[2]; | 30 | u8 buf[2]; |
31 | u32 if_freq; | ||
31 | u16 if_ctl; | 32 | u16 if_ctl; |
32 | u64 num; | 33 | u64 num; |
33 | struct reg_val_mask tab[] = { | 34 | struct reg_val_mask tab[] = { |
@@ -70,7 +71,17 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe, | |||
70 | priv->delivery_system = SYS_DVBC_ANNEX_AC; | 71 | priv->delivery_system = SYS_DVBC_ANNEX_AC; |
71 | priv->ber_running = 0; /* tune stops BER counter */ | 72 | priv->ber_running = 0; /* tune stops BER counter */ |
72 | 73 | ||
73 | num = priv->cfg.if_dvbc; | 74 | /* program IF frequency */ |
75 | if (fe->ops.tuner_ops.get_if_frequency) { | ||
76 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); | ||
77 | if (ret) | ||
78 | goto error; | ||
79 | } else | ||
80 | if_freq = 0; | ||
81 | |||
82 | dbg("%s: if_freq=%d", __func__, if_freq); | ||
83 | |||
84 | num = if_freq / 1000; /* Hz => kHz */ | ||
74 | num *= 0x4000; | 85 | num *= 0x4000; |
75 | if_ctl = cxd2820r_div_u64_round_closest(num, 41000); | 86 | if_ctl = cxd2820r_div_u64_round_closest(num, 41000); |
76 | buf[0] = (if_ctl >> 8) & 0x3f; | 87 | buf[0] = (if_ctl >> 8) & 0x3f; |
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c index a04f9c810101..b1450ac4b683 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t.c +++ b/drivers/media/dvb/frontends/cxd2820r_t.c | |||
@@ -26,8 +26,8 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, | |||
26 | { | 26 | { |
27 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 27 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
29 | int ret, i; | 29 | int ret, i, bw_i; |
30 | u32 if_khz, if_ctl; | 30 | u32 if_freq, if_ctl; |
31 | u64 num; | 31 | u64 num; |
32 | u8 buf[3], bw_param; | 32 | u8 buf[3], bw_param; |
33 | u8 bw_params1[][5] = { | 33 | u8 bw_params1[][5] = { |
@@ -57,6 +57,23 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, | |||
57 | 57 | ||
58 | dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); | 58 | dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); |
59 | 59 | ||
60 | switch (c->bandwidth_hz) { | ||
61 | case 6000000: | ||
62 | bw_i = 0; | ||
63 | bw_param = 2; | ||
64 | break; | ||
65 | case 7000000: | ||
66 | bw_i = 1; | ||
67 | bw_param = 1; | ||
68 | break; | ||
69 | case 8000000: | ||
70 | bw_i = 2; | ||
71 | bw_param = 0; | ||
72 | break; | ||
73 | default: | ||
74 | return -EINVAL; | ||
75 | } | ||
76 | |||
60 | /* update GPIOs */ | 77 | /* update GPIOs */ |
61 | ret = cxd2820r_gpio(fe); | 78 | ret = cxd2820r_gpio(fe); |
62 | if (ret) | 79 | if (ret) |
@@ -78,27 +95,17 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, | |||
78 | priv->delivery_system = SYS_DVBT; | 95 | priv->delivery_system = SYS_DVBT; |
79 | priv->ber_running = 0; /* tune stops BER counter */ | 96 | priv->ber_running = 0; /* tune stops BER counter */ |
80 | 97 | ||
81 | switch (c->bandwidth_hz) { | 98 | /* program IF frequency */ |
82 | case 6000000: | 99 | if (fe->ops.tuner_ops.get_if_frequency) { |
83 | if_khz = priv->cfg.if_dvbt_6; | 100 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); |
84 | i = 0; | 101 | if (ret) |
85 | bw_param = 2; | 102 | goto error; |
86 | break; | 103 | } else |
87 | case 7000000: | 104 | if_freq = 0; |
88 | if_khz = priv->cfg.if_dvbt_7; | 105 | |
89 | i = 1; | 106 | dbg("%s: if_freq=%d", __func__, if_freq); |
90 | bw_param = 1; | ||
91 | break; | ||
92 | case 8000000: | ||
93 | if_khz = priv->cfg.if_dvbt_8; | ||
94 | i = 2; | ||
95 | bw_param = 0; | ||
96 | break; | ||
97 | default: | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | 107 | ||
101 | num = if_khz; | 108 | num = if_freq / 1000; /* Hz => kHz */ |
102 | num *= 0x1000000; | 109 | num *= 0x1000000; |
103 | if_ctl = cxd2820r_div_u64_round_closest(num, 41000); | 110 | if_ctl = cxd2820r_div_u64_round_closest(num, 41000); |
104 | buf[0] = ((if_ctl >> 16) & 0xff); | 111 | buf[0] = ((if_ctl >> 16) & 0xff); |
@@ -109,7 +116,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, | |||
109 | if (ret) | 116 | if (ret) |
110 | goto error; | 117 | goto error; |
111 | 118 | ||
112 | ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5); | 119 | ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5); |
113 | if (ret) | 120 | if (ret) |
114 | goto error; | 121 | goto error; |
115 | 122 | ||
@@ -117,7 +124,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, | |||
117 | if (ret) | 124 | if (ret) |
118 | goto error; | 125 | goto error; |
119 | 126 | ||
120 | ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2); | 127 | ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2); |
121 | if (ret) | 128 | if (ret) |
122 | goto error; | 129 | goto error; |
123 | 130 | ||
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c index 6548588309f7..e21fc97291a8 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t2.c +++ b/drivers/media/dvb/frontends/cxd2820r_t2.c | |||
@@ -26,8 +26,8 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, | |||
26 | { | 26 | { |
27 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 27 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
29 | int ret, i; | 29 | int ret, i, bw_i; |
30 | u32 if_khz, if_ctl; | 30 | u32 if_freq, if_ctl; |
31 | u64 num; | 31 | u64 num; |
32 | u8 buf[3], bw_param; | 32 | u8 buf[3], bw_param; |
33 | u8 bw_params1[][5] = { | 33 | u8 bw_params1[][5] = { |
@@ -71,6 +71,27 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, | |||
71 | 71 | ||
72 | dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); | 72 | dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); |
73 | 73 | ||
74 | switch (c->bandwidth_hz) { | ||
75 | case 5000000: | ||
76 | bw_i = 0; | ||
77 | bw_param = 3; | ||
78 | break; | ||
79 | case 6000000: | ||
80 | bw_i = 1; | ||
81 | bw_param = 2; | ||
82 | break; | ||
83 | case 7000000: | ||
84 | bw_i = 2; | ||
85 | bw_param = 1; | ||
86 | break; | ||
87 | case 8000000: | ||
88 | bw_i = 3; | ||
89 | bw_param = 0; | ||
90 | break; | ||
91 | default: | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
74 | /* update GPIOs */ | 95 | /* update GPIOs */ |
75 | ret = cxd2820r_gpio(fe); | 96 | ret = cxd2820r_gpio(fe); |
76 | if (ret) | 97 | if (ret) |
@@ -91,32 +112,17 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, | |||
91 | 112 | ||
92 | priv->delivery_system = SYS_DVBT2; | 113 | priv->delivery_system = SYS_DVBT2; |
93 | 114 | ||
94 | switch (c->bandwidth_hz) { | 115 | /* program IF frequency */ |
95 | case 5000000: | 116 | if (fe->ops.tuner_ops.get_if_frequency) { |
96 | if_khz = priv->cfg.if_dvbt2_5; | 117 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); |
97 | i = 0; | 118 | if (ret) |
98 | bw_param = 3; | 119 | goto error; |
99 | break; | 120 | } else |
100 | case 6000000: | 121 | if_freq = 0; |
101 | if_khz = priv->cfg.if_dvbt2_6; | 122 | |
102 | i = 1; | 123 | dbg("%s: if_freq=%d", __func__, if_freq); |
103 | bw_param = 2; | ||
104 | break; | ||
105 | case 7000000: | ||
106 | if_khz = priv->cfg.if_dvbt2_7; | ||
107 | i = 2; | ||
108 | bw_param = 1; | ||
109 | break; | ||
110 | case 8000000: | ||
111 | if_khz = priv->cfg.if_dvbt2_8; | ||
112 | i = 3; | ||
113 | bw_param = 0; | ||
114 | break; | ||
115 | default: | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | 124 | ||
119 | num = if_khz; | 125 | num = if_freq / 1000; /* Hz => kHz */ |
120 | num *= 0x1000000; | 126 | num *= 0x1000000; |
121 | if_ctl = cxd2820r_div_u64_round_closest(num, 41000); | 127 | if_ctl = cxd2820r_div_u64_round_closest(num, 41000); |
122 | buf[0] = ((if_ctl >> 16) & 0xff); | 128 | buf[0] = ((if_ctl >> 16) & 0xff); |
@@ -127,7 +133,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, | |||
127 | if (ret) | 133 | if (ret) |
128 | goto error; | 134 | goto error; |
129 | 135 | ||
130 | ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5); | 136 | ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5); |
131 | if (ret) | 137 | if (ret) |
132 | goto error; | 138 | goto error; |
133 | 139 | ||
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index b174d1c78583..2b30ab2ade5e 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c | |||
@@ -717,6 +717,34 @@ static const u16 rf_ramp_pwm_cband_7090[] = { | |||
717 | (0 << 10) | 109, /* RF_RAMP4, LNA 4 */ | 717 | (0 << 10) | 109, /* RF_RAMP4, LNA 4 */ |
718 | }; | 718 | }; |
719 | 719 | ||
720 | static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = { | ||
721 | 186, | ||
722 | 40, | ||
723 | 746, | ||
724 | (10 << 10) | 345, | ||
725 | (0 << 10) | 746, | ||
726 | (0 << 10) | 0, | ||
727 | (0 << 10) | 0, | ||
728 | (28 << 10) | 200, | ||
729 | (0 << 10) | 345, | ||
730 | (20 << 10) | 0, | ||
731 | (0 << 10) | 200, | ||
732 | }; | ||
733 | |||
734 | static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = { | ||
735 | 86, | ||
736 | 40, | ||
737 | 345, | ||
738 | (0 << 10) | 0, | ||
739 | (0 << 10) | 0, | ||
740 | (0 << 10) | 0, | ||
741 | (0 << 10) | 0, | ||
742 | (28 << 10) | 200, | ||
743 | (0 << 10) | 345, | ||
744 | (20 << 10) | 0, | ||
745 | (0 << 10) | 200, | ||
746 | }; | ||
747 | |||
720 | static const u16 rf_ramp_pwm_cband_8090[] = { | 748 | static const u16 rf_ramp_pwm_cband_8090[] = { |
721 | 345, /* max RF gain in 10th of dB */ | 749 | 345, /* max RF gain in 10th of dB */ |
722 | 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ | 750 | 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ |
@@ -1076,8 +1104,16 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) | |||
1076 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs); | 1104 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs); |
1077 | if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) | 1105 | if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) |
1078 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090); | 1106 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090); |
1079 | else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) | 1107 | else if (state->identity.version == SOC_7090_P1G_11R1 |
1080 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090); | 1108 | || state->identity.version == SOC_7090_P1G_21R1) { |
1109 | if (state->config->is_dib7090e) { | ||
1110 | if (state->rf_ramp == NULL) | ||
1111 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity); | ||
1112 | else | ||
1113 | dib0090_set_rframp_pwm(state, state->rf_ramp); | ||
1114 | } else | ||
1115 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090); | ||
1116 | } | ||
1081 | } else { | 1117 | } else { |
1082 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); | 1118 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); |
1083 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); | 1119 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); |
@@ -1112,13 +1148,21 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) | |||
1112 | else | 1148 | else |
1113 | dib0090_write_reg(state, 0x32, (0 << 11)); | 1149 | dib0090_write_reg(state, 0x32, (0 << 11)); |
1114 | 1150 | ||
1115 | dib0090_write_reg(state, 0x04, 0x01); | 1151 | dib0090_write_reg(state, 0x04, 0x03); |
1116 | dib0090_write_reg(state, 0x39, (1 << 10)); | 1152 | dib0090_write_reg(state, 0x39, (1 << 10)); |
1117 | } | 1153 | } |
1118 | } | 1154 | } |
1119 | 1155 | ||
1120 | EXPORT_SYMBOL(dib0090_pwm_gain_reset); | 1156 | EXPORT_SYMBOL(dib0090_pwm_gain_reset); |
1121 | 1157 | ||
1158 | void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) | ||
1159 | { | ||
1160 | struct dib0090_state *state = fe->tuner_priv; | ||
1161 | if (DC_servo_cutoff < 4) | ||
1162 | dib0090_write_reg(state, 0x04, DC_servo_cutoff); | ||
1163 | } | ||
1164 | EXPORT_SYMBOL(dib0090_set_dc_servo); | ||
1165 | |||
1122 | static u32 dib0090_get_slow_adc_val(struct dib0090_state *state) | 1166 | static u32 dib0090_get_slow_adc_val(struct dib0090_state *state) |
1123 | { | 1167 | { |
1124 | u16 adc_val = dib0090_read_reg(state, 0x1d); | 1168 | u16 adc_val = dib0090_read_reg(state, 0x1d); |
@@ -1305,7 +1349,7 @@ void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * | |||
1305 | 1349 | ||
1306 | EXPORT_SYMBOL(dib0090_get_current_gain); | 1350 | EXPORT_SYMBOL(dib0090_get_current_gain); |
1307 | 1351 | ||
1308 | u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) | 1352 | u16 dib0090_get_wbd_target(struct dvb_frontend *fe) |
1309 | { | 1353 | { |
1310 | struct dib0090_state *state = fe->tuner_priv; | 1354 | struct dib0090_state *state = fe->tuner_priv; |
1311 | u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000; | 1355 | u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000; |
@@ -1342,9 +1386,57 @@ u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) | |||
1342 | 1386 | ||
1343 | return state->wbd_offset + wbd_tcold; | 1387 | return state->wbd_offset + wbd_tcold; |
1344 | } | 1388 | } |
1389 | EXPORT_SYMBOL(dib0090_get_wbd_target); | ||
1345 | 1390 | ||
1391 | u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) | ||
1392 | { | ||
1393 | struct dib0090_state *state = fe->tuner_priv; | ||
1394 | return state->wbd_offset; | ||
1395 | } | ||
1346 | EXPORT_SYMBOL(dib0090_get_wbd_offset); | 1396 | EXPORT_SYMBOL(dib0090_get_wbd_offset); |
1347 | 1397 | ||
1398 | int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3) | ||
1399 | { | ||
1400 | struct dib0090_state *state = fe->tuner_priv; | ||
1401 | |||
1402 | dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8) | ||
1403 | | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1)); | ||
1404 | |||
1405 | return 0; | ||
1406 | } | ||
1407 | EXPORT_SYMBOL(dib0090_set_switch); | ||
1408 | |||
1409 | int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) | ||
1410 | { | ||
1411 | struct dib0090_state *state = fe->tuner_priv; | ||
1412 | |||
1413 | dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff) | ||
1414 | | ((onoff & 1) << 15)); | ||
1415 | return 0; | ||
1416 | } | ||
1417 | EXPORT_SYMBOL(dib0090_set_vga); | ||
1418 | |||
1419 | int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity) | ||
1420 | { | ||
1421 | struct dib0090_state *state = fe->tuner_priv; | ||
1422 | |||
1423 | if ((!state->identity.p1g) || (!state->identity.in_soc) | ||
1424 | || ((state->identity.version != SOC_7090_P1G_21R1) | ||
1425 | && (state->identity.version != SOC_7090_P1G_11R1))) { | ||
1426 | dprintk("%s() function can only be used for dib7090P", __func__); | ||
1427 | return -ENODEV; | ||
1428 | } | ||
1429 | |||
1430 | if (cfg_sensitivity) | ||
1431 | state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity; | ||
1432 | else | ||
1433 | state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci; | ||
1434 | dib0090_pwm_gain_reset(fe); | ||
1435 | |||
1436 | return 0; | ||
1437 | } | ||
1438 | EXPORT_SYMBOL(dib0090_update_rframp_7090); | ||
1439 | |||
1348 | static const u16 dib0090_defaults[] = { | 1440 | static const u16 dib0090_defaults[] = { |
1349 | 1441 | ||
1350 | 25, 0x01, | 1442 | 25, 0x01, |
@@ -1430,7 +1522,7 @@ static void dib0090_set_default_config(struct dib0090_state *state, const u16 * | |||
1430 | #define POLY_MIN (u8) 0 | 1522 | #define POLY_MIN (u8) 0 |
1431 | #define POLY_MAX (u8) 8 | 1523 | #define POLY_MAX (u8) 8 |
1432 | 1524 | ||
1433 | void dib0090_set_EFUSE(struct dib0090_state *state) | 1525 | static void dib0090_set_EFUSE(struct dib0090_state *state) |
1434 | { | 1526 | { |
1435 | u8 c, h, n; | 1527 | u8 c, h, n; |
1436 | u16 e2, e4; | 1528 | u16 e2, e4; |
@@ -1505,7 +1597,10 @@ static int dib0090_reset(struct dvb_frontend *fe) | |||
1505 | dib0090_set_EFUSE(state); | 1597 | dib0090_set_EFUSE(state); |
1506 | 1598 | ||
1507 | /* Congigure in function of the crystal */ | 1599 | /* Congigure in function of the crystal */ |
1508 | if (state->config->io.clock_khz >= 24000) | 1600 | if (state->config->force_crystal_mode != 0) |
1601 | dib0090_write_reg(state, 0x14, | ||
1602 | state->config->force_crystal_mode & 3); | ||
1603 | else if (state->config->io.clock_khz >= 24000) | ||
1509 | dib0090_write_reg(state, 0x14, 1); | 1604 | dib0090_write_reg(state, 0x14, 1); |
1510 | else | 1605 | else |
1511 | dib0090_write_reg(state, 0x14, 2); | 1606 | dib0090_write_reg(state, 0x14, 2); |
@@ -1951,6 +2046,52 @@ static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = { | |||
1951 | #endif | 2046 | #endif |
1952 | }; | 2047 | }; |
1953 | 2048 | ||
2049 | static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = { | ||
2050 | #ifdef CONFIG_BAND_CBAND | ||
2051 | { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, | ||
2052 | { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, | ||
2053 | { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB }, | ||
2054 | { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB }, | ||
2055 | { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB }, | ||
2056 | { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB }, | ||
2057 | #endif | ||
2058 | }; | ||
2059 | |||
2060 | int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, | ||
2061 | u8 cfg_sensitivity) | ||
2062 | { | ||
2063 | struct dib0090_state *state = fe->tuner_priv; | ||
2064 | const struct dib0090_tuning *tune = | ||
2065 | dib0090_tuning_table_cband_7090e_sensitivity; | ||
2066 | const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = { | ||
2067 | { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, | ||
2068 | { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB }, | ||
2069 | { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB }, | ||
2070 | }; | ||
2071 | |||
2072 | if ((!state->identity.p1g) || (!state->identity.in_soc) | ||
2073 | || ((state->identity.version != SOC_7090_P1G_21R1) | ||
2074 | && (state->identity.version != SOC_7090_P1G_11R1))) { | ||
2075 | dprintk("%s() function can only be used for dib7090", __func__); | ||
2076 | return -ENODEV; | ||
2077 | } | ||
2078 | |||
2079 | if (cfg_sensitivity) | ||
2080 | tune = dib0090_tuning_table_cband_7090e_sensitivity; | ||
2081 | else | ||
2082 | tune = dib0090_tuning_table_cband_7090e_aci; | ||
2083 | |||
2084 | while (state->rf_request > tune->max_freq) | ||
2085 | tune++; | ||
2086 | |||
2087 | dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000) | ||
2088 | | (tune->lna_bias & 0x7fff)); | ||
2089 | dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f) | ||
2090 | | ((tune->lna_tune << 6) & 0x07c0)); | ||
2091 | return 0; | ||
2092 | } | ||
2093 | EXPORT_SYMBOL(dib0090_update_tuning_table_7090); | ||
2094 | |||
1954 | static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state) | 2095 | static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state) |
1955 | { | 2096 | { |
1956 | int ret = 0; | 2097 | int ret = 0; |
@@ -2199,12 +2340,18 @@ static int dib0090_tune(struct dvb_frontend *fe) | |||
2199 | if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF | 2340 | if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF |
2200 | || state->current_band & BAND_UHF) { | 2341 | || state->current_band & BAND_UHF) { |
2201 | state->current_band = BAND_CBAND; | 2342 | state->current_band = BAND_CBAND; |
2202 | tune = dib0090_tuning_table_cband_7090; | 2343 | if (state->config->is_dib7090e) |
2344 | tune = dib0090_tuning_table_cband_7090e_sensitivity; | ||
2345 | else | ||
2346 | tune = dib0090_tuning_table_cband_7090; | ||
2203 | } | 2347 | } |
2204 | } else { /* Use the CBAND input for all band under UHF */ | 2348 | } else { /* Use the CBAND input for all band under UHF */ |
2205 | if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) { | 2349 | if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) { |
2206 | state->current_band = BAND_CBAND; | 2350 | state->current_band = BAND_CBAND; |
2207 | tune = dib0090_tuning_table_cband_7090; | 2351 | if (state->config->is_dib7090e) |
2352 | tune = dib0090_tuning_table_cband_7090e_sensitivity; | ||
2353 | else | ||
2354 | tune = dib0090_tuning_table_cband_7090; | ||
2208 | } | 2355 | } |
2209 | } | 2356 | } |
2210 | } else | 2357 | } else |
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h index 13d85244ec16..781dc49de45b 100644 --- a/drivers/media/dvb/frontends/dib0090.h +++ b/drivers/media/dvb/frontends/dib0090.h | |||
@@ -71,6 +71,8 @@ struct dib0090_config { | |||
71 | u8 fref_clock_ratio; | 71 | u8 fref_clock_ratio; |
72 | u16 force_cband_input; | 72 | u16 force_cband_input; |
73 | struct dib0090_wbd_slope *wbd; | 73 | struct dib0090_wbd_slope *wbd; |
74 | u8 is_dib7090e; | ||
75 | u8 force_crystal_mode; | ||
74 | }; | 76 | }; |
75 | 77 | ||
76 | #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) | 78 | #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) |
@@ -78,13 +80,21 @@ extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c | |||
78 | extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); | 80 | extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); |
79 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); | 81 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); |
80 | extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); | 82 | extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); |
81 | extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); | 83 | extern u16 dib0090_get_wbd_target(struct dvb_frontend *tuner); |
84 | extern u16 dib0090_get_wbd_offset(struct dvb_frontend *fe); | ||
82 | extern int dib0090_gain_control(struct dvb_frontend *fe); | 85 | extern int dib0090_gain_control(struct dvb_frontend *fe); |
83 | extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); | 86 | extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); |
84 | extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); | 87 | extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); |
85 | extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); | 88 | extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); |
89 | extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff); | ||
90 | extern int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3); | ||
91 | extern int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff); | ||
92 | extern int dib0090_update_rframp_7090(struct dvb_frontend *fe, | ||
93 | u8 cfg_sensitivity); | ||
94 | extern int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, | ||
95 | u8 cfg_sensitivity); | ||
86 | #else | 96 | #else |
87 | static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) | 97 | static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) |
88 | { | 98 | { |
89 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 99 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
90 | return NULL; | 100 | return NULL; |
@@ -106,7 +116,13 @@ static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe) | |||
106 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 116 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
107 | } | 117 | } |
108 | 118 | ||
109 | static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) | 119 | static inline u16 dib0090_get_wbd_target(struct dvb_frontend *tuner) |
120 | { | ||
121 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) | ||
110 | { | 126 | { |
111 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 127 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
112 | return 0; | 128 | return 0; |
@@ -134,6 +150,38 @@ static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u | |||
134 | { | 150 | { |
135 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 151 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
136 | } | 152 | } |
153 | |||
154 | static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) | ||
155 | { | ||
156 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
157 | } | ||
158 | |||
159 | static inline int dib0090_set_switch(struct dvb_frontend *fe, | ||
160 | u8 sw1, u8 sw2, u8 sw3) | ||
161 | { | ||
162 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | static inline int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) | ||
167 | { | ||
168 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
169 | return -ENODEV; | ||
170 | } | ||
171 | |||
172 | static inline int dib0090_update_rframp_7090(struct dvb_frontend *fe, | ||
173 | u8 cfg_sensitivity) | ||
174 | { | ||
175 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
176 | return -ENODEV; | ||
177 | } | ||
178 | |||
179 | static inline int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, | ||
180 | u8 cfg_sensitivity) | ||
181 | { | ||
182 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
183 | return -ENODEV; | ||
184 | } | ||
137 | #endif | 185 | #endif |
138 | 186 | ||
139 | #endif | 187 | #endif |
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index ce8534ff142e..b5f3fb4f09ed 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c | |||
@@ -70,6 +70,8 @@ struct dib7000p_state { | |||
70 | u8 i2c_write_buffer[4]; | 70 | u8 i2c_write_buffer[4]; |
71 | u8 i2c_read_buffer[2]; | 71 | u8 i2c_read_buffer[2]; |
72 | struct mutex i2c_buffer_lock; | 72 | struct mutex i2c_buffer_lock; |
73 | |||
74 | u8 input_mode_mpeg; | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | enum dib7000p_power_mode { | 77 | enum dib7000p_power_mode { |
@@ -78,8 +80,11 @@ enum dib7000p_power_mode { | |||
78 | DIB7000P_POWER_INTERFACE_ONLY, | 80 | DIB7000P_POWER_INTERFACE_ONLY, |
79 | }; | 81 | }; |
80 | 82 | ||
83 | /* dib7090 specific fonctions */ | ||
81 | static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); | 84 | static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); |
82 | static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); | 85 | static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); |
86 | static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode); | ||
87 | static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode); | ||
83 | 88 | ||
84 | static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) | 89 | static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) |
85 | { | 90 | { |
@@ -276,17 +281,23 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p | |||
276 | dib7000p_write_word(state, 774, reg_774); | 281 | dib7000p_write_word(state, 774, reg_774); |
277 | dib7000p_write_word(state, 775, reg_775); | 282 | dib7000p_write_word(state, 775, reg_775); |
278 | dib7000p_write_word(state, 776, reg_776); | 283 | dib7000p_write_word(state, 776, reg_776); |
279 | dib7000p_write_word(state, 899, reg_899); | ||
280 | dib7000p_write_word(state, 1280, reg_1280); | 284 | dib7000p_write_word(state, 1280, reg_1280); |
285 | if (state->version != SOC7090) | ||
286 | dib7000p_write_word(state, 899, reg_899); | ||
281 | 287 | ||
282 | return 0; | 288 | return 0; |
283 | } | 289 | } |
284 | 290 | ||
285 | static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) | 291 | static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) |
286 | { | 292 | { |
287 | u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909); | 293 | u16 reg_908 = 0, reg_909 = 0; |
288 | u16 reg; | 294 | u16 reg; |
289 | 295 | ||
296 | if (state->version != SOC7090) { | ||
297 | reg_908 = dib7000p_read_word(state, 908); | ||
298 | reg_909 = dib7000p_read_word(state, 909); | ||
299 | } | ||
300 | |||
290 | switch (no) { | 301 | switch (no) { |
291 | case DIBX000_SLOW_ADC_ON: | 302 | case DIBX000_SLOW_ADC_ON: |
292 | if (state->version == SOC7090) { | 303 | if (state->version == SOC7090) { |
@@ -342,8 +353,10 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad | |||
342 | reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; | 353 | reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; |
343 | reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; | 354 | reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; |
344 | 355 | ||
345 | dib7000p_write_word(state, 908, reg_908); | 356 | if (state->version != SOC7090) { |
346 | dib7000p_write_word(state, 909, reg_909); | 357 | dib7000p_write_word(state, 908, reg_908); |
358 | dib7000p_write_word(state, 909, reg_909); | ||
359 | } | ||
347 | } | 360 | } |
348 | 361 | ||
349 | static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) | 362 | static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) |
@@ -398,6 +411,24 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) | |||
398 | } | 411 | } |
399 | EXPORT_SYMBOL(dib7000p_set_wbd_ref); | 412 | EXPORT_SYMBOL(dib7000p_set_wbd_ref); |
400 | 413 | ||
414 | int dib7000p_get_agc_values(struct dvb_frontend *fe, | ||
415 | u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) | ||
416 | { | ||
417 | struct dib7000p_state *state = fe->demodulator_priv; | ||
418 | |||
419 | if (agc_global != NULL) | ||
420 | *agc_global = dib7000p_read_word(state, 394); | ||
421 | if (agc1 != NULL) | ||
422 | *agc1 = dib7000p_read_word(state, 392); | ||
423 | if (agc2 != NULL) | ||
424 | *agc2 = dib7000p_read_word(state, 393); | ||
425 | if (wbd != NULL) | ||
426 | *wbd = dib7000p_read_word(state, 397); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | EXPORT_SYMBOL(dib7000p_get_agc_values); | ||
431 | |||
401 | static void dib7000p_reset_pll(struct dib7000p_state *state) | 432 | static void dib7000p_reset_pll(struct dib7000p_state *state) |
402 | { | 433 | { |
403 | struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; | 434 | struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; |
@@ -519,7 +550,7 @@ static u16 dib7000p_defaults[] = { | |||
519 | // auto search configuration | 550 | // auto search configuration |
520 | 3, 2, | 551 | 3, 2, |
521 | 0x0004, | 552 | 0x0004, |
522 | 0x1000, | 553 | (1<<3)|(1<<11)|(1<<12)|(1<<13), |
523 | 0x0814, /* Equal Lock */ | 554 | 0x0814, /* Equal Lock */ |
524 | 555 | ||
525 | 12, 6, | 556 | 12, 6, |
@@ -595,13 +626,6 @@ static u16 dib7000p_defaults[] = { | |||
595 | 1, 235, | 626 | 1, 235, |
596 | 0x0062, | 627 | 0x0062, |
597 | 628 | ||
598 | 2, 901, | ||
599 | 0x0006, | ||
600 | (3 << 10) | (1 << 6), | ||
601 | |||
602 | 1, 905, | ||
603 | 0x2c8e, | ||
604 | |||
605 | 0, | 629 | 0, |
606 | }; | 630 | }; |
607 | 631 | ||
@@ -618,15 +642,18 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) | |||
618 | dib7000p_write_word(state, 770, 0xffff); | 642 | dib7000p_write_word(state, 770, 0xffff); |
619 | dib7000p_write_word(state, 771, 0xffff); | 643 | dib7000p_write_word(state, 771, 0xffff); |
620 | dib7000p_write_word(state, 772, 0x001f); | 644 | dib7000p_write_word(state, 772, 0x001f); |
621 | dib7000p_write_word(state, 898, 0x0003); | ||
622 | dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3))); | 645 | dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3))); |
623 | 646 | ||
624 | dib7000p_write_word(state, 770, 0); | 647 | dib7000p_write_word(state, 770, 0); |
625 | dib7000p_write_word(state, 771, 0); | 648 | dib7000p_write_word(state, 771, 0); |
626 | dib7000p_write_word(state, 772, 0); | 649 | dib7000p_write_word(state, 772, 0); |
627 | dib7000p_write_word(state, 898, 0); | ||
628 | dib7000p_write_word(state, 1280, 0); | 650 | dib7000p_write_word(state, 1280, 0); |
629 | 651 | ||
652 | if (state->version != SOC7090) { | ||
653 | dib7000p_write_word(state, 898, 0x0003); | ||
654 | dib7000p_write_word(state, 898, 0); | ||
655 | } | ||
656 | |||
630 | /* default */ | 657 | /* default */ |
631 | dib7000p_reset_pll(state); | 658 | dib7000p_reset_pll(state); |
632 | 659 | ||
@@ -640,7 +667,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) | |||
640 | dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ | 667 | dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ |
641 | dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ | 668 | dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ |
642 | dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ | 669 | dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ |
643 | dib7000p_write_word(state, 273, (1<<6) | 30); | 670 | dib7000p_write_word(state, 273, (0<<6) | 30); |
644 | } | 671 | } |
645 | if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) | 672 | if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) |
646 | dprintk("OUTPUT_MODE could not be reset."); | 673 | dprintk("OUTPUT_MODE could not be reset."); |
@@ -655,7 +682,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) | |||
655 | dib7000p_set_bandwidth(state, 8000); | 682 | dib7000p_set_bandwidth(state, 8000); |
656 | 683 | ||
657 | if (state->version == SOC7090) { | 684 | if (state->version == SOC7090) { |
658 | dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ | 685 | dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ |
659 | } else { | 686 | } else { |
660 | if (state->cfg.tuner_is_baseband) | 687 | if (state->cfg.tuner_is_baseband) |
661 | dib7000p_write_word(state, 36, 0x0755); | 688 | dib7000p_write_word(state, 36, 0x0755); |
@@ -664,6 +691,11 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) | |||
664 | } | 691 | } |
665 | 692 | ||
666 | dib7000p_write_tab(state, dib7000p_defaults); | 693 | dib7000p_write_tab(state, dib7000p_defaults); |
694 | if (state->version != SOC7090) { | ||
695 | dib7000p_write_word(state, 901, 0x0006); | ||
696 | dib7000p_write_word(state, 902, (3 << 10) | (1 << 6)); | ||
697 | dib7000p_write_word(state, 905, 0x2c8e); | ||
698 | } | ||
667 | 699 | ||
668 | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); | 700 | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); |
669 | 701 | ||
@@ -1080,9 +1112,12 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron | |||
1080 | dib7000p_set_channel(state, &schan, 7); | 1112 | dib7000p_set_channel(state, &schan, 7); |
1081 | 1113 | ||
1082 | factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); | 1114 | factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); |
1083 | if (factor >= 5000) | 1115 | if (factor >= 5000) { |
1084 | factor = 1; | 1116 | if (state->version == SOC7090) |
1085 | else | 1117 | factor = 2; |
1118 | else | ||
1119 | factor = 1; | ||
1120 | } else | ||
1086 | factor = 6; | 1121 | factor = 6; |
1087 | 1122 | ||
1088 | value = 30 * internal * factor; | 1123 | value = 30 * internal * factor; |
@@ -1323,7 +1358,7 @@ static int dib7000p_sleep(struct dvb_frontend *demod) | |||
1323 | { | 1358 | { |
1324 | struct dib7000p_state *state = demod->demodulator_priv; | 1359 | struct dib7000p_state *state = demod->demodulator_priv; |
1325 | if (state->version == SOC7090) | 1360 | if (state->version == SOC7090) |
1326 | return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); | 1361 | return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); |
1327 | return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); | 1362 | return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); |
1328 | } | 1363 | } |
1329 | 1364 | ||
@@ -1445,10 +1480,9 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa | |||
1445 | struct dib7000p_state *state = fe->demodulator_priv; | 1480 | struct dib7000p_state *state = fe->demodulator_priv; |
1446 | int time, ret; | 1481 | int time, ret; |
1447 | 1482 | ||
1448 | if (state->version == SOC7090) { | 1483 | if (state->version == SOC7090) |
1449 | dib7090_set_diversity_in(fe, 0); | 1484 | dib7090_set_diversity_in(fe, 0); |
1450 | dib7090_set_output_mode(fe, OUTMODE_HIGH_Z); | 1485 | else |
1451 | } else | ||
1452 | dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); | 1486 | dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); |
1453 | 1487 | ||
1454 | /* maybe the parameter has been changed */ | 1488 | /* maybe the parameter has been changed */ |
@@ -1485,9 +1519,13 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa | |||
1485 | ret = dib7000p_tune(fe, fep); | 1519 | ret = dib7000p_tune(fe, fep); |
1486 | 1520 | ||
1487 | /* make this a config parameter */ | 1521 | /* make this a config parameter */ |
1488 | if (state->version == SOC7090) | 1522 | if (state->version == SOC7090) { |
1489 | dib7090_set_output_mode(fe, state->cfg.output_mode); | 1523 | dib7090_set_output_mode(fe, state->cfg.output_mode); |
1490 | else | 1524 | if (state->cfg.enMpegOutput == 0) { |
1525 | dib7090_setDibTxMux(state, MPEG_ON_DIBTX); | ||
1526 | dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); | ||
1527 | } | ||
1528 | } else | ||
1491 | dib7000p_set_output_mode(state, state->cfg.output_mode); | 1529 | dib7000p_set_output_mode(state, state->cfg.output_mode); |
1492 | 1530 | ||
1493 | return ret; | 1531 | return ret; |
@@ -1831,7 +1869,8 @@ static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg m | |||
1831 | return num; | 1869 | return num; |
1832 | } | 1870 | } |
1833 | 1871 | ||
1834 | int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address) | 1872 | static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, |
1873 | struct i2c_msg msg[], int num, u16 apb_address) | ||
1835 | { | 1874 | { |
1836 | struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); | 1875 | struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); |
1837 | u16 word; | 1876 | u16 word; |
@@ -1933,10 +1972,10 @@ static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] | |||
1933 | apb_address = 915; | 1972 | apb_address = 915; |
1934 | break; | 1973 | break; |
1935 | case 0x27: | 1974 | case 0x27: |
1936 | apb_address = 916; | 1975 | apb_address = 917; |
1937 | break; | 1976 | break; |
1938 | case 0x28: | 1977 | case 0x28: |
1939 | apb_address = 917; | 1978 | apb_address = 916; |
1940 | break; | 1979 | break; |
1941 | case 0x1d: | 1980 | case 0x1d: |
1942 | i = ((dib7000p_read_word(state, 72) >> 12) & 0x3); | 1981 | i = ((dib7000p_read_word(state, 72) >> 12) & 0x3); |
@@ -2031,12 +2070,7 @@ static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 | |||
2031 | 2070 | ||
2032 | static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) | 2071 | static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) |
2033 | { | 2072 | { |
2034 | u8 index_buf; | ||
2035 | u16 rx_copy_buf[22]; | ||
2036 | |||
2037 | dprintk("Configure DibStream Tx"); | 2073 | dprintk("Configure DibStream Tx"); |
2038 | for (index_buf = 0; index_buf < 22; index_buf++) | ||
2039 | rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf); | ||
2040 | 2074 | ||
2041 | dib7000p_write_word(state, 1615, 1); | 2075 | dib7000p_write_word(state, 1615, 1); |
2042 | dib7000p_write_word(state, 1603, P_Kin); | 2076 | dib7000p_write_word(state, 1603, P_Kin); |
@@ -2048,9 +2082,6 @@ static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout | |||
2048 | dib7000p_write_word(state, 1612, syncSize); | 2082 | dib7000p_write_word(state, 1612, syncSize); |
2049 | dib7000p_write_word(state, 1615, 0); | 2083 | dib7000p_write_word(state, 1615, 0); |
2050 | 2084 | ||
2051 | for (index_buf = 0; index_buf < 22; index_buf++) | ||
2052 | dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]); | ||
2053 | |||
2054 | return 0; | 2085 | return 0; |
2055 | } | 2086 | } |
2056 | 2087 | ||
@@ -2077,109 +2108,121 @@ static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout | |||
2077 | return 0; | 2108 | return 0; |
2078 | } | 2109 | } |
2079 | 2110 | ||
2080 | static int dib7090_enDivOnHostBus(struct dib7000p_state *state) | 2111 | static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff) |
2081 | { | ||
2082 | u16 reg; | ||
2083 | |||
2084 | dprintk("Enable Diversity on host bus"); | ||
2085 | reg = (1 << 8) | (1 << 5); | ||
2086 | dib7000p_write_word(state, 1288, reg); | ||
2087 | |||
2088 | return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); | ||
2089 | } | ||
2090 | |||
2091 | static int dib7090_enAdcOnHostBus(struct dib7000p_state *state) | ||
2092 | { | ||
2093 | u16 reg; | ||
2094 | |||
2095 | dprintk("Enable ADC on host bus"); | ||
2096 | reg = (1 << 7) | (1 << 5); | ||
2097 | dib7000p_write_word(state, 1288, reg); | ||
2098 | |||
2099 | return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); | ||
2100 | } | ||
2101 | |||
2102 | static int dib7090_enMpegOnHostBus(struct dib7000p_state *state) | ||
2103 | { | 2112 | { |
2104 | u16 reg; | 2113 | u16 reg_1287 = dib7000p_read_word(state, 1287); |
2105 | |||
2106 | dprintk("Enable Mpeg on host bus"); | ||
2107 | reg = (1 << 9) | (1 << 5); | ||
2108 | dib7000p_write_word(state, 1288, reg); | ||
2109 | 2114 | ||
2110 | return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); | 2115 | switch (onoff) { |
2111 | } | 2116 | case 1: |
2117 | reg_1287 &= ~(1<<7); | ||
2118 | break; | ||
2119 | case 0: | ||
2120 | reg_1287 |= (1<<7); | ||
2121 | break; | ||
2122 | } | ||
2112 | 2123 | ||
2113 | static int dib7090_enMpegInput(struct dib7000p_state *state) | 2124 | dib7000p_write_word(state, 1287, reg_1287); |
2114 | { | ||
2115 | dprintk("Enable Mpeg input"); | ||
2116 | return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ | ||
2117 | } | 2125 | } |
2118 | 2126 | ||
2119 | static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) | 2127 | static void dib7090_configMpegMux(struct dib7000p_state *state, |
2128 | u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) | ||
2120 | { | 2129 | { |
2121 | u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1); | ||
2122 | |||
2123 | dprintk("Enable Mpeg mux"); | 2130 | dprintk("Enable Mpeg mux"); |
2124 | dib7000p_write_word(state, 1287, reg); | ||
2125 | 2131 | ||
2126 | reg &= ~(1 << 7); | 2132 | dib7090_enMpegMux(state, 0); |
2127 | dib7000p_write_word(state, 1287, reg); | ||
2128 | 2133 | ||
2129 | reg = (1 << 4); | 2134 | /* If the input mode is MPEG do not divide the serial clock */ |
2130 | dib7000p_write_word(state, 1288, reg); | 2135 | if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) |
2136 | enSerialClkDiv2 = 0; | ||
2131 | 2137 | ||
2132 | return 0; | 2138 | dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2) |
2139 | | ((enSerialMode & 0x1) << 1) | ||
2140 | | (enSerialClkDiv2 & 0x1)); | ||
2141 | |||
2142 | dib7090_enMpegMux(state, 1); | ||
2133 | } | 2143 | } |
2134 | 2144 | ||
2135 | static int dib7090_disableMpegMux(struct dib7000p_state *state) | 2145 | static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode) |
2136 | { | 2146 | { |
2137 | u16 reg; | 2147 | u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7); |
2138 | |||
2139 | dprintk("Disable Mpeg mux"); | ||
2140 | dib7000p_write_word(state, 1288, 0); | ||
2141 | |||
2142 | reg = dib7000p_read_word(state, 1287); | ||
2143 | reg &= ~(1 << 7); | ||
2144 | dib7000p_write_word(state, 1287, reg); | ||
2145 | 2148 | ||
2146 | return 0; | 2149 | switch (mode) { |
2150 | case MPEG_ON_DIBTX: | ||
2151 | dprintk("SET MPEG ON DIBSTREAM TX"); | ||
2152 | dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); | ||
2153 | reg_1288 |= (1<<9); | ||
2154 | break; | ||
2155 | case DIV_ON_DIBTX: | ||
2156 | dprintk("SET DIV_OUT ON DIBSTREAM TX"); | ||
2157 | dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); | ||
2158 | reg_1288 |= (1<<8); | ||
2159 | break; | ||
2160 | case ADC_ON_DIBTX: | ||
2161 | dprintk("SET ADC_OUT ON DIBSTREAM TX"); | ||
2162 | dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); | ||
2163 | reg_1288 |= (1<<7); | ||
2164 | break; | ||
2165 | default: | ||
2166 | break; | ||
2167 | } | ||
2168 | dib7000p_write_word(state, 1288, reg_1288); | ||
2147 | } | 2169 | } |
2148 | 2170 | ||
2149 | static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode) | 2171 | static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode) |
2150 | { | 2172 | { |
2151 | struct dib7000p_state *state = fe->demodulator_priv; | 2173 | u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4); |
2152 | 2174 | ||
2153 | switch (mode) { | 2175 | switch (mode) { |
2154 | case INPUT_MODE_DIVERSITY: | 2176 | case DEMOUT_ON_HOSTBUS: |
2155 | dprintk("Enable diversity INPUT"); | 2177 | dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); |
2156 | dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); | 2178 | dib7090_enMpegMux(state, 0); |
2179 | reg_1288 |= (1<<6); | ||
2180 | break; | ||
2181 | case DIBTX_ON_HOSTBUS: | ||
2182 | dprintk("SET DIBSTREAM TX ON HOST BUS"); | ||
2183 | dib7090_enMpegMux(state, 0); | ||
2184 | reg_1288 |= (1<<5); | ||
2157 | break; | 2185 | break; |
2158 | case INPUT_MODE_MPEG: | 2186 | case MPEG_ON_HOSTBUS: |
2159 | dprintk("Enable Mpeg INPUT"); | 2187 | dprintk("SET MPEG MUX ON HOST BUS"); |
2160 | dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ | 2188 | reg_1288 |= (1<<4); |
2161 | break; | 2189 | break; |
2162 | case INPUT_MODE_OFF: | ||
2163 | default: | 2190 | default: |
2164 | dprintk("Disable INPUT"); | ||
2165 | dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0); | ||
2166 | break; | 2191 | break; |
2167 | } | 2192 | } |
2168 | return 0; | 2193 | dib7000p_write_word(state, 1288, reg_1288); |
2169 | } | 2194 | } |
2170 | 2195 | ||
2171 | static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) | 2196 | int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) |
2172 | { | 2197 | { |
2198 | struct dib7000p_state *state = fe->demodulator_priv; | ||
2199 | u16 reg_1287; | ||
2200 | |||
2173 | switch (onoff) { | 2201 | switch (onoff) { |
2174 | case 0: /* only use the internal way - not the diversity input */ | 2202 | case 0: /* only use the internal way - not the diversity input */ |
2175 | dib7090_set_input_mode(fe, INPUT_MODE_MPEG); | 2203 | dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__); |
2176 | break; | 2204 | dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); |
2177 | case 1: /* both ways */ | 2205 | |
2178 | case 2: /* only the diversity input */ | 2206 | /* Do not divide the serial clock of MPEG MUX */ |
2179 | dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY); | 2207 | /* in SERIAL MODE in case input mode MPEG is used */ |
2180 | break; | 2208 | reg_1287 = dib7000p_read_word(state, 1287); |
2209 | /* enSerialClkDiv2 == 1 ? */ | ||
2210 | if ((reg_1287 & 0x1) == 1) { | ||
2211 | /* force enSerialClkDiv2 = 0 */ | ||
2212 | reg_1287 &= ~0x1; | ||
2213 | dib7000p_write_word(state, 1287, reg_1287); | ||
2214 | } | ||
2215 | state->input_mode_mpeg = 1; | ||
2216 | break; | ||
2217 | case 1: /* both ways */ | ||
2218 | case 2: /* only the diversity input */ | ||
2219 | dprintk("%s ON : Enable diversity INPUT", __func__); | ||
2220 | dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); | ||
2221 | state->input_mode_mpeg = 0; | ||
2222 | break; | ||
2181 | } | 2223 | } |
2182 | 2224 | ||
2225 | dib7000p_set_diversity_in(&state->demod, onoff); | ||
2183 | return 0; | 2226 | return 0; |
2184 | } | 2227 | } |
2185 | 2228 | ||
@@ -2204,69 +2247,63 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) | |||
2204 | 2247 | ||
2205 | case OUTMODE_MPEG2_SERIAL: | 2248 | case OUTMODE_MPEG2_SERIAL: |
2206 | if (prefer_mpeg_mux_use) { | 2249 | if (prefer_mpeg_mux_use) { |
2207 | dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux"); | 2250 | dprintk("setting output mode TS_SERIAL using Mpeg Mux"); |
2208 | dib7090_enMpegOnHostBus(state); | 2251 | dib7090_configMpegMux(state, 3, 1, 1); |
2209 | dib7090_enMpegInput(state); | 2252 | dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); |
2210 | if (state->cfg.enMpegOutput == 1) | 2253 | } else {/* Use Smooth block */ |
2211 | dib7090_enMpegMux(state, 3, 1, 1); | 2254 | dprintk("setting output mode TS_SERIAL using Smooth bloc"); |
2212 | 2255 | dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); | |
2213 | } else { /* Use Smooth block */ | 2256 | outreg |= (2<<6) | (0 << 1); |
2214 | dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc"); | ||
2215 | dib7090_disableMpegMux(state); | ||
2216 | dib7000p_write_word(state, 1288, (1 << 6)); | ||
2217 | outreg |= (2 << 6) | (0 << 1); | ||
2218 | } | 2257 | } |
2219 | break; | 2258 | break; |
2220 | 2259 | ||
2221 | case OUTMODE_MPEG2_PAR_GATED_CLK: | 2260 | case OUTMODE_MPEG2_PAR_GATED_CLK: |
2222 | if (prefer_mpeg_mux_use) { | 2261 | if (prefer_mpeg_mux_use) { |
2223 | dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); | 2262 | dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux"); |
2224 | dib7090_enMpegOnHostBus(state); | 2263 | dib7090_configMpegMux(state, 2, 0, 0); |
2225 | dib7090_enMpegInput(state); | 2264 | dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); |
2226 | if (state->cfg.enMpegOutput == 1) | 2265 | } else { /* Use Smooth block */ |
2227 | dib7090_enMpegMux(state, 2, 0, 0); | 2266 | dprintk("setting output mode TS_PARALLEL_GATED using Smooth block"); |
2228 | } else { /* Use Smooth block */ | 2267 | dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); |
2229 | dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block"); | 2268 | outreg |= (0<<6); |
2230 | dib7090_disableMpegMux(state); | ||
2231 | dib7000p_write_word(state, 1288, (1 << 6)); | ||
2232 | outreg |= (0 << 6); | ||
2233 | } | 2269 | } |
2234 | break; | 2270 | break; |
2235 | 2271 | ||
2236 | case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ | 2272 | case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ |
2237 | dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block"); | 2273 | dprintk("setting output mode TS_PARALLEL_CONT using Smooth block"); |
2238 | dib7090_disableMpegMux(state); | 2274 | dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); |
2239 | dib7000p_write_word(state, 1288, (1 << 6)); | 2275 | outreg |= (1<<6); |
2240 | outreg |= (1 << 6); | ||
2241 | break; | 2276 | break; |
2242 | 2277 | ||
2243 | case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ | 2278 | case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ |
2244 | dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block"); | 2279 | dprintk("setting output mode TS_FIFO using Smooth block"); |
2245 | dib7090_disableMpegMux(state); | 2280 | dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); |
2246 | dib7000p_write_word(state, 1288, (1 << 6)); | 2281 | outreg |= (5<<6); |
2247 | outreg |= (5 << 6); | ||
2248 | smo_mode |= (3 << 1); | 2282 | smo_mode |= (3 << 1); |
2249 | fifo_threshold = 512; | 2283 | fifo_threshold = 512; |
2250 | break; | 2284 | break; |
2251 | 2285 | ||
2252 | case OUTMODE_DIVERSITY: | 2286 | case OUTMODE_DIVERSITY: |
2253 | dprintk("Sip 7090P setting output mode MODE_DIVERSITY"); | 2287 | dprintk("setting output mode MODE_DIVERSITY"); |
2254 | dib7090_disableMpegMux(state); | 2288 | dib7090_setDibTxMux(state, DIV_ON_DIBTX); |
2255 | dib7090_enDivOnHostBus(state); | 2289 | dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); |
2256 | break; | 2290 | break; |
2257 | 2291 | ||
2258 | case OUTMODE_ANALOG_ADC: | 2292 | case OUTMODE_ANALOG_ADC: |
2259 | dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC"); | 2293 | dprintk("setting output mode MODE_ANALOG_ADC"); |
2260 | dib7090_enAdcOnHostBus(state); | 2294 | dib7090_setDibTxMux(state, ADC_ON_DIBTX); |
2295 | dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); | ||
2261 | break; | 2296 | break; |
2262 | } | 2297 | } |
2298 | if (mode != OUTMODE_HIGH_Z) | ||
2299 | outreg |= (1 << 10); | ||
2263 | 2300 | ||
2264 | if (state->cfg.output_mpeg2_in_188_bytes) | 2301 | if (state->cfg.output_mpeg2_in_188_bytes) |
2265 | smo_mode |= (1 << 5); | 2302 | smo_mode |= (1 << 5); |
2266 | 2303 | ||
2267 | ret |= dib7000p_write_word(state, 235, smo_mode); | 2304 | ret |= dib7000p_write_word(state, 235, smo_mode); |
2268 | ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ | 2305 | ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ |
2269 | ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */ | 2306 | ret |= dib7000p_write_word(state, 1286, outreg); |
2270 | 2307 | ||
2271 | return ret; | 2308 | return ret; |
2272 | } | 2309 | } |
@@ -2296,13 +2333,6 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) | |||
2296 | } | 2333 | } |
2297 | EXPORT_SYMBOL(dib7090_tuner_sleep); | 2334 | EXPORT_SYMBOL(dib7090_tuner_sleep); |
2298 | 2335 | ||
2299 | int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) | ||
2300 | { | ||
2301 | dprintk("AGC restart callback: %d", restart); | ||
2302 | return 0; | ||
2303 | } | ||
2304 | EXPORT_SYMBOL(dib7090_agc_restart); | ||
2305 | |||
2306 | int dib7090_get_adc_power(struct dvb_frontend *fe) | 2336 | int dib7090_get_adc_power(struct dvb_frontend *fe) |
2307 | { | 2337 | { |
2308 | return dib7000p_get_adc_power(fe); | 2338 | return dib7000p_get_adc_power(fe); |
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 0179f9474bac..b61b03a6e1ed 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h | |||
@@ -56,11 +56,12 @@ extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); | |||
56 | extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); | 56 | extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); |
57 | extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw); | 57 | extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw); |
58 | extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf); | 58 | extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf); |
59 | extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart); | ||
60 | extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff); | 59 | extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff); |
61 | extern int dib7090_get_adc_power(struct dvb_frontend *fe); | 60 | extern int dib7090_get_adc_power(struct dvb_frontend *fe); |
62 | extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe); | 61 | extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe); |
63 | extern int dib7090_slave_reset(struct dvb_frontend *fe); | 62 | extern int dib7090_slave_reset(struct dvb_frontend *fe); |
63 | extern int dib7000p_get_agc_values(struct dvb_frontend *fe, | ||
64 | u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd); | ||
64 | #else | 65 | #else |
65 | static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) | 66 | static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) |
66 | { | 67 | { |
@@ -122,12 +123,6 @@ static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) | |||
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
124 | 125 | ||
125 | static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) | ||
126 | { | ||
127 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
128 | return -ENODEV; | ||
129 | } | ||
130 | |||
131 | static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) | 126 | static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) |
132 | { | 127 | { |
133 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 128 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
@@ -151,6 +146,13 @@ static inline int dib7090_slave_reset(struct dvb_frontend *fe) | |||
151 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 146 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
152 | return -ENODEV; | 147 | return -ENODEV; |
153 | } | 148 | } |
149 | |||
150 | static inline int dib7000p_get_agc_values(struct dvb_frontend *fe, | ||
151 | u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) | ||
152 | { | ||
153 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
154 | return -ENODEV; | ||
155 | } | ||
154 | #endif | 156 | #endif |
155 | 157 | ||
156 | #endif | 158 | #endif |
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index fe284d5292f5..b8da0c9e085e 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c | |||
@@ -81,11 +81,15 @@ struct dib8000_state { | |||
81 | u8 i2c_write_buffer[4]; | 81 | u8 i2c_write_buffer[4]; |
82 | u8 i2c_read_buffer[2]; | 82 | u8 i2c_read_buffer[2]; |
83 | struct mutex i2c_buffer_lock; | 83 | struct mutex i2c_buffer_lock; |
84 | u8 input_mode_mpeg; | ||
85 | |||
86 | u16 tuner_enable; | ||
87 | struct i2c_adapter dib8096p_tuner_adap; | ||
84 | }; | 88 | }; |
85 | 89 | ||
86 | enum dib8000_power_mode { | 90 | enum dib8000_power_mode { |
87 | DIB8000M_POWER_ALL = 0, | 91 | DIB8000_POWER_ALL = 0, |
88 | DIB8000M_POWER_INTERFACE_ONLY, | 92 | DIB8000_POWER_INTERFACE_ONLY, |
89 | }; | 93 | }; |
90 | 94 | ||
91 | static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) | 95 | static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) |
@@ -428,20 +432,31 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow | |||
428 | /* by default everything is going to be powered off */ | 432 | /* by default everything is going to be powered off */ |
429 | u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, | 433 | u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, |
430 | reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, | 434 | reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, |
435 | reg_1280; | ||
436 | |||
437 | if (state->revision != 0x8090) | ||
431 | reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; | 438 | reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; |
439 | else | ||
440 | reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80; | ||
432 | 441 | ||
433 | /* now, depending on the requested mode, we power on */ | 442 | /* now, depending on the requested mode, we power on */ |
434 | switch (mode) { | 443 | switch (mode) { |
435 | /* power up everything in the demod */ | 444 | /* power up everything in the demod */ |
436 | case DIB8000M_POWER_ALL: | 445 | case DIB8000_POWER_ALL: |
437 | reg_774 = 0x0000; | 446 | reg_774 = 0x0000; |
438 | reg_775 = 0x0000; | 447 | reg_775 = 0x0000; |
439 | reg_776 = 0x0000; | 448 | reg_776 = 0x0000; |
440 | reg_900 &= 0xfffc; | 449 | reg_900 &= 0xfffc; |
441 | reg_1280 &= 0x00ff; | 450 | if (state->revision != 0x8090) |
451 | reg_1280 &= 0x00ff; | ||
452 | else | ||
453 | reg_1280 &= 0x707f; | ||
442 | break; | 454 | break; |
443 | case DIB8000M_POWER_INTERFACE_ONLY: | 455 | case DIB8000_POWER_INTERFACE_ONLY: |
444 | reg_1280 &= 0x00ff; | 456 | if (state->revision != 0x8090) |
457 | reg_1280 &= 0x00ff; | ||
458 | else | ||
459 | reg_1280 &= 0xfa7b; | ||
445 | break; | 460 | break; |
446 | } | 461 | } |
447 | 462 | ||
@@ -453,19 +468,67 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow | |||
453 | dib8000_write_word(state, 1280, reg_1280); | 468 | dib8000_write_word(state, 1280, reg_1280); |
454 | } | 469 | } |
455 | 470 | ||
471 | static int dib8000_init_sdram(struct dib8000_state *state) | ||
472 | { | ||
473 | u16 reg = 0; | ||
474 | dprintk("Init sdram"); | ||
475 | |||
476 | reg = dib8000_read_word(state, 274)&0xfff0; | ||
477 | /* P_dintlv_delay_ram = 7 because of MobileSdram */ | ||
478 | dib8000_write_word(state, 274, reg | 0x7); | ||
479 | |||
480 | dib8000_write_word(state, 1803, (7<<2)); | ||
481 | |||
482 | reg = dib8000_read_word(state, 1280); | ||
483 | /* force restart P_restart_sdram */ | ||
484 | dib8000_write_word(state, 1280, reg | (1<<2)); | ||
485 | |||
486 | /* release restart P_restart_sdram */ | ||
487 | dib8000_write_word(state, 1280, reg); | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
456 | static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) | 492 | static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) |
457 | { | 493 | { |
458 | int ret = 0; | 494 | int ret = 0; |
459 | u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908); | 495 | u16 reg, reg_907 = dib8000_read_word(state, 907); |
496 | u16 reg_908 = dib8000_read_word(state, 908); | ||
460 | 497 | ||
461 | switch (no) { | 498 | switch (no) { |
462 | case DIBX000_SLOW_ADC_ON: | 499 | case DIBX000_SLOW_ADC_ON: |
463 | reg_908 |= (1 << 1) | (1 << 0); | 500 | if (state->revision != 0x8090) { |
464 | ret |= dib8000_write_word(state, 908, reg_908); | 501 | reg_908 |= (1 << 1) | (1 << 0); |
465 | reg_908 &= ~(1 << 1); | 502 | ret |= dib8000_write_word(state, 908, reg_908); |
503 | reg_908 &= ~(1 << 1); | ||
504 | } else { | ||
505 | reg = dib8000_read_word(state, 1925); | ||
506 | /* en_slowAdc = 1 & reset_sladc = 1 */ | ||
507 | dib8000_write_word(state, 1925, reg | | ||
508 | (1<<4) | (1<<2)); | ||
509 | |||
510 | /* read acces to make it works... strange ... */ | ||
511 | reg = dib8000_read_word(state, 1925); | ||
512 | msleep(20); | ||
513 | /* en_slowAdc = 1 & reset_sladc = 0 */ | ||
514 | dib8000_write_word(state, 1925, reg & ~(1<<4)); | ||
515 | |||
516 | reg = dib8000_read_word(state, 921) & ~((0x3 << 14) | ||
517 | | (0x3 << 12)); | ||
518 | /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; | ||
519 | (Vin2 = Vcm) */ | ||
520 | dib8000_write_word(state, 921, reg | (1 << 14) | ||
521 | | (3 << 12)); | ||
522 | } | ||
466 | break; | 523 | break; |
467 | 524 | ||
468 | case DIBX000_SLOW_ADC_OFF: | 525 | case DIBX000_SLOW_ADC_OFF: |
526 | if (state->revision == 0x8090) { | ||
527 | reg = dib8000_read_word(state, 1925); | ||
528 | /* reset_sladc = 1 en_slowAdc = 0 */ | ||
529 | dib8000_write_word(state, 1925, | ||
530 | (reg & ~(1<<2)) | (1<<4)); | ||
531 | } | ||
469 | reg_908 |= (1 << 1) | (1 << 0); | 532 | reg_908 |= (1 << 1) | (1 << 0); |
470 | break; | 533 | break; |
471 | 534 | ||
@@ -521,7 +584,12 @@ static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) | |||
521 | 584 | ||
522 | static int dib8000_sad_calib(struct dib8000_state *state) | 585 | static int dib8000_sad_calib(struct dib8000_state *state) |
523 | { | 586 | { |
524 | /* internal */ | 587 | if (state->revision == 0x8090) { |
588 | dprintk("%s: the sad calibration is not needed for the dib8096P", | ||
589 | __func__); | ||
590 | return 0; | ||
591 | } | ||
592 | /* internal */ | ||
525 | dib8000_write_word(state, 923, (0 << 1) | (0 << 0)); | 593 | dib8000_write_word(state, 923, (0 << 1) | (0 << 0)); |
526 | dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096 | 594 | dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096 |
527 | 595 | ||
@@ -546,48 +614,129 @@ EXPORT_SYMBOL(dib8000_set_wbd_ref); | |||
546 | static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) | 614 | static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) |
547 | { | 615 | { |
548 | dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); | 616 | dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); |
549 | dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */ | 617 | if (state->revision != 0x8090) { |
550 | dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff)); | 618 | dib8000_write_word(state, 23, |
619 | (u16) (((bw->internal * 1000) >> 16) & 0xffff)); | ||
620 | dib8000_write_word(state, 24, | ||
621 | (u16) ((bw->internal * 1000) & 0xffff)); | ||
622 | } else { | ||
623 | dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff)); | ||
624 | dib8000_write_word(state, 24, | ||
625 | (u16) ((bw->internal / 2 * 1000) & 0xffff)); | ||
626 | } | ||
551 | dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff)); | 627 | dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff)); |
552 | dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff)); | 628 | dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff)); |
553 | dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003)); | 629 | dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003)); |
554 | 630 | ||
555 | dib8000_write_word(state, 922, bw->sad_cfg); | 631 | if (state->revision != 0x8090) |
632 | dib8000_write_word(state, 922, bw->sad_cfg); | ||
556 | } | 633 | } |
557 | 634 | ||
558 | static void dib8000_reset_pll(struct dib8000_state *state) | 635 | static void dib8000_reset_pll(struct dib8000_state *state) |
559 | { | 636 | { |
560 | const struct dibx000_bandwidth_config *pll = state->cfg.pll; | 637 | const struct dibx000_bandwidth_config *pll = state->cfg.pll; |
561 | u16 clk_cfg1; | 638 | u16 clk_cfg1, reg; |
562 | 639 | ||
563 | // clk_cfg0 | 640 | if (state->revision != 0x8090) { |
564 | dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); | 641 | dib8000_write_word(state, 901, |
565 | 642 | (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); | |
566 | // clk_cfg1 | 643 | |
567 | clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | | 644 | clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | |
568 | (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | | 645 | (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | |
569 | (pll->pll_range << 1) | (pll->pll_reset << 0); | 646 | (1 << 3) | (pll->pll_range << 1) | |
570 | 647 | (pll->pll_reset << 0); | |
571 | dib8000_write_word(state, 902, clk_cfg1); | 648 | |
572 | clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); | 649 | dib8000_write_word(state, 902, clk_cfg1); |
573 | dib8000_write_word(state, 902, clk_cfg1); | 650 | clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); |
574 | 651 | dib8000_write_word(state, 902, clk_cfg1); | |
575 | dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */ | 652 | |
576 | 653 | dprintk("clk_cfg1: 0x%04x", clk_cfg1); | |
577 | /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ | 654 | |
578 | if (state->cfg.pll->ADClkSrc == 0) | 655 | /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ |
579 | dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | | 656 | if (state->cfg.pll->ADClkSrc == 0) |
580 | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | 657 | dib8000_write_word(state, 904, |
581 | else if (state->cfg.refclksel != 0) | 658 | (0 << 15) | (0 << 12) | (0 << 10) | |
582 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | | 659 | (pll->modulo << 8) | |
583 | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | | 660 | (pll->ADClkSrc << 7) | (0 << 1)); |
584 | (pll->ADClkSrc << 7) | (0 << 1)); | 661 | else if (state->cfg.refclksel != 0) |
585 | else | 662 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | |
586 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | 663 | ((state->cfg.refclksel & 0x3) << 10) | |
664 | (pll->modulo << 8) | | ||
665 | (pll->ADClkSrc << 7) | (0 << 1)); | ||
666 | else | ||
667 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | | ||
668 | (3 << 10) | (pll->modulo << 8) | | ||
669 | (pll->ADClkSrc << 7) | (0 << 1)); | ||
670 | } else { | ||
671 | dib8000_write_word(state, 1856, (!pll->pll_reset<<13) | | ||
672 | (pll->pll_range<<12) | (pll->pll_ratio<<6) | | ||
673 | (pll->pll_prediv)); | ||
674 | |||
675 | reg = dib8000_read_word(state, 1857); | ||
676 | dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15)); | ||
677 | |||
678 | reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */ | ||
679 | dib8000_write_word(state, 1858, reg | 1); | ||
680 | |||
681 | dib8000_write_word(state, 904, (pll->modulo << 8)); | ||
682 | } | ||
587 | 683 | ||
588 | dib8000_reset_pll_common(state, pll); | 684 | dib8000_reset_pll_common(state, pll); |
589 | } | 685 | } |
590 | 686 | ||
687 | int dib8000_update_pll(struct dvb_frontend *fe, | ||
688 | struct dibx000_bandwidth_config *pll) | ||
689 | { | ||
690 | struct dib8000_state *state = fe->demodulator_priv; | ||
691 | u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856); | ||
692 | u8 loopdiv, prediv; | ||
693 | u32 internal, xtal; | ||
694 | |||
695 | /* get back old values */ | ||
696 | prediv = reg_1856 & 0x3f; | ||
697 | loopdiv = (reg_1856 >> 6) & 0x3f; | ||
698 | |||
699 | if ((pll != NULL) && (pll->pll_prediv != prediv || | ||
700 | pll->pll_ratio != loopdiv)) { | ||
701 | dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); | ||
702 | reg_1856 &= 0xf000; | ||
703 | reg_1857 = dib8000_read_word(state, 1857); | ||
704 | /* disable PLL */ | ||
705 | dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15)); | ||
706 | |||
707 | dib8000_write_word(state, 1856, reg_1856 | | ||
708 | ((pll->pll_ratio & 0x3f) << 6) | | ||
709 | (pll->pll_prediv & 0x3f)); | ||
710 | |||
711 | /* write new system clk into P_sec_len */ | ||
712 | internal = dib8000_read32(state, 23) / 1000; | ||
713 | dprintk("Old Internal = %d", internal); | ||
714 | xtal = 2 * (internal / loopdiv) * prediv; | ||
715 | internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio; | ||
716 | dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000); | ||
717 | dprintk("New Internal = %d", internal); | ||
718 | |||
719 | dib8000_write_word(state, 23, | ||
720 | (u16) (((internal / 2) >> 16) & 0xffff)); | ||
721 | dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff)); | ||
722 | /* enable PLL */ | ||
723 | dib8000_write_word(state, 1857, reg_1857 | (1 << 15)); | ||
724 | |||
725 | while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1) | ||
726 | dprintk("Waiting for PLL to lock"); | ||
727 | |||
728 | /* verify */ | ||
729 | reg_1856 = dib8000_read_word(state, 1856); | ||
730 | dprintk("PLL Updated with prediv = %d and loopdiv = %d", | ||
731 | reg_1856&0x3f, (reg_1856>>6)&0x3f); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | return -EINVAL; | ||
736 | } | ||
737 | EXPORT_SYMBOL(dib8000_update_pll); | ||
738 | |||
739 | |||
591 | static int dib8000_reset_gpio(struct dib8000_state *st) | 740 | static int dib8000_reset_gpio(struct dib8000_state *st) |
592 | { | 741 | { |
593 | /* reset the GPIOs */ | 742 | /* reset the GPIOs */ |
@@ -721,9 +870,6 @@ static const u16 dib8000_defaults[] = { | |||
721 | (3 << 5) | /* P_ctrl_pre_freq_step=3 */ | 870 | (3 << 5) | /* P_ctrl_pre_freq_step=3 */ |
722 | (1 << 0), /* P_pre_freq_win_len=1 */ | 871 | (1 << 0), /* P_pre_freq_win_len=1 */ |
723 | 872 | ||
724 | 1, 903, | ||
725 | (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) | ||
726 | |||
727 | 0, | 873 | 0, |
728 | }; | 874 | }; |
729 | 875 | ||
@@ -740,7 +886,8 @@ static u16 dib8000_identify(struct i2c_device *client) | |||
740 | } | 886 | } |
741 | 887 | ||
742 | value = dib8000_i2c_read16(client, 897); | 888 | value = dib8000_i2c_read16(client, 897); |
743 | if (value != 0x8000 && value != 0x8001 && value != 0x8002) { | 889 | if (value != 0x8000 && value != 0x8001 && |
890 | value != 0x8002 && value != 0x8090) { | ||
744 | dprintk("wrong Device ID (%x)", value); | 891 | dprintk("wrong Device ID (%x)", value); |
745 | return 0; | 892 | return 0; |
746 | } | 893 | } |
@@ -755,6 +902,9 @@ static u16 dib8000_identify(struct i2c_device *client) | |||
755 | case 0x8002: | 902 | case 0x8002: |
756 | dprintk("found DiB8000C"); | 903 | dprintk("found DiB8000C"); |
757 | break; | 904 | break; |
905 | case 0x8090: | ||
906 | dprintk("found DiB8096P"); | ||
907 | break; | ||
758 | } | 908 | } |
759 | return value; | 909 | return value; |
760 | } | 910 | } |
@@ -763,17 +913,19 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
763 | { | 913 | { |
764 | struct dib8000_state *state = fe->demodulator_priv; | 914 | struct dib8000_state *state = fe->demodulator_priv; |
765 | 915 | ||
766 | dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */ | ||
767 | |||
768 | if ((state->revision = dib8000_identify(&state->i2c)) == 0) | 916 | if ((state->revision = dib8000_identify(&state->i2c)) == 0) |
769 | return -EINVAL; | 917 | return -EINVAL; |
770 | 918 | ||
919 | /* sram lead in, rdy */ | ||
920 | if (state->revision != 0x8090) | ||
921 | dib8000_write_word(state, 1287, 0x0003); | ||
922 | |||
771 | if (state->revision == 0x8000) | 923 | if (state->revision == 0x8000) |
772 | dprintk("error : dib8000 MA not supported"); | 924 | dprintk("error : dib8000 MA not supported"); |
773 | 925 | ||
774 | dibx000_reset_i2c_master(&state->i2c_master); | 926 | dibx000_reset_i2c_master(&state->i2c_master); |
775 | 927 | ||
776 | dib8000_set_power_mode(state, DIB8000M_POWER_ALL); | 928 | dib8000_set_power_mode(state, DIB8000_POWER_ALL); |
777 | 929 | ||
778 | /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ | 930 | /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ |
779 | dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); | 931 | dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); |
@@ -782,8 +934,10 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
782 | dib8000_write_word(state, 770, 0xffff); | 934 | dib8000_write_word(state, 770, 0xffff); |
783 | dib8000_write_word(state, 771, 0xffff); | 935 | dib8000_write_word(state, 771, 0xffff); |
784 | dib8000_write_word(state, 772, 0xfffc); | 936 | dib8000_write_word(state, 772, 0xfffc); |
785 | dib8000_write_word(state, 898, 0x000c); // sad | 937 | if (state->revision == 0x8090) |
786 | dib8000_write_word(state, 1280, 0x004d); | 938 | dib8000_write_word(state, 1280, 0x0045); |
939 | else | ||
940 | dib8000_write_word(state, 1280, 0x004d); | ||
787 | dib8000_write_word(state, 1281, 0x000c); | 941 | dib8000_write_word(state, 1281, 0x000c); |
788 | 942 | ||
789 | dib8000_write_word(state, 770, 0x0000); | 943 | dib8000_write_word(state, 770, 0x0000); |
@@ -794,19 +948,25 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
794 | dib8000_write_word(state, 1281, 0x0000); | 948 | dib8000_write_word(state, 1281, 0x0000); |
795 | 949 | ||
796 | /* drives */ | 950 | /* drives */ |
797 | if (state->cfg.drives) | 951 | if (state->revision != 0x8090) { |
798 | dib8000_write_word(state, 906, state->cfg.drives); | 952 | if (state->cfg.drives) |
799 | else { | 953 | dib8000_write_word(state, 906, state->cfg.drives); |
800 | dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); | 954 | else { |
801 | dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust | 955 | dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); |
956 | /* min drive SDRAM - not optimal - adjust */ | ||
957 | dib8000_write_word(state, 906, 0x2d98); | ||
958 | } | ||
802 | } | 959 | } |
803 | 960 | ||
804 | dib8000_reset_pll(state); | 961 | dib8000_reset_pll(state); |
962 | if (state->revision != 0x8090) | ||
963 | dib8000_write_word(state, 898, 0x0004); | ||
805 | 964 | ||
806 | if (dib8000_reset_gpio(state) != 0) | 965 | if (dib8000_reset_gpio(state) != 0) |
807 | dprintk("GPIO reset was not successful."); | 966 | dprintk("GPIO reset was not successful."); |
808 | 967 | ||
809 | if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) | 968 | if ((state->revision != 0x8090) && |
969 | (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)) | ||
810 | dprintk("OUTPUT_MODE could not be resetted."); | 970 | dprintk("OUTPUT_MODE could not be resetted."); |
811 | 971 | ||
812 | state->current_agc = NULL; | 972 | state->current_agc = NULL; |
@@ -832,6 +992,8 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
832 | l = *n++; | 992 | l = *n++; |
833 | } | 993 | } |
834 | } | 994 | } |
995 | if (state->revision != 0x8090) | ||
996 | dib8000_write_word(state, 903, (0 << 4) | 2); | ||
835 | state->isdbt_cfg_loaded = 0; | 997 | state->isdbt_cfg_loaded = 0; |
836 | 998 | ||
837 | //div_cfg override for special configs | 999 | //div_cfg override for special configs |
@@ -844,10 +1006,12 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
844 | dib8000_set_bandwidth(fe, 6000); | 1006 | dib8000_set_bandwidth(fe, 6000); |
845 | 1007 | ||
846 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); | 1008 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); |
847 | dib8000_sad_calib(state); | 1009 | if (state->revision != 0x8090) { |
848 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); | 1010 | dib8000_sad_calib(state); |
1011 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); | ||
1012 | } | ||
849 | 1013 | ||
850 | dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); | 1014 | dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); |
851 | 1015 | ||
852 | return 0; | 1016 | return 0; |
853 | } | 1017 | } |
@@ -879,6 +1043,8 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) | |||
879 | { | 1043 | { |
880 | struct dibx000_agc_config *agc = NULL; | 1044 | struct dibx000_agc_config *agc = NULL; |
881 | int i; | 1045 | int i; |
1046 | u16 reg; | ||
1047 | |||
882 | if (state->current_band == band && state->current_agc != NULL) | 1048 | if (state->current_band == band && state->current_agc != NULL) |
883 | return 0; | 1049 | return 0; |
884 | state->current_band = band; | 1050 | state->current_band = band; |
@@ -914,6 +1080,12 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) | |||
914 | dib8000_write_word(state, 106, state->wbd_ref); | 1080 | dib8000_write_word(state, 106, state->wbd_ref); |
915 | else // use default | 1081 | else // use default |
916 | dib8000_write_word(state, 106, agc->wbd_ref); | 1082 | dib8000_write_word(state, 106, agc->wbd_ref); |
1083 | |||
1084 | if (state->revision == 0x8090) { | ||
1085 | reg = dib8000_read_word(state, 922) & (0x3 << 2); | ||
1086 | dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2)); | ||
1087 | } | ||
1088 | |||
917 | dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); | 1089 | dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); |
918 | dib8000_write_word(state, 108, agc->agc1_max); | 1090 | dib8000_write_word(state, 108, agc->agc1_max); |
919 | dib8000_write_word(state, 109, agc->agc1_min); | 1091 | dib8000_write_word(state, 109, agc->agc1_min); |
@@ -925,7 +1097,10 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) | |||
925 | dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); | 1097 | dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); |
926 | 1098 | ||
927 | dib8000_write_word(state, 75, agc->agc1_pt3); | 1099 | dib8000_write_word(state, 75, agc->agc1_pt3); |
928 | dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */ | 1100 | if (state->revision != 0x8090) |
1101 | dib8000_write_word(state, 923, | ||
1102 | (dib8000_read_word(state, 923) & 0xffe3) | | ||
1103 | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); | ||
929 | 1104 | ||
930 | return 0; | 1105 | return 0; |
931 | } | 1106 | } |
@@ -968,14 +1143,30 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
968 | { | 1143 | { |
969 | struct dib8000_state *state = fe->demodulator_priv; | 1144 | struct dib8000_state *state = fe->demodulator_priv; |
970 | enum frontend_tune_state *tune_state = &state->tune_state; | 1145 | enum frontend_tune_state *tune_state = &state->tune_state; |
971 | |||
972 | int ret = 0; | 1146 | int ret = 0; |
1147 | u16 reg, upd_demod_gain_period = 0x8000; | ||
973 | 1148 | ||
974 | switch (*tune_state) { | 1149 | switch (*tune_state) { |
975 | case CT_AGC_START: | 1150 | case CT_AGC_START: |
976 | // set power-up level: interf+analog+AGC | 1151 | // set power-up level: interf+analog+AGC |
977 | 1152 | ||
978 | dib8000_set_adc_state(state, DIBX000_ADC_ON); | 1153 | if (state->revision != 0x8090) |
1154 | dib8000_set_adc_state(state, DIBX000_ADC_ON); | ||
1155 | else { | ||
1156 | dib8000_set_power_mode(state, DIB8000_POWER_ALL); | ||
1157 | |||
1158 | reg = dib8000_read_word(state, 1947)&0xff00; | ||
1159 | dib8000_write_word(state, 1946, | ||
1160 | upd_demod_gain_period & 0xFFFF); | ||
1161 | /* bit 14 = enDemodGain */ | ||
1162 | dib8000_write_word(state, 1947, reg | (1<<14) | | ||
1163 | ((upd_demod_gain_period >> 16) & 0xFF)); | ||
1164 | |||
1165 | /* enable adc i & q */ | ||
1166 | reg = dib8000_read_word(state, 1920); | ||
1167 | dib8000_write_word(state, 1920, (reg | 0x3) & | ||
1168 | (~(1 << 7))); | ||
1169 | } | ||
979 | 1170 | ||
980 | if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) { | 1171 | if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) { |
981 | *tune_state = CT_AGC_STOP; | 1172 | *tune_state = CT_AGC_STOP; |
@@ -1026,6 +1217,579 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
1026 | 1217 | ||
1027 | } | 1218 | } |
1028 | 1219 | ||
1220 | static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive) | ||
1221 | { | ||
1222 | u16 reg; | ||
1223 | |||
1224 | drive &= 0x7; | ||
1225 | |||
1226 | /* drive host bus 2, 3, 4 */ | ||
1227 | reg = dib8000_read_word(state, 1798) & | ||
1228 | ~(0x7 | (0x7 << 6) | (0x7 << 12)); | ||
1229 | reg |= (drive<<12) | (drive<<6) | drive; | ||
1230 | dib8000_write_word(state, 1798, reg); | ||
1231 | |||
1232 | /* drive host bus 5,6 */ | ||
1233 | reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8)); | ||
1234 | reg |= (drive<<8) | (drive<<2); | ||
1235 | dib8000_write_word(state, 1799, reg); | ||
1236 | |||
1237 | /* drive host bus 7, 8, 9 */ | ||
1238 | reg = dib8000_read_word(state, 1800) & | ||
1239 | ~(0x7 | (0x7 << 6) | (0x7 << 12)); | ||
1240 | reg |= (drive<<12) | (drive<<6) | drive; | ||
1241 | dib8000_write_word(state, 1800, reg); | ||
1242 | |||
1243 | /* drive host bus 10, 11 */ | ||
1244 | reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8)); | ||
1245 | reg |= (drive<<8) | (drive<<2); | ||
1246 | dib8000_write_word(state, 1801, reg); | ||
1247 | |||
1248 | /* drive host bus 12, 13, 14 */ | ||
1249 | reg = dib8000_read_word(state, 1802) & | ||
1250 | ~(0x7 | (0x7 << 6) | (0x7 << 12)); | ||
1251 | reg |= (drive<<12) | (drive<<6) | drive; | ||
1252 | dib8000_write_word(state, 1802, reg); | ||
1253 | } | ||
1254 | |||
1255 | static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout, | ||
1256 | u32 insertExtSynchro, u32 syncSize) | ||
1257 | { | ||
1258 | u32 quantif = 3; | ||
1259 | u32 nom = (insertExtSynchro * P_Kin+syncSize); | ||
1260 | u32 denom = P_Kout; | ||
1261 | u32 syncFreq = ((nom << quantif) / denom); | ||
1262 | |||
1263 | if ((syncFreq & ((1 << quantif) - 1)) != 0) | ||
1264 | syncFreq = (syncFreq >> quantif) + 1; | ||
1265 | else | ||
1266 | syncFreq = (syncFreq >> quantif); | ||
1267 | |||
1268 | if (syncFreq != 0) | ||
1269 | syncFreq = syncFreq - 1; | ||
1270 | |||
1271 | return syncFreq; | ||
1272 | } | ||
1273 | |||
1274 | static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin, | ||
1275 | u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, | ||
1276 | u32 syncWord, u32 syncSize) | ||
1277 | { | ||
1278 | dprintk("Configure DibStream Tx"); | ||
1279 | |||
1280 | dib8000_write_word(state, 1615, 1); | ||
1281 | dib8000_write_word(state, 1603, P_Kin); | ||
1282 | dib8000_write_word(state, 1605, P_Kout); | ||
1283 | dib8000_write_word(state, 1606, insertExtSynchro); | ||
1284 | dib8000_write_word(state, 1608, synchroMode); | ||
1285 | dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff); | ||
1286 | dib8000_write_word(state, 1610, syncWord & 0xffff); | ||
1287 | dib8000_write_word(state, 1612, syncSize); | ||
1288 | dib8000_write_word(state, 1615, 0); | ||
1289 | } | ||
1290 | |||
1291 | static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin, | ||
1292 | u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, | ||
1293 | u32 syncWord, u32 syncSize, u32 dataOutRate) | ||
1294 | { | ||
1295 | u32 syncFreq; | ||
1296 | |||
1297 | dprintk("Configure DibStream Rx synchroMode = %d", synchroMode); | ||
1298 | |||
1299 | if ((P_Kin != 0) && (P_Kout != 0)) { | ||
1300 | syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout, | ||
1301 | insertExtSynchro, syncSize); | ||
1302 | dib8000_write_word(state, 1542, syncFreq); | ||
1303 | } | ||
1304 | |||
1305 | dib8000_write_word(state, 1554, 1); | ||
1306 | dib8000_write_word(state, 1536, P_Kin); | ||
1307 | dib8000_write_word(state, 1537, P_Kout); | ||
1308 | dib8000_write_word(state, 1539, synchroMode); | ||
1309 | dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff); | ||
1310 | dib8000_write_word(state, 1541, syncWord & 0xffff); | ||
1311 | dib8000_write_word(state, 1543, syncSize); | ||
1312 | dib8000_write_word(state, 1544, dataOutRate); | ||
1313 | dib8000_write_word(state, 1554, 0); | ||
1314 | } | ||
1315 | |||
1316 | static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff) | ||
1317 | { | ||
1318 | u16 reg_1287; | ||
1319 | |||
1320 | reg_1287 = dib8000_read_word(state, 1287); | ||
1321 | |||
1322 | switch (onoff) { | ||
1323 | case 1: | ||
1324 | reg_1287 &= ~(1 << 8); | ||
1325 | break; | ||
1326 | case 0: | ||
1327 | reg_1287 |= (1 << 8); | ||
1328 | break; | ||
1329 | } | ||
1330 | |||
1331 | dib8000_write_word(state, 1287, reg_1287); | ||
1332 | } | ||
1333 | |||
1334 | static void dib8096p_configMpegMux(struct dib8000_state *state, | ||
1335 | u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) | ||
1336 | { | ||
1337 | u16 reg_1287; | ||
1338 | |||
1339 | dprintk("Enable Mpeg mux"); | ||
1340 | |||
1341 | dib8096p_enMpegMux(state, 0); | ||
1342 | |||
1343 | /* If the input mode is MPEG do not divide the serial clock */ | ||
1344 | if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) | ||
1345 | enSerialClkDiv2 = 0; | ||
1346 | |||
1347 | reg_1287 = ((pulseWidth & 0x1f) << 3) | | ||
1348 | ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1); | ||
1349 | dib8000_write_word(state, 1287, reg_1287); | ||
1350 | |||
1351 | dib8096p_enMpegMux(state, 1); | ||
1352 | } | ||
1353 | |||
1354 | static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode) | ||
1355 | { | ||
1356 | u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7); | ||
1357 | |||
1358 | switch (mode) { | ||
1359 | case MPEG_ON_DIBTX: | ||
1360 | dprintk("SET MPEG ON DIBSTREAM TX"); | ||
1361 | dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); | ||
1362 | reg_1288 |= (1 << 9); break; | ||
1363 | case DIV_ON_DIBTX: | ||
1364 | dprintk("SET DIV_OUT ON DIBSTREAM TX"); | ||
1365 | dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); | ||
1366 | reg_1288 |= (1 << 8); break; | ||
1367 | case ADC_ON_DIBTX: | ||
1368 | dprintk("SET ADC_OUT ON DIBSTREAM TX"); | ||
1369 | dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); | ||
1370 | reg_1288 |= (1 << 7); break; | ||
1371 | default: | ||
1372 | break; | ||
1373 | } | ||
1374 | dib8000_write_word(state, 1288, reg_1288); | ||
1375 | } | ||
1376 | |||
1377 | static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode) | ||
1378 | { | ||
1379 | u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4); | ||
1380 | |||
1381 | switch (mode) { | ||
1382 | case DEMOUT_ON_HOSTBUS: | ||
1383 | dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); | ||
1384 | dib8096p_enMpegMux(state, 0); | ||
1385 | reg_1288 |= (1 << 6); | ||
1386 | break; | ||
1387 | case DIBTX_ON_HOSTBUS: | ||
1388 | dprintk("SET DIBSTREAM TX ON HOST BUS"); | ||
1389 | dib8096p_enMpegMux(state, 0); | ||
1390 | reg_1288 |= (1 << 5); | ||
1391 | break; | ||
1392 | case MPEG_ON_HOSTBUS: | ||
1393 | dprintk("SET MPEG MUX ON HOST BUS"); | ||
1394 | reg_1288 |= (1 << 4); | ||
1395 | break; | ||
1396 | default: | ||
1397 | break; | ||
1398 | } | ||
1399 | dib8000_write_word(state, 1288, reg_1288); | ||
1400 | } | ||
1401 | |||
1402 | static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff) | ||
1403 | { | ||
1404 | struct dib8000_state *state = fe->demodulator_priv; | ||
1405 | u16 reg_1287; | ||
1406 | |||
1407 | switch (onoff) { | ||
1408 | case 0: /* only use the internal way - not the diversity input */ | ||
1409 | dprintk("%s mode OFF : by default Enable Mpeg INPUT", | ||
1410 | __func__); | ||
1411 | /* outputRate = 8 */ | ||
1412 | dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); | ||
1413 | |||
1414 | /* Do not divide the serial clock of MPEG MUX in | ||
1415 | SERIAL MODE in case input mode MPEG is used */ | ||
1416 | reg_1287 = dib8000_read_word(state, 1287); | ||
1417 | /* enSerialClkDiv2 == 1 ? */ | ||
1418 | if ((reg_1287 & 0x1) == 1) { | ||
1419 | /* force enSerialClkDiv2 = 0 */ | ||
1420 | reg_1287 &= ~0x1; | ||
1421 | dib8000_write_word(state, 1287, reg_1287); | ||
1422 | } | ||
1423 | state->input_mode_mpeg = 1; | ||
1424 | break; | ||
1425 | case 1: /* both ways */ | ||
1426 | case 2: /* only the diversity input */ | ||
1427 | dprintk("%s ON : Enable diversity INPUT", __func__); | ||
1428 | dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); | ||
1429 | state->input_mode_mpeg = 0; | ||
1430 | break; | ||
1431 | } | ||
1432 | |||
1433 | dib8000_set_diversity_in(state->fe[0], onoff); | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) | ||
1438 | { | ||
1439 | struct dib8000_state *state = fe->demodulator_priv; | ||
1440 | u16 outreg, smo_mode, fifo_threshold; | ||
1441 | u8 prefer_mpeg_mux_use = 1; | ||
1442 | int ret = 0; | ||
1443 | |||
1444 | dib8096p_host_bus_drive(state, 1); | ||
1445 | |||
1446 | fifo_threshold = 1792; | ||
1447 | smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); | ||
1448 | outreg = dib8000_read_word(state, 1286) & | ||
1449 | ~((1 << 10) | (0x7 << 6) | (1 << 1)); | ||
1450 | |||
1451 | switch (mode) { | ||
1452 | case OUTMODE_HIGH_Z: | ||
1453 | outreg = 0; | ||
1454 | break; | ||
1455 | |||
1456 | case OUTMODE_MPEG2_SERIAL: | ||
1457 | if (prefer_mpeg_mux_use) { | ||
1458 | dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux"); | ||
1459 | dib8096p_configMpegMux(state, 3, 1, 1); | ||
1460 | dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); | ||
1461 | } else {/* Use Smooth block */ | ||
1462 | dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc"); | ||
1463 | dib8096p_setHostBusMux(state, | ||
1464 | DEMOUT_ON_HOSTBUS); | ||
1465 | outreg |= (2 << 6) | (0 << 1); | ||
1466 | } | ||
1467 | break; | ||
1468 | |||
1469 | case OUTMODE_MPEG2_PAR_GATED_CLK: | ||
1470 | if (prefer_mpeg_mux_use) { | ||
1471 | dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); | ||
1472 | dib8096p_configMpegMux(state, 2, 0, 0); | ||
1473 | dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); | ||
1474 | } else { /* Use Smooth block */ | ||
1475 | dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block"); | ||
1476 | dib8096p_setHostBusMux(state, | ||
1477 | DEMOUT_ON_HOSTBUS); | ||
1478 | outreg |= (0 << 6); | ||
1479 | } | ||
1480 | break; | ||
1481 | |||
1482 | case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ | ||
1483 | dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block"); | ||
1484 | dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); | ||
1485 | outreg |= (1 << 6); | ||
1486 | break; | ||
1487 | |||
1488 | case OUTMODE_MPEG2_FIFO: | ||
1489 | /* Using Smooth block because not supported | ||
1490 | by new Mpeg Mux bloc */ | ||
1491 | dprintk("dib8096P setting output mode TS_FIFO using Smooth block"); | ||
1492 | dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); | ||
1493 | outreg |= (5 << 6); | ||
1494 | smo_mode |= (3 << 1); | ||
1495 | fifo_threshold = 512; | ||
1496 | break; | ||
1497 | |||
1498 | case OUTMODE_DIVERSITY: | ||
1499 | dprintk("dib8096P setting output mode MODE_DIVERSITY"); | ||
1500 | dib8096p_setDibTxMux(state, DIV_ON_DIBTX); | ||
1501 | dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); | ||
1502 | break; | ||
1503 | |||
1504 | case OUTMODE_ANALOG_ADC: | ||
1505 | dprintk("dib8096P setting output mode MODE_ANALOG_ADC"); | ||
1506 | dib8096p_setDibTxMux(state, ADC_ON_DIBTX); | ||
1507 | dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); | ||
1508 | break; | ||
1509 | } | ||
1510 | |||
1511 | if (mode != OUTMODE_HIGH_Z) | ||
1512 | outreg |= (1<<10); | ||
1513 | |||
1514 | dprintk("output_mpeg2_in_188_bytes = %d", | ||
1515 | state->cfg.output_mpeg2_in_188_bytes); | ||
1516 | if (state->cfg.output_mpeg2_in_188_bytes) | ||
1517 | smo_mode |= (1 << 5); | ||
1518 | |||
1519 | ret |= dib8000_write_word(state, 299, smo_mode); | ||
1520 | /* synchronous fread */ | ||
1521 | ret |= dib8000_write_word(state, 299 + 1, fifo_threshold); | ||
1522 | ret |= dib8000_write_word(state, 1286, outreg); | ||
1523 | |||
1524 | return ret; | ||
1525 | } | ||
1526 | |||
1527 | static int map_addr_to_serpar_number(struct i2c_msg *msg) | ||
1528 | { | ||
1529 | if (msg->buf[0] <= 15) | ||
1530 | msg->buf[0] -= 1; | ||
1531 | else if (msg->buf[0] == 17) | ||
1532 | msg->buf[0] = 15; | ||
1533 | else if (msg->buf[0] == 16) | ||
1534 | msg->buf[0] = 17; | ||
1535 | else if (msg->buf[0] == 19) | ||
1536 | msg->buf[0] = 16; | ||
1537 | else if (msg->buf[0] >= 21 && msg->buf[0] <= 25) | ||
1538 | msg->buf[0] -= 3; | ||
1539 | else if (msg->buf[0] == 28) | ||
1540 | msg->buf[0] = 23; | ||
1541 | else if (msg->buf[0] == 99) | ||
1542 | msg->buf[0] = 99; | ||
1543 | else | ||
1544 | return -EINVAL; | ||
1545 | return 0; | ||
1546 | } | ||
1547 | |||
1548 | static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap, | ||
1549 | struct i2c_msg msg[], int num) | ||
1550 | { | ||
1551 | struct dib8000_state *state = i2c_get_adapdata(i2c_adap); | ||
1552 | u8 n_overflow = 1; | ||
1553 | u16 i = 1000; | ||
1554 | u16 serpar_num = msg[0].buf[0]; | ||
1555 | |||
1556 | while (n_overflow == 1 && i) { | ||
1557 | n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; | ||
1558 | i--; | ||
1559 | if (i == 0) | ||
1560 | dprintk("Tuner ITF: write busy (overflow)"); | ||
1561 | } | ||
1562 | dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); | ||
1563 | dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); | ||
1564 | |||
1565 | return num; | ||
1566 | } | ||
1567 | |||
1568 | static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap, | ||
1569 | struct i2c_msg msg[], int num) | ||
1570 | { | ||
1571 | struct dib8000_state *state = i2c_get_adapdata(i2c_adap); | ||
1572 | u8 n_overflow = 1, n_empty = 1; | ||
1573 | u16 i = 1000; | ||
1574 | u16 serpar_num = msg[0].buf[0]; | ||
1575 | u16 read_word; | ||
1576 | |||
1577 | while (n_overflow == 1 && i) { | ||
1578 | n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; | ||
1579 | i--; | ||
1580 | if (i == 0) | ||
1581 | dprintk("TunerITF: read busy (overflow)"); | ||
1582 | } | ||
1583 | dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f)); | ||
1584 | |||
1585 | i = 1000; | ||
1586 | while (n_empty == 1 && i) { | ||
1587 | n_empty = dib8000_read_word(state, 1984)&0x1; | ||
1588 | i--; | ||
1589 | if (i == 0) | ||
1590 | dprintk("TunerITF: read busy (empty)"); | ||
1591 | } | ||
1592 | |||
1593 | read_word = dib8000_read_word(state, 1987); | ||
1594 | msg[1].buf[0] = (read_word >> 8) & 0xff; | ||
1595 | msg[1].buf[1] = (read_word) & 0xff; | ||
1596 | |||
1597 | return num; | ||
1598 | } | ||
1599 | |||
1600 | static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, | ||
1601 | struct i2c_msg msg[], int num) | ||
1602 | { | ||
1603 | if (map_addr_to_serpar_number(&msg[0]) == 0) { | ||
1604 | if (num == 1) /* write */ | ||
1605 | return dib8096p_tuner_write_serpar(i2c_adap, msg, 1); | ||
1606 | else /* read */ | ||
1607 | return dib8096p_tuner_read_serpar(i2c_adap, msg, 2); | ||
1608 | } | ||
1609 | return num; | ||
1610 | } | ||
1611 | |||
1612 | static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap, | ||
1613 | struct i2c_msg msg[], int num, u16 apb_address) | ||
1614 | { | ||
1615 | struct dib8000_state *state = i2c_get_adapdata(i2c_adap); | ||
1616 | u16 word; | ||
1617 | |||
1618 | if (num == 1) { /* write */ | ||
1619 | dib8000_write_word(state, apb_address, | ||
1620 | ((msg[0].buf[1] << 8) | (msg[0].buf[2]))); | ||
1621 | } else { | ||
1622 | word = dib8000_read_word(state, apb_address); | ||
1623 | msg[1].buf[0] = (word >> 8) & 0xff; | ||
1624 | msg[1].buf[1] = (word) & 0xff; | ||
1625 | } | ||
1626 | return num; | ||
1627 | } | ||
1628 | |||
1629 | static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap, | ||
1630 | struct i2c_msg msg[], int num) | ||
1631 | { | ||
1632 | struct dib8000_state *state = i2c_get_adapdata(i2c_adap); | ||
1633 | u16 apb_address = 0, word; | ||
1634 | int i = 0; | ||
1635 | |||
1636 | switch (msg[0].buf[0]) { | ||
1637 | case 0x12: | ||
1638 | apb_address = 1920; | ||
1639 | break; | ||
1640 | case 0x14: | ||
1641 | apb_address = 1921; | ||
1642 | break; | ||
1643 | case 0x24: | ||
1644 | apb_address = 1922; | ||
1645 | break; | ||
1646 | case 0x1a: | ||
1647 | apb_address = 1923; | ||
1648 | break; | ||
1649 | case 0x22: | ||
1650 | apb_address = 1924; | ||
1651 | break; | ||
1652 | case 0x33: | ||
1653 | apb_address = 1926; | ||
1654 | break; | ||
1655 | case 0x34: | ||
1656 | apb_address = 1927; | ||
1657 | break; | ||
1658 | case 0x35: | ||
1659 | apb_address = 1928; | ||
1660 | break; | ||
1661 | case 0x36: | ||
1662 | apb_address = 1929; | ||
1663 | break; | ||
1664 | case 0x37: | ||
1665 | apb_address = 1930; | ||
1666 | break; | ||
1667 | case 0x38: | ||
1668 | apb_address = 1931; | ||
1669 | break; | ||
1670 | case 0x39: | ||
1671 | apb_address = 1932; | ||
1672 | break; | ||
1673 | case 0x2a: | ||
1674 | apb_address = 1935; | ||
1675 | break; | ||
1676 | case 0x2b: | ||
1677 | apb_address = 1936; | ||
1678 | break; | ||
1679 | case 0x2c: | ||
1680 | apb_address = 1937; | ||
1681 | break; | ||
1682 | case 0x2d: | ||
1683 | apb_address = 1938; | ||
1684 | break; | ||
1685 | case 0x2e: | ||
1686 | apb_address = 1939; | ||
1687 | break; | ||
1688 | case 0x2f: | ||
1689 | apb_address = 1940; | ||
1690 | break; | ||
1691 | case 0x30: | ||
1692 | apb_address = 1941; | ||
1693 | break; | ||
1694 | case 0x31: | ||
1695 | apb_address = 1942; | ||
1696 | break; | ||
1697 | case 0x32: | ||
1698 | apb_address = 1943; | ||
1699 | break; | ||
1700 | case 0x3e: | ||
1701 | apb_address = 1944; | ||
1702 | break; | ||
1703 | case 0x3f: | ||
1704 | apb_address = 1945; | ||
1705 | break; | ||
1706 | case 0x40: | ||
1707 | apb_address = 1948; | ||
1708 | break; | ||
1709 | case 0x25: | ||
1710 | apb_address = 936; | ||
1711 | break; | ||
1712 | case 0x26: | ||
1713 | apb_address = 937; | ||
1714 | break; | ||
1715 | case 0x27: | ||
1716 | apb_address = 938; | ||
1717 | break; | ||
1718 | case 0x28: | ||
1719 | apb_address = 939; | ||
1720 | break; | ||
1721 | case 0x1d: | ||
1722 | /* get sad sel request */ | ||
1723 | i = ((dib8000_read_word(state, 921) >> 12)&0x3); | ||
1724 | word = dib8000_read_word(state, 924+i); | ||
1725 | msg[1].buf[0] = (word >> 8) & 0xff; | ||
1726 | msg[1].buf[1] = (word) & 0xff; | ||
1727 | return num; | ||
1728 | case 0x1f: | ||
1729 | if (num == 1) { /* write */ | ||
1730 | word = (u16) ((msg[0].buf[1] << 8) | | ||
1731 | msg[0].buf[2]); | ||
1732 | /* in the VGAMODE Sel are located on bit 0/1 */ | ||
1733 | word &= 0x3; | ||
1734 | word = (dib8000_read_word(state, 921) & | ||
1735 | ~(3<<12)) | (word<<12); | ||
1736 | /* Set the proper input */ | ||
1737 | dib8000_write_word(state, 921, word); | ||
1738 | return num; | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | if (apb_address != 0) /* R/W acces via APB */ | ||
1743 | return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address); | ||
1744 | else /* R/W access via SERPAR */ | ||
1745 | return dib8096p_tuner_rw_serpar(i2c_adap, msg, num); | ||
1746 | |||
1747 | return 0; | ||
1748 | } | ||
1749 | |||
1750 | static u32 dib8096p_i2c_func(struct i2c_adapter *adapter) | ||
1751 | { | ||
1752 | return I2C_FUNC_I2C; | ||
1753 | } | ||
1754 | |||
1755 | static struct i2c_algorithm dib8096p_tuner_xfer_algo = { | ||
1756 | .master_xfer = dib8096p_tuner_xfer, | ||
1757 | .functionality = dib8096p_i2c_func, | ||
1758 | }; | ||
1759 | |||
1760 | struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) | ||
1761 | { | ||
1762 | struct dib8000_state *st = fe->demodulator_priv; | ||
1763 | return &st->dib8096p_tuner_adap; | ||
1764 | } | ||
1765 | EXPORT_SYMBOL(dib8096p_get_i2c_tuner); | ||
1766 | |||
1767 | int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) | ||
1768 | { | ||
1769 | struct dib8000_state *state = fe->demodulator_priv; | ||
1770 | u16 en_cur_state; | ||
1771 | |||
1772 | dprintk("sleep dib8096p: %d", onoff); | ||
1773 | |||
1774 | en_cur_state = dib8000_read_word(state, 1922); | ||
1775 | |||
1776 | /* LNAs and MIX are ON and therefore it is a valid configuration */ | ||
1777 | if (en_cur_state > 0xff) | ||
1778 | state->tuner_enable = en_cur_state ; | ||
1779 | |||
1780 | if (onoff) | ||
1781 | en_cur_state &= 0x00ff; | ||
1782 | else { | ||
1783 | if (state->tuner_enable != 0) | ||
1784 | en_cur_state = state->tuner_enable; | ||
1785 | } | ||
1786 | |||
1787 | dib8000_write_word(state, 1922, en_cur_state); | ||
1788 | |||
1789 | return 0; | ||
1790 | } | ||
1791 | EXPORT_SYMBOL(dib8096p_tuner_sleep); | ||
1792 | |||
1029 | static const s32 lut_1000ln_mant[] = | 1793 | static const s32 lut_1000ln_mant[] = |
1030 | { | 1794 | { |
1031 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 | 1795 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 |
@@ -1051,6 +1815,26 @@ s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) | |||
1051 | } | 1815 | } |
1052 | EXPORT_SYMBOL(dib8000_get_adc_power); | 1816 | EXPORT_SYMBOL(dib8000_get_adc_power); |
1053 | 1817 | ||
1818 | int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) | ||
1819 | { | ||
1820 | struct dib8000_state *state = fe->demodulator_priv; | ||
1821 | int val = 0; | ||
1822 | |||
1823 | switch (IQ) { | ||
1824 | case 1: | ||
1825 | val = dib8000_read_word(state, 403); | ||
1826 | break; | ||
1827 | case 0: | ||
1828 | val = dib8000_read_word(state, 404); | ||
1829 | break; | ||
1830 | } | ||
1831 | if (val & 0x200) | ||
1832 | val -= 1024; | ||
1833 | |||
1834 | return val; | ||
1835 | } | ||
1836 | EXPORT_SYMBOL(dib8090p_get_dc_power); | ||
1837 | |||
1054 | static void dib8000_update_timf(struct dib8000_state *state) | 1838 | static void dib8000_update_timf(struct dib8000_state *state) |
1055 | { | 1839 | { |
1056 | u32 timf = state->timf = dib8000_read32(state, 435); | 1840 | u32 timf = state->timf = dib8000_read32(state, 435); |
@@ -1060,6 +1844,26 @@ static void dib8000_update_timf(struct dib8000_state *state) | |||
1060 | dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); | 1844 | dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); |
1061 | } | 1845 | } |
1062 | 1846 | ||
1847 | u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) | ||
1848 | { | ||
1849 | struct dib8000_state *state = fe->demodulator_priv; | ||
1850 | |||
1851 | switch (op) { | ||
1852 | case DEMOD_TIMF_SET: | ||
1853 | state->timf = timf; | ||
1854 | break; | ||
1855 | case DEMOD_TIMF_UPDATE: | ||
1856 | dib8000_update_timf(state); | ||
1857 | break; | ||
1858 | case DEMOD_TIMF_GET: | ||
1859 | break; | ||
1860 | } | ||
1861 | dib8000_set_bandwidth(state->fe[0], 6000); | ||
1862 | |||
1863 | return state->timf; | ||
1864 | } | ||
1865 | EXPORT_SYMBOL(dib8000_ctrl_timf); | ||
1866 | |||
1063 | static const u16 adc_target_16dB[11] = { | 1867 | static const u16 adc_target_16dB[11] = { |
1064 | (1 << 13) - 825 - 117, | 1868 | (1 << 13) - 825 - 117, |
1065 | (1 << 13) - 837 - 117, | 1869 | (1 << 13) - 837 - 117, |
@@ -1086,6 +1890,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1086 | u16 init_prbs = 0xfff; | 1890 | u16 init_prbs = 0xfff; |
1087 | u16 ana_gain = 0; | 1891 | u16 ana_gain = 0; |
1088 | 1892 | ||
1893 | if (state->revision == 0x8090) | ||
1894 | dib8000_init_sdram(state); | ||
1895 | |||
1089 | if (state->ber_monitored_layer != LAYER_ALL) | 1896 | if (state->ber_monitored_layer != LAYER_ALL) |
1090 | dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); | 1897 | dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); |
1091 | else | 1898 | else |
@@ -1418,7 +2225,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1418 | dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); | 2225 | dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); |
1419 | 2226 | ||
1420 | state->differential_constellation = (seg_diff_mask != 0); | 2227 | state->differential_constellation = (seg_diff_mask != 0); |
1421 | dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); | 2228 | if (state->revision != 0x8090) |
2229 | dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); | ||
2230 | else | ||
2231 | dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff); | ||
1422 | 2232 | ||
1423 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { | 2233 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1424 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) | 2234 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) |
@@ -1870,7 +2680,7 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1870 | { | 2680 | { |
1871 | struct dib8000_state *state = fe->demodulator_priv; | 2681 | struct dib8000_state *state = fe->demodulator_priv; |
1872 | int ret = 0; | 2682 | int ret = 0; |
1873 | u16 value, mode = fft_to_mode(state); | 2683 | u16 lock, value, mode = fft_to_mode(state); |
1874 | 2684 | ||
1875 | // we are already tuned - just resuming from suspend | 2685 | // we are already tuned - just resuming from suspend |
1876 | if (state == NULL) | 2686 | if (state == NULL) |
@@ -1924,7 +2734,11 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1924 | } | 2734 | } |
1925 | 2735 | ||
1926 | // we achieved a coff_cpil_lock - it's time to update the timf | 2736 | // we achieved a coff_cpil_lock - it's time to update the timf |
1927 | if ((dib8000_read_word(state, 568) >> 11) & 0x1) | 2737 | if (state->revision != 0x8090) |
2738 | lock = dib8000_read_word(state, 568); | ||
2739 | else | ||
2740 | lock = dib8000_read_word(state, 570); | ||
2741 | if ((lock >> 11) & 0x1) | ||
1928 | dib8000_update_timf(state); | 2742 | dib8000_update_timf(state); |
1929 | 2743 | ||
1930 | //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start | 2744 | //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start |
@@ -1946,11 +2760,14 @@ static int dib8000_wakeup(struct dvb_frontend *fe) | |||
1946 | u8 index_frontend; | 2760 | u8 index_frontend; |
1947 | int ret; | 2761 | int ret; |
1948 | 2762 | ||
1949 | dib8000_set_power_mode(state, DIB8000M_POWER_ALL); | 2763 | dib8000_set_power_mode(state, DIB8000_POWER_ALL); |
1950 | dib8000_set_adc_state(state, DIBX000_ADC_ON); | 2764 | dib8000_set_adc_state(state, DIBX000_ADC_ON); |
1951 | if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) | 2765 | if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) |
1952 | dprintk("could not start Slow ADC"); | 2766 | dprintk("could not start Slow ADC"); |
1953 | 2767 | ||
2768 | if (state->revision != 0x8090) | ||
2769 | dib8000_sad_calib(state); | ||
2770 | |||
1954 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | 2771 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { |
1955 | ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); | 2772 | ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); |
1956 | if (ret < 0) | 2773 | if (ret < 0) |
@@ -1972,8 +2789,9 @@ static int dib8000_sleep(struct dvb_frontend *fe) | |||
1972 | return ret; | 2789 | return ret; |
1973 | } | 2790 | } |
1974 | 2791 | ||
1975 | dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); | 2792 | if (state->revision != 0x8090) |
1976 | dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); | 2793 | dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); |
2794 | dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); | ||
1977 | return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); | 2795 | return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); |
1978 | } | 2796 | } |
1979 | 2797 | ||
@@ -2028,7 +2846,10 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
2028 | 2846 | ||
2029 | fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; | 2847 | fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; |
2030 | 2848 | ||
2031 | val = dib8000_read_word(state, 570); | 2849 | if (state->revision == 0x8090) |
2850 | val = dib8000_read_word(state, 572); | ||
2851 | else | ||
2852 | val = dib8000_read_word(state, 570); | ||
2032 | fe->dtv_property_cache.inversion = (val & 0x40) >> 6; | 2853 | fe->dtv_property_cache.inversion = (val & 0x40) >> 6; |
2033 | switch ((val & 0x30) >> 4) { | 2854 | switch ((val & 0x30) >> 4) { |
2034 | case 1: | 2855 | case 1: |
@@ -2158,7 +2979,12 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
2158 | state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; | 2979 | state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; |
2159 | memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); | 2980 | memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); |
2160 | 2981 | ||
2161 | dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z); | 2982 | if (state->revision != 0x8090) |
2983 | dib8000_set_output_mode(state->fe[index_frontend], | ||
2984 | OUTMODE_HIGH_Z); | ||
2985 | else | ||
2986 | dib8096p_set_output_mode(state->fe[index_frontend], | ||
2987 | OUTMODE_HIGH_Z); | ||
2162 | if (state->fe[index_frontend]->ops.tuner_ops.set_params) | 2988 | if (state->fe[index_frontend]->ops.tuner_ops.set_params) |
2163 | state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); | 2989 | state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); |
2164 | 2990 | ||
@@ -2215,7 +3041,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
2215 | ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) || | 3041 | ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) || |
2216 | ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && | 3042 | ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && |
2217 | ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { | 3043 | ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { |
2218 | int i = 80000; | 3044 | int i = 100; |
2219 | u8 found = 0; | 3045 | u8 found = 0; |
2220 | u8 tune_failed = 0; | 3046 | u8 tune_failed = 0; |
2221 | 3047 | ||
@@ -2243,6 +3069,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
2243 | default: | 3069 | default: |
2244 | dprintk("unhandled autosearch result"); | 3070 | dprintk("unhandled autosearch result"); |
2245 | case 1: | 3071 | case 1: |
3072 | tune_failed |= (1 << index_frontend); | ||
2246 | dprintk("autosearch failed for the frontend%i", index_frontend); | 3073 | dprintk("autosearch failed for the frontend%i", index_frontend); |
2247 | break; | 3074 | break; |
2248 | } | 3075 | } |
@@ -2268,14 +3095,37 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
2268 | ret = dib8000_tune(state->fe[index_frontend]); | 3095 | ret = dib8000_tune(state->fe[index_frontend]); |
2269 | 3096 | ||
2270 | /* set output mode and diversity input */ | 3097 | /* set output mode and diversity input */ |
2271 | dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); | 3098 | if (state->revision != 0x8090) { |
2272 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | 3099 | dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); |
2273 | dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); | 3100 | for (index_frontend = 1; |
2274 | dib8000_set_diversity_in(state->fe[index_frontend-1], 1); | 3101 | (index_frontend < MAX_NUMBER_OF_FRONTENDS) && |
2275 | } | 3102 | (state->fe[index_frontend] != NULL); |
3103 | index_frontend++) { | ||
3104 | dib8000_set_output_mode(state->fe[index_frontend], | ||
3105 | OUTMODE_DIVERSITY); | ||
3106 | dib8000_set_diversity_in(state->fe[index_frontend-1], 1); | ||
3107 | } | ||
2276 | 3108 | ||
2277 | /* turn off the diversity of the last chip */ | 3109 | /* turn off the diversity of the last chip */ |
2278 | dib8000_set_diversity_in(state->fe[index_frontend-1], 0); | 3110 | dib8000_set_diversity_in(state->fe[index_frontend-1], 0); |
3111 | } else { | ||
3112 | dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode); | ||
3113 | if (state->cfg.enMpegOutput == 0) { | ||
3114 | dib8096p_setDibTxMux(state, MPEG_ON_DIBTX); | ||
3115 | dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); | ||
3116 | } | ||
3117 | for (index_frontend = 1; | ||
3118 | (index_frontend < MAX_NUMBER_OF_FRONTENDS) && | ||
3119 | (state->fe[index_frontend] != NULL); | ||
3120 | index_frontend++) { | ||
3121 | dib8096p_set_output_mode(state->fe[index_frontend], | ||
3122 | OUTMODE_DIVERSITY); | ||
3123 | dib8096p_set_diversity_in(state->fe[index_frontend-1], 1); | ||
3124 | } | ||
3125 | |||
3126 | /* turn off the diversity of the last chip */ | ||
3127 | dib8096p_set_diversity_in(state->fe[index_frontend-1], 0); | ||
3128 | } | ||
2279 | 3129 | ||
2280 | return ret; | 3130 | return ret; |
2281 | } | 3131 | } |
@@ -2284,15 +3134,22 @@ static u16 dib8000_read_lock(struct dvb_frontend *fe) | |||
2284 | { | 3134 | { |
2285 | struct dib8000_state *state = fe->demodulator_priv; | 3135 | struct dib8000_state *state = fe->demodulator_priv; |
2286 | 3136 | ||
3137 | if (state->revision == 0x8090) | ||
3138 | return dib8000_read_word(state, 570); | ||
2287 | return dib8000_read_word(state, 568); | 3139 | return dib8000_read_word(state, 568); |
2288 | } | 3140 | } |
2289 | 3141 | ||
2290 | static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | 3142 | static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) |
2291 | { | 3143 | { |
2292 | struct dib8000_state *state = fe->demodulator_priv; | 3144 | struct dib8000_state *state = fe->demodulator_priv; |
2293 | u16 lock_slave = 0, lock = dib8000_read_word(state, 568); | 3145 | u16 lock_slave = 0, lock; |
2294 | u8 index_frontend; | 3146 | u8 index_frontend; |
2295 | 3147 | ||
3148 | if (state->revision == 0x8090) | ||
3149 | lock = dib8000_read_word(state, 570); | ||
3150 | else | ||
3151 | lock = dib8000_read_word(state, 568); | ||
3152 | |||
2296 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) | 3153 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) |
2297 | lock_slave |= dib8000_read_lock(state->fe[index_frontend]); | 3154 | lock_slave |= dib8000_read_lock(state->fe[index_frontend]); |
2298 | 3155 | ||
@@ -2330,14 +3187,26 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
2330 | static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber) | 3187 | static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber) |
2331 | { | 3188 | { |
2332 | struct dib8000_state *state = fe->demodulator_priv; | 3189 | struct dib8000_state *state = fe->demodulator_priv; |
2333 | *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments | 3190 | |
3191 | /* 13 segments */ | ||
3192 | if (state->revision == 0x8090) | ||
3193 | *ber = (dib8000_read_word(state, 562) << 16) | | ||
3194 | dib8000_read_word(state, 563); | ||
3195 | else | ||
3196 | *ber = (dib8000_read_word(state, 560) << 16) | | ||
3197 | dib8000_read_word(state, 561); | ||
2334 | return 0; | 3198 | return 0; |
2335 | } | 3199 | } |
2336 | 3200 | ||
2337 | static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | 3201 | static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) |
2338 | { | 3202 | { |
2339 | struct dib8000_state *state = fe->demodulator_priv; | 3203 | struct dib8000_state *state = fe->demodulator_priv; |
2340 | *unc = dib8000_read_word(state, 565); // packet error on 13 seg | 3204 | |
3205 | /* packet error on 13 seg */ | ||
3206 | if (state->revision == 0x8090) | ||
3207 | *unc = dib8000_read_word(state, 567); | ||
3208 | else | ||
3209 | *unc = dib8000_read_word(state, 565); | ||
2341 | return 0; | 3210 | return 0; |
2342 | } | 3211 | } |
2343 | 3212 | ||
@@ -2370,14 +3239,20 @@ static u32 dib8000_get_snr(struct dvb_frontend *fe) | |||
2370 | u32 n, s, exp; | 3239 | u32 n, s, exp; |
2371 | u16 val; | 3240 | u16 val; |
2372 | 3241 | ||
2373 | val = dib8000_read_word(state, 542); | 3242 | if (state->revision != 0x8090) |
3243 | val = dib8000_read_word(state, 542); | ||
3244 | else | ||
3245 | val = dib8000_read_word(state, 544); | ||
2374 | n = (val >> 6) & 0xff; | 3246 | n = (val >> 6) & 0xff; |
2375 | exp = (val & 0x3f); | 3247 | exp = (val & 0x3f); |
2376 | if ((exp & 0x20) != 0) | 3248 | if ((exp & 0x20) != 0) |
2377 | exp -= 0x40; | 3249 | exp -= 0x40; |
2378 | n <<= exp+16; | 3250 | n <<= exp+16; |
2379 | 3251 | ||
2380 | val = dib8000_read_word(state, 543); | 3252 | if (state->revision != 0x8090) |
3253 | val = dib8000_read_word(state, 543); | ||
3254 | else | ||
3255 | val = dib8000_read_word(state, 545); | ||
2381 | s = (val >> 6) & 0xff; | 3256 | s = (val >> 6) & 0xff; |
2382 | exp = (val & 0x3f); | 3257 | exp = (val & 0x3f); |
2383 | if ((exp & 0x20) != 0) | 3258 | if ((exp & 0x20) != 0) |
@@ -2401,7 +3276,7 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) | |||
2401 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) | 3276 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) |
2402 | snr_master += dib8000_get_snr(state->fe[index_frontend]); | 3277 | snr_master += dib8000_get_snr(state->fe[index_frontend]); |
2403 | 3278 | ||
2404 | if (snr_master != 0) { | 3279 | if ((snr_master >> 16) != 0) { |
2405 | snr_master = 10*intlog10(snr_master>>16); | 3280 | snr_master = 10*intlog10(snr_master>>16); |
2406 | *snr = snr_master / ((1 << 24) / 10); | 3281 | *snr = snr_master / ((1 << 24) / 10); |
2407 | } | 3282 | } |
@@ -2458,7 +3333,8 @@ struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int sla | |||
2458 | EXPORT_SYMBOL(dib8000_get_slave_frontend); | 3333 | EXPORT_SYMBOL(dib8000_get_slave_frontend); |
2459 | 3334 | ||
2460 | 3335 | ||
2461 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) | 3336 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, |
3337 | u8 default_addr, u8 first_addr, u8 is_dib8096p) | ||
2462 | { | 3338 | { |
2463 | int k = 0, ret = 0; | 3339 | int k = 0, ret = 0; |
2464 | u8 new_addr = 0; | 3340 | u8 new_addr = 0; |
@@ -2488,9 +3364,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau | |||
2488 | new_addr = first_addr + (k << 1); | 3364 | new_addr = first_addr + (k << 1); |
2489 | 3365 | ||
2490 | client.addr = new_addr; | 3366 | client.addr = new_addr; |
2491 | dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ | 3367 | if (!is_dib8096p) |
2492 | if (dib8000_identify(&client) == 0) { | ||
2493 | dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ | 3368 | dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ |
3369 | if (dib8000_identify(&client) == 0) { | ||
3370 | /* sram lead in, rdy */ | ||
3371 | if (!is_dib8096p) | ||
3372 | dib8000_i2c_write16(&client, 1287, 0x0003); | ||
2494 | client.addr = default_addr; | 3373 | client.addr = default_addr; |
2495 | if (dib8000_identify(&client) == 0) { | 3374 | if (dib8000_identify(&client) == 0) { |
2496 | dprintk("#%d: not identified", k); | 3375 | dprintk("#%d: not identified", k); |
@@ -2549,6 +3428,7 @@ static void dib8000_release(struct dvb_frontend *fe) | |||
2549 | dvb_frontend_detach(st->fe[index_frontend]); | 3428 | dvb_frontend_detach(st->fe[index_frontend]); |
2550 | 3429 | ||
2551 | dibx000_exit_i2c_master(&st->i2c_master); | 3430 | dibx000_exit_i2c_master(&st->i2c_master); |
3431 | i2c_del_adapter(&st->dib8096p_tuner_adap); | ||
2552 | kfree(st->fe[0]); | 3432 | kfree(st->fe[0]); |
2553 | kfree(st); | 3433 | kfree(st); |
2554 | } | 3434 | } |
@@ -2651,6 +3531,15 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s | |||
2651 | 3531 | ||
2652 | dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); | 3532 | dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); |
2653 | 3533 | ||
3534 | /* init 8096p tuner adapter */ | ||
3535 | strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface", | ||
3536 | sizeof(state->dib8096p_tuner_adap.name)); | ||
3537 | state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo; | ||
3538 | state->dib8096p_tuner_adap.algo_data = NULL; | ||
3539 | state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent; | ||
3540 | i2c_set_adapdata(&state->dib8096p_tuner_adap, state); | ||
3541 | i2c_add_adapter(&state->dib8096p_tuner_adap); | ||
3542 | |||
2654 | dib8000_reset(fe); | 3543 | dib8000_reset(fe); |
2655 | 3544 | ||
2656 | dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */ | 3545 | dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */ |
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index 617f9eba3a09..39591bb172c1 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h | |||
@@ -32,6 +32,7 @@ struct dib8000_config { | |||
32 | u8 div_cfg; | 32 | u8 div_cfg; |
33 | u8 output_mode; | 33 | u8 output_mode; |
34 | u8 refclksel; | 34 | u8 refclksel; |
35 | u8 enMpegOutput:1; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | #define DEFAULT_DIB8000_I2C_ADDRESS 18 | 38 | #define DEFAULT_DIB8000_I2C_ADDRESS 18 |
@@ -40,7 +41,8 @@ struct dib8000_config { | |||
40 | extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); | 41 | extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); |
41 | extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); | 42 | extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); |
42 | 43 | ||
43 | extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr); | 44 | extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, |
45 | u8 default_addr, u8 first_addr, u8 is_dib8096p); | ||
44 | 46 | ||
45 | extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); | 47 | extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); |
46 | extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); | 48 | extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); |
@@ -50,6 +52,13 @@ extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_st | |||
50 | extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); | 52 | extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); |
51 | extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); | 53 | extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); |
52 | extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); | 54 | extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); |
55 | extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe); | ||
56 | extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff); | ||
57 | extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ); | ||
58 | extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe, | ||
59 | uint8_t op, uint32_t timf); | ||
60 | extern int dib8000_update_pll(struct dvb_frontend *fe, | ||
61 | struct dibx000_bandwidth_config *pll); | ||
53 | extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); | 62 | extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); |
54 | extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); | 63 | extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); |
55 | extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); | 64 | extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); |
@@ -66,7 +75,9 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe | |||
66 | return NULL; | 75 | return NULL; |
67 | } | 76 | } |
68 | 77 | ||
69 | static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) | 78 | static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, |
79 | int no_of_demods, u8 default_addr, u8 first_addr, | ||
80 | u8 is_dib8096p) | ||
70 | { | 81 | { |
71 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 82 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
72 | return -ENODEV; | 83 | return -ENODEV; |
@@ -109,11 +120,38 @@ static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) | |||
109 | { | 120 | { |
110 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 121 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
111 | } | 122 | } |
123 | static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) | ||
124 | { | ||
125 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
126 | return NULL; | ||
127 | } | ||
128 | static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) | ||
129 | { | ||
130 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
131 | return 0; | ||
132 | } | ||
112 | static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) | 133 | static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) |
113 | { | 134 | { |
114 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 135 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
115 | return 0; | 136 | return 0; |
116 | } | 137 | } |
138 | static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) | ||
139 | { | ||
140 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
141 | return 0; | ||
142 | } | ||
143 | static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe, | ||
144 | uint8_t op, uint32_t timf) | ||
145 | { | ||
146 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
147 | return 0; | ||
148 | } | ||
149 | static inline int dib8000_update_pll(struct dvb_frontend *fe, | ||
150 | struct dibx000_bandwidth_config *pll) | ||
151 | { | ||
152 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
153 | return -ENODEV; | ||
154 | } | ||
117 | static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) | 155 | static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) |
118 | { | 156 | { |
119 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 157 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 5e011474be43..02e6431e7355 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h | |||
@@ -276,4 +276,11 @@ struct dibSubbandSelection { | |||
276 | #define DEMOD_TIMF_GET 0x01 | 276 | #define DEMOD_TIMF_GET 0x01 |
277 | #define DEMOD_TIMF_UPDATE 0x02 | 277 | #define DEMOD_TIMF_UPDATE 0x02 |
278 | 278 | ||
279 | #define MPEG_ON_DIBTX 1 | ||
280 | #define DIV_ON_DIBTX 2 | ||
281 | #define ADC_ON_DIBTX 3 | ||
282 | #define DEMOUT_ON_HOSTBUS 4 | ||
283 | #define DIBTX_ON_HOSTBUS 5 | ||
284 | #define MPEG_ON_HOSTBUS 6 | ||
285 | |||
279 | #endif | 286 | #endif |
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c index 88e46f4cdbb2..beb67759f824 100644 --- a/drivers/media/dvb/frontends/drxd_hard.c +++ b/drivers/media/dvb/frontends/drxd_hard.c | |||
@@ -914,14 +914,13 @@ static int load_firmware(struct drxd_state *state, const char *fw_name) | |||
914 | return -EIO; | 914 | return -EIO; |
915 | } | 915 | } |
916 | 916 | ||
917 | state->microcode = kmalloc(fw->size, GFP_KERNEL); | 917 | state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL); |
918 | if (state->microcode == NULL) { | 918 | if (state->microcode == NULL) { |
919 | release_firmware(fw); | 919 | release_firmware(fw); |
920 | printk(KERN_ERR "drxd: firmware load failure: no memory\n"); | 920 | printk(KERN_ERR "drxd: firmware load failure: no memory\n"); |
921 | return -ENOMEM; | 921 | return -ENOMEM; |
922 | } | 922 | } |
923 | 923 | ||
924 | memcpy(state->microcode, fw->data, fw->size); | ||
925 | state->microcode_length = fw->size; | 924 | state->microcode_length = fw->size; |
926 | release_firmware(fw); | 925 | release_firmware(fw); |
927 | return 0; | 926 | return 0; |
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 58baf419560c..e6d42e271b89 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h | |||
@@ -26,6 +26,8 @@ struct drxk_config { | |||
26 | bool antenna_dvbt; | 26 | bool antenna_dvbt; |
27 | u16 antenna_gpio; | 27 | u16 antenna_gpio; |
28 | 28 | ||
29 | int chunk_size; | ||
30 | |||
29 | const char *microcode_name; | 31 | const char *microcode_name; |
30 | }; | 32 | }; |
31 | 33 | ||
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index f6431ef827dc..d795898c0668 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c | |||
@@ -681,7 +681,8 @@ static int init_state(struct drxk_state *state) | |||
681 | state->m_hasOOB = false; | 681 | state->m_hasOOB = false; |
682 | state->m_hasAudio = false; | 682 | state->m_hasAudio = false; |
683 | 683 | ||
684 | state->m_ChunkSize = 124; | 684 | if (!state->m_ChunkSize) |
685 | state->m_ChunkSize = 124; | ||
685 | 686 | ||
686 | state->m_oscClockFreq = 0; | 687 | state->m_oscClockFreq = 0; |
687 | state->m_smartAntInverted = false; | 688 | state->m_smartAntInverted = false; |
@@ -1846,6 +1847,7 @@ static int SetOperationMode(struct drxk_state *state, | |||
1846 | */ | 1847 | */ |
1847 | switch (oMode) { | 1848 | switch (oMode) { |
1848 | case OM_DVBT: | 1849 | case OM_DVBT: |
1850 | dprintk(1, ": DVB-T\n"); | ||
1849 | state->m_OperationMode = oMode; | 1851 | state->m_OperationMode = oMode; |
1850 | status = SetDVBTStandard(state, oMode); | 1852 | status = SetDVBTStandard(state, oMode); |
1851 | if (status < 0) | 1853 | if (status < 0) |
@@ -1853,6 +1855,8 @@ static int SetOperationMode(struct drxk_state *state, | |||
1853 | break; | 1855 | break; |
1854 | case OM_QAM_ITU_A: /* fallthrough */ | 1856 | case OM_QAM_ITU_A: /* fallthrough */ |
1855 | case OM_QAM_ITU_C: | 1857 | case OM_QAM_ITU_C: |
1858 | dprintk(1, ": DVB-C Annex %c\n", | ||
1859 | (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C'); | ||
1856 | state->m_OperationMode = oMode; | 1860 | state->m_OperationMode = oMode; |
1857 | status = SetQAMStandard(state, oMode); | 1861 | status = SetQAMStandard(state, oMode); |
1858 | if (status < 0) | 1862 | if (status < 0) |
@@ -6182,7 +6186,10 @@ static int drxk_c_init(struct dvb_frontend *fe) | |||
6182 | dprintk(1, "\n"); | 6186 | dprintk(1, "\n"); |
6183 | if (mutex_trylock(&state->ctlock) == 0) | 6187 | if (mutex_trylock(&state->ctlock) == 0) |
6184 | return -EBUSY; | 6188 | return -EBUSY; |
6185 | SetOperationMode(state, OM_QAM_ITU_A); | 6189 | if (state->m_itut_annex_c) |
6190 | SetOperationMode(state, OM_QAM_ITU_C); | ||
6191 | else | ||
6192 | SetOperationMode(state, OM_QAM_ITU_A); | ||
6186 | return 0; | 6193 | return 0; |
6187 | } | 6194 | } |
6188 | 6195 | ||
@@ -6208,6 +6215,7 @@ static int drxk_set_parameters(struct dvb_frontend *fe, | |||
6208 | struct dvb_frontend_parameters *p) | 6215 | struct dvb_frontend_parameters *p) |
6209 | { | 6216 | { |
6210 | struct drxk_state *state = fe->demodulator_priv; | 6217 | struct drxk_state *state = fe->demodulator_priv; |
6218 | u32 delsys = fe->dtv_property_cache.delivery_system; | ||
6211 | u32 IF; | 6219 | u32 IF; |
6212 | 6220 | ||
6213 | dprintk(1, "\n"); | 6221 | dprintk(1, "\n"); |
@@ -6218,6 +6226,16 @@ static int drxk_set_parameters(struct dvb_frontend *fe, | |||
6218 | return -EINVAL; | 6226 | return -EINVAL; |
6219 | } | 6227 | } |
6220 | 6228 | ||
6229 | switch (delsys) { | ||
6230 | case SYS_DVBC_ANNEX_A: | ||
6231 | state->m_itut_annex_c = false; | ||
6232 | break; | ||
6233 | case SYS_DVBC_ANNEX_C: | ||
6234 | state->m_itut_annex_c = true; | ||
6235 | break; | ||
6236 | default: | ||
6237 | return -EINVAL; | ||
6238 | } | ||
6221 | 6239 | ||
6222 | if (fe->ops.i2c_gate_ctrl) | 6240 | if (fe->ops.i2c_gate_ctrl) |
6223 | fe->ops.i2c_gate_ctrl(fe, 1); | 6241 | fe->ops.i2c_gate_ctrl(fe, 1); |
@@ -6346,6 +6364,32 @@ static int drxk_t_get_frontend(struct dvb_frontend *fe, | |||
6346 | return 0; | 6364 | return 0; |
6347 | } | 6365 | } |
6348 | 6366 | ||
6367 | static int drxk_c_get_property(struct dvb_frontend *fe, struct dtv_property *p) | ||
6368 | { | ||
6369 | switch (p->cmd) { | ||
6370 | case DTV_ENUM_DELSYS: | ||
6371 | p->u.buffer.data[0] = SYS_DVBC_ANNEX_A; | ||
6372 | p->u.buffer.data[1] = SYS_DVBC_ANNEX_C; | ||
6373 | p->u.buffer.len = 2; | ||
6374 | break; | ||
6375 | default: | ||
6376 | break; | ||
6377 | } | ||
6378 | return 0; | ||
6379 | } | ||
6380 | static int drxk_t_get_property(struct dvb_frontend *fe, struct dtv_property *p) | ||
6381 | { | ||
6382 | switch (p->cmd) { | ||
6383 | case DTV_ENUM_DELSYS: | ||
6384 | p->u.buffer.data[0] = SYS_DVBT; | ||
6385 | p->u.buffer.len = 1; | ||
6386 | break; | ||
6387 | default: | ||
6388 | break; | ||
6389 | } | ||
6390 | return 0; | ||
6391 | } | ||
6392 | |||
6349 | static struct dvb_frontend_ops drxk_c_ops = { | 6393 | static struct dvb_frontend_ops drxk_c_ops = { |
6350 | .info = { | 6394 | .info = { |
6351 | .name = "DRXK DVB-C", | 6395 | .name = "DRXK DVB-C", |
@@ -6364,6 +6408,7 @@ static struct dvb_frontend_ops drxk_c_ops = { | |||
6364 | 6408 | ||
6365 | .set_frontend = drxk_set_parameters, | 6409 | .set_frontend = drxk_set_parameters, |
6366 | .get_frontend = drxk_c_get_frontend, | 6410 | .get_frontend = drxk_c_get_frontend, |
6411 | .get_property = drxk_c_get_property, | ||
6367 | .get_tune_settings = drxk_c_get_tune_settings, | 6412 | .get_tune_settings = drxk_c_get_tune_settings, |
6368 | 6413 | ||
6369 | .read_status = drxk_read_status, | 6414 | .read_status = drxk_read_status, |
@@ -6396,6 +6441,7 @@ static struct dvb_frontend_ops drxk_t_ops = { | |||
6396 | 6441 | ||
6397 | .set_frontend = drxk_set_parameters, | 6442 | .set_frontend = drxk_set_parameters, |
6398 | .get_frontend = drxk_t_get_frontend, | 6443 | .get_frontend = drxk_t_get_frontend, |
6444 | .get_property = drxk_t_get_property, | ||
6399 | 6445 | ||
6400 | .read_status = drxk_read_status, | 6446 | .read_status = drxk_read_status, |
6401 | .read_ber = drxk_read_ber, | 6447 | .read_ber = drxk_read_ber, |
@@ -6423,6 +6469,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, | |||
6423 | state->no_i2c_bridge = config->no_i2c_bridge; | 6469 | state->no_i2c_bridge = config->no_i2c_bridge; |
6424 | state->antenna_gpio = config->antenna_gpio; | 6470 | state->antenna_gpio = config->antenna_gpio; |
6425 | state->antenna_dvbt = config->antenna_dvbt; | 6471 | state->antenna_dvbt = config->antenna_dvbt; |
6472 | state->m_ChunkSize = config->chunk_size; | ||
6426 | 6473 | ||
6427 | /* NOTE: as more UIO bits will be used, add them to the mask */ | 6474 | /* NOTE: as more UIO bits will be used, add them to the mask */ |
6428 | state->UIO_mask = config->antenna_gpio; | 6475 | state->UIO_mask = config->antenna_gpio; |
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h index a05c32eecdcc..85a423f91960 100644 --- a/drivers/media/dvb/frontends/drxk_hard.h +++ b/drivers/media/dvb/frontends/drxk_hard.h | |||
@@ -263,6 +263,8 @@ struct drxk_state { | |||
263 | u8 m_TSDataStrength; | 263 | u8 m_TSDataStrength; |
264 | u8 m_TSClockkStrength; | 264 | u8 m_TSClockkStrength; |
265 | 265 | ||
266 | bool m_itut_annex_c; /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */ | ||
267 | |||
266 | enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */ | 268 | enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */ |
267 | u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case | 269 | u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case |
268 | static clockrate is selected */ | 270 | static clockrate is selected */ |
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h index 1c6fb4b66255..ad2b644db1da 100644 --- a/drivers/media/dvb/frontends/it913x-fe-priv.h +++ b/drivers/media/dvb/frontends/it913x-fe-priv.h | |||
@@ -153,8 +153,7 @@ struct table { | |||
153 | }; | 153 | }; |
154 | 154 | ||
155 | static struct table fe_clockTable[] = { | 155 | static struct table fe_clockTable[] = { |
156 | {12000000, tab3}, /* FPGA */ | 156 | {12000000, tab3}, /* 12.00MHz */ |
157 | {16384000, tab6}, /* 16.38MHz */ | ||
158 | {20480000, tab6}, /* 20.48MHz */ | 157 | {20480000, tab6}, /* 20.48MHz */ |
159 | {36000000, tab3}, /* 36.00MHz */ | 158 | {36000000, tab3}, /* 36.00MHz */ |
160 | {30000000, tab1}, /* 30.00MHz */ | 159 | {30000000, tab1}, /* 30.00MHz */ |
@@ -164,7 +163,6 @@ static struct table fe_clockTable[] = { | |||
164 | {34000000, tab2}, /* 34.00MHz */ | 163 | {34000000, tab2}, /* 34.00MHz */ |
165 | {24000000, tab1}, /* 24.00MHz */ | 164 | {24000000, tab1}, /* 24.00MHz */ |
166 | {22000000, tab8}, /* 22.00MHz */ | 165 | {22000000, tab8}, /* 22.00MHz */ |
167 | {12000000, tab3} /* 12.00MHz */ | ||
168 | }; | 166 | }; |
169 | 167 | ||
170 | /* fe get */ | 168 | /* fe get */ |
@@ -205,6 +203,10 @@ fe_modulation_t fe_con[] = { | |||
205 | 203 | ||
206 | /* Standard demodulator functions */ | 204 | /* Standard demodulator functions */ |
207 | static struct it913xset set_solo_fe[] = { | 205 | static struct it913xset set_solo_fe[] = { |
206 | {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, | ||
207 | {PRO_LINK, GPIOH5_ON, {0x01}, 0x01}, | ||
208 | {PRO_LINK, GPIOH5_O, {0x00}, 0x01}, | ||
209 | {PRO_LINK, GPIOH5_O, {0x01}, 0x01}, | ||
208 | {PRO_LINK, DVBT_INTEN, {0x04}, 0x01}, | 210 | {PRO_LINK, DVBT_INTEN, {0x04}, 0x01}, |
209 | {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01}, | 211 | {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01}, |
210 | {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01}, | 212 | {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01}, |
@@ -228,13 +230,127 @@ static struct it913xset init_1[] = { | |||
228 | {PRO_LINK, LOCK3_OUT, {0x01}, 0x01}, | 230 | {PRO_LINK, LOCK3_OUT, {0x01}, 0x01}, |
229 | {PRO_LINK, PADMISCDRSR, {0x01}, 0x01}, | 231 | {PRO_LINK, PADMISCDRSR, {0x01}, 0x01}, |
230 | {PRO_LINK, PADMISCDR2, {0x00}, 0x01}, | 232 | {PRO_LINK, PADMISCDR2, {0x00}, 0x01}, |
233 | {PRO_DMOD, 0xec57, {0x00, 0x00}, 0x02}, | ||
231 | {PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */ | 234 | {PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */ |
232 | {PRO_LINK, PADMISCDR8, {0x00}, 0x01}, | 235 | {PRO_LINK, PADMISCDR8, {0x00}, 0x01}, |
233 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | 236 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ |
234 | }; | 237 | }; |
235 | 238 | ||
236 | /* ---------IT9137 0x38 tuner init---------- */ | 239 | |
237 | static struct it913xset it9137_set[] = { | 240 | /* Version 1 types */ |
241 | static struct it913xset it9135_v1[] = { | ||
242 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
243 | {PRO_DMOD, 0x0070, {0x0a}, 0x01}, | ||
244 | {PRO_DMOD, 0x007e, {0x04}, 0x01}, | ||
245 | {PRO_DMOD, 0x0081, {0x0a}, 0x01}, | ||
246 | {PRO_DMOD, 0x008a, {0x01}, 0x01}, | ||
247 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
248 | {PRO_DMOD, 0x0092, {0x06}, 0x01}, | ||
249 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
250 | {PRO_DMOD, 0x009f, {0xe1}, 0x01}, | ||
251 | {PRO_DMOD, 0x00a0, {0xcf}, 0x01}, | ||
252 | {PRO_DMOD, 0x00a3, {0x01}, 0x01}, | ||
253 | {PRO_DMOD, 0x00a5, {0x01}, 0x01}, | ||
254 | {PRO_DMOD, 0x00a6, {0x01}, 0x01}, | ||
255 | {PRO_DMOD, 0x00a9, {0x00}, 0x01}, | ||
256 | {PRO_DMOD, 0x00aa, {0x01}, 0x01}, | ||
257 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
258 | {PRO_DMOD, 0x00c2, {0x05}, 0x01}, | ||
259 | {PRO_DMOD, 0x00c6, {0x19}, 0x01}, | ||
260 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
261 | {PRO_DMOD, 0xf016, {0x10}, 0x01}, | ||
262 | {PRO_DMOD, 0xf017, {0x04}, 0x01}, | ||
263 | {PRO_DMOD, 0xf018, {0x05}, 0x01}, | ||
264 | {PRO_DMOD, 0xf019, {0x04}, 0x01}, | ||
265 | {PRO_DMOD, 0xf01a, {0x05}, 0x01}, | ||
266 | {PRO_DMOD, 0xf021, {0x03}, 0x01}, | ||
267 | {PRO_DMOD, 0xf022, {0x0a}, 0x01}, | ||
268 | {PRO_DMOD, 0xf023, {0x0a}, 0x01}, | ||
269 | {PRO_DMOD, 0xf02b, {0x00}, 0x01}, | ||
270 | {PRO_DMOD, 0xf02c, {0x01}, 0x01}, | ||
271 | {PRO_DMOD, 0xf064, {0x03}, 0x01}, | ||
272 | {PRO_DMOD, 0xf065, {0xf9}, 0x01}, | ||
273 | {PRO_DMOD, 0xf066, {0x03}, 0x01}, | ||
274 | {PRO_DMOD, 0xf067, {0x01}, 0x01}, | ||
275 | {PRO_DMOD, 0xf06f, {0xe0}, 0x01}, | ||
276 | {PRO_DMOD, 0xf070, {0x03}, 0x01}, | ||
277 | {PRO_DMOD, 0xf072, {0x0f}, 0x01}, | ||
278 | {PRO_DMOD, 0xf073, {0x03}, 0x01}, | ||
279 | {PRO_DMOD, 0xf078, {0x00}, 0x01}, | ||
280 | {PRO_DMOD, 0xf087, {0x00}, 0x01}, | ||
281 | {PRO_DMOD, 0xf09b, {0x3f}, 0x01}, | ||
282 | {PRO_DMOD, 0xf09c, {0x00}, 0x01}, | ||
283 | {PRO_DMOD, 0xf09d, {0x20}, 0x01}, | ||
284 | {PRO_DMOD, 0xf09e, {0x00}, 0x01}, | ||
285 | {PRO_DMOD, 0xf09f, {0x0c}, 0x01}, | ||
286 | {PRO_DMOD, 0xf0a0, {0x00}, 0x01}, | ||
287 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
288 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
289 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
290 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
291 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
292 | {PRO_DMOD, 0xf14c, {0x00}, 0x01}, | ||
293 | {PRO_DMOD, 0xf14d, {0x00}, 0x01}, | ||
294 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
295 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
296 | {PRO_DMOD, 0xf15a, {0x00}, 0x01}, | ||
297 | {PRO_DMOD, 0xf15b, {0x08}, 0x01}, | ||
298 | {PRO_DMOD, 0xf15d, {0x03}, 0x01}, | ||
299 | {PRO_DMOD, 0xf15e, {0x05}, 0x01}, | ||
300 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
301 | {PRO_DMOD, 0xf166, {0x01}, 0x01}, | ||
302 | {PRO_DMOD, 0xf167, {0x40}, 0x01}, | ||
303 | {PRO_DMOD, 0xf168, {0x0f}, 0x01}, | ||
304 | {PRO_DMOD, 0xf17a, {0x00}, 0x01}, | ||
305 | {PRO_DMOD, 0xf17b, {0x00}, 0x01}, | ||
306 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
307 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
308 | {PRO_DMOD, 0xf1bc, {0x36}, 0x01}, | ||
309 | {PRO_DMOD, 0xf1bd, {0x00}, 0x01}, | ||
310 | {PRO_DMOD, 0xf1cb, {0xa0}, 0x01}, | ||
311 | {PRO_DMOD, 0xf1cc, {0x01}, 0x01}, | ||
312 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
313 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
314 | {PRO_DMOD, 0xf40e, {0x0a}, 0x01}, | ||
315 | {PRO_DMOD, 0xf40f, {0x40}, 0x01}, | ||
316 | {PRO_DMOD, 0xf410, {0x08}, 0x01}, | ||
317 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
318 | {PRO_DMOD, 0xf561, {0x15}, 0x01}, | ||
319 | {PRO_DMOD, 0xf562, {0x20}, 0x01}, | ||
320 | {PRO_DMOD, 0xf5df, {0xfb}, 0x01}, | ||
321 | {PRO_DMOD, 0xf5e0, {0x00}, 0x01}, | ||
322 | {PRO_DMOD, 0xf5e3, {0x09}, 0x01}, | ||
323 | {PRO_DMOD, 0xf5e4, {0x01}, 0x01}, | ||
324 | {PRO_DMOD, 0xf5e5, {0x01}, 0x01}, | ||
325 | {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, | ||
326 | {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, | ||
327 | {PRO_DMOD, 0xf600, {0x05}, 0x01}, | ||
328 | {PRO_DMOD, 0xf601, {0x08}, 0x01}, | ||
329 | {PRO_DMOD, 0xf602, {0x0b}, 0x01}, | ||
330 | {PRO_DMOD, 0xf603, {0x0e}, 0x01}, | ||
331 | {PRO_DMOD, 0xf604, {0x11}, 0x01}, | ||
332 | {PRO_DMOD, 0xf605, {0x14}, 0x01}, | ||
333 | {PRO_DMOD, 0xf606, {0x17}, 0x01}, | ||
334 | {PRO_DMOD, 0xf607, {0x1f}, 0x01}, | ||
335 | {PRO_DMOD, 0xf60e, {0x00}, 0x01}, | ||
336 | {PRO_DMOD, 0xf60f, {0x04}, 0x01}, | ||
337 | {PRO_DMOD, 0xf610, {0x32}, 0x01}, | ||
338 | {PRO_DMOD, 0xf611, {0x10}, 0x01}, | ||
339 | {PRO_DMOD, 0xf707, {0xfc}, 0x01}, | ||
340 | {PRO_DMOD, 0xf708, {0x00}, 0x01}, | ||
341 | {PRO_DMOD, 0xf709, {0x37}, 0x01}, | ||
342 | {PRO_DMOD, 0xf70a, {0x00}, 0x01}, | ||
343 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
344 | {PRO_DMOD, 0xf80f, {0x40}, 0x01}, | ||
345 | {PRO_DMOD, 0xf810, {0x54}, 0x01}, | ||
346 | {PRO_DMOD, 0xf811, {0x5a}, 0x01}, | ||
347 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
348 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
349 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
350 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
351 | }; | ||
352 | |||
353 | static struct it913xset it9135_38[] = { | ||
238 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, | 354 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, |
239 | {PRO_DMOD, 0x0046, {0x38}, 0x01}, | 355 | {PRO_DMOD, 0x0046, {0x38}, 0x01}, |
240 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | 356 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, |
@@ -244,7 +360,7 @@ static struct it913xset it9137_set[] = { | |||
244 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, | 360 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, |
245 | {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, | 361 | {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, |
246 | {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8, | 362 | {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8, |
247 | 0xd0, 0xc3, 0x01 }, 0x0a}, | 363 | 0xd0, 0xc3, 0x01}, 0x0a}, |
248 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | 364 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, |
249 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, | 365 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, |
250 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | 366 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, |
@@ -262,15 +378,25 @@ static struct it913xset it9137_set[] = { | |||
262 | {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, | 378 | {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, |
263 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, | 379 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, |
264 | {PRO_DMOD, 0x00fc, { 0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77, | 380 | {PRO_DMOD, 0x00fc, { 0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77, |
265 | 0x00, 0x02, 0xc8, 0x05, 0x7b }, 0x0c}, | 381 | 0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c}, |
266 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, | 382 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, |
267 | {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, | 383 | {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, |
268 | {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0xbc, 0xa0}, 0x04}, | 384 | {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04}, |
269 | {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03}, | 385 | {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03}, |
270 | {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, | 386 | {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, |
271 | {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, | 387 | {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, |
272 | {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, | 388 | {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, |
273 | {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8}, 0x04}, | 389 | {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05}, |
390 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
391 | {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, | ||
392 | {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, | ||
393 | {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, | ||
394 | {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, | ||
395 | {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, | ||
396 | {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, | ||
397 | {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, | ||
398 | {PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03}, | ||
399 | {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, | ||
274 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | 400 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, |
275 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | 401 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, |
276 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | 402 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, |
@@ -301,7 +427,7 @@ static struct it913xset it9137_set[] = { | |||
301 | {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, | 427 | {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, |
302 | {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, | 428 | {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, |
303 | {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, | 429 | {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, |
304 | 0x1f }, 0x08}, | 430 | 0x1f}, 0x08}, |
305 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, | 431 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, |
306 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, | 432 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, |
307 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | 433 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, |
@@ -309,21 +435,605 @@ static struct it913xset it9137_set[] = { | |||
309 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | 435 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, |
310 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | 436 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, |
311 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | 437 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, |
312 | {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, | 438 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ |
313 | {PRO_LINK, GPIOH5_ON, {0x01}, 0x01}, | 439 | }; |
314 | {PRO_LINK, GPIOH5_O, {0x00}, 0x01}, | 440 | |
315 | {PRO_LINK, GPIOH5_O, {0x01}, 0x01}, | 441 | static struct it913xset it9135_51[] = { |
316 | {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ | 442 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, |
443 | {PRO_DMOD, 0x0046, {0x51}, 0x01}, | ||
444 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
445 | {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, | ||
446 | {PRO_DMOD, 0x0068, {0x0a}, 0x01}, | ||
447 | {PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03}, | ||
448 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, | ||
449 | {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, | ||
450 | {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96, | ||
451 | 0xcf, 0xc3, 0x01}, 0x0a}, | ||
452 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
453 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, | ||
454 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
455 | {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, | ||
456 | {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, | ||
457 | {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, | ||
458 | {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, | ||
459 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
460 | {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02}, | ||
461 | {PRO_DMOD, 0x00b6, {0x14}, 0x01}, | ||
462 | {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03}, | ||
463 | {PRO_DMOD, 0x00c4, {0x00}, 0x01}, | ||
464 | {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, | ||
465 | {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03}, | ||
466 | {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, | ||
467 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, | ||
468 | {PRO_DMOD, 0x00fc, { 0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77, | ||
469 | 0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c}, | ||
470 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, | ||
471 | {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, | ||
472 | {PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04}, | ||
473 | {PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03}, | ||
474 | {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, | ||
475 | {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, | ||
476 | {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, | ||
477 | {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05}, | ||
478 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
479 | {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, | ||
480 | {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, | ||
481 | {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, | ||
482 | {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, | ||
483 | {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, | ||
484 | {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, | ||
485 | {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, | ||
486 | {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03}, | ||
487 | {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, | ||
488 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
489 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
490 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
491 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
492 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
493 | {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, | ||
494 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
495 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
496 | {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, | ||
497 | {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, | ||
498 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
499 | {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, | ||
500 | {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, | ||
501 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
502 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
503 | {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, | ||
504 | {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, | ||
505 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
506 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
507 | {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, | ||
508 | {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, | ||
509 | {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, | ||
510 | {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, | ||
511 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
512 | {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, | ||
513 | {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02}, | ||
514 | {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, | ||
515 | {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, | ||
516 | {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, | ||
517 | {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, | ||
518 | 0x1f}, 0x08}, | ||
519 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, | ||
520 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, | ||
521 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
522 | {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, | ||
523 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
524 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
525 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
526 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
527 | }; | ||
528 | |||
529 | static struct it913xset it9135_52[] = { | ||
530 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, | ||
531 | {PRO_DMOD, 0x0046, {0x52}, 0x01}, | ||
532 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
533 | {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, | ||
534 | {PRO_DMOD, 0x0068, {0x10}, 0x01}, | ||
535 | {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, | ||
536 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05}, | ||
537 | {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, | ||
538 | {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97, | ||
539 | 0xc0, 0x9e, 0x01}, 0x0a}, | ||
540 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
541 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, | ||
542 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
543 | {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, | ||
544 | {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, | ||
545 | {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04}, | ||
546 | {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, | ||
547 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
548 | {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02}, | ||
549 | {PRO_DMOD, 0x00b6, {0x14}, 0x01}, | ||
550 | {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03}, | ||
551 | {PRO_DMOD, 0x00c4, {0x00}, 0x01}, | ||
552 | {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, | ||
553 | {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03}, | ||
554 | {PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03}, | ||
555 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, | ||
556 | {PRO_DMOD, 0x00fc, { 0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77, | ||
557 | 0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c}, | ||
558 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, | ||
559 | {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, | ||
560 | {PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04}, | ||
561 | {PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03}, | ||
562 | {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, | ||
563 | {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, | ||
564 | {PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05}, | ||
565 | {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05}, | ||
566 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
567 | {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, | ||
568 | {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, | ||
569 | {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, | ||
570 | {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, | ||
571 | {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, | ||
572 | {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, | ||
573 | {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, | ||
574 | {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03}, | ||
575 | {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, | ||
576 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
577 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
578 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
579 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
580 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
581 | {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, | ||
582 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
583 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
584 | {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, | ||
585 | {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, | ||
586 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
587 | {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, | ||
588 | {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, | ||
589 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
590 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
591 | {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, | ||
592 | {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, | ||
593 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
594 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
595 | {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, | ||
596 | {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, | ||
597 | {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, | ||
598 | {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, | ||
599 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
600 | {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, | ||
601 | {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02}, | ||
602 | {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, | ||
603 | {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, | ||
604 | {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, | ||
605 | {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, | ||
606 | 0x1f}, 0x08}, | ||
607 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, | ||
608 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, | ||
609 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
610 | {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, | ||
611 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
612 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
613 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
614 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
317 | }; | 615 | }; |
318 | 616 | ||
617 | /* Version 2 types */ | ||
618 | static struct it913xset it9135_v2[] = { | ||
619 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
620 | {PRO_DMOD, 0x0070, {0x0a}, 0x01}, | ||
621 | {PRO_DMOD, 0x007e, {0x04}, 0x01}, | ||
622 | {PRO_DMOD, 0x0081, {0x0a}, 0x01}, | ||
623 | {PRO_DMOD, 0x008a, {0x01}, 0x01}, | ||
624 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
625 | {PRO_DMOD, 0x0092, {0x06}, 0x01}, | ||
626 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
627 | {PRO_DMOD, 0x009f, {0xe1}, 0x01}, | ||
628 | {PRO_DMOD, 0x00a0, {0xcf}, 0x01}, | ||
629 | {PRO_DMOD, 0x00a3, {0x01}, 0x01}, | ||
630 | {PRO_DMOD, 0x00a5, {0x01}, 0x01}, | ||
631 | {PRO_DMOD, 0x00a6, {0x01}, 0x01}, | ||
632 | {PRO_DMOD, 0x00a9, {0x00}, 0x01}, | ||
633 | {PRO_DMOD, 0x00aa, {0x01}, 0x01}, | ||
634 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
635 | {PRO_DMOD, 0x00c2, {0x05}, 0x01}, | ||
636 | {PRO_DMOD, 0x00c6, {0x19}, 0x01}, | ||
637 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
638 | {PRO_DMOD, 0xf02b, {0x00}, 0x01}, | ||
639 | {PRO_DMOD, 0xf064, {0x03}, 0x01}, | ||
640 | {PRO_DMOD, 0xf065, {0xf9}, 0x01}, | ||
641 | {PRO_DMOD, 0xf066, {0x03}, 0x01}, | ||
642 | {PRO_DMOD, 0xf067, {0x01}, 0x01}, | ||
643 | {PRO_DMOD, 0xf06f, {0xe0}, 0x01}, | ||
644 | {PRO_DMOD, 0xf070, {0x03}, 0x01}, | ||
645 | {PRO_DMOD, 0xf072, {0x0f}, 0x01}, | ||
646 | {PRO_DMOD, 0xf073, {0x03}, 0x01}, | ||
647 | {PRO_DMOD, 0xf078, {0x00}, 0x01}, | ||
648 | {PRO_DMOD, 0xf087, {0x00}, 0x01}, | ||
649 | {PRO_DMOD, 0xf09b, {0x3f}, 0x01}, | ||
650 | {PRO_DMOD, 0xf09c, {0x00}, 0x01}, | ||
651 | {PRO_DMOD, 0xf09d, {0x20}, 0x01}, | ||
652 | {PRO_DMOD, 0xf09e, {0x00}, 0x01}, | ||
653 | {PRO_DMOD, 0xf09f, {0x0c}, 0x01}, | ||
654 | {PRO_DMOD, 0xf0a0, {0x00}, 0x01}, | ||
655 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
656 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
657 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
658 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
659 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
660 | {PRO_DMOD, 0xf14c, {0x00}, 0x01}, | ||
661 | {PRO_DMOD, 0xf14d, {0x00}, 0x01}, | ||
662 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
663 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
664 | {PRO_DMOD, 0xf15a, {0x00}, 0x01}, | ||
665 | {PRO_DMOD, 0xf15b, {0x08}, 0x01}, | ||
666 | {PRO_DMOD, 0xf15d, {0x03}, 0x01}, | ||
667 | {PRO_DMOD, 0xf15e, {0x05}, 0x01}, | ||
668 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
669 | {PRO_DMOD, 0xf166, {0x01}, 0x01}, | ||
670 | {PRO_DMOD, 0xf167, {0x40}, 0x01}, | ||
671 | {PRO_DMOD, 0xf168, {0x0f}, 0x01}, | ||
672 | {PRO_DMOD, 0xf17a, {0x00}, 0x01}, | ||
673 | {PRO_DMOD, 0xf17b, {0x00}, 0x01}, | ||
674 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
675 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
676 | {PRO_DMOD, 0xf1bc, {0x36}, 0x01}, | ||
677 | {PRO_DMOD, 0xf1bd, {0x00}, 0x01}, | ||
678 | {PRO_DMOD, 0xf1cb, {0xa0}, 0x01}, | ||
679 | {PRO_DMOD, 0xf1cc, {0x01}, 0x01}, | ||
680 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
681 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
682 | {PRO_DMOD, 0xf40e, {0x0a}, 0x01}, | ||
683 | {PRO_DMOD, 0xf40f, {0x40}, 0x01}, | ||
684 | {PRO_DMOD, 0xf410, {0x08}, 0x01}, | ||
685 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
686 | {PRO_DMOD, 0xf561, {0x15}, 0x01}, | ||
687 | {PRO_DMOD, 0xf562, {0x20}, 0x01}, | ||
688 | {PRO_DMOD, 0xf5e3, {0x09}, 0x01}, | ||
689 | {PRO_DMOD, 0xf5e4, {0x01}, 0x01}, | ||
690 | {PRO_DMOD, 0xf5e5, {0x01}, 0x01}, | ||
691 | {PRO_DMOD, 0xf600, {0x05}, 0x01}, | ||
692 | {PRO_DMOD, 0xf601, {0x08}, 0x01}, | ||
693 | {PRO_DMOD, 0xf602, {0x0b}, 0x01}, | ||
694 | {PRO_DMOD, 0xf603, {0x0e}, 0x01}, | ||
695 | {PRO_DMOD, 0xf604, {0x11}, 0x01}, | ||
696 | {PRO_DMOD, 0xf605, {0x14}, 0x01}, | ||
697 | {PRO_DMOD, 0xf606, {0x17}, 0x01}, | ||
698 | {PRO_DMOD, 0xf607, {0x1f}, 0x01}, | ||
699 | {PRO_DMOD, 0xf60e, {0x00}, 0x01}, | ||
700 | {PRO_DMOD, 0xf60f, {0x04}, 0x01}, | ||
701 | {PRO_DMOD, 0xf610, {0x32}, 0x01}, | ||
702 | {PRO_DMOD, 0xf611, {0x10}, 0x01}, | ||
703 | {PRO_DMOD, 0xf707, {0xfc}, 0x01}, | ||
704 | {PRO_DMOD, 0xf708, {0x00}, 0x01}, | ||
705 | {PRO_DMOD, 0xf709, {0x37}, 0x01}, | ||
706 | {PRO_DMOD, 0xf70a, {0x00}, 0x01}, | ||
707 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
708 | {PRO_DMOD, 0xf80f, {0x40}, 0x01}, | ||
709 | {PRO_DMOD, 0xf810, {0x54}, 0x01}, | ||
710 | {PRO_DMOD, 0xf811, {0x5a}, 0x01}, | ||
711 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
712 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
713 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
714 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
715 | }; | ||
716 | |||
717 | static struct it913xset it9135_60[] = { | ||
718 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, | ||
719 | {PRO_DMOD, 0x0046, {0x60}, 0x01}, | ||
720 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
721 | {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, | ||
722 | {PRO_DMOD, 0x0068, {0x0a}, 0x01}, | ||
723 | {PRO_DMOD, 0x006a, {0x03}, 0x01}, | ||
724 | {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, | ||
725 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05}, | ||
726 | {PRO_DMOD, 0x007e, {0x04}, 0x01}, | ||
727 | {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, | ||
728 | {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07}, | ||
729 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
730 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, | ||
731 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
732 | {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, | ||
733 | {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, | ||
734 | {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, | ||
735 | {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, | ||
736 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
737 | {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, | ||
738 | {PRO_DMOD, 0x00b6, {0x14}, 0x01}, | ||
739 | {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, | ||
740 | {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, | ||
741 | {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, | ||
742 | {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03}, | ||
743 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, | ||
744 | {PRO_DMOD, 0x00fc, { 0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c, | ||
745 | 0x00, 0x02, 0xbe, 0x00}, 0x0b}, | ||
746 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, | ||
747 | {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, | ||
748 | {PRO_DMOD, 0x011a, {0xbe}, 0x01}, | ||
749 | {PRO_DMOD, 0x0124, {0xae}, 0x01}, | ||
750 | {PRO_DMOD, 0x0127, {0x00}, 0x01}, | ||
751 | {PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04}, | ||
752 | {PRO_DMOD, 0x0137, {0x00}, 0x01}, | ||
753 | {PRO_DMOD, 0x013b, {0x08}, 0x01}, | ||
754 | {PRO_DMOD, 0x013f, {0x5b}, 0x01}, | ||
755 | {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c, | ||
756 | 0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6, | ||
757 | 0x33}, 0x0f}, | ||
758 | {PRO_DMOD, 0x0151, {0x28}, 0x01}, | ||
759 | {PRO_DMOD, 0x0153, {0xbc}, 0x01}, | ||
760 | {PRO_DMOD, 0x0178, {0x09}, 0x01}, | ||
761 | {PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02}, | ||
762 | {PRO_DMOD, 0x0185, {0x24}, 0x01}, | ||
763 | {PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05}, | ||
764 | {PRO_DMOD, 0xed02, {0xff}, 0x01}, | ||
765 | {PRO_DMOD, 0xee42, {0xff}, 0x01}, | ||
766 | {PRO_DMOD, 0xee82, {0xff}, 0x01}, | ||
767 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
768 | {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, | ||
769 | {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, | ||
770 | {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, | ||
771 | {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, | ||
772 | {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, | ||
773 | {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, | ||
774 | {PRO_DMOD, 0xf087, {0x00}, 0x01}, | ||
775 | {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, | ||
776 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
777 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
778 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
779 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
780 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
781 | {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, | ||
782 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
783 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
784 | {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, | ||
785 | {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, | ||
786 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
787 | {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, | ||
788 | {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, | ||
789 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
790 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
791 | {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, | ||
792 | {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, | ||
793 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
794 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
795 | {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, | ||
796 | {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, | ||
797 | {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, | ||
798 | {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, | ||
799 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
800 | {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, | ||
801 | {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, | ||
802 | {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17 | ||
803 | , 0x1f}, 0x08}, | ||
804 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, | ||
805 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, | ||
806 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
807 | {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, | ||
808 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
809 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
810 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
811 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
812 | }; | ||
813 | |||
814 | static struct it913xset it9135_61[] = { | ||
815 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, | ||
816 | {PRO_DMOD, 0x0046, {0x61}, 0x01}, | ||
817 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
818 | {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, | ||
819 | {PRO_DMOD, 0x0068, {0x06}, 0x01}, | ||
820 | {PRO_DMOD, 0x006a, {0x03}, 0x01}, | ||
821 | {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, | ||
822 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05}, | ||
823 | {PRO_DMOD, 0x007e, {0x04}, 0x01}, | ||
824 | {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, | ||
825 | {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07}, | ||
826 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
827 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, | ||
828 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
829 | {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, | ||
830 | {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, | ||
831 | {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04}, | ||
832 | {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, | ||
833 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
834 | {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, | ||
835 | {PRO_DMOD, 0x00b6, {0x14}, 0x01}, | ||
836 | {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, | ||
837 | {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, | ||
838 | {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, | ||
839 | {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03}, | ||
840 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, | ||
841 | {PRO_DMOD, 0x00fc, { 0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c, | ||
842 | 0x01, 0x02, 0xc8, 0x00}, 0x0b}, | ||
843 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, | ||
844 | {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, | ||
845 | {PRO_DMOD, 0x011a, {0xc6}, 0x01}, | ||
846 | {PRO_DMOD, 0x0124, {0xa8}, 0x01}, | ||
847 | {PRO_DMOD, 0x0127, {0x00}, 0x01}, | ||
848 | {PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04}, | ||
849 | {PRO_DMOD, 0x0137, {0x00}, 0x01}, | ||
850 | {PRO_DMOD, 0x013b, {0x05}, 0x01}, | ||
851 | {PRO_DMOD, 0x013f, {0x5b}, 0x01}, | ||
852 | {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c, | ||
853 | 0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6, | ||
854 | 0x33}, 0x0f}, | ||
855 | {PRO_DMOD, 0x0151, {0x28}, 0x01}, | ||
856 | {PRO_DMOD, 0x0153, {0xcc}, 0x01}, | ||
857 | {PRO_DMOD, 0x0178, {0x09}, 0x01}, | ||
858 | {PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02}, | ||
859 | {PRO_DMOD, 0x0185, {0x28}, 0x01}, | ||
860 | {PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05}, | ||
861 | {PRO_DMOD, 0xed02, {0xff}, 0x01}, | ||
862 | {PRO_DMOD, 0xee42, {0xff}, 0x01}, | ||
863 | {PRO_DMOD, 0xee82, {0xff}, 0x01}, | ||
864 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
865 | {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, | ||
866 | {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, | ||
867 | {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, | ||
868 | {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, | ||
869 | {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, | ||
870 | {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, | ||
871 | {PRO_DMOD, 0xf087, {0x00}, 0x01}, | ||
872 | {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, | ||
873 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
874 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
875 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
876 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
877 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
878 | {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, | ||
879 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
880 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
881 | {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, | ||
882 | {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, | ||
883 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
884 | {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, | ||
885 | {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, | ||
886 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
887 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
888 | {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, | ||
889 | {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, | ||
890 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
891 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
892 | {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, | ||
893 | {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, | ||
894 | {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, | ||
895 | {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, | ||
896 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
897 | {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, | ||
898 | {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, | ||
899 | {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, | ||
900 | 0x1f}, 0x08}, | ||
901 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, | ||
902 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, | ||
903 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
904 | {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, | ||
905 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
906 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
907 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
908 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
909 | }; | ||
910 | |||
911 | static struct it913xset it9135_62[] = { | ||
912 | {PRO_DMOD, 0x0043, {0x00}, 0x01}, | ||
913 | {PRO_DMOD, 0x0046, {0x62}, 0x01}, | ||
914 | {PRO_DMOD, 0x0051, {0x01}, 0x01}, | ||
915 | {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, | ||
916 | {PRO_DMOD, 0x0068, {0x0a}, 0x01}, | ||
917 | {PRO_DMOD, 0x006a, {0x03}, 0x01}, | ||
918 | {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, | ||
919 | {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05}, | ||
920 | {PRO_DMOD, 0x007e, {0x04}, 0x01}, | ||
921 | {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, | ||
922 | {PRO_DMOD, 0x0084, { 0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01}, | ||
923 | 0x07}, | ||
924 | {PRO_DMOD, 0x008e, {0x01}, 0x01}, | ||
925 | {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, | ||
926 | {PRO_DMOD, 0x0099, {0x01}, 0x01}, | ||
927 | {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, | ||
928 | {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, | ||
929 | {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, | ||
930 | {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, | ||
931 | {PRO_DMOD, 0x00b0, {0x01}, 0x01}, | ||
932 | {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, | ||
933 | {PRO_DMOD, 0x00b6, {0x14}, 0x01}, | ||
934 | {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, | ||
935 | {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, | ||
936 | {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, | ||
937 | {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, | ||
938 | {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, | ||
939 | {PRO_DMOD, 0x00fc, { 0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c, | ||
940 | 0x02, 0x02, 0xc2, 0x00}, 0x0b}, | ||
941 | {PRO_DMOD, 0x0109, {0x02}, 0x01}, | ||
942 | {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, | ||
943 | {PRO_DMOD, 0x011a, {0xb8}, 0x01}, | ||
944 | {PRO_DMOD, 0x0124, {0xa8}, 0x01}, | ||
945 | {PRO_DMOD, 0x0127, {0x00}, 0x01}, | ||
946 | {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, | ||
947 | {PRO_DMOD, 0x0137, {0x00}, 0x01}, | ||
948 | {PRO_DMOD, 0x013b, {0x05}, 0x01}, | ||
949 | {PRO_DMOD, 0x013f, {0x5b}, 0x01}, | ||
950 | {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c, | ||
951 | 0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0, | ||
952 | 0x33}, 0x0f}, | ||
953 | {PRO_DMOD, 0x0151, {0x28}, 0x01}, | ||
954 | {PRO_DMOD, 0x0153, {0xb2}, 0x01}, | ||
955 | {PRO_DMOD, 0x0178, {0x09}, 0x01}, | ||
956 | {PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02}, | ||
957 | {PRO_DMOD, 0x0185, {0x24}, 0x01}, | ||
958 | {PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05}, | ||
959 | {PRO_DMOD, 0xed02, {0xff}, 0x01}, | ||
960 | {PRO_DMOD, 0xee42, {0xff}, 0x01}, | ||
961 | {PRO_DMOD, 0xee82, {0xff}, 0x01}, | ||
962 | {PRO_DMOD, 0xf000, {0x0f}, 0x01}, | ||
963 | {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, | ||
964 | {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, | ||
965 | {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, | ||
966 | {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, | ||
967 | {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, | ||
968 | {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, | ||
969 | {PRO_DMOD, 0xf087, {0x00}, 0x01}, | ||
970 | {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, | ||
971 | {PRO_DMOD, 0xf130, {0x04}, 0x01}, | ||
972 | {PRO_DMOD, 0xf132, {0x04}, 0x01}, | ||
973 | {PRO_DMOD, 0xf144, {0x1a}, 0x01}, | ||
974 | {PRO_DMOD, 0xf146, {0x00}, 0x01}, | ||
975 | {PRO_DMOD, 0xf14a, {0x01}, 0x01}, | ||
976 | {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, | ||
977 | {PRO_DMOD, 0xf14f, {0x04}, 0x01}, | ||
978 | {PRO_DMOD, 0xf158, {0x7f}, 0x01}, | ||
979 | {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, | ||
980 | {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, | ||
981 | {PRO_DMOD, 0xf163, {0x05}, 0x01}, | ||
982 | {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, | ||
983 | {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, | ||
984 | {PRO_DMOD, 0xf183, {0x01}, 0x01}, | ||
985 | {PRO_DMOD, 0xf19d, {0x40}, 0x01}, | ||
986 | {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, | ||
987 | {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, | ||
988 | {PRO_DMOD, 0xf204, {0x10}, 0x01}, | ||
989 | {PRO_DMOD, 0xf214, {0x00}, 0x01}, | ||
990 | {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, | ||
991 | {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, | ||
992 | {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, | ||
993 | {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, | ||
994 | {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, | ||
995 | {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, | ||
996 | {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, | ||
997 | {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, | ||
998 | 0x1f}, 0x08}, | ||
999 | {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, | ||
1000 | {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, | ||
1001 | {PRO_DMOD, 0xf78b, {0x01}, 0x01}, | ||
1002 | {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, | ||
1003 | {PRO_DMOD, 0xf905, {0x01}, 0x01}, | ||
1004 | {PRO_DMOD, 0xfb06, {0x03}, 0x01}, | ||
1005 | {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, | ||
1006 | {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ | ||
1007 | }; | ||
1008 | |||
1009 | /* Tuner setting scripts (still keeping it9137) */ | ||
319 | static struct it913xset it9137_tuner_off[] = { | 1010 | static struct it913xset it9137_tuner_off[] = { |
320 | {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off */ | 1011 | {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off */ |
321 | {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */ | 1012 | {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */ |
322 | {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04}, | 1013 | {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04}, |
1014 | {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
1015 | 0x00, 0x00, 0x00, 0x00}, 0x0c}, | ||
1016 | {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04}, | ||
1017 | {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
1018 | 0x00}, 0x09}, | ||
1019 | {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
1020 | 0x00, 0x00}, 0x0a}, | ||
1021 | {PRO_DMOD, 0xec20, {0x00}, 0x01}, | ||
323 | {PRO_DMOD, 0xec3f, {0x01}, 0x01}, | 1022 | {PRO_DMOD, 0xec3f, {0x01}, 0x01}, |
324 | {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ | 1023 | {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ |
325 | }; | 1024 | }; |
326 | 1025 | ||
1026 | static struct it913xset set_it9135_template[] = { | ||
1027 | {PRO_DMOD, 0xee06, {0x00}, 0x01}, | ||
1028 | {PRO_DMOD, 0xec56, {0x00}, 0x01}, | ||
1029 | {PRO_DMOD, 0xec4c, {0x00}, 0x01}, | ||
1030 | {PRO_DMOD, 0xec4d, {0x00}, 0x01}, | ||
1031 | {PRO_DMOD, 0xec4e, {0x00}, 0x01}, | ||
1032 | {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */ | ||
1033 | {PRO_DMOD, 0x011f, {0x00}, 0x01}, | ||
1034 | {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ | ||
1035 | }; | ||
1036 | |||
327 | static struct it913xset set_it9137_template[] = { | 1037 | static struct it913xset set_it9137_template[] = { |
328 | {PRO_DMOD, 0xee06, {0x00}, 0x01}, | 1038 | {PRO_DMOD, 0xee06, {0x00}, 0x01}, |
329 | {PRO_DMOD, 0xec56, {0x00}, 0x01}, | 1039 | {PRO_DMOD, 0xec56, {0x00}, 0x01}, |
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index d4bd24eb4700..8088e62a2028 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c | |||
@@ -46,13 +46,17 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."); | |||
46 | dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \ | 46 | dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \ |
47 | *p, *(p+1), *(p+2), *(p+3), *(p+4), \ | 47 | *p, *(p+1), *(p+2), *(p+3), *(p+4), \ |
48 | *(p+5), *(p+6), *(p+7)); | 48 | *(p+5), *(p+6), *(p+7)); |
49 | #define info(format, arg...) \ | ||
50 | printk(KERN_INFO "it913x-fe: " format "\n" , ## arg) | ||
49 | 51 | ||
50 | struct it913x_fe_state { | 52 | struct it913x_fe_state { |
51 | struct dvb_frontend frontend; | 53 | struct dvb_frontend frontend; |
52 | struct i2c_adapter *i2c_adap; | 54 | struct i2c_adapter *i2c_adap; |
55 | struct ite_config *config; | ||
53 | u8 i2c_addr; | 56 | u8 i2c_addr; |
54 | u32 frequency; | 57 | u32 frequency; |
55 | u8 adf; | 58 | fe_modulation_t constellation; |
59 | fe_transmit_mode_t transmission_mode; | ||
56 | u32 crystalFrequency; | 60 | u32 crystalFrequency; |
57 | u32 adcFrequency; | 61 | u32 adcFrequency; |
58 | u8 tuner_type; | 62 | u8 tuner_type; |
@@ -211,13 +215,17 @@ static int it913x_init_tuner(struct it913x_fe_state *state) | |||
211 | state->tun_fn_min /= (state->tun_fdiv * nv_val); | 215 | state->tun_fn_min /= (state->tun_fdiv * nv_val); |
212 | deb_info("Tuner fn_min %d", state->tun_fn_min); | 216 | deb_info("Tuner fn_min %d", state->tun_fn_min); |
213 | 217 | ||
214 | for (i = 0; i < 50; i++) { | 218 | if (state->config->chip_ver > 1) |
215 | reg = it913x_read_reg_u8(state, 0xec82); | 219 | msleep(50); |
216 | if (reg > 0) | 220 | else { |
217 | break; | 221 | for (i = 0; i < 50; i++) { |
218 | if (reg < 0) | 222 | reg = it913x_read_reg_u8(state, 0xec82); |
219 | return -ENODEV; | 223 | if (reg > 0) |
220 | udelay(2000); | 224 | break; |
225 | if (reg < 0) | ||
226 | return -ENODEV; | ||
227 | udelay(2000); | ||
228 | } | ||
221 | } | 229 | } |
222 | 230 | ||
223 | return it913x_write_reg(state, PRO_DMOD, 0xed81, val); | 231 | return it913x_write_reg(state, PRO_DMOD, 0xed81, val); |
@@ -237,6 +245,11 @@ static int it9137_set_tuner(struct it913x_fe_state *state, | |||
237 | u8 lna_band; | 245 | u8 lna_band; |
238 | u8 bw; | 246 | u8 bw; |
239 | 247 | ||
248 | if (state->config->firmware_ver == 1) | ||
249 | set_tuner = set_it9135_template; | ||
250 | else | ||
251 | set_tuner = set_it9137_template; | ||
252 | |||
240 | deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth); | 253 | deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth); |
241 | 254 | ||
242 | if (frequency >= 51000 && frequency <= 440000) { | 255 | if (frequency >= 51000 && frequency <= 440000) { |
@@ -492,14 +505,50 @@ static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, | |||
492 | return 0; | 505 | return 0; |
493 | } | 506 | } |
494 | 507 | ||
495 | static int it913x_fe_read_snr(struct dvb_frontend *fe, u16* snr) | 508 | static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) |
496 | { | 509 | { |
497 | struct it913x_fe_state *state = fe->demodulator_priv; | 510 | struct it913x_fe_state *state = fe->demodulator_priv; |
498 | int ret = it913x_read_reg_u8(state, SIGNAL_QUALITY); | 511 | int ret; |
499 | ret = (ret * 0xff) / 0x64; | 512 | u8 reg[3]; |
500 | ret |= (ret << 0x8); | 513 | u32 snr_val, snr_min, snr_max; |
501 | *snr = ~ret; | 514 | u32 temp; |
502 | return 0; | 515 | |
516 | ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg)); | ||
517 | |||
518 | snr_val = (u32)(reg[2] << 16) | (reg[1] < 8) | reg[0]; | ||
519 | |||
520 | ret |= it913x_read_reg(state, 0xf78b, reg, 1); | ||
521 | if (reg[0]) | ||
522 | snr_val /= reg[0]; | ||
523 | |||
524 | if (state->transmission_mode == TRANSMISSION_MODE_2K) | ||
525 | snr_val *= 4; | ||
526 | else if (state->transmission_mode == TRANSMISSION_MODE_4K) | ||
527 | snr_val *= 2; | ||
528 | |||
529 | if (state->constellation == QPSK) { | ||
530 | snr_min = 0xb4711; | ||
531 | snr_max = 0x191451; | ||
532 | } else if (state->constellation == QAM_16) { | ||
533 | snr_min = 0x4f0d5; | ||
534 | snr_max = 0xc7925; | ||
535 | } else if (state->constellation == QAM_64) { | ||
536 | snr_min = 0x256d0; | ||
537 | snr_max = 0x626be; | ||
538 | } else | ||
539 | return -EINVAL; | ||
540 | |||
541 | if (snr_val < snr_min) | ||
542 | *snr = 0; | ||
543 | else if (snr_val < snr_max) { | ||
544 | temp = (snr_val - snr_min) >> 5; | ||
545 | temp *= 0xffff; | ||
546 | temp /= (snr_max - snr_min) >> 5; | ||
547 | *snr = (u16)temp; | ||
548 | } else | ||
549 | *snr = 0xffff; | ||
550 | |||
551 | return (ret < 0) ? -ENODEV : 0; | ||
503 | } | 552 | } |
504 | 553 | ||
505 | static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) | 554 | static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) |
@@ -526,9 +575,13 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe, | |||
526 | if (reg[3] < 3) | 575 | if (reg[3] < 3) |
527 | p->u.ofdm.constellation = fe_con[reg[3]]; | 576 | p->u.ofdm.constellation = fe_con[reg[3]]; |
528 | 577 | ||
578 | state->constellation = p->u.ofdm.constellation; | ||
579 | |||
529 | if (reg[0] < 3) | 580 | if (reg[0] < 3) |
530 | p->u.ofdm.transmission_mode = fe_mode[reg[0]]; | 581 | p->u.ofdm.transmission_mode = fe_mode[reg[0]]; |
531 | 582 | ||
583 | state->transmission_mode = p->u.ofdm.transmission_mode; | ||
584 | |||
532 | if (reg[1] < 4) | 585 | if (reg[1] < 4) |
533 | p->u.ofdm.guard_interval = fe_gi[reg[1]]; | 586 | p->u.ofdm.guard_interval = fe_gi[reg[1]]; |
534 | 587 | ||
@@ -578,7 +631,12 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe, | |||
578 | 631 | ||
579 | deb_info("Frontend Set Tuner Type %02x", state->tuner_type); | 632 | deb_info("Frontend Set Tuner Type %02x", state->tuner_type); |
580 | switch (state->tuner_type) { | 633 | switch (state->tuner_type) { |
581 | case IT9137: /* Tuner type 0x38 */ | 634 | case IT9135_38: |
635 | case IT9135_51: | ||
636 | case IT9135_52: | ||
637 | case IT9135_60: | ||
638 | case IT9135_61: | ||
639 | case IT9135_62: | ||
582 | ret = it9137_set_tuner(state, | 640 | ret = it9137_set_tuner(state, |
583 | p->u.ofdm.bandwidth, p->frequency); | 641 | p->u.ofdm.bandwidth, p->frequency); |
584 | break; | 642 | break; |
@@ -678,16 +736,19 @@ static u32 compute_div(u32 a, u32 b, u32 x) | |||
678 | 736 | ||
679 | static int it913x_fe_start(struct it913x_fe_state *state) | 737 | static int it913x_fe_start(struct it913x_fe_state *state) |
680 | { | 738 | { |
681 | struct it913xset *set_fe; | 739 | struct it913xset *set_lna; |
682 | struct it913xset *set_mode; | 740 | struct it913xset *set_mode; |
683 | int ret; | 741 | int ret; |
684 | u8 adf = (state->adf & 0xf); | 742 | u8 adf = (state->config->adf & 0xf); |
685 | u32 adc, xtal; | 743 | u32 adc, xtal; |
686 | u8 b[4]; | 744 | u8 b[4]; |
687 | 745 | ||
688 | ret = it913x_init_tuner(state); | 746 | if (state->config->chip_ver == 1) |
747 | ret = it913x_init_tuner(state); | ||
689 | 748 | ||
690 | if (adf < 12) { | 749 | info("ADF table value :%02x", adf); |
750 | |||
751 | if (adf < 10) { | ||
691 | state->crystalFrequency = fe_clockTable[adf].xtal ; | 752 | state->crystalFrequency = fe_clockTable[adf].xtal ; |
692 | state->table = fe_clockTable[adf].table; | 753 | state->table = fe_clockTable[adf].table; |
693 | state->adcFrequency = state->table->adcFrequency; | 754 | state->adcFrequency = state->table->adcFrequency; |
@@ -698,9 +759,6 @@ static int it913x_fe_start(struct it913x_fe_state *state) | |||
698 | } else | 759 | } else |
699 | return -EINVAL; | 760 | return -EINVAL; |
700 | 761 | ||
701 | deb_info("Xtal Freq :%d Adc Freq :%d Adc %08x Xtal %08x", | ||
702 | state->crystalFrequency, state->adcFrequency, adc, xtal); | ||
703 | |||
704 | /* Set LED indicator on GPIOH3 */ | 762 | /* Set LED indicator on GPIOH3 */ |
705 | ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1); | 763 | ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1); |
706 | ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1); | 764 | ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1); |
@@ -721,22 +779,71 @@ static int it913x_fe_start(struct it913x_fe_state *state) | |||
721 | b[2] = (adc >> 16) & 0xff; | 779 | b[2] = (adc >> 16) & 0xff; |
722 | ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3); | 780 | ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3); |
723 | 781 | ||
782 | if (state->config->adc_x2) | ||
783 | ret |= it913x_write_reg(state, PRO_DMOD, ADC_X_2, 0x01); | ||
784 | b[0] = 0; | ||
785 | b[1] = 0; | ||
786 | b[2] = 0; | ||
787 | ret |= it913x_write(state, PRO_DMOD, 0x0029, b, 3); | ||
788 | |||
789 | info("Crystal Frequency :%d Adc Frequency :%d ADC X2: %02x", | ||
790 | state->crystalFrequency, state->adcFrequency, | ||
791 | state->config->adc_x2); | ||
792 | deb_info("Xtal value :%04x Adc value :%04x", xtal, adc); | ||
793 | |||
794 | if (ret < 0) | ||
795 | return -ENODEV; | ||
796 | |||
797 | /* v1 or v2 tuner script */ | ||
798 | if (state->config->chip_ver > 1) | ||
799 | ret = it913x_fe_script_loader(state, it9135_v2); | ||
800 | else | ||
801 | ret = it913x_fe_script_loader(state, it9135_v1); | ||
802 | if (ret < 0) | ||
803 | return ret; | ||
804 | |||
805 | /* LNA Scripts */ | ||
724 | switch (state->tuner_type) { | 806 | switch (state->tuner_type) { |
725 | case IT9137: /* Tuner type 0x38 */ | 807 | case IT9135_51: |
726 | set_fe = it9137_set; | 808 | set_lna = it9135_51; |
809 | break; | ||
810 | case IT9135_52: | ||
811 | set_lna = it9135_52; | ||
812 | break; | ||
813 | case IT9135_60: | ||
814 | set_lna = it9135_60; | ||
815 | break; | ||
816 | case IT9135_61: | ||
817 | set_lna = it9135_61; | ||
727 | break; | 818 | break; |
819 | case IT9135_62: | ||
820 | set_lna = it9135_62; | ||
821 | break; | ||
822 | case IT9135_38: | ||
728 | default: | 823 | default: |
729 | return -EINVAL; | 824 | set_lna = it9135_38; |
825 | } | ||
826 | info("Tuner LNA type :%02x", state->tuner_type); | ||
827 | |||
828 | ret = it913x_fe_script_loader(state, set_lna); | ||
829 | if (ret < 0) | ||
830 | return ret; | ||
831 | |||
832 | if (state->config->chip_ver == 2) { | ||
833 | ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1); | ||
834 | ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0); | ||
835 | ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0); | ||
836 | ret |= it913x_init_tuner(state); | ||
730 | } | 837 | } |
838 | if (ret < 0) | ||
839 | return -ENODEV; | ||
731 | 840 | ||
732 | /* set the demod */ | ||
733 | ret = it913x_fe_script_loader(state, set_fe); | ||
734 | /* Always solo frontend */ | 841 | /* Always solo frontend */ |
735 | set_mode = set_solo_fe; | 842 | set_mode = set_solo_fe; |
736 | ret |= it913x_fe_script_loader(state, set_mode); | 843 | ret |= it913x_fe_script_loader(state, set_mode); |
737 | 844 | ||
738 | ret |= it913x_fe_suspend(state); | 845 | ret |= it913x_fe_suspend(state); |
739 | return 0; | 846 | return (ret < 0) ? -ENODEV : 0; |
740 | } | 847 | } |
741 | 848 | ||
742 | static int it913x_fe_init(struct dvb_frontend *fe) | 849 | static int it913x_fe_init(struct dvb_frontend *fe) |
@@ -746,17 +853,11 @@ static int it913x_fe_init(struct dvb_frontend *fe) | |||
746 | /* Power Up Tuner - common all versions */ | 853 | /* Power Up Tuner - common all versions */ |
747 | ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1); | 854 | ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1); |
748 | 855 | ||
749 | ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0); | ||
750 | |||
751 | ret |= it913x_fe_script_loader(state, init_1); | 856 | ret |= it913x_fe_script_loader(state, init_1); |
752 | 857 | ||
753 | switch (state->tuner_type) { | 858 | ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0); |
754 | case IT9137: | 859 | |
755 | ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0); | 860 | ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0); |
756 | break; | ||
757 | default: | ||
758 | return -EINVAL; | ||
759 | } | ||
760 | 861 | ||
761 | return (ret < 0) ? -ENODEV : 0; | 862 | return (ret < 0) ? -ENODEV : 0; |
762 | } | 863 | } |
@@ -770,19 +871,34 @@ static void it913x_fe_release(struct dvb_frontend *fe) | |||
770 | static struct dvb_frontend_ops it913x_fe_ofdm_ops; | 871 | static struct dvb_frontend_ops it913x_fe_ofdm_ops; |
771 | 872 | ||
772 | struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, | 873 | struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, |
773 | u8 i2c_addr, u8 adf, u8 type) | 874 | u8 i2c_addr, struct ite_config *config) |
774 | { | 875 | { |
775 | struct it913x_fe_state *state = NULL; | 876 | struct it913x_fe_state *state = NULL; |
776 | int ret; | 877 | int ret; |
878 | |||
777 | /* allocate memory for the internal state */ | 879 | /* allocate memory for the internal state */ |
778 | state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL); | 880 | state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL); |
779 | if (state == NULL) | 881 | if (state == NULL) |
882 | return NULL; | ||
883 | if (config == NULL) | ||
780 | goto error; | 884 | goto error; |
781 | 885 | ||
782 | state->i2c_adap = i2c_adap; | 886 | state->i2c_adap = i2c_adap; |
783 | state->i2c_addr = i2c_addr; | 887 | state->i2c_addr = i2c_addr; |
784 | state->adf = adf; | 888 | state->config = config; |
785 | state->tuner_type = type; | 889 | |
890 | switch (state->config->tuner_id_0) { | ||
891 | case IT9135_51: | ||
892 | case IT9135_52: | ||
893 | case IT9135_60: | ||
894 | case IT9135_61: | ||
895 | case IT9135_62: | ||
896 | state->tuner_type = state->config->tuner_id_0; | ||
897 | break; | ||
898 | default: | ||
899 | case IT9135_38: | ||
900 | state->tuner_type = IT9135_38; | ||
901 | } | ||
786 | 902 | ||
787 | ret = it913x_fe_start(state); | 903 | ret = it913x_fe_start(state); |
788 | if (ret < 0) | 904 | if (ret < 0) |
@@ -835,5 +951,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = { | |||
835 | 951 | ||
836 | MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); | 952 | MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); |
837 | MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); | 953 | MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); |
838 | MODULE_VERSION("1.07"); | 954 | MODULE_VERSION("1.12"); |
839 | MODULE_LICENSE("GPL"); | 955 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h index 9d97f32e690b..4143ef9c4fab 100644 --- a/drivers/media/dvb/frontends/it913x-fe.h +++ b/drivers/media/dvb/frontends/it913x-fe.h | |||
@@ -23,13 +23,27 @@ | |||
23 | 23 | ||
24 | #include <linux/dvb/frontend.h> | 24 | #include <linux/dvb/frontend.h> |
25 | #include "dvb_frontend.h" | 25 | #include "dvb_frontend.h" |
26 | |||
27 | struct ite_config { | ||
28 | u8 chip_ver; | ||
29 | u16 chip_type; | ||
30 | u32 firmware; | ||
31 | u8 firmware_ver; | ||
32 | u8 adc_x2; | ||
33 | u8 tuner_id_0; | ||
34 | u8 tuner_id_1; | ||
35 | u8 dual_mode; | ||
36 | u8 adf; | ||
37 | }; | ||
38 | |||
26 | #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ | 39 | #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ |
27 | defined(MODULE)) | 40 | defined(MODULE)) |
28 | extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, | 41 | extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, |
29 | u8 i2c_addr, u8 adf, u8 type); | 42 | u8 i2c_addr, struct ite_config *config); |
30 | #else | 43 | #else |
31 | static inline struct dvb_frontend *it913x_fe_attach( | 44 | static inline struct dvb_frontend *it913x_fe_attach( |
32 | struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 adf, u8 type) | 45 | struct i2c_adapter *i2c_adap, |
46 | u8 i2c_addr, struct ite_config *config) | ||
33 | { | 47 | { |
34 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 48 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
35 | return NULL; | 49 | return NULL; |
@@ -144,8 +158,14 @@ static inline struct dvb_frontend *it913x_fe_attach( | |||
144 | #define EST_SIGNAL_LEVEL 0x004a | 158 | #define EST_SIGNAL_LEVEL 0x004a |
145 | #define FREE_BAND 0x004b | 159 | #define FREE_BAND 0x004b |
146 | #define SUSPEND_FLAG 0x004c | 160 | #define SUSPEND_FLAG 0x004c |
147 | /* Build in tuners */ | 161 | /* Build in tuner types */ |
148 | #define IT9137 0x38 | 162 | #define IT9137 0x38 |
163 | #define IT9135_38 0x38 | ||
164 | #define IT9135_51 0x50 | ||
165 | #define IT9135_52 0x52 | ||
166 | #define IT9135_60 0x60 | ||
167 | #define IT9135_61 0x61 | ||
168 | #define IT9135_62 0x62 | ||
149 | 169 | ||
150 | enum { | 170 | enum { |
151 | CMD_DEMOD_READ = 0, | 171 | CMD_DEMOD_READ = 0, |
@@ -193,4 +213,11 @@ enum { | |||
193 | WRITE_CMD, | 213 | WRITE_CMD, |
194 | }; | 214 | }; |
195 | 215 | ||
216 | enum { | ||
217 | IT9135_AUTO = 0, | ||
218 | IT9137_FW, | ||
219 | IT9135_V1_FW, | ||
220 | IT9135_V2_FW, | ||
221 | }; | ||
222 | |||
196 | #endif /* IT913X_FE_H */ | 223 | #endif /* IT913X_FE_H */ |
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 0e2f61a8978f..0d6d5e3e2c31 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c | |||
@@ -879,7 +879,36 @@ static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
879 | static int s5h1409_read_signal_strength(struct dvb_frontend *fe, | 879 | static int s5h1409_read_signal_strength(struct dvb_frontend *fe, |
880 | u16 *signal_strength) | 880 | u16 *signal_strength) |
881 | { | 881 | { |
882 | return s5h1409_read_snr(fe, signal_strength); | 882 | /* borrowed from lgdt330x.c |
883 | * | ||
884 | * Calculate strength from SNR up to 35dB | ||
885 | * Even though the SNR can go higher than 35dB, | ||
886 | * there is some comfort factor in having a range of | ||
887 | * strong signals that can show at 100% | ||
888 | */ | ||
889 | u16 snr; | ||
890 | u32 tmp; | ||
891 | int ret = s5h1409_read_snr(fe, &snr); | ||
892 | |||
893 | *signal_strength = 0; | ||
894 | |||
895 | if (0 == ret) { | ||
896 | /* The following calculation method was chosen | ||
897 | * purely for the sake of code re-use from the | ||
898 | * other demod drivers that use this method */ | ||
899 | |||
900 | /* Convert from SNR in dB * 10 to 8.24 fixed-point */ | ||
901 | tmp = (snr * ((1 << 24) / 10)); | ||
902 | |||
903 | /* Convert from 8.24 fixed-point to | ||
904 | * scale the range 0 - 35*2^24 into 0 - 65535*/ | ||
905 | if (tmp >= 8960 * 0x10000) | ||
906 | *signal_strength = 0xffff; | ||
907 | else | ||
908 | *signal_strength = tmp / 8960; | ||
909 | } | ||
910 | |||
911 | return ret; | ||
883 | } | 912 | } |
884 | 913 | ||
885 | static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 914 | static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index d8adf1e32019..5fca113a2013 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/drivers/media/dvb/frontends/s5h1411.c | |||
@@ -794,7 +794,36 @@ static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
794 | static int s5h1411_read_signal_strength(struct dvb_frontend *fe, | 794 | static int s5h1411_read_signal_strength(struct dvb_frontend *fe, |
795 | u16 *signal_strength) | 795 | u16 *signal_strength) |
796 | { | 796 | { |
797 | return s5h1411_read_snr(fe, signal_strength); | 797 | /* borrowed from lgdt330x.c |
798 | * | ||
799 | * Calculate strength from SNR up to 35dB | ||
800 | * Even though the SNR can go higher than 35dB, | ||
801 | * there is some comfort factor in having a range of | ||
802 | * strong signals that can show at 100% | ||
803 | */ | ||
804 | u16 snr; | ||
805 | u32 tmp; | ||
806 | int ret = s5h1411_read_snr(fe, &snr); | ||
807 | |||
808 | *signal_strength = 0; | ||
809 | |||
810 | if (0 == ret) { | ||
811 | /* The following calculation method was chosen | ||
812 | * purely for the sake of code re-use from the | ||
813 | * other demod drivers that use this method */ | ||
814 | |||
815 | /* Convert from SNR in dB * 10 to 8.24 fixed-point */ | ||
816 | tmp = (snr * ((1 << 24) / 10)); | ||
817 | |||
818 | /* Convert from 8.24 fixed-point to | ||
819 | * scale the range 0 - 35*2^24 into 0 - 65535*/ | ||
820 | if (tmp >= 8960 * 0x10000) | ||
821 | *signal_strength = 0xffff; | ||
822 | else | ||
823 | *signal_strength = tmp / 8960; | ||
824 | } | ||
825 | |||
826 | return ret; | ||
798 | } | 827 | } |
799 | 828 | ||
800 | static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 829 | static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index 8408ef877b4b..9c93d9f1ae6a 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c | |||
@@ -1605,6 +1605,21 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) | |||
1605 | return DVBFE_ALGO_CUSTOM; | 1605 | return DVBFE_ALGO_CUSTOM; |
1606 | } | 1606 | } |
1607 | 1607 | ||
1608 | static int stb0899_get_property(struct dvb_frontend *fe, struct dtv_property *p) | ||
1609 | { | ||
1610 | switch (p->cmd) { | ||
1611 | case DTV_ENUM_DELSYS: | ||
1612 | p->u.buffer.data[0] = SYS_DSS; | ||
1613 | p->u.buffer.data[1] = SYS_DVBS; | ||
1614 | p->u.buffer.data[2] = SYS_DVBS2; | ||
1615 | p->u.buffer.len = 3; | ||
1616 | break; | ||
1617 | default: | ||
1618 | break; | ||
1619 | } | ||
1620 | return 0; | ||
1621 | } | ||
1622 | |||
1608 | static struct dvb_frontend_ops stb0899_ops = { | 1623 | static struct dvb_frontend_ops stb0899_ops = { |
1609 | 1624 | ||
1610 | .info = { | 1625 | .info = { |
@@ -1647,6 +1662,8 @@ static struct dvb_frontend_ops stb0899_ops = { | |||
1647 | .diseqc_send_master_cmd = stb0899_send_diseqc_msg, | 1662 | .diseqc_send_master_cmd = stb0899_send_diseqc_msg, |
1648 | .diseqc_recv_slave_reply = stb0899_recv_slave_reply, | 1663 | .diseqc_recv_slave_reply = stb0899_recv_slave_reply, |
1649 | .diseqc_send_burst = stb0899_send_diseqc_burst, | 1664 | .diseqc_send_burst = stb0899_send_diseqc_burst, |
1665 | |||
1666 | .get_property = stb0899_get_property, | ||
1650 | }; | 1667 | }; |
1651 | 1668 | ||
1652 | struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c) | 1669 | struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c) |
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 0ca316d6fffa..2b8d78c7cdb1 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c | |||
@@ -985,7 +985,16 @@ static int stb0900_get_property(struct dvb_frontend *fe, | |||
985 | struct dtv_property *tvp) | 985 | struct dtv_property *tvp) |
986 | { | 986 | { |
987 | dprintk("%s(..)\n", __func__); | 987 | dprintk("%s(..)\n", __func__); |
988 | 988 | switch (tvp->cmd) { | |
989 | case DTV_ENUM_DELSYS: | ||
990 | tvp->u.buffer.data[0] = SYS_DSS; | ||
991 | tvp->u.buffer.data[1] = SYS_DVBS; | ||
992 | tvp->u.buffer.data[2] = SYS_DVBS2; | ||
993 | tvp->u.buffer.len = 3; | ||
994 | break; | ||
995 | default: | ||
996 | break; | ||
997 | } | ||
989 | return 0; | 998 | return 0; |
990 | } | 999 | } |
991 | 1000 | ||
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index ebda41936b90..8a2637c20d7c 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c | |||
@@ -4711,6 +4711,21 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, | |||
4711 | } | 4711 | } |
4712 | EXPORT_SYMBOL(stv090x_set_gpio); | 4712 | EXPORT_SYMBOL(stv090x_set_gpio); |
4713 | 4713 | ||
4714 | static int stv090x_get_property(struct dvb_frontend *fe, struct dtv_property *p) | ||
4715 | { | ||
4716 | switch (p->cmd) { | ||
4717 | case DTV_ENUM_DELSYS: | ||
4718 | p->u.buffer.data[0] = SYS_DSS; | ||
4719 | p->u.buffer.data[1] = SYS_DVBS; | ||
4720 | p->u.buffer.data[2] = SYS_DVBS2; | ||
4721 | p->u.buffer.len = 3; | ||
4722 | break; | ||
4723 | default: | ||
4724 | break; | ||
4725 | } | ||
4726 | return 0; | ||
4727 | } | ||
4728 | |||
4714 | static struct dvb_frontend_ops stv090x_ops = { | 4729 | static struct dvb_frontend_ops stv090x_ops = { |
4715 | 4730 | ||
4716 | .info = { | 4731 | .info = { |
@@ -4743,7 +4758,9 @@ static struct dvb_frontend_ops stv090x_ops = { | |||
4743 | .read_status = stv090x_read_status, | 4758 | .read_status = stv090x_read_status, |
4744 | .read_ber = stv090x_read_per, | 4759 | .read_ber = stv090x_read_per, |
4745 | .read_signal_strength = stv090x_read_signal_strength, | 4760 | .read_signal_strength = stv090x_read_signal_strength, |
4746 | .read_snr = stv090x_read_cnr | 4761 | .read_snr = stv090x_read_cnr, |
4762 | |||
4763 | .get_property = stv090x_get_property, | ||
4747 | }; | 4764 | }; |
4748 | 4765 | ||
4749 | 4766 | ||
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 6ca533ea0f0e..2518c5a33225 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -224,29 +224,60 @@ static int tda10021_init (struct dvb_frontend *fe) | |||
224 | return 0; | 224 | return 0; |
225 | } | 225 | } |
226 | 226 | ||
227 | struct qam_params { | ||
228 | u8 conf, agcref, lthr, mseth, aref; | ||
229 | }; | ||
230 | |||
227 | static int tda10021_set_parameters (struct dvb_frontend *fe, | 231 | static int tda10021_set_parameters (struct dvb_frontend *fe, |
228 | struct dvb_frontend_parameters *p) | 232 | struct dvb_frontend_parameters *p) |
229 | { | 233 | { |
234 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
235 | u32 delsys = c->delivery_system; | ||
236 | unsigned qam = c->modulation; | ||
237 | bool is_annex_c; | ||
238 | u32 reg0x3d; | ||
230 | struct tda10021_state* state = fe->demodulator_priv; | 239 | struct tda10021_state* state = fe->demodulator_priv; |
240 | static const struct qam_params qam_params[] = { | ||
241 | /* Modulation Conf AGCref LTHR MSETH AREF */ | ||
242 | [QPSK] = { 0x14, 0x78, 0x78, 0x8c, 0x96 }, | ||
243 | [QAM_16] = { 0x00, 0x8c, 0x87, 0xa2, 0x91 }, | ||
244 | [QAM_32] = { 0x04, 0x8c, 0x64, 0x74, 0x96 }, | ||
245 | [QAM_64] = { 0x08, 0x6a, 0x46, 0x43, 0x6a }, | ||
246 | [QAM_128] = { 0x0c, 0x78, 0x36, 0x34, 0x7e }, | ||
247 | [QAM_256] = { 0x10, 0x5c, 0x26, 0x23, 0x6b }, | ||
248 | }; | ||
249 | |||
250 | switch (delsys) { | ||
251 | case SYS_DVBC_ANNEX_A: | ||
252 | is_annex_c = false; | ||
253 | break; | ||
254 | case SYS_DVBC_ANNEX_C: | ||
255 | is_annex_c = true; | ||
256 | break; | ||
257 | default: | ||
258 | return -EINVAL; | ||
259 | } | ||
231 | 260 | ||
232 | //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256 | 261 | /* |
233 | //CONF | 262 | * gcc optimizes the code bellow the same way as it would code: |
234 | static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 }; | 263 | * "if (qam > 5) return -EINVAL;" |
235 | //AGCREF value | 264 | * Yet, the code is clearer, as it shows what QAM standards are |
236 | static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c }; | 265 | * supported by the driver, and avoids the usage of magic numbers on |
237 | //LTHR value | 266 | * it. |
238 | static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 }; | 267 | */ |
239 | //MSETH | 268 | switch (qam) { |
240 | static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 }; | 269 | case QPSK: |
241 | //AREF | 270 | case QAM_16: |
242 | static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b }; | 271 | case QAM_32: |
243 | 272 | case QAM_64: | |
244 | int qam = p->u.qam.modulation; | 273 | case QAM_128: |
245 | 274 | case QAM_256: | |
246 | if (qam < 0 || qam > 5) | 275 | break; |
276 | default: | ||
247 | return -EINVAL; | 277 | return -EINVAL; |
278 | } | ||
248 | 279 | ||
249 | if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) | 280 | if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF) |
250 | return -EINVAL; | 281 | return -EINVAL; |
251 | 282 | ||
252 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); | 283 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); |
@@ -256,15 +287,24 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, | |||
256 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 287 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
257 | } | 288 | } |
258 | 289 | ||
259 | tda10021_set_symbolrate (state, p->u.qam.symbol_rate); | 290 | tda10021_set_symbolrate(state, c->symbol_rate); |
260 | _tda10021_writereg (state, 0x34, state->pwm); | 291 | _tda10021_writereg(state, 0x34, state->pwm); |
261 | 292 | ||
262 | _tda10021_writereg (state, 0x01, reg0x01[qam]); | 293 | _tda10021_writereg(state, 0x01, qam_params[qam].agcref); |
263 | _tda10021_writereg (state, 0x05, reg0x05[qam]); | 294 | _tda10021_writereg(state, 0x05, qam_params[qam].lthr); |
264 | _tda10021_writereg (state, 0x08, reg0x08[qam]); | 295 | _tda10021_writereg(state, 0x08, qam_params[qam].mseth); |
265 | _tda10021_writereg (state, 0x09, reg0x09[qam]); | 296 | _tda10021_writereg(state, 0x09, qam_params[qam].aref); |
266 | 297 | ||
267 | tda10021_setup_reg0 (state, reg0x00[qam], p->inversion); | 298 | /* |
299 | * Bit 0 == 0 means roll-off = 0.15 (Annex A) | ||
300 | * == 1 means roll-off = 0.13 (Annex C) | ||
301 | */ | ||
302 | reg0x3d = tda10021_readreg (state, 0x3d); | ||
303 | if (is_annex_c) | ||
304 | _tda10021_writereg (state, 0x3d, 0x01 | reg0x3d); | ||
305 | else | ||
306 | _tda10021_writereg (state, 0x3d, 0xfe & reg0x3d); | ||
307 | tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion); | ||
268 | 308 | ||
269 | return 0; | 309 | return 0; |
270 | } | 310 | } |
@@ -443,6 +483,21 @@ error: | |||
443 | return NULL; | 483 | return NULL; |
444 | } | 484 | } |
445 | 485 | ||
486 | static int tda10021_get_property(struct dvb_frontend *fe, | ||
487 | struct dtv_property *p) | ||
488 | { | ||
489 | switch (p->cmd) { | ||
490 | case DTV_ENUM_DELSYS: | ||
491 | p->u.buffer.data[0] = SYS_DVBC_ANNEX_A; | ||
492 | p->u.buffer.data[1] = SYS_DVBC_ANNEX_C; | ||
493 | p->u.buffer.len = 2; | ||
494 | break; | ||
495 | default: | ||
496 | break; | ||
497 | } | ||
498 | return 0; | ||
499 | } | ||
500 | |||
446 | static struct dvb_frontend_ops tda10021_ops = { | 501 | static struct dvb_frontend_ops tda10021_ops = { |
447 | 502 | ||
448 | .info = { | 503 | .info = { |
@@ -471,6 +526,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
471 | 526 | ||
472 | .set_frontend = tda10021_set_parameters, | 527 | .set_frontend = tda10021_set_parameters, |
473 | .get_frontend = tda10021_get_frontend, | 528 | .get_frontend = tda10021_get_frontend, |
529 | .get_property = tda10021_get_property, | ||
474 | 530 | ||
475 | .read_status = tda10021_read_status, | 531 | .read_status = tda10021_read_status, |
476 | .read_ber = tda10021_read_ber, | 532 | .read_ber = tda10021_read_ber, |
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c index a3c34eecdee9..af7f1b808a34 100644 --- a/drivers/media/dvb/frontends/tda10023.c +++ b/drivers/media/dvb/frontends/tda10023.c | |||
@@ -298,43 +298,97 @@ static int tda10023_init (struct dvb_frontend *fe) | |||
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
300 | 300 | ||
301 | struct qam_params { | ||
302 | u8 qam, lockthr, mseth, aref, agcrefnyq, eragnyq_thd; | ||
303 | }; | ||
304 | |||
301 | static int tda10023_set_parameters (struct dvb_frontend *fe, | 305 | static int tda10023_set_parameters (struct dvb_frontend *fe, |
302 | struct dvb_frontend_parameters *p) | 306 | struct dvb_frontend_parameters *p) |
303 | { | 307 | { |
308 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
309 | u32 delsys = c->delivery_system; | ||
310 | unsigned qam = c->modulation; | ||
311 | bool is_annex_c; | ||
304 | struct tda10023_state* state = fe->demodulator_priv; | 312 | struct tda10023_state* state = fe->demodulator_priv; |
305 | 313 | static const struct qam_params qam_params[] = { | |
306 | static int qamvals[6][6] = { | 314 | /* Modulation QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD */ |
307 | // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD | 315 | [QPSK] = { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, |
308 | { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM | 316 | [QAM_16] = { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, |
309 | { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM | 317 | [QAM_32] = { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, |
310 | { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM | 318 | [QAM_64] = { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, |
311 | { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM | 319 | [QAM_128] = { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, |
312 | { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM | 320 | [QAM_256] = { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, |
313 | { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM | ||
314 | }; | 321 | }; |
315 | 322 | ||
316 | int qam = p->u.qam.modulation; | 323 | switch (delsys) { |
324 | case SYS_DVBC_ANNEX_A: | ||
325 | is_annex_c = false; | ||
326 | break; | ||
327 | case SYS_DVBC_ANNEX_C: | ||
328 | is_annex_c = true; | ||
329 | break; | ||
330 | default: | ||
331 | return -EINVAL; | ||
332 | } | ||
317 | 333 | ||
318 | if (qam < 0 || qam > 5) | 334 | /* |
335 | * gcc optimizes the code bellow the same way as it would code: | ||
336 | * "if (qam > 5) return -EINVAL;" | ||
337 | * Yet, the code is clearer, as it shows what QAM standards are | ||
338 | * supported by the driver, and avoids the usage of magic numbers on | ||
339 | * it. | ||
340 | */ | ||
341 | switch (qam) { | ||
342 | case QPSK: | ||
343 | case QAM_16: | ||
344 | case QAM_32: | ||
345 | case QAM_64: | ||
346 | case QAM_128: | ||
347 | case QAM_256: | ||
348 | break; | ||
349 | default: | ||
319 | return -EINVAL; | 350 | return -EINVAL; |
351 | } | ||
320 | 352 | ||
321 | if (fe->ops.tuner_ops.set_params) { | 353 | if (fe->ops.tuner_ops.set_params) { |
322 | fe->ops.tuner_ops.set_params(fe, p); | 354 | fe->ops.tuner_ops.set_params(fe, p); |
323 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 355 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
324 | } | 356 | } |
325 | 357 | ||
326 | tda10023_set_symbolrate (state, p->u.qam.symbol_rate); | 358 | tda10023_set_symbolrate(state, c->symbol_rate); |
327 | tda10023_writereg (state, 0x05, qamvals[qam][1]); | 359 | tda10023_writereg(state, 0x05, qam_params[qam].lockthr); |
328 | tda10023_writereg (state, 0x08, qamvals[qam][2]); | 360 | tda10023_writereg(state, 0x08, qam_params[qam].mseth); |
329 | tda10023_writereg (state, 0x09, qamvals[qam][3]); | 361 | tda10023_writereg(state, 0x09, qam_params[qam].aref); |
330 | tda10023_writereg (state, 0xb4, qamvals[qam][4]); | 362 | tda10023_writereg(state, 0xb4, qam_params[qam].agcrefnyq); |
331 | tda10023_writereg (state, 0xb6, qamvals[qam][5]); | 363 | tda10023_writereg(state, 0xb6, qam_params[qam].eragnyq_thd); |
364 | #if 0 | ||
365 | tda10023_writereg(state, 0x04, (c->inversion ? 0x12 : 0x32)); | ||
366 | tda10023_writebit(state, 0x04, 0x60, (c->inversion ? 0 : 0x20)); | ||
367 | #endif | ||
368 | tda10023_writebit(state, 0x04, 0x40, 0x40); | ||
369 | |||
370 | if (is_annex_c) | ||
371 | tda10023_writebit(state, 0x3d, 0xfc, 0x03); | ||
372 | else | ||
373 | tda10023_writebit(state, 0x3d, 0xfc, 0x02); | ||
374 | |||
375 | tda10023_setup_reg0(state, qam_params[qam].qam); | ||
332 | 376 | ||
333 | // tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32)); | 377 | return 0; |
334 | // tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20)); | 378 | } |
335 | tda10023_writebit (state, 0x04, 0x40, 0x40); | ||
336 | tda10023_setup_reg0 (state, qamvals[qam][0]); | ||
337 | 379 | ||
380 | static int tda10023_get_property(struct dvb_frontend *fe, | ||
381 | struct dtv_property *p) | ||
382 | { | ||
383 | switch (p->cmd) { | ||
384 | case DTV_ENUM_DELSYS: | ||
385 | p->u.buffer.data[0] = SYS_DVBC_ANNEX_A; | ||
386 | p->u.buffer.data[1] = SYS_DVBC_ANNEX_C; | ||
387 | p->u.buffer.len = 2; | ||
388 | break; | ||
389 | default: | ||
390 | break; | ||
391 | } | ||
338 | return 0; | 392 | return 0; |
339 | } | 393 | } |
340 | 394 | ||
@@ -557,7 +611,7 @@ static struct dvb_frontend_ops tda10023_ops = { | |||
557 | 611 | ||
558 | .set_frontend = tda10023_set_parameters, | 612 | .set_frontend = tda10023_set_parameters, |
559 | .get_frontend = tda10023_get_frontend, | 613 | .get_frontend = tda10023_get_frontend, |
560 | 614 | .get_property = tda10023_get_property, | |
561 | .read_status = tda10023_read_status, | 615 | .read_status = tda10023_read_status, |
562 | .read_ber = tda10023_read_ber, | 616 | .read_ber = tda10023_read_ber, |
563 | .read_signal_strength = tda10023_read_signal_strength, | 617 | .read_signal_strength = tda10023_read_signal_strength, |
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c index 1b1bf200c55c..0f8e9622bc96 100644 --- a/drivers/media/dvb/frontends/tda18271c2dd.c +++ b/drivers/media/dvb/frontends/tda18271c2dd.c | |||
@@ -1123,20 +1123,6 @@ static int release(struct dvb_frontend *fe) | |||
1123 | return 0; | 1123 | return 0; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | /* | ||
1127 | * As defined on EN 300 429 Annex A and on ITU-T J.83 annex A, the DVB-C | ||
1128 | * roll-off factor is 0.15. | ||
1129 | * According with the specs, the amount of the needed bandwith is given by: | ||
1130 | * Bw = Symbol_rate * (1 + 0.15) | ||
1131 | * As such, the maximum symbol rate supported by 6 MHz is | ||
1132 | * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds | ||
1133 | *NOTE: For ITU-T J.83 Annex C, the roll-off factor is 0.13. So: | ||
1134 | * max_symbol_rate = 6 MHz / 1.13 = 5309735 Baud | ||
1135 | * That means that an adjustment is needed for Japan, | ||
1136 | * but, as currently DRX-K is hardcoded to Annex A, let's stick | ||
1137 | * with 0.15 roll-off factor. | ||
1138 | */ | ||
1139 | #define MAX_SYMBOL_RATE_6MHz 5217391 | ||
1140 | 1126 | ||
1141 | static int set_params(struct dvb_frontend *fe, | 1127 | static int set_params(struct dvb_frontend *fe, |
1142 | struct dvb_frontend_parameters *params) | 1128 | struct dvb_frontend_parameters *params) |
@@ -1144,34 +1130,44 @@ static int set_params(struct dvb_frontend *fe, | |||
1144 | struct tda_state *state = fe->tuner_priv; | 1130 | struct tda_state *state = fe->tuner_priv; |
1145 | int status = 0; | 1131 | int status = 0; |
1146 | int Standard; | 1132 | int Standard; |
1133 | u32 bw = fe->dtv_property_cache.bandwidth_hz; | ||
1134 | u32 delsys = fe->dtv_property_cache.delivery_system; | ||
1147 | 1135 | ||
1148 | state->m_Frequency = params->frequency; | 1136 | state->m_Frequency = fe->dtv_property_cache.frequency; |
1149 | 1137 | ||
1150 | if (fe->ops.info.type == FE_OFDM) | 1138 | switch (delsys) { |
1151 | switch (params->u.ofdm.bandwidth) { | 1139 | case SYS_DVBT: |
1152 | case BANDWIDTH_6_MHZ: | 1140 | case SYS_DVBT2: |
1141 | switch (bw) { | ||
1142 | case 6000000: | ||
1153 | Standard = HF_DVBT_6MHZ; | 1143 | Standard = HF_DVBT_6MHZ; |
1154 | break; | 1144 | break; |
1155 | case BANDWIDTH_7_MHZ: | 1145 | case 7000000: |
1156 | Standard = HF_DVBT_7MHZ; | 1146 | Standard = HF_DVBT_7MHZ; |
1157 | break; | 1147 | break; |
1158 | default: | 1148 | case 8000000: |
1159 | case BANDWIDTH_8_MHZ: | ||
1160 | Standard = HF_DVBT_8MHZ; | 1149 | Standard = HF_DVBT_8MHZ; |
1161 | break; | 1150 | break; |
1151 | default: | ||
1152 | return -EINVAL; | ||
1162 | } | 1153 | } |
1163 | else if (fe->ops.info.type == FE_QAM) { | 1154 | case SYS_DVBC_ANNEX_A: |
1164 | if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) | 1155 | case SYS_DVBC_ANNEX_C: |
1156 | if (bw <= 6000000) | ||
1165 | Standard = HF_DVBC_6MHZ; | 1157 | Standard = HF_DVBC_6MHZ; |
1158 | else if (bw <= 7000000) | ||
1159 | Standard = HF_DVBC_7MHZ; | ||
1166 | else | 1160 | else |
1167 | Standard = HF_DVBC_8MHZ; | 1161 | Standard = HF_DVBC_8MHZ; |
1168 | } else | 1162 | default: |
1169 | return -EINVAL; | 1163 | return -EINVAL; |
1164 | } | ||
1170 | do { | 1165 | do { |
1171 | status = RFTrackingFiltersCorrection(state, params->frequency); | 1166 | status = RFTrackingFiltersCorrection(state, state->m_Frequency); |
1172 | if (status < 0) | 1167 | if (status < 0) |
1173 | break; | 1168 | break; |
1174 | status = ChannelConfiguration(state, params->frequency, Standard); | 1169 | status = ChannelConfiguration(state, state->m_Frequency, |
1170 | Standard); | ||
1175 | if (status < 0) | 1171 | if (status < 0) |
1176 | break; | 1172 | break; |
1177 | 1173 | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 3d20719fce1a..abf6b55cf6d5 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -991,7 +991,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) | |||
991 | 991 | ||
992 | if (feed->type == DMX_TYPE_TS) { | 992 | if (feed->type == DMX_TYPE_TS) { |
993 | if ((feed->ts_type & TS_DECODER) && | 993 | if ((feed->ts_type & TS_DECODER) && |
994 | (feed->pes_type < DMX_TS_PES_OTHER)) { | 994 | (feed->pes_type <= DMX_TS_PES_PCR)) { |
995 | switch (demux->dmx.frontend->source) { | 995 | switch (demux->dmx.frontend->source) { |
996 | case DMX_MEMORY_FE: | 996 | case DMX_MEMORY_FE: |
997 | if (feed->ts_type & TS_DECODER) | 997 | if (feed->ts_type & TS_DECODER) |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index ca02e9722172..ab180f99fde6 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -193,7 +193,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
193 | dev->input_phys = budget_ci->ir.phys; | 193 | dev->input_phys = budget_ci->ir.phys; |
194 | dev->input_id.bustype = BUS_PCI; | 194 | dev->input_id.bustype = BUS_PCI; |
195 | dev->input_id.version = 1; | 195 | dev->input_id.version = 1; |
196 | dev->scanmask = 0xff; | ||
197 | if (saa->pci->subsystem_vendor) { | 196 | if (saa->pci->subsystem_vendor) { |
198 | dev->input_id.vendor = saa->pci->subsystem_vendor; | 197 | dev->input_id.vendor = saa->pci->subsystem_vendor; |
199 | dev->input_id.product = saa->pci->subsystem_device; | 198 | dev->input_id.product = saa->pci->subsystem_device; |
@@ -234,6 +233,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
234 | dev->map_name = RC_MAP_BUDGET_CI_OLD; | 233 | dev->map_name = RC_MAP_BUDGET_CI_OLD; |
235 | break; | 234 | break; |
236 | } | 235 | } |
236 | if (!budget_ci->ir.full_rc5) | ||
237 | dev->scanmask = 0xff; | ||
237 | 238 | ||
238 | error = rc_register_device(dev); | 239 | error = rc_register_device(dev); |
239 | if (error) { | 240 | if (error) { |
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 6edc9ba81203..6f9eb94e85b3 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c | |||
@@ -108,8 +108,7 @@ static long media_device_enum_entities(struct media_device *mdev, | |||
108 | u_ent.group_id = ent->group_id; | 108 | u_ent.group_id = ent->group_id; |
109 | u_ent.pads = ent->num_pads; | 109 | u_ent.pads = ent->num_pads; |
110 | u_ent.links = ent->num_links - ent->num_backlinks; | 110 | u_ent.links = ent->num_links - ent->num_backlinks; |
111 | u_ent.v4l.major = ent->v4l.major; | 111 | memcpy(&u_ent.raw, &ent->info, sizeof(ent->info)); |
112 | u_ent.v4l.minor = ent->v4l.minor; | ||
113 | if (copy_to_user(uent, &u_ent, sizeof(u_ent))) | 112 | if (copy_to_user(uent, &u_ent, sizeof(u_ent))) |
114 | return -EFAULT; | 113 | return -EFAULT; |
115 | return 0; | 114 | return 0; |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index ccd5f0d8a012..e954781c90bf 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -11,6 +11,162 @@ menuconfig RADIO_ADAPTERS | |||
11 | 11 | ||
12 | if RADIO_ADAPTERS && VIDEO_V4L2 | 12 | if RADIO_ADAPTERS && VIDEO_V4L2 |
13 | 13 | ||
14 | config RADIO_SI470X | ||
15 | bool "Silicon Labs Si470x FM Radio Receiver support" | ||
16 | depends on VIDEO_V4L2 | ||
17 | |||
18 | source "drivers/media/radio/si470x/Kconfig" | ||
19 | |||
20 | config USB_MR800 | ||
21 | tristate "AverMedia MR 800 USB FM radio support" | ||
22 | depends on USB && VIDEO_V4L2 | ||
23 | ---help--- | ||
24 | Say Y here if you want to connect this type of radio to your | ||
25 | computer's USB port. Note that the audio is not digital, and | ||
26 | you must connect the line out connector to a sound card or a | ||
27 | set of speakers. | ||
28 | |||
29 | To compile this driver as a module, choose M here: the | ||
30 | module will be called radio-mr800. | ||
31 | |||
32 | config USB_DSBR | ||
33 | tristate "D-Link/GemTek USB FM radio support" | ||
34 | depends on USB && VIDEO_V4L2 | ||
35 | ---help--- | ||
36 | Say Y here if you want to connect this type of radio to your | ||
37 | computer's USB port. Note that the audio is not digital, and | ||
38 | you must connect the line out connector to a sound card or a | ||
39 | set of speakers. | ||
40 | |||
41 | To compile this driver as a module, choose M here: the | ||
42 | module will be called dsbr100. | ||
43 | |||
44 | config RADIO_MAXIRADIO | ||
45 | tristate "Guillemot MAXI Radio FM 2000 radio" | ||
46 | depends on VIDEO_V4L2 && PCI | ||
47 | ---help--- | ||
48 | Choose Y here if you have this radio card. This card may also be | ||
49 | found as Gemtek PCI FM. | ||
50 | |||
51 | In order to control your radio card, you will need to use programs | ||
52 | that are compatible with the Video For Linux API. Information on | ||
53 | this API and pointers to "v4l" programs may be found at | ||
54 | <file:Documentation/video4linux/API.html>. | ||
55 | |||
56 | To compile this driver as a module, choose M here: the | ||
57 | module will be called radio-maxiradio. | ||
58 | |||
59 | |||
60 | config I2C_SI4713 | ||
61 | tristate "I2C driver for Silicon Labs Si4713 device" | ||
62 | depends on I2C && VIDEO_V4L2 | ||
63 | ---help--- | ||
64 | Say Y here if you want support to Si4713 I2C device. | ||
65 | This device driver supports only i2c bus. | ||
66 | |||
67 | To compile this driver as a module, choose M here: the | ||
68 | module will be called si4713. | ||
69 | |||
70 | config RADIO_SI4713 | ||
71 | tristate "Silicon Labs Si4713 FM Radio Transmitter support" | ||
72 | depends on I2C && VIDEO_V4L2 | ||
73 | select I2C_SI4713 | ||
74 | ---help--- | ||
75 | Say Y here if you want support to Si4713 FM Radio Transmitter. | ||
76 | This device can transmit audio through FM. It can transmit | ||
77 | RDS and RBDS signals as well. This module is the v4l2 radio | ||
78 | interface for the i2c driver of this device. | ||
79 | |||
80 | To compile this driver as a module, choose M here: the | ||
81 | module will be called radio-si4713. | ||
82 | |||
83 | config RADIO_TEA5764 | ||
84 | tristate "TEA5764 I2C FM radio support" | ||
85 | depends on I2C && VIDEO_V4L2 | ||
86 | ---help--- | ||
87 | Say Y here if you want to use the TEA5764 FM chip found in | ||
88 | EZX phones. This FM chip is present in EZX phones from Motorola, | ||
89 | connected to internal pxa I2C bus. | ||
90 | |||
91 | To compile this driver as a module, choose M here: the | ||
92 | module will be called radio-tea5764. | ||
93 | |||
94 | config RADIO_TEA5764_XTAL | ||
95 | bool "TEA5764 crystal reference" | ||
96 | depends on RADIO_TEA5764=y | ||
97 | default y | ||
98 | help | ||
99 | Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N | ||
100 | here if TEA5764 reference frequency is connected in FREQIN. | ||
101 | |||
102 | config RADIO_SAA7706H | ||
103 | tristate "SAA7706H Car Radio DSP" | ||
104 | depends on I2C && VIDEO_V4L2 | ||
105 | ---help--- | ||
106 | Say Y here if you want to use the SAA7706H Car radio Digital | ||
107 | Signal Processor, found for instance on the Russellville development | ||
108 | board. On the russellville the device is connected to internal | ||
109 | timberdale I2C bus. | ||
110 | |||
111 | To compile this driver as a module, choose M here: the | ||
112 | module will be called SAA7706H. | ||
113 | |||
114 | config RADIO_TEF6862 | ||
115 | tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" | ||
116 | depends on I2C && VIDEO_V4L2 | ||
117 | ---help--- | ||
118 | Say Y here if you want to use the TEF6862 Car Radio Enhanced | ||
119 | Selectivity Tuner, found for instance on the Russellville development | ||
120 | board. On the russellville the device is connected to internal | ||
121 | timberdale I2C bus. | ||
122 | |||
123 | To compile this driver as a module, choose M here: the | ||
124 | module will be called TEF6862. | ||
125 | |||
126 | config RADIO_TIMBERDALE | ||
127 | tristate "Enable the Timberdale radio driver" | ||
128 | depends on MFD_TIMBERDALE && VIDEO_V4L2 | ||
129 | depends on I2C # for RADIO_SAA7706H | ||
130 | select RADIO_TEF6862 | ||
131 | select RADIO_SAA7706H | ||
132 | ---help--- | ||
133 | This is a kind of umbrella driver for the Radio Tuner and DSP | ||
134 | found behind the Timberdale FPGA on the Russellville board. | ||
135 | Enabling this driver will automatically select the DSP and tuner. | ||
136 | |||
137 | config RADIO_WL1273 | ||
138 | tristate "Texas Instruments WL1273 I2C FM Radio" | ||
139 | depends on I2C && VIDEO_V4L2 | ||
140 | select MFD_CORE | ||
141 | select MFD_WL1273_CORE | ||
142 | select FW_LOADER | ||
143 | ---help--- | ||
144 | Choose Y here if you have this FM radio chip. | ||
145 | |||
146 | In order to control your radio card, you will need to use programs | ||
147 | that are compatible with the Video For Linux 2 API. Information on | ||
148 | this API and pointers to "v4l2" programs may be found at | ||
149 | <file:Documentation/video4linux/API.html>. | ||
150 | |||
151 | To compile this driver as a module, choose M here: the | ||
152 | module will be called radio-wl1273. | ||
153 | |||
154 | # TI's ST based wl128x FM radio | ||
155 | source "drivers/media/radio/wl128x/Kconfig" | ||
156 | |||
157 | # | ||
158 | # ISA drivers configuration | ||
159 | # | ||
160 | |||
161 | menuconfig V4L_RADIO_ISA_DRIVERS | ||
162 | bool "ISA radio devices" | ||
163 | depends on ISA | ||
164 | default n | ||
165 | ---help--- | ||
166 | Say Y here to enable support for these ISA drivers. | ||
167 | |||
168 | if V4L_RADIO_ISA_DRIVERS | ||
169 | |||
14 | config RADIO_CADET | 170 | config RADIO_CADET |
15 | tristate "ADS Cadet AM/FM Tuner" | 171 | tristate "ADS Cadet AM/FM Tuner" |
16 | depends on ISA && VIDEO_V4L2 | 172 | depends on ISA && VIDEO_V4L2 |
@@ -151,21 +307,6 @@ config RADIO_GEMTEK_PROBE | |||
151 | following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and | 307 | following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and |
152 | 0x28c. | 308 | 0x28c. |
153 | 309 | ||
154 | config RADIO_MAXIRADIO | ||
155 | tristate "Guillemot MAXI Radio FM 2000 radio" | ||
156 | depends on VIDEO_V4L2 && PCI | ||
157 | ---help--- | ||
158 | Choose Y here if you have this radio card. This card may also be | ||
159 | found as Gemtek PCI FM. | ||
160 | |||
161 | In order to control your radio card, you will need to use programs | ||
162 | that are compatible with the Video For Linux API. Information on | ||
163 | this API and pointers to "v4l" programs may be found at | ||
164 | <file:Documentation/video4linux/API.html>. | ||
165 | |||
166 | To compile this driver as a module, choose M here: the | ||
167 | module will be called radio-maxiradio. | ||
168 | |||
169 | config RADIO_MIROPCM20 | 310 | config RADIO_MIROPCM20 |
170 | tristate "miroSOUND PCM20 radio" | 311 | tristate "miroSOUND PCM20 radio" |
171 | depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND | 312 | depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND |
@@ -316,130 +457,6 @@ config RADIO_ZOLTRIX_PORT | |||
316 | help | 457 | help |
317 | Enter the I/O port of your Zoltrix radio card. | 458 | Enter the I/O port of your Zoltrix radio card. |
318 | 459 | ||
319 | config I2C_SI4713 | 460 | endif # V4L_RADIO_ISA_DRIVERS |
320 | tristate "I2C driver for Silicon Labs Si4713 device" | ||
321 | depends on I2C && VIDEO_V4L2 | ||
322 | ---help--- | ||
323 | Say Y here if you want support to Si4713 I2C device. | ||
324 | This device driver supports only i2c bus. | ||
325 | |||
326 | To compile this driver as a module, choose M here: the | ||
327 | module will be called si4713. | ||
328 | |||
329 | config RADIO_SI4713 | ||
330 | tristate "Silicon Labs Si4713 FM Radio Transmitter support" | ||
331 | depends on I2C && VIDEO_V4L2 | ||
332 | select I2C_SI4713 | ||
333 | ---help--- | ||
334 | Say Y here if you want support to Si4713 FM Radio Transmitter. | ||
335 | This device can transmit audio through FM. It can transmit | ||
336 | RDS and RBDS signals as well. This module is the v4l2 radio | ||
337 | interface for the i2c driver of this device. | ||
338 | |||
339 | To compile this driver as a module, choose M here: the | ||
340 | module will be called radio-si4713. | ||
341 | |||
342 | config USB_DSBR | ||
343 | tristate "D-Link/GemTek USB FM radio support" | ||
344 | depends on USB && VIDEO_V4L2 | ||
345 | ---help--- | ||
346 | Say Y here if you want to connect this type of radio to your | ||
347 | computer's USB port. Note that the audio is not digital, and | ||
348 | you must connect the line out connector to a sound card or a | ||
349 | set of speakers. | ||
350 | |||
351 | To compile this driver as a module, choose M here: the | ||
352 | module will be called dsbr100. | ||
353 | |||
354 | config RADIO_SI470X | ||
355 | bool "Silicon Labs Si470x FM Radio Receiver support" | ||
356 | depends on VIDEO_V4L2 | ||
357 | |||
358 | source "drivers/media/radio/si470x/Kconfig" | ||
359 | |||
360 | config USB_MR800 | ||
361 | tristate "AverMedia MR 800 USB FM radio support" | ||
362 | depends on USB && VIDEO_V4L2 | ||
363 | ---help--- | ||
364 | Say Y here if you want to connect this type of radio to your | ||
365 | computer's USB port. Note that the audio is not digital, and | ||
366 | you must connect the line out connector to a sound card or a | ||
367 | set of speakers. | ||
368 | |||
369 | To compile this driver as a module, choose M here: the | ||
370 | module will be called radio-mr800. | ||
371 | |||
372 | config RADIO_TEA5764 | ||
373 | tristate "TEA5764 I2C FM radio support" | ||
374 | depends on I2C && VIDEO_V4L2 | ||
375 | ---help--- | ||
376 | Say Y here if you want to use the TEA5764 FM chip found in | ||
377 | EZX phones. This FM chip is present in EZX phones from Motorola, | ||
378 | connected to internal pxa I2C bus. | ||
379 | |||
380 | To compile this driver as a module, choose M here: the | ||
381 | module will be called radio-tea5764. | ||
382 | |||
383 | config RADIO_TEA5764_XTAL | ||
384 | bool "TEA5764 crystal reference" | ||
385 | depends on RADIO_TEA5764=y | ||
386 | default y | ||
387 | help | ||
388 | Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N | ||
389 | here if TEA5764 reference frequency is connected in FREQIN. | ||
390 | |||
391 | config RADIO_SAA7706H | ||
392 | tristate "SAA7706H Car Radio DSP" | ||
393 | depends on I2C && VIDEO_V4L2 | ||
394 | ---help--- | ||
395 | Say Y here if you want to use the SAA7706H Car radio Digital | ||
396 | Signal Processor, found for instance on the Russellville development | ||
397 | board. On the russellville the device is connected to internal | ||
398 | timberdale I2C bus. | ||
399 | |||
400 | To compile this driver as a module, choose M here: the | ||
401 | module will be called SAA7706H. | ||
402 | |||
403 | config RADIO_TEF6862 | ||
404 | tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" | ||
405 | depends on I2C && VIDEO_V4L2 | ||
406 | ---help--- | ||
407 | Say Y here if you want to use the TEF6862 Car Radio Enhanced | ||
408 | Selectivity Tuner, found for instance on the Russellville development | ||
409 | board. On the russellville the device is connected to internal | ||
410 | timberdale I2C bus. | ||
411 | |||
412 | To compile this driver as a module, choose M here: the | ||
413 | module will be called TEF6862. | ||
414 | |||
415 | config RADIO_TIMBERDALE | ||
416 | tristate "Enable the Timberdale radio driver" | ||
417 | depends on MFD_TIMBERDALE && VIDEO_V4L2 | ||
418 | depends on I2C # for RADIO_SAA7706H | ||
419 | select RADIO_TEF6862 | ||
420 | select RADIO_SAA7706H | ||
421 | ---help--- | ||
422 | This is a kind of umbrella driver for the Radio Tuner and DSP | ||
423 | found behind the Timberdale FPGA on the Russellville board. | ||
424 | Enabling this driver will automatically select the DSP and tuner. | ||
425 | |||
426 | config RADIO_WL1273 | ||
427 | tristate "Texas Instruments WL1273 I2C FM Radio" | ||
428 | depends on I2C && VIDEO_V4L2 | ||
429 | select MFD_WL1273_CORE | ||
430 | select FW_LOADER | ||
431 | ---help--- | ||
432 | Choose Y here if you have this FM radio chip. | ||
433 | |||
434 | In order to control your radio card, you will need to use programs | ||
435 | that are compatible with the Video For Linux 2 API. Information on | ||
436 | this API and pointers to "v4l2" programs may be found at | ||
437 | <file:Documentation/video4linux/API.html>. | ||
438 | |||
439 | To compile this driver as a module, choose M here: the | ||
440 | module will be called radio-wl1273. | ||
441 | |||
442 | # TI's ST based wl128x FM radio | ||
443 | source "drivers/media/radio/wl128x/Kconfig" | ||
444 | 461 | ||
445 | endif # RADIO_ADAPTERS | 462 | endif # RADIO_ADAPTERS |
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index 0991e1973678..3408685b690c 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c | |||
@@ -118,9 +118,11 @@ static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | |||
118 | i2cmsg[2] = pll & 0xff; | 118 | i2cmsg[2] = pll & 0xff; |
119 | 119 | ||
120 | err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg)); | 120 | err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg)); |
121 | if (!err) | 121 | if (err != sizeof(i2cmsg)) |
122 | state->freq = f->frequency; | 122 | return err < 0 ? err : -EIO; |
123 | return err; | 123 | |
124 | state->freq = f->frequency; | ||
125 | return 0; | ||
124 | } | 126 | } |
125 | 127 | ||
126 | static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | 128 | static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) |
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c index 4f5c43d2566c..077d369a0173 100644 --- a/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c | |||
@@ -84,6 +84,7 @@ static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf, | |||
84 | struct fmdev *fmdev; | 84 | struct fmdev *fmdev; |
85 | 85 | ||
86 | ret = copy_from_user(&rds, buf, sizeof(rds)); | 86 | ret = copy_from_user(&rds, buf, sizeof(rds)); |
87 | rds.text[sizeof(rds.text) - 1] = '\0'; | ||
87 | fmdbg("(%d)type: %d, text %s, af %d\n", | 88 | fmdbg("(%d)type: %d, text %s, af %d\n", |
88 | ret, rds.text_type, rds.text, rds.af_freq); | 89 | ret, rds.text_type, rds.text, rds.af_freq); |
89 | if (ret) | 90 | if (ret) |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index aeb7f43dfb65..4df4affeea5f 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -87,6 +87,16 @@ config IR_RC5_SZ_DECODER | |||
87 | uses an IR protocol that is almost standard RC-5, but not quite, | 87 | uses an IR protocol that is almost standard RC-5, but not quite, |
88 | as it uses an additional bit). | 88 | as it uses an additional bit). |
89 | 89 | ||
90 | config IR_SANYO_DECODER | ||
91 | tristate "Enable IR raw decoder for the Sanyo protocol" | ||
92 | depends on RC_CORE | ||
93 | default y | ||
94 | |||
95 | ---help--- | ||
96 | Enable this option if you have an infrared remote control which | ||
97 | uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes), | ||
98 | and you need software decoding support. | ||
99 | |||
90 | config IR_MCE_KBD_DECODER | 100 | config IR_MCE_KBD_DECODER |
91 | tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" | 101 | tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" |
92 | depends on RC_CORE | 102 | depends on RC_CORE |
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 2156e786b557..fb3dee2dd845 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o | |||
10 | obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o | 10 | obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o |
11 | obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o | 11 | obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o |
12 | obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o | 12 | obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o |
13 | obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o | ||
13 | obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o | 14 | obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o |
14 | obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o | 15 | obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o |
15 | 16 | ||
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 17f8db00435a..3c9431a9f62d 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c | |||
@@ -194,8 +194,8 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", | 197 | IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n", |
198 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 198 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
199 | data->state = STATE_INACTIVE; | 199 | data->state = STATE_INACTIVE; |
200 | return -EINVAL; | 200 | return -EINVAL; |
201 | } | 201 | } |
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 2e5cd3100b64..95e630998aaf 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c | |||
@@ -357,6 +357,7 @@ static void init_decoders(struct work_struct *work) | |||
357 | load_rc6_decode(); | 357 | load_rc6_decode(); |
358 | load_jvc_decode(); | 358 | load_jvc_decode(); |
359 | load_sony_decode(); | 359 | load_sony_decode(); |
360 | load_sanyo_decode(); | ||
360 | load_mce_kbd_decode(); | 361 | load_mce_kbd_decode(); |
361 | load_lirc_codec(); | 362 | load_lirc_codec(); |
362 | 363 | ||
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 140fb67e2f89..4cfdd7fa4bbd 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c | |||
@@ -18,24 +18,31 @@ | |||
18 | /* | 18 | /* |
19 | * This decoder currently supports: | 19 | * This decoder currently supports: |
20 | * RC6-0-16 (standard toggle bit in header) | 20 | * RC6-0-16 (standard toggle bit in header) |
21 | * RC6-6A-20 (no toggle bit) | ||
21 | * RC6-6A-24 (no toggle bit) | 22 | * RC6-6A-24 (no toggle bit) |
22 | * RC6-6A-32 (MCE version with toggle bit in body) | 23 | * RC6-6A-32 (MCE version with toggle bit in body) |
23 | */ | 24 | */ |
24 | 25 | ||
25 | #define RC6_UNIT 444444 /* us */ | 26 | #define RC6_UNIT 444444 /* nanosecs */ |
26 | #define RC6_HEADER_NBITS 4 /* not including toggle bit */ | 27 | #define RC6_HEADER_NBITS 4 /* not including toggle bit */ |
27 | #define RC6_0_NBITS 16 | 28 | #define RC6_0_NBITS 16 |
28 | #define RC6_6A_SMALL_NBITS 24 | 29 | #define RC6_6A_32_NBITS 32 |
29 | #define RC6_6A_LARGE_NBITS 32 | 30 | #define RC6_6A_NBITS 128 /* Variable 8..128 */ |
30 | #define RC6_PREFIX_PULSE (6 * RC6_UNIT) | 31 | #define RC6_PREFIX_PULSE (6 * RC6_UNIT) |
31 | #define RC6_PREFIX_SPACE (2 * RC6_UNIT) | 32 | #define RC6_PREFIX_SPACE (2 * RC6_UNIT) |
32 | #define RC6_BIT_START (1 * RC6_UNIT) | 33 | #define RC6_BIT_START (1 * RC6_UNIT) |
33 | #define RC6_BIT_END (1 * RC6_UNIT) | 34 | #define RC6_BIT_END (1 * RC6_UNIT) |
34 | #define RC6_TOGGLE_START (2 * RC6_UNIT) | 35 | #define RC6_TOGGLE_START (2 * RC6_UNIT) |
35 | #define RC6_TOGGLE_END (2 * RC6_UNIT) | 36 | #define RC6_TOGGLE_END (2 * RC6_UNIT) |
37 | #define RC6_SUFFIX_SPACE (6 * RC6_UNIT) | ||
36 | #define RC6_MODE_MASK 0x07 /* for the header bits */ | 38 | #define RC6_MODE_MASK 0x07 /* for the header bits */ |
37 | #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ | 39 | #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ |
38 | #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ | 40 | #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ |
41 | #define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */ | ||
42 | #define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */ | ||
43 | #ifndef CHAR_BIT | ||
44 | #define CHAR_BIT 8 /* Normally in <limits.h> */ | ||
45 | #endif | ||
39 | 46 | ||
40 | enum rc6_mode { | 47 | enum rc6_mode { |
41 | RC6_MODE_0, | 48 | RC6_MODE_0, |
@@ -125,6 +132,7 @@ again: | |||
125 | break; | 132 | break; |
126 | 133 | ||
127 | data->state = STATE_HEADER_BIT_START; | 134 | data->state = STATE_HEADER_BIT_START; |
135 | data->header = 0; | ||
128 | return 0; | 136 | return 0; |
129 | 137 | ||
130 | case STATE_HEADER_BIT_START: | 138 | case STATE_HEADER_BIT_START: |
@@ -171,20 +179,14 @@ again: | |||
171 | data->state = STATE_BODY_BIT_START; | 179 | data->state = STATE_BODY_BIT_START; |
172 | decrease_duration(&ev, RC6_TOGGLE_END); | 180 | decrease_duration(&ev, RC6_TOGGLE_END); |
173 | data->count = 0; | 181 | data->count = 0; |
182 | data->body = 0; | ||
174 | 183 | ||
175 | switch (rc6_mode(data)) { | 184 | switch (rc6_mode(data)) { |
176 | case RC6_MODE_0: | 185 | case RC6_MODE_0: |
177 | data->wanted_bits = RC6_0_NBITS; | 186 | data->wanted_bits = RC6_0_NBITS; |
178 | break; | 187 | break; |
179 | case RC6_MODE_6A: | 188 | case RC6_MODE_6A: |
180 | /* This might look weird, but we basically | 189 | data->wanted_bits = RC6_6A_NBITS; |
181 | check the value of the first body bit to | ||
182 | determine the number of bits in mode 6A */ | ||
183 | if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) || | ||
184 | geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) | ||
185 | data->wanted_bits = RC6_6A_LARGE_NBITS; | ||
186 | else | ||
187 | data->wanted_bits = RC6_6A_SMALL_NBITS; | ||
188 | break; | 190 | break; |
189 | default: | 191 | default: |
190 | IR_dprintk(1, "RC6 unknown mode\n"); | 192 | IR_dprintk(1, "RC6 unknown mode\n"); |
@@ -193,15 +195,21 @@ again: | |||
193 | goto again; | 195 | goto again; |
194 | 196 | ||
195 | case STATE_BODY_BIT_START: | 197 | case STATE_BODY_BIT_START: |
196 | if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) | 198 | if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { |
197 | break; | 199 | /* Discard LSB's that won't fit in data->body */ |
198 | 200 | if (data->count++ < CHAR_BIT * sizeof data->body) { | |
199 | data->body <<= 1; | 201 | data->body <<= 1; |
200 | if (ev.pulse) | 202 | if (ev.pulse) |
201 | data->body |= 1; | 203 | data->body |= 1; |
202 | data->count++; | 204 | } |
203 | data->state = STATE_BODY_BIT_END; | 205 | data->state = STATE_BODY_BIT_END; |
204 | return 0; | 206 | return 0; |
207 | } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && | ||
208 | geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { | ||
209 | data->state = STATE_FINISHED; | ||
210 | goto again; | ||
211 | } | ||
212 | break; | ||
205 | 213 | ||
206 | case STATE_BODY_BIT_END: | 214 | case STATE_BODY_BIT_END: |
207 | if (!is_transition(&ev, &dev->raw->prev_ev)) | 215 | if (!is_transition(&ev, &dev->raw->prev_ev)) |
@@ -221,20 +229,27 @@ again: | |||
221 | 229 | ||
222 | switch (rc6_mode(data)) { | 230 | switch (rc6_mode(data)) { |
223 | case RC6_MODE_0: | 231 | case RC6_MODE_0: |
224 | scancode = data->body & 0xffff; | 232 | scancode = data->body; |
225 | toggle = data->toggle; | 233 | toggle = data->toggle; |
226 | IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", | 234 | IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", |
227 | scancode, toggle); | 235 | scancode, toggle); |
228 | break; | 236 | break; |
229 | case RC6_MODE_6A: | 237 | case RC6_MODE_6A: |
230 | if (data->wanted_bits == RC6_6A_LARGE_NBITS) { | 238 | if (data->count > CHAR_BIT * sizeof data->body) { |
231 | toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0; | 239 | IR_dprintk(1, "RC6 too many (%u) data bits\n", |
232 | scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK; | 240 | data->count); |
241 | goto out; | ||
242 | } | ||
243 | |||
244 | scancode = data->body; | ||
245 | if (data->count == RC6_6A_32_NBITS && | ||
246 | (scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { | ||
247 | /* MCE RC */ | ||
248 | toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0; | ||
249 | scancode &= ~RC6_6A_MCE_TOGGLE_MASK; | ||
233 | } else { | 250 | } else { |
234 | toggle = 0; | 251 | toggle = 0; |
235 | scancode = data->body & 0xffffff; | ||
236 | } | 252 | } |
237 | |||
238 | IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", | 253 | IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", |
239 | scancode, toggle); | 254 | scancode, toggle); |
240 | break; | 255 | break; |
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c new file mode 100644 index 000000000000..d38fbdd0b25a --- /dev/null +++ b/drivers/media/rc/ir-sanyo-decoder.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol | ||
2 | * | ||
3 | * Copyright (C) 2011 by Mauro Carvalho Chehab <mchehab@redhat.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * This protocol uses the NEC protocol timings. However, data is formatted as: | ||
15 | * 13 bits Custom Code | ||
16 | * 13 bits NOT(Custom Code) | ||
17 | * 8 bits Key data | ||
18 | * 8 bits NOT(Key data) | ||
19 | * | ||
20 | * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon | ||
21 | * Information for this protocol is available at the Sanyo LC7461 datasheet. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/bitrev.h> | ||
26 | #include "rc-core-priv.h" | ||
27 | |||
28 | #define SANYO_NBITS (13+13+8+8) | ||
29 | #define SANYO_UNIT 562500 /* ns */ | ||
30 | #define SANYO_HEADER_PULSE (16 * SANYO_UNIT) | ||
31 | #define SANYO_HEADER_SPACE (8 * SANYO_UNIT) | ||
32 | #define SANYO_BIT_PULSE (1 * SANYO_UNIT) | ||
33 | #define SANYO_BIT_0_SPACE (1 * SANYO_UNIT) | ||
34 | #define SANYO_BIT_1_SPACE (3 * SANYO_UNIT) | ||
35 | #define SANYO_REPEAT_SPACE (150 * SANYO_UNIT) | ||
36 | #define SANYO_TRAILER_PULSE (1 * SANYO_UNIT) | ||
37 | #define SANYO_TRAILER_SPACE (10 * SANYO_UNIT) /* in fact, 42 */ | ||
38 | |||
39 | enum sanyo_state { | ||
40 | STATE_INACTIVE, | ||
41 | STATE_HEADER_SPACE, | ||
42 | STATE_BIT_PULSE, | ||
43 | STATE_BIT_SPACE, | ||
44 | STATE_TRAILER_PULSE, | ||
45 | STATE_TRAILER_SPACE, | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * ir_sanyo_decode() - Decode one SANYO pulse or space | ||
50 | * @dev: the struct rc_dev descriptor of the device | ||
51 | * @duration: the struct ir_raw_event descriptor of the pulse/space | ||
52 | * | ||
53 | * This function returns -EINVAL if the pulse violates the state machine | ||
54 | */ | ||
55 | static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) | ||
56 | { | ||
57 | struct sanyo_dec *data = &dev->raw->sanyo; | ||
58 | u32 scancode; | ||
59 | u8 address, not_address, command, not_command; | ||
60 | |||
61 | if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO)) | ||
62 | return 0; | ||
63 | |||
64 | if (!is_timing_event(ev)) { | ||
65 | if (ev.reset) { | ||
66 | IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); | ||
67 | data->state = STATE_INACTIVE; | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n", | ||
73 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | ||
74 | |||
75 | switch (data->state) { | ||
76 | |||
77 | case STATE_INACTIVE: | ||
78 | if (!ev.pulse) | ||
79 | break; | ||
80 | |||
81 | if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) { | ||
82 | data->count = 0; | ||
83 | data->state = STATE_HEADER_SPACE; | ||
84 | return 0; | ||
85 | } | ||
86 | break; | ||
87 | |||
88 | |||
89 | case STATE_HEADER_SPACE: | ||
90 | if (ev.pulse) | ||
91 | break; | ||
92 | |||
93 | if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) { | ||
94 | data->state = STATE_BIT_PULSE; | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | break; | ||
99 | |||
100 | case STATE_BIT_PULSE: | ||
101 | if (!ev.pulse) | ||
102 | break; | ||
103 | |||
104 | if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2)) | ||
105 | break; | ||
106 | |||
107 | data->state = STATE_BIT_SPACE; | ||
108 | return 0; | ||
109 | |||
110 | case STATE_BIT_SPACE: | ||
111 | if (ev.pulse) | ||
112 | break; | ||
113 | |||
114 | if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { | ||
115 | if (!dev->keypressed) { | ||
116 | IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n"); | ||
117 | } else { | ||
118 | rc_repeat(dev); | ||
119 | IR_dprintk(1, "SANYO repeat last key\n"); | ||
120 | data->state = STATE_INACTIVE; | ||
121 | } | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | data->bits <<= 1; | ||
126 | if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2)) | ||
127 | data->bits |= 1; | ||
128 | else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2)) | ||
129 | break; | ||
130 | data->count++; | ||
131 | |||
132 | if (data->count == SANYO_NBITS) | ||
133 | data->state = STATE_TRAILER_PULSE; | ||
134 | else | ||
135 | data->state = STATE_BIT_PULSE; | ||
136 | |||
137 | return 0; | ||
138 | |||
139 | case STATE_TRAILER_PULSE: | ||
140 | if (!ev.pulse) | ||
141 | break; | ||
142 | |||
143 | if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2)) | ||
144 | break; | ||
145 | |||
146 | data->state = STATE_TRAILER_SPACE; | ||
147 | return 0; | ||
148 | |||
149 | case STATE_TRAILER_SPACE: | ||
150 | if (ev.pulse) | ||
151 | break; | ||
152 | |||
153 | if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2)) | ||
154 | break; | ||
155 | |||
156 | address = bitrev16((data->bits >> 29) & 0x1fff) >> 3; | ||
157 | not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; | ||
158 | command = bitrev8((data->bits >> 8) & 0xff); | ||
159 | not_command = bitrev8((data->bits >> 0) & 0xff); | ||
160 | |||
161 | if ((command ^ not_command) != 0xff) { | ||
162 | IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n", | ||
163 | data->bits); | ||
164 | data->state = STATE_INACTIVE; | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | scancode = address << 8 | command; | ||
169 | IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); | ||
170 | rc_keydown(dev, scancode, 0); | ||
171 | data->state = STATE_INACTIVE; | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n", | ||
176 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | ||
177 | data->state = STATE_INACTIVE; | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | static struct ir_raw_handler sanyo_handler = { | ||
182 | .protocols = RC_TYPE_SANYO, | ||
183 | .decode = ir_sanyo_decode, | ||
184 | }; | ||
185 | |||
186 | static int __init ir_sanyo_decode_init(void) | ||
187 | { | ||
188 | ir_raw_handler_register(&sanyo_handler); | ||
189 | |||
190 | printk(KERN_INFO "IR SANYO protocol handler initialized\n"); | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static void __exit ir_sanyo_decode_exit(void) | ||
195 | { | ||
196 | ir_raw_handler_unregister(&sanyo_handler); | ||
197 | } | ||
198 | |||
199 | module_init(ir_sanyo_decode_init); | ||
200 | module_exit(ir_sanyo_decode_exit); | ||
201 | |||
202 | MODULE_LICENSE("GPL"); | ||
203 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
204 | MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | ||
205 | MODULE_DESCRIPTION("SANYO IR protocol decoder"); | ||
diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c index e51c6163378b..929bbbc16393 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge.c +++ b/drivers/media/rc/keymaps/rc-hauppauge.c | |||
@@ -183,6 +183,57 @@ static struct rc_map_table rc5_hauppauge_new[] = { | |||
183 | { 0x1d3f, KEY_HOME }, | 183 | { 0x1d3f, KEY_HOME }, |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * Keycodes for PT# R-005 remote bundled with Haupauge HVR-930C | ||
187 | * Keycodes start with address = 0x1c | ||
188 | */ | ||
189 | { 0x1c3b, KEY_GOTO }, | ||
190 | { 0x1c3d, KEY_POWER }, | ||
191 | |||
192 | { 0x1c14, KEY_UP }, | ||
193 | { 0x1c15, KEY_DOWN }, | ||
194 | { 0x1c16, KEY_LEFT }, | ||
195 | { 0x1c17, KEY_RIGHT }, | ||
196 | { 0x1c25, KEY_OK }, | ||
197 | |||
198 | { 0x1c00, KEY_0 }, | ||
199 | { 0x1c01, KEY_1 }, | ||
200 | { 0x1c02, KEY_2 }, | ||
201 | { 0x1c03, KEY_3 }, | ||
202 | { 0x1c04, KEY_4 }, | ||
203 | { 0x1c05, KEY_5 }, | ||
204 | { 0x1c06, KEY_6 }, | ||
205 | { 0x1c07, KEY_7 }, | ||
206 | { 0x1c08, KEY_8 }, | ||
207 | { 0x1c09, KEY_9 }, | ||
208 | |||
209 | { 0x1c1f, KEY_EXIT }, /* BACK */ | ||
210 | { 0x1c0d, KEY_MENU }, | ||
211 | { 0x1c1c, KEY_TV }, | ||
212 | |||
213 | { 0x1c10, KEY_VOLUMEUP }, | ||
214 | { 0x1c11, KEY_VOLUMEDOWN }, | ||
215 | |||
216 | { 0x1c20, KEY_CHANNELUP }, | ||
217 | { 0x1c21, KEY_CHANNELDOWN }, | ||
218 | |||
219 | { 0x1c0f, KEY_MUTE }, | ||
220 | { 0x1c12, KEY_PREVIOUS }, /* Prev */ | ||
221 | |||
222 | { 0x1c36, KEY_STOP }, | ||
223 | { 0x1c37, KEY_RECORD }, | ||
224 | |||
225 | { 0x1c24, KEY_LAST }, /* <| */ | ||
226 | { 0x1c1e, KEY_NEXT }, /* >| */ | ||
227 | |||
228 | { 0x1c0a, KEY_TEXT }, | ||
229 | { 0x1c0e, KEY_SUBTITLE }, /* CC */ | ||
230 | |||
231 | { 0x1c32, KEY_REWIND }, | ||
232 | { 0x1c30, KEY_PAUSE }, | ||
233 | { 0x1c35, KEY_PLAY }, | ||
234 | { 0x1c34, KEY_FASTFORWARD }, | ||
235 | |||
236 | /* | ||
186 | * Keycodes for the old Black Remote Controller | 237 | * Keycodes for the old Black Remote Controller |
187 | * This one also uses RC-5 protocol | 238 | * This one also uses RC-5 protocol |
188 | * Keycodes start with address = 0x00 | 239 | * Keycodes start with address = 0x00 |
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index c6ca870e8b7e..b72f8580e317 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h | |||
@@ -84,6 +84,11 @@ struct ir_raw_event_ctrl { | |||
84 | unsigned count; | 84 | unsigned count; |
85 | unsigned wanted_bits; | 85 | unsigned wanted_bits; |
86 | } rc5_sz; | 86 | } rc5_sz; |
87 | struct sanyo_dec { | ||
88 | int state; | ||
89 | unsigned count; | ||
90 | u64 bits; | ||
91 | } sanyo; | ||
87 | struct mce_kbd_dec { | 92 | struct mce_kbd_dec { |
88 | struct input_dev *idev; | 93 | struct input_dev *idev; |
89 | struct timer_list rx_timeout; | 94 | struct timer_list rx_timeout; |
@@ -193,6 +198,13 @@ static inline void load_jvc_decode(void) { } | |||
193 | static inline void load_sony_decode(void) { } | 198 | static inline void load_sony_decode(void) { } |
194 | #endif | 199 | #endif |
195 | 200 | ||
201 | /* from ir-sanyo-decoder.c */ | ||
202 | #ifdef CONFIG_IR_SANYO_DECODER_MODULE | ||
203 | #define load_sanyo_decode() request_module("ir-sanyo-decoder") | ||
204 | #else | ||
205 | static inline void load_sanyo_decode(void) { } | ||
206 | #endif | ||
207 | |||
196 | /* from ir-mce_kbd-decoder.c */ | 208 | /* from ir-mce_kbd-decoder.c */ |
197 | #ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE | 209 | #ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE |
198 | #define load_mce_kbd_decode() request_module("ir-mce_kbd-decoder") | 210 | #define load_mce_kbd_decode() request_module("ir-mce_kbd-decoder") |
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 29f900065d8a..0ea55ea2b71d 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -736,6 +736,7 @@ static struct { | |||
736 | { RC_TYPE_JVC, "jvc" }, | 736 | { RC_TYPE_JVC, "jvc" }, |
737 | { RC_TYPE_SONY, "sony" }, | 737 | { RC_TYPE_SONY, "sony" }, |
738 | { RC_TYPE_RC5_SZ, "rc-5-sz" }, | 738 | { RC_TYPE_RC5_SZ, "rc-5-sz" }, |
739 | { RC_TYPE_SANYO, "sanyo" }, | ||
739 | { RC_TYPE_MCE_KBD, "mce_kbd" }, | 740 | { RC_TYPE_MCE_KBD, "mce_kbd" }, |
740 | { RC_TYPE_LIRC, "lirc" }, | 741 | { RC_TYPE_LIRC, "lirc" }, |
741 | { RC_TYPE_OTHER, "other" }, | 742 | { RC_TYPE_OTHER, "other" }, |
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 61287fcca61a..9bff23cb0a5b 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c | |||
@@ -286,12 +286,6 @@ static void redrat3_issue_async(struct redrat3_dev *rr3) | |||
286 | 286 | ||
287 | rr3_ftr(rr3->dev, "Entering %s\n", __func__); | 287 | rr3_ftr(rr3->dev, "Entering %s\n", __func__); |
288 | 288 | ||
289 | if (!rr3->det_enabled) { | ||
290 | dev_warn(rr3->dev, "not issuing async read, " | ||
291 | "detector not enabled\n"); | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize); | 289 | memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize); |
296 | res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC); | 290 | res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC); |
297 | if (res) | 291 | if (res) |
@@ -827,6 +821,7 @@ out: | |||
827 | static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) | 821 | static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) |
828 | { | 822 | { |
829 | struct redrat3_dev *rr3; | 823 | struct redrat3_dev *rr3; |
824 | int ret; | ||
830 | 825 | ||
831 | if (!urb) | 826 | if (!urb) |
832 | return; | 827 | return; |
@@ -840,15 +835,13 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) | |||
840 | 835 | ||
841 | rr3_ftr(rr3->dev, "Entering %s\n", __func__); | 836 | rr3_ftr(rr3->dev, "Entering %s\n", __func__); |
842 | 837 | ||
843 | if (!rr3->det_enabled) { | ||
844 | rr3_dbg(rr3->dev, "received a read callback but detector " | ||
845 | "disabled - ignoring\n"); | ||
846 | return; | ||
847 | } | ||
848 | |||
849 | switch (urb->status) { | 838 | switch (urb->status) { |
850 | case 0: | 839 | case 0: |
851 | redrat3_get_ir_data(rr3, urb->actual_length); | 840 | ret = redrat3_get_ir_data(rr3, urb->actual_length); |
841 | if (!ret) { | ||
842 | /* no error, prepare to read more */ | ||
843 | redrat3_issue_async(rr3); | ||
844 | } | ||
852 | break; | 845 | break; |
853 | 846 | ||
854 | case -ECONNRESET: | 847 | case -ECONNRESET: |
@@ -865,11 +858,6 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) | |||
865 | rr3->pkttype = 0; | 858 | rr3->pkttype = 0; |
866 | break; | 859 | break; |
867 | } | 860 | } |
868 | |||
869 | if (!rr3->transmitting) | ||
870 | redrat3_issue_async(rr3); | ||
871 | else | ||
872 | rr3_dbg(rr3->dev, "IR transmit in progress\n"); | ||
873 | } | 861 | } |
874 | 862 | ||
875 | static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | 863 | static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) |
@@ -896,21 +884,24 @@ static u16 mod_freq_to_val(unsigned int mod_freq) | |||
896 | return (u16)(65536 - (mult / mod_freq)); | 884 | return (u16)(65536 - (mult / mod_freq)); |
897 | } | 885 | } |
898 | 886 | ||
899 | static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier) | 887 | static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier) |
900 | { | 888 | { |
901 | struct redrat3_dev *rr3 = dev->priv; | 889 | struct redrat3_dev *rr3 = rcdev->priv; |
890 | struct device *dev = rr3->dev; | ||
902 | 891 | ||
892 | rr3_dbg(dev, "Setting modulation frequency to %u", carrier); | ||
903 | rr3->carrier = carrier; | 893 | rr3->carrier = carrier; |
904 | 894 | ||
905 | return carrier; | 895 | return carrier; |
906 | } | 896 | } |
907 | 897 | ||
908 | static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) | 898 | static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, |
899 | unsigned count) | ||
909 | { | 900 | { |
910 | struct redrat3_dev *rr3 = rcdev->priv; | 901 | struct redrat3_dev *rr3 = rcdev->priv; |
911 | struct device *dev = rr3->dev; | 902 | struct device *dev = rr3->dev; |
912 | struct redrat3_signal_header header; | 903 | struct redrat3_signal_header header; |
913 | int i, j, count, ret, ret_len, offset; | 904 | int i, j, ret, ret_len, offset; |
914 | int lencheck, cur_sample_len, pipe; | 905 | int lencheck, cur_sample_len, pipe; |
915 | char *buffer = NULL, *sigdata = NULL; | 906 | char *buffer = NULL, *sigdata = NULL; |
916 | int *sample_lens = NULL; | 907 | int *sample_lens = NULL; |
@@ -928,20 +919,13 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) | |||
928 | return -EAGAIN; | 919 | return -EAGAIN; |
929 | } | 920 | } |
930 | 921 | ||
931 | count = n / sizeof(int); | ||
932 | if (count > (RR3_DRIVER_MAXLENS * 2)) | 922 | if (count > (RR3_DRIVER_MAXLENS * 2)) |
933 | return -EINVAL; | 923 | return -EINVAL; |
934 | 924 | ||
925 | /* rr3 will disable rc detector on transmit */ | ||
926 | rr3->det_enabled = false; | ||
935 | rr3->transmitting = true; | 927 | rr3->transmitting = true; |
936 | 928 | ||
937 | redrat3_disable_detector(rr3); | ||
938 | |||
939 | if (rr3->det_enabled) { | ||
940 | dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__); | ||
941 | ret = -EIO; | ||
942 | goto out; | ||
943 | } | ||
944 | |||
945 | sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); | 929 | sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); |
946 | if (!sample_lens) { | 930 | if (!sample_lens) { |
947 | ret = -ENOMEM; | 931 | ret = -ENOMEM; |
@@ -1055,7 +1039,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) | |||
1055 | if (ret < 0) | 1039 | if (ret < 0) |
1056 | dev_err(dev, "Error: control msg send failed, rc %d\n", ret); | 1040 | dev_err(dev, "Error: control msg send failed, rc %d\n", ret); |
1057 | else | 1041 | else |
1058 | ret = n; | 1042 | ret = count; |
1059 | 1043 | ||
1060 | out: | 1044 | out: |
1061 | kfree(sample_lens); | 1045 | kfree(sample_lens); |
@@ -1063,8 +1047,8 @@ out: | |||
1063 | kfree(sigdata); | 1047 | kfree(sigdata); |
1064 | 1048 | ||
1065 | rr3->transmitting = false; | 1049 | rr3->transmitting = false; |
1066 | 1050 | /* rr3 re-enables rc detector because it was enabled before */ | |
1067 | redrat3_enable_detector(rr3); | 1051 | rr3->det_enabled = true; |
1068 | 1052 | ||
1069 | return ret; | 1053 | return ret; |
1070 | } | 1054 | } |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index b303a3f8a9f8..0e4d241fc6e6 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -533,6 +533,13 @@ config VIDEO_ADP1653 | |||
533 | This is a driver for the ADP1653 flash controller. It is used for | 533 | This is a driver for the ADP1653 flash controller. It is used for |
534 | example in Nokia N900. | 534 | example in Nokia N900. |
535 | 535 | ||
536 | config VIDEO_AS3645A | ||
537 | tristate "AS3645A flash driver support" | ||
538 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
539 | ---help--- | ||
540 | This is a driver for the AS3645A and LM3555 flash controllers. It has | ||
541 | build in control for flash, torch and indicator LEDs. | ||
542 | |||
536 | comment "Video improvement chips" | 543 | comment "Video improvement chips" |
537 | 544 | ||
538 | config VIDEO_UPD64031A | 545 | config VIDEO_UPD64031A |
@@ -580,25 +587,6 @@ config VIDEO_M52790 | |||
580 | 587 | ||
581 | endmenu # encoder / decoder chips | 588 | endmenu # encoder / decoder chips |
582 | 589 | ||
583 | config VIDEO_SH_VOU | ||
584 | tristate "SuperH VOU video output driver" | ||
585 | depends on VIDEO_DEV && ARCH_SHMOBILE | ||
586 | select VIDEOBUF_DMA_CONTIG | ||
587 | help | ||
588 | Support for the Video Output Unit (VOU) on SuperH SoCs. | ||
589 | |||
590 | config VIDEO_VIU | ||
591 | tristate "Freescale VIU Video Driver" | ||
592 | depends on VIDEO_V4L2 && PPC_MPC512x | ||
593 | select VIDEOBUF_DMA_CONTIG | ||
594 | default y | ||
595 | ---help--- | ||
596 | Support for Freescale VIU video driver. This device captures | ||
597 | video data, or overlays video on DIU frame buffer. | ||
598 | |||
599 | Say Y here if you want to enable VIU device on MPC5121e Rev2+. | ||
600 | In doubt, say N. | ||
601 | |||
602 | config VIDEO_VIVI | 590 | config VIDEO_VIVI |
603 | tristate "Virtual Video Driver" | 591 | tristate "Virtual Video Driver" |
604 | depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 | 592 | depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 |
@@ -613,66 +601,130 @@ config VIDEO_VIVI | |||
613 | Say Y here if you want to test video apps or debug V4L devices. | 601 | Say Y here if you want to test video apps or debug V4L devices. |
614 | In doubt, say N. | 602 | In doubt, say N. |
615 | 603 | ||
616 | source "drivers/media/video/davinci/Kconfig" | 604 | # |
605 | # USB Multimedia device configuration | ||
606 | # | ||
617 | 607 | ||
618 | source "drivers/media/video/omap/Kconfig" | 608 | menuconfig V4L_USB_DRIVERS |
609 | bool "V4L USB devices" | ||
610 | depends on USB | ||
611 | default y | ||
619 | 612 | ||
620 | source "drivers/media/video/bt8xx/Kconfig" | 613 | if V4L_USB_DRIVERS |
621 | 614 | ||
622 | config VIDEO_PMS | 615 | source "drivers/media/video/uvc/Kconfig" |
623 | tristate "Mediavision Pro Movie Studio Video For Linux" | 616 | |
624 | depends on ISA && VIDEO_V4L2 | 617 | source "drivers/media/video/gspca/Kconfig" |
625 | help | 618 | |
626 | Say Y if you have such a thing. | 619 | source "drivers/media/video/pvrusb2/Kconfig" |
620 | |||
621 | source "drivers/media/video/hdpvr/Kconfig" | ||
622 | |||
623 | source "drivers/media/video/em28xx/Kconfig" | ||
624 | |||
625 | source "drivers/media/video/tlg2300/Kconfig" | ||
626 | |||
627 | source "drivers/media/video/cx231xx/Kconfig" | ||
628 | |||
629 | source "drivers/media/video/tm6000/Kconfig" | ||
630 | |||
631 | source "drivers/media/video/usbvision/Kconfig" | ||
632 | |||
633 | source "drivers/media/video/et61x251/Kconfig" | ||
634 | |||
635 | source "drivers/media/video/sn9c102/Kconfig" | ||
636 | |||
637 | source "drivers/media/video/pwc/Kconfig" | ||
638 | |||
639 | source "drivers/media/video/cpia2/Kconfig" | ||
640 | |||
641 | config USB_ZR364XX | ||
642 | tristate "USB ZR364XX Camera support" | ||
643 | depends on VIDEO_V4L2 | ||
644 | select VIDEOBUF_GEN | ||
645 | select VIDEOBUF_VMALLOC | ||
646 | ---help--- | ||
647 | Say Y here if you want to connect this type of camera to your | ||
648 | computer's USB port. | ||
649 | See <file:Documentation/video4linux/zr364xx.txt> for more info | ||
650 | and list of supported cameras. | ||
627 | 651 | ||
628 | To compile this driver as a module, choose M here: the | 652 | To compile this driver as a module, choose M here: the |
629 | module will be called pms. | 653 | module will be called zr364xx. |
630 | 654 | ||
631 | config VIDEO_BWQCAM | 655 | config USB_STKWEBCAM |
632 | tristate "Quickcam BW Video For Linux" | 656 | tristate "USB Syntek DC1125 Camera support" |
633 | depends on PARPORT && VIDEO_V4L2 | 657 | depends on VIDEO_V4L2 && EXPERIMENTAL |
634 | help | 658 | ---help--- |
635 | Say Y have if you the black and white version of the QuickCam | 659 | Say Y here if you want to use this type of camera. |
636 | camera. See the next option for the color version. | 660 | Supported devices are typically found in some Asus laptops, |
661 | with USB id 174f:a311 and 05e1:0501. Other Syntek cameras | ||
662 | may be supported by the stk11xx driver, from which this is | ||
663 | derived, see <http://sourceforge.net/projects/syntekdriver/> | ||
637 | 664 | ||
638 | To compile this driver as a module, choose M here: the | 665 | To compile this driver as a module, choose M here: the |
639 | module will be called bw-qcam. | 666 | module will be called stkwebcam. |
640 | 667 | ||
641 | config VIDEO_CQCAM | 668 | config USB_S2255 |
642 | tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" | 669 | tristate "USB Sensoray 2255 video capture device" |
643 | depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2 | 670 | depends on VIDEO_V4L2 |
671 | select VIDEOBUF_VMALLOC | ||
672 | default n | ||
644 | help | 673 | help |
645 | This is the video4linux driver for the colour version of the | 674 | Say Y here if you want support for the Sensoray 2255 USB device. |
646 | Connectix QuickCam. If you have one of these cameras, say Y here, | 675 | This driver can be compiled as a module, called s2255drv. |
647 | otherwise say N. This driver does not work with the original | ||
648 | monochrome QuickCam, QuickCam VC or QuickClip. It is also available | ||
649 | as a module (c-qcam). | ||
650 | Read <file:Documentation/video4linux/CQcam.txt> for more information. | ||
651 | 676 | ||
652 | config VIDEO_W9966 | 677 | endif # V4L_USB_DRIVERS |
653 | tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" | ||
654 | depends on PARPORT_1284 && PARPORT && VIDEO_V4L2 | ||
655 | help | ||
656 | Video4linux driver for Winbond's w9966 based Webcams. | ||
657 | Currently tested with the LifeView FlyCam Supra. | ||
658 | If you have one of these cameras, say Y here | ||
659 | otherwise say N. | ||
660 | This driver is also available as a module (w9966). | ||
661 | 678 | ||
662 | Check out <file:Documentation/video4linux/w9966.txt> for more | 679 | # |
663 | information. | 680 | # PCI drivers configuration |
681 | # | ||
664 | 682 | ||
665 | source "drivers/media/video/cpia2/Kconfig" | 683 | menuconfig V4L_PCI_DRIVERS |
684 | bool "V4L PCI(e) devices" | ||
685 | depends on PCI | ||
686 | default y | ||
687 | ---help--- | ||
688 | Say Y here to enable support for these PCI(e) drivers. | ||
666 | 689 | ||
667 | config VIDEO_VINO | 690 | if V4L_PCI_DRIVERS |
668 | tristate "SGI Vino Video For Linux (EXPERIMENTAL)" | ||
669 | depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 | ||
670 | select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO | ||
671 | help | ||
672 | Say Y here to build in support for the Vino video input system found | ||
673 | on SGI Indy machines. | ||
674 | 691 | ||
675 | source "drivers/media/video/zoran/Kconfig" | 692 | source "drivers/media/video/au0828/Kconfig" |
693 | |||
694 | source "drivers/media/video/bt8xx/Kconfig" | ||
695 | |||
696 | source "drivers/media/video/cx18/Kconfig" | ||
697 | |||
698 | source "drivers/media/video/cx23885/Kconfig" | ||
699 | |||
700 | source "drivers/media/video/cx25821/Kconfig" | ||
701 | |||
702 | source "drivers/media/video/cx88/Kconfig" | ||
703 | |||
704 | config VIDEO_HEXIUM_GEMINI | ||
705 | tristate "Hexium Gemini frame grabber" | ||
706 | depends on PCI && VIDEO_V4L2 && I2C | ||
707 | select VIDEO_SAA7146_VV | ||
708 | ---help--- | ||
709 | This is a video4linux driver for the Hexium Gemini frame | ||
710 | grabber card by Hexium. Please note that the Gemini Dual | ||
711 | card is *not* fully supported. | ||
712 | |||
713 | To compile this driver as a module, choose M here: the | ||
714 | module will be called hexium_gemini. | ||
715 | |||
716 | config VIDEO_HEXIUM_ORION | ||
717 | tristate "Hexium HV-PCI6 and Orion frame grabber" | ||
718 | depends on PCI && VIDEO_V4L2 && I2C | ||
719 | select VIDEO_SAA7146_VV | ||
720 | ---help--- | ||
721 | This is a video4linux driver for the Hexium HV-PCI6 and | ||
722 | Orion frame grabber cards by Hexium. | ||
723 | |||
724 | To compile this driver as a module, choose M here: the | ||
725 | module will be called hexium_orion. | ||
726 | |||
727 | source "drivers/media/video/ivtv/Kconfig" | ||
676 | 728 | ||
677 | config VIDEO_MEYE | 729 | config VIDEO_MEYE |
678 | tristate "Sony Vaio Picturebook Motion Eye Video For Linux" | 730 | tristate "Sony Vaio Picturebook Motion Eye Video For Linux" |
@@ -688,8 +740,6 @@ config VIDEO_MEYE | |||
688 | To compile this driver as a module, choose M here: the | 740 | To compile this driver as a module, choose M here: the |
689 | module will be called meye. | 741 | module will be called meye. |
690 | 742 | ||
691 | source "drivers/media/video/saa7134/Kconfig" | ||
692 | |||
693 | config VIDEO_MXB | 743 | config VIDEO_MXB |
694 | tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" | 744 | tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" |
695 | depends on PCI && VIDEO_V4L2 && I2C | 745 | depends on PCI && VIDEO_V4L2 && I2C |
@@ -706,28 +756,119 @@ config VIDEO_MXB | |||
706 | To compile this driver as a module, choose M here: the | 756 | To compile this driver as a module, choose M here: the |
707 | module will be called mxb. | 757 | module will be called mxb. |
708 | 758 | ||
709 | config VIDEO_HEXIUM_ORION | 759 | source "drivers/media/video/saa7134/Kconfig" |
710 | tristate "Hexium HV-PCI6 and Orion frame grabber" | 760 | |
711 | depends on PCI && VIDEO_V4L2 && I2C | 761 | source "drivers/media/video/saa7164/Kconfig" |
712 | select VIDEO_SAA7146_VV | 762 | |
763 | source "drivers/media/video/zoran/Kconfig" | ||
764 | |||
765 | endif # V4L_PCI_DRIVERS | ||
766 | |||
767 | # | ||
768 | # ISA & parallel port drivers configuration | ||
769 | # | ||
770 | |||
771 | menuconfig V4L_ISA_PARPORT_DRIVERS | ||
772 | bool "V4L ISA and parallel port devices" | ||
773 | depends on ISA || PARPORT | ||
774 | default n | ||
713 | ---help--- | 775 | ---help--- |
714 | This is a video4linux driver for the Hexium HV-PCI6 and | 776 | Say Y here to enable support for these ISA and parallel port drivers. |
715 | Orion frame grabber cards by Hexium. | 777 | |
778 | if V4L_ISA_PARPORT_DRIVERS | ||
779 | |||
780 | config VIDEO_BWQCAM | ||
781 | tristate "Quickcam BW Video For Linux" | ||
782 | depends on PARPORT && VIDEO_V4L2 | ||
783 | help | ||
784 | Say Y have if you the black and white version of the QuickCam | ||
785 | camera. See the next option for the color version. | ||
716 | 786 | ||
717 | To compile this driver as a module, choose M here: the | 787 | To compile this driver as a module, choose M here: the |
718 | module will be called hexium_orion. | 788 | module will be called bw-qcam. |
719 | 789 | ||
720 | config VIDEO_HEXIUM_GEMINI | 790 | config VIDEO_CQCAM |
721 | tristate "Hexium Gemini frame grabber" | 791 | tristate "QuickCam Colour Video For Linux" |
722 | depends on PCI && VIDEO_V4L2 && I2C | 792 | depends on PARPORT && VIDEO_V4L2 |
723 | select VIDEO_SAA7146_VV | 793 | help |
724 | ---help--- | 794 | This is the video4linux driver for the colour version of the |
725 | This is a video4linux driver for the Hexium Gemini frame | 795 | Connectix QuickCam. If you have one of these cameras, say Y here, |
726 | grabber card by Hexium. Please note that the Gemini Dual | 796 | otherwise say N. This driver does not work with the original |
727 | card is *not* fully supported. | 797 | monochrome QuickCam, QuickCam VC or QuickClip. It is also available |
798 | as a module (c-qcam). | ||
799 | Read <file:Documentation/video4linux/CQcam.txt> for more information. | ||
800 | |||
801 | config VIDEO_PMS | ||
802 | tristate "Mediavision Pro Movie Studio Video For Linux" | ||
803 | depends on ISA && VIDEO_V4L2 | ||
804 | help | ||
805 | Say Y if you have the ISA Mediavision Pro Movie Studio | ||
806 | capture card. | ||
728 | 807 | ||
729 | To compile this driver as a module, choose M here: the | 808 | To compile this driver as a module, choose M here: the |
730 | module will be called hexium_gemini. | 809 | module will be called pms. |
810 | |||
811 | config VIDEO_W9966 | ||
812 | tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" | ||
813 | depends on PARPORT_1284 && PARPORT && VIDEO_V4L2 | ||
814 | help | ||
815 | Video4linux driver for Winbond's w9966 based Webcams. | ||
816 | Currently tested with the LifeView FlyCam Supra. | ||
817 | If you have one of these cameras, say Y here | ||
818 | otherwise say N. | ||
819 | This driver is also available as a module (w9966). | ||
820 | |||
821 | Check out <file:Documentation/video4linux/w9966.txt> for more | ||
822 | information. | ||
823 | |||
824 | endif # V4L_ISA_PARPORT_DRIVERS | ||
825 | |||
826 | menuconfig V4L_PLATFORM_DRIVERS | ||
827 | bool "V4L platform devices" | ||
828 | default n | ||
829 | ---help--- | ||
830 | Say Y here to enable support for platform-specific V4L drivers. | ||
831 | |||
832 | if V4L_PLATFORM_DRIVERS | ||
833 | |||
834 | source "drivers/media/video/marvell-ccic/Kconfig" | ||
835 | |||
836 | config VIDEO_VIA_CAMERA | ||
837 | tristate "VIAFB camera controller support" | ||
838 | depends on FB_VIA | ||
839 | select VIDEOBUF_DMA_SG | ||
840 | select VIDEO_OV7670 | ||
841 | help | ||
842 | Driver support for the integrated camera controller in VIA | ||
843 | Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems | ||
844 | with ov7670 sensors. | ||
845 | |||
846 | # | ||
847 | # Platform multimedia device configuration | ||
848 | # | ||
849 | |||
850 | source "drivers/media/video/davinci/Kconfig" | ||
851 | |||
852 | source "drivers/media/video/omap/Kconfig" | ||
853 | |||
854 | config VIDEO_SH_VOU | ||
855 | tristate "SuperH VOU video output driver" | ||
856 | depends on VIDEO_DEV && ARCH_SHMOBILE | ||
857 | select VIDEOBUF_DMA_CONTIG | ||
858 | help | ||
859 | Support for the Video Output Unit (VOU) on SuperH SoCs. | ||
860 | |||
861 | config VIDEO_VIU | ||
862 | tristate "Freescale VIU Video Driver" | ||
863 | depends on VIDEO_V4L2 && PPC_MPC512x | ||
864 | select VIDEOBUF_DMA_CONTIG | ||
865 | default y | ||
866 | ---help--- | ||
867 | Support for Freescale VIU video driver. This device captures | ||
868 | video data, or overlays video on DIU frame buffer. | ||
869 | |||
870 | Say Y here if you want to enable VIU device on MPC5121e Rev2+. | ||
871 | In doubt, say N. | ||
731 | 872 | ||
732 | config VIDEO_TIMBERDALE | 873 | config VIDEO_TIMBERDALE |
733 | tristate "Support for timberdale Video In/LogiWIN" | 874 | tristate "Support for timberdale Video In/LogiWIN" |
@@ -739,21 +880,13 @@ config VIDEO_TIMBERDALE | |||
739 | ---help--- | 880 | ---help--- |
740 | Add support for the Video In peripherial of the timberdale FPGA. | 881 | Add support for the Video In peripherial of the timberdale FPGA. |
741 | 882 | ||
742 | source "drivers/media/video/cx88/Kconfig" | 883 | config VIDEO_VINO |
743 | 884 | tristate "SGI Vino Video For Linux" | |
744 | source "drivers/media/video/cx23885/Kconfig" | 885 | depends on I2C && SGI_IP22 && VIDEO_V4L2 |
745 | 886 | select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO | |
746 | source "drivers/media/video/cx25821/Kconfig" | 887 | help |
747 | 888 | Say Y here to build in support for the Vino video input system found | |
748 | source "drivers/media/video/au0828/Kconfig" | 889 | on SGI Indy machines. |
749 | |||
750 | source "drivers/media/video/ivtv/Kconfig" | ||
751 | |||
752 | source "drivers/media/video/cx18/Kconfig" | ||
753 | |||
754 | source "drivers/media/video/saa7164/Kconfig" | ||
755 | |||
756 | source "drivers/media/video/marvell-ccic/Kconfig" | ||
757 | 890 | ||
758 | config VIDEO_M32R_AR | 891 | config VIDEO_M32R_AR |
759 | tristate "AR devices" | 892 | tristate "AR devices" |
@@ -774,16 +907,6 @@ config VIDEO_M32R_AR_M64278 | |||
774 | To compile this driver as a module, choose M here: the | 907 | To compile this driver as a module, choose M here: the |
775 | module will be called arv. | 908 | module will be called arv. |
776 | 909 | ||
777 | config VIDEO_VIA_CAMERA | ||
778 | tristate "VIAFB camera controller support" | ||
779 | depends on FB_VIA | ||
780 | select VIDEOBUF_DMA_SG | ||
781 | select VIDEO_OV7670 | ||
782 | help | ||
783 | Driver support for the integrated camera controller in VIA | ||
784 | Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems | ||
785 | with ov7670 sensors. | ||
786 | |||
787 | config VIDEO_OMAP3 | 910 | config VIDEO_OMAP3 |
788 | tristate "OMAP 3 Camera support (EXPERIMENTAL)" | 911 | tristate "OMAP 3 Camera support (EXPERIMENTAL)" |
789 | depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL | 912 | depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL |
@@ -1002,78 +1125,7 @@ config VIDEO_S5P_MIPI_CSIS | |||
1002 | 1125 | ||
1003 | source "drivers/media/video/s5p-tv/Kconfig" | 1126 | source "drivers/media/video/s5p-tv/Kconfig" |
1004 | 1127 | ||
1005 | # | 1128 | endif # V4L_PLATFORM_DRIVERS |
1006 | # USB Multimedia device configuration | ||
1007 | # | ||
1008 | |||
1009 | menuconfig V4L_USB_DRIVERS | ||
1010 | bool "V4L USB devices" | ||
1011 | depends on USB | ||
1012 | default y | ||
1013 | |||
1014 | if V4L_USB_DRIVERS && USB | ||
1015 | |||
1016 | source "drivers/media/video/uvc/Kconfig" | ||
1017 | |||
1018 | source "drivers/media/video/gspca/Kconfig" | ||
1019 | |||
1020 | source "drivers/media/video/pvrusb2/Kconfig" | ||
1021 | |||
1022 | source "drivers/media/video/hdpvr/Kconfig" | ||
1023 | |||
1024 | source "drivers/media/video/em28xx/Kconfig" | ||
1025 | |||
1026 | source "drivers/media/video/tlg2300/Kconfig" | ||
1027 | |||
1028 | source "drivers/media/video/cx231xx/Kconfig" | ||
1029 | |||
1030 | source "drivers/media/video/tm6000/Kconfig" | ||
1031 | |||
1032 | source "drivers/media/video/usbvision/Kconfig" | ||
1033 | |||
1034 | source "drivers/media/video/et61x251/Kconfig" | ||
1035 | |||
1036 | source "drivers/media/video/sn9c102/Kconfig" | ||
1037 | |||
1038 | source "drivers/media/video/pwc/Kconfig" | ||
1039 | |||
1040 | config USB_ZR364XX | ||
1041 | tristate "USB ZR364XX Camera support" | ||
1042 | depends on VIDEO_V4L2 | ||
1043 | select VIDEOBUF_GEN | ||
1044 | select VIDEOBUF_VMALLOC | ||
1045 | ---help--- | ||
1046 | Say Y here if you want to connect this type of camera to your | ||
1047 | computer's USB port. | ||
1048 | See <file:Documentation/video4linux/zr364xx.txt> for more info | ||
1049 | and list of supported cameras. | ||
1050 | |||
1051 | To compile this driver as a module, choose M here: the | ||
1052 | module will be called zr364xx. | ||
1053 | |||
1054 | config USB_STKWEBCAM | ||
1055 | tristate "USB Syntek DC1125 Camera support" | ||
1056 | depends on VIDEO_V4L2 && EXPERIMENTAL | ||
1057 | ---help--- | ||
1058 | Say Y here if you want to use this type of camera. | ||
1059 | Supported devices are typically found in some Asus laptops, | ||
1060 | with USB id 174f:a311 and 05e1:0501. Other Syntek cameras | ||
1061 | may be supported by the stk11xx driver, from which this is | ||
1062 | derived, see <http://sourceforge.net/projects/syntekdriver/> | ||
1063 | |||
1064 | To compile this driver as a module, choose M here: the | ||
1065 | module will be called stkwebcam. | ||
1066 | |||
1067 | config USB_S2255 | ||
1068 | tristate "USB Sensoray 2255 video capture device" | ||
1069 | depends on VIDEO_V4L2 | ||
1070 | select VIDEOBUF_VMALLOC | ||
1071 | default n | ||
1072 | help | ||
1073 | Say Y here if you want support for the Sensoray 2255 USB device. | ||
1074 | This driver can be compiled as a module, called s2255drv. | ||
1075 | |||
1076 | endif # V4L_USB_DRIVERS | ||
1077 | endif # VIDEO_CAPTURE_DRIVERS | 1129 | endif # VIDEO_CAPTURE_DRIVERS |
1078 | 1130 | ||
1079 | menuconfig V4L_MEM2MEM_DRIVERS | 1131 | menuconfig V4L_MEM2MEM_DRIVERS |
@@ -1098,6 +1150,15 @@ config VIDEO_MEM2MEM_TESTDEV | |||
1098 | This is a virtual test device for the memory-to-memory driver | 1150 | This is a virtual test device for the memory-to-memory driver |
1099 | framework. | 1151 | framework. |
1100 | 1152 | ||
1153 | config VIDEO_SAMSUNG_S5P_G2D | ||
1154 | tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver" | ||
1155 | depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P | ||
1156 | select VIDEOBUF2_DMA_CONTIG | ||
1157 | select V4L2_MEM2MEM_DEV | ||
1158 | default n | ||
1159 | ---help--- | ||
1160 | This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D | ||
1161 | 2d graphics accelerator. | ||
1101 | 1162 | ||
1102 | config VIDEO_SAMSUNG_S5P_MFC | 1163 | config VIDEO_SAMSUNG_S5P_MFC |
1103 | tristate "Samsung S5P MFC 5.1 Video Codec" | 1164 | tristate "Samsung S5P MFC 5.1 Video Codec" |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 117f9c4b4cb9..86aabd64383e 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -74,6 +74,7 @@ obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o | |||
74 | obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ | 74 | obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ |
75 | obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o | 75 | obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o |
76 | obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o | 76 | obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o |
77 | obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o | ||
77 | 78 | ||
78 | obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o | 79 | obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o |
79 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | 80 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
@@ -180,6 +181,8 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ | |||
180 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ | 181 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ |
181 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ | 182 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ |
182 | 183 | ||
184 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ | ||
185 | |||
183 | obj-$(CONFIG_ARCH_DAVINCI) += davinci/ | 186 | obj-$(CONFIG_ARCH_DAVINCI) += davinci/ |
184 | 187 | ||
185 | obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o | 188 | obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o |
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 23ba5c37c3e4..879f1d839760 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c | |||
@@ -64,6 +64,11 @@ static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd) | |||
64 | 64 | ||
65 | static char *inputs[] = { "pass_through", "play_back" }; | 65 | static char *inputs[] = { "pass_through", "play_back" }; |
66 | 66 | ||
67 | static enum v4l2_mbus_pixelcode adv7170_codes[] = { | ||
68 | V4L2_MBUS_FMT_UYVY8_2X8, | ||
69 | V4L2_MBUS_FMT_UYVY8_1X16, | ||
70 | }; | ||
71 | |||
67 | /* ----------------------------------------------------------------------- */ | 72 | /* ----------------------------------------------------------------------- */ |
68 | 73 | ||
69 | static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value) | 74 | static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value) |
@@ -258,6 +263,60 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, | |||
258 | return 0; | 263 | return 0; |
259 | } | 264 | } |
260 | 265 | ||
266 | static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | ||
267 | enum v4l2_mbus_pixelcode *code) | ||
268 | { | ||
269 | if (index >= ARRAY_SIZE(adv7170_codes)) | ||
270 | return -EINVAL; | ||
271 | |||
272 | *code = adv7170_codes[index]; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int adv7170_g_fmt(struct v4l2_subdev *sd, | ||
277 | struct v4l2_mbus_framefmt *mf) | ||
278 | { | ||
279 | u8 val = adv7170_read(sd, 0x7); | ||
280 | |||
281 | if ((val & 0x40) == (1 << 6)) | ||
282 | mf->code = V4L2_MBUS_FMT_UYVY8_1X16; | ||
283 | else | ||
284 | mf->code = V4L2_MBUS_FMT_UYVY8_2X8; | ||
285 | |||
286 | mf->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
287 | mf->width = 0; | ||
288 | mf->height = 0; | ||
289 | mf->field = V4L2_FIELD_ANY; | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int adv7170_s_fmt(struct v4l2_subdev *sd, | ||
295 | struct v4l2_mbus_framefmt *mf) | ||
296 | { | ||
297 | u8 val = adv7170_read(sd, 0x7); | ||
298 | int ret; | ||
299 | |||
300 | switch (mf->code) { | ||
301 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
302 | val &= ~0x40; | ||
303 | break; | ||
304 | |||
305 | case V4L2_MBUS_FMT_UYVY8_1X16: | ||
306 | val |= 0x40; | ||
307 | break; | ||
308 | |||
309 | default: | ||
310 | v4l2_dbg(1, debug, sd, | ||
311 | "illegal v4l2_mbus_framefmt code: %d\n", mf->code); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | |||
315 | ret = adv7170_write(sd, 0x7, val); | ||
316 | |||
317 | return ret; | ||
318 | } | ||
319 | |||
261 | static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) | 320 | static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
262 | { | 321 | { |
263 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 322 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
@@ -274,6 +333,9 @@ static const struct v4l2_subdev_core_ops adv7170_core_ops = { | |||
274 | static const struct v4l2_subdev_video_ops adv7170_video_ops = { | 333 | static const struct v4l2_subdev_video_ops adv7170_video_ops = { |
275 | .s_std_output = adv7170_s_std_output, | 334 | .s_std_output = adv7170_s_std_output, |
276 | .s_routing = adv7170_s_routing, | 335 | .s_routing = adv7170_s_routing, |
336 | .s_mbus_fmt = adv7170_s_fmt, | ||
337 | .g_mbus_fmt = adv7170_g_fmt, | ||
338 | .enum_mbus_fmt = adv7170_enum_fmt, | ||
277 | }; | 339 | }; |
278 | 340 | ||
279 | static const struct v4l2_subdev_ops adv7170_ops = { | 341 | static const struct v4l2_subdev_ops adv7170_ops = { |
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c new file mode 100644 index 000000000000..ec859a580651 --- /dev/null +++ b/drivers/media/video/as3645a.c | |||
@@ -0,0 +1,904 @@ | |||
1 | /* | ||
2 | * drivers/media/video/as3645a.c - AS3645A and LM3555 flash controllers driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2011 Nokia Corporation | ||
5 | * Copyright (c) 2011, Intel Corporation. | ||
6 | * | ||
7 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * version 2 as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
21 | * 02110-1301 USA | ||
22 | * | ||
23 | * TODO: | ||
24 | * - Check hardware FSTROBE control when sensor driver add support for this | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/delay.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/mutex.h> | ||
32 | |||
33 | #include <media/as3645a.h> | ||
34 | #include <media/v4l2-ctrls.h> | ||
35 | #include <media/v4l2-device.h> | ||
36 | |||
37 | #define AS_TIMER_MS_TO_CODE(t) (((t) - 100) / 50) | ||
38 | #define AS_TIMER_CODE_TO_MS(c) (50 * (c) + 100) | ||
39 | |||
40 | /* Register definitions */ | ||
41 | |||
42 | /* Read-only Design info register: Reset state: xxxx 0001 */ | ||
43 | #define AS_DESIGN_INFO_REG 0x00 | ||
44 | #define AS_DESIGN_INFO_FACTORY(x) (((x) >> 4)) | ||
45 | #define AS_DESIGN_INFO_MODEL(x) ((x) & 0x0f) | ||
46 | |||
47 | /* Read-only Version control register: Reset state: 0000 0000 | ||
48 | * for first engineering samples | ||
49 | */ | ||
50 | #define AS_VERSION_CONTROL_REG 0x01 | ||
51 | #define AS_VERSION_CONTROL_RFU(x) (((x) >> 4)) | ||
52 | #define AS_VERSION_CONTROL_VERSION(x) ((x) & 0x0f) | ||
53 | |||
54 | /* Read / Write (Indicator and timer register): Reset state: 0000 1111 */ | ||
55 | #define AS_INDICATOR_AND_TIMER_REG 0x02 | ||
56 | #define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT 0 | ||
57 | #define AS_INDICATOR_AND_TIMER_VREF_SHIFT 4 | ||
58 | #define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT 6 | ||
59 | |||
60 | /* Read / Write (Current set register): Reset state: 0110 1001 */ | ||
61 | #define AS_CURRENT_SET_REG 0x03 | ||
62 | #define AS_CURRENT_ASSIST_LIGHT_SHIFT 0 | ||
63 | #define AS_CURRENT_LED_DET_ON (1 << 3) | ||
64 | #define AS_CURRENT_FLASH_CURRENT_SHIFT 4 | ||
65 | |||
66 | /* Read / Write (Control register): Reset state: 1011 0100 */ | ||
67 | #define AS_CONTROL_REG 0x04 | ||
68 | #define AS_CONTROL_MODE_SETTING_SHIFT 0 | ||
69 | #define AS_CONTROL_STROBE_ON (1 << 2) | ||
70 | #define AS_CONTROL_OUT_ON (1 << 3) | ||
71 | #define AS_CONTROL_EXT_TORCH_ON (1 << 4) | ||
72 | #define AS_CONTROL_STROBE_TYPE_EDGE (0 << 5) | ||
73 | #define AS_CONTROL_STROBE_TYPE_LEVEL (1 << 5) | ||
74 | #define AS_CONTROL_COIL_PEAK_SHIFT 6 | ||
75 | |||
76 | /* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */ | ||
77 | #define AS_FAULT_INFO_REG 0x05 | ||
78 | #define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT (1 << 1) | ||
79 | #define AS_FAULT_INFO_INDICATOR_LED (1 << 2) | ||
80 | #define AS_FAULT_INFO_LED_AMOUNT (1 << 3) | ||
81 | #define AS_FAULT_INFO_TIMEOUT (1 << 4) | ||
82 | #define AS_FAULT_INFO_OVER_TEMPERATURE (1 << 5) | ||
83 | #define AS_FAULT_INFO_SHORT_CIRCUIT (1 << 6) | ||
84 | #define AS_FAULT_INFO_OVER_VOLTAGE (1 << 7) | ||
85 | |||
86 | /* Boost register */ | ||
87 | #define AS_BOOST_REG 0x0d | ||
88 | #define AS_BOOST_CURRENT_DISABLE (0 << 0) | ||
89 | #define AS_BOOST_CURRENT_ENABLE (1 << 0) | ||
90 | |||
91 | /* Password register is used to unlock boost register writing */ | ||
92 | #define AS_PASSWORD_REG 0x0f | ||
93 | #define AS_PASSWORD_UNLOCK_VALUE 0x55 | ||
94 | |||
95 | enum as_mode { | ||
96 | AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT, | ||
97 | AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT, | ||
98 | AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT, | ||
99 | AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT, | ||
100 | }; | ||
101 | |||
102 | /* | ||
103 | * struct as3645a | ||
104 | * | ||
105 | * @subdev: V4L2 subdev | ||
106 | * @pdata: Flash platform data | ||
107 | * @power_lock: Protects power_count | ||
108 | * @power_count: Power reference count | ||
109 | * @led_mode: V4L2 flash LED mode | ||
110 | * @timeout: Flash timeout in microseconds | ||
111 | * @flash_current: Flash current (0=200mA ... 15=500mA). Maximum | ||
112 | * values are 400mA for two LEDs and 500mA for one LED. | ||
113 | * @assist_current: Torch/Assist light current (0=20mA, 1=40mA ... 7=160mA) | ||
114 | * @indicator_current: Indicator LED current (0=0mA, 1=2.5mA ... 4=10mA) | ||
115 | * @strobe_source: Flash strobe source (software or external) | ||
116 | */ | ||
117 | struct as3645a { | ||
118 | struct v4l2_subdev subdev; | ||
119 | const struct as3645a_platform_data *pdata; | ||
120 | |||
121 | struct mutex power_lock; | ||
122 | int power_count; | ||
123 | |||
124 | /* Controls */ | ||
125 | struct v4l2_ctrl_handler ctrls; | ||
126 | |||
127 | enum v4l2_flash_led_mode led_mode; | ||
128 | unsigned int timeout; | ||
129 | u8 flash_current; | ||
130 | u8 assist_current; | ||
131 | u8 indicator_current; | ||
132 | enum v4l2_flash_strobe_source strobe_source; | ||
133 | }; | ||
134 | |||
135 | #define to_as3645a(sd) container_of(sd, struct as3645a, subdev) | ||
136 | |||
137 | /* Return negative errno else zero on success */ | ||
138 | static int as3645a_write(struct as3645a *flash, u8 addr, u8 val) | ||
139 | { | ||
140 | struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); | ||
141 | int rval; | ||
142 | |||
143 | rval = i2c_smbus_write_byte_data(client, addr, val); | ||
144 | |||
145 | dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val, | ||
146 | rval < 0 ? "fail" : "ok"); | ||
147 | |||
148 | return rval; | ||
149 | } | ||
150 | |||
151 | /* Return negative errno else a data byte received from the device. */ | ||
152 | static int as3645a_read(struct as3645a *flash, u8 addr) | ||
153 | { | ||
154 | struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); | ||
155 | int rval; | ||
156 | |||
157 | rval = i2c_smbus_read_byte_data(client, addr); | ||
158 | |||
159 | dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval, | ||
160 | rval < 0 ? "fail" : "ok"); | ||
161 | |||
162 | return rval; | ||
163 | } | ||
164 | |||
165 | /* ----------------------------------------------------------------------------- | ||
166 | * Hardware configuration and trigger | ||
167 | */ | ||
168 | |||
169 | /* | ||
170 | * as3645a_set_config - Set flash configuration registers | ||
171 | * @flash: The flash | ||
172 | * | ||
173 | * Configure the hardware with flash, assist and indicator currents, as well as | ||
174 | * flash timeout. | ||
175 | * | ||
176 | * Return 0 on success, or a negative error code if an I2C communication error | ||
177 | * occurred. | ||
178 | */ | ||
179 | static int as3645a_set_config(struct as3645a *flash) | ||
180 | { | ||
181 | int ret; | ||
182 | u8 val; | ||
183 | |||
184 | val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT) | ||
185 | | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT) | ||
186 | | AS_CURRENT_LED_DET_ON; | ||
187 | |||
188 | ret = as3645a_write(flash, AS_CURRENT_SET_REG, val); | ||
189 | if (ret < 0) | ||
190 | return ret; | ||
191 | |||
192 | val = AS_TIMER_MS_TO_CODE(flash->timeout / 1000) | ||
193 | << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT; | ||
194 | |||
195 | val |= (flash->pdata->vref << AS_INDICATOR_AND_TIMER_VREF_SHIFT) | ||
196 | | ((flash->indicator_current ? flash->indicator_current - 1 : 0) | ||
197 | << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT); | ||
198 | |||
199 | return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val); | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * as3645a_set_control - Set flash control register | ||
204 | * @flash: The flash | ||
205 | * @mode: Desired output mode | ||
206 | * @on: Desired output state | ||
207 | * | ||
208 | * Configure the hardware with output mode and state. | ||
209 | * | ||
210 | * Return 0 on success, or a negative error code if an I2C communication error | ||
211 | * occurred. | ||
212 | */ | ||
213 | static int | ||
214 | as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on) | ||
215 | { | ||
216 | u8 reg; | ||
217 | |||
218 | /* Configure output parameters and operation mode. */ | ||
219 | reg = (flash->pdata->peak << AS_CONTROL_COIL_PEAK_SHIFT) | ||
220 | | (on ? AS_CONTROL_OUT_ON : 0) | ||
221 | | mode; | ||
222 | |||
223 | if (flash->led_mode == V4L2_FLASH_LED_MODE_FLASH && | ||
224 | flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) { | ||
225 | reg |= AS_CONTROL_STROBE_TYPE_LEVEL | ||
226 | | AS_CONTROL_STROBE_ON; | ||
227 | } | ||
228 | |||
229 | return as3645a_write(flash, AS_CONTROL_REG, reg); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * as3645a_set_output - Configure output and operation mode | ||
234 | * @flash: Flash controller | ||
235 | * @strobe: Strobe the flash (only valid in flash mode) | ||
236 | * | ||
237 | * Turn the LEDs output on/off and set the operation mode based on the current | ||
238 | * parameters. | ||
239 | * | ||
240 | * The AS3645A can't control the indicator LED independently of the flash/torch | ||
241 | * LED. If the flash controller is in V4L2_FLASH_LED_MODE_NONE mode, set the | ||
242 | * chip to indicator mode. Otherwise set it to assist light (torch) or flash | ||
243 | * mode. | ||
244 | * | ||
245 | * In indicator and assist modes, turn the output on/off based on the indicator | ||
246 | * and torch currents. In software strobe flash mode, turn the output on/off | ||
247 | * based on the strobe parameter. | ||
248 | */ | ||
249 | static int as3645a_set_output(struct as3645a *flash, bool strobe) | ||
250 | { | ||
251 | enum as_mode mode; | ||
252 | bool on; | ||
253 | |||
254 | switch (flash->led_mode) { | ||
255 | case V4L2_FLASH_LED_MODE_NONE: | ||
256 | on = flash->indicator_current != 0; | ||
257 | mode = AS_MODE_INDICATOR; | ||
258 | break; | ||
259 | case V4L2_FLASH_LED_MODE_TORCH: | ||
260 | on = true; | ||
261 | mode = AS_MODE_ASSIST; | ||
262 | break; | ||
263 | case V4L2_FLASH_LED_MODE_FLASH: | ||
264 | on = strobe; | ||
265 | mode = AS_MODE_FLASH; | ||
266 | break; | ||
267 | default: | ||
268 | BUG(); | ||
269 | } | ||
270 | |||
271 | /* Configure output parameters and operation mode. */ | ||
272 | return as3645a_set_control(flash, mode, on); | ||
273 | } | ||
274 | |||
275 | /* ----------------------------------------------------------------------------- | ||
276 | * V4L2 controls | ||
277 | */ | ||
278 | |||
279 | static int as3645a_is_active(struct as3645a *flash) | ||
280 | { | ||
281 | int ret; | ||
282 | |||
283 | ret = as3645a_read(flash, AS_CONTROL_REG); | ||
284 | return ret < 0 ? ret : !!(ret & AS_CONTROL_OUT_ON); | ||
285 | } | ||
286 | |||
287 | static int as3645a_read_fault(struct as3645a *flash) | ||
288 | { | ||
289 | struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); | ||
290 | int rval; | ||
291 | |||
292 | /* NOTE: reading register clear fault status */ | ||
293 | rval = as3645a_read(flash, AS_FAULT_INFO_REG); | ||
294 | if (rval < 0) | ||
295 | return rval; | ||
296 | |||
297 | if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT) | ||
298 | dev_dbg(&client->dev, "Inductor Peak limit fault\n"); | ||
299 | |||
300 | if (rval & AS_FAULT_INFO_INDICATOR_LED) | ||
301 | dev_dbg(&client->dev, "Indicator LED fault: " | ||
302 | "Short circuit or open loop\n"); | ||
303 | |||
304 | dev_dbg(&client->dev, "%u connected LEDs\n", | ||
305 | rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1); | ||
306 | |||
307 | if (rval & AS_FAULT_INFO_TIMEOUT) | ||
308 | dev_dbg(&client->dev, "Timeout fault\n"); | ||
309 | |||
310 | if (rval & AS_FAULT_INFO_OVER_TEMPERATURE) | ||
311 | dev_dbg(&client->dev, "Over temperature fault\n"); | ||
312 | |||
313 | if (rval & AS_FAULT_INFO_SHORT_CIRCUIT) | ||
314 | dev_dbg(&client->dev, "Short circuit fault\n"); | ||
315 | |||
316 | if (rval & AS_FAULT_INFO_OVER_VOLTAGE) | ||
317 | dev_dbg(&client->dev, "Over voltage fault: " | ||
318 | "Indicates missing capacitor or open connection\n"); | ||
319 | |||
320 | return rval; | ||
321 | } | ||
322 | |||
323 | static int as3645a_get_ctrl(struct v4l2_ctrl *ctrl) | ||
324 | { | ||
325 | struct as3645a *flash = | ||
326 | container_of(ctrl->handler, struct as3645a, ctrls); | ||
327 | struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); | ||
328 | int value; | ||
329 | |||
330 | switch (ctrl->id) { | ||
331 | case V4L2_CID_FLASH_FAULT: | ||
332 | value = as3645a_read_fault(flash); | ||
333 | if (value < 0) | ||
334 | return value; | ||
335 | |||
336 | ctrl->cur.val = 0; | ||
337 | if (value & AS_FAULT_INFO_SHORT_CIRCUIT) | ||
338 | ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; | ||
339 | if (value & AS_FAULT_INFO_OVER_TEMPERATURE) | ||
340 | ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; | ||
341 | if (value & AS_FAULT_INFO_TIMEOUT) | ||
342 | ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT; | ||
343 | if (value & AS_FAULT_INFO_OVER_VOLTAGE) | ||
344 | ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE; | ||
345 | if (value & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT) | ||
346 | ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_CURRENT; | ||
347 | if (value & AS_FAULT_INFO_INDICATOR_LED) | ||
348 | ctrl->cur.val |= V4L2_FLASH_FAULT_INDICATOR; | ||
349 | break; | ||
350 | |||
351 | case V4L2_CID_FLASH_STROBE_STATUS: | ||
352 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) { | ||
353 | ctrl->cur.val = 0; | ||
354 | break; | ||
355 | } | ||
356 | |||
357 | value = as3645a_is_active(flash); | ||
358 | if (value < 0) | ||
359 | return value; | ||
360 | |||
361 | ctrl->cur.val = value; | ||
362 | break; | ||
363 | } | ||
364 | |||
365 | dev_dbg(&client->dev, "G_CTRL %08x:%d\n", ctrl->id, ctrl->cur.val); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int as3645a_set_ctrl(struct v4l2_ctrl *ctrl) | ||
371 | { | ||
372 | struct as3645a *flash = | ||
373 | container_of(ctrl->handler, struct as3645a, ctrls); | ||
374 | struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); | ||
375 | int ret; | ||
376 | |||
377 | dev_dbg(&client->dev, "S_CTRL %08x:%d\n", ctrl->id, ctrl->val); | ||
378 | |||
379 | /* If a control that doesn't apply to the current mode is modified, | ||
380 | * we store the value and return immediately. The setting will be | ||
381 | * applied when the LED mode is changed. Otherwise we apply the setting | ||
382 | * immediately. | ||
383 | */ | ||
384 | |||
385 | switch (ctrl->id) { | ||
386 | case V4L2_CID_FLASH_LED_MODE: | ||
387 | if (flash->indicator_current) | ||
388 | return -EBUSY; | ||
389 | |||
390 | ret = as3645a_set_config(flash); | ||
391 | if (ret < 0) | ||
392 | return ret; | ||
393 | |||
394 | flash->led_mode = ctrl->val; | ||
395 | return as3645a_set_output(flash, false); | ||
396 | |||
397 | case V4L2_CID_FLASH_STROBE_SOURCE: | ||
398 | flash->strobe_source = ctrl->val; | ||
399 | |||
400 | /* Applies to flash mode only. */ | ||
401 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
402 | break; | ||
403 | |||
404 | return as3645a_set_output(flash, false); | ||
405 | |||
406 | case V4L2_CID_FLASH_STROBE: | ||
407 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
408 | return -EBUSY; | ||
409 | |||
410 | return as3645a_set_output(flash, true); | ||
411 | |||
412 | case V4L2_CID_FLASH_STROBE_STOP: | ||
413 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
414 | return -EBUSY; | ||
415 | |||
416 | return as3645a_set_output(flash, false); | ||
417 | |||
418 | case V4L2_CID_FLASH_TIMEOUT: | ||
419 | flash->timeout = ctrl->val; | ||
420 | |||
421 | /* Applies to flash mode only. */ | ||
422 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
423 | break; | ||
424 | |||
425 | return as3645a_set_config(flash); | ||
426 | |||
427 | case V4L2_CID_FLASH_INTENSITY: | ||
428 | flash->flash_current = (ctrl->val - AS3645A_FLASH_INTENSITY_MIN) | ||
429 | / AS3645A_FLASH_INTENSITY_STEP; | ||
430 | |||
431 | /* Applies to flash mode only. */ | ||
432 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
433 | break; | ||
434 | |||
435 | return as3645a_set_config(flash); | ||
436 | |||
437 | case V4L2_CID_FLASH_TORCH_INTENSITY: | ||
438 | flash->assist_current = | ||
439 | (ctrl->val - AS3645A_TORCH_INTENSITY_MIN) | ||
440 | / AS3645A_TORCH_INTENSITY_STEP; | ||
441 | |||
442 | /* Applies to torch mode only. */ | ||
443 | if (flash->led_mode != V4L2_FLASH_LED_MODE_TORCH) | ||
444 | break; | ||
445 | |||
446 | return as3645a_set_config(flash); | ||
447 | |||
448 | case V4L2_CID_FLASH_INDICATOR_INTENSITY: | ||
449 | if (flash->led_mode != V4L2_FLASH_LED_MODE_NONE) | ||
450 | return -EBUSY; | ||
451 | |||
452 | flash->indicator_current = | ||
453 | (ctrl->val - AS3645A_INDICATOR_INTENSITY_MIN) | ||
454 | / AS3645A_INDICATOR_INTENSITY_STEP; | ||
455 | |||
456 | ret = as3645a_set_config(flash); | ||
457 | if (ret < 0) | ||
458 | return ret; | ||
459 | |||
460 | if ((ctrl->val == 0) == (ctrl->cur.val == 0)) | ||
461 | break; | ||
462 | |||
463 | return as3645a_set_output(flash, false); | ||
464 | } | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | static const struct v4l2_ctrl_ops as3645a_ctrl_ops = { | ||
470 | .g_volatile_ctrl = as3645a_get_ctrl, | ||
471 | .s_ctrl = as3645a_set_ctrl, | ||
472 | }; | ||
473 | |||
474 | /* ----------------------------------------------------------------------------- | ||
475 | * V4L2 subdev core operations | ||
476 | */ | ||
477 | |||
478 | /* Put device into know state. */ | ||
479 | static int as3645a_setup(struct as3645a *flash) | ||
480 | { | ||
481 | struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); | ||
482 | int ret; | ||
483 | |||
484 | /* clear errors */ | ||
485 | ret = as3645a_read(flash, AS_FAULT_INFO_REG); | ||
486 | if (ret < 0) | ||
487 | return ret; | ||
488 | |||
489 | dev_dbg(&client->dev, "Fault info: %02x\n", ret); | ||
490 | |||
491 | ret = as3645a_set_config(flash); | ||
492 | if (ret < 0) | ||
493 | return ret; | ||
494 | |||
495 | ret = as3645a_set_output(flash, false); | ||
496 | if (ret < 0) | ||
497 | return ret; | ||
498 | |||
499 | /* read status */ | ||
500 | ret = as3645a_read_fault(flash); | ||
501 | if (ret < 0) | ||
502 | return ret; | ||
503 | |||
504 | dev_dbg(&client->dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n", | ||
505 | as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG)); | ||
506 | dev_dbg(&client->dev, "AS_CURRENT_SET_REG: %02x\n", | ||
507 | as3645a_read(flash, AS_CURRENT_SET_REG)); | ||
508 | dev_dbg(&client->dev, "AS_CONTROL_REG: %02x\n", | ||
509 | as3645a_read(flash, AS_CONTROL_REG)); | ||
510 | |||
511 | return ret & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0; | ||
512 | } | ||
513 | |||
514 | static int __as3645a_set_power(struct as3645a *flash, int on) | ||
515 | { | ||
516 | int ret; | ||
517 | |||
518 | if (!on) | ||
519 | as3645a_set_control(flash, AS_MODE_EXT_TORCH, false); | ||
520 | |||
521 | if (flash->pdata->set_power) { | ||
522 | ret = flash->pdata->set_power(&flash->subdev, on); | ||
523 | if (ret < 0) | ||
524 | return ret; | ||
525 | } | ||
526 | |||
527 | if (!on) | ||
528 | return 0; | ||
529 | |||
530 | ret = as3645a_setup(flash); | ||
531 | if (ret < 0) { | ||
532 | if (flash->pdata->set_power) | ||
533 | flash->pdata->set_power(&flash->subdev, 0); | ||
534 | } | ||
535 | |||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | static int as3645a_set_power(struct v4l2_subdev *sd, int on) | ||
540 | { | ||
541 | struct as3645a *flash = to_as3645a(sd); | ||
542 | int ret = 0; | ||
543 | |||
544 | mutex_lock(&flash->power_lock); | ||
545 | |||
546 | if (flash->power_count == !on) { | ||
547 | ret = __as3645a_set_power(flash, !!on); | ||
548 | if (ret < 0) | ||
549 | goto done; | ||
550 | } | ||
551 | |||
552 | flash->power_count += on ? 1 : -1; | ||
553 | WARN_ON(flash->power_count < 0); | ||
554 | |||
555 | done: | ||
556 | mutex_unlock(&flash->power_lock); | ||
557 | return ret; | ||
558 | } | ||
559 | |||
560 | static int as3645a_registered(struct v4l2_subdev *sd) | ||
561 | { | ||
562 | struct as3645a *flash = to_as3645a(sd); | ||
563 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
564 | int rval, man, model, rfu, version; | ||
565 | const char *vendor; | ||
566 | |||
567 | /* Power up the flash driver and read manufacturer ID, model ID, RFU | ||
568 | * and version. | ||
569 | */ | ||
570 | rval = as3645a_set_power(&flash->subdev, 1); | ||
571 | if (rval < 0) | ||
572 | return rval; | ||
573 | |||
574 | rval = as3645a_read(flash, AS_DESIGN_INFO_REG); | ||
575 | if (rval < 0) | ||
576 | goto power_off; | ||
577 | |||
578 | man = AS_DESIGN_INFO_FACTORY(rval); | ||
579 | model = AS_DESIGN_INFO_MODEL(rval); | ||
580 | |||
581 | rval = as3645a_read(flash, AS_VERSION_CONTROL_REG); | ||
582 | if (rval < 0) | ||
583 | goto power_off; | ||
584 | |||
585 | rfu = AS_VERSION_CONTROL_RFU(rval); | ||
586 | version = AS_VERSION_CONTROL_VERSION(rval); | ||
587 | |||
588 | /* Verify the chip model and version. */ | ||
589 | if (model != 0x01 || rfu != 0x00) { | ||
590 | dev_err(&client->dev, "AS3645A not detected " | ||
591 | "(model %d rfu %d)\n", model, rfu); | ||
592 | rval = -ENODEV; | ||
593 | goto power_off; | ||
594 | } | ||
595 | |||
596 | switch (man) { | ||
597 | case 1: | ||
598 | vendor = "AMS, Austria Micro Systems"; | ||
599 | break; | ||
600 | case 2: | ||
601 | vendor = "ADI, Analog Devices Inc."; | ||
602 | break; | ||
603 | case 3: | ||
604 | vendor = "NSC, National Semiconductor"; | ||
605 | break; | ||
606 | case 4: | ||
607 | vendor = "NXP"; | ||
608 | break; | ||
609 | case 5: | ||
610 | vendor = "TI, Texas Instrument"; | ||
611 | break; | ||
612 | default: | ||
613 | vendor = "Unknown"; | ||
614 | } | ||
615 | |||
616 | dev_info(&client->dev, "Chip vendor: %s (%d) Version: %d\n", vendor, | ||
617 | man, version); | ||
618 | |||
619 | rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE); | ||
620 | if (rval < 0) | ||
621 | goto power_off; | ||
622 | |||
623 | rval = as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE); | ||
624 | if (rval < 0) | ||
625 | goto power_off; | ||
626 | |||
627 | /* Setup default values. This makes sure that the chip is in a known | ||
628 | * state, in case the power rail can't be controlled. | ||
629 | */ | ||
630 | rval = as3645a_setup(flash); | ||
631 | |||
632 | power_off: | ||
633 | as3645a_set_power(&flash->subdev, 0); | ||
634 | |||
635 | return rval; | ||
636 | } | ||
637 | |||
638 | static int as3645a_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
639 | { | ||
640 | return as3645a_set_power(sd, 1); | ||
641 | } | ||
642 | |||
643 | static int as3645a_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
644 | { | ||
645 | return as3645a_set_power(sd, 0); | ||
646 | } | ||
647 | |||
648 | static const struct v4l2_subdev_core_ops as3645a_core_ops = { | ||
649 | .s_power = as3645a_set_power, | ||
650 | }; | ||
651 | |||
652 | static const struct v4l2_subdev_ops as3645a_ops = { | ||
653 | .core = &as3645a_core_ops, | ||
654 | }; | ||
655 | |||
656 | static const struct v4l2_subdev_internal_ops as3645a_internal_ops = { | ||
657 | .registered = as3645a_registered, | ||
658 | .open = as3645a_open, | ||
659 | .close = as3645a_close, | ||
660 | }; | ||
661 | |||
662 | /* ----------------------------------------------------------------------------- | ||
663 | * I2C driver | ||
664 | */ | ||
665 | #ifdef CONFIG_PM | ||
666 | |||
667 | static int as3645a_suspend(struct device *dev) | ||
668 | { | ||
669 | struct i2c_client *client = to_i2c_client(dev); | ||
670 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); | ||
671 | struct as3645a *flash = to_as3645a(subdev); | ||
672 | int rval; | ||
673 | |||
674 | if (flash->power_count == 0) | ||
675 | return 0; | ||
676 | |||
677 | rval = __as3645a_set_power(flash, 0); | ||
678 | |||
679 | dev_dbg(&client->dev, "Suspend %s\n", rval < 0 ? "failed" : "ok"); | ||
680 | |||
681 | return rval; | ||
682 | } | ||
683 | |||
684 | static int as3645a_resume(struct device *dev) | ||
685 | { | ||
686 | struct i2c_client *client = to_i2c_client(dev); | ||
687 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); | ||
688 | struct as3645a *flash = to_as3645a(subdev); | ||
689 | int rval; | ||
690 | |||
691 | if (flash->power_count == 0) | ||
692 | return 0; | ||
693 | |||
694 | rval = __as3645a_set_power(flash, 1); | ||
695 | |||
696 | dev_dbg(&client->dev, "Resume %s\n", rval < 0 ? "fail" : "ok"); | ||
697 | |||
698 | return rval; | ||
699 | } | ||
700 | |||
701 | #else | ||
702 | |||
703 | #define as3645a_suspend NULL | ||
704 | #define as3645a_resume NULL | ||
705 | |||
706 | #endif /* CONFIG_PM */ | ||
707 | |||
708 | /* | ||
709 | * as3645a_init_controls - Create controls | ||
710 | * @flash: The flash | ||
711 | * | ||
712 | * The number of LEDs reported in platform data is used to compute default | ||
713 | * limits. Parameters passed through platform data can override those limits. | ||
714 | */ | ||
715 | static int as3645a_init_controls(struct as3645a *flash) | ||
716 | { | ||
717 | const struct as3645a_platform_data *pdata = flash->pdata; | ||
718 | struct v4l2_ctrl *ctrl; | ||
719 | int maximum; | ||
720 | |||
721 | v4l2_ctrl_handler_init(&flash->ctrls, 10); | ||
722 | |||
723 | /* V4L2_CID_FLASH_LED_MODE */ | ||
724 | v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops, | ||
725 | V4L2_CID_FLASH_LED_MODE, 2, ~7, | ||
726 | V4L2_FLASH_LED_MODE_NONE); | ||
727 | |||
728 | /* V4L2_CID_FLASH_STROBE_SOURCE */ | ||
729 | v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops, | ||
730 | V4L2_CID_FLASH_STROBE_SOURCE, | ||
731 | pdata->ext_strobe ? 1 : 0, | ||
732 | pdata->ext_strobe ? ~3 : ~1, | ||
733 | V4L2_FLASH_STROBE_SOURCE_SOFTWARE); | ||
734 | |||
735 | flash->strobe_source = V4L2_FLASH_STROBE_SOURCE_SOFTWARE; | ||
736 | |||
737 | /* V4L2_CID_FLASH_STROBE */ | ||
738 | v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
739 | V4L2_CID_FLASH_STROBE, 0, 0, 0, 0); | ||
740 | |||
741 | /* V4L2_CID_FLASH_STROBE_STOP */ | ||
742 | v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
743 | V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0); | ||
744 | |||
745 | /* V4L2_CID_FLASH_STROBE_STATUS */ | ||
746 | ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
747 | V4L2_CID_FLASH_STROBE_STATUS, 0, 1, 1, 1); | ||
748 | if (ctrl != NULL) | ||
749 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; | ||
750 | |||
751 | /* V4L2_CID_FLASH_TIMEOUT */ | ||
752 | maximum = pdata->timeout_max; | ||
753 | |||
754 | v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
755 | V4L2_CID_FLASH_TIMEOUT, AS3645A_FLASH_TIMEOUT_MIN, | ||
756 | maximum, AS3645A_FLASH_TIMEOUT_STEP, maximum); | ||
757 | |||
758 | flash->timeout = maximum; | ||
759 | |||
760 | /* V4L2_CID_FLASH_INTENSITY */ | ||
761 | maximum = pdata->flash_max_current; | ||
762 | |||
763 | v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
764 | V4L2_CID_FLASH_INTENSITY, AS3645A_FLASH_INTENSITY_MIN, | ||
765 | maximum, AS3645A_FLASH_INTENSITY_STEP, maximum); | ||
766 | |||
767 | flash->flash_current = (maximum - AS3645A_FLASH_INTENSITY_MIN) | ||
768 | / AS3645A_FLASH_INTENSITY_STEP; | ||
769 | |||
770 | /* V4L2_CID_FLASH_TORCH_INTENSITY */ | ||
771 | maximum = pdata->torch_max_current; | ||
772 | |||
773 | v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
774 | V4L2_CID_FLASH_TORCH_INTENSITY, | ||
775 | AS3645A_TORCH_INTENSITY_MIN, maximum, | ||
776 | AS3645A_TORCH_INTENSITY_STEP, | ||
777 | AS3645A_TORCH_INTENSITY_MIN); | ||
778 | |||
779 | flash->assist_current = 0; | ||
780 | |||
781 | /* V4L2_CID_FLASH_INDICATOR_INTENSITY */ | ||
782 | v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
783 | V4L2_CID_FLASH_INDICATOR_INTENSITY, | ||
784 | AS3645A_INDICATOR_INTENSITY_MIN, | ||
785 | AS3645A_INDICATOR_INTENSITY_MAX, | ||
786 | AS3645A_INDICATOR_INTENSITY_STEP, | ||
787 | AS3645A_INDICATOR_INTENSITY_MIN); | ||
788 | |||
789 | flash->indicator_current = 0; | ||
790 | |||
791 | /* V4L2_CID_FLASH_FAULT */ | ||
792 | ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops, | ||
793 | V4L2_CID_FLASH_FAULT, 0, | ||
794 | V4L2_FLASH_FAULT_OVER_VOLTAGE | | ||
795 | V4L2_FLASH_FAULT_TIMEOUT | | ||
796 | V4L2_FLASH_FAULT_OVER_TEMPERATURE | | ||
797 | V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0); | ||
798 | if (ctrl != NULL) | ||
799 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; | ||
800 | |||
801 | flash->subdev.ctrl_handler = &flash->ctrls; | ||
802 | |||
803 | return flash->ctrls.error; | ||
804 | } | ||
805 | |||
806 | static int as3645a_probe(struct i2c_client *client, | ||
807 | const struct i2c_device_id *devid) | ||
808 | { | ||
809 | struct as3645a *flash; | ||
810 | int ret; | ||
811 | |||
812 | if (client->dev.platform_data == NULL) | ||
813 | return -ENODEV; | ||
814 | |||
815 | flash = kzalloc(sizeof(*flash), GFP_KERNEL); | ||
816 | if (flash == NULL) | ||
817 | return -ENOMEM; | ||
818 | |||
819 | flash->pdata = client->dev.platform_data; | ||
820 | |||
821 | v4l2_i2c_subdev_init(&flash->subdev, client, &as3645a_ops); | ||
822 | flash->subdev.internal_ops = &as3645a_internal_ops; | ||
823 | flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
824 | |||
825 | ret = as3645a_init_controls(flash); | ||
826 | if (ret < 0) | ||
827 | goto done; | ||
828 | |||
829 | ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0); | ||
830 | if (ret < 0) | ||
831 | goto done; | ||
832 | |||
833 | flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; | ||
834 | |||
835 | mutex_init(&flash->power_lock); | ||
836 | |||
837 | flash->led_mode = V4L2_FLASH_LED_MODE_NONE; | ||
838 | |||
839 | done: | ||
840 | if (ret < 0) { | ||
841 | v4l2_ctrl_handler_free(&flash->ctrls); | ||
842 | kfree(flash); | ||
843 | } | ||
844 | |||
845 | return ret; | ||
846 | } | ||
847 | |||
848 | static int __exit as3645a_remove(struct i2c_client *client) | ||
849 | { | ||
850 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); | ||
851 | struct as3645a *flash = to_as3645a(subdev); | ||
852 | |||
853 | v4l2_device_unregister_subdev(subdev); | ||
854 | v4l2_ctrl_handler_free(&flash->ctrls); | ||
855 | media_entity_cleanup(&flash->subdev.entity); | ||
856 | mutex_destroy(&flash->power_lock); | ||
857 | kfree(flash); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static const struct i2c_device_id as3645a_id_table[] = { | ||
863 | { AS3645A_NAME, 0 }, | ||
864 | { }, | ||
865 | }; | ||
866 | MODULE_DEVICE_TABLE(i2c, as3645a_id_table); | ||
867 | |||
868 | static const struct dev_pm_ops as3645a_pm_ops = { | ||
869 | .suspend = as3645a_suspend, | ||
870 | .resume = as3645a_resume, | ||
871 | }; | ||
872 | |||
873 | static struct i2c_driver as3645a_i2c_driver = { | ||
874 | .driver = { | ||
875 | .name = AS3645A_NAME, | ||
876 | .pm = &as3645a_pm_ops, | ||
877 | }, | ||
878 | .probe = as3645a_probe, | ||
879 | .remove = __exit_p(as3645a_remove), | ||
880 | .id_table = as3645a_id_table, | ||
881 | }; | ||
882 | |||
883 | static int __init as3645a_init(void) | ||
884 | { | ||
885 | int rval; | ||
886 | |||
887 | rval = i2c_add_driver(&as3645a_i2c_driver); | ||
888 | if (rval) | ||
889 | pr_err("%s: Failed to register the driver\n", AS3645A_NAME); | ||
890 | |||
891 | return rval; | ||
892 | } | ||
893 | |||
894 | static void __exit as3645a_exit(void) | ||
895 | { | ||
896 | i2c_del_driver(&as3645a_i2c_driver); | ||
897 | } | ||
898 | |||
899 | module_init(as3645a_init); | ||
900 | module_exit(as3645a_exit); | ||
901 | |||
902 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
903 | MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones"); | ||
904 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c index 8c775c59e120..fbc904f2f6fd 100644 --- a/drivers/media/video/atmel-isi.c +++ b/drivers/media/video/atmel-isi.c | |||
@@ -1036,7 +1036,7 @@ err_alloc_ctx: | |||
1036 | err_alloc_descriptors: | 1036 | err_alloc_descriptors: |
1037 | kfree(isi); | 1037 | kfree(isi); |
1038 | err_alloc_isi: | 1038 | err_alloc_isi: |
1039 | clk_put(isi->pclk); | 1039 | clk_put(pclk); |
1040 | 1040 | ||
1041 | return ret; | 1041 | return ret; |
1042 | } | 1042 | } |
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c index cbdb65c34f21..05c299fa5d79 100644 --- a/drivers/media/video/au0828/au0828-i2c.c +++ b/drivers/media/video/au0828/au0828-i2c.c | |||
@@ -348,7 +348,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) | |||
348 | } | 348 | } |
349 | } | 349 | } |
350 | 350 | ||
351 | /* init + register i2c algo-bit adapter */ | 351 | /* init + register i2c adapter */ |
352 | int au0828_i2c_register(struct au0828_dev *dev) | 352 | int au0828_i2c_register(struct au0828_dev *dev) |
353 | { | 353 | { |
354 | dprintk(1, "%s()\n", __func__); | 354 | dprintk(1, "%s()\n", __func__); |
diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt8xx/bt848.h index 0bcd95303bb0..c37e6acffded 100644 --- a/drivers/media/video/bt8xx/bt848.h +++ b/drivers/media/video/bt8xx/bt848.h | |||
@@ -30,6 +30,10 @@ | |||
30 | #ifndef PCI_DEVICE_ID_BT849 | 30 | #ifndef PCI_DEVICE_ID_BT849 |
31 | #define PCI_DEVICE_ID_BT849 0x351 | 31 | #define PCI_DEVICE_ID_BT849 0x351 |
32 | #endif | 32 | #endif |
33 | #ifndef PCI_DEVICE_ID_FUSION879 | ||
34 | #define PCI_DEVICE_ID_FUSION879 0x36c | ||
35 | #endif | ||
36 | |||
33 | #ifndef PCI_DEVICE_ID_BT878 | 37 | #ifndef PCI_DEVICE_ID_BT878 |
34 | #define PCI_DEVICE_ID_BT878 0x36e | 38 | #define PCI_DEVICE_ID_BT878 0x36e |
35 | #endif | 39 | #endif |
@@ -37,7 +41,6 @@ | |||
37 | #define PCI_DEVICE_ID_BT879 0x36f | 41 | #define PCI_DEVICE_ID_BT879 0x36f |
38 | #endif | 42 | #endif |
39 | 43 | ||
40 | |||
41 | /* Brooktree 848 registers */ | 44 | /* Brooktree 848 registers */ |
42 | 45 | ||
43 | #define BT848_DSTATUS 0x000 | 46 | #define BT848_DSTATUS 0x000 |
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 5939021d8eba..ff2933ab705f 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -80,6 +80,8 @@ static void phytec_muxsel(struct bttv *btv, unsigned int input); | |||
80 | static void gv800s_muxsel(struct bttv *btv, unsigned int input); | 80 | static void gv800s_muxsel(struct bttv *btv, unsigned int input); |
81 | static void gv800s_init(struct bttv *btv); | 81 | static void gv800s_init(struct bttv *btv); |
82 | 82 | ||
83 | static void td3116_muxsel(struct bttv *btv, unsigned int input); | ||
84 | |||
83 | static int terratec_active_radio_upgrade(struct bttv *btv); | 85 | static int terratec_active_radio_upgrade(struct bttv *btv); |
84 | static int tea5757_read(struct bttv *btv); | 86 | static int tea5757_read(struct bttv *btv); |
85 | static int tea5757_write(struct bttv *btv, int value); | 87 | static int tea5757_write(struct bttv *btv, int value); |
@@ -284,7 +286,8 @@ static struct CARD { | |||
284 | { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, | 286 | { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, |
285 | { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, | 287 | { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, |
286 | { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, | 288 | { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, |
287 | { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" }, | 289 | { 0x03116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 311" }, |
290 | { 0x06116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 611" }, | ||
288 | { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, | 291 | { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, |
289 | { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, | 292 | { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, |
290 | { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, | 293 | { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, |
@@ -341,6 +344,7 @@ static struct CARD { | |||
341 | { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" }, | 344 | { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" }, |
342 | { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" }, | 345 | { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" }, |
343 | { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" }, | 346 | { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" }, |
347 | { 0x3116f200, BTTV_BOARD_TVT_TD3116, "Tongwei Video Technology TD-3116" }, | ||
344 | 348 | ||
345 | { 0, -1, NULL } | 349 | { 0, -1, NULL } |
346 | }; | 350 | }; |
@@ -1526,10 +1530,10 @@ struct tvcard bttv_tvcards[] = { | |||
1526 | GPIO20,22,23: R30,R29,R28 | 1530 | GPIO20,22,23: R30,R29,R28 |
1527 | */ | 1531 | */ |
1528 | }, | 1532 | }, |
1529 | [BTTV_BOARD_SENSORAY311] = { | 1533 | [BTTV_BOARD_SENSORAY311_611] = { |
1530 | /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ | 1534 | /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ |
1531 | /* you must jumper JP5 for the card to work */ | 1535 | /* you must jumper JP5 for the 311 card (PC/104+) to work */ |
1532 | .name = "Sensoray 311", | 1536 | .name = "Sensoray 311/611", |
1533 | .video_inputs = 5, | 1537 | .video_inputs = 5, |
1534 | /* .audio_inputs= 0, */ | 1538 | /* .audio_inputs= 0, */ |
1535 | .svhs = 4, | 1539 | .svhs = 4, |
@@ -2879,6 +2883,16 @@ struct tvcard bttv_tvcards[] = { | |||
2879 | .tuner_type = TUNER_ABSENT, | 2883 | .tuner_type = TUNER_ABSENT, |
2880 | .tuner_addr = ADDR_UNSET, | 2884 | .tuner_addr = ADDR_UNSET, |
2881 | }, | 2885 | }, |
2886 | [BTTV_BOARD_TVT_TD3116] = { | ||
2887 | .name = "Tongwei Video Technology TD-3116", | ||
2888 | .video_inputs = 16, | ||
2889 | .gpiomask = 0xc00ff, | ||
2890 | .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), | ||
2891 | .muxsel_hook = td3116_muxsel, | ||
2892 | .svhs = NO_SVHS, | ||
2893 | .pll = PLL_28, | ||
2894 | .tuner_type = TUNER_ABSENT, | ||
2895 | }, | ||
2882 | }; | 2896 | }; |
2883 | 2897 | ||
2884 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2898 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
@@ -3228,6 +3242,42 @@ static void geovision_muxsel(struct bttv *btv, unsigned int input) | |||
3228 | gpio_bits(0xf, inmux); | 3242 | gpio_bits(0xf, inmux); |
3229 | } | 3243 | } |
3230 | 3244 | ||
3245 | /* | ||
3246 | * The TD3116 has 2 74HC4051 muxes wired to the MUX0 input of a bt878. | ||
3247 | * The first 74HC4051 has the lower 8 inputs, the second one the higher 8. | ||
3248 | * The muxes are controlled via a 74HC373 latch which is connected to | ||
3249 | * GPIOs 0-7. GPIO 18 is connected to the LE signal of the latch. | ||
3250 | * Q0 of the latch is connected to the Enable (~E) input of the first | ||
3251 | * 74HC4051. Q1 - Q3 are connected to S0 - S2 of the same 74HC4051. | ||
3252 | * Q4 - Q7 are connected to the second 74HC4051 in the same way. | ||
3253 | */ | ||
3254 | |||
3255 | static void td3116_latch_value(struct bttv *btv, u32 value) | ||
3256 | { | ||
3257 | gpio_bits((1<<18) | 0xff, value); | ||
3258 | gpio_bits((1<<18) | 0xff, (1<<18) | value); | ||
3259 | udelay(1); | ||
3260 | gpio_bits((1<<18) | 0xff, value); | ||
3261 | } | ||
3262 | |||
3263 | static void td3116_muxsel(struct bttv *btv, unsigned int input) | ||
3264 | { | ||
3265 | u32 value; | ||
3266 | u32 highbit; | ||
3267 | |||
3268 | highbit = (input & 0x8) >> 3 ; | ||
3269 | |||
3270 | /* Disable outputs and set value in the mux */ | ||
3271 | value = 0x11; /* Disable outputs */ | ||
3272 | value |= ((input & 0x7) << 1) << (4 * highbit); | ||
3273 | td3116_latch_value(btv, value); | ||
3274 | |||
3275 | /* Enable the correct output */ | ||
3276 | value &= ~0x11; | ||
3277 | value |= ((highbit ^ 0x1) << 4) | highbit; | ||
3278 | td3116_latch_value(btv, value); | ||
3279 | } | ||
3280 | |||
3231 | /* ----------------------------------------------------------------------- */ | 3281 | /* ----------------------------------------------------------------------- */ |
3232 | 3282 | ||
3233 | static void bttv_reset_audio(struct bttv *btv) | 3283 | static void bttv_reset_audio(struct bttv *btv) |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 3dd06607aec2..76c301f05095 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -4572,6 +4572,7 @@ static struct pci_device_id bttv_pci_tbl[] = { | |||
4572 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0}, | 4572 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0}, |
4573 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0}, | 4573 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0}, |
4574 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0}, | 4574 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0}, |
4575 | {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0}, | ||
4575 | {0,} | 4576 | {0,} |
4576 | }; | 4577 | }; |
4577 | 4578 | ||
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index e3952af7e56e..580c8e682392 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -346,7 +346,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) | |||
346 | } | 346 | } |
347 | } | 347 | } |
348 | 348 | ||
349 | /* init + register i2c algo-bit adapter */ | 349 | /* init + register i2c adapter */ |
350 | int __devinit init_bttv_i2c(struct bttv *btv) | 350 | int __devinit init_bttv_i2c(struct bttv *btv) |
351 | { | 351 | { |
352 | strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); | 352 | strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index c6333595c6b9..c5171619ac79 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -96,7 +96,7 @@ | |||
96 | #define BTTV_BOARD_PV_BT878P_PLUS 0x46 | 96 | #define BTTV_BOARD_PV_BT878P_PLUS 0x46 |
97 | #define BTTV_BOARD_FLYVIDEO98EZ 0x47 | 97 | #define BTTV_BOARD_FLYVIDEO98EZ 0x47 |
98 | #define BTTV_BOARD_PV_BT878P_9B 0x48 | 98 | #define BTTV_BOARD_PV_BT878P_9B 0x48 |
99 | #define BTTV_BOARD_SENSORAY311 0x49 | 99 | #define BTTV_BOARD_SENSORAY311_611 0x49 |
100 | #define BTTV_BOARD_RV605 0x4a | 100 | #define BTTV_BOARD_RV605 0x4a |
101 | #define BTTV_BOARD_POWERCLR_MTV878 0x4b | 101 | #define BTTV_BOARD_POWERCLR_MTV878 0x4b |
102 | #define BTTV_BOARD_WINDVR 0x4c | 102 | #define BTTV_BOARD_WINDVR 0x4c |
@@ -183,6 +183,7 @@ | |||
183 | #define BTTV_BOARD_GEOVISION_GV800S 0x9d | 183 | #define BTTV_BOARD_GEOVISION_GV800S 0x9d |
184 | #define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e | 184 | #define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e |
185 | #define BTTV_BOARD_PV183 0x9f | 185 | #define BTTV_BOARD_PV183 0x9f |
186 | #define BTTV_BOARD_TVT_TD3116 0xa0 | ||
186 | 187 | ||
187 | 188 | ||
188 | /* more card-specific defines */ | 189 | /* more card-specific defines */ |
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 040aaa87579d..51609d5c88ce 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
@@ -232,7 +232,7 @@ static struct i2c_algo_bit_data cx18_i2c_algo_template = { | |||
232 | .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */ | 232 | .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */ |
233 | }; | 233 | }; |
234 | 234 | ||
235 | /* init + register i2c algo-bit adapter */ | 235 | /* init + register i2c adapter */ |
236 | int init_cx18_i2c(struct cx18 *cx) | 236 | int init_cx18_i2c(struct cx18 *cx) |
237 | { | 237 | { |
238 | int i, err; | 238 | int i, err; |
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h index bdfd1921e300..1180fdc8d983 100644 --- a/drivers/media/video/cx18/cx18-i2c.h +++ b/drivers/media/video/cx18/cx18-i2c.h | |||
@@ -24,6 +24,6 @@ | |||
24 | int cx18_i2c_register(struct cx18 *cx, unsigned idx); | 24 | int cx18_i2c_register(struct cx18 *cx, unsigned idx); |
25 | struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw); | 25 | struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw); |
26 | 26 | ||
27 | /* init + register i2c algo-bit adapter */ | 27 | /* init + register i2c adapter */ |
28 | int init_cx18_i2c(struct cx18 *cx); | 28 | int init_cx18_i2c(struct cx18 *cx); |
29 | void exit_cx18_i2c(struct cx18 *cx); | 29 | void exit_cx18_i2c(struct cx18 *cx); |
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig index ae85a7a7bd73..c74ce9e450e8 100644 --- a/drivers/media/video/cx231xx/Kconfig +++ b/drivers/media/video/cx231xx/Kconfig | |||
@@ -42,8 +42,8 @@ config VIDEO_CX231XX_DVB | |||
42 | tristate "DVB/ATSC Support for Cx231xx based TV cards" | 42 | tristate "DVB/ATSC Support for Cx231xx based TV cards" |
43 | depends on VIDEO_CX231XX && DVB_CORE | 43 | depends on VIDEO_CX231XX && DVB_CORE |
44 | select VIDEOBUF_DVB | 44 | select VIDEOBUF_DVB |
45 | select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE | 45 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE |
46 | select MEDIA_TUNER_NXP18271 if !DVB_FE_CUSTOMISE | 46 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE |
47 | select DVB_MB86A20S if !DVB_FE_CUSTOMISE | 47 | select DVB_MB86A20S if !DVB_FE_CUSTOMISE |
48 | 48 | ||
49 | ---help--- | 49 | ---help--- |
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index c3cf08945e4c..ac03c26d7a63 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -438,6 +438,36 @@ struct cx23885_board cx23885_boards[] = { | |||
438 | .gpio0 = 0, | 438 | .gpio0 = 0, |
439 | } }, | 439 | } }, |
440 | }, | 440 | }, |
441 | [CX23885_BOARD_MYGICA_X8507] = { | ||
442 | .name = "Mygica X8507", | ||
443 | .tuner_type = TUNER_XC5000, | ||
444 | .tuner_addr = 0x61, | ||
445 | .tuner_bus = 1, | ||
446 | .porta = CX23885_ANALOG_VIDEO, | ||
447 | .input = { | ||
448 | { | ||
449 | .type = CX23885_VMUX_TELEVISION, | ||
450 | .vmux = CX25840_COMPOSITE2, | ||
451 | .amux = CX25840_AUDIO8, | ||
452 | }, | ||
453 | { | ||
454 | .type = CX23885_VMUX_COMPOSITE1, | ||
455 | .vmux = CX25840_COMPOSITE8, | ||
456 | }, | ||
457 | { | ||
458 | .type = CX23885_VMUX_SVIDEO, | ||
459 | .vmux = CX25840_SVIDEO_LUMA3 | | ||
460 | CX25840_SVIDEO_CHROMA4, | ||
461 | }, | ||
462 | { | ||
463 | .type = CX23885_VMUX_COMPONENT, | ||
464 | .vmux = CX25840_COMPONENT_ON | | ||
465 | CX25840_VIN1_CH1 | | ||
466 | CX25840_VIN6_CH2 | | ||
467 | CX25840_VIN7_CH3, | ||
468 | }, | ||
469 | }, | ||
470 | } | ||
441 | }; | 471 | }; |
442 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 472 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
443 | 473 | ||
@@ -637,6 +667,10 @@ struct cx23885_subid cx23885_subids[] = { | |||
637 | .subvendor = 0x1b55, | 667 | .subvendor = 0x1b55, |
638 | .subdevice = 0xe2e4, | 668 | .subdevice = 0xe2e4, |
639 | .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF, | 669 | .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF, |
670 | }, { | ||
671 | .subvendor = 0x14f1, | ||
672 | .subdevice = 0x8502, | ||
673 | .card = CX23885_BOARD_MYGICA_X8507, | ||
640 | }, | 674 | }, |
641 | }; | 675 | }; |
642 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 676 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -1068,6 +1102,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1068 | break; | 1102 | break; |
1069 | case CX23885_BOARD_MYGICA_X8506: | 1103 | case CX23885_BOARD_MYGICA_X8506: |
1070 | case CX23885_BOARD_MAGICPRO_PROHDTVE2: | 1104 | case CX23885_BOARD_MAGICPRO_PROHDTVE2: |
1105 | case CX23885_BOARD_MYGICA_X8507: | ||
1071 | /* GPIO-0 (0)Analog / (1)Digital TV */ | 1106 | /* GPIO-0 (0)Analog / (1)Digital TV */ |
1072 | /* GPIO-1 reset XC5000 */ | 1107 | /* GPIO-1 reset XC5000 */ |
1073 | /* GPIO-2 reset LGS8GL5 / LGS8G75 */ | 1108 | /* GPIO-2 reset LGS8GL5 / LGS8G75 */ |
@@ -1468,6 +1503,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1468 | case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: | 1503 | case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: |
1469 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 1504 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
1470 | case CX23885_BOARD_MPX885: | 1505 | case CX23885_BOARD_MPX885: |
1506 | case CX23885_BOARD_MYGICA_X8507: | ||
1471 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1507 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1472 | &dev->i2c_bus[2].i2c_adap, | 1508 | &dev->i2c_bus[2].i2c_adap, |
1473 | "cx25840", 0x88 >> 1, NULL); | 1509 | "cx25840", 0x88 >> 1, NULL); |
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 0ff7a9e98f3e..be1e21d8295c 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c | |||
@@ -309,7 +309,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) | |||
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | /* init + register i2c algo-bit adapter */ | 312 | /* init + register i2c adapter */ |
313 | int cx23885_i2c_register(struct cx23885_i2c *bus) | 313 | int cx23885_i2c_register(struct cx23885_i2c *bus) |
314 | { | 314 | { |
315 | struct cx23885_dev *dev = bus->dev; | 315 | struct cx23885_dev *dev = bus->dev; |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index e730b9263016..7415524e8777 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -492,7 +492,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) | |||
492 | dev->input = input; | 492 | dev->input = input; |
493 | 493 | ||
494 | if (dev->board == CX23885_BOARD_MYGICA_X8506 || | 494 | if (dev->board == CX23885_BOARD_MYGICA_X8506 || |
495 | dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) { | 495 | dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2 || |
496 | dev->board == CX23885_BOARD_MYGICA_X8507) { | ||
496 | /* Select Analog TV */ | 497 | /* Select Analog TV */ |
497 | if (INPUT(input)->type == CX23885_VMUX_TELEVISION) | 498 | if (INPUT(input)->type == CX23885_VMUX_TELEVISION) |
498 | cx23885_gpio_clear(dev, GPIO_0); | 499 | cx23885_gpio_clear(dev, GPIO_0); |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index b49036fe3ffd..519f40d2af5d 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -87,6 +87,7 @@ | |||
87 | #define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30 | 87 | #define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30 |
88 | #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31 | 88 | #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31 |
89 | #define CX23885_BOARD_MPX885 32 | 89 | #define CX23885_BOARD_MPX885 32 |
90 | #define CX23885_BOARD_MYGICA_X8507 33 | ||
90 | 91 | ||
91 | #define GPIO_0 0x00000001 | 92 | #define GPIO_0 0x00000001 |
92 | #define GPIO_1 0x00000002 | 93 | #define GPIO_1 0x00000002 |
diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c index 09e99de5fd21..6142ae2aee40 100644 --- a/drivers/media/video/cx25821/cx25821-alsa.c +++ b/drivers/media/video/cx25821/cx25821-alsa.c | |||
@@ -176,8 +176,7 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) | |||
176 | 176 | ||
177 | /* Set the input mode to 16-bit */ | 177 | /* Set the input mode to 16-bit */ |
178 | tmp = cx_read(AUD_A_CFG); | 178 | tmp = cx_read(AUD_A_CFG); |
179 | cx_write(AUD_A_CFG, | 179 | cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | |
180 | tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | | ||
181 | FLD_AUD_CLK_ENABLE); | 180 | FLD_AUD_CLK_ENABLE); |
182 | 181 | ||
183 | /* | 182 | /* |
@@ -188,9 +187,8 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) | |||
188 | */ | 187 | */ |
189 | 188 | ||
190 | /* Enables corresponding bits at AUD_INT_STAT */ | 189 | /* Enables corresponding bits at AUD_INT_STAT */ |
191 | cx_write(AUD_A_INT_MSK, | 190 | cx_write(AUD_A_INT_MSK, FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | |
192 | FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC | | 191 | FLD_AUD_DST_SYNC | FLD_AUD_DST_OPC_ERR); |
193 | FLD_AUD_DST_OPC_ERR); | ||
194 | 192 | ||
195 | /* Clean any pending interrupt bits already set */ | 193 | /* Clean any pending interrupt bits already set */ |
196 | cx_write(AUD_A_INT_STAT, ~0); | 194 | cx_write(AUD_A_INT_STAT, ~0); |
@@ -200,8 +198,8 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) | |||
200 | 198 | ||
201 | /* Turn on audio downstream fifo and risc enable 0x101 */ | 199 | /* Turn on audio downstream fifo and risc enable 0x101 */ |
202 | tmp = cx_read(AUD_INT_DMA_CTL); | 200 | tmp = cx_read(AUD_INT_DMA_CTL); |
203 | cx_set(AUD_INT_DMA_CTL, | 201 | cx_set(AUD_INT_DMA_CTL, tmp | |
204 | tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); | 202 | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); |
205 | 203 | ||
206 | mdelay(100); | 204 | mdelay(100); |
207 | return 0; | 205 | return 0; |
@@ -220,9 +218,8 @@ static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip) | |||
220 | 218 | ||
221 | /* disable irqs */ | 219 | /* disable irqs */ |
222 | cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT); | 220 | cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT); |
223 | cx_clear(AUD_A_INT_MSK, | 221 | cx_clear(AUD_A_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | |
224 | AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 | | 222 | AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1); |
225 | AUD_INT_DN_RISCI1); | ||
226 | 223 | ||
227 | return 0; | 224 | return 0; |
228 | } | 225 | } |
@@ -234,15 +231,15 @@ static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip) | |||
234 | */ | 231 | */ |
235 | static char *cx25821_aud_irqs[32] = { | 232 | static char *cx25821_aud_irqs[32] = { |
236 | "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ | 233 | "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ |
237 | NULL, /* reserved */ | 234 | NULL, /* reserved */ |
238 | "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ | 235 | "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ |
239 | NULL, /* reserved */ | 236 | NULL, /* reserved */ |
240 | "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ | 237 | "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ |
241 | NULL, /* reserved */ | 238 | NULL, /* reserved */ |
242 | "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ | 239 | "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ |
243 | NULL, /* reserved */ | 240 | NULL, /* reserved */ |
244 | "opc_err", "par_err", "rip_err", /* 16-18 */ | 241 | "opc_err", "par_err", "rip_err", /* 16-18 */ |
245 | "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ | 242 | "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ |
246 | }; | 243 | }; |
247 | 244 | ||
248 | /* | 245 | /* |
@@ -258,10 +255,8 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status, | |||
258 | 255 | ||
259 | cx_write(AUD_A_INT_STAT, status); | 256 | cx_write(AUD_A_INT_STAT, status); |
260 | if (debug > 1 || (status & mask & ~0xff)) | 257 | if (debug > 1 || (status & mask & ~0xff)) |
261 | cx25821_print_irqbits(dev->name, "irq aud", | 258 | cx25821_print_irqbits(dev->name, "irq aud", cx25821_aud_irqs, |
262 | cx25821_aud_irqs, | 259 | ARRAY_SIZE(cx25821_aud_irqs), status, mask); |
263 | ARRAY_SIZE(cx25821_aud_irqs), status, | ||
264 | mask); | ||
265 | 260 | ||
266 | /* risc op code error */ | 261 | /* risc op code error */ |
267 | if (status & AUD_INT_OPC_ERR) { | 262 | if (status & AUD_INT_OPC_ERR) { |
@@ -270,8 +265,7 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status, | |||
270 | cx_clear(AUD_INT_DMA_CTL, | 265 | cx_clear(AUD_INT_DMA_CTL, |
271 | FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN); | 266 | FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN); |
272 | cx25821_sram_channel_dump_audio(dev, | 267 | cx25821_sram_channel_dump_audio(dev, |
273 | &cx25821_sram_channels | 268 | &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]); |
274 | [AUDIO_SRAM_CHANNEL]); | ||
275 | } | 269 | } |
276 | if (status & AUD_INT_DN_SYNC) { | 270 | if (status & AUD_INT_DN_SYNC) { |
277 | pr_warn("WARNING %s: Downstream sync error!\n", dev->name); | 271 | pr_warn("WARNING %s: Downstream sync error!\n", dev->name); |
@@ -317,8 +311,9 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id) | |||
317 | cx25821_aud_irq(chip, audint_status, | 311 | cx25821_aud_irq(chip, audint_status, |
318 | audint_mask); | 312 | audint_mask); |
319 | break; | 313 | break; |
320 | } else | 314 | } else { |
321 | goto out; | 315 | goto out; |
316 | } | ||
322 | } | 317 | } |
323 | 318 | ||
324 | handled = 1; | 319 | handled = 1; |
@@ -361,9 +356,8 @@ static int dsp_buffer_free(struct cx25821_audio_dev *chip) | |||
361 | */ | 356 | */ |
362 | #define DEFAULT_FIFO_SIZE 384 | 357 | #define DEFAULT_FIFO_SIZE 384 |
363 | static struct snd_pcm_hardware snd_cx25821_digital_hw = { | 358 | static struct snd_pcm_hardware snd_cx25821_digital_hw = { |
364 | .info = SNDRV_PCM_INFO_MMAP | | 359 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
365 | SNDRV_PCM_INFO_INTERLEAVED | | 360 | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, |
366 | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, | ||
367 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 361 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
368 | 362 | ||
369 | .rates = SNDRV_PCM_RATE_48000, | 363 | .rates = SNDRV_PCM_RATE_48000, |
@@ -396,8 +390,8 @@ static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream) | |||
396 | return -ENODEV; | 390 | return -ENODEV; |
397 | } | 391 | } |
398 | 392 | ||
399 | err = | 393 | err = snd_pcm_hw_constraint_pow2(runtime, 0, |
400 | snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS); | 394 | SNDRV_PCM_HW_PARAM_PERIODS); |
401 | if (err < 0) | 395 | if (err < 0) |
402 | goto _error; | 396 | goto _error; |
403 | 397 | ||
@@ -468,8 +462,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, | |||
468 | dma = &buf->dma; | 462 | dma = &buf->dma; |
469 | videobuf_dma_init(dma); | 463 | videobuf_dma_init(dma); |
470 | ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, | 464 | ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, |
471 | (PAGE_ALIGN(chip->dma_size) >> | 465 | (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); |
472 | PAGE_SHIFT)); | ||
473 | if (ret < 0) | 466 | if (ret < 0) |
474 | goto error; | 467 | goto error; |
475 | 468 | ||
@@ -477,10 +470,8 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, | |||
477 | if (ret < 0) | 470 | if (ret < 0) |
478 | goto error; | 471 | goto error; |
479 | 472 | ||
480 | ret = | 473 | ret = cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist, |
481 | cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist, | 474 | chip->period_size, chip->num_periods, 1); |
482 | chip->period_size, chip->num_periods, | ||
483 | 1); | ||
484 | if (ret < 0) { | 475 | if (ret < 0) { |
485 | pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n"); | 476 | pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n"); |
486 | goto error; | 477 | goto error; |
@@ -686,7 +677,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) | |||
686 | } | 677 | } |
687 | 678 | ||
688 | err = snd_card_create(index[devno], id[devno], THIS_MODULE, | 679 | err = snd_card_create(index[devno], id[devno], THIS_MODULE, |
689 | sizeof(struct cx25821_audio_dev), &card); | 680 | sizeof(struct cx25821_audio_dev), &card); |
690 | if (err < 0) { | 681 | if (err < 0) { |
691 | pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n", | 682 | pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n", |
692 | __func__); | 683 | __func__); |
@@ -711,8 +702,8 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) | |||
711 | IRQF_SHARED, chip->dev->name, chip); | 702 | IRQF_SHARED, chip->dev->name, chip); |
712 | 703 | ||
713 | if (err < 0) { | 704 | if (err < 0) { |
714 | pr_err("ERROR %s: can't get IRQ %d for ALSA\n", | 705 | pr_err("ERROR %s: can't get IRQ %d for ALSA\n", chip->dev->name, |
715 | chip->dev->name, dev->pci->irq); | 706 | dev->pci->irq); |
716 | goto error; | 707 | goto error; |
717 | } | 708 | } |
718 | 709 | ||
@@ -730,8 +721,8 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) | |||
730 | chip->iobase, chip->irq); | 721 | chip->iobase, chip->irq); |
731 | strcpy(card->mixername, "CX25821"); | 722 | strcpy(card->mixername, "CX25821"); |
732 | 723 | ||
733 | pr_info("%s/%i: ALSA support for cx25821 boards\n", | 724 | pr_info("%s/%i: ALSA support for cx25821 boards\n", card->driver, |
734 | card->driver, devno); | 725 | devno); |
735 | 726 | ||
736 | err = snd_card_register(card); | 727 | err = snd_card_register(card); |
737 | if (err < 0) { | 728 | if (err < 0) { |
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c index c20d6dece154..20c7ca3351a8 100644 --- a/drivers/media/video/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c | |||
@@ -107,7 +107,7 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev, | |||
107 | { | 107 | { |
108 | unsigned int line; | 108 | unsigned int line; |
109 | struct sram_channel *sram_ch = | 109 | struct sram_channel *sram_ch = |
110 | dev->channels[dev->_audio_upstream_channel].sram_channels; | 110 | dev->channels[dev->_audio_upstream_channel].sram_channels; |
111 | int offset = 0; | 111 | int offset = 0; |
112 | 112 | ||
113 | /* scan lines */ | 113 | /* scan lines */ |
@@ -175,10 +175,8 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev, | |||
175 | } | 175 | } |
176 | 176 | ||
177 | rp = cx25821_risc_field_upstream_audio(dev, rp, | 177 | rp = cx25821_risc_field_upstream_audio(dev, rp, |
178 | dev-> | 178 | dev->_audiodata_buf_phys_addr + databuf_offset, |
179 | _audiodata_buf_phys_addr | 179 | bpl, fifo_enable); |
180 | + databuf_offset, bpl, | ||
181 | fifo_enable); | ||
182 | 180 | ||
183 | if (USE_RISC_NOOP_AUDIO) { | 181 | if (USE_RISC_NOOP_AUDIO) { |
184 | for (i = 0; i < NUM_NO_OPS; i++) | 182 | for (i = 0; i < NUM_NO_OPS; i++) |
@@ -193,7 +191,7 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev, | |||
193 | 191 | ||
194 | /* Recalculate virtual address based on frame index */ | 192 | /* Recalculate virtual address based on frame index */ |
195 | rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 + | 193 | rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 + |
196 | (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4); | 194 | (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4); |
197 | } | 195 | } |
198 | 196 | ||
199 | return 0; | 197 | return 0; |
@@ -218,7 +216,7 @@ void cx25821_free_memory_audio(struct cx25821_dev *dev) | |||
218 | void cx25821_stop_upstream_audio(struct cx25821_dev *dev) | 216 | void cx25821_stop_upstream_audio(struct cx25821_dev *dev) |
219 | { | 217 | { |
220 | struct sram_channel *sram_ch = | 218 | struct sram_channel *sram_ch = |
221 | dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; | 219 | dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; |
222 | u32 tmp = 0; | 220 | u32 tmp = 0; |
223 | 221 | ||
224 | if (!dev->_audio_is_running) { | 222 | if (!dev->_audio_is_running) { |
@@ -286,14 +284,14 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, | |||
286 | } else { | 284 | } else { |
287 | if (!(myfile->f_op)) { | 285 | if (!(myfile->f_op)) { |
288 | pr_err("%s(): File has no file operations registered!\n", | 286 | pr_err("%s(): File has no file operations registered!\n", |
289 | __func__); | 287 | __func__); |
290 | filp_close(myfile, NULL); | 288 | filp_close(myfile, NULL); |
291 | return -EIO; | 289 | return -EIO; |
292 | } | 290 | } |
293 | 291 | ||
294 | if (!myfile->f_op->read) { | 292 | if (!myfile->f_op->read) { |
295 | pr_err("%s(): File has no READ operations registered!\n", | 293 | pr_err("%s(): File has no READ operations registered!\n", |
296 | __func__); | 294 | __func__); |
297 | filp_close(myfile, NULL); | 295 | filp_close(myfile, NULL); |
298 | return -EIO; | 296 | return -EIO; |
299 | } | 297 | } |
@@ -305,14 +303,14 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, | |||
305 | for (i = 0; i < dev->_audio_lines_count; i++) { | 303 | for (i = 0; i < dev->_audio_lines_count; i++) { |
306 | pos = file_offset; | 304 | pos = file_offset; |
307 | 305 | ||
308 | vfs_read_retval = | 306 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, |
309 | vfs_read(myfile, mybuf, line_size, &pos); | 307 | &pos); |
310 | 308 | ||
311 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | 309 | if (vfs_read_retval > 0 && vfs_read_retval == line_size |
312 | && dev->_audiodata_buf_virt_addr != NULL) { | 310 | && dev->_audiodata_buf_virt_addr != NULL) { |
313 | memcpy((void *)(dev->_audiodata_buf_virt_addr + | 311 | memcpy((void *)(dev->_audiodata_buf_virt_addr + |
314 | frame_offset / 4), mybuf, | 312 | frame_offset / 4), mybuf, |
315 | vfs_read_retval); | 313 | vfs_read_retval); |
316 | } | 314 | } |
317 | 315 | ||
318 | file_offset += vfs_read_retval; | 316 | file_offset += vfs_read_retval; |
@@ -328,8 +326,8 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, | |||
328 | if (i > 0) | 326 | if (i > 0) |
329 | dev->_audioframe_count++; | 327 | dev->_audioframe_count++; |
330 | 328 | ||
331 | dev->_audiofile_status = | 329 | dev->_audiofile_status = (vfs_read_retval == line_size) ? |
332 | (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; | 330 | IN_PROGRESS : END_OF_FILE; |
333 | 331 | ||
334 | set_fs(old_fs); | 332 | set_fs(old_fs); |
335 | filp_close(myfile, NULL); | 333 | filp_close(myfile, NULL); |
@@ -340,12 +338,12 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, | |||
340 | 338 | ||
341 | static void cx25821_audioups_handler(struct work_struct *work) | 339 | static void cx25821_audioups_handler(struct work_struct *work) |
342 | { | 340 | { |
343 | struct cx25821_dev *dev = | 341 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, |
344 | container_of(work, struct cx25821_dev, _audio_work_entry); | 342 | _audio_work_entry); |
345 | 343 | ||
346 | if (!dev) { | 344 | if (!dev) { |
347 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | 345 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", |
348 | __func__); | 346 | __func__); |
349 | return; | 347 | return; |
350 | } | 348 | } |
351 | 349 | ||
@@ -370,19 +368,19 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, | |||
370 | if (IS_ERR(myfile)) { | 368 | if (IS_ERR(myfile)) { |
371 | const int open_errno = -PTR_ERR(myfile); | 369 | const int open_errno = -PTR_ERR(myfile); |
372 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | 370 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", |
373 | __func__, dev->_audiofilename, open_errno); | 371 | __func__, dev->_audiofilename, open_errno); |
374 | return PTR_ERR(myfile); | 372 | return PTR_ERR(myfile); |
375 | } else { | 373 | } else { |
376 | if (!(myfile->f_op)) { | 374 | if (!(myfile->f_op)) { |
377 | pr_err("%s(): File has no file operations registered!\n", | 375 | pr_err("%s(): File has no file operations registered!\n", |
378 | __func__); | 376 | __func__); |
379 | filp_close(myfile, NULL); | 377 | filp_close(myfile, NULL); |
380 | return -EIO; | 378 | return -EIO; |
381 | } | 379 | } |
382 | 380 | ||
383 | if (!myfile->f_op->read) { | 381 | if (!myfile->f_op->read) { |
384 | pr_err("%s(): File has no READ operations registered!\n", | 382 | pr_err("%s(): File has no READ operations registered!\n", |
385 | __func__); | 383 | __func__); |
386 | filp_close(myfile, NULL); | 384 | filp_close(myfile, NULL); |
387 | return -EIO; | 385 | return -EIO; |
388 | } | 386 | } |
@@ -395,12 +393,12 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, | |||
395 | for (i = 0; i < dev->_audio_lines_count; i++) { | 393 | for (i = 0; i < dev->_audio_lines_count; i++) { |
396 | pos = offset; | 394 | pos = offset; |
397 | 395 | ||
398 | vfs_read_retval = | 396 | vfs_read_retval = vfs_read(myfile, mybuf, |
399 | vfs_read(myfile, mybuf, line_size, &pos); | 397 | line_size, &pos); |
400 | 398 | ||
401 | if (vfs_read_retval > 0 | 399 | if (vfs_read_retval > 0 && |
402 | && vfs_read_retval == line_size | 400 | vfs_read_retval == line_size && |
403 | && dev->_audiodata_buf_virt_addr != NULL) { | 401 | dev->_audiodata_buf_virt_addr != NULL) { |
404 | memcpy((void *)(dev-> | 402 | memcpy((void *)(dev-> |
405 | _audiodata_buf_virt_addr | 403 | _audiodata_buf_virt_addr |
406 | + offset / 4), mybuf, | 404 | + offset / 4), mybuf, |
@@ -423,8 +421,8 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, | |||
423 | break; | 421 | break; |
424 | } | 422 | } |
425 | 423 | ||
426 | dev->_audiofile_status = | 424 | dev->_audiofile_status = (vfs_read_retval == line_size) ? |
427 | (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; | 425 | IN_PROGRESS : END_OF_FILE; |
428 | 426 | ||
429 | set_fs(old_fs); | 427 | set_fs(old_fs); |
430 | myfile->f_pos = 0; | 428 | myfile->f_pos = 0; |
@@ -444,9 +442,8 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, | |||
444 | 442 | ||
445 | cx25821_free_memory_audio(dev); | 443 | cx25821_free_memory_audio(dev); |
446 | 444 | ||
447 | dev->_risc_virt_addr = | 445 | dev->_risc_virt_addr = pci_alloc_consistent(dev->pci, |
448 | pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size, | 446 | dev->audio_upstream_riscbuf_size, &dma_addr); |
449 | &dma_addr); | ||
450 | dev->_risc_virt_start_addr = dev->_risc_virt_addr; | 447 | dev->_risc_virt_start_addr = dev->_risc_virt_addr; |
451 | dev->_risc_phys_start_addr = dma_addr; | 448 | dev->_risc_phys_start_addr = dma_addr; |
452 | dev->_risc_phys_addr = dma_addr; | 449 | dev->_risc_phys_addr = dma_addr; |
@@ -454,22 +451,21 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, | |||
454 | 451 | ||
455 | if (!dev->_risc_virt_addr) { | 452 | if (!dev->_risc_virt_addr) { |
456 | printk(KERN_DEBUG | 453 | printk(KERN_DEBUG |
457 | pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n")); | 454 | pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n")); |
458 | return -ENOMEM; | 455 | return -ENOMEM; |
459 | } | 456 | } |
460 | /* Clear out memory at address */ | 457 | /* Clear out memory at address */ |
461 | memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size); | 458 | memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size); |
462 | 459 | ||
463 | /* For Audio Data buffer allocation */ | 460 | /* For Audio Data buffer allocation */ |
464 | dev->_audiodata_buf_virt_addr = | 461 | dev->_audiodata_buf_virt_addr = pci_alloc_consistent(dev->pci, |
465 | pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size, | 462 | dev->audio_upstream_databuf_size, &data_dma_addr); |
466 | &data_dma_addr); | ||
467 | dev->_audiodata_buf_phys_addr = data_dma_addr; | 463 | dev->_audiodata_buf_phys_addr = data_dma_addr; |
468 | dev->_audiodata_buf_size = dev->audio_upstream_databuf_size; | 464 | dev->_audiodata_buf_size = dev->audio_upstream_databuf_size; |
469 | 465 | ||
470 | if (!dev->_audiodata_buf_virt_addr) { | 466 | if (!dev->_audiodata_buf_virt_addr) { |
471 | printk(KERN_DEBUG | 467 | printk(KERN_DEBUG |
472 | pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n")); | 468 | pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n")); |
473 | return -ENOMEM; | 469 | return -ENOMEM; |
474 | } | 470 | } |
475 | /* Clear out memory at address */ | 471 | /* Clear out memory at address */ |
@@ -480,12 +476,11 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, | |||
480 | return ret; | 476 | return ret; |
481 | 477 | ||
482 | /* Creating RISC programs */ | 478 | /* Creating RISC programs */ |
483 | ret = | 479 | ret = cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, |
484 | cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, | 480 | dev->_audio_lines_count); |
485 | dev->_audio_lines_count); | ||
486 | if (ret < 0) { | 481 | if (ret < 0) { |
487 | printk(KERN_DEBUG | 482 | printk(KERN_DEBUG |
488 | pr_fmt("ERROR creating audio upstream RISC programs!\n")); | 483 | pr_fmt("ERROR creating audio upstream RISC programs!\n")); |
489 | goto error; | 484 | goto error; |
490 | } | 485 | } |
491 | 486 | ||
@@ -533,9 +528,9 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
533 | 528 | ||
534 | if (dev->_risc_virt_start_addr != NULL) { | 529 | if (dev->_risc_virt_start_addr != NULL) { |
535 | risc_phys_jump_addr = | 530 | risc_phys_jump_addr = |
536 | dev->_risc_phys_start_addr + | 531 | dev->_risc_phys_start_addr + |
537 | RISC_SYNC_INSTRUCTION_SIZE + | 532 | RISC_SYNC_INSTRUCTION_SIZE + |
538 | AUDIO_RISC_DMA_BUF_SIZE; | 533 | AUDIO_RISC_DMA_BUF_SIZE; |
539 | 534 | ||
540 | rp = cx25821_risc_field_upstream_audio(dev, | 535 | rp = cx25821_risc_field_upstream_audio(dev, |
541 | dev->_risc_virt_start_addr + 1, | 536 | dev->_risc_virt_start_addr + 1, |
@@ -632,7 +627,7 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, | |||
632 | /* 10 millisecond timeout */ | 627 | /* 10 millisecond timeout */ |
633 | if (count++ > 1000) { | 628 | if (count++ > 1000) { |
634 | pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n", | 629 | pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n", |
635 | __func__); | 630 | __func__); |
636 | return; | 631 | return; |
637 | } | 632 | } |
638 | 633 | ||
@@ -661,9 +656,9 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, | |||
661 | 656 | ||
662 | /* Set the input mode to 16-bit */ | 657 | /* Set the input mode to 16-bit */ |
663 | tmp = cx_read(sram_ch->aud_cfg); | 658 | tmp = cx_read(sram_ch->aud_cfg); |
664 | tmp |= | 659 | tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | |
665 | FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | | 660 | FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | |
666 | FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE; | 661 | FLD_AUD_SONY_MODE; |
667 | cx_write(sram_ch->aud_cfg, tmp); | 662 | cx_write(sram_ch->aud_cfg, tmp); |
668 | 663 | ||
669 | /* Read and write back the interrupt status register to clear it */ | 664 | /* Read and write back the interrupt status register to clear it */ |
@@ -678,12 +673,11 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, | |||
678 | tmp = cx_read(sram_ch->int_msk); | 673 | tmp = cx_read(sram_ch->int_msk); |
679 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | 674 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); |
680 | 675 | ||
681 | err = | 676 | err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio, |
682 | request_irq(dev->pci->irq, cx25821_upstream_irq_audio, | ||
683 | IRQF_SHARED, dev->name, dev); | 677 | IRQF_SHARED, dev->name, dev); |
684 | if (err < 0) { | 678 | if (err < 0) { |
685 | pr_err("%s: can't get upstream IRQ %d\n", | 679 | pr_err("%s: can't get upstream IRQ %d\n", dev->name, |
686 | dev->name, dev->pci->irq); | 680 | dev->pci->irq); |
687 | goto fail_irq; | 681 | goto fail_irq; |
688 | } | 682 | } |
689 | 683 | ||
@@ -726,7 +720,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) | |||
726 | 720 | ||
727 | if (!dev->_irq_audio_queues) { | 721 | if (!dev->_irq_audio_queues) { |
728 | printk(KERN_DEBUG | 722 | printk(KERN_DEBUG |
729 | pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n")); | 723 | pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n")); |
730 | return -ENOMEM; | 724 | return -ENOMEM; |
731 | } | 725 | } |
732 | 726 | ||
@@ -739,33 +733,30 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) | |||
739 | 733 | ||
740 | if (dev->input_audiofilename) { | 734 | if (dev->input_audiofilename) { |
741 | str_length = strlen(dev->input_audiofilename); | 735 | str_length = strlen(dev->input_audiofilename); |
742 | dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); | 736 | dev->_audiofilename = kmemdup(dev->input_audiofilename, |
737 | str_length + 1, GFP_KERNEL); | ||
743 | 738 | ||
744 | if (!dev->_audiofilename) | 739 | if (!dev->_audiofilename) |
745 | goto error; | 740 | goto error; |
746 | 741 | ||
747 | memcpy(dev->_audiofilename, dev->input_audiofilename, | ||
748 | str_length + 1); | ||
749 | |||
750 | /* Default if filename is empty string */ | 742 | /* Default if filename is empty string */ |
751 | if (strcmp(dev->input_audiofilename, "") == 0) | 743 | if (strcmp(dev->input_audiofilename, "") == 0) |
752 | dev->_audiofilename = "/root/audioGOOD.wav"; | 744 | dev->_audiofilename = "/root/audioGOOD.wav"; |
753 | } else { | 745 | } else { |
754 | str_length = strlen(_defaultAudioName); | 746 | str_length = strlen(_defaultAudioName); |
755 | dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); | 747 | dev->_audiofilename = kmemdup(_defaultAudioName, |
748 | str_length + 1, GFP_KERNEL); | ||
756 | 749 | ||
757 | if (!dev->_audiofilename) | 750 | if (!dev->_audiofilename) |
758 | goto error; | 751 | goto error; |
759 | |||
760 | memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1); | ||
761 | } | 752 | } |
762 | 753 | ||
763 | retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, | 754 | retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, |
764 | _line_size, 0); | 755 | _line_size, 0); |
765 | 756 | ||
766 | dev->audio_upstream_riscbuf_size = | 757 | dev->audio_upstream_riscbuf_size = |
767 | AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS + | 758 | AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS + |
768 | RISC_SYNC_INSTRUCTION_SIZE; | 759 | RISC_SYNC_INSTRUCTION_SIZE; |
769 | dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS; | 760 | dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS; |
770 | 761 | ||
771 | /* Allocating buffers and prepare RISC program */ | 762 | /* Allocating buffers and prepare RISC program */ |
@@ -773,7 +764,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) | |||
773 | _line_size); | 764 | _line_size); |
774 | if (retval < 0) { | 765 | if (retval < 0) { |
775 | pr_err("%s: Failed to set up Audio upstream buffers!\n", | 766 | pr_err("%s: Failed to set up Audio upstream buffers!\n", |
776 | dev->name); | 767 | dev->name); |
777 | goto error; | 768 | goto error; |
778 | } | 769 | } |
779 | /* Start RISC engine */ | 770 | /* Start RISC engine */ |
diff --git a/drivers/media/video/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h index 8eb55b7b88cb..1fc2d24f5110 100644 --- a/drivers/media/video/cx25821/cx25821-audio.h +++ b/drivers/media/video/cx25821/cx25821-audio.h | |||
@@ -23,39 +23,40 @@ | |||
23 | #ifndef __CX25821_AUDIO_H__ | 23 | #ifndef __CX25821_AUDIO_H__ |
24 | #define __CX25821_AUDIO_H__ | 24 | #define __CX25821_AUDIO_H__ |
25 | 25 | ||
26 | #define USE_RISC_NOOP 1 | 26 | #define USE_RISC_NOOP 1 |
27 | #define LINES_PER_BUFFER 15 | 27 | #define LINES_PER_BUFFER 15 |
28 | #define AUDIO_LINE_SIZE 128 | 28 | #define AUDIO_LINE_SIZE 128 |
29 | 29 | ||
30 | /* Number of buffer programs to use at once. */ | 30 | /* Number of buffer programs to use at once. */ |
31 | #define NUMBER_OF_PROGRAMS 8 | 31 | #define NUMBER_OF_PROGRAMS 8 |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Max size of the RISC program for a buffer. - worst case is 2 writes per line | 34 | * Max size of the RISC program for a buffer. - worst case is 2 writes per line |
35 | * Space is also added for the 4 no-op instructions added on the end. | 35 | * Space is also added for the 4 no-op instructions added on the end. |
36 | */ | 36 | */ |
37 | #ifndef USE_RISC_NOOP | 37 | #ifndef USE_RISC_NOOP |
38 | #define MAX_BUFFER_PROGRAM_SIZE \ | 38 | #define MAX_BUFFER_PROGRAM_SIZE \ |
39 | (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ | 39 | (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ |
40 | RISC_WRITECR_INSTRUCTION_SIZE * 4) | 40 | RISC_WRITECR_INSTRUCTION_SIZE * 4) |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */ | 43 | /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */ |
44 | #ifdef USE_RISC_NOOP | 44 | #ifdef USE_RISC_NOOP |
45 | #define MAX_BUFFER_PROGRAM_SIZE \ | 45 | #define MAX_BUFFER_PROGRAM_SIZE \ |
46 | (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ | 46 | (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ |
47 | RISC_NOOP_INSTRUCTION_SIZE * 4) | 47 | RISC_NOOP_INSTRUCTION_SIZE * 4) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | /* Sizes of various instructions in bytes. Used when adding instructions. */ | 50 | /* Sizes of various instructions in bytes. Used when adding instructions. */ |
51 | #define RISC_WRITE_INSTRUCTION_SIZE 12 | 51 | #define RISC_WRITE_INSTRUCTION_SIZE 12 |
52 | #define RISC_JUMP_INSTRUCTION_SIZE 12 | 52 | #define RISC_JUMP_INSTRUCTION_SIZE 12 |
53 | #define RISC_SKIP_INSTRUCTION_SIZE 4 | 53 | #define RISC_SKIP_INSTRUCTION_SIZE 4 |
54 | #define RISC_SYNC_INSTRUCTION_SIZE 4 | 54 | #define RISC_SYNC_INSTRUCTION_SIZE 4 |
55 | #define RISC_WRITECR_INSTRUCTION_SIZE 16 | 55 | #define RISC_WRITECR_INSTRUCTION_SIZE 16 |
56 | #define RISC_NOOP_INSTRUCTION_SIZE 4 | 56 | #define RISC_NOOP_INSTRUCTION_SIZE 4 |
57 | 57 | ||
58 | #define MAX_AUDIO_DMA_BUFFER_SIZE \ | 58 | #define MAX_AUDIO_DMA_BUFFER_SIZE \ |
59 | (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE) | 59 | (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + \ |
60 | RISC_SYNC_INSTRUCTION_SIZE) | ||
60 | 61 | ||
61 | #endif | 62 | #endif |
diff --git a/drivers/media/video/cx25821/cx25821-cards.c b/drivers/media/video/cx25821/cx25821-cards.c index 6ace60313b49..99988c988095 100644 --- a/drivers/media/video/cx25821/cx25821-cards.c +++ b/drivers/media/video/cx25821/cx25821-cards.c | |||
@@ -67,6 +67,6 @@ void cx25821_card_setup(struct cx25821_dev *dev) | |||
67 | if (dev->i2c_bus[0].i2c_rc == 0) { | 67 | if (dev->i2c_bus[0].i2c_rc == 0) { |
68 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; | 68 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; |
69 | tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, | 69 | tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, |
70 | sizeof(eeprom)); | 70 | sizeof(eeprom)); |
71 | } | 71 | } |
72 | } | 72 | } |
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c index a7fa38f9594e..f617474f9073 100644 --- a/drivers/media/video/cx25821/cx25821-core.c +++ b/drivers/media/video/cx25821/cx25821-core.c | |||
@@ -804,8 +804,8 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, | |||
804 | u32 format) | 804 | u32 format) |
805 | { | 805 | { |
806 | if (channel_select <= 7 && channel_select >= 0) { | 806 | if (channel_select <= 7 && channel_select >= 0) { |
807 | cx_write(dev->channels[channel_select]. | 807 | cx_write(dev->channels[channel_select].sram_channels->pix_frmt, |
808 | sram_channels->pix_frmt, format); | 808 | format); |
809 | dev->channels[channel_select].pixel_formats = format; | 809 | dev->channels[channel_select].pixel_formats = format; |
810 | } | 810 | } |
811 | } | 811 | } |
@@ -855,21 +855,19 @@ static void cx25821_initialize(struct cx25821_dev *dev) | |||
855 | } | 855 | } |
856 | 856 | ||
857 | cx25821_sram_channel_setup_audio(dev, | 857 | cx25821_sram_channel_setup_audio(dev, |
858 | dev->channels[SRAM_CH08].sram_channels, | 858 | dev->channels[SRAM_CH08].sram_channels, 128, 0); |
859 | 128, 0); | ||
860 | 859 | ||
861 | cx25821_gpio_init(dev); | 860 | cx25821_gpio_init(dev); |
862 | } | 861 | } |
863 | 862 | ||
864 | static int cx25821_get_resources(struct cx25821_dev *dev) | 863 | static int cx25821_get_resources(struct cx25821_dev *dev) |
865 | { | 864 | { |
866 | if (request_mem_region | 865 | if (request_mem_region(pci_resource_start(dev->pci, 0), |
867 | (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0), | 866 | pci_resource_len(dev->pci, 0), dev->name)) |
868 | dev->name)) | ||
869 | return 0; | 867 | return 0; |
870 | 868 | ||
871 | pr_err("%s: can't get MMIO memory @ 0x%llx\n", | 869 | pr_err("%s: can't get MMIO memory @ 0x%llx\n", |
872 | dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); | 870 | dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); |
873 | 871 | ||
874 | return -EBUSY; | 872 | return -EBUSY; |
875 | } | 873 | } |
@@ -972,8 +970,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
972 | dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0)); | 970 | dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0)); |
973 | 971 | ||
974 | if (!dev->lmmio) { | 972 | if (!dev->lmmio) { |
975 | CX25821_ERR | 973 | CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n"); |
976 | ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n"); | ||
977 | cx25821_iounmap(dev); | 974 | cx25821_iounmap(dev); |
978 | return -ENOMEM; | 975 | return -ENOMEM; |
979 | } | 976 | } |
@@ -994,7 +991,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
994 | * cx25821_i2c_register(&dev->i2c_bus[2]); */ | 991 | * cx25821_i2c_register(&dev->i2c_bus[2]); */ |
995 | 992 | ||
996 | CX25821_INFO("i2c register! bus->i2c_rc = %d\n", | 993 | CX25821_INFO("i2c register! bus->i2c_rc = %d\n", |
997 | dev->i2c_bus[0].i2c_rc); | 994 | dev->i2c_bus[0].i2c_rc); |
998 | 995 | ||
999 | cx25821_card_setup(dev); | 996 | cx25821_card_setup(dev); |
1000 | 997 | ||
@@ -1004,9 +1001,8 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
1004 | cx25821_video_register(dev); | 1001 | cx25821_video_register(dev); |
1005 | 1002 | ||
1006 | /* register IOCTL device */ | 1003 | /* register IOCTL device */ |
1007 | dev->ioctl_dev = | 1004 | dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci, |
1008 | cx25821_vdev_init(dev, dev->pci, &cx25821_videoioctl_template, | 1005 | &cx25821_videoioctl_template, "video"); |
1009 | "video"); | ||
1010 | 1006 | ||
1011 | if (video_register_device | 1007 | if (video_register_device |
1012 | (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) { | 1008 | (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) { |
@@ -1103,16 +1099,15 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, | |||
1103 | } | 1099 | } |
1104 | if (bpl <= sg_dma_len(sg) - offset) { | 1100 | if (bpl <= sg_dma_len(sg) - offset) { |
1105 | /* fits into current chunk */ | 1101 | /* fits into current chunk */ |
1106 | *(rp++) = | 1102 | *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | |
1107 | cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl); | 1103 | bpl); |
1108 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | 1104 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); |
1109 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1105 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1110 | offset += bpl; | 1106 | offset += bpl; |
1111 | } else { | 1107 | } else { |
1112 | /* scanline needs to be split */ | 1108 | /* scanline needs to be split */ |
1113 | todo = bpl; | 1109 | todo = bpl; |
1114 | *(rp++) = | 1110 | *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | |
1115 | cpu_to_le32(RISC_WRITE | RISC_SOL | | ||
1116 | (sg_dma_len(sg) - offset)); | 1111 | (sg_dma_len(sg) - offset)); |
1117 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | 1112 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); |
1118 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1113 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
@@ -1120,8 +1115,8 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, | |||
1120 | offset = 0; | 1115 | offset = 0; |
1121 | sg++; | 1116 | sg++; |
1122 | while (todo > sg_dma_len(sg)) { | 1117 | while (todo > sg_dma_len(sg)) { |
1123 | *(rp++) = | 1118 | *(rp++) = cpu_to_le32(RISC_WRITE | |
1124 | cpu_to_le32(RISC_WRITE | sg_dma_len(sg)); | 1119 | sg_dma_len(sg)); |
1125 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | 1120 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); |
1126 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1121 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1127 | todo -= sg_dma_len(sg); | 1122 | todo -= sg_dma_len(sg); |
@@ -1160,8 +1155,8 @@ int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1160 | can cause next bpl to start close to a page border. First DMA | 1155 | can cause next bpl to start close to a page border. First DMA |
1161 | region may be smaller than PAGE_SIZE */ | 1156 | region may be smaller than PAGE_SIZE */ |
1162 | /* write and jump need and extra dword */ | 1157 | /* write and jump need and extra dword */ |
1163 | instructions = | 1158 | instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + |
1164 | fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); | 1159 | lines); |
1165 | instructions += 2; | 1160 | instructions += 2; |
1166 | rc = btcx_riscmem_alloc(pci, risc, instructions * 12); | 1161 | rc = btcx_riscmem_alloc(pci, risc, instructions * 12); |
1167 | 1162 | ||
@@ -1215,8 +1210,8 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, | |||
1215 | 1210 | ||
1216 | if (bpl <= sg_dma_len(sg) - offset) { | 1211 | if (bpl <= sg_dma_len(sg) - offset) { |
1217 | /* fits into current chunk */ | 1212 | /* fits into current chunk */ |
1218 | *(rp++) = | 1213 | *(rp++) = cpu_to_le32(RISC_WRITE | sol | RISC_EOL | |
1219 | cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl); | 1214 | bpl); |
1220 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | 1215 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); |
1221 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1216 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1222 | offset += bpl; | 1217 | offset += bpl; |
@@ -1224,7 +1219,7 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, | |||
1224 | /* scanline needs to be split */ | 1219 | /* scanline needs to be split */ |
1225 | todo = bpl; | 1220 | todo = bpl; |
1226 | *(rp++) = cpu_to_le32(RISC_WRITE | sol | | 1221 | *(rp++) = cpu_to_le32(RISC_WRITE | sol | |
1227 | (sg_dma_len(sg) - offset)); | 1222 | (sg_dma_len(sg) - offset)); |
1228 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); | 1223 | *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); |
1229 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1224 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1230 | todo -= (sg_dma_len(sg) - offset); | 1225 | todo -= (sg_dma_len(sg) - offset); |
@@ -1232,7 +1227,7 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, | |||
1232 | sg++; | 1227 | sg++; |
1233 | while (todo > sg_dma_len(sg)) { | 1228 | while (todo > sg_dma_len(sg)) { |
1234 | *(rp++) = cpu_to_le32(RISC_WRITE | | 1229 | *(rp++) = cpu_to_le32(RISC_WRITE | |
1235 | sg_dma_len(sg)); | 1230 | sg_dma_len(sg)); |
1236 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | 1231 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); |
1237 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1232 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1238 | todo -= sg_dma_len(sg); | 1233 | todo -= sg_dma_len(sg); |
@@ -1339,8 +1334,8 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id) | |||
1339 | sram_channels->int_stat); | 1334 | sram_channels->int_stat); |
1340 | 1335 | ||
1341 | if (vid_status) | 1336 | if (vid_status) |
1342 | handled += | 1337 | handled += cx25821_video_irq(dev, i, |
1343 | cx25821_video_irq(dev, i, vid_status); | 1338 | vid_status); |
1344 | 1339 | ||
1345 | cx_write(PCI_INT_STAT, mask[i]); | 1340 | cx_write(PCI_INT_STAT, mask[i]); |
1346 | } | 1341 | } |
@@ -1427,9 +1422,8 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev, | |||
1427 | goto fail_irq; | 1422 | goto fail_irq; |
1428 | } | 1423 | } |
1429 | 1424 | ||
1430 | err = | 1425 | err = request_irq(pci_dev->irq, cx25821_irq, |
1431 | request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED, | 1426 | IRQF_SHARED, dev->name, dev); |
1432 | dev->name, dev); | ||
1433 | 1427 | ||
1434 | if (err < 0) { | 1428 | if (err < 0) { |
1435 | pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); | 1429 | pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); |
@@ -1512,6 +1506,5 @@ static void __exit cx25821_fini(void) | |||
1512 | pci_unregister_driver(&cx25821_pci_driver); | 1506 | pci_unregister_driver(&cx25821_pci_driver); |
1513 | } | 1507 | } |
1514 | 1508 | ||
1515 | |||
1516 | module_init(cx25821_init); | 1509 | module_init(cx25821_init); |
1517 | module_exit(cx25821_fini); | 1510 | module_exit(cx25821_fini); |
diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c index 4d3d0ce40785..12d7300fa1e9 100644 --- a/drivers/media/video/cx25821/cx25821-i2c.c +++ b/drivers/media/video/cx25821/cx25821-i2c.c | |||
@@ -252,8 +252,8 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | |||
252 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | 252 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && |
253 | msgs[i].addr == msgs[i + 1].addr) { | 253 | msgs[i].addr == msgs[i + 1].addr) { |
254 | /* write then read from same address */ | 254 | /* write then read from same address */ |
255 | retval = | 255 | retval = i2c_sendbytes(i2c_adap, &msgs[i], |
256 | i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len); | 256 | msgs[i + 1].len); |
257 | 257 | ||
258 | if (retval < 0) | 258 | if (retval < 0) |
259 | goto err; | 259 | goto err; |
@@ -276,10 +276,8 @@ err: | |||
276 | 276 | ||
277 | static u32 cx25821_functionality(struct i2c_adapter *adap) | 277 | static u32 cx25821_functionality(struct i2c_adapter *adap) |
278 | { | 278 | { |
279 | return I2C_FUNC_SMBUS_EMUL | | 279 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA | |
280 | I2C_FUNC_I2C | | 280 | I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA; |
281 | I2C_FUNC_SMBUS_WORD_DATA | | ||
282 | I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA; | ||
283 | } | 281 | } |
284 | 282 | ||
285 | static struct i2c_algorithm cx25821_i2c_algo_template = { | 283 | static struct i2c_algorithm cx25821_i2c_algo_template = { |
@@ -300,7 +298,7 @@ static struct i2c_client cx25821_i2c_client_template = { | |||
300 | .name = "cx25821 internal", | 298 | .name = "cx25821 internal", |
301 | }; | 299 | }; |
302 | 300 | ||
303 | /* init + register i2c algo-bit adapter */ | 301 | /* init + register i2c adapter */ |
304 | int cx25821_i2c_register(struct cx25821_i2c *bus) | 302 | int cx25821_i2c_register(struct cx25821_i2c *bus) |
305 | { | 303 | { |
306 | struct cx25821_dev *dev = bus->dev; | 304 | struct cx25821_dev *dev = bus->dev; |
diff --git a/drivers/media/video/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h index 60d197f57556..7a9e6470ba22 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-defines.h +++ b/drivers/media/video/cx25821/cx25821-medusa-defines.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #ifndef _MEDUSA_DEF_H_ | 23 | #ifndef _MEDUSA_DEF_H_ |
24 | #define _MEDUSA_DEF_H_ | 24 | #define _MEDUSA_DEF_H_ |
25 | 25 | ||
26 | /* Video deocder that we supported */ | 26 | /* Video decoder that we supported */ |
27 | #define VDEC_A 0 | 27 | #define VDEC_A 0 |
28 | #define VDEC_B 1 | 28 | #define VDEC_B 1 |
29 | #define VDEC_C 2 | 29 | #define VDEC_C 2 |
@@ -34,9 +34,9 @@ | |||
34 | #define VDEC_H 7 | 34 | #define VDEC_H 7 |
35 | 35 | ||
36 | /* end of display sequence */ | 36 | /* end of display sequence */ |
37 | #define END_OF_SEQ 0xF; | 37 | #define END_OF_SEQ 0xF; |
38 | 38 | ||
39 | /* registry string size */ | 39 | /* registry string size */ |
40 | #define MAX_REGISTRY_SZ 40; | 40 | #define MAX_REGISTRY_SZ 40; |
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/drivers/media/video/cx25821/cx25821-medusa-reg.h b/drivers/media/video/cx25821/cx25821-medusa-reg.h index 1c1c228352d1..c98ac946b277 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-reg.h +++ b/drivers/media/video/cx25821/cx25821-medusa-reg.h | |||
@@ -28,22 +28,22 @@ | |||
28 | #define HOST_REGISTER2 0x0001 | 28 | #define HOST_REGISTER2 0x0001 |
29 | 29 | ||
30 | /* Chip Configuration Registers */ | 30 | /* Chip Configuration Registers */ |
31 | #define CHIP_CTRL 0x0100 | 31 | #define CHIP_CTRL 0x0100 |
32 | #define AFE_AB_CTRL 0x0104 | 32 | #define AFE_AB_CTRL 0x0104 |
33 | #define AFE_CD_CTRL 0x0108 | 33 | #define AFE_CD_CTRL 0x0108 |
34 | #define AFE_EF_CTRL 0x010C | 34 | #define AFE_EF_CTRL 0x010C |
35 | #define AFE_GH_CTRL 0x0110 | 35 | #define AFE_GH_CTRL 0x0110 |
36 | #define DENC_AB_CTRL 0x0114 | 36 | #define DENC_AB_CTRL 0x0114 |
37 | #define BYP_AB_CTRL 0x0118 | 37 | #define BYP_AB_CTRL 0x0118 |
38 | #define MON_A_CTRL 0x011C | 38 | #define MON_A_CTRL 0x011C |
39 | #define DISP_SEQ_A 0x0120 | 39 | #define DISP_SEQ_A 0x0120 |
40 | #define DISP_SEQ_B 0x0124 | 40 | #define DISP_SEQ_B 0x0124 |
41 | #define DISP_AB_CNT 0x0128 | 41 | #define DISP_AB_CNT 0x0128 |
42 | #define DISP_CD_CNT 0x012C | 42 | #define DISP_CD_CNT 0x012C |
43 | #define DISP_EF_CNT 0x0130 | 43 | #define DISP_EF_CNT 0x0130 |
44 | #define DISP_GH_CNT 0x0134 | 44 | #define DISP_GH_CNT 0x0134 |
45 | #define DISP_IJ_CNT 0x0138 | 45 | #define DISP_IJ_CNT 0x0138 |
46 | #define PIN_OE_CTRL 0x013C | 46 | #define PIN_OE_CTRL 0x013C |
47 | #define PIN_SPD_CTRL 0x0140 | 47 | #define PIN_SPD_CTRL 0x0140 |
48 | #define PIN_SPD_CTRL2 0x0144 | 48 | #define PIN_SPD_CTRL2 0x0144 |
49 | #define IRQ_STAT_CTRL 0x0148 | 49 | #define IRQ_STAT_CTRL 0x0148 |
@@ -51,8 +51,8 @@ | |||
51 | #define POWER_CTRL_CD 0x0150 | 51 | #define POWER_CTRL_CD 0x0150 |
52 | #define POWER_CTRL_EF 0x0154 | 52 | #define POWER_CTRL_EF 0x0154 |
53 | #define POWER_CTRL_GH 0x0158 | 53 | #define POWER_CTRL_GH 0x0158 |
54 | #define TUNE_CTRL 0x015C | 54 | #define TUNE_CTRL 0x015C |
55 | #define BIAS_CTRL 0x0160 | 55 | #define BIAS_CTRL 0x0160 |
56 | #define AFE_AB_DIAG_CTRL 0x0164 | 56 | #define AFE_AB_DIAG_CTRL 0x0164 |
57 | #define AFE_CD_DIAG_CTRL 0x0168 | 57 | #define AFE_CD_DIAG_CTRL 0x0168 |
58 | #define AFE_EF_DIAG_CTRL 0x016C | 58 | #define AFE_EF_DIAG_CTRL 0x016C |
@@ -61,17 +61,17 @@ | |||
61 | #define PLL_CD_DIAG_CTRL 0x0178 | 61 | #define PLL_CD_DIAG_CTRL 0x0178 |
62 | #define PLL_EF_DIAG_CTRL 0x017C | 62 | #define PLL_EF_DIAG_CTRL 0x017C |
63 | #define PLL_GH_DIAG_CTRL 0x0180 | 63 | #define PLL_GH_DIAG_CTRL 0x0180 |
64 | #define TEST_CTRL 0x0184 | 64 | #define TEST_CTRL 0x0184 |
65 | #define BIST_STAT 0x0188 | 65 | #define BIST_STAT 0x0188 |
66 | #define BIST_STAT2 0x018C | 66 | #define BIST_STAT2 0x018C |
67 | #define BIST_VID_PLL_AB_STAT 0x0190 | 67 | #define BIST_VID_PLL_AB_STAT 0x0190 |
68 | #define BIST_VID_PLL_CD_STAT 0x0194 | 68 | #define BIST_VID_PLL_CD_STAT 0x0194 |
69 | #define BIST_VID_PLL_EF_STAT 0x0198 | 69 | #define BIST_VID_PLL_EF_STAT 0x0198 |
70 | #define BIST_VID_PLL_GH_STAT 0x019C | 70 | #define BIST_VID_PLL_GH_STAT 0x019C |
71 | #define DLL_DIAG_CTRL 0x01A0 | 71 | #define DLL_DIAG_CTRL 0x01A0 |
72 | #define DEV_CH_ID_CTRL 0x01A4 | 72 | #define DEV_CH_ID_CTRL 0x01A4 |
73 | #define ABIST_CTRL_STATUS 0x01A8 | 73 | #define ABIST_CTRL_STATUS 0x01A8 |
74 | #define ABIST_FREQ 0x01AC | 74 | #define ABIST_FREQ 0x01AC |
75 | #define ABIST_GOERT_SHIFT 0x01B0 | 75 | #define ABIST_GOERT_SHIFT 0x01B0 |
76 | #define ABIST_COEF12 0x01B4 | 76 | #define ABIST_COEF12 0x01B4 |
77 | #define ABIST_COEF34 0x01B8 | 77 | #define ABIST_COEF34 0x01B8 |
@@ -92,357 +92,357 @@ | |||
92 | #define ABIST_CLAMP_E 0x01F4 | 92 | #define ABIST_CLAMP_E 0x01F4 |
93 | #define ABIST_CLAMP_F 0x01F8 | 93 | #define ABIST_CLAMP_F 0x01F8 |
94 | 94 | ||
95 | /* Digital Video Encoder A Registers */ | 95 | /* Digital Video Encoder A Registers */ |
96 | #define DENC_A_REG_1 0x0200 | 96 | #define DENC_A_REG_1 0x0200 |
97 | #define DENC_A_REG_2 0x0204 | 97 | #define DENC_A_REG_2 0x0204 |
98 | #define DENC_A_REG_3 0x0208 | 98 | #define DENC_A_REG_3 0x0208 |
99 | #define DENC_A_REG_4 0x020C | 99 | #define DENC_A_REG_4 0x020C |
100 | #define DENC_A_REG_5 0x0210 | 100 | #define DENC_A_REG_5 0x0210 |
101 | #define DENC_A_REG_6 0x0214 | 101 | #define DENC_A_REG_6 0x0214 |
102 | #define DENC_A_REG_7 0x0218 | 102 | #define DENC_A_REG_7 0x0218 |
103 | #define DENC_A_REG_8 0x021C | 103 | #define DENC_A_REG_8 0x021C |
104 | 104 | ||
105 | /* Digital Video Encoder B Registers */ | 105 | /* Digital Video Encoder B Registers */ |
106 | #define DENC_B_REG_1 0x0300 | 106 | #define DENC_B_REG_1 0x0300 |
107 | #define DENC_B_REG_2 0x0304 | 107 | #define DENC_B_REG_2 0x0304 |
108 | #define DENC_B_REG_3 0x0308 | 108 | #define DENC_B_REG_3 0x0308 |
109 | #define DENC_B_REG_4 0x030C | 109 | #define DENC_B_REG_4 0x030C |
110 | #define DENC_B_REG_5 0x0310 | 110 | #define DENC_B_REG_5 0x0310 |
111 | #define DENC_B_REG_6 0x0314 | 111 | #define DENC_B_REG_6 0x0314 |
112 | #define DENC_B_REG_7 0x0318 | 112 | #define DENC_B_REG_7 0x0318 |
113 | #define DENC_B_REG_8 0x031C | 113 | #define DENC_B_REG_8 0x031C |
114 | 114 | ||
115 | /* Video Decoder A Registers */ | 115 | /* Video Decoder A Registers */ |
116 | #define MODE_CTRL 0x1000 | 116 | #define MODE_CTRL 0x1000 |
117 | #define OUT_CTRL1 0x1004 | 117 | #define OUT_CTRL1 0x1004 |
118 | #define OUT_CTRL_NS 0x1008 | 118 | #define OUT_CTRL_NS 0x1008 |
119 | #define GEN_STAT 0x100C | 119 | #define GEN_STAT 0x100C |
120 | #define INT_STAT_MASK 0x1010 | 120 | #define INT_STAT_MASK 0x1010 |
121 | #define LUMA_CTRL 0x1014 | 121 | #define LUMA_CTRL 0x1014 |
122 | #define CHROMA_CTRL 0x1018 | 122 | #define CHROMA_CTRL 0x1018 |
123 | #define CRUSH_CTRL 0x101C | 123 | #define CRUSH_CTRL 0x101C |
124 | #define HORIZ_TIM_CTRL 0x1020 | 124 | #define HORIZ_TIM_CTRL 0x1020 |
125 | #define VERT_TIM_CTRL 0x1024 | 125 | #define VERT_TIM_CTRL 0x1024 |
126 | #define MISC_TIM_CTRL 0x1028 | 126 | #define MISC_TIM_CTRL 0x1028 |
127 | #define FIELD_COUNT 0x102C | 127 | #define FIELD_COUNT 0x102C |
128 | #define HSCALE_CTRL 0x1030 | 128 | #define HSCALE_CTRL 0x1030 |
129 | #define VSCALE_CTRL 0x1034 | 129 | #define VSCALE_CTRL 0x1034 |
130 | #define MAN_VGA_CTRL 0x1038 | 130 | #define MAN_VGA_CTRL 0x1038 |
131 | #define MAN_AGC_CTRL 0x103C | 131 | #define MAN_AGC_CTRL 0x103C |
132 | #define DFE_CTRL1 0x1040 | 132 | #define DFE_CTRL1 0x1040 |
133 | #define DFE_CTRL2 0x1044 | 133 | #define DFE_CTRL2 0x1044 |
134 | #define DFE_CTRL3 0x1048 | 134 | #define DFE_CTRL3 0x1048 |
135 | #define PLL_CTRL 0x104C | 135 | #define PLL_CTRL 0x104C |
136 | #define PLL_CTRL_FAST 0x1050 | 136 | #define PLL_CTRL_FAST 0x1050 |
137 | #define HTL_CTRL 0x1054 | 137 | #define HTL_CTRL 0x1054 |
138 | #define SRC_CFG 0x1058 | 138 | #define SRC_CFG 0x1058 |
139 | #define SC_STEP_SIZE 0x105C | 139 | #define SC_STEP_SIZE 0x105C |
140 | #define SC_CONVERGE_CTRL 0x1060 | 140 | #define SC_CONVERGE_CTRL 0x1060 |
141 | #define SC_LOOP_CTRL 0x1064 | 141 | #define SC_LOOP_CTRL 0x1064 |
142 | #define COMB_2D_HFS_CFG 0x1068 | 142 | #define COMB_2D_HFS_CFG 0x1068 |
143 | #define COMB_2D_HFD_CFG 0x106C | 143 | #define COMB_2D_HFD_CFG 0x106C |
144 | #define COMB_2D_LF_CFG 0x1070 | 144 | #define COMB_2D_LF_CFG 0x1070 |
145 | #define COMB_2D_BLEND 0x1074 | 145 | #define COMB_2D_BLEND 0x1074 |
146 | #define COMB_MISC_CTRL 0x1078 | 146 | #define COMB_MISC_CTRL 0x1078 |
147 | #define COMB_FLAT_THRESH_CTRL 0x107C | 147 | #define COMB_FLAT_THRESH_CTRL 0x107C |
148 | #define COMB_TEST 0x1080 | 148 | #define COMB_TEST 0x1080 |
149 | #define BP_MISC_CTRL 0x1084 | 149 | #define BP_MISC_CTRL 0x1084 |
150 | #define VCR_DET_CTRL 0x1088 | 150 | #define VCR_DET_CTRL 0x1088 |
151 | #define NOISE_DET_CTRL 0x108C | 151 | #define NOISE_DET_CTRL 0x108C |
152 | #define COMB_FLAT_NOISE_CTRL 0x1090 | 152 | #define COMB_FLAT_NOISE_CTRL 0x1090 |
153 | #define VERSION 0x11F8 | 153 | #define VERSION 0x11F8 |
154 | #define SOFT_RST_CTRL 0x11FC | 154 | #define SOFT_RST_CTRL 0x11FC |
155 | 155 | ||
156 | /* Video Decoder B Registers */ | 156 | /* Video Decoder B Registers */ |
157 | #define VDEC_B_MODE_CTRL 0x1200 | 157 | #define VDEC_B_MODE_CTRL 0x1200 |
158 | #define VDEC_B_OUT_CTRL1 0x1204 | 158 | #define VDEC_B_OUT_CTRL1 0x1204 |
159 | #define VDEC_B_OUT_CTRL_NS 0x1208 | 159 | #define VDEC_B_OUT_CTRL_NS 0x1208 |
160 | #define VDEC_B_GEN_STAT 0x120C | 160 | #define VDEC_B_GEN_STAT 0x120C |
161 | #define VDEC_B_INT_STAT_MASK 0x1210 | 161 | #define VDEC_B_INT_STAT_MASK 0x1210 |
162 | #define VDEC_B_LUMA_CTRL 0x1214 | 162 | #define VDEC_B_LUMA_CTRL 0x1214 |
163 | #define VDEC_B_CHROMA_CTRL 0x1218 | 163 | #define VDEC_B_CHROMA_CTRL 0x1218 |
164 | #define VDEC_B_CRUSH_CTRL 0x121C | 164 | #define VDEC_B_CRUSH_CTRL 0x121C |
165 | #define VDEC_B_HORIZ_TIM_CTRL 0x1220 | 165 | #define VDEC_B_HORIZ_TIM_CTRL 0x1220 |
166 | #define VDEC_B_VERT_TIM_CTRL 0x1224 | 166 | #define VDEC_B_VERT_TIM_CTRL 0x1224 |
167 | #define VDEC_B_MISC_TIM_CTRL 0x1228 | 167 | #define VDEC_B_MISC_TIM_CTRL 0x1228 |
168 | #define VDEC_B_FIELD_COUNT 0x122C | 168 | #define VDEC_B_FIELD_COUNT 0x122C |
169 | #define VDEC_B_HSCALE_CTRL 0x1230 | 169 | #define VDEC_B_HSCALE_CTRL 0x1230 |
170 | #define VDEC_B_VSCALE_CTRL 0x1234 | 170 | #define VDEC_B_VSCALE_CTRL 0x1234 |
171 | #define VDEC_B_MAN_VGA_CTRL 0x1238 | 171 | #define VDEC_B_MAN_VGA_CTRL 0x1238 |
172 | #define VDEC_B_MAN_AGC_CTRL 0x123C | 172 | #define VDEC_B_MAN_AGC_CTRL 0x123C |
173 | #define VDEC_B_DFE_CTRL1 0x1240 | 173 | #define VDEC_B_DFE_CTRL1 0x1240 |
174 | #define VDEC_B_DFE_CTRL2 0x1244 | 174 | #define VDEC_B_DFE_CTRL2 0x1244 |
175 | #define VDEC_B_DFE_CTRL3 0x1248 | 175 | #define VDEC_B_DFE_CTRL3 0x1248 |
176 | #define VDEC_B_PLL_CTRL 0x124C | 176 | #define VDEC_B_PLL_CTRL 0x124C |
177 | #define VDEC_B_PLL_CTRL_FAST 0x1250 | 177 | #define VDEC_B_PLL_CTRL_FAST 0x1250 |
178 | #define VDEC_B_HTL_CTRL 0x1254 | 178 | #define VDEC_B_HTL_CTRL 0x1254 |
179 | #define VDEC_B_SRC_CFG 0x1258 | 179 | #define VDEC_B_SRC_CFG 0x1258 |
180 | #define VDEC_B_SC_STEP_SIZE 0x125C | 180 | #define VDEC_B_SC_STEP_SIZE 0x125C |
181 | #define VDEC_B_SC_CONVERGE_CTRL 0x1260 | 181 | #define VDEC_B_SC_CONVERGE_CTRL 0x1260 |
182 | #define VDEC_B_SC_LOOP_CTRL 0x1264 | 182 | #define VDEC_B_SC_LOOP_CTRL 0x1264 |
183 | #define VDEC_B_COMB_2D_HFS_CFG 0x1268 | 183 | #define VDEC_B_COMB_2D_HFS_CFG 0x1268 |
184 | #define VDEC_B_COMB_2D_HFD_CFG 0x126C | 184 | #define VDEC_B_COMB_2D_HFD_CFG 0x126C |
185 | #define VDEC_B_COMB_2D_LF_CFG 0x1270 | 185 | #define VDEC_B_COMB_2D_LF_CFG 0x1270 |
186 | #define VDEC_B_COMB_2D_BLEND 0x1274 | 186 | #define VDEC_B_COMB_2D_BLEND 0x1274 |
187 | #define VDEC_B_COMB_MISC_CTRL 0x1278 | 187 | #define VDEC_B_COMB_MISC_CTRL 0x1278 |
188 | #define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C | 188 | #define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C |
189 | #define VDEC_B_COMB_TEST 0x1280 | 189 | #define VDEC_B_COMB_TEST 0x1280 |
190 | #define VDEC_B_BP_MISC_CTRL 0x1284 | 190 | #define VDEC_B_BP_MISC_CTRL 0x1284 |
191 | #define VDEC_B_VCR_DET_CTRL 0x1288 | 191 | #define VDEC_B_VCR_DET_CTRL 0x1288 |
192 | #define VDEC_B_NOISE_DET_CTRL 0x128C | 192 | #define VDEC_B_NOISE_DET_CTRL 0x128C |
193 | #define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290 | 193 | #define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290 |
194 | #define VDEC_B_VERSION 0x13F8 | 194 | #define VDEC_B_VERSION 0x13F8 |
195 | #define VDEC_B_SOFT_RST_CTRL 0x13FC | 195 | #define VDEC_B_SOFT_RST_CTRL 0x13FC |
196 | 196 | ||
197 | /* Video Decoder C Registers */ | 197 | /* Video Decoder C Registers */ |
198 | #define VDEC_C_MODE_CTRL 0x1400 | 198 | #define VDEC_C_MODE_CTRL 0x1400 |
199 | #define VDEC_C_OUT_CTRL1 0x1404 | 199 | #define VDEC_C_OUT_CTRL1 0x1404 |
200 | #define VDEC_C_OUT_CTRL_NS 0x1408 | 200 | #define VDEC_C_OUT_CTRL_NS 0x1408 |
201 | #define VDEC_C_GEN_STAT 0x140C | 201 | #define VDEC_C_GEN_STAT 0x140C |
202 | #define VDEC_C_INT_STAT_MASK 0x1410 | 202 | #define VDEC_C_INT_STAT_MASK 0x1410 |
203 | #define VDEC_C_LUMA_CTRL 0x1414 | 203 | #define VDEC_C_LUMA_CTRL 0x1414 |
204 | #define VDEC_C_CHROMA_CTRL 0x1418 | 204 | #define VDEC_C_CHROMA_CTRL 0x1418 |
205 | #define VDEC_C_CRUSH_CTRL 0x141C | 205 | #define VDEC_C_CRUSH_CTRL 0x141C |
206 | #define VDEC_C_HORIZ_TIM_CTRL 0x1420 | 206 | #define VDEC_C_HORIZ_TIM_CTRL 0x1420 |
207 | #define VDEC_C_VERT_TIM_CTRL 0x1424 | 207 | #define VDEC_C_VERT_TIM_CTRL 0x1424 |
208 | #define VDEC_C_MISC_TIM_CTRL 0x1428 | 208 | #define VDEC_C_MISC_TIM_CTRL 0x1428 |
209 | #define VDEC_C_FIELD_COUNT 0x142C | 209 | #define VDEC_C_FIELD_COUNT 0x142C |
210 | #define VDEC_C_HSCALE_CTRL 0x1430 | 210 | #define VDEC_C_HSCALE_CTRL 0x1430 |
211 | #define VDEC_C_VSCALE_CTRL 0x1434 | 211 | #define VDEC_C_VSCALE_CTRL 0x1434 |
212 | #define VDEC_C_MAN_VGA_CTRL 0x1438 | 212 | #define VDEC_C_MAN_VGA_CTRL 0x1438 |
213 | #define VDEC_C_MAN_AGC_CTRL 0x143C | 213 | #define VDEC_C_MAN_AGC_CTRL 0x143C |
214 | #define VDEC_C_DFE_CTRL1 0x1440 | 214 | #define VDEC_C_DFE_CTRL1 0x1440 |
215 | #define VDEC_C_DFE_CTRL2 0x1444 | 215 | #define VDEC_C_DFE_CTRL2 0x1444 |
216 | #define VDEC_C_DFE_CTRL3 0x1448 | 216 | #define VDEC_C_DFE_CTRL3 0x1448 |
217 | #define VDEC_C_PLL_CTRL 0x144C | 217 | #define VDEC_C_PLL_CTRL 0x144C |
218 | #define VDEC_C_PLL_CTRL_FAST 0x1450 | 218 | #define VDEC_C_PLL_CTRL_FAST 0x1450 |
219 | #define VDEC_C_HTL_CTRL 0x1454 | 219 | #define VDEC_C_HTL_CTRL 0x1454 |
220 | #define VDEC_C_SRC_CFG 0x1458 | 220 | #define VDEC_C_SRC_CFG 0x1458 |
221 | #define VDEC_C_SC_STEP_SIZE 0x145C | 221 | #define VDEC_C_SC_STEP_SIZE 0x145C |
222 | #define VDEC_C_SC_CONVERGE_CTRL 0x1460 | 222 | #define VDEC_C_SC_CONVERGE_CTRL 0x1460 |
223 | #define VDEC_C_SC_LOOP_CTRL 0x1464 | 223 | #define VDEC_C_SC_LOOP_CTRL 0x1464 |
224 | #define VDEC_C_COMB_2D_HFS_CFG 0x1468 | 224 | #define VDEC_C_COMB_2D_HFS_CFG 0x1468 |
225 | #define VDEC_C_COMB_2D_HFD_CFG 0x146C | 225 | #define VDEC_C_COMB_2D_HFD_CFG 0x146C |
226 | #define VDEC_C_COMB_2D_LF_CFG 0x1470 | 226 | #define VDEC_C_COMB_2D_LF_CFG 0x1470 |
227 | #define VDEC_C_COMB_2D_BLEND 0x1474 | 227 | #define VDEC_C_COMB_2D_BLEND 0x1474 |
228 | #define VDEC_C_COMB_MISC_CTRL 0x1478 | 228 | #define VDEC_C_COMB_MISC_CTRL 0x1478 |
229 | #define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C | 229 | #define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C |
230 | #define VDEC_C_COMB_TEST 0x1480 | 230 | #define VDEC_C_COMB_TEST 0x1480 |
231 | #define VDEC_C_BP_MISC_CTRL 0x1484 | 231 | #define VDEC_C_BP_MISC_CTRL 0x1484 |
232 | #define VDEC_C_VCR_DET_CTRL 0x1488 | 232 | #define VDEC_C_VCR_DET_CTRL 0x1488 |
233 | #define VDEC_C_NOISE_DET_CTRL 0x148C | 233 | #define VDEC_C_NOISE_DET_CTRL 0x148C |
234 | #define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490 | 234 | #define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490 |
235 | #define VDEC_C_VERSION 0x15F8 | 235 | #define VDEC_C_VERSION 0x15F8 |
236 | #define VDEC_C_SOFT_RST_CTRL 0x15FC | 236 | #define VDEC_C_SOFT_RST_CTRL 0x15FC |
237 | 237 | ||
238 | /* Video Decoder D Registers */ | 238 | /* Video Decoder D Registers */ |
239 | #define VDEC_D_MODE_CTRL 0x1600 | 239 | #define VDEC_D_MODE_CTRL 0x1600 |
240 | #define VDEC_D_OUT_CTRL1 0x1604 | 240 | #define VDEC_D_OUT_CTRL1 0x1604 |
241 | #define VDEC_D_OUT_CTRL_NS 0x1608 | 241 | #define VDEC_D_OUT_CTRL_NS 0x1608 |
242 | #define VDEC_D_GEN_STAT 0x160C | 242 | #define VDEC_D_GEN_STAT 0x160C |
243 | #define VDEC_D_INT_STAT_MASK 0x1610 | 243 | #define VDEC_D_INT_STAT_MASK 0x1610 |
244 | #define VDEC_D_LUMA_CTRL 0x1614 | 244 | #define VDEC_D_LUMA_CTRL 0x1614 |
245 | #define VDEC_D_CHROMA_CTRL 0x1618 | 245 | #define VDEC_D_CHROMA_CTRL 0x1618 |
246 | #define VDEC_D_CRUSH_CTRL 0x161C | 246 | #define VDEC_D_CRUSH_CTRL 0x161C |
247 | #define VDEC_D_HORIZ_TIM_CTRL 0x1620 | 247 | #define VDEC_D_HORIZ_TIM_CTRL 0x1620 |
248 | #define VDEC_D_VERT_TIM_CTRL 0x1624 | 248 | #define VDEC_D_VERT_TIM_CTRL 0x1624 |
249 | #define VDEC_D_MISC_TIM_CTRL 0x1628 | 249 | #define VDEC_D_MISC_TIM_CTRL 0x1628 |
250 | #define VDEC_D_FIELD_COUNT 0x162C | 250 | #define VDEC_D_FIELD_COUNT 0x162C |
251 | #define VDEC_D_HSCALE_CTRL 0x1630 | 251 | #define VDEC_D_HSCALE_CTRL 0x1630 |
252 | #define VDEC_D_VSCALE_CTRL 0x1634 | 252 | #define VDEC_D_VSCALE_CTRL 0x1634 |
253 | #define VDEC_D_MAN_VGA_CTRL 0x1638 | 253 | #define VDEC_D_MAN_VGA_CTRL 0x1638 |
254 | #define VDEC_D_MAN_AGC_CTRL 0x163C | 254 | #define VDEC_D_MAN_AGC_CTRL 0x163C |
255 | #define VDEC_D_DFE_CTRL1 0x1640 | 255 | #define VDEC_D_DFE_CTRL1 0x1640 |
256 | #define VDEC_D_DFE_CTRL2 0x1644 | 256 | #define VDEC_D_DFE_CTRL2 0x1644 |
257 | #define VDEC_D_DFE_CTRL3 0x1648 | 257 | #define VDEC_D_DFE_CTRL3 0x1648 |
258 | #define VDEC_D_PLL_CTRL 0x164C | 258 | #define VDEC_D_PLL_CTRL 0x164C |
259 | #define VDEC_D_PLL_CTRL_FAST 0x1650 | 259 | #define VDEC_D_PLL_CTRL_FAST 0x1650 |
260 | #define VDEC_D_HTL_CTRL 0x1654 | 260 | #define VDEC_D_HTL_CTRL 0x1654 |
261 | #define VDEC_D_SRC_CFG 0x1658 | 261 | #define VDEC_D_SRC_CFG 0x1658 |
262 | #define VDEC_D_SC_STEP_SIZE 0x165C | 262 | #define VDEC_D_SC_STEP_SIZE 0x165C |
263 | #define VDEC_D_SC_CONVERGE_CTRL 0x1660 | 263 | #define VDEC_D_SC_CONVERGE_CTRL 0x1660 |
264 | #define VDEC_D_SC_LOOP_CTRL 0x1664 | 264 | #define VDEC_D_SC_LOOP_CTRL 0x1664 |
265 | #define VDEC_D_COMB_2D_HFS_CFG 0x1668 | 265 | #define VDEC_D_COMB_2D_HFS_CFG 0x1668 |
266 | #define VDEC_D_COMB_2D_HFD_CFG 0x166C | 266 | #define VDEC_D_COMB_2D_HFD_CFG 0x166C |
267 | #define VDEC_D_COMB_2D_LF_CFG 0x1670 | 267 | #define VDEC_D_COMB_2D_LF_CFG 0x1670 |
268 | #define VDEC_D_COMB_2D_BLEND 0x1674 | 268 | #define VDEC_D_COMB_2D_BLEND 0x1674 |
269 | #define VDEC_D_COMB_MISC_CTRL 0x1678 | 269 | #define VDEC_D_COMB_MISC_CTRL 0x1678 |
270 | #define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C | 270 | #define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C |
271 | #define VDEC_D_COMB_TEST 0x1680 | 271 | #define VDEC_D_COMB_TEST 0x1680 |
272 | #define VDEC_D_BP_MISC_CTRL 0x1684 | 272 | #define VDEC_D_BP_MISC_CTRL 0x1684 |
273 | #define VDEC_D_VCR_DET_CTRL 0x1688 | 273 | #define VDEC_D_VCR_DET_CTRL 0x1688 |
274 | #define VDEC_D_NOISE_DET_CTRL 0x168C | 274 | #define VDEC_D_NOISE_DET_CTRL 0x168C |
275 | #define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690 | 275 | #define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690 |
276 | #define VDEC_D_VERSION 0x17F8 | 276 | #define VDEC_D_VERSION 0x17F8 |
277 | #define VDEC_D_SOFT_RST_CTRL 0x17FC | 277 | #define VDEC_D_SOFT_RST_CTRL 0x17FC |
278 | 278 | ||
279 | /* Video Decoder E Registers */ | 279 | /* Video Decoder E Registers */ |
280 | #define VDEC_E_MODE_CTRL 0x1800 | 280 | #define VDEC_E_MODE_CTRL 0x1800 |
281 | #define VDEC_E_OUT_CTRL1 0x1804 | 281 | #define VDEC_E_OUT_CTRL1 0x1804 |
282 | #define VDEC_E_OUT_CTRL_NS 0x1808 | 282 | #define VDEC_E_OUT_CTRL_NS 0x1808 |
283 | #define VDEC_E_GEN_STAT 0x180C | 283 | #define VDEC_E_GEN_STAT 0x180C |
284 | #define VDEC_E_INT_STAT_MASK 0x1810 | 284 | #define VDEC_E_INT_STAT_MASK 0x1810 |
285 | #define VDEC_E_LUMA_CTRL 0x1814 | 285 | #define VDEC_E_LUMA_CTRL 0x1814 |
286 | #define VDEC_E_CHROMA_CTRL 0x1818 | 286 | #define VDEC_E_CHROMA_CTRL 0x1818 |
287 | #define VDEC_E_CRUSH_CTRL 0x181C | 287 | #define VDEC_E_CRUSH_CTRL 0x181C |
288 | #define VDEC_E_HORIZ_TIM_CTRL 0x1820 | 288 | #define VDEC_E_HORIZ_TIM_CTRL 0x1820 |
289 | #define VDEC_E_VERT_TIM_CTRL 0x1824 | 289 | #define VDEC_E_VERT_TIM_CTRL 0x1824 |
290 | #define VDEC_E_MISC_TIM_CTRL 0x1828 | 290 | #define VDEC_E_MISC_TIM_CTRL 0x1828 |
291 | #define VDEC_E_FIELD_COUNT 0x182C | 291 | #define VDEC_E_FIELD_COUNT 0x182C |
292 | #define VDEC_E_HSCALE_CTRL 0x1830 | 292 | #define VDEC_E_HSCALE_CTRL 0x1830 |
293 | #define VDEC_E_VSCALE_CTRL 0x1834 | 293 | #define VDEC_E_VSCALE_CTRL 0x1834 |
294 | #define VDEC_E_MAN_VGA_CTRL 0x1838 | 294 | #define VDEC_E_MAN_VGA_CTRL 0x1838 |
295 | #define VDEC_E_MAN_AGC_CTRL 0x183C | 295 | #define VDEC_E_MAN_AGC_CTRL 0x183C |
296 | #define VDEC_E_DFE_CTRL1 0x1840 | 296 | #define VDEC_E_DFE_CTRL1 0x1840 |
297 | #define VDEC_E_DFE_CTRL2 0x1844 | 297 | #define VDEC_E_DFE_CTRL2 0x1844 |
298 | #define VDEC_E_DFE_CTRL3 0x1848 | 298 | #define VDEC_E_DFE_CTRL3 0x1848 |
299 | #define VDEC_E_PLL_CTRL 0x184C | 299 | #define VDEC_E_PLL_CTRL 0x184C |
300 | #define VDEC_E_PLL_CTRL_FAST 0x1850 | 300 | #define VDEC_E_PLL_CTRL_FAST 0x1850 |
301 | #define VDEC_E_HTL_CTRL 0x1854 | 301 | #define VDEC_E_HTL_CTRL 0x1854 |
302 | #define VDEC_E_SRC_CFG 0x1858 | 302 | #define VDEC_E_SRC_CFG 0x1858 |
303 | #define VDEC_E_SC_STEP_SIZE 0x185C | 303 | #define VDEC_E_SC_STEP_SIZE 0x185C |
304 | #define VDEC_E_SC_CONVERGE_CTRL 0x1860 | 304 | #define VDEC_E_SC_CONVERGE_CTRL 0x1860 |
305 | #define VDEC_E_SC_LOOP_CTRL 0x1864 | 305 | #define VDEC_E_SC_LOOP_CTRL 0x1864 |
306 | #define VDEC_E_COMB_2D_HFS_CFG 0x1868 | 306 | #define VDEC_E_COMB_2D_HFS_CFG 0x1868 |
307 | #define VDEC_E_COMB_2D_HFD_CFG 0x186C | 307 | #define VDEC_E_COMB_2D_HFD_CFG 0x186C |
308 | #define VDEC_E_COMB_2D_LF_CFG 0x1870 | 308 | #define VDEC_E_COMB_2D_LF_CFG 0x1870 |
309 | #define VDEC_E_COMB_2D_BLEND 0x1874 | 309 | #define VDEC_E_COMB_2D_BLEND 0x1874 |
310 | #define VDEC_E_COMB_MISC_CTRL 0x1878 | 310 | #define VDEC_E_COMB_MISC_CTRL 0x1878 |
311 | #define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C | 311 | #define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C |
312 | #define VDEC_E_COMB_TEST 0x1880 | 312 | #define VDEC_E_COMB_TEST 0x1880 |
313 | #define VDEC_E_BP_MISC_CTRL 0x1884 | 313 | #define VDEC_E_BP_MISC_CTRL 0x1884 |
314 | #define VDEC_E_VCR_DET_CTRL 0x1888 | 314 | #define VDEC_E_VCR_DET_CTRL 0x1888 |
315 | #define VDEC_E_NOISE_DET_CTRL 0x188C | 315 | #define VDEC_E_NOISE_DET_CTRL 0x188C |
316 | #define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890 | 316 | #define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890 |
317 | #define VDEC_E_VERSION 0x19F8 | 317 | #define VDEC_E_VERSION 0x19F8 |
318 | #define VDEC_E_SOFT_RST_CTRL 0x19FC | 318 | #define VDEC_E_SOFT_RST_CTRL 0x19FC |
319 | 319 | ||
320 | /* Video Decoder F Registers */ | 320 | /* Video Decoder F Registers */ |
321 | #define VDEC_F_MODE_CTRL 0x1A00 | 321 | #define VDEC_F_MODE_CTRL 0x1A00 |
322 | #define VDEC_F_OUT_CTRL1 0x1A04 | 322 | #define VDEC_F_OUT_CTRL1 0x1A04 |
323 | #define VDEC_F_OUT_CTRL_NS 0x1A08 | 323 | #define VDEC_F_OUT_CTRL_NS 0x1A08 |
324 | #define VDEC_F_GEN_STAT 0x1A0C | 324 | #define VDEC_F_GEN_STAT 0x1A0C |
325 | #define VDEC_F_INT_STAT_MASK 0x1A10 | 325 | #define VDEC_F_INT_STAT_MASK 0x1A10 |
326 | #define VDEC_F_LUMA_CTRL 0x1A14 | 326 | #define VDEC_F_LUMA_CTRL 0x1A14 |
327 | #define VDEC_F_CHROMA_CTRL 0x1A18 | 327 | #define VDEC_F_CHROMA_CTRL 0x1A18 |
328 | #define VDEC_F_CRUSH_CTRL 0x1A1C | 328 | #define VDEC_F_CRUSH_CTRL 0x1A1C |
329 | #define VDEC_F_HORIZ_TIM_CTRL 0x1A20 | 329 | #define VDEC_F_HORIZ_TIM_CTRL 0x1A20 |
330 | #define VDEC_F_VERT_TIM_CTRL 0x1A24 | 330 | #define VDEC_F_VERT_TIM_CTRL 0x1A24 |
331 | #define VDEC_F_MISC_TIM_CTRL 0x1A28 | 331 | #define VDEC_F_MISC_TIM_CTRL 0x1A28 |
332 | #define VDEC_F_FIELD_COUNT 0x1A2C | 332 | #define VDEC_F_FIELD_COUNT 0x1A2C |
333 | #define VDEC_F_HSCALE_CTRL 0x1A30 | 333 | #define VDEC_F_HSCALE_CTRL 0x1A30 |
334 | #define VDEC_F_VSCALE_CTRL 0x1A34 | 334 | #define VDEC_F_VSCALE_CTRL 0x1A34 |
335 | #define VDEC_F_MAN_VGA_CTRL 0x1A38 | 335 | #define VDEC_F_MAN_VGA_CTRL 0x1A38 |
336 | #define VDEC_F_MAN_AGC_CTRL 0x1A3C | 336 | #define VDEC_F_MAN_AGC_CTRL 0x1A3C |
337 | #define VDEC_F_DFE_CTRL1 0x1A40 | 337 | #define VDEC_F_DFE_CTRL1 0x1A40 |
338 | #define VDEC_F_DFE_CTRL2 0x1A44 | 338 | #define VDEC_F_DFE_CTRL2 0x1A44 |
339 | #define VDEC_F_DFE_CTRL3 0x1A48 | 339 | #define VDEC_F_DFE_CTRL3 0x1A48 |
340 | #define VDEC_F_PLL_CTRL 0x1A4C | 340 | #define VDEC_F_PLL_CTRL 0x1A4C |
341 | #define VDEC_F_PLL_CTRL_FAST 0x1A50 | 341 | #define VDEC_F_PLL_CTRL_FAST 0x1A50 |
342 | #define VDEC_F_HTL_CTRL 0x1A54 | 342 | #define VDEC_F_HTL_CTRL 0x1A54 |
343 | #define VDEC_F_SRC_CFG 0x1A58 | 343 | #define VDEC_F_SRC_CFG 0x1A58 |
344 | #define VDEC_F_SC_STEP_SIZE 0x1A5C | 344 | #define VDEC_F_SC_STEP_SIZE 0x1A5C |
345 | #define VDEC_F_SC_CONVERGE_CTRL 0x1A60 | 345 | #define VDEC_F_SC_CONVERGE_CTRL 0x1A60 |
346 | #define VDEC_F_SC_LOOP_CTRL 0x1A64 | 346 | #define VDEC_F_SC_LOOP_CTRL 0x1A64 |
347 | #define VDEC_F_COMB_2D_HFS_CFG 0x1A68 | 347 | #define VDEC_F_COMB_2D_HFS_CFG 0x1A68 |
348 | #define VDEC_F_COMB_2D_HFD_CFG 0x1A6C | 348 | #define VDEC_F_COMB_2D_HFD_CFG 0x1A6C |
349 | #define VDEC_F_COMB_2D_LF_CFG 0x1A70 | 349 | #define VDEC_F_COMB_2D_LF_CFG 0x1A70 |
350 | #define VDEC_F_COMB_2D_BLEND 0x1A74 | 350 | #define VDEC_F_COMB_2D_BLEND 0x1A74 |
351 | #define VDEC_F_COMB_MISC_CTRL 0x1A78 | 351 | #define VDEC_F_COMB_MISC_CTRL 0x1A78 |
352 | #define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C | 352 | #define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C |
353 | #define VDEC_F_COMB_TEST 0x1A80 | 353 | #define VDEC_F_COMB_TEST 0x1A80 |
354 | #define VDEC_F_BP_MISC_CTRL 0x1A84 | 354 | #define VDEC_F_BP_MISC_CTRL 0x1A84 |
355 | #define VDEC_F_VCR_DET_CTRL 0x1A88 | 355 | #define VDEC_F_VCR_DET_CTRL 0x1A88 |
356 | #define VDEC_F_NOISE_DET_CTRL 0x1A8C | 356 | #define VDEC_F_NOISE_DET_CTRL 0x1A8C |
357 | #define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90 | 357 | #define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90 |
358 | #define VDEC_F_VERSION 0x1BF8 | 358 | #define VDEC_F_VERSION 0x1BF8 |
359 | #define VDEC_F_SOFT_RST_CTRL 0x1BFC | 359 | #define VDEC_F_SOFT_RST_CTRL 0x1BFC |
360 | 360 | ||
361 | /* Video Decoder G Registers */ | 361 | /* Video Decoder G Registers */ |
362 | #define VDEC_G_MODE_CTRL 0x1C00 | 362 | #define VDEC_G_MODE_CTRL 0x1C00 |
363 | #define VDEC_G_OUT_CTRL1 0x1C04 | 363 | #define VDEC_G_OUT_CTRL1 0x1C04 |
364 | #define VDEC_G_OUT_CTRL_NS 0x1C08 | 364 | #define VDEC_G_OUT_CTRL_NS 0x1C08 |
365 | #define VDEC_G_GEN_STAT 0x1C0C | 365 | #define VDEC_G_GEN_STAT 0x1C0C |
366 | #define VDEC_G_INT_STAT_MASK 0x1C10 | 366 | #define VDEC_G_INT_STAT_MASK 0x1C10 |
367 | #define VDEC_G_LUMA_CTRL 0x1C14 | 367 | #define VDEC_G_LUMA_CTRL 0x1C14 |
368 | #define VDEC_G_CHROMA_CTRL 0x1C18 | 368 | #define VDEC_G_CHROMA_CTRL 0x1C18 |
369 | #define VDEC_G_CRUSH_CTRL 0x1C1C | 369 | #define VDEC_G_CRUSH_CTRL 0x1C1C |
370 | #define VDEC_G_HORIZ_TIM_CTRL 0x1C20 | 370 | #define VDEC_G_HORIZ_TIM_CTRL 0x1C20 |
371 | #define VDEC_G_VERT_TIM_CTRL 0x1C24 | 371 | #define VDEC_G_VERT_TIM_CTRL 0x1C24 |
372 | #define VDEC_G_MISC_TIM_CTRL 0x1C28 | 372 | #define VDEC_G_MISC_TIM_CTRL 0x1C28 |
373 | #define VDEC_G_FIELD_COUNT 0x1C2C | 373 | #define VDEC_G_FIELD_COUNT 0x1C2C |
374 | #define VDEC_G_HSCALE_CTRL 0x1C30 | 374 | #define VDEC_G_HSCALE_CTRL 0x1C30 |
375 | #define VDEC_G_VSCALE_CTRL 0x1C34 | 375 | #define VDEC_G_VSCALE_CTRL 0x1C34 |
376 | #define VDEC_G_MAN_VGA_CTRL 0x1C38 | 376 | #define VDEC_G_MAN_VGA_CTRL 0x1C38 |
377 | #define VDEC_G_MAN_AGC_CTRL 0x1C3C | 377 | #define VDEC_G_MAN_AGC_CTRL 0x1C3C |
378 | #define VDEC_G_DFE_CTRL1 0x1C40 | 378 | #define VDEC_G_DFE_CTRL1 0x1C40 |
379 | #define VDEC_G_DFE_CTRL2 0x1C44 | 379 | #define VDEC_G_DFE_CTRL2 0x1C44 |
380 | #define VDEC_G_DFE_CTRL3 0x1C48 | 380 | #define VDEC_G_DFE_CTRL3 0x1C48 |
381 | #define VDEC_G_PLL_CTRL 0x1C4C | 381 | #define VDEC_G_PLL_CTRL 0x1C4C |
382 | #define VDEC_G_PLL_CTRL_FAST 0x1C50 | 382 | #define VDEC_G_PLL_CTRL_FAST 0x1C50 |
383 | #define VDEC_G_HTL_CTRL 0x1C54 | 383 | #define VDEC_G_HTL_CTRL 0x1C54 |
384 | #define VDEC_G_SRC_CFG 0x1C58 | 384 | #define VDEC_G_SRC_CFG 0x1C58 |
385 | #define VDEC_G_SC_STEP_SIZE 0x1C5C | 385 | #define VDEC_G_SC_STEP_SIZE 0x1C5C |
386 | #define VDEC_G_SC_CONVERGE_CTRL 0x1C60 | 386 | #define VDEC_G_SC_CONVERGE_CTRL 0x1C60 |
387 | #define VDEC_G_SC_LOOP_CTRL 0x1C64 | 387 | #define VDEC_G_SC_LOOP_CTRL 0x1C64 |
388 | #define VDEC_G_COMB_2D_HFS_CFG 0x1C68 | 388 | #define VDEC_G_COMB_2D_HFS_CFG 0x1C68 |
389 | #define VDEC_G_COMB_2D_HFD_CFG 0x1C6C | 389 | #define VDEC_G_COMB_2D_HFD_CFG 0x1C6C |
390 | #define VDEC_G_COMB_2D_LF_CFG 0x1C70 | 390 | #define VDEC_G_COMB_2D_LF_CFG 0x1C70 |
391 | #define VDEC_G_COMB_2D_BLEND 0x1C74 | 391 | #define VDEC_G_COMB_2D_BLEND 0x1C74 |
392 | #define VDEC_G_COMB_MISC_CTRL 0x1C78 | 392 | #define VDEC_G_COMB_MISC_CTRL 0x1C78 |
393 | #define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C | 393 | #define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C |
394 | #define VDEC_G_COMB_TEST 0x1C80 | 394 | #define VDEC_G_COMB_TEST 0x1C80 |
395 | #define VDEC_G_BP_MISC_CTRL 0x1C84 | 395 | #define VDEC_G_BP_MISC_CTRL 0x1C84 |
396 | #define VDEC_G_VCR_DET_CTRL 0x1C88 | 396 | #define VDEC_G_VCR_DET_CTRL 0x1C88 |
397 | #define VDEC_G_NOISE_DET_CTRL 0x1C8C | 397 | #define VDEC_G_NOISE_DET_CTRL 0x1C8C |
398 | #define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90 | 398 | #define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90 |
399 | #define VDEC_G_VERSION 0x1DF8 | 399 | #define VDEC_G_VERSION 0x1DF8 |
400 | #define VDEC_G_SOFT_RST_CTRL 0x1DFC | 400 | #define VDEC_G_SOFT_RST_CTRL 0x1DFC |
401 | 401 | ||
402 | /* Video Decoder H Registers */ | 402 | /* Video Decoder H Registers */ |
403 | #define VDEC_H_MODE_CTRL 0x1E00 | 403 | #define VDEC_H_MODE_CTRL 0x1E00 |
404 | #define VDEC_H_OUT_CTRL1 0x1E04 | 404 | #define VDEC_H_OUT_CTRL1 0x1E04 |
405 | #define VDEC_H_OUT_CTRL_NS 0x1E08 | 405 | #define VDEC_H_OUT_CTRL_NS 0x1E08 |
406 | #define VDEC_H_GEN_STAT 0x1E0C | 406 | #define VDEC_H_GEN_STAT 0x1E0C |
407 | #define VDEC_H_INT_STAT_MASK 0x1E1E | 407 | #define VDEC_H_INT_STAT_MASK 0x1E1E |
408 | #define VDEC_H_LUMA_CTRL 0x1E14 | 408 | #define VDEC_H_LUMA_CTRL 0x1E14 |
409 | #define VDEC_H_CHROMA_CTRL 0x1E18 | 409 | #define VDEC_H_CHROMA_CTRL 0x1E18 |
410 | #define VDEC_H_CRUSH_CTRL 0x1E1C | 410 | #define VDEC_H_CRUSH_CTRL 0x1E1C |
411 | #define VDEC_H_HORIZ_TIM_CTRL 0x1E20 | 411 | #define VDEC_H_HORIZ_TIM_CTRL 0x1E20 |
412 | #define VDEC_H_VERT_TIM_CTRL 0x1E24 | 412 | #define VDEC_H_VERT_TIM_CTRL 0x1E24 |
413 | #define VDEC_H_MISC_TIM_CTRL 0x1E28 | 413 | #define VDEC_H_MISC_TIM_CTRL 0x1E28 |
414 | #define VDEC_H_FIELD_COUNT 0x1E2C | 414 | #define VDEC_H_FIELD_COUNT 0x1E2C |
415 | #define VDEC_H_HSCALE_CTRL 0x1E30 | 415 | #define VDEC_H_HSCALE_CTRL 0x1E30 |
416 | #define VDEC_H_VSCALE_CTRL 0x1E34 | 416 | #define VDEC_H_VSCALE_CTRL 0x1E34 |
417 | #define VDEC_H_MAN_VGA_CTRL 0x1E38 | 417 | #define VDEC_H_MAN_VGA_CTRL 0x1E38 |
418 | #define VDEC_H_MAN_AGC_CTRL 0x1E3C | 418 | #define VDEC_H_MAN_AGC_CTRL 0x1E3C |
419 | #define VDEC_H_DFE_CTRL1 0x1E40 | 419 | #define VDEC_H_DFE_CTRL1 0x1E40 |
420 | #define VDEC_H_DFE_CTRL2 0x1E44 | 420 | #define VDEC_H_DFE_CTRL2 0x1E44 |
421 | #define VDEC_H_DFE_CTRL3 0x1E48 | 421 | #define VDEC_H_DFE_CTRL3 0x1E48 |
422 | #define VDEC_H_PLL_CTRL 0x1E4C | 422 | #define VDEC_H_PLL_CTRL 0x1E4C |
423 | #define VDEC_H_PLL_CTRL_FAST 0x1E50 | 423 | #define VDEC_H_PLL_CTRL_FAST 0x1E50 |
424 | #define VDEC_H_HTL_CTRL 0x1E54 | 424 | #define VDEC_H_HTL_CTRL 0x1E54 |
425 | #define VDEC_H_SRC_CFG 0x1E58 | 425 | #define VDEC_H_SRC_CFG 0x1E58 |
426 | #define VDEC_H_SC_STEP_SIZE 0x1E5C | 426 | #define VDEC_H_SC_STEP_SIZE 0x1E5C |
427 | #define VDEC_H_SC_CONVERGE_CTRL 0x1E60 | 427 | #define VDEC_H_SC_CONVERGE_CTRL 0x1E60 |
428 | #define VDEC_H_SC_LOOP_CTRL 0x1E64 | 428 | #define VDEC_H_SC_LOOP_CTRL 0x1E64 |
429 | #define VDEC_H_COMB_2D_HFS_CFG 0x1E68 | 429 | #define VDEC_H_COMB_2D_HFS_CFG 0x1E68 |
430 | #define VDEC_H_COMB_2D_HFD_CFG 0x1E6C | 430 | #define VDEC_H_COMB_2D_HFD_CFG 0x1E6C |
431 | #define VDEC_H_COMB_2D_LF_CFG 0x1E70 | 431 | #define VDEC_H_COMB_2D_LF_CFG 0x1E70 |
432 | #define VDEC_H_COMB_2D_BLEND 0x1E74 | 432 | #define VDEC_H_COMB_2D_BLEND 0x1E74 |
433 | #define VDEC_H_COMB_MISC_CTRL 0x1E78 | 433 | #define VDEC_H_COMB_MISC_CTRL 0x1E78 |
434 | #define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C | 434 | #define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C |
435 | #define VDEC_H_COMB_TEST 0x1E80 | 435 | #define VDEC_H_COMB_TEST 0x1E80 |
436 | #define VDEC_H_BP_MISC_CTRL 0x1E84 | 436 | #define VDEC_H_BP_MISC_CTRL 0x1E84 |
437 | #define VDEC_H_VCR_DET_CTRL 0x1E88 | 437 | #define VDEC_H_VCR_DET_CTRL 0x1E88 |
438 | #define VDEC_H_NOISE_DET_CTRL 0x1E8C | 438 | #define VDEC_H_NOISE_DET_CTRL 0x1E8C |
439 | #define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90 | 439 | #define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90 |
440 | #define VDEC_H_VERSION 0x1FF8 | 440 | #define VDEC_H_VERSION 0x1FF8 |
441 | #define VDEC_H_SOFT_RST_CTRL 0x1FFC | 441 | #define VDEC_H_SOFT_RST_CTRL 0x1FFC |
442 | 442 | ||
443 | /*****************************************************************************/ | 443 | /*****************************************************************************/ |
444 | /* LUMA_CTRL register fields */ | 444 | /* LUMA_CTRL register fields */ |
445 | #define VDEC_A_BRITE_CTRL 0x1014 | 445 | #define VDEC_A_BRITE_CTRL 0x1014 |
446 | #define VDEC_A_CNTRST_CTRL 0x1015 | 446 | #define VDEC_A_CNTRST_CTRL 0x1015 |
447 | #define VDEC_A_PEAK_SEL 0x1016 | 447 | #define VDEC_A_PEAK_SEL 0x1016 |
448 | 448 | ||
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c index fc780d0908dc..298a68d98c2f 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-video.c +++ b/drivers/media/video/cx25821/cx25821-medusa-video.c | |||
@@ -99,82 +99,67 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev) | |||
99 | 99 | ||
100 | for (i = 0; i < MAX_DECODERS; i++) { | 100 | for (i = 0; i < MAX_DECODERS; i++) { |
101 | /* set video format NTSC-M */ | 101 | /* set video format NTSC-M */ |
102 | value = | 102 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
103 | cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), | 103 | MODE_CTRL + (0x200 * i), &tmp); |
104 | &tmp); | ||
105 | value &= 0xFFFFFFF0; | 104 | value &= 0xFFFFFFF0; |
106 | /* enable the fast locking mode bit[16] */ | 105 | /* enable the fast locking mode bit[16] */ |
107 | value |= 0x10001; | 106 | value |= 0x10001; |
108 | ret_val = | 107 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
109 | cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), | 108 | MODE_CTRL + (0x200 * i), value); |
110 | value); | ||
111 | 109 | ||
112 | /* resolution NTSC 720x480 */ | 110 | /* resolution NTSC 720x480 */ |
113 | value = | 111 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
114 | cx25821_i2c_read(&dev->i2c_bus[0], | 112 | HORIZ_TIM_CTRL + (0x200 * i), &tmp); |
115 | HORIZ_TIM_CTRL + (0x200 * i), &tmp); | ||
116 | value &= 0x00C00C00; | 113 | value &= 0x00C00C00; |
117 | value |= 0x612D0074; | 114 | value |= 0x612D0074; |
118 | ret_val = | 115 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
119 | cx25821_i2c_write(&dev->i2c_bus[0], | 116 | HORIZ_TIM_CTRL + (0x200 * i), value); |
120 | HORIZ_TIM_CTRL + (0x200 * i), value); | ||
121 | 117 | ||
122 | value = | 118 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
123 | cx25821_i2c_read(&dev->i2c_bus[0], | 119 | VERT_TIM_CTRL + (0x200 * i), &tmp); |
124 | VERT_TIM_CTRL + (0x200 * i), &tmp); | ||
125 | value &= 0x00C00C00; | 120 | value &= 0x00C00C00; |
126 | value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */ | 121 | value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */ |
127 | ret_val = | 122 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
128 | cx25821_i2c_write(&dev->i2c_bus[0], | 123 | VERT_TIM_CTRL + (0x200 * i), value); |
129 | VERT_TIM_CTRL + (0x200 * i), value); | ||
130 | 124 | ||
131 | /* chroma subcarrier step size */ | 125 | /* chroma subcarrier step size */ |
132 | ret_val = | 126 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
133 | cx25821_i2c_write(&dev->i2c_bus[0], | 127 | SC_STEP_SIZE + (0x200 * i), 0x43E00000); |
134 | SC_STEP_SIZE + (0x200 * i), 0x43E00000); | ||
135 | 128 | ||
136 | /* enable VIP optional active */ | 129 | /* enable VIP optional active */ |
137 | value = | 130 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
138 | cx25821_i2c_read(&dev->i2c_bus[0], | 131 | OUT_CTRL_NS + (0x200 * i), &tmp); |
139 | OUT_CTRL_NS + (0x200 * i), &tmp); | ||
140 | value &= 0xFFFBFFFF; | 132 | value &= 0xFFFBFFFF; |
141 | value |= 0x00040000; | 133 | value |= 0x00040000; |
142 | ret_val = | 134 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
143 | cx25821_i2c_write(&dev->i2c_bus[0], | 135 | OUT_CTRL_NS + (0x200 * i), value); |
144 | OUT_CTRL_NS + (0x200 * i), value); | ||
145 | 136 | ||
146 | /* enable VIP optional active (VIP_OPT_AL) for direct output. */ | 137 | /* enable VIP optional active (VIP_OPT_AL) for direct output. */ |
147 | value = | 138 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
148 | cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), | 139 | OUT_CTRL1 + (0x200 * i), &tmp); |
149 | &tmp); | ||
150 | value &= 0xFFFBFFFF; | 140 | value &= 0xFFFBFFFF; |
151 | value |= 0x00040000; | 141 | value |= 0x00040000; |
152 | ret_val = | 142 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
153 | cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), | 143 | OUT_CTRL1 + (0x200 * i), value); |
154 | value); | ||
155 | 144 | ||
156 | /* | 145 | /* |
157 | * clear VPRES_VERT_EN bit, fixes the chroma run away problem | 146 | * clear VPRES_VERT_EN bit, fixes the chroma run away problem |
158 | * when the input switching rate < 16 fields | 147 | * when the input switching rate < 16 fields |
159 | */ | 148 | */ |
160 | value = | 149 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
161 | cx25821_i2c_read(&dev->i2c_bus[0], | 150 | MISC_TIM_CTRL + (0x200 * i), &tmp); |
162 | MISC_TIM_CTRL + (0x200 * i), &tmp); | ||
163 | /* disable special play detection */ | 151 | /* disable special play detection */ |
164 | value = setBitAtPos(value, 14); | 152 | value = setBitAtPos(value, 14); |
165 | value = clearBitAtPos(value, 15); | 153 | value = clearBitAtPos(value, 15); |
166 | ret_val = | 154 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
167 | cx25821_i2c_write(&dev->i2c_bus[0], | 155 | MISC_TIM_CTRL + (0x200 * i), value); |
168 | MISC_TIM_CTRL + (0x200 * i), value); | ||
169 | 156 | ||
170 | /* set vbi_gate_en to 0 */ | 157 | /* set vbi_gate_en to 0 */ |
171 | value = | 158 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
172 | cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), | 159 | DFE_CTRL1 + (0x200 * i), &tmp); |
173 | &tmp); | ||
174 | value = clearBitAtPos(value, 29); | 160 | value = clearBitAtPos(value, 29); |
175 | ret_val = | 161 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
176 | cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), | 162 | DFE_CTRL1 + (0x200 * i), value); |
177 | value); | ||
178 | 163 | ||
179 | /* Enable the generation of blue field output if no video */ | 164 | /* Enable the generation of blue field output if no video */ |
180 | medusa_enable_bluefield_output(dev, i, 1); | 165 | medusa_enable_bluefield_output(dev, i, 1); |
@@ -182,61 +167,49 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev) | |||
182 | 167 | ||
183 | for (i = 0; i < MAX_ENCODERS; i++) { | 168 | for (i = 0; i < MAX_ENCODERS; i++) { |
184 | /* NTSC hclock */ | 169 | /* NTSC hclock */ |
185 | value = | 170 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
186 | cx25821_i2c_read(&dev->i2c_bus[0], | 171 | DENC_A_REG_1 + (0x100 * i), &tmp); |
187 | DENC_A_REG_1 + (0x100 * i), &tmp); | ||
188 | value &= 0xF000FC00; | 172 | value &= 0xF000FC00; |
189 | value |= 0x06B402D0; | 173 | value |= 0x06B402D0; |
190 | ret_val = | 174 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
191 | cx25821_i2c_write(&dev->i2c_bus[0], | 175 | DENC_A_REG_1 + (0x100 * i), value); |
192 | DENC_A_REG_1 + (0x100 * i), value); | ||
193 | 176 | ||
194 | /* burst begin and burst end */ | 177 | /* burst begin and burst end */ |
195 | value = | 178 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
196 | cx25821_i2c_read(&dev->i2c_bus[0], | 179 | DENC_A_REG_2 + (0x100 * i), &tmp); |
197 | DENC_A_REG_2 + (0x100 * i), &tmp); | ||
198 | value &= 0xFF000000; | 180 | value &= 0xFF000000; |
199 | value |= 0x007E9054; | 181 | value |= 0x007E9054; |
200 | ret_val = | 182 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
201 | cx25821_i2c_write(&dev->i2c_bus[0], | 183 | DENC_A_REG_2 + (0x100 * i), value); |
202 | DENC_A_REG_2 + (0x100 * i), value); | ||
203 | 184 | ||
204 | value = | 185 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
205 | cx25821_i2c_read(&dev->i2c_bus[0], | 186 | DENC_A_REG_3 + (0x100 * i), &tmp); |
206 | DENC_A_REG_3 + (0x100 * i), &tmp); | ||
207 | value &= 0xFC00FE00; | 187 | value &= 0xFC00FE00; |
208 | value |= 0x00EC00F0; | 188 | value |= 0x00EC00F0; |
209 | ret_val = | 189 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
210 | cx25821_i2c_write(&dev->i2c_bus[0], | 190 | DENC_A_REG_3 + (0x100 * i), value); |
211 | DENC_A_REG_3 + (0x100 * i), value); | ||
212 | 191 | ||
213 | /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */ | 192 | /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */ |
214 | value = | 193 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
215 | cx25821_i2c_read(&dev->i2c_bus[0], | 194 | DENC_A_REG_4 + (0x100 * i), &tmp); |
216 | DENC_A_REG_4 + (0x100 * i), &tmp); | ||
217 | value &= 0x00FCFFFF; | 195 | value &= 0x00FCFFFF; |
218 | value |= 0x13020000; | 196 | value |= 0x13020000; |
219 | ret_val = | 197 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
220 | cx25821_i2c_write(&dev->i2c_bus[0], | 198 | DENC_A_REG_4 + (0x100 * i), value); |
221 | DENC_A_REG_4 + (0x100 * i), value); | ||
222 | 199 | ||
223 | value = | 200 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
224 | cx25821_i2c_read(&dev->i2c_bus[0], | 201 | DENC_A_REG_5 + (0x100 * i), &tmp); |
225 | DENC_A_REG_5 + (0x100 * i), &tmp); | ||
226 | value &= 0xFFFF0000; | 202 | value &= 0xFFFF0000; |
227 | value |= 0x0000E575; | 203 | value |= 0x0000E575; |
228 | ret_val = | 204 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
229 | cx25821_i2c_write(&dev->i2c_bus[0], | 205 | DENC_A_REG_5 + (0x100 * i), value); |
230 | DENC_A_REG_5 + (0x100 * i), value); | ||
231 | 206 | ||
232 | ret_val = | 207 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
233 | cx25821_i2c_write(&dev->i2c_bus[0], | 208 | DENC_A_REG_6 + (0x100 * i), 0x009A89C1); |
234 | DENC_A_REG_6 + (0x100 * i), 0x009A89C1); | ||
235 | 209 | ||
236 | /* Subcarrier Increment */ | 210 | /* Subcarrier Increment */ |
237 | ret_val = | 211 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
238 | cx25821_i2c_write(&dev->i2c_bus[0], | 212 | DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); |
239 | DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); | ||
240 | } | 213 | } |
241 | 214 | ||
242 | /* set picture resolutions */ | 215 | /* set picture resolutions */ |
@@ -261,34 +234,27 @@ static int medusa_PALCombInit(struct cx25821_dev *dev, int dec) | |||
261 | u32 value = 0, tmp = 0; | 234 | u32 value = 0, tmp = 0; |
262 | 235 | ||
263 | /* Setup for 2D threshold */ | 236 | /* Setup for 2D threshold */ |
264 | ret_val = | 237 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
265 | cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec), | 238 | COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861); |
266 | 0x20002861); | 239 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
267 | ret_val = | 240 | COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861); |
268 | cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec), | 241 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
269 | 0x20002861); | 242 | COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023); |
270 | ret_val = | ||
271 | cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec), | ||
272 | 0x200A1023); | ||
273 | 243 | ||
274 | /* Setup flat chroma and luma thresholds */ | 244 | /* Setup flat chroma and luma thresholds */ |
275 | value = | 245 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
276 | cx25821_i2c_read(&dev->i2c_bus[0], | 246 | COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); |
277 | COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); | ||
278 | value &= 0x06230000; | 247 | value &= 0x06230000; |
279 | ret_val = | 248 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
280 | cx25821_i2c_write(&dev->i2c_bus[0], | 249 | COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); |
281 | COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); | ||
282 | 250 | ||
283 | /* set comb 2D blend */ | 251 | /* set comb 2D blend */ |
284 | ret_val = | 252 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
285 | cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec), | 253 | COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F); |
286 | 0x210F0F0F); | ||
287 | 254 | ||
288 | /* COMB MISC CONTROL */ | 255 | /* COMB MISC CONTROL */ |
289 | ret_val = | 256 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
290 | cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec), | 257 | COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F); |
291 | 0x41120A7F); | ||
292 | 258 | ||
293 | return ret_val; | 259 | return ret_val; |
294 | } | 260 | } |
@@ -304,83 +270,68 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) | |||
304 | 270 | ||
305 | for (i = 0; i < MAX_DECODERS; i++) { | 271 | for (i = 0; i < MAX_DECODERS; i++) { |
306 | /* set video format PAL-BDGHI */ | 272 | /* set video format PAL-BDGHI */ |
307 | value = | 273 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
308 | cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), | 274 | MODE_CTRL + (0x200 * i), &tmp); |
309 | &tmp); | ||
310 | value &= 0xFFFFFFF0; | 275 | value &= 0xFFFFFFF0; |
311 | /* enable the fast locking mode bit[16] */ | 276 | /* enable the fast locking mode bit[16] */ |
312 | value |= 0x10004; | 277 | value |= 0x10004; |
313 | ret_val = | 278 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
314 | cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), | 279 | MODE_CTRL + (0x200 * i), value); |
315 | value); | ||
316 | 280 | ||
317 | /* resolution PAL 720x576 */ | 281 | /* resolution PAL 720x576 */ |
318 | value = | 282 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
319 | cx25821_i2c_read(&dev->i2c_bus[0], | 283 | HORIZ_TIM_CTRL + (0x200 * i), &tmp); |
320 | HORIZ_TIM_CTRL + (0x200 * i), &tmp); | ||
321 | value &= 0x00C00C00; | 284 | value &= 0x00C00C00; |
322 | value |= 0x632D007D; | 285 | value |= 0x632D007D; |
323 | ret_val = | 286 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
324 | cx25821_i2c_write(&dev->i2c_bus[0], | 287 | HORIZ_TIM_CTRL + (0x200 * i), value); |
325 | HORIZ_TIM_CTRL + (0x200 * i), value); | ||
326 | 288 | ||
327 | /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */ | 289 | /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */ |
328 | value = | 290 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
329 | cx25821_i2c_read(&dev->i2c_bus[0], | 291 | VERT_TIM_CTRL + (0x200 * i), &tmp); |
330 | VERT_TIM_CTRL + (0x200 * i), &tmp); | ||
331 | value &= 0x00C00C00; | 292 | value &= 0x00C00C00; |
332 | value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */ | 293 | value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */ |
333 | ret_val = | 294 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
334 | cx25821_i2c_write(&dev->i2c_bus[0], | 295 | VERT_TIM_CTRL + (0x200 * i), value); |
335 | VERT_TIM_CTRL + (0x200 * i), value); | ||
336 | 296 | ||
337 | /* chroma subcarrier step size */ | 297 | /* chroma subcarrier step size */ |
338 | ret_val = | 298 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
339 | cx25821_i2c_write(&dev->i2c_bus[0], | 299 | SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); |
340 | SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); | ||
341 | 300 | ||
342 | /* enable VIP optional active */ | 301 | /* enable VIP optional active */ |
343 | value = | 302 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
344 | cx25821_i2c_read(&dev->i2c_bus[0], | 303 | OUT_CTRL_NS + (0x200 * i), &tmp); |
345 | OUT_CTRL_NS + (0x200 * i), &tmp); | ||
346 | value &= 0xFFFBFFFF; | 304 | value &= 0xFFFBFFFF; |
347 | value |= 0x00040000; | 305 | value |= 0x00040000; |
348 | ret_val = | 306 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
349 | cx25821_i2c_write(&dev->i2c_bus[0], | 307 | OUT_CTRL_NS + (0x200 * i), value); |
350 | OUT_CTRL_NS + (0x200 * i), value); | ||
351 | 308 | ||
352 | /* enable VIP optional active (VIP_OPT_AL) for direct output. */ | 309 | /* enable VIP optional active (VIP_OPT_AL) for direct output. */ |
353 | value = | 310 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
354 | cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), | 311 | OUT_CTRL1 + (0x200 * i), &tmp); |
355 | &tmp); | ||
356 | value &= 0xFFFBFFFF; | 312 | value &= 0xFFFBFFFF; |
357 | value |= 0x00040000; | 313 | value |= 0x00040000; |
358 | ret_val = | 314 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
359 | cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), | 315 | OUT_CTRL1 + (0x200 * i), value); |
360 | value); | ||
361 | 316 | ||
362 | /* | 317 | /* |
363 | * clear VPRES_VERT_EN bit, fixes the chroma run away problem | 318 | * clear VPRES_VERT_EN bit, fixes the chroma run away problem |
364 | * when the input switching rate < 16 fields | 319 | * when the input switching rate < 16 fields |
365 | */ | 320 | */ |
366 | value = | 321 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
367 | cx25821_i2c_read(&dev->i2c_bus[0], | 322 | MISC_TIM_CTRL + (0x200 * i), &tmp); |
368 | MISC_TIM_CTRL + (0x200 * i), &tmp); | ||
369 | /* disable special play detection */ | 323 | /* disable special play detection */ |
370 | value = setBitAtPos(value, 14); | 324 | value = setBitAtPos(value, 14); |
371 | value = clearBitAtPos(value, 15); | 325 | value = clearBitAtPos(value, 15); |
372 | ret_val = | 326 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
373 | cx25821_i2c_write(&dev->i2c_bus[0], | 327 | MISC_TIM_CTRL + (0x200 * i), value); |
374 | MISC_TIM_CTRL + (0x200 * i), value); | ||
375 | 328 | ||
376 | /* set vbi_gate_en to 0 */ | 329 | /* set vbi_gate_en to 0 */ |
377 | value = | 330 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
378 | cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), | 331 | DFE_CTRL1 + (0x200 * i), &tmp); |
379 | &tmp); | ||
380 | value = clearBitAtPos(value, 29); | 332 | value = clearBitAtPos(value, 29); |
381 | ret_val = | 333 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
382 | cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), | 334 | DFE_CTRL1 + (0x200 * i), value); |
383 | value); | ||
384 | 335 | ||
385 | medusa_PALCombInit(dev, i); | 336 | medusa_PALCombInit(dev, i); |
386 | 337 | ||
@@ -390,62 +341,50 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) | |||
390 | 341 | ||
391 | for (i = 0; i < MAX_ENCODERS; i++) { | 342 | for (i = 0; i < MAX_ENCODERS; i++) { |
392 | /* PAL hclock */ | 343 | /* PAL hclock */ |
393 | value = | 344 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
394 | cx25821_i2c_read(&dev->i2c_bus[0], | 345 | DENC_A_REG_1 + (0x100 * i), &tmp); |
395 | DENC_A_REG_1 + (0x100 * i), &tmp); | ||
396 | value &= 0xF000FC00; | 346 | value &= 0xF000FC00; |
397 | value |= 0x06C002D0; | 347 | value |= 0x06C002D0; |
398 | ret_val = | 348 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
399 | cx25821_i2c_write(&dev->i2c_bus[0], | 349 | DENC_A_REG_1 + (0x100 * i), value); |
400 | DENC_A_REG_1 + (0x100 * i), value); | ||
401 | 350 | ||
402 | /* burst begin and burst end */ | 351 | /* burst begin and burst end */ |
403 | value = | 352 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
404 | cx25821_i2c_read(&dev->i2c_bus[0], | 353 | DENC_A_REG_2 + (0x100 * i), &tmp); |
405 | DENC_A_REG_2 + (0x100 * i), &tmp); | ||
406 | value &= 0xFF000000; | 354 | value &= 0xFF000000; |
407 | value |= 0x007E9754; | 355 | value |= 0x007E9754; |
408 | ret_val = | 356 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
409 | cx25821_i2c_write(&dev->i2c_bus[0], | 357 | DENC_A_REG_2 + (0x100 * i), value); |
410 | DENC_A_REG_2 + (0x100 * i), value); | ||
411 | 358 | ||
412 | /* hblank and vactive */ | 359 | /* hblank and vactive */ |
413 | value = | 360 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
414 | cx25821_i2c_read(&dev->i2c_bus[0], | 361 | DENC_A_REG_3 + (0x100 * i), &tmp); |
415 | DENC_A_REG_3 + (0x100 * i), &tmp); | ||
416 | value &= 0xFC00FE00; | 362 | value &= 0xFC00FE00; |
417 | value |= 0x00FC0120; | 363 | value |= 0x00FC0120; |
418 | ret_val = | 364 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
419 | cx25821_i2c_write(&dev->i2c_bus[0], | 365 | DENC_A_REG_3 + (0x100 * i), value); |
420 | DENC_A_REG_3 + (0x100 * i), value); | ||
421 | 366 | ||
422 | /* set PAL vblank, phase alternation, 0 IRE pedestal */ | 367 | /* set PAL vblank, phase alternation, 0 IRE pedestal */ |
423 | value = | 368 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
424 | cx25821_i2c_read(&dev->i2c_bus[0], | 369 | DENC_A_REG_4 + (0x100 * i), &tmp); |
425 | DENC_A_REG_4 + (0x100 * i), &tmp); | ||
426 | value &= 0x00FCFFFF; | 370 | value &= 0x00FCFFFF; |
427 | value |= 0x14010000; | 371 | value |= 0x14010000; |
428 | ret_val = | 372 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
429 | cx25821_i2c_write(&dev->i2c_bus[0], | 373 | DENC_A_REG_4 + (0x100 * i), value); |
430 | DENC_A_REG_4 + (0x100 * i), value); | ||
431 | 374 | ||
432 | value = | 375 | value = cx25821_i2c_read(&dev->i2c_bus[0], |
433 | cx25821_i2c_read(&dev->i2c_bus[0], | 376 | DENC_A_REG_5 + (0x100 * i), &tmp); |
434 | DENC_A_REG_5 + (0x100 * i), &tmp); | ||
435 | value &= 0xFFFF0000; | 377 | value &= 0xFFFF0000; |
436 | value |= 0x0000F078; | 378 | value |= 0x0000F078; |
437 | ret_val = | 379 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
438 | cx25821_i2c_write(&dev->i2c_bus[0], | 380 | DENC_A_REG_5 + (0x100 * i), value); |
439 | DENC_A_REG_5 + (0x100 * i), value); | ||
440 | 381 | ||
441 | ret_val = | 382 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
442 | cx25821_i2c_write(&dev->i2c_bus[0], | 383 | DENC_A_REG_6 + (0x100 * i), 0x00A493CF); |
443 | DENC_A_REG_6 + (0x100 * i), 0x00A493CF); | ||
444 | 384 | ||
445 | /* Subcarrier Increment */ | 385 | /* Subcarrier Increment */ |
446 | ret_val = | 386 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
447 | cx25821_i2c_write(&dev->i2c_bus[0], | 387 | DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); |
448 | DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); | ||
449 | } | 388 | } |
450 | 389 | ||
451 | /* set picture resolutions */ | 390 | /* set picture resolutions */ |
@@ -499,7 +438,7 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, | |||
499 | 438 | ||
500 | mutex_lock(&dev->lock); | 439 | mutex_lock(&dev->lock); |
501 | 440 | ||
502 | /* validate the width - cannot be negative */ | 441 | /* validate the width */ |
503 | if (width > MAX_WIDTH) { | 442 | if (width > MAX_WIDTH) { |
504 | pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", | 443 | pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", |
505 | __func__, width, MAX_WIDTH); | 444 | __func__, width, MAX_WIDTH); |
@@ -543,12 +482,10 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, | |||
543 | 482 | ||
544 | for (; decoder < decoder_count; decoder++) { | 483 | for (; decoder < decoder_count; decoder++) { |
545 | /* write scaling values for each decoder */ | 484 | /* write scaling values for each decoder */ |
546 | ret_val = | 485 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
547 | cx25821_i2c_write(&dev->i2c_bus[0], | 486 | HSCALE_CTRL + (0x200 * decoder), hscale); |
548 | HSCALE_CTRL + (0x200 * decoder), hscale); | 487 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], |
549 | ret_val = | 488 | VSCALE_CTRL + (0x200 * decoder), vscale); |
550 | cx25821_i2c_write(&dev->i2c_bus[0], | ||
551 | VSCALE_CTRL + (0x200 * decoder), vscale); | ||
552 | } | 489 | } |
553 | 490 | ||
554 | mutex_unlock(&dev->lock); | 491 | mutex_unlock(&dev->lock); |
@@ -606,8 +543,8 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, | |||
606 | } | 543 | } |
607 | 544 | ||
608 | /* Map to Medusa register setting */ | 545 | /* Map to Medusa register setting */ |
609 | static int mapM(int srcMin, | 546 | static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax, |
610 | int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal) | 547 | int *dstVal) |
611 | { | 548 | { |
612 | int numerator; | 549 | int numerator; |
613 | int denominator; | 550 | int denominator; |
@@ -654,23 +591,19 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) | |||
654 | u32 val = 0, tmp = 0; | 591 | u32 val = 0, tmp = 0; |
655 | 592 | ||
656 | mutex_lock(&dev->lock); | 593 | mutex_lock(&dev->lock); |
657 | if ((brightness > VIDEO_PROCAMP_MAX) | 594 | if ((brightness > VIDEO_PROCAMP_MAX) || |
658 | || (brightness < VIDEO_PROCAMP_MIN)) { | 595 | (brightness < VIDEO_PROCAMP_MIN)) { |
659 | mutex_unlock(&dev->lock); | 596 | mutex_unlock(&dev->lock); |
660 | return -1; | 597 | return -1; |
661 | } | 598 | } |
662 | ret_val = | 599 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, |
663 | mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, | 600 | SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); |
664 | SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); | ||
665 | value = convert_to_twos(value, 8); | 601 | value = convert_to_twos(value, 8); |
666 | val = | 602 | val = cx25821_i2c_read(&dev->i2c_bus[0], |
667 | cx25821_i2c_read(&dev->i2c_bus[0], | 603 | VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp); |
668 | VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp); | ||
669 | val &= 0xFFFFFF00; | 604 | val &= 0xFFFFFF00; |
670 | ret_val |= | 605 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], |
671 | cx25821_i2c_write(&dev->i2c_bus[0], | 606 | VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value); |
672 | VDEC_A_BRITE_CTRL + (0x200 * decoder), | ||
673 | val | value); | ||
674 | mutex_unlock(&dev->lock); | 607 | mutex_unlock(&dev->lock); |
675 | return ret_val; | 608 | return ret_val; |
676 | } | 609 | } |
@@ -688,17 +621,13 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) | |||
688 | return -1; | 621 | return -1; |
689 | } | 622 | } |
690 | 623 | ||
691 | ret_val = | 624 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, |
692 | mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, | 625 | UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); |
693 | UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); | 626 | val = cx25821_i2c_read(&dev->i2c_bus[0], |
694 | val = | 627 | VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp); |
695 | cx25821_i2c_read(&dev->i2c_bus[0], | ||
696 | VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp); | ||
697 | val &= 0xFFFFFF00; | 628 | val &= 0xFFFFFF00; |
698 | ret_val |= | 629 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], |
699 | cx25821_i2c_write(&dev->i2c_bus[0], | 630 | VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value); |
700 | VDEC_A_CNTRST_CTRL + (0x200 * decoder), | ||
701 | val | value); | ||
702 | 631 | ||
703 | mutex_unlock(&dev->lock); | 632 | mutex_unlock(&dev->lock); |
704 | return ret_val; | 633 | return ret_val; |
@@ -717,19 +646,16 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) | |||
717 | return -1; | 646 | return -1; |
718 | } | 647 | } |
719 | 648 | ||
720 | ret_val = | 649 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, |
721 | mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN, | 650 | SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); |
722 | SIGNED_BYTE_MAX, &value); | ||
723 | 651 | ||
724 | value = convert_to_twos(value, 8); | 652 | value = convert_to_twos(value, 8); |
725 | val = | 653 | val = cx25821_i2c_read(&dev->i2c_bus[0], |
726 | cx25821_i2c_read(&dev->i2c_bus[0], | 654 | VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp); |
727 | VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp); | ||
728 | val &= 0xFFFFFF00; | 655 | val &= 0xFFFFFF00; |
729 | 656 | ||
730 | ret_val |= | 657 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], |
731 | cx25821_i2c_write(&dev->i2c_bus[0], | 658 | VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); |
732 | VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); | ||
733 | 659 | ||
734 | mutex_unlock(&dev->lock); | 660 | mutex_unlock(&dev->lock); |
735 | return ret_val; | 661 | return ret_val; |
@@ -743,33 +669,26 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) | |||
743 | 669 | ||
744 | mutex_lock(&dev->lock); | 670 | mutex_lock(&dev->lock); |
745 | 671 | ||
746 | if ((saturation > VIDEO_PROCAMP_MAX) | 672 | if ((saturation > VIDEO_PROCAMP_MAX) || |
747 | || (saturation < VIDEO_PROCAMP_MIN)) { | 673 | (saturation < VIDEO_PROCAMP_MIN)) { |
748 | mutex_unlock(&dev->lock); | 674 | mutex_unlock(&dev->lock); |
749 | return -1; | 675 | return -1; |
750 | } | 676 | } |
751 | 677 | ||
752 | ret_val = | 678 | ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, |
753 | mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, | 679 | UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); |
754 | UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); | ||
755 | 680 | ||
756 | val = | 681 | val = cx25821_i2c_read(&dev->i2c_bus[0], |
757 | cx25821_i2c_read(&dev->i2c_bus[0], | 682 | VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp); |
758 | VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp); | ||
759 | val &= 0xFFFFFF00; | 683 | val &= 0xFFFFFF00; |
760 | ret_val |= | 684 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], |
761 | cx25821_i2c_write(&dev->i2c_bus[0], | 685 | VDEC_A_USAT_CTRL + (0x200 * decoder), val | value); |
762 | VDEC_A_USAT_CTRL + (0x200 * decoder), | 686 | |
763 | val | value); | 687 | val = cx25821_i2c_read(&dev->i2c_bus[0], |
764 | 688 | VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp); | |
765 | val = | ||
766 | cx25821_i2c_read(&dev->i2c_bus[0], | ||
767 | VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp); | ||
768 | val &= 0xFFFFFF00; | 689 | val &= 0xFFFFFF00; |
769 | ret_val |= | 690 | ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], |
770 | cx25821_i2c_write(&dev->i2c_bus[0], | 691 | VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value); |
771 | VDEC_A_VSAT_CTRL + (0x200 * decoder), | ||
772 | val | value); | ||
773 | 692 | ||
774 | mutex_unlock(&dev->lock); | 693 | mutex_unlock(&dev->lock); |
775 | return ret_val; | 694 | return ret_val; |
@@ -830,9 +749,8 @@ int medusa_video_init(struct cx25821_dev *dev) | |||
830 | /* select AFE clock to output mode */ | 749 | /* select AFE clock to output mode */ |
831 | value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); | 750 | value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); |
832 | value &= 0x83FFFFFF; | 751 | value &= 0x83FFFFFF; |
833 | ret_val = | 752 | ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, |
834 | cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, | 753 | value | 0x10000000); |
835 | value | 0x10000000); | ||
836 | 754 | ||
837 | if (ret_val < 0) | 755 | if (ret_val < 0) |
838 | goto error; | 756 | goto error; |
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index 2a724ddfa53f..5a157cf4a95e 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c | |||
@@ -65,9 +65,8 @@ static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, | |||
65 | *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); | 65 | *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); |
66 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 66 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
67 | 67 | ||
68 | if ((lines <= NTSC_FIELD_HEIGHT) | 68 | if ((lines <= NTSC_FIELD_HEIGHT) || |
69 | || (line < (NTSC_FIELD_HEIGHT - 1)) | 69 | (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { |
70 | || !(dev->_isNTSC_ch2)) { | ||
71 | offset += dist_betwn_starts; | 70 | offset += dist_betwn_starts; |
72 | } | 71 | } |
73 | } | 72 | } |
@@ -85,7 +84,7 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, | |||
85 | { | 84 | { |
86 | unsigned int line, i; | 85 | unsigned int line, i; |
87 | struct sram_channel *sram_ch = | 86 | struct sram_channel *sram_ch = |
88 | dev->channels[dev->_channel2_upstream_select].sram_channels; | 87 | dev->channels[dev->_channel2_upstream_select].sram_channels; |
89 | int dist_betwn_starts = bpl * 2; | 88 | int dist_betwn_starts = bpl * 2; |
90 | 89 | ||
91 | /* sync instruction */ | 90 | /* sync instruction */ |
@@ -103,9 +102,8 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, | |||
103 | *(rp++) = cpu_to_le32(databuf_phys_addr + offset); | 102 | *(rp++) = cpu_to_le32(databuf_phys_addr + offset); |
104 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 103 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
105 | 104 | ||
106 | if ((lines <= NTSC_FIELD_HEIGHT) | 105 | if ((lines <= NTSC_FIELD_HEIGHT) || |
107 | || (line < (NTSC_FIELD_HEIGHT - 1)) | 106 | (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { |
108 | || !(dev->_isNTSC_ch2)) { | ||
109 | offset += dist_betwn_starts; | 107 | offset += dist_betwn_starts; |
110 | } | 108 | } |
111 | 109 | ||
@@ -173,7 +171,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, | |||
173 | 171 | ||
174 | fifo_enable = FIFO_DISABLE; | 172 | fifo_enable = FIFO_DISABLE; |
175 | 173 | ||
176 | /* Even field */ | 174 | /* Even field */ |
177 | rp = cx25821_risc_field_upstream_ch2(dev, rp, | 175 | rp = cx25821_risc_field_upstream_ch2(dev, rp, |
178 | dev->_data_buf_phys_addr_ch2 + databuf_offset, | 176 | dev->_data_buf_phys_addr_ch2 + databuf_offset, |
179 | bottom_offset, 0x200, bpl, singlefield_lines, | 177 | bottom_offset, 0x200, bpl, singlefield_lines, |
@@ -189,9 +187,9 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, | |||
189 | } | 187 | } |
190 | 188 | ||
191 | /* | 189 | /* |
192 | Loop to 2ndFrameRISC or to Start of | 190 | * Loop to 2ndFrameRISC or to Start of |
193 | Risc program & generate IRQ | 191 | * Risc program & generate IRQ |
194 | */ | 192 | */ |
195 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); | 193 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); |
196 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | 194 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); |
197 | *(rp++) = cpu_to_le32(0); | 195 | *(rp++) = cpu_to_le32(0); |
@@ -203,7 +201,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, | |||
203 | void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) | 201 | void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) |
204 | { | 202 | { |
205 | struct sram_channel *sram_ch = | 203 | struct sram_channel *sram_ch = |
206 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; | 204 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; |
207 | u32 tmp = 0; | 205 | u32 tmp = 0; |
208 | 206 | ||
209 | if (!dev->_is_running_ch2) { | 207 | if (!dev->_is_running_ch2) { |
@@ -262,9 +260,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
262 | struct file *myfile; | 260 | struct file *myfile; |
263 | int frame_index_temp = dev->_frame_index_ch2; | 261 | int frame_index_temp = dev->_frame_index_ch2; |
264 | int i = 0; | 262 | int i = 0; |
265 | int line_size = | 263 | int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? |
266 | (dev->_pixel_format_ch2 == | 264 | Y411_LINE_SZ : Y422_LINE_SZ; |
267 | PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; | ||
268 | int frame_size = 0; | 265 | int frame_size = 0; |
269 | int frame_offset = 0; | 266 | int frame_offset = 0; |
270 | ssize_t vfs_read_retval = 0; | 267 | ssize_t vfs_read_retval = 0; |
@@ -277,14 +274,11 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
277 | return 0; | 274 | return 0; |
278 | 275 | ||
279 | if (dev->_isNTSC_ch2) { | 276 | if (dev->_isNTSC_ch2) { |
280 | frame_size = | 277 | frame_size = (line_size == Y411_LINE_SZ) ? |
281 | (line_size == | 278 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; |
282 | Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : | ||
283 | FRAME_SIZE_NTSC_Y422; | ||
284 | } else { | 279 | } else { |
285 | frame_size = | 280 | frame_size = (line_size == Y411_LINE_SZ) ? |
286 | (line_size == | 281 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; |
287 | Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
288 | } | 282 | } |
289 | 283 | ||
290 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; | 284 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; |
@@ -318,14 +312,14 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
318 | for (i = 0; i < dev->_lines_count_ch2; i++) { | 312 | for (i = 0; i < dev->_lines_count_ch2; i++) { |
319 | pos = file_offset; | 313 | pos = file_offset; |
320 | 314 | ||
321 | vfs_read_retval = | 315 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, |
322 | vfs_read(myfile, mybuf, line_size, &pos); | 316 | &pos); |
323 | 317 | ||
324 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | 318 | if (vfs_read_retval > 0 && vfs_read_retval == line_size |
325 | && dev->_data_buf_virt_addr_ch2 != NULL) { | 319 | && dev->_data_buf_virt_addr_ch2 != NULL) { |
326 | memcpy((void *)(dev->_data_buf_virt_addr_ch2 + | 320 | memcpy((void *)(dev->_data_buf_virt_addr_ch2 + |
327 | frame_offset / 4), mybuf, | 321 | frame_offset / 4), mybuf, |
328 | vfs_read_retval); | 322 | vfs_read_retval); |
329 | } | 323 | } |
330 | 324 | ||
331 | file_offset += vfs_read_retval; | 325 | file_offset += vfs_read_retval; |
@@ -341,8 +335,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
341 | if (i > 0) | 335 | if (i > 0) |
342 | dev->_frame_count_ch2++; | 336 | dev->_frame_count_ch2++; |
343 | 337 | ||
344 | dev->_file_status_ch2 = | 338 | dev->_file_status_ch2 = (vfs_read_retval == line_size) ? |
345 | (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; | 339 | IN_PROGRESS : END_OF_FILE; |
346 | 340 | ||
347 | set_fs(old_fs); | 341 | set_fs(old_fs); |
348 | filp_close(myfile, NULL); | 342 | filp_close(myfile, NULL); |
@@ -353,8 +347,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
353 | 347 | ||
354 | static void cx25821_vidups_handler_ch2(struct work_struct *work) | 348 | static void cx25821_vidups_handler_ch2(struct work_struct *work) |
355 | { | 349 | { |
356 | struct cx25821_dev *dev = | 350 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, |
357 | container_of(work, struct cx25821_dev, _irq_work_entry_ch2); | 351 | _irq_work_entry_ch2); |
358 | 352 | ||
359 | if (!dev) { | 353 | if (!dev) { |
360 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | 354 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", |
@@ -362,18 +356,16 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work) | |||
362 | return; | 356 | return; |
363 | } | 357 | } |
364 | 358 | ||
365 | cx25821_get_frame_ch2(dev, | 359 | cx25821_get_frame_ch2(dev, dev->channels[dev-> |
366 | dev->channels[dev-> | 360 | _channel2_upstream_select].sram_channels); |
367 | _channel2_upstream_select].sram_channels); | ||
368 | } | 361 | } |
369 | 362 | ||
370 | int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | 363 | int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) |
371 | { | 364 | { |
372 | struct file *myfile; | 365 | struct file *myfile; |
373 | int i = 0, j = 0; | 366 | int i = 0, j = 0; |
374 | int line_size = | 367 | int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? |
375 | (dev->_pixel_format_ch2 == | 368 | Y411_LINE_SZ : Y422_LINE_SZ; |
376 | PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; | ||
377 | ssize_t vfs_read_retval = 0; | 369 | ssize_t vfs_read_retval = 0; |
378 | char mybuf[line_size]; | 370 | char mybuf[line_size]; |
379 | loff_t pos; | 371 | loff_t pos; |
@@ -410,16 +402,16 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
410 | for (i = 0; i < dev->_lines_count_ch2; i++) { | 402 | for (i = 0; i < dev->_lines_count_ch2; i++) { |
411 | pos = offset; | 403 | pos = offset; |
412 | 404 | ||
413 | vfs_read_retval = | 405 | vfs_read_retval = vfs_read(myfile, mybuf, |
414 | vfs_read(myfile, mybuf, line_size, &pos); | 406 | line_size, &pos); |
415 | 407 | ||
416 | if (vfs_read_retval > 0 | 408 | if (vfs_read_retval > 0 && |
417 | && vfs_read_retval == line_size | 409 | vfs_read_retval == line_size && |
418 | && dev->_data_buf_virt_addr_ch2 != NULL) { | 410 | dev->_data_buf_virt_addr_ch2 != NULL) { |
419 | memcpy((void *)(dev-> | 411 | memcpy((void *)(dev-> |
420 | _data_buf_virt_addr_ch2 | 412 | _data_buf_virt_addr_ch2 |
421 | + offset / 4), mybuf, | 413 | + offset / 4), mybuf, |
422 | vfs_read_retval); | 414 | vfs_read_retval); |
423 | } | 415 | } |
424 | 416 | ||
425 | offset += vfs_read_retval; | 417 | offset += vfs_read_retval; |
@@ -438,8 +430,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
438 | break; | 430 | break; |
439 | } | 431 | } |
440 | 432 | ||
441 | dev->_file_status_ch2 = | 433 | dev->_file_status_ch2 = (vfs_read_retval == line_size) ? |
442 | (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; | 434 | IN_PROGRESS : END_OF_FILE; |
443 | 435 | ||
444 | set_fs(old_fs); | 436 | set_fs(old_fs); |
445 | myfile->f_pos = 0; | 437 | myfile->f_pos = 0; |
@@ -463,9 +455,8 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | |||
463 | dev->_dma_phys_addr_ch2); | 455 | dev->_dma_phys_addr_ch2); |
464 | } | 456 | } |
465 | 457 | ||
466 | dev->_dma_virt_addr_ch2 = | 458 | dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, |
467 | pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, | 459 | dev->upstream_riscbuf_size_ch2, &dma_addr); |
468 | &dma_addr); | ||
469 | dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; | 460 | dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; |
470 | dev->_dma_phys_start_addr_ch2 = dma_addr; | 461 | dev->_dma_phys_start_addr_ch2 = dma_addr; |
471 | dev->_dma_phys_addr_ch2 = dma_addr; | 462 | dev->_dma_phys_addr_ch2 = dma_addr; |
@@ -485,9 +476,8 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | |||
485 | dev->_data_buf_phys_addr_ch2); | 476 | dev->_data_buf_phys_addr_ch2); |
486 | } | 477 | } |
487 | /* For Video Data buffer allocation */ | 478 | /* For Video Data buffer allocation */ |
488 | dev->_data_buf_virt_addr_ch2 = | 479 | dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, |
489 | pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2, | 480 | dev->upstream_databuf_size_ch2, &data_dma_addr); |
490 | &data_dma_addr); | ||
491 | dev->_data_buf_phys_addr_ch2 = data_dma_addr; | 481 | dev->_data_buf_phys_addr_ch2 = data_dma_addr; |
492 | dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; | 482 | dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; |
493 | 483 | ||
@@ -563,8 +553,8 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, | |||
563 | else | 553 | else |
564 | line_size_in_bytes = Y422_LINE_SZ; | 554 | line_size_in_bytes = Y422_LINE_SZ; |
565 | risc_phys_jump_addr = | 555 | risc_phys_jump_addr = |
566 | dev->_dma_phys_start_addr_ch2 + | 556 | dev->_dma_phys_start_addr_ch2 + |
567 | odd_risc_prog_size; | 557 | odd_risc_prog_size; |
568 | 558 | ||
569 | rp = cx25821_update_riscprogram_ch2(dev, | 559 | rp = cx25821_update_riscprogram_ch2(dev, |
570 | dev->_dma_virt_start_addr_ch2, | 560 | dev->_dma_virt_start_addr_ch2, |
@@ -612,11 +602,9 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) | |||
612 | vid_status = cx_read(sram_ch->int_stat); | 602 | vid_status = cx_read(sram_ch->int_stat); |
613 | 603 | ||
614 | /* Only deal with our interrupt */ | 604 | /* Only deal with our interrupt */ |
615 | if (vid_status) { | 605 | if (vid_status) |
616 | handled = | 606 | handled = cx25821_video_upstream_irq_ch2(dev, channel_num, |
617 | cx25821_video_upstream_irq_ch2(dev, channel_num, | 607 | vid_status); |
618 | vid_status); | ||
619 | } | ||
620 | 608 | ||
621 | if (handled < 0) | 609 | if (handled < 0) |
622 | cx25821_stop_upstream_video_ch2(dev); | 610 | cx25821_stop_upstream_video_ch2(dev); |
@@ -691,8 +679,7 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, | |||
691 | tmp = cx_read(sram_ch->int_msk); | 679 | tmp = cx_read(sram_ch->int_msk); |
692 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | 680 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); |
693 | 681 | ||
694 | err = | 682 | err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, |
695 | request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, | ||
696 | IRQF_SHARED, dev->name, dev); | 683 | IRQF_SHARED, dev->name, dev); |
697 | if (err < 0) { | 684 | if (err < 0) { |
698 | pr_err("%s: can't get upstream IRQ %d\n", | 685 | pr_err("%s: can't get upstream IRQ %d\n", |
@@ -752,45 +739,38 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | |||
752 | dev->_file_status_ch2 = RESET_STATUS; | 739 | dev->_file_status_ch2 = RESET_STATUS; |
753 | dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; | 740 | dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; |
754 | dev->_pixel_format_ch2 = pixel_format; | 741 | dev->_pixel_format_ch2 = pixel_format; |
755 | dev->_line_size_ch2 = | 742 | dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? |
756 | (dev->_pixel_format_ch2 == | 743 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; |
757 | PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
758 | data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; | 744 | data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; |
759 | risc_buffer_size = | 745 | risc_buffer_size = dev->_isNTSC_ch2 ? |
760 | dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; | 746 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; |
761 | 747 | ||
762 | if (dev->input_filename_ch2) { | 748 | if (dev->input_filename_ch2) { |
763 | str_length = strlen(dev->input_filename_ch2); | 749 | str_length = strlen(dev->input_filename_ch2); |
764 | dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); | 750 | dev->_filename_ch2 = kmemdup(dev->input_filename_ch2, |
751 | str_length + 1, GFP_KERNEL); | ||
765 | 752 | ||
766 | if (!dev->_filename_ch2) | 753 | if (!dev->_filename_ch2) |
767 | goto error; | 754 | goto error; |
768 | |||
769 | memcpy(dev->_filename_ch2, dev->input_filename_ch2, | ||
770 | str_length + 1); | ||
771 | } else { | 755 | } else { |
772 | str_length = strlen(dev->_defaultname_ch2); | 756 | str_length = strlen(dev->_defaultname_ch2); |
773 | dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); | 757 | dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2, |
758 | str_length + 1, GFP_KERNEL); | ||
774 | 759 | ||
775 | if (!dev->_filename_ch2) | 760 | if (!dev->_filename_ch2) |
776 | goto error; | 761 | goto error; |
777 | |||
778 | memcpy(dev->_filename_ch2, dev->_defaultname_ch2, | ||
779 | str_length + 1); | ||
780 | } | 762 | } |
781 | 763 | ||
782 | /* Default if filename is empty string */ | 764 | /* Default if filename is empty string */ |
783 | if (strcmp(dev->input_filename_ch2, "") == 0) { | 765 | if (strcmp(dev->input_filename_ch2, "") == 0) { |
784 | if (dev->_isNTSC_ch2) { | 766 | if (dev->_isNTSC_ch2) { |
785 | dev->_filename_ch2 = | 767 | dev->_filename_ch2 = (dev->_pixel_format_ch2 == |
786 | (dev->_pixel_format_ch2 == | 768 | PIXEL_FRMT_411) ? "/root/vid411.yuv" : |
787 | PIXEL_FRMT_411) ? "/root/vid411.yuv" : | 769 | "/root/vidtest.yuv"; |
788 | "/root/vidtest.yuv"; | ||
789 | } else { | 770 | } else { |
790 | dev->_filename_ch2 = | 771 | dev->_filename_ch2 = (dev->_pixel_format_ch2 == |
791 | (dev->_pixel_format_ch2 == | 772 | PIXEL_FRMT_411) ? "/root/pal411.yuv" : |
792 | PIXEL_FRMT_411) ? "/root/pal411.yuv" : | 773 | "/root/pal422.yuv"; |
793 | "/root/pal422.yuv"; | ||
794 | } | 774 | } |
795 | } | 775 | } |
796 | 776 | ||
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c index c0b80068f468..21e7d657f049 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream.c | |||
@@ -136,7 +136,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, | |||
136 | { | 136 | { |
137 | unsigned int line, i; | 137 | unsigned int line, i; |
138 | struct sram_channel *sram_ch = | 138 | struct sram_channel *sram_ch = |
139 | dev->channels[dev->_channel_upstream_select].sram_channels; | 139 | dev->channels[dev->_channel_upstream_select].sram_channels; |
140 | int dist_betwn_starts = bpl * 2; | 140 | int dist_betwn_starts = bpl * 2; |
141 | 141 | ||
142 | /* sync instruction */ | 142 | /* sync instruction */ |
@@ -194,15 +194,12 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
194 | if (dev->_isNTSC) { | 194 | if (dev->_isNTSC) { |
195 | odd_num_lines = singlefield_lines + 1; | 195 | odd_num_lines = singlefield_lines + 1; |
196 | risc_program_size = FRAME1_VID_PROG_SIZE; | 196 | risc_program_size = FRAME1_VID_PROG_SIZE; |
197 | frame_size = | 197 | frame_size = (bpl == Y411_LINE_SZ) ? |
198 | (bpl == | 198 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; |
199 | Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : | ||
200 | FRAME_SIZE_NTSC_Y422; | ||
201 | } else { | 199 | } else { |
202 | risc_program_size = PAL_VID_PROG_SIZE; | 200 | risc_program_size = PAL_VID_PROG_SIZE; |
203 | frame_size = | 201 | frame_size = (bpl == Y411_LINE_SZ) ? |
204 | (bpl == | 202 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; |
205 | Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
206 | } | 203 | } |
207 | 204 | ||
208 | /* Virtual address of Risc buffer program */ | 205 | /* Virtual address of Risc buffer program */ |
@@ -214,13 +211,9 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
214 | if (UNSET != top_offset) { | 211 | if (UNSET != top_offset) { |
215 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; | 212 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; |
216 | rp = cx25821_risc_field_upstream(dev, rp, | 213 | rp = cx25821_risc_field_upstream(dev, rp, |
217 | dev-> | 214 | dev->_data_buf_phys_addr + |
218 | _data_buf_phys_addr + | 215 | databuf_offset, top_offset, 0, bpl, |
219 | databuf_offset, | 216 | odd_num_lines, fifo_enable, ODD_FIELD); |
220 | top_offset, 0, bpl, | ||
221 | odd_num_lines, | ||
222 | fifo_enable, | ||
223 | ODD_FIELD); | ||
224 | } | 217 | } |
225 | 218 | ||
226 | fifo_enable = FIFO_DISABLE; | 219 | fifo_enable = FIFO_DISABLE; |
@@ -234,8 +227,8 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
234 | 227 | ||
235 | if (frame == 0) { | 228 | if (frame == 0) { |
236 | risc_flag = RISC_CNT_RESET; | 229 | risc_flag = RISC_CNT_RESET; |
237 | risc_phys_jump_addr = | 230 | risc_phys_jump_addr = dev->_dma_phys_start_addr + |
238 | dev->_dma_phys_start_addr + risc_program_size; | 231 | risc_program_size; |
239 | } else { | 232 | } else { |
240 | risc_phys_jump_addr = dev->_dma_phys_start_addr; | 233 | risc_phys_jump_addr = dev->_dma_phys_start_addr; |
241 | risc_flag = RISC_CNT_INC; | 234 | risc_flag = RISC_CNT_INC; |
@@ -255,7 +248,7 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
255 | void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) | 248 | void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) |
256 | { | 249 | { |
257 | struct sram_channel *sram_ch = | 250 | struct sram_channel *sram_ch = |
258 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; | 251 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; |
259 | u32 tmp = 0; | 252 | u32 tmp = 0; |
260 | 253 | ||
261 | if (!dev->_is_running) { | 254 | if (!dev->_is_running) { |
@@ -312,9 +305,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
312 | struct file *myfile; | 305 | struct file *myfile; |
313 | int frame_index_temp = dev->_frame_index; | 306 | int frame_index_temp = dev->_frame_index; |
314 | int i = 0; | 307 | int i = 0; |
315 | int line_size = | 308 | int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? |
316 | (dev->_pixel_format == | 309 | Y411_LINE_SZ : Y422_LINE_SZ; |
317 | PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; | ||
318 | int frame_size = 0; | 310 | int frame_size = 0; |
319 | int frame_offset = 0; | 311 | int frame_offset = 0; |
320 | ssize_t vfs_read_retval = 0; | 312 | ssize_t vfs_read_retval = 0; |
@@ -326,16 +318,12 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
326 | if (dev->_file_status == END_OF_FILE) | 318 | if (dev->_file_status == END_OF_FILE) |
327 | return 0; | 319 | return 0; |
328 | 320 | ||
329 | if (dev->_isNTSC) { | 321 | if (dev->_isNTSC) |
330 | frame_size = | 322 | frame_size = (line_size == Y411_LINE_SZ) ? |
331 | (line_size == | 323 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; |
332 | Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : | 324 | else |
333 | FRAME_SIZE_NTSC_Y422; | 325 | frame_size = (line_size == Y411_LINE_SZ) ? |
334 | } else { | 326 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; |
335 | frame_size = | ||
336 | (line_size == | ||
337 | Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
338 | } | ||
339 | 327 | ||
340 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; | 328 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; |
341 | file_offset = dev->_frame_count * frame_size; | 329 | file_offset = dev->_frame_count * frame_size; |
@@ -369,8 +357,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
369 | for (i = 0; i < dev->_lines_count; i++) { | 357 | for (i = 0; i < dev->_lines_count; i++) { |
370 | pos = file_offset; | 358 | pos = file_offset; |
371 | 359 | ||
372 | vfs_read_retval = | 360 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, |
373 | vfs_read(myfile, mybuf, line_size, &pos); | 361 | &pos); |
374 | 362 | ||
375 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | 363 | if (vfs_read_retval > 0 && vfs_read_retval == line_size |
376 | && dev->_data_buf_virt_addr != NULL) { | 364 | && dev->_data_buf_virt_addr != NULL) { |
@@ -392,8 +380,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
392 | if (i > 0) | 380 | if (i > 0) |
393 | dev->_frame_count++; | 381 | dev->_frame_count++; |
394 | 382 | ||
395 | dev->_file_status = | 383 | dev->_file_status = (vfs_read_retval == line_size) ? |
396 | (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; | 384 | IN_PROGRESS : END_OF_FILE; |
397 | 385 | ||
398 | set_fs(old_fs); | 386 | set_fs(old_fs); |
399 | filp_close(myfile, NULL); | 387 | filp_close(myfile, NULL); |
@@ -404,8 +392,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
404 | 392 | ||
405 | static void cx25821_vidups_handler(struct work_struct *work) | 393 | static void cx25821_vidups_handler(struct work_struct *work) |
406 | { | 394 | { |
407 | struct cx25821_dev *dev = | 395 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, |
408 | container_of(work, struct cx25821_dev, _irq_work_entry); | 396 | _irq_work_entry); |
409 | 397 | ||
410 | if (!dev) { | 398 | if (!dev) { |
411 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | 399 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", |
@@ -413,18 +401,16 @@ static void cx25821_vidups_handler(struct work_struct *work) | |||
413 | return; | 401 | return; |
414 | } | 402 | } |
415 | 403 | ||
416 | cx25821_get_frame(dev, | 404 | cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select]. |
417 | dev->channels[dev->_channel_upstream_select]. | 405 | sram_channels); |
418 | sram_channels); | ||
419 | } | 406 | } |
420 | 407 | ||
421 | int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) | 408 | int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) |
422 | { | 409 | { |
423 | struct file *myfile; | 410 | struct file *myfile; |
424 | int i = 0, j = 0; | 411 | int i = 0, j = 0; |
425 | int line_size = | 412 | int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? |
426 | (dev->_pixel_format == | 413 | Y411_LINE_SZ : Y422_LINE_SZ; |
427 | PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; | ||
428 | ssize_t vfs_read_retval = 0; | 414 | ssize_t vfs_read_retval = 0; |
429 | char mybuf[line_size]; | 415 | char mybuf[line_size]; |
430 | loff_t pos; | 416 | loff_t pos; |
@@ -461,8 +447,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
461 | for (i = 0; i < dev->_lines_count; i++) { | 447 | for (i = 0; i < dev->_lines_count; i++) { |
462 | pos = offset; | 448 | pos = offset; |
463 | 449 | ||
464 | vfs_read_retval = | 450 | vfs_read_retval = vfs_read(myfile, mybuf, |
465 | vfs_read(myfile, mybuf, line_size, &pos); | 451 | line_size, &pos); |
466 | 452 | ||
467 | if (vfs_read_retval > 0 | 453 | if (vfs_read_retval > 0 |
468 | && vfs_read_retval == line_size | 454 | && vfs_read_retval == line_size |
@@ -489,8 +475,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
489 | break; | 475 | break; |
490 | } | 476 | } |
491 | 477 | ||
492 | dev->_file_status = | 478 | dev->_file_status = (vfs_read_retval == line_size) ? |
493 | (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; | 479 | IN_PROGRESS : END_OF_FILE; |
494 | 480 | ||
495 | set_fs(old_fs); | 481 | set_fs(old_fs); |
496 | myfile->f_pos = 0; | 482 | myfile->f_pos = 0; |
@@ -507,14 +493,12 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, | |||
507 | dma_addr_t dma_addr; | 493 | dma_addr_t dma_addr; |
508 | dma_addr_t data_dma_addr; | 494 | dma_addr_t data_dma_addr; |
509 | 495 | ||
510 | if (dev->_dma_virt_addr != NULL) { | 496 | if (dev->_dma_virt_addr != NULL) |
511 | pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, | 497 | pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, |
512 | dev->_dma_virt_addr, dev->_dma_phys_addr); | 498 | dev->_dma_virt_addr, dev->_dma_phys_addr); |
513 | } | ||
514 | 499 | ||
515 | dev->_dma_virt_addr = | 500 | dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, |
516 | pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size, | 501 | dev->upstream_riscbuf_size, &dma_addr); |
517 | &dma_addr); | ||
518 | dev->_dma_virt_start_addr = dev->_dma_virt_addr; | 502 | dev->_dma_virt_start_addr = dev->_dma_virt_addr; |
519 | dev->_dma_phys_start_addr = dma_addr; | 503 | dev->_dma_phys_start_addr = dma_addr; |
520 | dev->_dma_phys_addr = dma_addr; | 504 | dev->_dma_phys_addr = dma_addr; |
@@ -528,15 +512,13 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, | |||
528 | /* Clear memory at address */ | 512 | /* Clear memory at address */ |
529 | memset(dev->_dma_virt_addr, 0, dev->_risc_size); | 513 | memset(dev->_dma_virt_addr, 0, dev->_risc_size); |
530 | 514 | ||
531 | if (dev->_data_buf_virt_addr != NULL) { | 515 | if (dev->_data_buf_virt_addr != NULL) |
532 | pci_free_consistent(dev->pci, dev->upstream_databuf_size, | 516 | pci_free_consistent(dev->pci, dev->upstream_databuf_size, |
533 | dev->_data_buf_virt_addr, | 517 | dev->_data_buf_virt_addr, |
534 | dev->_data_buf_phys_addr); | 518 | dev->_data_buf_phys_addr); |
535 | } | ||
536 | /* For Video Data buffer allocation */ | 519 | /* For Video Data buffer allocation */ |
537 | dev->_data_buf_virt_addr = | 520 | dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, |
538 | pci_alloc_consistent(dev->pci, dev->upstream_databuf_size, | 521 | dev->upstream_databuf_size, &data_dma_addr); |
539 | &data_dma_addr); | ||
540 | dev->_data_buf_phys_addr = data_dma_addr; | 522 | dev->_data_buf_phys_addr = data_dma_addr; |
541 | dev->_data_buf_size = dev->upstream_databuf_size; | 523 | dev->_data_buf_size = dev->upstream_databuf_size; |
542 | 524 | ||
@@ -553,9 +535,8 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, | |||
553 | return ret; | 535 | return ret; |
554 | 536 | ||
555 | /* Create RISC programs */ | 537 | /* Create RISC programs */ |
556 | ret = | 538 | ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, |
557 | cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, | 539 | dev->_lines_count); |
558 | dev->_lines_count); | ||
559 | if (ret < 0) { | 540 | if (ret < 0) { |
560 | pr_info("Failed creating Video Upstream Risc programs!\n"); | 541 | pr_info("Failed creating Video Upstream Risc programs!\n"); |
561 | goto error; | 542 | goto error; |
@@ -672,10 +653,9 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) | |||
672 | vid_status = cx_read(sram_ch->int_stat); | 653 | vid_status = cx_read(sram_ch->int_stat); |
673 | 654 | ||
674 | /* Only deal with our interrupt */ | 655 | /* Only deal with our interrupt */ |
675 | if (vid_status) { | 656 | if (vid_status) |
676 | handled = | 657 | handled = cx25821_video_upstream_irq(dev, channel_num, |
677 | cx25821_video_upstream_irq(dev, channel_num, vid_status); | 658 | vid_status); |
678 | } | ||
679 | 659 | ||
680 | if (handled < 0) | 660 | if (handled < 0) |
681 | cx25821_stop_upstream_video_ch1(dev); | 661 | cx25821_stop_upstream_video_ch1(dev); |
@@ -747,8 +727,7 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, | |||
747 | tmp = cx_read(sram_ch->int_msk); | 727 | tmp = cx_read(sram_ch->int_msk); |
748 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | 728 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); |
749 | 729 | ||
750 | err = | 730 | err = request_irq(dev->pci->irq, cx25821_upstream_irq, |
751 | request_irq(dev->pci->irq, cx25821_upstream_irq, | ||
752 | IRQF_SHARED, dev->name, dev); | 731 | IRQF_SHARED, dev->name, dev); |
753 | if (err < 0) { | 732 | if (err < 0) { |
754 | pr_err("%s: can't get upstream IRQ %d\n", | 733 | pr_err("%s: can't get upstream IRQ %d\n", |
@@ -807,43 +786,38 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | |||
807 | dev->_file_status = RESET_STATUS; | 786 | dev->_file_status = RESET_STATUS; |
808 | dev->_lines_count = dev->_isNTSC ? 480 : 576; | 787 | dev->_lines_count = dev->_isNTSC ? 480 : 576; |
809 | dev->_pixel_format = pixel_format; | 788 | dev->_pixel_format = pixel_format; |
810 | dev->_line_size = | 789 | dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? |
811 | (dev->_pixel_format == | 790 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; |
812 | PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
813 | data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; | 791 | data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; |
814 | risc_buffer_size = | 792 | risc_buffer_size = dev->_isNTSC ? |
815 | dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; | 793 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; |
816 | 794 | ||
817 | if (dev->input_filename) { | 795 | if (dev->input_filename) { |
818 | str_length = strlen(dev->input_filename); | 796 | str_length = strlen(dev->input_filename); |
819 | dev->_filename = kmalloc(str_length + 1, GFP_KERNEL); | 797 | dev->_filename = kmemdup(dev->input_filename, str_length + 1, |
798 | GFP_KERNEL); | ||
820 | 799 | ||
821 | if (!dev->_filename) | 800 | if (!dev->_filename) |
822 | goto error; | 801 | goto error; |
823 | |||
824 | memcpy(dev->_filename, dev->input_filename, str_length + 1); | ||
825 | } else { | 802 | } else { |
826 | str_length = strlen(dev->_defaultname); | 803 | str_length = strlen(dev->_defaultname); |
827 | dev->_filename = kmalloc(str_length + 1, GFP_KERNEL); | 804 | dev->_filename = kmemdup(dev->_defaultname, str_length + 1, |
805 | GFP_KERNEL); | ||
828 | 806 | ||
829 | if (!dev->_filename) | 807 | if (!dev->_filename) |
830 | goto error; | 808 | goto error; |
831 | |||
832 | memcpy(dev->_filename, dev->_defaultname, str_length + 1); | ||
833 | } | 809 | } |
834 | 810 | ||
835 | /* Default if filename is empty string */ | 811 | /* Default if filename is empty string */ |
836 | if (strcmp(dev->input_filename, "") == 0) { | 812 | if (strcmp(dev->input_filename, "") == 0) { |
837 | if (dev->_isNTSC) { | 813 | if (dev->_isNTSC) { |
838 | dev->_filename = | 814 | dev->_filename = |
839 | (dev->_pixel_format == | 815 | (dev->_pixel_format == PIXEL_FRMT_411) ? |
840 | PIXEL_FRMT_411) ? "/root/vid411.yuv" : | 816 | "/root/vid411.yuv" : "/root/vidtest.yuv"; |
841 | "/root/vidtest.yuv"; | ||
842 | } else { | 817 | } else { |
843 | dev->_filename = | 818 | dev->_filename = |
844 | (dev->_pixel_format == | 819 | (dev->_pixel_format == PIXEL_FRMT_411) ? |
845 | PIXEL_FRMT_411) ? "/root/pal411.yuv" : | 820 | "/root/pal411.yuv" : "/root/pal422.yuv"; |
846 | "/root/pal422.yuv"; | ||
847 | } | 821 | } |
848 | } | 822 | } |
849 | 823 | ||
@@ -852,13 +826,11 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | |||
852 | dev->_file_status = RESET_STATUS; | 826 | dev->_file_status = RESET_STATUS; |
853 | dev->_lines_count = dev->_isNTSC ? 480 : 576; | 827 | dev->_lines_count = dev->_isNTSC ? 480 : 576; |
854 | dev->_pixel_format = pixel_format; | 828 | dev->_pixel_format = pixel_format; |
855 | dev->_line_size = | 829 | dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? |
856 | (dev->_pixel_format == | 830 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; |
857 | PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
858 | 831 | ||
859 | retval = | 832 | retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, |
860 | cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size, | 833 | dev->_line_size, 0); |
861 | 0); | ||
862 | 834 | ||
863 | /* setup fifo + format */ | 835 | /* setup fifo + format */ |
864 | cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); | 836 | cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); |
diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index 4d6907cda75b..ffd8bc79c02e 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c | |||
@@ -118,12 +118,12 @@ void cx25821_dump_video_queue(struct cx25821_dev *dev, | |||
118 | 118 | ||
119 | if (!list_empty(&q->active)) { | 119 | if (!list_empty(&q->active)) { |
120 | list_for_each(item, &q->active) | 120 | list_for_each(item, &q->active) |
121 | buf = list_entry(item, struct cx25821_buffer, vb.queue); | 121 | buf = list_entry(item, struct cx25821_buffer, vb.queue); |
122 | } | 122 | } |
123 | 123 | ||
124 | if (!list_empty(&q->queued)) { | 124 | if (!list_empty(&q->queued)) { |
125 | list_for_each(item, &q->queued) | 125 | list_for_each(item, &q->queued) |
126 | buf = list_entry(item, struct cx25821_buffer, vb.queue); | 126 | buf = list_entry(item, struct cx25821_buffer, vb.queue); |
127 | } | 127 | } |
128 | 128 | ||
129 | } | 129 | } |
@@ -140,8 +140,8 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, | |||
140 | break; | 140 | break; |
141 | } | 141 | } |
142 | 142 | ||
143 | buf = | 143 | buf = list_entry(q->active.next, struct cx25821_buffer, |
144 | list_entry(q->active.next, struct cx25821_buffer, vb.queue); | 144 | vb.queue); |
145 | 145 | ||
146 | /* count comes from the hw and it is 16bit wide -- | 146 | /* count comes from the hw and it is 16bit wide -- |
147 | * this trick handles wrap-arounds correctly for | 147 | * this trick handles wrap-arounds correctly for |
@@ -318,8 +318,8 @@ int cx25821_restart_video_queue(struct cx25821_dev *dev, | |||
318 | struct list_head *item; | 318 | struct list_head *item; |
319 | 319 | ||
320 | if (!list_empty(&q->active)) { | 320 | if (!list_empty(&q->active)) { |
321 | buf = | 321 | buf = list_entry(q->active.next, struct cx25821_buffer, |
322 | list_entry(q->active.next, struct cx25821_buffer, vb.queue); | 322 | vb.queue); |
323 | 323 | ||
324 | cx25821_start_video_dma(dev, q, buf, channel); | 324 | cx25821_start_video_dma(dev, q, buf, channel); |
325 | 325 | ||
@@ -337,8 +337,8 @@ int cx25821_restart_video_queue(struct cx25821_dev *dev, | |||
337 | if (list_empty(&q->queued)) | 337 | if (list_empty(&q->queued)) |
338 | return 0; | 338 | return 0; |
339 | 339 | ||
340 | buf = | 340 | buf = list_entry(q->queued.next, struct cx25821_buffer, |
341 | list_entry(q->queued.next, struct cx25821_buffer, vb.queue); | 341 | vb.queue); |
342 | 342 | ||
343 | if (NULL == prev) { | 343 | if (NULL == prev) { |
344 | list_move_tail(&buf->vb.queue, &q->active); | 344 | list_move_tail(&buf->vb.queue, &q->active); |
@@ -375,8 +375,8 @@ void cx25821_vid_timeout(unsigned long data) | |||
375 | 375 | ||
376 | spin_lock_irqsave(&dev->slock, flags); | 376 | spin_lock_irqsave(&dev->slock, flags); |
377 | while (!list_empty(&q->active)) { | 377 | while (!list_empty(&q->active)) { |
378 | buf = | 378 | buf = list_entry(q->active.next, struct cx25821_buffer, |
379 | list_entry(q->active.next, struct cx25821_buffer, vb.queue); | 379 | vb.queue); |
380 | list_del(&buf->vb.queue); | 380 | list_del(&buf->vb.queue); |
381 | 381 | ||
382 | buf->vb.state = VIDEOBUF_ERROR; | 382 | buf->vb.state = VIDEOBUF_ERROR; |
@@ -484,8 +484,7 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
484 | cx25821_init_controls(dev, i); | 484 | cx25821_init_controls(dev, i); |
485 | 485 | ||
486 | cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, | 486 | cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, |
487 | dev->channels[i].sram_channels->dma_ctl, | 487 | dev->channels[i].sram_channels->dma_ctl, 0x11, 0); |
488 | 0x11, 0); | ||
489 | 488 | ||
490 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; | 489 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; |
491 | dev->channels[i].video_dev = NULL; | 490 | dev->channels[i].video_dev = NULL; |
@@ -499,15 +498,14 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
499 | dev->channels[i].timeout_data.dev = dev; | 498 | dev->channels[i].timeout_data.dev = dev; |
500 | dev->channels[i].timeout_data.channel = | 499 | dev->channels[i].timeout_data.channel = |
501 | &cx25821_sram_channels[i]; | 500 | &cx25821_sram_channels[i]; |
502 | dev->channels[i].vidq.timeout.function = | 501 | dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; |
503 | cx25821_vid_timeout; | ||
504 | dev->channels[i].vidq.timeout.data = | 502 | dev->channels[i].vidq.timeout.data = |
505 | (unsigned long)&dev->channels[i].timeout_data; | 503 | (unsigned long)&dev->channels[i].timeout_data; |
506 | init_timer(&dev->channels[i].vidq.timeout); | 504 | init_timer(&dev->channels[i].vidq.timeout); |
507 | 505 | ||
508 | /* register v4l devices */ | 506 | /* register v4l devices */ |
509 | dev->channels[i].video_dev = cx25821_vdev_init(dev, | 507 | dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, |
510 | dev->pci, &cx25821_video_device, "video"); | 508 | &cx25821_video_device, "video"); |
511 | 509 | ||
512 | err = video_register_device(dev->channels[i].video_dev, | 510 | err = video_register_device(dev->channels[i].video_dev, |
513 | VFL_TYPE_GRABBER, video_nr[dev->nr]); | 511 | VFL_TYPE_GRABBER, video_nr[dev->nr]); |
@@ -528,7 +526,6 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
528 | #endif | 526 | #endif |
529 | mutex_unlock(&dev->lock); | 527 | mutex_unlock(&dev->lock); |
530 | 528 | ||
531 | |||
532 | return 0; | 529 | return 0; |
533 | 530 | ||
534 | fail_unreg: | 531 | fail_unreg: |
@@ -558,7 +555,7 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
558 | struct cx25821_fh *fh = q->priv_data; | 555 | struct cx25821_fh *fh = q->priv_data; |
559 | struct cx25821_dev *dev = fh->dev; | 556 | struct cx25821_dev *dev = fh->dev; |
560 | struct cx25821_buffer *buf = | 557 | struct cx25821_buffer *buf = |
561 | container_of(vb, struct cx25821_buffer, vb); | 558 | container_of(vb, struct cx25821_buffer, vb); |
562 | int rc, init_buffer = 0; | 559 | int rc, init_buffer = 0; |
563 | u32 line0_offset, line1_offset; | 560 | u32 line0_offset, line1_offset; |
564 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 561 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
@@ -617,14 +614,13 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
617 | if (channel_opened >= 0 && channel_opened <= 7) { | 614 | if (channel_opened >= 0 && channel_opened <= 7) { |
618 | if (dev->channels[channel_opened] | 615 | if (dev->channels[channel_opened] |
619 | .use_cif_resolution) { | 616 | .use_cif_resolution) { |
620 | if (dev->tvnorm & V4L2_STD_PAL_BG | 617 | if (dev->tvnorm & V4L2_STD_PAL_BG || |
621 | || dev->tvnorm & V4L2_STD_PAL_DK) | 618 | dev->tvnorm & V4L2_STD_PAL_DK) |
622 | bpl_local = 352 << 1; | 619 | bpl_local = 352 << 1; |
623 | else | 620 | else |
624 | bpl_local = | 621 | bpl_local = dev->channels[ |
625 | dev->channels[channel_opened]. | 622 | channel_opened]. |
626 | cif_width << | 623 | cif_width << 1; |
627 | 1; | ||
628 | } | 624 | } |
629 | } | 625 | } |
630 | } | 626 | } |
@@ -685,7 +681,7 @@ void cx25821_buffer_release(struct videobuf_queue *q, | |||
685 | struct videobuf_buffer *vb) | 681 | struct videobuf_buffer *vb) |
686 | { | 682 | { |
687 | struct cx25821_buffer *buf = | 683 | struct cx25821_buffer *buf = |
688 | container_of(vb, struct cx25821_buffer, vb); | 684 | container_of(vb, struct cx25821_buffer, vb); |
689 | 685 | ||
690 | cx25821_free_buffer(q, buf); | 686 | cx25821_free_buffer(q, buf); |
691 | } | 687 | } |
@@ -723,7 +719,7 @@ int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) | |||
723 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 719 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) |
724 | { | 720 | { |
725 | struct cx25821_buffer *buf = | 721 | struct cx25821_buffer *buf = |
726 | container_of(vb, struct cx25821_buffer, vb); | 722 | container_of(vb, struct cx25821_buffer, vb); |
727 | struct cx25821_buffer *prev; | 723 | struct cx25821_buffer *prev; |
728 | struct cx25821_fh *fh = vq->priv_data; | 724 | struct cx25821_fh *fh = vq->priv_data; |
729 | struct cx25821_dev *dev = fh->dev; | 725 | struct cx25821_dev *dev = fh->dev; |
@@ -814,7 +810,7 @@ static int video_open(struct file *file) | |||
814 | 810 | ||
815 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { | 811 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { |
816 | if (h->channels[i].video_dev && | 812 | if (h->channels[i].video_dev && |
817 | h->channels[i].video_dev->minor == minor) { | 813 | h->channels[i].video_dev->minor == minor) { |
818 | dev = h; | 814 | dev = h; |
819 | ch_id = i; | 815 | ch_id = i; |
820 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 816 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
@@ -848,11 +844,10 @@ static int video_open(struct file *file) | |||
848 | 844 | ||
849 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); | 845 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); |
850 | 846 | ||
851 | videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, | 847 | videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, |
852 | &dev->pci->dev, &dev->slock, | 848 | &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
853 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 849 | V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), |
854 | V4L2_FIELD_INTERLACED, | 850 | fh, NULL); |
855 | sizeof(struct cx25821_buffer), fh, NULL); | ||
856 | 851 | ||
857 | dprintk(1, "post videobuf_queue_init()\n"); | 852 | dprintk(1, "post videobuf_queue_init()\n"); |
858 | mutex_unlock(&cx25821_devlist_mutex); | 853 | mutex_unlock(&cx25821_devlist_mutex); |
@@ -1168,8 +1163,8 @@ int cx25821_vidioc_querycap(struct file *file, void *priv, | |||
1168 | strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); | 1163 | strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); |
1169 | sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); | 1164 | sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); |
1170 | cap->version = CX25821_VERSION_CODE; | 1165 | cap->version = CX25821_VERSION_CODE; |
1171 | cap->capabilities = | 1166 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | |
1172 | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | 1167 | V4L2_CAP_STREAMING; |
1173 | if (UNSET != dev->tuner_type) | 1168 | if (UNSET != dev->tuner_type) |
1174 | cap->capabilities |= V4L2_CAP_TUNER; | 1169 | cap->capabilities |= V4L2_CAP_TUNER; |
1175 | return 0; | 1170 | return 0; |
@@ -1454,38 +1449,38 @@ static const struct v4l2_queryctrl no_ctl = { | |||
1454 | static struct v4l2_queryctrl cx25821_ctls[] = { | 1449 | static struct v4l2_queryctrl cx25821_ctls[] = { |
1455 | /* --- video --- */ | 1450 | /* --- video --- */ |
1456 | { | 1451 | { |
1457 | .id = V4L2_CID_BRIGHTNESS, | 1452 | .id = V4L2_CID_BRIGHTNESS, |
1458 | .name = "Brightness", | 1453 | .name = "Brightness", |
1459 | .minimum = 0, | 1454 | .minimum = 0, |
1460 | .maximum = 10000, | 1455 | .maximum = 10000, |
1461 | .step = 1, | 1456 | .step = 1, |
1462 | .default_value = 6200, | 1457 | .default_value = 6200, |
1463 | .type = V4L2_CTRL_TYPE_INTEGER, | 1458 | .type = V4L2_CTRL_TYPE_INTEGER, |
1464 | }, { | 1459 | }, { |
1465 | .id = V4L2_CID_CONTRAST, | 1460 | .id = V4L2_CID_CONTRAST, |
1466 | .name = "Contrast", | 1461 | .name = "Contrast", |
1467 | .minimum = 0, | 1462 | .minimum = 0, |
1468 | .maximum = 10000, | 1463 | .maximum = 10000, |
1469 | .step = 1, | 1464 | .step = 1, |
1470 | .default_value = 5000, | 1465 | .default_value = 5000, |
1471 | .type = V4L2_CTRL_TYPE_INTEGER, | 1466 | .type = V4L2_CTRL_TYPE_INTEGER, |
1472 | }, { | 1467 | }, { |
1473 | .id = V4L2_CID_SATURATION, | 1468 | .id = V4L2_CID_SATURATION, |
1474 | .name = "Saturation", | 1469 | .name = "Saturation", |
1475 | .minimum = 0, | 1470 | .minimum = 0, |
1476 | .maximum = 10000, | 1471 | .maximum = 10000, |
1477 | .step = 1, | 1472 | .step = 1, |
1478 | .default_value = 5000, | 1473 | .default_value = 5000, |
1479 | .type = V4L2_CTRL_TYPE_INTEGER, | 1474 | .type = V4L2_CTRL_TYPE_INTEGER, |
1480 | }, { | 1475 | }, { |
1481 | .id = V4L2_CID_HUE, | 1476 | .id = V4L2_CID_HUE, |
1482 | .name = "Hue", | 1477 | .name = "Hue", |
1483 | .minimum = 0, | 1478 | .minimum = 0, |
1484 | .maximum = 10000, | 1479 | .maximum = 10000, |
1485 | .step = 1, | 1480 | .step = 1, |
1486 | .default_value = 5000, | 1481 | .default_value = 5000, |
1487 | .type = V4L2_CTRL_TYPE_INTEGER, | 1482 | .type = V4L2_CTRL_TYPE_INTEGER, |
1488 | } | 1483 | } |
1489 | }; | 1484 | }; |
1490 | static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); | 1485 | static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); |
1491 | 1486 | ||
@@ -1623,7 +1618,8 @@ int cx25821_vidioc_cropcap(struct file *file, void *priv, | |||
1623 | 1618 | ||
1624 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1619 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1625 | return -EINVAL; | 1620 | return -EINVAL; |
1626 | cropcap->bounds.top = cropcap->bounds.left = 0; | 1621 | cropcap->bounds.top = 0; |
1622 | cropcap->bounds.left = 0; | ||
1627 | cropcap->bounds.width = 720; | 1623 | cropcap->bounds.width = 720; |
1628 | cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480; | 1624 | cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480; |
1629 | cropcap->pixelaspect.numerator = | 1625 | cropcap->pixelaspect.numerator = |
@@ -1829,8 +1825,11 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, | |||
1829 | struct downstream_user_struct *data_from_user; | 1825 | struct downstream_user_struct *data_from_user; |
1830 | int command; | 1826 | int command; |
1831 | int width = 720; | 1827 | int width = 720; |
1832 | int selected_channel = 0, pix_format = 0, i = 0; | 1828 | int selected_channel = 0; |
1833 | int cif_enable = 0, cif_width = 0; | 1829 | int pix_format = 0; |
1830 | int i = 0; | ||
1831 | int cif_enable = 0; | ||
1832 | int cif_width = 0; | ||
1834 | u32 value = 0; | 1833 | u32 value = 0; |
1835 | 1834 | ||
1836 | data_from_user = (struct downstream_user_struct *)arg; | 1835 | data_from_user = (struct downstream_user_struct *)arg; |
@@ -1895,8 +1894,8 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, | |||
1895 | } | 1894 | } |
1896 | 1895 | ||
1897 | if (selected_channel <= 7 && selected_channel >= 0) { | 1896 | if (selected_channel <= 7 && selected_channel >= 0) { |
1898 | dev->channels[selected_channel]. | 1897 | dev->channels[selected_channel].use_cif_resolution = |
1899 | use_cif_resolution = cif_enable; | 1898 | cif_enable; |
1900 | dev->channels[selected_channel].cif_width = width; | 1899 | dev->channels[selected_channel].cif_width = width; |
1901 | } else { | 1900 | } else { |
1902 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | 1901 | for (i = 0; i < VID_CHANNEL_NUM; i++) { |
@@ -1932,9 +1931,9 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, | |||
1932 | static long cx25821_video_ioctl(struct file *file, | 1931 | static long cx25821_video_ioctl(struct file *file, |
1933 | unsigned int cmd, unsigned long arg) | 1932 | unsigned int cmd, unsigned long arg) |
1934 | { | 1933 | { |
1935 | int ret = 0; | 1934 | int ret = 0; |
1936 | 1935 | ||
1937 | struct cx25821_fh *fh = file->private_data; | 1936 | struct cx25821_fh *fh = file->private_data; |
1938 | 1937 | ||
1939 | /* check to see if it's the video upstream */ | 1938 | /* check to see if it's the video upstream */ |
1940 | if (fh->channel_id == SRAM_CH09) { | 1939 | if (fh->channel_id == SRAM_CH09) { |
diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h index 2d2d00932823..b9aa801b00a7 100644 --- a/drivers/media/video/cx25821/cx25821.h +++ b/drivers/media/video/cx25821/cx25821.h | |||
@@ -67,7 +67,7 @@ | |||
67 | #define MAX_CAMERAS 16 | 67 | #define MAX_CAMERAS 16 |
68 | 68 | ||
69 | /* Max number of inputs by card */ | 69 | /* Max number of inputs by card */ |
70 | #define MAX_CX25821_INPUT 8 | 70 | #define MAX_CX25821_INPUT 8 |
71 | #define INPUT(nr) (&cx25821_boards[dev->board].input[nr]) | 71 | #define INPUT(nr) (&cx25821_boards[dev->board].input[nr]) |
72 | #define RESOURCE_VIDEO0 1 | 72 | #define RESOURCE_VIDEO0 1 |
73 | #define RESOURCE_VIDEO1 2 | 73 | #define RESOURCE_VIDEO1 2 |
@@ -85,7 +85,7 @@ | |||
85 | 85 | ||
86 | #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ | 86 | #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ |
87 | 87 | ||
88 | #define UNKNOWN_BOARD 0 | 88 | #define UNKNOWN_BOARD 0 |
89 | #define CX25821_BOARD 1 | 89 | #define CX25821_BOARD 1 |
90 | 90 | ||
91 | /* Currently supported by the driver */ | 91 | /* Currently supported by the driver */ |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 5c42abdf422f..3598dc087b08 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -70,11 +70,6 @@ config VIDEO_CX88_DVB | |||
70 | To compile this driver as a module, choose M here: the | 70 | To compile this driver as a module, choose M here: the |
71 | module will be called cx88-dvb. | 71 | module will be called cx88-dvb. |
72 | 72 | ||
73 | config VIDEO_CX88_MPEG | ||
74 | tristate | ||
75 | depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD | ||
76 | default y | ||
77 | |||
78 | config VIDEO_CX88_VP3054 | 73 | config VIDEO_CX88_VP3054 |
79 | tristate "VP-3054 Secondary I2C Bus Support" | 74 | tristate "VP-3054 Secondary I2C Bus Support" |
80 | default m | 75 | default m |
@@ -84,3 +79,8 @@ config VIDEO_CX88_VP3054 | |||
84 | Conexant 2388x chip and the MT352 demodulator, | 79 | Conexant 2388x chip and the MT352 demodulator, |
85 | which also require support for the VP-3054 | 80 | which also require support for the VP-3054 |
86 | Secondary I2C bus, such at DNTV Live! DVB-T Pro. | 81 | Secondary I2C bus, such at DNTV Live! DVB-T Pro. |
82 | |||
83 | config VIDEO_CX88_MPEG | ||
84 | tristate | ||
85 | depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD | ||
86 | default y | ||
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index a1fe0abb6e43..de0f1af74e41 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -132,7 +132,7 @@ static void do_i2c_scan(const char *name, struct i2c_client *c) | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | /* init + register i2c algo-bit adapter */ | 135 | /* init + register i2c adapter */ |
136 | int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | 136 | int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) |
137 | { | 137 | { |
138 | /* Prevents usage of invalid delay values */ | 138 | /* Prevents usage of invalid delay values */ |
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c index 8588a86d9b45..d98da4bfb256 100644 --- a/drivers/media/video/davinci/vpbe_display.c +++ b/drivers/media/video/davinci/vpbe_display.c | |||
@@ -1746,15 +1746,16 @@ static __devinit int vpbe_display_probe(struct platform_device *pdev) | |||
1746 | for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { | 1746 | for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { |
1747 | if (register_device(disp_dev->dev[i], disp_dev, pdev)) { | 1747 | if (register_device(disp_dev->dev[i], disp_dev, pdev)) { |
1748 | err = -ENODEV; | 1748 | err = -ENODEV; |
1749 | goto probe_out; | 1749 | goto probe_out_irq; |
1750 | } | 1750 | } |
1751 | } | 1751 | } |
1752 | 1752 | ||
1753 | printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n"); | 1753 | printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n"); |
1754 | return 0; | 1754 | return 0; |
1755 | 1755 | ||
1756 | probe_out: | 1756 | probe_out_irq: |
1757 | free_irq(res->start, disp_dev); | 1757 | free_irq(res->start, disp_dev); |
1758 | probe_out: | ||
1758 | for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { | 1759 | for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { |
1759 | /* Get the pointer to the layer object */ | 1760 | /* Get the pointer to the layer object */ |
1760 | vpbe_display_layer = disp_dev->dev[k]; | 1761 | vpbe_display_layer = disp_dev->dev[k]; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 9b747c266afa..1704da05540d 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -336,6 +336,23 @@ static struct em28xx_reg_seq pctv_460e[] = { | |||
336 | { -1, -1, -1, -1}, | 336 | { -1, -1, -1, -1}, |
337 | }; | 337 | }; |
338 | 338 | ||
339 | #if 0 | ||
340 | static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | ||
341 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
342 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */ | ||
343 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
344 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, | ||
345 | { -1, -1, -1, -1}, | ||
346 | }; | ||
347 | |||
348 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { | ||
349 | {EM2874_R80_GPIO, 0xf6, 0xff, 10}, | ||
350 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
351 | {EM2874_R80_GPIO, 0xa6, 0xff, 10}, | ||
352 | { -1, -1, -1, -1}, | ||
353 | }; | ||
354 | #endif | ||
355 | |||
339 | /* | 356 | /* |
340 | * Board definitions | 357 | * Board definitions |
341 | */ | 358 | */ |
@@ -887,6 +904,37 @@ struct em28xx_board em28xx_boards[] = { | |||
887 | .tuner_addr = 0x41, | 904 | .tuner_addr = 0x41, |
888 | .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ | 905 | .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ |
889 | .tuner_gpio = terratec_h5_gpio, | 906 | .tuner_gpio = terratec_h5_gpio, |
907 | #else | ||
908 | .tuner_type = TUNER_ABSENT, | ||
909 | #endif | ||
910 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
911 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
912 | EM28XX_I2C_FREQ_400_KHZ, | ||
913 | }, | ||
914 | [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { | ||
915 | .name = "Hauppauge WinTV HVR 930C", | ||
916 | .has_dvb = 1, | ||
917 | #if 0 /* FIXME: Add analog support */ | ||
918 | .tuner_type = TUNER_XC5000, | ||
919 | .tuner_addr = 0x41, | ||
920 | .dvb_gpio = hauppauge_930c_digital, | ||
921 | .tuner_gpio = hauppauge_930c_gpio, | ||
922 | #else | ||
923 | .tuner_type = TUNER_ABSENT, | ||
924 | #endif | ||
925 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
926 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
927 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
928 | EM28XX_I2C_FREQ_400_KHZ, | ||
929 | }, | ||
930 | [EM2884_BOARD_CINERGY_HTC_STICK] = { | ||
931 | .name = "Terratec Cinergy HTC Stick", | ||
932 | .has_dvb = 1, | ||
933 | #if 0 | ||
934 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
935 | .tuner_addr = 0x41, | ||
936 | .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ | ||
937 | .tuner_gpio = terratec_h5_gpio, | ||
890 | #endif | 938 | #endif |
891 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | 939 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | |
892 | EM28XX_I2C_CLK_WAIT_ENABLE | | 940 | EM28XX_I2C_CLK_WAIT_ENABLE | |
@@ -1914,17 +1962,19 @@ struct usb_device_id em28xx_id_table[] = { | |||
1914 | { USB_DEVICE(0x0ccd, 0x0042), | 1962 | { USB_DEVICE(0x0ccd, 0x0042), |
1915 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, | 1963 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, |
1916 | { USB_DEVICE(0x0ccd, 0x0043), | 1964 | { USB_DEVICE(0x0ccd, 0x0043), |
1965 | .driver_info = EM2870_BOARD_TERRATEC_XS }, | ||
1966 | { USB_DEVICE(0x0ccd, 0x10a2), /* H5 Rev. 1 */ | ||
1917 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | 1967 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, |
1918 | { USB_DEVICE(0x0ccd, 0x10a2), /* Rev. 1 */ | 1968 | { USB_DEVICE(0x0ccd, 0x10ad), /* H5 Rev. 2 */ |
1919 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | 1969 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, |
1920 | { USB_DEVICE(0x0ccd, 0x10ad), /* Rev. 2 */ | ||
1921 | .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, | ||
1922 | { USB_DEVICE(0x0ccd, 0x0084), | 1970 | { USB_DEVICE(0x0ccd, 0x0084), |
1923 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, | 1971 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, |
1924 | { USB_DEVICE(0x0ccd, 0x0096), | 1972 | { USB_DEVICE(0x0ccd, 0x0096), |
1925 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | 1973 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, |
1926 | { USB_DEVICE(0x0ccd, 0x10AF), | 1974 | { USB_DEVICE(0x0ccd, 0x10AF), |
1927 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | 1975 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, |
1976 | { USB_DEVICE(0x0ccd, 0x00b2), | ||
1977 | .driver_info = EM2884_BOARD_CINERGY_HTC_STICK }, | ||
1928 | { USB_DEVICE(0x0fd9, 0x0033), | 1978 | { USB_DEVICE(0x0fd9, 0x0033), |
1929 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, | 1979 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, |
1930 | { USB_DEVICE(0x185b, 0x2870), | 1980 | { USB_DEVICE(0x185b, 0x2870), |
@@ -1975,6 +2025,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
1975 | .driver_info = EM28174_BOARD_PCTV_290E }, | 2025 | .driver_info = EM28174_BOARD_PCTV_290E }, |
1976 | { USB_DEVICE(0x2013, 0x024c), | 2026 | { USB_DEVICE(0x2013, 0x024c), |
1977 | .driver_info = EM28174_BOARD_PCTV_460E }, | 2027 | .driver_info = EM28174_BOARD_PCTV_460E }, |
2028 | { USB_DEVICE(0x2040, 0x1605), | ||
2029 | .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, | ||
1978 | { }, | 2030 | { }, |
1979 | }; | 2031 | }; |
1980 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 2032 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); |
@@ -2028,10 +2080,10 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) | |||
2028 | int rc = 0; | 2080 | int rc = 0; |
2029 | struct em28xx *dev = ptr; | 2081 | struct em28xx *dev = ptr; |
2030 | 2082 | ||
2031 | if (dev->tuner_type != TUNER_XC2028) | 2083 | if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) |
2032 | return 0; | 2084 | return 0; |
2033 | 2085 | ||
2034 | if (command != XC2028_TUNER_RESET) | 2086 | if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) |
2035 | return 0; | 2087 | return 0; |
2036 | 2088 | ||
2037 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); | 2089 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index cef7a2d409cb..3868c1e73592 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -316,6 +316,14 @@ struct drxk_config terratec_h5_drxk = { | |||
316 | .microcode_name = "dvb-usb-terratec-h5-drxk.fw", | 316 | .microcode_name = "dvb-usb-terratec-h5-drxk.fw", |
317 | }; | 317 | }; |
318 | 318 | ||
319 | struct drxk_config hauppauge_930c_drxk = { | ||
320 | .adr = 0x29, | ||
321 | .single_master = 1, | ||
322 | .no_i2c_bridge = 1, | ||
323 | .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", | ||
324 | .chunk_size = 56, | ||
325 | }; | ||
326 | |||
319 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | 327 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) |
320 | { | 328 | { |
321 | struct em28xx_dvb *dvb = fe->sec_priv; | 329 | struct em28xx_dvb *dvb = fe->sec_priv; |
@@ -334,6 +342,73 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
334 | return status; | 342 | return status; |
335 | } | 343 | } |
336 | 344 | ||
345 | static void hauppauge_hvr930c_init(struct em28xx *dev) | ||
346 | { | ||
347 | int i; | ||
348 | |||
349 | struct em28xx_reg_seq hauppauge_hvr930c_init[] = { | ||
350 | {EM2874_R80_GPIO, 0xff, 0xff, 0x65}, | ||
351 | {EM2874_R80_GPIO, 0xfb, 0xff, 0x32}, | ||
352 | {EM2874_R80_GPIO, 0xff, 0xff, 0xb8}, | ||
353 | { -1, -1, -1, -1}, | ||
354 | }; | ||
355 | struct em28xx_reg_seq hauppauge_hvr930c_end[] = { | ||
356 | {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, | ||
357 | {EM2874_R80_GPIO, 0xaf, 0xff, 0x65}, | ||
358 | {EM2874_R80_GPIO, 0xef, 0xff, 0x76}, | ||
359 | {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, | ||
360 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, | ||
361 | {EM2874_R80_GPIO, 0xef, 0xff, 0x40}, | ||
362 | |||
363 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x65}, | ||
364 | {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, | ||
365 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, | ||
366 | {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, | ||
367 | |||
368 | { -1, -1, -1, -1}, | ||
369 | }; | ||
370 | |||
371 | struct { | ||
372 | unsigned char r[4]; | ||
373 | int len; | ||
374 | } regs[] = { | ||
375 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
376 | {{ 0x01, 0x02 }, 2}, | ||
377 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
378 | {{ 0x01, 0x00 }, 2}, | ||
379 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
380 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
381 | {{ 0x01, 0x00 }, 2}, | ||
382 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
383 | {{ 0x04, 0x00 }, 2}, | ||
384 | {{ 0x00, 0x04 }, 2}, | ||
385 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
386 | {{ 0x04, 0x14 }, 2}, | ||
387 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
388 | }; | ||
389 | |||
390 | em28xx_gpio_set(dev, hauppauge_hvr930c_init); | ||
391 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
392 | msleep(10); | ||
393 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
394 | msleep(10); | ||
395 | |||
396 | dev->i2c_client.addr = 0x82 >> 1; | ||
397 | |||
398 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
399 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
400 | em28xx_gpio_set(dev, hauppauge_hvr930c_end); | ||
401 | |||
402 | msleep(100); | ||
403 | |||
404 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
405 | msleep(30); | ||
406 | |||
407 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
408 | msleep(10); | ||
409 | |||
410 | } | ||
411 | |||
337 | static void terratec_h5_init(struct em28xx *dev) | 412 | static void terratec_h5_init(struct em28xx *dev) |
338 | { | 413 | { |
339 | int i; | 414 | int i; |
@@ -425,13 +500,6 @@ static struct tda10023_config em28xx_tda10023_config = { | |||
425 | static struct cxd2820r_config em28xx_cxd2820r_config = { | 500 | static struct cxd2820r_config em28xx_cxd2820r_config = { |
426 | .i2c_address = (0xd8 >> 1), | 501 | .i2c_address = (0xd8 >> 1), |
427 | .ts_mode = CXD2820R_TS_SERIAL, | 502 | .ts_mode = CXD2820R_TS_SERIAL, |
428 | .if_dvbt_6 = 3300, | ||
429 | .if_dvbt_7 = 3500, | ||
430 | .if_dvbt_8 = 4000, | ||
431 | .if_dvbt2_6 = 3300, | ||
432 | .if_dvbt2_7 = 3500, | ||
433 | .if_dvbt2_8 = 4000, | ||
434 | .if_dvbc = 5000, | ||
435 | 503 | ||
436 | /* enable LNA for DVB-T2 and DVB-C */ | 504 | /* enable LNA for DVB-T2 and DVB-C */ |
437 | .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | 505 | .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, |
@@ -788,7 +856,55 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
788 | mfe_shared = 1; | 856 | mfe_shared = 1; |
789 | } | 857 | } |
790 | break; | 858 | break; |
859 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: | ||
860 | { | ||
861 | struct xc5000_config cfg; | ||
862 | hauppauge_hvr930c_init(dev); | ||
863 | |||
864 | dvb->dont_attach_fe1 = 1; | ||
865 | |||
866 | dvb->fe[0] = dvb_attach(drxk_attach, | ||
867 | &hauppauge_930c_drxk, &dev->i2c_adap, | ||
868 | &dvb->fe[1]); | ||
869 | if (!dvb->fe[0]) { | ||
870 | result = -EINVAL; | ||
871 | goto out_free; | ||
872 | } | ||
873 | /* FIXME: do we need a pll semaphore? */ | ||
874 | dvb->fe[0]->sec_priv = dvb; | ||
875 | sema_init(&dvb->pll_mutex, 1); | ||
876 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
877 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
878 | dvb->fe[1]->id = 1; | ||
879 | |||
880 | /* Attach xc5000 */ | ||
881 | memset(&cfg, 0, sizeof(cfg)); | ||
882 | cfg.i2c_address = 0x61; | ||
883 | cfg.if_khz = 4000; | ||
884 | |||
885 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
886 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
887 | if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, | ||
888 | &cfg)) { | ||
889 | result = -EINVAL; | ||
890 | goto out_free; | ||
891 | } | ||
892 | |||
893 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
894 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
895 | |||
896 | /* Hack - needed by drxk/tda18271c2dd */ | ||
897 | dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv; | ||
898 | memcpy(&dvb->fe[1]->ops.tuner_ops, | ||
899 | &dvb->fe[0]->ops.tuner_ops, | ||
900 | sizeof(dvb->fe[0]->ops.tuner_ops)); | ||
901 | |||
902 | mfe_shared = 1; | ||
903 | |||
904 | break; | ||
905 | } | ||
791 | case EM2884_BOARD_TERRATEC_H5: | 906 | case EM2884_BOARD_TERRATEC_H5: |
907 | case EM2884_BOARD_CINERGY_HTC_STICK: | ||
792 | terratec_h5_init(dev); | 908 | terratec_h5_init(dev); |
793 | 909 | ||
794 | dvb->dont_attach_fe1 = 1; | 910 | dvb->dont_attach_fe1 = 1; |
@@ -798,7 +914,6 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
798 | result = -EINVAL; | 914 | result = -EINVAL; |
799 | goto out_free; | 915 | goto out_free; |
800 | } | 916 | } |
801 | |||
802 | /* FIXME: do we need a pll semaphore? */ | 917 | /* FIXME: do we need a pll semaphore? */ |
803 | dvb->fe[0]->sec_priv = dvb; | 918 | dvb->fe[0]->sec_priv = dvb; |
804 | sema_init(&dvb->pll_mutex, 1); | 919 | sema_init(&dvb->pll_mutex, 1); |
@@ -822,6 +937,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
822 | &dvb->fe[0]->ops.tuner_ops, | 937 | &dvb->fe[0]->ops.tuner_ops, |
823 | sizeof(dvb->fe[0]->ops.tuner_ops)); | 938 | sizeof(dvb->fe[0]->ops.tuner_ops)); |
824 | 939 | ||
940 | mfe_shared = 1; | ||
941 | |||
825 | break; | 942 | break; |
826 | case EM28174_BOARD_PCTV_460E: | 943 | case EM28174_BOARD_PCTV_460E: |
827 | /* attach demod */ | 944 | /* attach demod */ |
@@ -845,6 +962,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
845 | } | 962 | } |
846 | /* define general-purpose callback pointer */ | 963 | /* define general-purpose callback pointer */ |
847 | dvb->fe[0]->callback = em28xx_tuner_callback; | 964 | dvb->fe[0]->callback = em28xx_tuner_callback; |
965 | if (dvb->fe[1]) | ||
966 | dvb->fe[1]->callback = em28xx_tuner_callback; | ||
848 | 967 | ||
849 | /* register everything */ | 968 | /* register everything */ |
850 | result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); | 969 | result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 679da4804281..2630b265b0e8 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -306,7 +306,8 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) | |||
306 | poll_result.rc_data[0], | 306 | poll_result.rc_data[0], |
307 | poll_result.toggle_bit); | 307 | poll_result.toggle_bit); |
308 | 308 | ||
309 | if (ir->dev->chip_id == CHIP_ID_EM2874) | 309 | if (ir->dev->chip_id == CHIP_ID_EM2874 || |
310 | ir->dev->chip_id == CHIP_ID_EM2884) | ||
310 | /* The em2874 clears the readcount field every time the | 311 | /* The em2874 clears the readcount field every time the |
311 | register is read. The em2860/2880 datasheet says that it | 312 | register is read. The em2860/2880 datasheet says that it |
312 | is supposed to clear the readcount, but it doesn't. So with | 313 | is supposed to clear the readcount, but it doesn't. So with |
@@ -371,13 +372,15 @@ int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type) | |||
371 | case CHIP_ID_EM2883: | 372 | case CHIP_ID_EM2883: |
372 | ir->get_key = default_polling_getkey; | 373 | ir->get_key = default_polling_getkey; |
373 | break; | 374 | break; |
375 | case CHIP_ID_EM2884: | ||
374 | case CHIP_ID_EM2874: | 376 | case CHIP_ID_EM2874: |
375 | case CHIP_ID_EM28174: | 377 | case CHIP_ID_EM28174: |
376 | ir->get_key = em2874_polling_getkey; | 378 | ir->get_key = em2874_polling_getkey; |
377 | em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); | 379 | em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); |
378 | break; | 380 | break; |
379 | default: | 381 | default: |
380 | printk("Unrecognized em28xx chip id: IR not supported\n"); | 382 | printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", |
383 | dev->chip_id); | ||
381 | rc = -EINVAL; | 384 | rc = -EINVAL; |
382 | } | 385 | } |
383 | 386 | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 2a2cb7ed0014..b1199ef6da68 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <media/videobuf-dvb.h> | 38 | #include <media/videobuf-dvb.h> |
39 | #endif | 39 | #endif |
40 | #include "tuner-xc2028.h" | 40 | #include "tuner-xc2028.h" |
41 | #include "xc5000.h" | ||
41 | #include "em28xx-reg.h" | 42 | #include "em28xx-reg.h" |
42 | 43 | ||
43 | /* Boards supported by driver */ | 44 | /* Boards supported by driver */ |
@@ -121,6 +122,8 @@ | |||
121 | #define EM28174_BOARD_PCTV_290E 78 | 122 | #define EM28174_BOARD_PCTV_290E 78 |
122 | #define EM2884_BOARD_TERRATEC_H5 79 | 123 | #define EM2884_BOARD_TERRATEC_H5 79 |
123 | #define EM28174_BOARD_PCTV_460E 80 | 124 | #define EM28174_BOARD_PCTV_460E 80 |
125 | #define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 | ||
126 | #define EM2884_BOARD_CINERGY_HTC_STICK 82 | ||
124 | 127 | ||
125 | /* Limits minimum and default number of buffers */ | 128 | /* Limits minimum and default number of buffers */ |
126 | #define EM28XX_MIN_BUF 4 | 129 | #define EM28XX_MIN_BUF 4 |
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c index 6ae26160b81f..390291ceba26 100644 --- a/drivers/media/video/gspca/benq.c +++ b/drivers/media/video/gspca/benq.c | |||
@@ -76,7 +76,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
76 | gspca_dev->cam.cam_mode = vga_mode; | 76 | gspca_dev->cam.cam_mode = vga_mode; |
77 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | 77 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); |
78 | gspca_dev->cam.no_urb_create = 1; | 78 | gspca_dev->cam.no_urb_create = 1; |
79 | gspca_dev->cam.reverse_alts = 1; | ||
80 | return 0; | 79 | return 0; |
81 | } | 80 | } |
82 | 81 | ||
@@ -135,13 +134,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
135 | 134 | ||
136 | static void sd_stopN(struct gspca_dev *gspca_dev) | 135 | static void sd_stopN(struct gspca_dev *gspca_dev) |
137 | { | 136 | { |
137 | struct usb_interface *intf; | ||
138 | |||
138 | reg_w(gspca_dev, 0x003c, 0x0003); | 139 | reg_w(gspca_dev, 0x003c, 0x0003); |
139 | reg_w(gspca_dev, 0x003c, 0x0004); | 140 | reg_w(gspca_dev, 0x003c, 0x0004); |
140 | reg_w(gspca_dev, 0x003c, 0x0005); | 141 | reg_w(gspca_dev, 0x003c, 0x0005); |
141 | reg_w(gspca_dev, 0x003c, 0x0006); | 142 | reg_w(gspca_dev, 0x003c, 0x0006); |
142 | reg_w(gspca_dev, 0x003c, 0x0007); | 143 | reg_w(gspca_dev, 0x003c, 0x0007); |
144 | |||
145 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | ||
143 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, | 146 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, |
144 | gspca_dev->nbalt - 1); | 147 | intf->num_altsetting - 1); |
145 | } | 148 | } |
146 | 149 | ||
147 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 150 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index 2ced3b73994f..d74da8e0fef9 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c | |||
@@ -337,7 +337,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
337 | return -1; | 337 | return -1; |
338 | 338 | ||
339 | cam = &gspca_dev->cam; | 339 | cam = &gspca_dev->cam; |
340 | gspca_dev->nbalt = 4; | ||
341 | 340 | ||
342 | switch (sd->sensor) { | 341 | switch (sd->sensor) { |
343 | case ID_MI1320: | 342 | case ID_MI1320: |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 881e04c7ffe6..271be9866893 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -880,7 +880,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
880 | for (;;) { | 880 | for (;;) { |
881 | if (alt != gspca_dev->alt) { | 881 | if (alt != gspca_dev->alt) { |
882 | alt = gspca_dev->alt; | 882 | alt = gspca_dev->alt; |
883 | if (gspca_dev->nbalt > 1) { | 883 | if (intf->num_altsetting > 1) { |
884 | ret = usb_set_interface(gspca_dev->dev, | 884 | ret = usb_set_interface(gspca_dev->dev, |
885 | gspca_dev->iface, | 885 | gspca_dev->iface, |
886 | alt); | 886 | alt); |
@@ -2300,7 +2300,6 @@ int gspca_dev_probe2(struct usb_interface *intf, | |||
2300 | } | 2300 | } |
2301 | gspca_dev->dev = dev; | 2301 | gspca_dev->dev = dev; |
2302 | gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber; | 2302 | gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber; |
2303 | gspca_dev->nbalt = intf->num_altsetting; | ||
2304 | 2303 | ||
2305 | /* check if any audio device */ | 2304 | /* check if any audio device */ |
2306 | if (dev->config->desc.bNumInterfaces != 1) { | 2305 | if (dev->config->desc.bNumInterfaces != 1) { |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index e444f16e1497..5f1f46c8e373 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -69,7 +69,6 @@ struct cam { | |||
69 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | 69 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ |
70 | u8 npkt; /* number of packets in an ISOC message | 70 | u8 npkt; /* number of packets in an ISOC message |
71 | * 0 is the default value: 32 packets */ | 71 | * 0 is the default value: 32 packets */ |
72 | u8 reverse_alts; /* Alt settings are in high to low order */ | ||
73 | }; | 72 | }; |
74 | 73 | ||
75 | struct gspca_dev; | 74 | struct gspca_dev; |
@@ -208,7 +207,6 @@ struct gspca_dev { | |||
208 | char memory; /* memory type (V4L2_MEMORY_xxx) */ | 207 | char memory; /* memory type (V4L2_MEMORY_xxx) */ |
209 | __u8 iface; /* USB interface number */ | 208 | __u8 iface; /* USB interface number */ |
210 | __u8 alt; /* USB alternate setting */ | 209 | __u8 alt; /* USB alternate setting */ |
211 | __u8 nbalt; /* number of USB alternate settings */ | ||
212 | u8 audio; /* presence of audio device */ | 210 | u8 audio; /* presence of audio device */ |
213 | }; | 211 | }; |
214 | 212 | ||
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c index f3f7fe0ec4b7..494b05ed8f1a 100644 --- a/drivers/media/video/gspca/konica.c +++ b/drivers/media/video/gspca/konica.c | |||
@@ -247,9 +247,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
247 | gspca_dev->cam.cam_mode = vga_mode; | 247 | gspca_dev->cam.cam_mode = vga_mode; |
248 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | 248 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); |
249 | gspca_dev->cam.no_urb_create = 1; | 249 | gspca_dev->cam.no_urb_create = 1; |
250 | /* The highest alt setting has an isoc packetsize of 0, so we | ||
251 | don't want to use it */ | ||
252 | gspca_dev->nbalt--; | ||
253 | 250 | ||
254 | sd->brightness = BRIGHTNESS_DEFAULT; | 251 | sd->brightness = BRIGHTNESS_DEFAULT; |
255 | sd->contrast = CONTRAST_DEFAULT; | 252 | sd->contrast = CONTRAST_DEFAULT; |
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index ef45fa575752..edd32793bb17 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
@@ -263,7 +263,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
263 | cam->nmodes = ARRAY_SIZE(vga_mode); | 263 | cam->nmodes = ARRAY_SIZE(vga_mode); |
264 | cam->ctrls = sd->ctrls; | 264 | cam->ctrls = sd->ctrls; |
265 | sd->quality = QUALITY_DEF; | 265 | sd->quality = QUALITY_DEF; |
266 | gspca_dev->nbalt = 9; /* use the altsetting 08 */ | ||
267 | return 0; | 266 | return 0; |
268 | } | 267 | } |
269 | 268 | ||
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c index 7681814e594f..3830054a683e 100644 --- a/drivers/media/video/gspca/nw80x.c +++ b/drivers/media/video/gspca/nw80x.c | |||
@@ -1763,7 +1763,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1763 | if ((unsigned) webcam >= NWEBCAMS) | 1763 | if ((unsigned) webcam >= NWEBCAMS) |
1764 | webcam = 0; | 1764 | webcam = 0; |
1765 | sd->webcam = webcam; | 1765 | sd->webcam = webcam; |
1766 | gspca_dev->cam.reverse_alts = 1; | ||
1767 | gspca_dev->cam.ctrls = sd->ctrls; | 1766 | gspca_dev->cam.ctrls = sd->ctrls; |
1768 | sd->ag_cnt = -1; | 1767 | sd->ag_cnt = -1; |
1769 | 1768 | ||
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 6a01b35a9478..3d68ad5015d5 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -3348,7 +3348,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3348 | case BRIDGE_W9968CF: | 3348 | case BRIDGE_W9968CF: |
3349 | cam->cam_mode = w9968cf_vga_mode; | 3349 | cam->cam_mode = w9968cf_vga_mode; |
3350 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); | 3350 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); |
3351 | cam->reverse_alts = 1; | ||
3352 | break; | 3351 | break; |
3353 | } | 3352 | } |
3354 | 3353 | ||
diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c index 3b71bbcd977a..6d9835342e0a 100644 --- a/drivers/media/video/gspca/se401.c +++ b/drivers/media/video/gspca/se401.c | |||
@@ -376,7 +376,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
376 | cam->bulk_size = BULK_SIZE; | 376 | cam->bulk_size = BULK_SIZE; |
377 | cam->bulk_nurbs = 4; | 377 | cam->bulk_nurbs = 4; |
378 | cam->ctrls = sd->ctrls; | 378 | cam->ctrls = sd->ctrls; |
379 | gspca_dev->nbalt = 1; /* Ignore the bogus isoc alt settings */ | ||
380 | sd->resetlevel = 0x2d; /* Set initial resetlevel */ | 379 | sd->resetlevel = 0x2d; /* Set initial resetlevel */ |
381 | 380 | ||
382 | /* See if the camera supports brightness */ | 381 | /* See if the camera supports brightness */ |
@@ -395,6 +394,14 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
395 | return 0; | 394 | return 0; |
396 | } | 395 | } |
397 | 396 | ||
397 | /* function called at start time before URB creation */ | ||
398 | static int sd_isoc_init(struct gspca_dev *gspca_dev) | ||
399 | { | ||
400 | gspca_dev->alt = 1; /* Ignore the bogus isoc alt settings */ | ||
401 | |||
402 | return gspca_dev->usb_err; | ||
403 | } | ||
404 | |||
398 | /* -- start the camera -- */ | 405 | /* -- start the camera -- */ |
399 | static int sd_start(struct gspca_dev *gspca_dev) | 406 | static int sd_start(struct gspca_dev *gspca_dev) |
400 | { | 407 | { |
@@ -714,6 +721,7 @@ static const struct sd_desc sd_desc = { | |||
714 | .nctrls = ARRAY_SIZE(sd_ctrls), | 721 | .nctrls = ARRAY_SIZE(sd_ctrls), |
715 | .config = sd_config, | 722 | .config = sd_config, |
716 | .init = sd_init, | 723 | .init = sd_init, |
724 | .isoc_init = sd_isoc_init, | ||
717 | .start = sd_start, | 725 | .start = sd_start, |
718 | .stopN = sd_stopN, | 726 | .stopN = sd_stopN, |
719 | .dq_callback = sd_dq_callback, | 727 | .dq_callback = sd_dq_callback, |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index c746bf19ca14..c55d6674c1c6 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -1235,7 +1235,7 @@ static const u8 po2030n_sensor_param1[][8] = { | |||
1235 | {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ | 1235 | {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ |
1236 | {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, | 1236 | {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, |
1237 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, | 1237 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, |
1238 | {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10}, | 1238 | {0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */ |
1239 | /*param2*/ | 1239 | /*param2*/ |
1240 | {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, | 1240 | {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, |
1241 | {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, | 1241 | {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, |
@@ -1779,10 +1779,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1779 | sd->ag_cnt = -1; | 1779 | sd->ag_cnt = -1; |
1780 | sd->quality = QUALITY_DEF; | 1780 | sd->quality = QUALITY_DEF; |
1781 | 1781 | ||
1782 | /* if USB 1.1, let some bandwidth for the audio device */ | ||
1783 | if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH) | ||
1784 | gspca_dev->nbalt--; | ||
1785 | |||
1786 | INIT_WORK(&sd->work, qual_upd); | 1782 | INIT_WORK(&sd->work, qual_upd); |
1787 | 1783 | ||
1788 | return 0; | 1784 | return 0; |
@@ -2063,6 +2059,16 @@ static void setredblue(struct gspca_dev *gspca_dev) | |||
2063 | { | 2059 | { |
2064 | struct sd *sd = (struct sd *) gspca_dev; | 2060 | struct sd *sd = (struct sd *) gspca_dev; |
2065 | 2061 | ||
2062 | if (sd->sensor == SENSOR_PO2030N) { | ||
2063 | u8 rg1b[] = /* red green1 blue (no g2) */ | ||
2064 | {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; | ||
2065 | |||
2066 | /* 0x40 = normal value = gain x 1 */ | ||
2067 | rg1b[3] = sd->ctrls[RED].val * 2; | ||
2068 | rg1b[5] = sd->ctrls[BLUE].val * 2; | ||
2069 | i2c_w8(gspca_dev, rg1b); | ||
2070 | return; | ||
2071 | } | ||
2066 | reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); | 2072 | reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); |
2067 | /* reg_w1(gspca_dev, 0x07, 32); */ | 2073 | /* reg_w1(gspca_dev, 0x07, 32); */ |
2068 | reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); | 2074 | reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); |
@@ -2397,7 +2403,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2397 | reg_w1(gspca_dev, 0x17, reg17); | 2403 | reg_w1(gspca_dev, 0x17, reg17); |
2398 | reg01 &= ~S_PWR_DN; /* sensor power on */ | 2404 | reg01 &= ~S_PWR_DN; /* sensor power on */ |
2399 | reg_w1(gspca_dev, 0x01, reg01); | 2405 | reg_w1(gspca_dev, 0x01, reg01); |
2400 | reg01 &= ~SYS_SEL_48M; | 2406 | reg01 &= ~SCL_SEL_OD; /* remove open-drain mode */ |
2401 | reg_w1(gspca_dev, 0x01, reg01); | 2407 | reg_w1(gspca_dev, 0x01, reg01); |
2402 | 2408 | ||
2403 | switch (sd->sensor) { | 2409 | switch (sd->sensor) { |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index c82fd53cef95..61743d425584 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -451,7 +451,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
451 | } | 451 | } |
452 | 452 | ||
453 | cam = &gspca_dev->cam; | 453 | cam = &gspca_dev->cam; |
454 | gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ | ||
455 | 454 | ||
456 | sd->chip_revision = id->driver_info; | 455 | sd->chip_revision = id->driver_info; |
457 | if (sd->chip_revision == Rev012A) { | 456 | if (sd->chip_revision == Rev012A) { |
diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c index 29596c59837f..acb209a67100 100644 --- a/drivers/media/video/gspca/topro.c +++ b/drivers/media/video/gspca/topro.c | |||
@@ -3946,7 +3946,7 @@ static int get_fr_idx(struct gspca_dev *gspca_dev) | |||
3946 | /* 640x480 * 30 fps does not work */ | 3946 | /* 640x480 * 30 fps does not work */ |
3947 | if (i == 6 /* if 30 fps */ | 3947 | if (i == 6 /* if 30 fps */ |
3948 | && gspca_dev->width == 640) | 3948 | && gspca_dev->width == 640) |
3949 | i = 0x86; /* 15 fps */ | 3949 | i = 0x05; /* 15 fps */ |
3950 | } else { | 3950 | } else { |
3951 | for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) { | 3951 | for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) { |
3952 | if (sd->framerate >= rates_6810[i]) | 3952 | if (sd->framerate >= rates_6810[i]) |
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c index 3aed42acdb5a..628ba535026f 100644 --- a/drivers/media/video/gspca/xirlink_cit.c +++ b/drivers/media/video/gspca/xirlink_cit.c | |||
@@ -995,14 +995,12 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
995 | case CIT_MODEL0: | 995 | case CIT_MODEL0: |
996 | cam->cam_mode = model0_mode; | 996 | cam->cam_mode = model0_mode; |
997 | cam->nmodes = ARRAY_SIZE(model0_mode); | 997 | cam->nmodes = ARRAY_SIZE(model0_mode); |
998 | cam->reverse_alts = 1; | ||
999 | gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP)); | 998 | gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP)); |
1000 | sd->sof_len = 4; | 999 | sd->sof_len = 4; |
1001 | break; | 1000 | break; |
1002 | case CIT_MODEL1: | 1001 | case CIT_MODEL1: |
1003 | cam->cam_mode = cif_yuv_mode; | 1002 | cam->cam_mode = cif_yuv_mode; |
1004 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); | 1003 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); |
1005 | cam->reverse_alts = 1; | ||
1006 | gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP); | 1004 | gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP); |
1007 | sd->sof_len = 4; | 1005 | sd->sof_len = 4; |
1008 | break; | 1006 | break; |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 30ea1e479492..f22e02f8d758 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -5381,12 +5381,12 @@ static const struct usb_action tas5130c_NoFlikerScale[] = { | |||
5381 | {} | 5381 | {} |
5382 | }; | 5382 | }; |
5383 | 5383 | ||
5384 | static const struct usb_action gc0303_InitialScale[] = { | 5384 | /* from usbvm305.inf 0ac8:305b 07/06/15 (3 - tas5130c) */ |
5385 | static const struct usb_action gc0303_Initial[] = { | ||
5385 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ | 5386 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ |
5386 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ | 5387 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ |
5387 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ | 5388 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ |
5388 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc, | 5389 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, |
5389 | * 0<->10 */ | ||
5390 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ | 5390 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ |
5391 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ | 5391 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ |
5392 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ | 5392 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ |
@@ -5405,29 +5405,22 @@ static const struct usb_action gc0303_InitialScale[] = { | |||
5405 | * 6<->8 */ | 5405 | * 6<->8 */ |
5406 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ | 5406 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ |
5407 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ | 5407 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ |
5408 | {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ | ||
5409 | {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ | ||
5410 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ | ||
5411 | {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ | ||
5412 | {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ | ||
5413 | /*?? {0xaa, 0x01, 0x0000}, */ | ||
5414 | {0xaa, 0x01, 0x0000}, | 5408 | {0xaa, 0x01, 0x0000}, |
5415 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ | 5409 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ |
5416 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ | 5410 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ |
5411 | {0xaa, 0x1b, 0x0000}, | ||
5417 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ | 5412 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ |
5418 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ | 5413 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ |
5419 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ | 5414 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ |
5420 | {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ | 5415 | {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ |
5421 | {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ | 5416 | {0xaa, 0x0a, 0x0002}, |
5422 | {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ | 5417 | {0xaa, 0x0b, 0x0000}, |
5423 | {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ | 5418 | {0xaa, 0x0c, 0x0002}, |
5424 | {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ | 5419 | {0xaa, 0x0d, 0x0000}, |
5425 | {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ | 5420 | {0xaa, 0x0e, 0x0002}, |
5426 | {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ | 5421 | {0xaa, 0x0f, 0x0000}, |
5427 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ | 5422 | {0xaa, 0x10, 0x0002}, |
5428 | {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ | 5423 | {0xaa, 0x11, 0x0000}, |
5429 | /*?? {0xa0, 0x00, 0x0039}, | ||
5430 | {0xa1, 0x01, 0x0037}, */ | ||
5431 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ | 5424 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ |
5432 | {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ | 5425 | {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ |
5433 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ | 5426 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ |
@@ -5442,17 +5435,18 @@ static const struct usb_action gc0303_InitialScale[] = { | |||
5442 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ | 5435 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ |
5443 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ | 5436 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ |
5444 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ | 5437 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ |
5445 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ | 5438 | {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN}, |
5446 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ | 5439 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ |
5447 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ | 5440 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ |
5441 | {0xaa, 0x1b, 0x0000}, | ||
5448 | {} | 5442 | {} |
5449 | }; | 5443 | }; |
5450 | 5444 | ||
5451 | static const struct usb_action gc0303_Initial[] = { | 5445 | static const struct usb_action gc0303_InitialScale[] = { |
5452 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ | 5446 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ |
5453 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ | 5447 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ |
5454 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ | 5448 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ |
5455 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc, */ | 5449 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, |
5456 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ | 5450 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ |
5457 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ | 5451 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ |
5458 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ | 5452 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ |
@@ -5471,34 +5465,26 @@ static const struct usb_action gc0303_Initial[] = { | |||
5471 | * 8<->6 */ | 5465 | * 8<->6 */ |
5472 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ | 5466 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ |
5473 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ | 5467 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ |
5474 | {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ | ||
5475 | {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ | ||
5476 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ | ||
5477 | {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ | ||
5478 | {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ | ||
5479 | /*?? {0xaa, 0x01, 0x0000}, */ | ||
5480 | {0xaa, 0x01, 0x0000}, | 5468 | {0xaa, 0x01, 0x0000}, |
5481 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ | 5469 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ |
5482 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ | 5470 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ |
5471 | {0xaa, 0x1b, 0x0000}, | ||
5483 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ | 5472 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ |
5484 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ | 5473 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ |
5485 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ | 5474 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ |
5486 | {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ | 5475 | {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ |
5487 | {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ | 5476 | {0xaa, 0x0a, 0x0001}, |
5488 | {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ | 5477 | {0xaa, 0x0b, 0x0000}, |
5489 | {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ | 5478 | {0xaa, 0x0c, 0x0001}, |
5490 | {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ | 5479 | {0xaa, 0x0d, 0x0000}, |
5491 | {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ | 5480 | {0xaa, 0x0e, 0x0001}, |
5492 | {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ | 5481 | {0xaa, 0x0f, 0x0000}, |
5493 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ | 5482 | {0xaa, 0x10, 0x0001}, |
5494 | {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ | 5483 | {0xaa, 0x11, 0x0000}, |
5495 | /*?? {0xa0, 0x00, 0x0039}, | ||
5496 | {0xa1, 0x01, 0x0037}, */ | ||
5497 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ | 5484 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ |
5498 | {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ | 5485 | {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ |
5499 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ | 5486 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ |
5500 | {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ | 5487 | {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ |
5501 | {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ | ||
5502 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ | 5488 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ |
5503 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ | 5489 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ |
5504 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ | 5490 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ |
@@ -5508,36 +5494,37 @@ static const struct usb_action gc0303_Initial[] = { | |||
5508 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ | 5494 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ |
5509 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ | 5495 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ |
5510 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ | 5496 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ |
5511 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ | 5497 | {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN}, |
5512 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ | 5498 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ |
5513 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ | 5499 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ |
5500 | {0xaa, 0x1b, 0x0000}, | ||
5514 | {} | 5501 | {} |
5515 | }; | 5502 | }; |
5516 | static const struct usb_action gc0303_50HZScale[] = { | 5503 | static const struct usb_action gc0303_50HZ[] = { |
5517 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5504 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5518 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ | 5505 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ |
5519 | {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ | 5506 | {0xaa, 0x84, 0x0063}, |
5520 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | 5507 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ |
5521 | {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ | 5508 | {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ |
5522 | {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ | 5509 | {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ |
5523 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | 5510 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ |
5524 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | 5511 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ |
5525 | {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ | 5512 | {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ |
5526 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | 5513 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ |
5527 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | 5514 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ |
5528 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ | 5515 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ |
5529 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ | 5516 | {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, |
5530 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | 5517 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ |
5531 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | 5518 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ |
5532 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | 5519 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ |
5533 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | 5520 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ |
5534 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | 5521 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ |
5535 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | 5522 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ |
5536 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ | 5523 | {0xa0, 0x7f, ZC3XX_R18D_YTARGET}, |
5537 | {} | 5524 | {} |
5538 | }; | 5525 | }; |
5539 | 5526 | ||
5540 | static const struct usb_action gc0303_50HZ[] = { | 5527 | static const struct usb_action gc0303_50HZScale[] = { |
5541 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5528 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5542 | {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ | 5529 | {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ |
5543 | {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ | 5530 | {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ |
@@ -5550,21 +5537,21 @@ static const struct usb_action gc0303_50HZ[] = { | |||
5550 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | 5537 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ |
5551 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | 5538 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ |
5552 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ | 5539 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ |
5553 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ | 5540 | {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ |
5554 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | 5541 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ |
5555 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | 5542 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ |
5556 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | 5543 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ |
5557 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | 5544 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ |
5558 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | 5545 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ |
5559 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | 5546 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ |
5560 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ | 5547 | {0xa0, 0x7f, ZC3XX_R18D_YTARGET}, |
5561 | {} | 5548 | {} |
5562 | }; | 5549 | }; |
5563 | 5550 | ||
5564 | static const struct usb_action gc0303_60HZScale[] = { | 5551 | static const struct usb_action gc0303_60HZ[] = { |
5565 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5552 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5566 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ | 5553 | {0xaa, 0x83, 0x0000}, |
5567 | {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ | 5554 | {0xaa, 0x84, 0x003b}, |
5568 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | 5555 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ |
5569 | {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ | 5556 | {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ |
5570 | {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ | 5557 | {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ |
@@ -5581,14 +5568,14 @@ static const struct usb_action gc0303_60HZScale[] = { | |||
5581 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | 5568 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ |
5582 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | 5569 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ |
5583 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | 5570 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ |
5584 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ | 5571 | {0xa0, 0x80, ZC3XX_R18D_YTARGET}, |
5585 | {} | 5572 | {} |
5586 | }; | 5573 | }; |
5587 | 5574 | ||
5588 | static const struct usb_action gc0303_60HZ[] = { | 5575 | static const struct usb_action gc0303_60HZScale[] = { |
5589 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5576 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5590 | {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ | 5577 | {0xaa, 0x83, 0x0000}, |
5591 | {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ | 5578 | {0xaa, 0x84, 0x0076}, |
5592 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | 5579 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ |
5593 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */ | 5580 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */ |
5594 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */ | 5581 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */ |
@@ -5605,18 +5592,18 @@ static const struct usb_action gc0303_60HZ[] = { | |||
5605 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */ | 5592 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */ |
5606 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */ | 5593 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */ |
5607 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | 5594 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ |
5608 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,d,78,cc */ | 5595 | {0xa0, 0x80, ZC3XX_R18D_YTARGET}, |
5609 | {} | 5596 | {} |
5610 | }; | 5597 | }; |
5611 | 5598 | ||
5612 | static const struct usb_action gc0303_NoFlikerScale[] = { | 5599 | static const struct usb_action gc0303_NoFliker[] = { |
5613 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ | 5600 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ |
5614 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5601 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5615 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | 5602 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ |
5616 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ | 5603 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ |
5617 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */ | 5604 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */ |
5618 | {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ | 5605 | {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, |
5619 | {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ | 5606 | {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, |
5620 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | 5607 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ |
5621 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | 5608 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ |
5622 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ | 5609 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ |
@@ -5631,14 +5618,14 @@ static const struct usb_action gc0303_NoFlikerScale[] = { | |||
5631 | {} | 5618 | {} |
5632 | }; | 5619 | }; |
5633 | 5620 | ||
5634 | static const struct usb_action gc0303_NoFliker[] = { | 5621 | static const struct usb_action gc0303_NoFlikerScale[] = { |
5635 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ | 5622 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ |
5636 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 5623 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
5637 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | 5624 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ |
5638 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ | 5625 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ |
5639 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | 5626 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ |
5640 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc, */ | 5627 | {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, |
5641 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc, */ | 5628 | {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, |
5642 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | 5629 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ |
5643 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | 5630 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ |
5644 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ | 5631 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ |
@@ -5809,7 +5796,7 @@ static void setmatrix(struct gspca_dev *gspca_dev) | |||
5809 | static const u8 tas5130c_matrix[9] = | 5796 | static const u8 tas5130c_matrix[9] = |
5810 | {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; | 5797 | {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; |
5811 | static const u8 gc0303_matrix[9] = | 5798 | static const u8 gc0303_matrix[9] = |
5812 | {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; | 5799 | {0x6c, 0xea, 0xea, 0xea, 0x6c, 0xea, 0xea, 0xea, 0x6c}; |
5813 | static const u8 *matrix_tb[SENSOR_MAX] = { | 5800 | static const u8 *matrix_tb[SENSOR_MAX] = { |
5814 | [SENSOR_ADCM2700] = adcm2700_matrix, | 5801 | [SENSOR_ADCM2700] = adcm2700_matrix, |
5815 | [SENSOR_CS2102] = ov7620_matrix, | 5802 | [SENSOR_CS2102] = ov7620_matrix, |
@@ -6426,10 +6413,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6426 | gspca_dev->cam.ctrls = sd->ctrls; | 6413 | gspca_dev->cam.ctrls = sd->ctrls; |
6427 | sd->quality = QUALITY_DEF; | 6414 | sd->quality = QUALITY_DEF; |
6428 | 6415 | ||
6429 | /* if USB 1.1, let some bandwidth for the audio device */ | ||
6430 | if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH) | ||
6431 | gspca_dev->nbalt--; | ||
6432 | |||
6433 | return 0; | 6416 | return 0; |
6434 | } | 6417 | } |
6435 | 6418 | ||
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h index 9332920ca4ff..7b9ec1cfeb80 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.h +++ b/drivers/media/video/ivtv/ivtv-i2c.h | |||
@@ -25,7 +25,7 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv); | |||
25 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx); | 25 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx); |
26 | struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); | 26 | struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); |
27 | 27 | ||
28 | /* init + register i2c algo-bit adapter */ | 28 | /* init + register i2c adapter */ |
29 | int init_ivtv_i2c(struct ivtv *itv); | 29 | int init_ivtv_i2c(struct ivtv *itv); |
30 | void exit_ivtv_i2c(struct ivtv *itv); | 30 | void exit_ivtv_i2c(struct ivtv *itv); |
31 | 31 | ||
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index e2b1029b16cd..097c9d3d04a8 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -109,14 +109,13 @@ static struct mt9m001 *to_mt9m001(const struct i2c_client *client) | |||
109 | 109 | ||
110 | static int reg_read(struct i2c_client *client, const u8 reg) | 110 | static int reg_read(struct i2c_client *client, const u8 reg) |
111 | { | 111 | { |
112 | s32 data = i2c_smbus_read_word_data(client, reg); | 112 | return i2c_smbus_read_word_swapped(client, reg); |
113 | return data < 0 ? data : swab16(data); | ||
114 | } | 113 | } |
115 | 114 | ||
116 | static int reg_write(struct i2c_client *client, const u8 reg, | 115 | static int reg_write(struct i2c_client *client, const u8 reg, |
117 | const u16 data) | 116 | const u16 data) |
118 | { | 117 | { |
119 | return i2c_smbus_write_word_data(client, reg, swab16(data)); | 118 | return i2c_smbus_write_word_swapped(client, reg, data); |
120 | } | 119 | } |
121 | 120 | ||
122 | static int reg_set(struct i2c_client *client, const u8 reg, | 121 | static int reg_set(struct i2c_client *client, const u8 reg, |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 398f96ffd35e..95ca6c74f5df 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -211,7 +211,7 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) | |||
211 | if (page > 2) | 211 | if (page > 2) |
212 | return -EINVAL; | 212 | return -EINVAL; |
213 | 213 | ||
214 | ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); | 214 | ret = i2c_smbus_write_word_swapped(client, MT9M111_PAGE_MAP, page); |
215 | if (!ret) | 215 | if (!ret) |
216 | mt9m111->lastpage = page; | 216 | mt9m111->lastpage = page; |
217 | return ret; | 217 | return ret; |
@@ -223,7 +223,7 @@ static int mt9m111_reg_read(struct i2c_client *client, const u16 reg) | |||
223 | 223 | ||
224 | ret = reg_page_map_set(client, reg); | 224 | ret = reg_page_map_set(client, reg); |
225 | if (!ret) | 225 | if (!ret) |
226 | ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff)); | 226 | ret = i2c_smbus_read_word_swapped(client, reg & 0xff); |
227 | 227 | ||
228 | dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); | 228 | dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); |
229 | return ret; | 229 | return ret; |
@@ -236,8 +236,7 @@ static int mt9m111_reg_write(struct i2c_client *client, const u16 reg, | |||
236 | 236 | ||
237 | ret = reg_page_map_set(client, reg); | 237 | ret = reg_page_map_set(client, reg); |
238 | if (!ret) | 238 | if (!ret) |
239 | ret = i2c_smbus_write_word_data(client, reg & 0xff, | 239 | ret = i2c_smbus_write_word_swapped(client, reg & 0xff, data); |
240 | swab16(data)); | ||
241 | dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); | 240 | dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); |
242 | return ret; | 241 | return ret; |
243 | } | 242 | } |
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c index 73c068993f05..93c3ec7426e8 100644 --- a/drivers/media/video/mt9p031.c +++ b/drivers/media/video/mt9p031.c | |||
@@ -132,13 +132,12 @@ static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd) | |||
132 | 132 | ||
133 | static int mt9p031_read(struct i2c_client *client, u8 reg) | 133 | static int mt9p031_read(struct i2c_client *client, u8 reg) |
134 | { | 134 | { |
135 | s32 data = i2c_smbus_read_word_data(client, reg); | 135 | return i2c_smbus_read_word_swapped(client, reg); |
136 | return data < 0 ? data : be16_to_cpu(data); | ||
137 | } | 136 | } |
138 | 137 | ||
139 | static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data) | 138 | static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data) |
140 | { | 139 | { |
141 | return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); | 140 | return i2c_smbus_write_word_swapped(client, reg, data); |
142 | } | 141 | } |
143 | 142 | ||
144 | static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear, | 143 | static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear, |
diff --git a/drivers/media/video/mt9t001.c b/drivers/media/video/mt9t001.c index 08074b8a2736..cd81d04a529e 100644 --- a/drivers/media/video/mt9t001.c +++ b/drivers/media/video/mt9t001.c | |||
@@ -133,13 +133,12 @@ static inline struct mt9t001 *to_mt9t001(struct v4l2_subdev *sd) | |||
133 | 133 | ||
134 | static int mt9t001_read(struct i2c_client *client, u8 reg) | 134 | static int mt9t001_read(struct i2c_client *client, u8 reg) |
135 | { | 135 | { |
136 | s32 data = i2c_smbus_read_word_data(client, reg); | 136 | return i2c_smbus_read_word_swapped(client, reg); |
137 | return data < 0 ? data : be16_to_cpu(data); | ||
138 | } | 137 | } |
139 | 138 | ||
140 | static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data) | 139 | static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data) |
141 | { | 140 | { |
142 | return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); | 141 | return i2c_smbus_write_word_swapped(client, reg, data); |
143 | } | 142 | } |
144 | 143 | ||
145 | static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear, | 144 | static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear, |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 0e78477452ff..84add1aef139 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -90,14 +90,13 @@ static struct mt9t031 *to_mt9t031(const struct i2c_client *client) | |||
90 | 90 | ||
91 | static int reg_read(struct i2c_client *client, const u8 reg) | 91 | static int reg_read(struct i2c_client *client, const u8 reg) |
92 | { | 92 | { |
93 | s32 data = i2c_smbus_read_word_data(client, reg); | 93 | return i2c_smbus_read_word_swapped(client, reg); |
94 | return data < 0 ? data : swab16(data); | ||
95 | } | 94 | } |
96 | 95 | ||
97 | static int reg_write(struct i2c_client *client, const u8 reg, | 96 | static int reg_write(struct i2c_client *client, const u8 reg, |
98 | const u16 data) | 97 | const u16 data) |
99 | { | 98 | { |
100 | return i2c_smbus_write_word_data(client, reg, swab16(data)); | 99 | return i2c_smbus_write_word_swapped(client, reg, data); |
101 | } | 100 | } |
102 | 101 | ||
103 | static int reg_set(struct i2c_client *client, const u8 reg, | 102 | static int reg_set(struct i2c_client *client, const u8 reg, |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 690ee0d42eeb..944940758fa3 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -130,14 +130,13 @@ static struct mt9v022 *to_mt9v022(const struct i2c_client *client) | |||
130 | 130 | ||
131 | static int reg_read(struct i2c_client *client, const u8 reg) | 131 | static int reg_read(struct i2c_client *client, const u8 reg) |
132 | { | 132 | { |
133 | s32 data = i2c_smbus_read_word_data(client, reg); | 133 | return i2c_smbus_read_word_swapped(client, reg); |
134 | return data < 0 ? data : swab16(data); | ||
135 | } | 134 | } |
136 | 135 | ||
137 | static int reg_write(struct i2c_client *client, const u8 reg, | 136 | static int reg_write(struct i2c_client *client, const u8 reg, |
138 | const u16 data) | 137 | const u16 data) |
139 | { | 138 | { |
140 | return i2c_smbus_write_word_data(client, reg, swab16(data)); | 139 | return i2c_smbus_write_word_swapped(client, reg, data); |
141 | } | 140 | } |
142 | 141 | ||
143 | static int reg_set(struct i2c_client *client, const u8 reg, | 142 | static int reg_set(struct i2c_client *client, const u8 reg, |
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c index f080c162123f..d90b982cc218 100644 --- a/drivers/media/video/mt9v032.c +++ b/drivers/media/video/mt9v032.c | |||
@@ -139,10 +139,10 @@ static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd) | |||
139 | 139 | ||
140 | static int mt9v032_read(struct i2c_client *client, const u8 reg) | 140 | static int mt9v032_read(struct i2c_client *client, const u8 reg) |
141 | { | 141 | { |
142 | s32 data = i2c_smbus_read_word_data(client, reg); | 142 | s32 data = i2c_smbus_read_word_swapped(client, reg); |
143 | dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__, | 143 | dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__, |
144 | swab16(data), reg); | 144 | data, reg); |
145 | return data < 0 ? data : swab16(data); | 145 | return data; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int mt9v032_write(struct i2c_client *client, const u8 reg, | 148 | static int mt9v032_write(struct i2c_client *client, const u8 reg, |
@@ -150,7 +150,7 @@ static int mt9v032_write(struct i2c_client *client, const u8 reg, | |||
150 | { | 150 | { |
151 | dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__, | 151 | dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__, |
152 | data, reg); | 152 | data, reg); |
153 | return i2c_smbus_write_word_data(client, reg, swab16(data)); | 153 | return i2c_smbus_write_word_swapped(client, reg, data); |
154 | } | 154 | } |
155 | 155 | ||
156 | static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set) | 156 | static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set) |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index ee0d0b39cd17..00d6d192b88c 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -524,10 +524,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | static int omapvid_handle_interlace_display(struct omap_vout_device *vout, | ||
528 | unsigned int irqstatus, struct timeval timevalue) | ||
529 | { | ||
530 | u32 fid; | ||
531 | |||
532 | if (vout->first_int) { | ||
533 | vout->first_int = 0; | ||
534 | goto err; | ||
535 | } | ||
536 | |||
537 | if (irqstatus & DISPC_IRQ_EVSYNC_ODD) | ||
538 | fid = 1; | ||
539 | else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) | ||
540 | fid = 0; | ||
541 | else | ||
542 | goto err; | ||
543 | |||
544 | vout->field_id ^= 1; | ||
545 | if (fid != vout->field_id) { | ||
546 | if (fid == 0) | ||
547 | vout->field_id = fid; | ||
548 | } else if (0 == fid) { | ||
549 | if (vout->cur_frm == vout->next_frm) | ||
550 | goto err; | ||
551 | |||
552 | vout->cur_frm->ts = timevalue; | ||
553 | vout->cur_frm->state = VIDEOBUF_DONE; | ||
554 | wake_up_interruptible(&vout->cur_frm->done); | ||
555 | vout->cur_frm = vout->next_frm; | ||
556 | } else { | ||
557 | if (list_empty(&vout->dma_queue) || | ||
558 | (vout->cur_frm != vout->next_frm)) | ||
559 | goto err; | ||
560 | } | ||
561 | |||
562 | return vout->field_id; | ||
563 | err: | ||
564 | return 0; | ||
565 | } | ||
566 | |||
527 | static void omap_vout_isr(void *arg, unsigned int irqstatus) | 567 | static void omap_vout_isr(void *arg, unsigned int irqstatus) |
528 | { | 568 | { |
529 | int ret; | 569 | int ret, fid, mgr_id; |
530 | u32 addr, fid; | 570 | u32 addr, irq; |
531 | struct omap_overlay *ovl; | 571 | struct omap_overlay *ovl; |
532 | struct timeval timevalue; | 572 | struct timeval timevalue; |
533 | struct omapvideo_info *ovid; | 573 | struct omapvideo_info *ovid; |
@@ -543,112 +583,73 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) | |||
543 | if (!ovl->manager || !ovl->manager->device) | 583 | if (!ovl->manager || !ovl->manager->device) |
544 | return; | 584 | return; |
545 | 585 | ||
586 | mgr_id = ovl->manager->id; | ||
546 | cur_display = ovl->manager->device; | 587 | cur_display = ovl->manager->device; |
547 | 588 | ||
548 | spin_lock(&vout->vbq_lock); | 589 | spin_lock(&vout->vbq_lock); |
549 | do_gettimeofday(&timevalue); | 590 | do_gettimeofday(&timevalue); |
550 | 591 | ||
551 | if (cur_display->type != OMAP_DISPLAY_TYPE_VENC) { | 592 | switch (cur_display->type) { |
552 | switch (cur_display->type) { | 593 | case OMAP_DISPLAY_TYPE_DSI: |
553 | case OMAP_DISPLAY_TYPE_DPI: | 594 | case OMAP_DISPLAY_TYPE_DPI: |
554 | if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) | 595 | if (mgr_id == OMAP_DSS_CHANNEL_LCD) |
555 | goto vout_isr_err; | 596 | irq = DISPC_IRQ_VSYNC; |
556 | break; | 597 | else if (mgr_id == OMAP_DSS_CHANNEL_LCD2) |
557 | case OMAP_DISPLAY_TYPE_HDMI: | 598 | irq = DISPC_IRQ_VSYNC2; |
558 | if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN)) | 599 | else |
559 | goto vout_isr_err; | ||
560 | break; | ||
561 | default: | ||
562 | goto vout_isr_err; | ||
563 | } | ||
564 | if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { | ||
565 | vout->cur_frm->ts = timevalue; | ||
566 | vout->cur_frm->state = VIDEOBUF_DONE; | ||
567 | wake_up_interruptible(&vout->cur_frm->done); | ||
568 | vout->cur_frm = vout->next_frm; | ||
569 | } | ||
570 | vout->first_int = 0; | ||
571 | if (list_empty(&vout->dma_queue)) | ||
572 | goto vout_isr_err; | 600 | goto vout_isr_err; |
573 | 601 | ||
574 | vout->next_frm = list_entry(vout->dma_queue.next, | 602 | if (!(irqstatus & irq)) |
575 | struct videobuf_buffer, queue); | 603 | goto vout_isr_err; |
576 | list_del(&vout->next_frm->queue); | 604 | break; |
577 | 605 | case OMAP_DISPLAY_TYPE_VENC: | |
578 | vout->next_frm->state = VIDEOBUF_ACTIVE; | 606 | fid = omapvid_handle_interlace_display(vout, irqstatus, |
607 | timevalue); | ||
608 | if (!fid) | ||
609 | goto vout_isr_err; | ||
610 | break; | ||
611 | case OMAP_DISPLAY_TYPE_HDMI: | ||
612 | if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN)) | ||
613 | goto vout_isr_err; | ||
614 | break; | ||
615 | default: | ||
616 | goto vout_isr_err; | ||
617 | } | ||
579 | 618 | ||
580 | addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] | 619 | if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { |
581 | + vout->cropped_offset; | 620 | vout->cur_frm->ts = timevalue; |
621 | vout->cur_frm->state = VIDEOBUF_DONE; | ||
622 | wake_up_interruptible(&vout->cur_frm->done); | ||
623 | vout->cur_frm = vout->next_frm; | ||
624 | } | ||
582 | 625 | ||
583 | /* First save the configuration in ovelray structure */ | 626 | vout->first_int = 0; |
584 | ret = omapvid_init(vout, addr); | 627 | if (list_empty(&vout->dma_queue)) |
585 | if (ret) | 628 | goto vout_isr_err; |
586 | printk(KERN_ERR VOUT_NAME | ||
587 | "failed to set overlay info\n"); | ||
588 | /* Enable the pipeline and set the Go bit */ | ||
589 | ret = omapvid_apply_changes(vout); | ||
590 | if (ret) | ||
591 | printk(KERN_ERR VOUT_NAME "failed to change mode\n"); | ||
592 | } else { | ||
593 | 629 | ||
594 | if (vout->first_int) { | 630 | vout->next_frm = list_entry(vout->dma_queue.next, |
595 | vout->first_int = 0; | 631 | struct videobuf_buffer, queue); |
596 | goto vout_isr_err; | 632 | list_del(&vout->next_frm->queue); |
597 | } | ||
598 | if (irqstatus & DISPC_IRQ_EVSYNC_ODD) | ||
599 | fid = 1; | ||
600 | else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) | ||
601 | fid = 0; | ||
602 | else | ||
603 | goto vout_isr_err; | ||
604 | 633 | ||
605 | vout->field_id ^= 1; | 634 | vout->next_frm->state = VIDEOBUF_ACTIVE; |
606 | if (fid != vout->field_id) { | ||
607 | if (0 == fid) | ||
608 | vout->field_id = fid; | ||
609 | 635 | ||
610 | goto vout_isr_err; | 636 | addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] |
611 | } | 637 | + vout->cropped_offset; |
612 | if (0 == fid) { | ||
613 | if (vout->cur_frm == vout->next_frm) | ||
614 | goto vout_isr_err; | ||
615 | |||
616 | vout->cur_frm->ts = timevalue; | ||
617 | vout->cur_frm->state = VIDEOBUF_DONE; | ||
618 | wake_up_interruptible(&vout->cur_frm->done); | ||
619 | vout->cur_frm = vout->next_frm; | ||
620 | } else if (1 == fid) { | ||
621 | if (list_empty(&vout->dma_queue) || | ||
622 | (vout->cur_frm != vout->next_frm)) | ||
623 | goto vout_isr_err; | ||
624 | |||
625 | vout->next_frm = list_entry(vout->dma_queue.next, | ||
626 | struct videobuf_buffer, queue); | ||
627 | list_del(&vout->next_frm->queue); | ||
628 | |||
629 | vout->next_frm->state = VIDEOBUF_ACTIVE; | ||
630 | addr = (unsigned long) | ||
631 | vout->queued_buf_addr[vout->next_frm->i] + | ||
632 | vout->cropped_offset; | ||
633 | /* First save the configuration in ovelray structure */ | ||
634 | ret = omapvid_init(vout, addr); | ||
635 | if (ret) | ||
636 | printk(KERN_ERR VOUT_NAME | ||
637 | "failed to set overlay info\n"); | ||
638 | /* Enable the pipeline and set the Go bit */ | ||
639 | ret = omapvid_apply_changes(vout); | ||
640 | if (ret) | ||
641 | printk(KERN_ERR VOUT_NAME | ||
642 | "failed to change mode\n"); | ||
643 | } | ||
644 | 638 | ||
645 | } | 639 | /* First save the configuration in ovelray structure */ |
640 | ret = omapvid_init(vout, addr); | ||
641 | if (ret) | ||
642 | printk(KERN_ERR VOUT_NAME | ||
643 | "failed to set overlay info\n"); | ||
644 | /* Enable the pipeline and set the Go bit */ | ||
645 | ret = omapvid_apply_changes(vout); | ||
646 | if (ret) | ||
647 | printk(KERN_ERR VOUT_NAME "failed to change mode\n"); | ||
646 | 648 | ||
647 | vout_isr_err: | 649 | vout_isr_err: |
648 | spin_unlock(&vout->vbq_lock); | 650 | spin_unlock(&vout->vbq_lock); |
649 | } | 651 | } |
650 | 652 | ||
651 | |||
652 | /* Video buffer call backs */ | 653 | /* Video buffer call backs */ |
653 | 654 | ||
654 | /* | 655 | /* |
@@ -664,10 +665,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, | |||
664 | u32 phy_addr = 0, virt_addr = 0; | 665 | u32 phy_addr = 0, virt_addr = 0; |
665 | struct omap_vout_device *vout = q->priv_data; | 666 | struct omap_vout_device *vout = q->priv_data; |
666 | struct omapvideo_info *ovid = &vout->vid_info; | 667 | struct omapvideo_info *ovid = &vout->vid_info; |
668 | int vid_max_buf_size; | ||
667 | 669 | ||
668 | if (!vout) | 670 | if (!vout) |
669 | return -EINVAL; | 671 | return -EINVAL; |
670 | 672 | ||
673 | vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize : | ||
674 | video2_bufsize; | ||
675 | |||
671 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type) | 676 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type) |
672 | return -EINVAL; | 677 | return -EINVAL; |
673 | 678 | ||
@@ -690,7 +695,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, | |||
690 | video1_numbuffers : video2_numbuffers; | 695 | video1_numbuffers : video2_numbuffers; |
691 | 696 | ||
692 | /* Check the size of the buffer */ | 697 | /* Check the size of the buffer */ |
693 | if (*size > vout->buffer_size) { | 698 | if (*size > vid_max_buf_size) { |
694 | v4l2_err(&vout->vid_dev->v4l2_dev, | 699 | v4l2_err(&vout->vid_dev->v4l2_dev, |
695 | "buffer allocation mismatch [%u] [%u]\n", | 700 | "buffer allocation mismatch [%u] [%u]\n", |
696 | *size, vout->buffer_size); | 701 | *size, vout->buffer_size); |
diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h index d793501cafcc..27a95d23b913 100644 --- a/drivers/media/video/omap/omap_voutdef.h +++ b/drivers/media/video/omap/omap_voutdef.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #define MAC_VRFB_CTXS 4 | 25 | #define MAC_VRFB_CTXS 4 |
26 | #define MAX_VOUT_DEV 2 | 26 | #define MAX_VOUT_DEV 2 |
27 | #define MAX_OVLS 3 | 27 | #define MAX_OVLS 3 |
28 | #define MAX_DISPLAYS 3 | 28 | #define MAX_DISPLAYS 10 |
29 | #define MAX_MANAGERS 3 | 29 | #define MAX_MANAGERS 3 |
30 | 30 | ||
31 | #define QQVGA_WIDTH 160 | 31 | #define QQVGA_WIDTH 160 |
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index b818cacf420f..5cc15ba6a76a 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -410,6 +410,7 @@ static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus) | |||
410 | static void isp_isr_sbl(struct isp_device *isp) | 410 | static void isp_isr_sbl(struct isp_device *isp) |
411 | { | 411 | { |
412 | struct device *dev = isp->dev; | 412 | struct device *dev = isp->dev; |
413 | struct isp_pipeline *pipe; | ||
413 | u32 sbl_pcr; | 414 | u32 sbl_pcr; |
414 | 415 | ||
415 | /* | 416 | /* |
@@ -423,27 +424,38 @@ static void isp_isr_sbl(struct isp_device *isp) | |||
423 | if (sbl_pcr) | 424 | if (sbl_pcr) |
424 | dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr); | 425 | dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr); |
425 | 426 | ||
426 | if (sbl_pcr & (ISPSBL_PCR_CCDC_WBL_OVF | ISPSBL_PCR_CSIA_WBL_OVF | 427 | if (sbl_pcr & ISPSBL_PCR_CSIB_WBL_OVF) { |
427 | | ISPSBL_PCR_CSIB_WBL_OVF)) { | 428 | pipe = to_isp_pipeline(&isp->isp_ccp2.subdev.entity); |
428 | isp->isp_ccdc.error = 1; | 429 | if (pipe != NULL) |
429 | if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW) | 430 | pipe->error = true; |
430 | isp->isp_prev.error = 1; | 431 | } |
431 | if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER) | 432 | |
432 | isp->isp_res.error = 1; | 433 | if (sbl_pcr & ISPSBL_PCR_CSIA_WBL_OVF) { |
434 | pipe = to_isp_pipeline(&isp->isp_csi2a.subdev.entity); | ||
435 | if (pipe != NULL) | ||
436 | pipe->error = true; | ||
437 | } | ||
438 | |||
439 | if (sbl_pcr & ISPSBL_PCR_CCDC_WBL_OVF) { | ||
440 | pipe = to_isp_pipeline(&isp->isp_ccdc.subdev.entity); | ||
441 | if (pipe != NULL) | ||
442 | pipe->error = true; | ||
433 | } | 443 | } |
434 | 444 | ||
435 | if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) { | 445 | if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) { |
436 | isp->isp_prev.error = 1; | 446 | pipe = to_isp_pipeline(&isp->isp_prev.subdev.entity); |
437 | if (isp->isp_res.input == RESIZER_INPUT_VP && | 447 | if (pipe != NULL) |
438 | !(isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)) | 448 | pipe->error = true; |
439 | isp->isp_res.error = 1; | ||
440 | } | 449 | } |
441 | 450 | ||
442 | if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF | 451 | if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF |
443 | | ISPSBL_PCR_RSZ2_WBL_OVF | 452 | | ISPSBL_PCR_RSZ2_WBL_OVF |
444 | | ISPSBL_PCR_RSZ3_WBL_OVF | 453 | | ISPSBL_PCR_RSZ3_WBL_OVF |
445 | | ISPSBL_PCR_RSZ4_WBL_OVF)) | 454 | | ISPSBL_PCR_RSZ4_WBL_OVF)) { |
446 | isp->isp_res.error = 1; | 455 | pipe = to_isp_pipeline(&isp->isp_res.subdev.entity); |
456 | if (pipe != NULL) | ||
457 | pipe->error = true; | ||
458 | } | ||
447 | 459 | ||
448 | if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF) | 460 | if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF) |
449 | omap3isp_stat_sbl_overflow(&isp->isp_af); | 461 | omap3isp_stat_sbl_overflow(&isp->isp_af); |
@@ -471,24 +483,17 @@ static irqreturn_t isp_isr(int irq, void *_isp) | |||
471 | IRQ0STATUS_HS_VS_IRQ; | 483 | IRQ0STATUS_HS_VS_IRQ; |
472 | struct isp_device *isp = _isp; | 484 | struct isp_device *isp = _isp; |
473 | u32 irqstatus; | 485 | u32 irqstatus; |
474 | int ret; | ||
475 | 486 | ||
476 | irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | 487 | irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); |
477 | isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | 488 | isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); |
478 | 489 | ||
479 | isp_isr_sbl(isp); | 490 | isp_isr_sbl(isp); |
480 | 491 | ||
481 | if (irqstatus & IRQ0STATUS_CSIA_IRQ) { | 492 | if (irqstatus & IRQ0STATUS_CSIA_IRQ) |
482 | ret = omap3isp_csi2_isr(&isp->isp_csi2a); | 493 | omap3isp_csi2_isr(&isp->isp_csi2a); |
483 | if (ret) | ||
484 | isp->isp_ccdc.error = 1; | ||
485 | } | ||
486 | 494 | ||
487 | if (irqstatus & IRQ0STATUS_CSIB_IRQ) { | 495 | if (irqstatus & IRQ0STATUS_CSIB_IRQ) |
488 | ret = omap3isp_ccp2_isr(&isp->isp_ccp2); | 496 | omap3isp_ccp2_isr(&isp->isp_ccp2); |
489 | if (ret) | ||
490 | isp->isp_ccdc.error = 1; | ||
491 | } | ||
492 | 497 | ||
493 | if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) { | 498 | if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) { |
494 | if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW) | 499 | if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW) |
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index 54a4a3f22e2e..3663834ca94c 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c | |||
@@ -1406,9 +1406,8 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) | |||
1406 | 1406 | ||
1407 | static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc) | 1407 | static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc) |
1408 | { | 1408 | { |
1409 | struct isp_pipeline *pipe = | 1409 | struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity); |
1410 | to_isp_pipeline(&ccdc->video_out.video.entity); | 1410 | struct video_device *vdev = &ccdc->subdev.devnode; |
1411 | struct video_device *vdev = ccdc->subdev.devnode; | ||
1412 | struct v4l2_event event; | 1411 | struct v4l2_event event; |
1413 | 1412 | ||
1414 | memset(&event, 0, sizeof(event)); | 1413 | memset(&event, 0, sizeof(event)); |
@@ -1428,8 +1427,11 @@ static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events) | |||
1428 | unsigned long flags; | 1427 | unsigned long flags; |
1429 | 1428 | ||
1430 | if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) { | 1429 | if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) { |
1430 | struct isp_pipeline *pipe = | ||
1431 | to_isp_pipeline(&ccdc->subdev.entity); | ||
1432 | |||
1431 | ccdc_lsc_error_handler(ccdc); | 1433 | ccdc_lsc_error_handler(ccdc); |
1432 | ccdc->error = 1; | 1434 | pipe->error = true; |
1433 | dev_dbg(to_device(ccdc), "lsc prefetch error\n"); | 1435 | dev_dbg(to_device(ccdc), "lsc prefetch error\n"); |
1434 | } | 1436 | } |
1435 | 1437 | ||
@@ -1504,7 +1506,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) | |||
1504 | goto done; | 1506 | goto done; |
1505 | } | 1507 | } |
1506 | 1508 | ||
1507 | buffer = omap3isp_video_buffer_next(&ccdc->video_out, ccdc->error); | 1509 | buffer = omap3isp_video_buffer_next(&ccdc->video_out); |
1508 | if (buffer != NULL) { | 1510 | if (buffer != NULL) { |
1509 | ccdc_set_outaddr(ccdc, buffer->isp_addr); | 1511 | ccdc_set_outaddr(ccdc, buffer->isp_addr); |
1510 | restart = 1; | 1512 | restart = 1; |
@@ -1518,7 +1520,6 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) | |||
1518 | ISP_PIPELINE_STREAM_SINGLESHOT); | 1520 | ISP_PIPELINE_STREAM_SINGLESHOT); |
1519 | 1521 | ||
1520 | done: | 1522 | done: |
1521 | ccdc->error = 0; | ||
1522 | return restart; | 1523 | return restart; |
1523 | } | 1524 | } |
1524 | 1525 | ||
@@ -1744,7 +1745,6 @@ static int ccdc_set_stream(struct v4l2_subdev *sd, int enable) | |||
1744 | */ | 1745 | */ |
1745 | ccdc_config_vp(ccdc); | 1746 | ccdc_config_vp(ccdc); |
1746 | ccdc_enable_vp(ccdc, 1); | 1747 | ccdc_enable_vp(ccdc, 1); |
1747 | ccdc->error = 0; | ||
1748 | ccdc_print_status(ccdc); | 1748 | ccdc_print_status(ccdc); |
1749 | } | 1749 | } |
1750 | 1750 | ||
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h index 483a19cac1ad..6d0264bab75b 100644 --- a/drivers/media/video/omap3isp/ispccdc.h +++ b/drivers/media/video/omap3isp/ispccdc.h | |||
@@ -150,7 +150,6 @@ struct ispccdc_lsc { | |||
150 | * @input: Active input | 150 | * @input: Active input |
151 | * @output: Active outputs | 151 | * @output: Active outputs |
152 | * @video_out: Output video node | 152 | * @video_out: Output video node |
153 | * @error: A hardware error occurred during capture | ||
154 | * @alaw: A-law compression enabled (1) or disabled (0) | 153 | * @alaw: A-law compression enabled (1) or disabled (0) |
155 | * @lpf: Low pass filter enabled (1) or disabled (0) | 154 | * @lpf: Low pass filter enabled (1) or disabled (0) |
156 | * @obclamp: Optical-black clamp enabled (1) or disabled (0) | 155 | * @obclamp: Optical-black clamp enabled (1) or disabled (0) |
@@ -178,7 +177,6 @@ struct isp_ccdc_device { | |||
178 | enum ccdc_input_entity input; | 177 | enum ccdc_input_entity input; |
179 | unsigned int output; | 178 | unsigned int output; |
180 | struct isp_video video_out; | 179 | struct isp_video video_out; |
181 | unsigned int error; | ||
182 | 180 | ||
183 | unsigned int alaw:1, | 181 | unsigned int alaw:1, |
184 | lpf:1, | 182 | lpf:1, |
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c index 904ca8c8b17f..70ddbf35b223 100644 --- a/drivers/media/video/omap3isp/ispccp2.c +++ b/drivers/media/video/omap3isp/ispccp2.c | |||
@@ -556,7 +556,7 @@ static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2) | |||
556 | struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); | 556 | struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); |
557 | struct isp_buffer *buffer; | 557 | struct isp_buffer *buffer; |
558 | 558 | ||
559 | buffer = omap3isp_video_buffer_next(&ccp2->video_in, ccp2->error); | 559 | buffer = omap3isp_video_buffer_next(&ccp2->video_in); |
560 | if (buffer != NULL) | 560 | if (buffer != NULL) |
561 | ccp2_set_inaddr(ccp2, buffer->isp_addr); | 561 | ccp2_set_inaddr(ccp2, buffer->isp_addr); |
562 | 562 | ||
@@ -567,8 +567,6 @@ static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2) | |||
567 | omap3isp_pipeline_set_stream(pipe, | 567 | omap3isp_pipeline_set_stream(pipe, |
568 | ISP_PIPELINE_STREAM_SINGLESHOT); | 568 | ISP_PIPELINE_STREAM_SINGLESHOT); |
569 | } | 569 | } |
570 | |||
571 | ccp2->error = 0; | ||
572 | } | 570 | } |
573 | 571 | ||
574 | /* | 572 | /* |
@@ -576,13 +574,11 @@ static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2) | |||
576 | * @ccp2: Pointer to ISP CCP2 device | 574 | * @ccp2: Pointer to ISP CCP2 device |
577 | * | 575 | * |
578 | * This will handle the CCP2 interrupts | 576 | * This will handle the CCP2 interrupts |
579 | * | ||
580 | * Returns -EIO in case of error, or 0 on success. | ||
581 | */ | 577 | */ |
582 | int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2) | 578 | void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2) |
583 | { | 579 | { |
580 | struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); | ||
584 | struct isp_device *isp = to_isp_device(ccp2); | 581 | struct isp_device *isp = to_isp_device(ccp2); |
585 | int ret = 0; | ||
586 | static const u32 ISPCCP2_LC01_ERROR = | 582 | static const u32 ISPCCP2_LC01_ERROR = |
587 | ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ | | 583 | ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ | |
588 | ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ | | 584 | ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ | |
@@ -604,19 +600,18 @@ int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2) | |||
604 | ISPCCP2_LCM_IRQSTATUS); | 600 | ISPCCP2_LCM_IRQSTATUS); |
605 | /* Errors */ | 601 | /* Errors */ |
606 | if (lcx_irqstatus & ISPCCP2_LC01_ERROR) { | 602 | if (lcx_irqstatus & ISPCCP2_LC01_ERROR) { |
607 | ccp2->error = 1; | 603 | pipe->error = true; |
608 | dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus); | 604 | dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus); |
609 | return -EIO; | 605 | return; |
610 | } | 606 | } |
611 | 607 | ||
612 | if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) { | 608 | if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) { |
613 | ccp2->error = 1; | 609 | pipe->error = true; |
614 | dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus); | 610 | dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus); |
615 | ret = -EIO; | ||
616 | } | 611 | } |
617 | 612 | ||
618 | if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping)) | 613 | if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping)) |
619 | return 0; | 614 | return; |
620 | 615 | ||
621 | /* Frame number propagation */ | 616 | /* Frame number propagation */ |
622 | if (lcx_irqstatus & ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ) { | 617 | if (lcx_irqstatus & ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ) { |
@@ -629,8 +624,6 @@ int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2) | |||
629 | /* Handle queued buffers on frame end interrupts */ | 624 | /* Handle queued buffers on frame end interrupts */ |
630 | if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ) | 625 | if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ) |
631 | ccp2_isr_buffer(ccp2); | 626 | ccp2_isr_buffer(ccp2); |
632 | |||
633 | return ret; | ||
634 | } | 627 | } |
635 | 628 | ||
636 | /* ----------------------------------------------------------------------------- | 629 | /* ----------------------------------------------------------------------------- |
@@ -867,7 +860,6 @@ static int ccp2_s_stream(struct v4l2_subdev *sd, int enable) | |||
867 | if (enable == ISP_PIPELINE_STREAM_STOPPED) | 860 | if (enable == ISP_PIPELINE_STREAM_STOPPED) |
868 | return 0; | 861 | return 0; |
869 | atomic_set(&ccp2->stopping, 0); | 862 | atomic_set(&ccp2->stopping, 0); |
870 | ccp2->error = 0; | ||
871 | } | 863 | } |
872 | 864 | ||
873 | switch (enable) { | 865 | switch (enable) { |
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/video/omap3isp/ispccp2.h index 6674e9de2cd7..76d65f4576ef 100644 --- a/drivers/media/video/omap3isp/ispccp2.h +++ b/drivers/media/video/omap3isp/ispccp2.h | |||
@@ -82,7 +82,6 @@ struct isp_ccp2_device { | |||
82 | struct isp_video video_in; | 82 | struct isp_video video_in; |
83 | struct isp_csiphy *phy; | 83 | struct isp_csiphy *phy; |
84 | struct regulator *vdds_csib; | 84 | struct regulator *vdds_csib; |
85 | unsigned int error; | ||
86 | enum isp_pipeline_stream_state state; | 85 | enum isp_pipeline_stream_state state; |
87 | wait_queue_head_t wait; | 86 | wait_queue_head_t wait; |
88 | atomic_t stopping; | 87 | atomic_t stopping; |
@@ -94,6 +93,6 @@ void omap3isp_ccp2_cleanup(struct isp_device *isp); | |||
94 | int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2, | 93 | int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2, |
95 | struct v4l2_device *vdev); | 94 | struct v4l2_device *vdev); |
96 | void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2); | 95 | void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2); |
97 | int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2); | 96 | void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2); |
98 | 97 | ||
99 | #endif /* OMAP3_ISP_CCP2_H */ | 98 | #endif /* OMAP3_ISP_CCP2_H */ |
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c index 0c5f1cb9d99d..fcb5168996a7 100644 --- a/drivers/media/video/omap3isp/ispcsi2.c +++ b/drivers/media/video/omap3isp/ispcsi2.c | |||
@@ -667,7 +667,7 @@ static void csi2_isr_buffer(struct isp_csi2_device *csi2) | |||
667 | 667 | ||
668 | csi2_ctx_enable(isp, csi2, 0, 0); | 668 | csi2_ctx_enable(isp, csi2, 0, 0); |
669 | 669 | ||
670 | buffer = omap3isp_video_buffer_next(&csi2->video_out, 0); | 670 | buffer = omap3isp_video_buffer_next(&csi2->video_out); |
671 | 671 | ||
672 | /* | 672 | /* |
673 | * Let video queue operation restart engine if there is an underrun | 673 | * Let video queue operation restart engine if there is an underrun |
@@ -727,17 +727,15 @@ static void csi2_isr_ctx(struct isp_csi2_device *csi2, | |||
727 | 727 | ||
728 | /* | 728 | /* |
729 | * omap3isp_csi2_isr - CSI2 interrupt handling. | 729 | * omap3isp_csi2_isr - CSI2 interrupt handling. |
730 | * | ||
731 | * Return -EIO on Transmission error | ||
732 | */ | 730 | */ |
733 | int omap3isp_csi2_isr(struct isp_csi2_device *csi2) | 731 | void omap3isp_csi2_isr(struct isp_csi2_device *csi2) |
734 | { | 732 | { |
733 | struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); | ||
735 | u32 csi2_irqstatus, cpxio1_irqstatus; | 734 | u32 csi2_irqstatus, cpxio1_irqstatus; |
736 | struct isp_device *isp = csi2->isp; | 735 | struct isp_device *isp = csi2->isp; |
737 | int retval = 0; | ||
738 | 736 | ||
739 | if (!csi2->available) | 737 | if (!csi2->available) |
740 | return -ENODEV; | 738 | return; |
741 | 739 | ||
742 | csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS); | 740 | csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS); |
743 | isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS); | 741 | isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS); |
@@ -750,7 +748,7 @@ int omap3isp_csi2_isr(struct isp_csi2_device *csi2) | |||
750 | csi2->regs1, ISPCSI2_PHY_IRQSTATUS); | 748 | csi2->regs1, ISPCSI2_PHY_IRQSTATUS); |
751 | dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ " | 749 | dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ " |
752 | "%x\n", cpxio1_irqstatus); | 750 | "%x\n", cpxio1_irqstatus); |
753 | retval = -EIO; | 751 | pipe->error = true; |
754 | } | 752 | } |
755 | 753 | ||
756 | if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ | | 754 | if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ | |
@@ -775,11 +773,11 @@ int omap3isp_csi2_isr(struct isp_csi2_device *csi2) | |||
775 | ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0, | 773 | ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0, |
776 | (csi2_irqstatus & | 774 | (csi2_irqstatus & |
777 | ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0); | 775 | ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0); |
778 | retval = -EIO; | 776 | pipe->error = true; |
779 | } | 777 | } |
780 | 778 | ||
781 | if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping)) | 779 | if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping)) |
782 | return 0; | 780 | return; |
783 | 781 | ||
784 | /* Successful cases */ | 782 | /* Successful cases */ |
785 | if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) | 783 | if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) |
@@ -787,8 +785,6 @@ int omap3isp_csi2_isr(struct isp_csi2_device *csi2) | |||
787 | 785 | ||
788 | if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ) | 786 | if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ) |
789 | dev_dbg(isp->dev, "CSI2: ECC correction done\n"); | 787 | dev_dbg(isp->dev, "CSI2: ECC correction done\n"); |
790 | |||
791 | return retval; | ||
792 | } | 788 | } |
793 | 789 | ||
794 | /* ----------------------------------------------------------------------------- | 790 | /* ----------------------------------------------------------------------------- |
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h index 456fb7fb8a0f..885ad79a7678 100644 --- a/drivers/media/video/omap3isp/ispcsi2.h +++ b/drivers/media/video/omap3isp/ispcsi2.h | |||
@@ -156,7 +156,7 @@ struct isp_csi2_device { | |||
156 | atomic_t stopping; | 156 | atomic_t stopping; |
157 | }; | 157 | }; |
158 | 158 | ||
159 | int omap3isp_csi2_isr(struct isp_csi2_device *csi2); | 159 | void omap3isp_csi2_isr(struct isp_csi2_device *csi2); |
160 | int omap3isp_csi2_reset(struct isp_csi2_device *csi2); | 160 | int omap3isp_csi2_reset(struct isp_csi2_device *csi2); |
161 | int omap3isp_csi2_init(struct isp_device *isp); | 161 | int omap3isp_csi2_init(struct isp_device *isp); |
162 | void omap3isp_csi2_cleanup(struct isp_device *isp); | 162 | void omap3isp_csi2_cleanup(struct isp_device *isp); |
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c index ccb876fe023f..6d0fb2c8c26d 100644 --- a/drivers/media/video/omap3isp/isppreview.c +++ b/drivers/media/video/omap3isp/isppreview.c | |||
@@ -116,11 +116,11 @@ static struct omap3isp_prev_csc flr_prev_csc = { | |||
116 | #define PREV_MIN_IN_HEIGHT 8 | 116 | #define PREV_MIN_IN_HEIGHT 8 |
117 | #define PREV_MAX_IN_HEIGHT 16384 | 117 | #define PREV_MAX_IN_HEIGHT 16384 |
118 | 118 | ||
119 | #define PREV_MIN_OUT_WIDTH 0 | 119 | #define PREV_MIN_OUT_WIDTH 0 |
120 | #define PREV_MIN_OUT_HEIGHT 0 | 120 | #define PREV_MIN_OUT_HEIGHT 0 |
121 | #define PREV_MAX_OUT_WIDTH 1280 | 121 | #define PREV_MAX_OUT_WIDTH_REV_1 1280 |
122 | #define PREV_MAX_OUT_WIDTH_ES2 3300 | 122 | #define PREV_MAX_OUT_WIDTH_REV_2 3300 |
123 | #define PREV_MAX_OUT_WIDTH_3630 4096 | 123 | #define PREV_MAX_OUT_WIDTH_REV_15 4096 |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * Coeficient Tables for the submodules in Preview. | 126 | * Coeficient Tables for the submodules in Preview. |
@@ -1306,14 +1306,14 @@ static unsigned int preview_max_out_width(struct isp_prev_device *prev) | |||
1306 | 1306 | ||
1307 | switch (isp->revision) { | 1307 | switch (isp->revision) { |
1308 | case ISP_REVISION_1_0: | 1308 | case ISP_REVISION_1_0: |
1309 | return PREV_MAX_OUT_WIDTH; | 1309 | return PREV_MAX_OUT_WIDTH_REV_1; |
1310 | 1310 | ||
1311 | case ISP_REVISION_2_0: | 1311 | case ISP_REVISION_2_0: |
1312 | default: | 1312 | default: |
1313 | return PREV_MAX_OUT_WIDTH_ES2; | 1313 | return PREV_MAX_OUT_WIDTH_REV_2; |
1314 | 1314 | ||
1315 | case ISP_REVISION_15_0: | 1315 | case ISP_REVISION_15_0: |
1316 | return PREV_MAX_OUT_WIDTH_3630; | 1316 | return PREV_MAX_OUT_WIDTH_REV_15; |
1317 | } | 1317 | } |
1318 | } | 1318 | } |
1319 | 1319 | ||
@@ -1404,16 +1404,14 @@ static void preview_isr_buffer(struct isp_prev_device *prev) | |||
1404 | int restart = 0; | 1404 | int restart = 0; |
1405 | 1405 | ||
1406 | if (prev->input == PREVIEW_INPUT_MEMORY) { | 1406 | if (prev->input == PREVIEW_INPUT_MEMORY) { |
1407 | buffer = omap3isp_video_buffer_next(&prev->video_in, | 1407 | buffer = omap3isp_video_buffer_next(&prev->video_in); |
1408 | prev->error); | ||
1409 | if (buffer != NULL) | 1408 | if (buffer != NULL) |
1410 | preview_set_inaddr(prev, buffer->isp_addr); | 1409 | preview_set_inaddr(prev, buffer->isp_addr); |
1411 | pipe->state |= ISP_PIPELINE_IDLE_INPUT; | 1410 | pipe->state |= ISP_PIPELINE_IDLE_INPUT; |
1412 | } | 1411 | } |
1413 | 1412 | ||
1414 | if (prev->output & PREVIEW_OUTPUT_MEMORY) { | 1413 | if (prev->output & PREVIEW_OUTPUT_MEMORY) { |
1415 | buffer = omap3isp_video_buffer_next(&prev->video_out, | 1414 | buffer = omap3isp_video_buffer_next(&prev->video_out); |
1416 | prev->error); | ||
1417 | if (buffer != NULL) { | 1415 | if (buffer != NULL) { |
1418 | preview_set_outaddr(prev, buffer->isp_addr); | 1416 | preview_set_outaddr(prev, buffer->isp_addr); |
1419 | restart = 1; | 1417 | restart = 1; |
@@ -1440,8 +1438,6 @@ static void preview_isr_buffer(struct isp_prev_device *prev) | |||
1440 | default: | 1438 | default: |
1441 | return; | 1439 | return; |
1442 | } | 1440 | } |
1443 | |||
1444 | prev->error = 0; | ||
1445 | } | 1441 | } |
1446 | 1442 | ||
1447 | /* | 1443 | /* |
@@ -1565,7 +1561,6 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable) | |||
1565 | omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW); | 1561 | omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW); |
1566 | preview_configure(prev); | 1562 | preview_configure(prev); |
1567 | atomic_set(&prev->stopping, 0); | 1563 | atomic_set(&prev->stopping, 0); |
1568 | prev->error = 0; | ||
1569 | preview_print_status(prev); | 1564 | preview_print_status(prev); |
1570 | } | 1565 | } |
1571 | 1566 | ||
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h index f54e775c2df4..09686607973c 100644 --- a/drivers/media/video/omap3isp/isppreview.h +++ b/drivers/media/video/omap3isp/isppreview.h | |||
@@ -157,7 +157,6 @@ struct isptables_update { | |||
157 | * @output: Bitmask of the active output | 157 | * @output: Bitmask of the active output |
158 | * @video_in: Input video entity | 158 | * @video_in: Input video entity |
159 | * @video_out: Output video entity | 159 | * @video_out: Output video entity |
160 | * @error: A hardware error occurred during capture | ||
161 | * @params: Module configuration data | 160 | * @params: Module configuration data |
162 | * @shadow_update: If set, update the hardware configured in the next interrupt | 161 | * @shadow_update: If set, update the hardware configured in the next interrupt |
163 | * @underrun: Whether the preview entity has queued buffers on the output | 162 | * @underrun: Whether the preview entity has queued buffers on the output |
@@ -179,7 +178,6 @@ struct isp_prev_device { | |||
179 | unsigned int output; | 178 | unsigned int output; |
180 | struct isp_video video_in; | 179 | struct isp_video video_in; |
181 | struct isp_video video_out; | 180 | struct isp_video video_out; |
182 | unsigned int error; | ||
183 | 181 | ||
184 | struct prev_params params; | 182 | struct prev_params params; |
185 | unsigned int shadow_update:1; | 183 | unsigned int shadow_update:1; |
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c index 50e593bfcfaf..6958a9e3dc22 100644 --- a/drivers/media/video/omap3isp/ispresizer.c +++ b/drivers/media/video/omap3isp/ispresizer.c | |||
@@ -1038,7 +1038,7 @@ static void resizer_isr_buffer(struct isp_res_device *res) | |||
1038 | /* Complete the output buffer and, if reading from memory, the input | 1038 | /* Complete the output buffer and, if reading from memory, the input |
1039 | * buffer. | 1039 | * buffer. |
1040 | */ | 1040 | */ |
1041 | buffer = omap3isp_video_buffer_next(&res->video_out, res->error); | 1041 | buffer = omap3isp_video_buffer_next(&res->video_out); |
1042 | if (buffer != NULL) { | 1042 | if (buffer != NULL) { |
1043 | resizer_set_outaddr(res, buffer->isp_addr); | 1043 | resizer_set_outaddr(res, buffer->isp_addr); |
1044 | restart = 1; | 1044 | restart = 1; |
@@ -1047,7 +1047,7 @@ static void resizer_isr_buffer(struct isp_res_device *res) | |||
1047 | pipe->state |= ISP_PIPELINE_IDLE_OUTPUT; | 1047 | pipe->state |= ISP_PIPELINE_IDLE_OUTPUT; |
1048 | 1048 | ||
1049 | if (res->input == RESIZER_INPUT_MEMORY) { | 1049 | if (res->input == RESIZER_INPUT_MEMORY) { |
1050 | buffer = omap3isp_video_buffer_next(&res->video_in, 0); | 1050 | buffer = omap3isp_video_buffer_next(&res->video_in); |
1051 | if (buffer != NULL) | 1051 | if (buffer != NULL) |
1052 | resizer_set_inaddr(res, buffer->isp_addr); | 1052 | resizer_set_inaddr(res, buffer->isp_addr); |
1053 | pipe->state |= ISP_PIPELINE_IDLE_INPUT; | 1053 | pipe->state |= ISP_PIPELINE_IDLE_INPUT; |
@@ -1064,8 +1064,6 @@ static void resizer_isr_buffer(struct isp_res_device *res) | |||
1064 | if (restart) | 1064 | if (restart) |
1065 | resizer_enable_oneshot(res); | 1065 | resizer_enable_oneshot(res); |
1066 | } | 1066 | } |
1067 | |||
1068 | res->error = 0; | ||
1069 | } | 1067 | } |
1070 | 1068 | ||
1071 | /* | 1069 | /* |
@@ -1154,7 +1152,6 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable) | |||
1154 | 1152 | ||
1155 | omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER); | 1153 | omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER); |
1156 | resizer_configure(res); | 1154 | resizer_configure(res); |
1157 | res->error = 0; | ||
1158 | resizer_print_status(res); | 1155 | resizer_print_status(res); |
1159 | } | 1156 | } |
1160 | 1157 | ||
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/video/omap3isp/ispresizer.h index 76abc2e42126..70c1c0e1bbdf 100644 --- a/drivers/media/video/omap3isp/ispresizer.h +++ b/drivers/media/video/omap3isp/ispresizer.h | |||
@@ -107,7 +107,6 @@ struct isp_res_device { | |||
107 | enum resizer_input_entity input; | 107 | enum resizer_input_entity input; |
108 | struct isp_video video_in; | 108 | struct isp_video video_in; |
109 | struct isp_video video_out; | 109 | struct isp_video video_out; |
110 | unsigned int error; | ||
111 | 110 | ||
112 | u32 addr_base; /* stored source buffer address in memory mode */ | 111 | u32 addr_base; /* stored source buffer address in memory mode */ |
113 | u32 crop_offset; /* additional offset for crop in memory mode */ | 112 | u32 crop_offset; /* additional offset for crop in memory mode */ |
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index f2290578448c..615dae58942b 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c | |||
@@ -211,14 +211,14 @@ static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix, | |||
211 | mbus->width = pix->width; | 211 | mbus->width = pix->width; |
212 | mbus->height = pix->height; | 212 | mbus->height = pix->height; |
213 | 213 | ||
214 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | 214 | /* Skip the last format in the loop so that it will be selected if no |
215 | * match is found. | ||
216 | */ | ||
217 | for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) { | ||
215 | if (formats[i].pixelformat == pix->pixelformat) | 218 | if (formats[i].pixelformat == pix->pixelformat) |
216 | break; | 219 | break; |
217 | } | 220 | } |
218 | 221 | ||
219 | if (WARN_ON(i == ARRAY_SIZE(formats))) | ||
220 | return; | ||
221 | |||
222 | mbus->code = formats[i].code; | 222 | mbus->code = formats[i].code; |
223 | mbus->colorspace = pix->colorspace; | 223 | mbus->colorspace = pix->colorspace; |
224 | mbus->field = pix->field; | 224 | mbus->field = pix->field; |
@@ -581,21 +581,20 @@ static const struct isp_video_queue_operations isp_video_queue_ops = { | |||
581 | /* | 581 | /* |
582 | * omap3isp_video_buffer_next - Complete the current buffer and return the next | 582 | * omap3isp_video_buffer_next - Complete the current buffer and return the next |
583 | * @video: ISP video object | 583 | * @video: ISP video object |
584 | * @error: Whether an error occurred during capture | ||
585 | * | 584 | * |
586 | * Remove the current video buffer from the DMA queue and fill its timestamp, | 585 | * Remove the current video buffer from the DMA queue and fill its timestamp, |
587 | * field count and state fields before waking up its completion handler. | 586 | * field count and state fields before waking up its completion handler. |
588 | * | 587 | * |
589 | * The buffer state is set to VIDEOBUF_DONE if no error occurred (@error is 0) | 588 | * For capture video nodes the buffer state is set to ISP_BUF_STATE_DONE if no |
590 | * or VIDEOBUF_ERROR otherwise (@error is non-zero). | 589 | * error has been flagged in the pipeline, or to ISP_BUF_STATE_ERROR otherwise. |
590 | * For video output nodes the buffer state is always set to ISP_BUF_STATE_DONE. | ||
591 | * | 591 | * |
592 | * The DMA queue is expected to contain at least one buffer. | 592 | * The DMA queue is expected to contain at least one buffer. |
593 | * | 593 | * |
594 | * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is | 594 | * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is |
595 | * empty. | 595 | * empty. |
596 | */ | 596 | */ |
597 | struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video, | 597 | struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video) |
598 | unsigned int error) | ||
599 | { | 598 | { |
600 | struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity); | 599 | struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity); |
601 | struct isp_video_queue *queue = video->queue; | 600 | struct isp_video_queue *queue = video->queue; |
@@ -630,7 +629,13 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video, | |||
630 | else | 629 | else |
631 | buf->vbuf.sequence = atomic_read(&pipe->frame_number); | 630 | buf->vbuf.sequence = atomic_read(&pipe->frame_number); |
632 | 631 | ||
633 | buf->state = error ? ISP_BUF_STATE_ERROR : ISP_BUF_STATE_DONE; | 632 | /* Report pipeline errors to userspace on the capture device side. */ |
633 | if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) { | ||
634 | buf->state = ISP_BUF_STATE_ERROR; | ||
635 | pipe->error = false; | ||
636 | } else { | ||
637 | buf->state = ISP_BUF_STATE_DONE; | ||
638 | } | ||
634 | 639 | ||
635 | wake_up(&buf->wait); | 640 | wake_up(&buf->wait); |
636 | 641 | ||
@@ -1016,6 +1021,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1016 | if (ret < 0) | 1021 | if (ret < 0) |
1017 | goto error; | 1022 | goto error; |
1018 | 1023 | ||
1024 | pipe->error = false; | ||
1025 | |||
1019 | spin_lock_irqsave(&pipe->lock, flags); | 1026 | spin_lock_irqsave(&pipe->lock, flags); |
1020 | pipe->state &= ~ISP_PIPELINE_STREAM; | 1027 | pipe->state &= ~ISP_PIPELINE_STREAM; |
1021 | pipe->state |= state; | 1028 | pipe->state |= state; |
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h index 08cbfa144e6e..d91bdb919be0 100644 --- a/drivers/media/video/omap3isp/ispvideo.h +++ b/drivers/media/video/omap3isp/ispvideo.h | |||
@@ -85,6 +85,10 @@ enum isp_pipeline_state { | |||
85 | ISP_PIPELINE_STREAM = 64, | 85 | ISP_PIPELINE_STREAM = 64, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* | ||
89 | * struct isp_pipeline - An ISP hardware pipeline | ||
90 | * @error: A hardware error occurred during capture | ||
91 | */ | ||
88 | struct isp_pipeline { | 92 | struct isp_pipeline { |
89 | struct media_pipeline pipe; | 93 | struct media_pipeline pipe; |
90 | spinlock_t lock; /* Pipeline state and queue flags */ | 94 | spinlock_t lock; /* Pipeline state and queue flags */ |
@@ -96,6 +100,7 @@ struct isp_pipeline { | |||
96 | unsigned int max_rate; | 100 | unsigned int max_rate; |
97 | atomic_t frame_number; | 101 | atomic_t frame_number; |
98 | bool do_propagation; /* of frame number */ | 102 | bool do_propagation; /* of frame number */ |
103 | bool error; | ||
99 | struct v4l2_fract max_timeperframe; | 104 | struct v4l2_fract max_timeperframe; |
100 | }; | 105 | }; |
101 | 106 | ||
@@ -194,8 +199,7 @@ void omap3isp_video_cleanup(struct isp_video *video); | |||
194 | int omap3isp_video_register(struct isp_video *video, | 199 | int omap3isp_video_register(struct isp_video *video, |
195 | struct v4l2_device *vdev); | 200 | struct v4l2_device *vdev); |
196 | void omap3isp_video_unregister(struct isp_video *video); | 201 | void omap3isp_video_unregister(struct isp_video *video); |
197 | struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video, | 202 | struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video); |
198 | unsigned int error); | ||
199 | void omap3isp_video_resume(struct isp_video *video, int continuous); | 203 | void omap3isp_video_resume(struct isp_video *video, int continuous); |
200 | struct media_pad *omap3isp_video_remote_pad(struct isp_video *video); | 204 | struct media_pad *omap3isp_video_remote_pad(struct isp_video *video); |
201 | 205 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 122b45760f0d..ebc2c7e39233 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -2546,8 +2546,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2546 | } | 2546 | } |
2547 | 2547 | ||
2548 | /* Define and configure additional controls from cx2341x module. */ | 2548 | /* Define and configure additional controls from cx2341x module. */ |
2549 | hdw->mpeg_ctrl_info = kzalloc( | 2549 | hdw->mpeg_ctrl_info = kcalloc(MPEGDEF_COUNT, |
2550 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); | 2550 | sizeof(*(hdw->mpeg_ctrl_info)), |
2551 | GFP_KERNEL); | ||
2551 | if (!hdw->mpeg_ctrl_info) goto fail; | 2552 | if (!hdw->mpeg_ctrl_info) goto fail; |
2552 | for (idx = 0; idx < MPEGDEF_COUNT; idx++) { | 2553 | for (idx = 0; idx < MPEGDEF_COUNT; idx++) { |
2553 | cptr = hdw->controls + idx + CTRLDEF_COUNT; | 2554 | cptr = hdw->controls + idx + CTRLDEF_COUNT; |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 3977addf3ba8..b42c239de9cf 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -113,10 +113,9 @@ static int _send_control_msg(struct pwc_device *pdev, | |||
113 | void *kbuf = NULL; | 113 | void *kbuf = NULL; |
114 | 114 | ||
115 | if (buflen) { | 115 | if (buflen) { |
116 | kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */ | 116 | kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */ |
117 | if (kbuf == NULL) | 117 | if (kbuf == NULL) |
118 | return -ENOMEM; | 118 | return -ENOMEM; |
119 | memcpy(kbuf, buf, buflen); | ||
120 | } | 119 | } |
121 | 120 | ||
122 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | 121 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), |
diff --git a/drivers/media/video/s5p-g2d/Makefile b/drivers/media/video/s5p-g2d/Makefile new file mode 100644 index 000000000000..2c48c416a804 --- /dev/null +++ b/drivers/media/video/s5p-g2d/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | s5p-g2d-objs := g2d.o g2d-hw.o | ||
2 | |||
3 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d.o | ||
diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c new file mode 100644 index 000000000000..39937cf03c88 --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d-hw.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Samsung S5P G2D - 2D Graphics Accelerator Driver | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
5 | * Kamil Debski, <k.debski@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version | ||
11 | */ | ||
12 | |||
13 | #include <linux/io.h> | ||
14 | |||
15 | #include "g2d.h" | ||
16 | #include "g2d-regs.h" | ||
17 | |||
18 | #define w(x, a) writel((x), d->regs + (a)) | ||
19 | #define r(a) readl(d->regs + (a)) | ||
20 | |||
21 | /* g2d_reset clears all g2d registers */ | ||
22 | void g2d_reset(struct g2d_dev *d) | ||
23 | { | ||
24 | w(1, SOFT_RESET_REG); | ||
25 | } | ||
26 | |||
27 | void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f) | ||
28 | { | ||
29 | u32 n; | ||
30 | |||
31 | w(f->stride & 0xFFFF, SRC_STRIDE_REG); | ||
32 | |||
33 | n = f->o_height & 0xFFF; | ||
34 | n <<= 16; | ||
35 | n |= f->o_width & 0xFFF; | ||
36 | w(n, SRC_LEFT_TOP_REG); | ||
37 | |||
38 | n = f->bottom & 0xFFF; | ||
39 | n <<= 16; | ||
40 | n |= f->right & 0xFFF; | ||
41 | w(n, SRC_RIGHT_BOTTOM_REG); | ||
42 | |||
43 | w(f->fmt->hw, SRC_COLOR_MODE_REG); | ||
44 | } | ||
45 | |||
46 | void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a) | ||
47 | { | ||
48 | w(a, SRC_BASE_ADDR_REG); | ||
49 | } | ||
50 | |||
51 | void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f) | ||
52 | { | ||
53 | u32 n; | ||
54 | |||
55 | w(f->stride & 0xFFFF, DST_STRIDE_REG); | ||
56 | |||
57 | n = f->o_height & 0xFFF; | ||
58 | n <<= 16; | ||
59 | n |= f->o_width & 0xFFF; | ||
60 | w(n, DST_LEFT_TOP_REG); | ||
61 | |||
62 | n = f->bottom & 0xFFF; | ||
63 | n <<= 16; | ||
64 | n |= f->right & 0xFFF; | ||
65 | w(n, DST_RIGHT_BOTTOM_REG); | ||
66 | |||
67 | w(f->fmt->hw, DST_COLOR_MODE_REG); | ||
68 | } | ||
69 | |||
70 | void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a) | ||
71 | { | ||
72 | w(a, DST_BASE_ADDR_REG); | ||
73 | } | ||
74 | |||
75 | void g2d_set_rop4(struct g2d_dev *d, u32 r) | ||
76 | { | ||
77 | w(r, ROP4_REG); | ||
78 | } | ||
79 | |||
80 | u32 g2d_cmd_stretch(u32 e) | ||
81 | { | ||
82 | e &= 1; | ||
83 | return e << 4; | ||
84 | } | ||
85 | |||
86 | void g2d_set_cmd(struct g2d_dev *d, u32 c) | ||
87 | { | ||
88 | w(c, BITBLT_COMMAND_REG); | ||
89 | } | ||
90 | |||
91 | void g2d_start(struct g2d_dev *d) | ||
92 | { | ||
93 | /* Clear cache */ | ||
94 | w(0x7, CACHECTL_REG); | ||
95 | /* Enable interrupt */ | ||
96 | w(1, INTEN_REG); | ||
97 | /* Start G2D engine */ | ||
98 | w(1, BITBLT_START_REG); | ||
99 | } | ||
100 | |||
101 | void g2d_clear_int(struct g2d_dev *d) | ||
102 | { | ||
103 | w(1, INTC_PEND_REG); | ||
104 | } | ||
diff --git a/drivers/media/video/s5p-g2d/g2d-regs.h b/drivers/media/video/s5p-g2d/g2d-regs.h new file mode 100644 index 000000000000..02e1cf50da4e --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d-regs.h | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * Samsung S5P G2D - 2D Graphics Accelerator Driver | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
5 | * Kamil Debski, <k.debski@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version | ||
11 | */ | ||
12 | |||
13 | /* General Registers */ | ||
14 | #define SOFT_RESET_REG 0x0000 /* Software reset reg */ | ||
15 | #define INTEN_REG 0x0004 /* Interrupt Enable reg */ | ||
16 | #define INTC_PEND_REG 0x000C /* Interrupt Control Pending reg */ | ||
17 | #define FIFO_STAT_REG 0x0010 /* Command FIFO Status reg */ | ||
18 | #define AXI_ID_MODE_REG 0x0014 /* AXI Read ID Mode reg */ | ||
19 | #define CACHECTL_REG 0x0018 /* Cache & Buffer clear reg */ | ||
20 | #define AXI_MODE_REG 0x001C /* AXI Mode reg */ | ||
21 | |||
22 | /* Command Registers */ | ||
23 | #define BITBLT_START_REG 0x0100 /* BitBLT Start reg */ | ||
24 | #define BITBLT_COMMAND_REG 0x0104 /* Command reg for BitBLT */ | ||
25 | |||
26 | /* Parameter Setting Registers (Rotate & Direction) */ | ||
27 | #define ROTATE_REG 0x0200 /* Rotation reg */ | ||
28 | #define SRC_MSK_DIRECT_REG 0x0204 /* Src and Mask Direction reg */ | ||
29 | #define DST_PAT_DIRECT_REG 0x0208 /* Dest and Pattern Direction reg */ | ||
30 | |||
31 | /* Parameter Setting Registers (Src) */ | ||
32 | #define SRC_SELECT_REG 0x0300 /* Src Image Selection reg */ | ||
33 | #define SRC_BASE_ADDR_REG 0x0304 /* Src Image Base Address reg */ | ||
34 | #define SRC_STRIDE_REG 0x0308 /* Src Stride reg */ | ||
35 | #define SRC_COLOR_MODE_REG 0x030C /* Src Image Color Mode reg */ | ||
36 | #define SRC_LEFT_TOP_REG 0x0310 /* Src Left Top Coordinate reg */ | ||
37 | #define SRC_RIGHT_BOTTOM_REG 0x0314 /* Src Right Bottom Coordinate reg */ | ||
38 | |||
39 | /* Parameter Setting Registers (Dest) */ | ||
40 | #define DST_SELECT_REG 0x0400 /* Dest Image Selection reg */ | ||
41 | #define DST_BASE_ADDR_REG 0x0404 /* Dest Image Base Address reg */ | ||
42 | #define DST_STRIDE_REG 0x0408 /* Dest Stride reg */ | ||
43 | #define DST_COLOR_MODE_REG 0x040C /* Dest Image Color Mode reg */ | ||
44 | #define DST_LEFT_TOP_REG 0x0410 /* Dest Left Top Coordinate reg */ | ||
45 | #define DST_RIGHT_BOTTOM_REG 0x0414 /* Dest Right Bottom Coordinate reg */ | ||
46 | |||
47 | /* Parameter Setting Registers (Pattern) */ | ||
48 | #define PAT_BASE_ADDR_REG 0x0500 /* Pattern Image Base Address reg */ | ||
49 | #define PAT_SIZE_REG 0x0504 /* Pattern Image Size reg */ | ||
50 | #define PAT_COLOR_MODE_REG 0x0508 /* Pattern Image Color Mode reg */ | ||
51 | #define PAT_OFFSET_REG 0x050C /* Pattern Left Top Coordinate reg */ | ||
52 | #define PAT_STRIDE_REG 0x0510 /* Pattern Stride reg */ | ||
53 | |||
54 | /* Parameter Setting Registers (Mask) */ | ||
55 | #define MASK_BASE_ADDR_REG 0x0520 /* Mask Base Address reg */ | ||
56 | #define MASK_STRIDE_REG 0x0524 /* Mask Stride reg */ | ||
57 | |||
58 | /* Parameter Setting Registers (Clipping Window) */ | ||
59 | #define CW_LT_REG 0x0600 /* LeftTop coordinates of Clip Window */ | ||
60 | #define CW_RB_REG 0x0604 /* RightBottom coordinates of Clip | ||
61 | Window */ | ||
62 | |||
63 | /* Parameter Setting Registers (ROP & Alpha Setting) */ | ||
64 | #define THIRD_OPERAND_REG 0x0610 /* Third Operand Selection reg */ | ||
65 | #define ROP4_REG 0x0614 /* Raster Operation reg */ | ||
66 | #define ALPHA_REG 0x0618 /* Alpha value, Fading offset value */ | ||
67 | |||
68 | /* Parameter Setting Registers (Color) */ | ||
69 | #define FG_COLOR_REG 0x0700 /* Foreground Color reg */ | ||
70 | #define BG_COLOR_REG 0x0704 /* Background Color reg */ | ||
71 | #define BS_COLOR_REG 0x0708 /* Blue Screen Color reg */ | ||
72 | |||
73 | /* Parameter Setting Registers (Color Key) */ | ||
74 | #define SRC_COLORKEY_CTRL_REG 0x0710 /* Src Colorkey control reg */ | ||
75 | #define SRC_COLORKEY_DR_MIN_REG 0x0714 /* Src Colorkey Decision Reference | ||
76 | Min reg */ | ||
77 | #define SRC_COLORKEY_DR_MAX_REG 0x0718 /* Src Colorkey Decision Reference | ||
78 | Max reg */ | ||
79 | #define DST_COLORKEY_CTRL_REG 0x071C /* Dest Colorkey control reg */ | ||
80 | #define DST_COLORKEY_DR_MIN_REG 0x0720 /* Dest Colorkey Decision Reference | ||
81 | Min reg */ | ||
82 | #define DST_COLORKEY_DR_MAX_REG 0x0724 /* Dest Colorkey Decision Reference | ||
83 | Max reg */ | ||
84 | |||
85 | /* Color mode values */ | ||
86 | |||
87 | #define ORDER_XRGB 0 | ||
88 | #define ORDER_RGBX 1 | ||
89 | #define ORDER_XBGR 2 | ||
90 | #define ORDER_BGRX 3 | ||
91 | |||
92 | #define MODE_XRGB_8888 0 | ||
93 | #define MODE_ARGB_8888 1 | ||
94 | #define MODE_RGB_565 2 | ||
95 | #define MODE_XRGB_1555 3 | ||
96 | #define MODE_ARGB_1555 4 | ||
97 | #define MODE_XRGB_4444 5 | ||
98 | #define MODE_ARGB_4444 6 | ||
99 | #define MODE_PACKED_RGB_888 7 | ||
100 | |||
101 | #define COLOR_MODE(o, m) (((o) << 4) | (m)) | ||
102 | |||
103 | /* ROP4 operation values */ | ||
104 | #define ROP4_COPY 0xCCCC | ||
105 | #define ROP4_INVERT 0x3333 | ||
106 | |||
107 | /* Hardware limits */ | ||
108 | #define MAX_WIDTH 8000 | ||
109 | #define MAX_HEIGHT 8000 | ||
110 | |||
111 | #define G2D_TIMEOUT 500 | ||
112 | |||
113 | #define DEFAULT_WIDTH 100 | ||
114 | #define DEFAULT_HEIGHT 100 | ||
115 | |||
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c new file mode 100644 index 000000000000..1f156c8fe63e --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d.c | |||
@@ -0,0 +1,824 @@ | |||
1 | /* | ||
2 | * Samsung S5P G2D - 2D Graphics Accelerator Driver | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
5 | * Kamil Debski, <k.debski@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/version.h> | ||
16 | #include <linux/timer.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | |||
22 | #include <linux/platform_device.h> | ||
23 | #include <media/v4l2-mem2mem.h> | ||
24 | #include <media/v4l2-device.h> | ||
25 | #include <media/v4l2-ioctl.h> | ||
26 | #include <media/videobuf2-core.h> | ||
27 | #include <media/videobuf2-dma-contig.h> | ||
28 | |||
29 | #include "g2d.h" | ||
30 | #include "g2d-regs.h" | ||
31 | |||
32 | #define fh2ctx(__fh) container_of(__fh, struct g2d_ctx, fh) | ||
33 | |||
34 | static struct g2d_fmt formats[] = { | ||
35 | { | ||
36 | .name = "XRGB_8888", | ||
37 | .fourcc = V4L2_PIX_FMT_RGB32, | ||
38 | .depth = 32, | ||
39 | .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888), | ||
40 | }, | ||
41 | { | ||
42 | .name = "RGB_565", | ||
43 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
44 | .depth = 16, | ||
45 | .hw = COLOR_MODE(ORDER_XRGB, MODE_RGB_565), | ||
46 | }, | ||
47 | { | ||
48 | .name = "XRGB_1555", | ||
49 | .fourcc = V4L2_PIX_FMT_RGB555X, | ||
50 | .depth = 16, | ||
51 | .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555), | ||
52 | }, | ||
53 | { | ||
54 | .name = "XRGB_4444", | ||
55 | .fourcc = V4L2_PIX_FMT_RGB444, | ||
56 | .depth = 16, | ||
57 | .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444), | ||
58 | }, | ||
59 | { | ||
60 | .name = "PACKED_RGB_888", | ||
61 | .fourcc = V4L2_PIX_FMT_RGB24, | ||
62 | .depth = 24, | ||
63 | .hw = COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888), | ||
64 | }, | ||
65 | }; | ||
66 | #define NUM_FORMATS ARRAY_SIZE(formats) | ||
67 | |||
68 | struct g2d_frame def_frame = { | ||
69 | .width = DEFAULT_WIDTH, | ||
70 | .height = DEFAULT_HEIGHT, | ||
71 | .c_width = DEFAULT_WIDTH, | ||
72 | .c_height = DEFAULT_HEIGHT, | ||
73 | .o_width = 0, | ||
74 | .o_height = 0, | ||
75 | .fmt = &formats[0], | ||
76 | .right = DEFAULT_WIDTH, | ||
77 | .bottom = DEFAULT_HEIGHT, | ||
78 | }; | ||
79 | |||
80 | struct g2d_fmt *find_fmt(struct v4l2_format *f) | ||
81 | { | ||
82 | unsigned int i; | ||
83 | for (i = 0; i < NUM_FORMATS; i++) { | ||
84 | if (formats[i].fourcc == f->fmt.pix.pixelformat) | ||
85 | return &formats[i]; | ||
86 | } | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | |||
91 | static struct g2d_frame *get_frame(struct g2d_ctx *ctx, | ||
92 | enum v4l2_buf_type type) | ||
93 | { | ||
94 | switch (type) { | ||
95 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
96 | return &ctx->in; | ||
97 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
98 | return &ctx->out; | ||
99 | default: | ||
100 | return ERR_PTR(-EINVAL); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static int g2d_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | ||
105 | unsigned int *nbuffers, unsigned int *nplanes, | ||
106 | unsigned int sizes[], void *alloc_ctxs[]) | ||
107 | { | ||
108 | struct g2d_ctx *ctx = vb2_get_drv_priv(vq); | ||
109 | struct g2d_frame *f = get_frame(ctx, vq->type); | ||
110 | |||
111 | if (IS_ERR(f)) | ||
112 | return PTR_ERR(f); | ||
113 | |||
114 | sizes[0] = f->size; | ||
115 | *nplanes = 1; | ||
116 | alloc_ctxs[0] = ctx->dev->alloc_ctx; | ||
117 | |||
118 | if (*nbuffers == 0) | ||
119 | *nbuffers = 1; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int g2d_buf_prepare(struct vb2_buffer *vb) | ||
125 | { | ||
126 | struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
127 | struct g2d_frame *f = get_frame(ctx, vb->vb2_queue->type); | ||
128 | |||
129 | if (IS_ERR(f)) | ||
130 | return PTR_ERR(f); | ||
131 | vb2_set_plane_payload(vb, 0, f->size); | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static void g2d_buf_queue(struct vb2_buffer *vb) | ||
136 | { | ||
137 | struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
138 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); | ||
139 | } | ||
140 | |||
141 | |||
142 | static struct vb2_ops g2d_qops = { | ||
143 | .queue_setup = g2d_queue_setup, | ||
144 | .buf_prepare = g2d_buf_prepare, | ||
145 | .buf_queue = g2d_buf_queue, | ||
146 | }; | ||
147 | |||
148 | static int queue_init(void *priv, struct vb2_queue *src_vq, | ||
149 | struct vb2_queue *dst_vq) | ||
150 | { | ||
151 | struct g2d_ctx *ctx = priv; | ||
152 | int ret; | ||
153 | |||
154 | memset(src_vq, 0, sizeof(*src_vq)); | ||
155 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
156 | src_vq->io_modes = VB2_MMAP | VB2_USERPTR; | ||
157 | src_vq->drv_priv = ctx; | ||
158 | src_vq->ops = &g2d_qops; | ||
159 | src_vq->mem_ops = &vb2_dma_contig_memops; | ||
160 | src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | ||
161 | |||
162 | ret = vb2_queue_init(src_vq); | ||
163 | if (ret) | ||
164 | return ret; | ||
165 | |||
166 | memset(dst_vq, 0, sizeof(*dst_vq)); | ||
167 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
168 | dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; | ||
169 | dst_vq->drv_priv = ctx; | ||
170 | dst_vq->ops = &g2d_qops; | ||
171 | dst_vq->mem_ops = &vb2_dma_contig_memops; | ||
172 | dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | ||
173 | |||
174 | return vb2_queue_init(dst_vq); | ||
175 | } | ||
176 | |||
177 | static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) | ||
178 | { | ||
179 | struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx, | ||
180 | ctrl_handler); | ||
181 | switch (ctrl->id) { | ||
182 | case V4L2_CID_COLORFX: | ||
183 | if (ctrl->val == V4L2_COLORFX_NEGATIVE) | ||
184 | ctx->rop = ROP4_INVERT; | ||
185 | else | ||
186 | ctx->rop = ROP4_COPY; | ||
187 | default: | ||
188 | v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); | ||
189 | return -EINVAL; | ||
190 | } | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static const struct v4l2_ctrl_ops g2d_ctrl_ops = { | ||
195 | .s_ctrl = g2d_s_ctrl, | ||
196 | }; | ||
197 | |||
198 | int g2d_setup_ctrls(struct g2d_ctx *ctx) | ||
199 | { | ||
200 | struct g2d_dev *dev = ctx->dev; | ||
201 | |||
202 | v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); | ||
203 | if (ctx->ctrl_handler.error) { | ||
204 | v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); | ||
205 | return ctx->ctrl_handler.error; | ||
206 | } | ||
207 | |||
208 | v4l2_ctrl_new_std_menu( | ||
209 | &ctx->ctrl_handler, | ||
210 | &g2d_ctrl_ops, | ||
211 | V4L2_CID_COLORFX, | ||
212 | V4L2_COLORFX_NEGATIVE, | ||
213 | ~((1 << V4L2_COLORFX_NONE) | (1 << V4L2_COLORFX_NEGATIVE)), | ||
214 | V4L2_COLORFX_NONE); | ||
215 | |||
216 | if (ctx->ctrl_handler.error) { | ||
217 | v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); | ||
218 | return ctx->ctrl_handler.error; | ||
219 | } | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int g2d_open(struct file *file) | ||
225 | { | ||
226 | struct g2d_dev *dev = video_drvdata(file); | ||
227 | struct g2d_ctx *ctx = NULL; | ||
228 | int ret = 0; | ||
229 | |||
230 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
231 | if (!ctx) | ||
232 | return -ENOMEM; | ||
233 | ctx->dev = dev; | ||
234 | /* Set default formats */ | ||
235 | ctx->in = def_frame; | ||
236 | ctx->out = def_frame; | ||
237 | |||
238 | ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); | ||
239 | if (IS_ERR(ctx->m2m_ctx)) { | ||
240 | ret = PTR_ERR(ctx->m2m_ctx); | ||
241 | kfree(ctx); | ||
242 | return ret; | ||
243 | } | ||
244 | v4l2_fh_init(&ctx->fh, video_devdata(file)); | ||
245 | file->private_data = &ctx->fh; | ||
246 | v4l2_fh_add(&ctx->fh); | ||
247 | |||
248 | g2d_setup_ctrls(ctx); | ||
249 | |||
250 | /* Write the default values to the ctx struct */ | ||
251 | v4l2_ctrl_handler_setup(&ctx->ctrl_handler); | ||
252 | |||
253 | ctx->fh.ctrl_handler = &ctx->ctrl_handler; | ||
254 | |||
255 | v4l2_info(&dev->v4l2_dev, "instance opened\n"); | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int g2d_release(struct file *file) | ||
260 | { | ||
261 | struct g2d_dev *dev = video_drvdata(file); | ||
262 | struct g2d_ctx *ctx = fh2ctx(file->private_data); | ||
263 | |||
264 | v4l2_ctrl_handler_free(&ctx->ctrl_handler); | ||
265 | v4l2_fh_del(&ctx->fh); | ||
266 | v4l2_fh_exit(&ctx->fh); | ||
267 | kfree(ctx); | ||
268 | v4l2_info(&dev->v4l2_dev, "instance closed\n"); | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | |||
273 | static int vidioc_querycap(struct file *file, void *priv, | ||
274 | struct v4l2_capability *cap) | ||
275 | { | ||
276 | strncpy(cap->driver, G2D_NAME, sizeof(cap->driver) - 1); | ||
277 | strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1); | ||
278 | cap->bus_info[0] = 0; | ||
279 | cap->version = KERNEL_VERSION(1, 0, 0); | ||
280 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | ||
281 | | V4L2_CAP_STREAMING; | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) | ||
286 | { | ||
287 | struct g2d_fmt *fmt; | ||
288 | if (f->index >= NUM_FORMATS) | ||
289 | return -EINVAL; | ||
290 | fmt = &formats[f->index]; | ||
291 | f->pixelformat = fmt->fourcc; | ||
292 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) | ||
297 | { | ||
298 | struct g2d_ctx *ctx = prv; | ||
299 | struct vb2_queue *vq; | ||
300 | struct g2d_frame *frm; | ||
301 | |||
302 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | ||
303 | if (!vq) | ||
304 | return -EINVAL; | ||
305 | frm = get_frame(ctx, f->type); | ||
306 | if (IS_ERR(frm)) | ||
307 | return PTR_ERR(frm); | ||
308 | |||
309 | f->fmt.pix.width = frm->width; | ||
310 | f->fmt.pix.height = frm->height; | ||
311 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
312 | f->fmt.pix.pixelformat = frm->fmt->fourcc; | ||
313 | f->fmt.pix.bytesperline = (frm->width * frm->fmt->depth) >> 3; | ||
314 | f->fmt.pix.sizeimage = frm->size; | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) | ||
319 | { | ||
320 | struct g2d_fmt *fmt; | ||
321 | enum v4l2_field *field; | ||
322 | |||
323 | fmt = find_fmt(f); | ||
324 | if (!fmt) | ||
325 | return -EINVAL; | ||
326 | |||
327 | field = &f->fmt.pix.field; | ||
328 | if (*field == V4L2_FIELD_ANY) | ||
329 | *field = V4L2_FIELD_NONE; | ||
330 | else if (*field != V4L2_FIELD_NONE) | ||
331 | return -EINVAL; | ||
332 | |||
333 | if (f->fmt.pix.width > MAX_WIDTH) | ||
334 | f->fmt.pix.width = MAX_WIDTH; | ||
335 | if (f->fmt.pix.height > MAX_HEIGHT) | ||
336 | f->fmt.pix.height = MAX_HEIGHT; | ||
337 | |||
338 | if (f->fmt.pix.width < 1) | ||
339 | f->fmt.pix.width = 1; | ||
340 | if (f->fmt.pix.height < 1) | ||
341 | f->fmt.pix.height = 1; | ||
342 | |||
343 | f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; | ||
344 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) | ||
349 | { | ||
350 | struct g2d_ctx *ctx = prv; | ||
351 | struct g2d_dev *dev = ctx->dev; | ||
352 | struct vb2_queue *vq; | ||
353 | struct g2d_frame *frm; | ||
354 | struct g2d_fmt *fmt; | ||
355 | int ret = 0; | ||
356 | |||
357 | /* Adjust all values accordingly to the hardware capabilities | ||
358 | * and chosen format. */ | ||
359 | ret = vidioc_try_fmt(file, prv, f); | ||
360 | if (ret) | ||
361 | return ret; | ||
362 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | ||
363 | if (vb2_is_busy(vq)) { | ||
364 | v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type); | ||
365 | return -EBUSY; | ||
366 | } | ||
367 | frm = get_frame(ctx, f->type); | ||
368 | if (IS_ERR(frm)) | ||
369 | return PTR_ERR(frm); | ||
370 | fmt = find_fmt(f); | ||
371 | if (!fmt) | ||
372 | return -EINVAL; | ||
373 | frm->width = f->fmt.pix.width; | ||
374 | frm->height = f->fmt.pix.height; | ||
375 | frm->size = f->fmt.pix.sizeimage; | ||
376 | /* Reset crop settings */ | ||
377 | frm->o_width = 0; | ||
378 | frm->o_height = 0; | ||
379 | frm->c_width = frm->width; | ||
380 | frm->c_height = frm->height; | ||
381 | frm->right = frm->width; | ||
382 | frm->bottom = frm->height; | ||
383 | frm->fmt = fmt; | ||
384 | frm->stride = f->fmt.pix.bytesperline; | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait) | ||
389 | { | ||
390 | struct g2d_ctx *ctx = fh2ctx(file->private_data); | ||
391 | return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); | ||
392 | } | ||
393 | |||
394 | static int g2d_mmap(struct file *file, struct vm_area_struct *vma) | ||
395 | { | ||
396 | struct g2d_ctx *ctx = fh2ctx(file->private_data); | ||
397 | return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); | ||
398 | } | ||
399 | |||
400 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
401 | struct v4l2_requestbuffers *reqbufs) | ||
402 | { | ||
403 | struct g2d_ctx *ctx = priv; | ||
404 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); | ||
405 | } | ||
406 | |||
407 | static int vidioc_querybuf(struct file *file, void *priv, | ||
408 | struct v4l2_buffer *buf) | ||
409 | { | ||
410 | struct g2d_ctx *ctx = priv; | ||
411 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); | ||
412 | } | ||
413 | |||
414 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
415 | { | ||
416 | struct g2d_ctx *ctx = priv; | ||
417 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); | ||
418 | } | ||
419 | |||
420 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
421 | { | ||
422 | struct g2d_ctx *ctx = priv; | ||
423 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); | ||
424 | } | ||
425 | |||
426 | |||
427 | static int vidioc_streamon(struct file *file, void *priv, | ||
428 | enum v4l2_buf_type type) | ||
429 | { | ||
430 | struct g2d_ctx *ctx = priv; | ||
431 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | ||
432 | } | ||
433 | |||
434 | static int vidioc_streamoff(struct file *file, void *priv, | ||
435 | enum v4l2_buf_type type) | ||
436 | { | ||
437 | struct g2d_ctx *ctx = priv; | ||
438 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); | ||
439 | } | ||
440 | |||
441 | static int vidioc_cropcap(struct file *file, void *priv, | ||
442 | struct v4l2_cropcap *cr) | ||
443 | { | ||
444 | struct g2d_ctx *ctx = priv; | ||
445 | struct g2d_frame *f; | ||
446 | |||
447 | f = get_frame(ctx, cr->type); | ||
448 | if (IS_ERR(f)) | ||
449 | return PTR_ERR(f); | ||
450 | |||
451 | cr->bounds.left = 0; | ||
452 | cr->bounds.top = 0; | ||
453 | cr->bounds.width = f->width; | ||
454 | cr->bounds.height = f->height; | ||
455 | cr->defrect = cr->bounds; | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr) | ||
460 | { | ||
461 | struct g2d_ctx *ctx = prv; | ||
462 | struct g2d_frame *f; | ||
463 | |||
464 | f = get_frame(ctx, cr->type); | ||
465 | if (IS_ERR(f)) | ||
466 | return PTR_ERR(f); | ||
467 | |||
468 | cr->c.left = f->o_height; | ||
469 | cr->c.top = f->o_width; | ||
470 | cr->c.width = f->c_width; | ||
471 | cr->c.height = f->c_height; | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr) | ||
476 | { | ||
477 | struct g2d_ctx *ctx = prv; | ||
478 | struct g2d_dev *dev = ctx->dev; | ||
479 | struct g2d_frame *f; | ||
480 | |||
481 | f = get_frame(ctx, cr->type); | ||
482 | if (IS_ERR(f)) | ||
483 | return PTR_ERR(f); | ||
484 | |||
485 | if (cr->c.top < 0 || cr->c.left < 0) { | ||
486 | v4l2_err(&dev->v4l2_dev, | ||
487 | "doesn't support negative values for top & left\n"); | ||
488 | return -EINVAL; | ||
489 | } | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static int vidioc_s_crop(struct file *file, void *prv, struct v4l2_crop *cr) | ||
495 | { | ||
496 | struct g2d_ctx *ctx = prv; | ||
497 | struct g2d_frame *f; | ||
498 | int ret; | ||
499 | |||
500 | ret = vidioc_try_crop(file, prv, cr); | ||
501 | if (ret) | ||
502 | return ret; | ||
503 | f = get_frame(ctx, cr->type); | ||
504 | if (IS_ERR(f)) | ||
505 | return PTR_ERR(f); | ||
506 | |||
507 | f->c_width = cr->c.width; | ||
508 | f->c_height = cr->c.height; | ||
509 | f->o_width = cr->c.left; | ||
510 | f->o_height = cr->c.top; | ||
511 | f->bottom = f->o_height + f->c_height; | ||
512 | f->right = f->o_width + f->c_width; | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static void g2d_lock(void *prv) | ||
517 | { | ||
518 | struct g2d_ctx *ctx = prv; | ||
519 | struct g2d_dev *dev = ctx->dev; | ||
520 | mutex_lock(&dev->mutex); | ||
521 | } | ||
522 | |||
523 | static void g2d_unlock(void *prv) | ||
524 | { | ||
525 | struct g2d_ctx *ctx = prv; | ||
526 | struct g2d_dev *dev = ctx->dev; | ||
527 | mutex_unlock(&dev->mutex); | ||
528 | } | ||
529 | |||
530 | static void job_abort(void *prv) | ||
531 | { | ||
532 | struct g2d_ctx *ctx = prv; | ||
533 | struct g2d_dev *dev = ctx->dev; | ||
534 | int ret; | ||
535 | |||
536 | if (dev->curr == 0) /* No job currently running */ | ||
537 | return; | ||
538 | |||
539 | ret = wait_event_timeout(dev->irq_queue, | ||
540 | dev->curr == 0, | ||
541 | msecs_to_jiffies(G2D_TIMEOUT)); | ||
542 | } | ||
543 | |||
544 | static void device_run(void *prv) | ||
545 | { | ||
546 | struct g2d_ctx *ctx = prv; | ||
547 | struct g2d_dev *dev = ctx->dev; | ||
548 | struct vb2_buffer *src, *dst; | ||
549 | u32 cmd = 0; | ||
550 | |||
551 | dev->curr = ctx; | ||
552 | |||
553 | src = v4l2_m2m_next_src_buf(ctx->m2m_ctx); | ||
554 | dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); | ||
555 | |||
556 | clk_enable(dev->gate); | ||
557 | g2d_reset(dev); | ||
558 | |||
559 | g2d_set_src_size(dev, &ctx->in); | ||
560 | g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0)); | ||
561 | |||
562 | g2d_set_dst_size(dev, &ctx->out); | ||
563 | g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); | ||
564 | |||
565 | g2d_set_rop4(dev, ctx->rop); | ||
566 | if (ctx->in.c_width != ctx->out.c_width || | ||
567 | ctx->in.c_height != ctx->out.c_height) | ||
568 | cmd |= g2d_cmd_stretch(1); | ||
569 | g2d_set_cmd(dev, cmd); | ||
570 | g2d_start(dev); | ||
571 | } | ||
572 | |||
573 | static irqreturn_t g2d_isr(int irq, void *prv) | ||
574 | { | ||
575 | struct g2d_dev *dev = prv; | ||
576 | struct g2d_ctx *ctx = dev->curr; | ||
577 | struct vb2_buffer *src, *dst; | ||
578 | |||
579 | g2d_clear_int(dev); | ||
580 | clk_disable(dev->gate); | ||
581 | |||
582 | BUG_ON(ctx == 0); | ||
583 | |||
584 | src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); | ||
585 | dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); | ||
586 | |||
587 | BUG_ON(src == 0); | ||
588 | BUG_ON(dst == 0); | ||
589 | |||
590 | v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); | ||
591 | v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); | ||
592 | v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx); | ||
593 | |||
594 | dev->curr = 0; | ||
595 | wake_up(&dev->irq_queue); | ||
596 | return IRQ_HANDLED; | ||
597 | } | ||
598 | |||
599 | static const struct v4l2_file_operations g2d_fops = { | ||
600 | .owner = THIS_MODULE, | ||
601 | .open = g2d_open, | ||
602 | .release = g2d_release, | ||
603 | .poll = g2d_poll, | ||
604 | .unlocked_ioctl = video_ioctl2, | ||
605 | .mmap = g2d_mmap, | ||
606 | }; | ||
607 | |||
608 | static const struct v4l2_ioctl_ops g2d_ioctl_ops = { | ||
609 | .vidioc_querycap = vidioc_querycap, | ||
610 | |||
611 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, | ||
612 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt, | ||
613 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt, | ||
614 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt, | ||
615 | |||
616 | .vidioc_enum_fmt_vid_out = vidioc_enum_fmt, | ||
617 | .vidioc_g_fmt_vid_out = vidioc_g_fmt, | ||
618 | .vidioc_try_fmt_vid_out = vidioc_try_fmt, | ||
619 | .vidioc_s_fmt_vid_out = vidioc_s_fmt, | ||
620 | |||
621 | .vidioc_reqbufs = vidioc_reqbufs, | ||
622 | .vidioc_querybuf = vidioc_querybuf, | ||
623 | |||
624 | .vidioc_qbuf = vidioc_qbuf, | ||
625 | .vidioc_dqbuf = vidioc_dqbuf, | ||
626 | |||
627 | .vidioc_streamon = vidioc_streamon, | ||
628 | .vidioc_streamoff = vidioc_streamoff, | ||
629 | |||
630 | .vidioc_g_crop = vidioc_g_crop, | ||
631 | .vidioc_s_crop = vidioc_s_crop, | ||
632 | .vidioc_cropcap = vidioc_cropcap, | ||
633 | }; | ||
634 | |||
635 | static struct video_device g2d_videodev = { | ||
636 | .name = G2D_NAME, | ||
637 | .fops = &g2d_fops, | ||
638 | .ioctl_ops = &g2d_ioctl_ops, | ||
639 | .minor = -1, | ||
640 | .release = video_device_release, | ||
641 | }; | ||
642 | |||
643 | static struct v4l2_m2m_ops g2d_m2m_ops = { | ||
644 | .device_run = device_run, | ||
645 | .job_abort = job_abort, | ||
646 | .lock = g2d_lock, | ||
647 | .unlock = g2d_unlock, | ||
648 | }; | ||
649 | |||
650 | static int g2d_probe(struct platform_device *pdev) | ||
651 | { | ||
652 | struct g2d_dev *dev; | ||
653 | struct video_device *vfd; | ||
654 | struct resource *res; | ||
655 | int ret = 0; | ||
656 | |||
657 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
658 | if (!dev) | ||
659 | return -ENOMEM; | ||
660 | spin_lock_init(&dev->irqlock); | ||
661 | mutex_init(&dev->mutex); | ||
662 | atomic_set(&dev->num_inst, 0); | ||
663 | init_waitqueue_head(&dev->irq_queue); | ||
664 | |||
665 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
666 | if (!res) { | ||
667 | dev_err(&pdev->dev, "failed to find registers\n"); | ||
668 | ret = -ENOENT; | ||
669 | goto free_dev; | ||
670 | } | ||
671 | |||
672 | dev->res_regs = request_mem_region(res->start, resource_size(res), | ||
673 | dev_name(&pdev->dev)); | ||
674 | |||
675 | if (!dev->res_regs) { | ||
676 | dev_err(&pdev->dev, "failed to obtain register region\n"); | ||
677 | ret = -ENOENT; | ||
678 | goto free_dev; | ||
679 | } | ||
680 | |||
681 | dev->regs = ioremap(res->start, resource_size(res)); | ||
682 | if (!dev->regs) { | ||
683 | dev_err(&pdev->dev, "failed to map registers\n"); | ||
684 | ret = -ENOENT; | ||
685 | goto rel_res_regs; | ||
686 | } | ||
687 | |||
688 | dev->clk = clk_get(&pdev->dev, "sclk_fimg2d"); | ||
689 | if (IS_ERR_OR_NULL(dev->clk)) { | ||
690 | dev_err(&pdev->dev, "failed to get g2d clock\n"); | ||
691 | ret = -ENXIO; | ||
692 | goto unmap_regs; | ||
693 | } | ||
694 | |||
695 | dev->gate = clk_get(&pdev->dev, "fimg2d"); | ||
696 | if (IS_ERR_OR_NULL(dev->gate)) { | ||
697 | dev_err(&pdev->dev, "failed to get g2d clock gate\n"); | ||
698 | ret = -ENXIO; | ||
699 | goto put_clk; | ||
700 | } | ||
701 | |||
702 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
703 | if (!res) { | ||
704 | dev_err(&pdev->dev, "failed to find IRQ\n"); | ||
705 | ret = -ENXIO; | ||
706 | goto put_clk_gate; | ||
707 | } | ||
708 | |||
709 | dev->irq = res->start; | ||
710 | |||
711 | ret = request_irq(dev->irq, g2d_isr, 0, pdev->name, dev); | ||
712 | if (ret) { | ||
713 | dev_err(&pdev->dev, "failed to install IRQ\n"); | ||
714 | goto put_clk_gate; | ||
715 | } | ||
716 | |||
717 | dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | ||
718 | if (IS_ERR(dev->alloc_ctx)) { | ||
719 | ret = PTR_ERR(dev->alloc_ctx); | ||
720 | goto rel_irq; | ||
721 | } | ||
722 | |||
723 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); | ||
724 | if (ret) | ||
725 | goto alloc_ctx_cleanup; | ||
726 | vfd = video_device_alloc(); | ||
727 | if (!vfd) { | ||
728 | v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); | ||
729 | ret = -ENOMEM; | ||
730 | goto unreg_v4l2_dev; | ||
731 | } | ||
732 | *vfd = g2d_videodev; | ||
733 | vfd->lock = &dev->mutex; | ||
734 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
735 | if (ret) { | ||
736 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | ||
737 | goto rel_vdev; | ||
738 | } | ||
739 | video_set_drvdata(vfd, dev); | ||
740 | snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name); | ||
741 | dev->vfd = vfd; | ||
742 | v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n", | ||
743 | vfd->num); | ||
744 | platform_set_drvdata(pdev, dev); | ||
745 | dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops); | ||
746 | if (IS_ERR(dev->m2m_dev)) { | ||
747 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); | ||
748 | ret = PTR_ERR(dev->m2m_dev); | ||
749 | goto unreg_video_dev; | ||
750 | } | ||
751 | |||
752 | def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; | ||
753 | |||
754 | return 0; | ||
755 | |||
756 | unreg_video_dev: | ||
757 | video_unregister_device(dev->vfd); | ||
758 | rel_vdev: | ||
759 | video_device_release(vfd); | ||
760 | unreg_v4l2_dev: | ||
761 | v4l2_device_unregister(&dev->v4l2_dev); | ||
762 | alloc_ctx_cleanup: | ||
763 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | ||
764 | rel_irq: | ||
765 | free_irq(dev->irq, dev); | ||
766 | put_clk_gate: | ||
767 | clk_put(dev->gate); | ||
768 | put_clk: | ||
769 | clk_put(dev->clk); | ||
770 | unmap_regs: | ||
771 | iounmap(dev->regs); | ||
772 | rel_res_regs: | ||
773 | release_resource(dev->res_regs); | ||
774 | free_dev: | ||
775 | kfree(dev); | ||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | static int g2d_remove(struct platform_device *pdev) | ||
780 | { | ||
781 | struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev); | ||
782 | |||
783 | v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME); | ||
784 | v4l2_m2m_release(dev->m2m_dev); | ||
785 | video_unregister_device(dev->vfd); | ||
786 | v4l2_device_unregister(&dev->v4l2_dev); | ||
787 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | ||
788 | free_irq(dev->irq, dev); | ||
789 | clk_put(dev->gate); | ||
790 | clk_put(dev->clk); | ||
791 | iounmap(dev->regs); | ||
792 | release_resource(dev->res_regs); | ||
793 | kfree(dev); | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | static struct platform_driver g2d_pdrv = { | ||
798 | .probe = g2d_probe, | ||
799 | .remove = g2d_remove, | ||
800 | .driver = { | ||
801 | .name = G2D_NAME, | ||
802 | .owner = THIS_MODULE, | ||
803 | }, | ||
804 | }; | ||
805 | |||
806 | static void __exit g2d_exit(void) | ||
807 | { | ||
808 | platform_driver_unregister(&g2d_pdrv); | ||
809 | }; | ||
810 | |||
811 | static int __init g2d_init(void) | ||
812 | { | ||
813 | int ret = 0; | ||
814 | |||
815 | ret = platform_driver_register(&g2d_pdrv); | ||
816 | return ret; | ||
817 | }; | ||
818 | |||
819 | module_init(g2d_init); | ||
820 | module_exit(g2d_exit); | ||
821 | |||
822 | MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>"); | ||
823 | MODULE_DESCRIPTION("S5P G2D 2d graphics accelerator driver"); | ||
824 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h new file mode 100644 index 000000000000..5eae90107bf8 --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Samsung S5P G2D - 2D Graphics Accelerator Driver | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
5 | * Kamil Debski, <k.debski@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version | ||
11 | */ | ||
12 | |||
13 | #include <media/v4l2-device.h> | ||
14 | #include <media/v4l2-ctrls.h> | ||
15 | |||
16 | #define G2D_NAME "s5p-g2d" | ||
17 | |||
18 | struct g2d_dev { | ||
19 | struct v4l2_device v4l2_dev; | ||
20 | struct v4l2_m2m_dev *m2m_dev; | ||
21 | struct video_device *vfd; | ||
22 | struct mutex mutex; | ||
23 | spinlock_t irqlock; | ||
24 | atomic_t num_inst; | ||
25 | struct vb2_alloc_ctx *alloc_ctx; | ||
26 | struct resource *res_regs; | ||
27 | void __iomem *regs; | ||
28 | struct clk *clk; | ||
29 | struct clk *gate; | ||
30 | struct g2d_ctx *curr; | ||
31 | int irq; | ||
32 | wait_queue_head_t irq_queue; | ||
33 | }; | ||
34 | |||
35 | struct g2d_frame { | ||
36 | /* Original dimensions */ | ||
37 | u32 width; | ||
38 | u32 height; | ||
39 | /* Crop size */ | ||
40 | u32 c_width; | ||
41 | u32 c_height; | ||
42 | /* Offset */ | ||
43 | u32 o_width; | ||
44 | u32 o_height; | ||
45 | /* Image format */ | ||
46 | struct g2d_fmt *fmt; | ||
47 | /* Variables that can calculated once and reused */ | ||
48 | u32 stride; | ||
49 | u32 bottom; | ||
50 | u32 right; | ||
51 | u32 size; | ||
52 | }; | ||
53 | |||
54 | struct g2d_ctx { | ||
55 | struct v4l2_fh fh; | ||
56 | struct g2d_dev *dev; | ||
57 | struct v4l2_m2m_ctx *m2m_ctx; | ||
58 | struct g2d_frame in; | ||
59 | struct g2d_frame out; | ||
60 | struct v4l2_ctrl_handler ctrl_handler; | ||
61 | u32 rop; | ||
62 | }; | ||
63 | |||
64 | struct g2d_fmt { | ||
65 | char *name; | ||
66 | u32 fourcc; | ||
67 | int depth; | ||
68 | u32 hw; | ||
69 | }; | ||
70 | |||
71 | |||
72 | void g2d_reset(struct g2d_dev *d); | ||
73 | void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f); | ||
74 | void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a); | ||
75 | void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f); | ||
76 | void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a); | ||
77 | void g2d_start(struct g2d_dev *d); | ||
78 | void g2d_clear_int(struct g2d_dev *d); | ||
79 | void g2d_set_rop4(struct g2d_dev *d, u32 r); | ||
80 | u32 g2d_cmd_stretch(u32 e); | ||
81 | void g2d_set_cmd(struct g2d_dev *d, u32 c); | ||
82 | |||
83 | |||
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 0f9fb99adeb4..065d0f6be4a0 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -5691,6 +5691,27 @@ struct saa7134_board saa7134_boards[] = { | |||
5691 | .amux = LINE1, | 5691 | .amux = LINE1, |
5692 | }, | 5692 | }, |
5693 | }, | 5693 | }, |
5694 | [SAA7134_BOARD_SENSORAY811_911] = { | ||
5695 | .name = "Sensoray 811/911", | ||
5696 | .audio_clock = 0x00200000, | ||
5697 | .tuner_type = TUNER_ABSENT, | ||
5698 | .radio_type = UNSET, | ||
5699 | .tuner_addr = ADDR_UNSET, | ||
5700 | .radio_addr = ADDR_UNSET, | ||
5701 | .inputs = {{ | ||
5702 | .name = name_comp1, | ||
5703 | .vmux = 0, | ||
5704 | .amux = LINE1, | ||
5705 | }, { | ||
5706 | .name = name_comp3, | ||
5707 | .vmux = 2, | ||
5708 | .amux = LINE1, | ||
5709 | }, { | ||
5710 | .name = name_svideo, | ||
5711 | .vmux = 8, | ||
5712 | .amux = LINE1, | ||
5713 | } }, | ||
5714 | }, | ||
5694 | 5715 | ||
5695 | }; | 5716 | }; |
5696 | 5717 | ||
@@ -6914,6 +6935,18 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
6914 | .subdevice = 0xd136, | 6935 | .subdevice = 0xd136, |
6915 | .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2, | 6936 | .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2, |
6916 | }, { | 6937 | }, { |
6938 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
6939 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
6940 | .subvendor = 0x6000, | ||
6941 | .subdevice = 0x0811, | ||
6942 | .driver_data = SAA7134_BOARD_SENSORAY811_911, | ||
6943 | }, { | ||
6944 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
6945 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
6946 | .subvendor = 0x6000, | ||
6947 | .subdevice = 0x0911, | ||
6948 | .driver_data = SAA7134_BOARD_SENSORAY811_911, | ||
6949 | }, { | ||
6917 | /* --- boards without eeprom + subsystem ID --- */ | 6950 | /* --- boards without eeprom + subsystem ID --- */ |
6918 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6951 | .vendor = PCI_VENDOR_ID_PHILIPS, |
6919 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6952 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 9b550687213a..4ad9de4410d4 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -330,6 +330,7 @@ struct saa7134_card_ir { | |||
330 | #define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185 | 330 | #define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185 |
331 | #define SAA7134_BOARD_BEHOLD_501 186 | 331 | #define SAA7134_BOARD_BEHOLD_501 186 |
332 | #define SAA7134_BOARD_BEHOLD_503FM 187 | 332 | #define SAA7134_BOARD_BEHOLD_503FM 187 |
333 | #define SAA7134_BOARD_SENSORAY811_911 188 | ||
333 | 334 | ||
334 | #define SAA7134_MAXBOARDS 32 | 335 | #define SAA7134_MAXBOARDS 32 |
335 | #define SAA7134_INPUT_MAX 8 | 336 | #define SAA7134_INPUT_MAX 8 |
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c index 466e1b02f91f..a7f58a998752 100644 --- a/drivers/media/video/saa7164/saa7164-bus.c +++ b/drivers/media/video/saa7164/saa7164-bus.c | |||
@@ -149,7 +149,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, | |||
149 | saa7164_bus_verify(dev); | 149 | saa7164_bus_verify(dev); |
150 | 150 | ||
151 | msg->size = cpu_to_le16(msg->size); | 151 | msg->size = cpu_to_le16(msg->size); |
152 | msg->command = cpu_to_le16(msg->command); | 152 | msg->command = cpu_to_le32(msg->command); |
153 | msg->controlselector = cpu_to_le16(msg->controlselector); | 153 | msg->controlselector = cpu_to_le16(msg->controlselector); |
154 | 154 | ||
155 | if (msg->size > dev->bus.m_wMaxReqSize) { | 155 | if (msg->size > dev->bus.m_wMaxReqSize) { |
@@ -464,7 +464,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, | |||
464 | 464 | ||
465 | peekout: | 465 | peekout: |
466 | msg->size = le16_to_cpu(msg->size); | 466 | msg->size = le16_to_cpu(msg->size); |
467 | msg->command = le16_to_cpu(msg->command); | 467 | msg->command = le32_to_cpu(msg->command); |
468 | msg->controlselector = le16_to_cpu(msg->controlselector); | 468 | msg->controlselector = le16_to_cpu(msg->controlselector); |
469 | ret = SAA_OK; | 469 | ret = SAA_OK; |
470 | out: | 470 | out: |
diff --git a/drivers/media/video/tm6000/Kconfig b/drivers/media/video/tm6000/Kconfig index 114eec8a630a..a43b77abd931 100644 --- a/drivers/media/video/tm6000/Kconfig +++ b/drivers/media/video/tm6000/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_TM6000 | 1 | config VIDEO_TM6000 |
2 | tristate "TV Master TM5600/6000/6010 driver" | 2 | tristate "TV Master TM5600/6000/6010 driver" |
3 | depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB && EXPERIMENTAL | 3 | depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select MEDIA_TUNER_XC2028 | 5 | select MEDIA_TUNER_XC2028 |
6 | select MEDIA_TUNER_XC5000 | 6 | select MEDIA_TUNER_XC5000 |
@@ -16,7 +16,7 @@ config VIDEO_TM6000 | |||
16 | 16 | ||
17 | config VIDEO_TM6000_ALSA | 17 | config VIDEO_TM6000_ALSA |
18 | tristate "TV Master TM5600/6000/6010 audio support" | 18 | tristate "TV Master TM5600/6000/6010 audio support" |
19 | depends on VIDEO_TM6000 && SND && EXPERIMENTAL | 19 | depends on VIDEO_TM6000 && SND |
20 | select SND_PCM | 20 | select SND_PCM |
21 | ---help--- | 21 | ---help--- |
22 | This is a video4linux driver for direct (DMA) audio for | 22 | This is a video4linux driver for direct (DMA) audio for |
@@ -27,7 +27,7 @@ config VIDEO_TM6000_ALSA | |||
27 | 27 | ||
28 | config VIDEO_TM6000_DVB | 28 | config VIDEO_TM6000_DVB |
29 | tristate "DVB Support for tm6000 based TV cards" | 29 | tristate "DVB Support for tm6000 based TV cards" |
30 | depends on VIDEO_TM6000 && DVB_CORE && USB && EXPERIMENTAL | 30 | depends on VIDEO_TM6000 && DVB_CORE && USB |
31 | select DVB_ZL10353 | 31 | select DVB_ZL10353 |
32 | ---help--- | 32 | ---help--- |
33 | This adds support for DVB cards based on the tm5600/tm6000 chip. | 33 | This adds support for DVB cards based on the tm5600/tm6000 chip. |
diff --git a/drivers/media/video/tm6000/tm6000-alsa.c b/drivers/media/video/tm6000/tm6000-alsa.c index 7d675c72fd47..ddffd67c0d82 100644 --- a/drivers/media/video/tm6000/tm6000-alsa.c +++ b/drivers/media/video/tm6000/tm6000-alsa.c | |||
@@ -146,20 +146,21 @@ static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size) | |||
146 | #define DEFAULT_FIFO_SIZE 4096 | 146 | #define DEFAULT_FIFO_SIZE 4096 |
147 | 147 | ||
148 | static struct snd_pcm_hardware snd_tm6000_digital_hw = { | 148 | static struct snd_pcm_hardware snd_tm6000_digital_hw = { |
149 | .info = SNDRV_PCM_INFO_MMAP | | 149 | .info = SNDRV_PCM_INFO_BATCH | |
150 | SNDRV_PCM_INFO_MMAP | | ||
150 | SNDRV_PCM_INFO_INTERLEAVED | | 151 | SNDRV_PCM_INFO_INTERLEAVED | |
151 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 152 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
152 | SNDRV_PCM_INFO_MMAP_VALID, | 153 | SNDRV_PCM_INFO_MMAP_VALID, |
153 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 154 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
154 | 155 | ||
155 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | 156 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT, |
156 | .rate_min = 48000, | 157 | .rate_min = 48000, |
157 | .rate_max = 48000, | 158 | .rate_max = 48000, |
158 | .channels_min = 2, | 159 | .channels_min = 2, |
159 | .channels_max = 2, | 160 | .channels_max = 2, |
160 | .period_bytes_min = 64, | 161 | .period_bytes_min = 64, |
161 | .period_bytes_max = 12544, | 162 | .period_bytes_max = 12544, |
162 | .periods_min = 1, | 163 | .periods_min = 2, |
163 | .periods_max = 98, | 164 | .periods_max = 98, |
164 | .buffer_bytes_max = 62720 * 8, | 165 | .buffer_bytes_max = 62720 * 8, |
165 | }; | 166 | }; |
@@ -181,6 +182,7 @@ static int snd_tm6000_pcm_open(struct snd_pcm_substream *substream) | |||
181 | chip->substream = substream; | 182 | chip->substream = substream; |
182 | 183 | ||
183 | runtime->hw = snd_tm6000_digital_hw; | 184 | runtime->hw = snd_tm6000_digital_hw; |
185 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
184 | 186 | ||
185 | return 0; | 187 | return 0; |
186 | _error: | 188 | _error: |
@@ -347,9 +349,13 @@ static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd) | |||
347 | int err = 0; | 349 | int err = 0; |
348 | 350 | ||
349 | switch (cmd) { | 351 | switch (cmd) { |
352 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | ||
353 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | ||
350 | case SNDRV_PCM_TRIGGER_START: | 354 | case SNDRV_PCM_TRIGGER_START: |
351 | atomic_set(&core->stream_started, 1); | 355 | atomic_set(&core->stream_started, 1); |
352 | break; | 356 | break; |
357 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | ||
358 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | ||
353 | case SNDRV_PCM_TRIGGER_STOP: | 359 | case SNDRV_PCM_TRIGGER_STOP: |
354 | atomic_set(&core->stream_started, 0); | 360 | atomic_set(&core->stream_started, 0); |
355 | break; | 361 | break; |
@@ -371,6 +377,14 @@ static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream) | |||
371 | return chip->buf_pos; | 377 | return chip->buf_pos; |
372 | } | 378 | } |
373 | 379 | ||
380 | static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, | ||
381 | unsigned long offset) | ||
382 | { | ||
383 | void *pageptr = subs->runtime->dma_area + offset; | ||
384 | |||
385 | return vmalloc_to_page(pageptr); | ||
386 | } | ||
387 | |||
374 | /* | 388 | /* |
375 | * operators | 389 | * operators |
376 | */ | 390 | */ |
@@ -383,6 +397,7 @@ static struct snd_pcm_ops snd_tm6000_pcm_ops = { | |||
383 | .prepare = snd_tm6000_prepare, | 397 | .prepare = snd_tm6000_prepare, |
384 | .trigger = snd_tm6000_card_trigger, | 398 | .trigger = snd_tm6000_card_trigger, |
385 | .pointer = snd_tm6000_pointer, | 399 | .pointer = snd_tm6000_pointer, |
400 | .page = snd_pcm_get_vmalloc_page, | ||
386 | }; | 401 | }; |
387 | 402 | ||
388 | /* | 403 | /* |
diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/video/tm6000/tm6000-cards.c index ec2578a0fdf7..6b74259cd5c8 100644 --- a/drivers/media/video/tm6000/tm6000-cards.c +++ b/drivers/media/video/tm6000/tm6000-cards.c | |||
@@ -351,6 +351,7 @@ static struct tm6000_board tm6000_boards[] = { | |||
351 | .tuner_addr = 0xc2 >> 1, | 351 | .tuner_addr = 0xc2 >> 1, |
352 | .demod_addr = 0x1e >> 1, | 352 | .demod_addr = 0x1e >> 1, |
353 | .type = TM6010, | 353 | .type = TM6010, |
354 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
354 | .caps = { | 355 | .caps = { |
355 | .has_tuner = 1, | 356 | .has_tuner = 1, |
356 | .has_dvb = 1, | 357 | .has_dvb = 1, |
@@ -639,6 +640,7 @@ static struct usb_device_id tm6000_id_table[] = { | |||
639 | { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE }, | 640 | { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE }, |
640 | { } | 641 | { } |
641 | }; | 642 | }; |
643 | MODULE_DEVICE_TABLE(usb, tm6000_id_table); | ||
642 | 644 | ||
643 | /* Control power led for show some activity */ | 645 | /* Control power led for show some activity */ |
644 | void tm6000_flash_led(struct tm6000_core *dev, u8 state) | 646 | void tm6000_flash_led(struct tm6000_core *dev, u8 state) |
@@ -1050,6 +1052,33 @@ static void use_alternative_detection_method(struct tm6000_core *dev) | |||
1050 | tm6000_boards[model].name, model); | 1052 | tm6000_boards[model].name, model); |
1051 | } | 1053 | } |
1052 | 1054 | ||
1055 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
1056 | static void request_module_async(struct work_struct *work) | ||
1057 | { | ||
1058 | struct tm6000_core *dev = container_of(work, struct tm6000_core, | ||
1059 | request_module_wk); | ||
1060 | |||
1061 | request_module("tm6000-alsa"); | ||
1062 | |||
1063 | if (dev->caps.has_dvb) | ||
1064 | request_module("tm6000-dvb"); | ||
1065 | } | ||
1066 | |||
1067 | static void request_modules(struct tm6000_core *dev) | ||
1068 | { | ||
1069 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
1070 | schedule_work(&dev->request_module_wk); | ||
1071 | } | ||
1072 | |||
1073 | static void flush_request_modules(struct tm6000_core *dev) | ||
1074 | { | ||
1075 | flush_work_sync(&dev->request_module_wk); | ||
1076 | } | ||
1077 | #else | ||
1078 | #define request_modules(dev) | ||
1079 | #define flush_request_modules(dev) | ||
1080 | #endif /* CONFIG_MODULES */ | ||
1081 | |||
1053 | static int tm6000_init_dev(struct tm6000_core *dev) | 1082 | static int tm6000_init_dev(struct tm6000_core *dev) |
1054 | { | 1083 | { |
1055 | struct v4l2_frequency f; | 1084 | struct v4l2_frequency f; |
@@ -1112,6 +1141,8 @@ static int tm6000_init_dev(struct tm6000_core *dev) | |||
1112 | 1141 | ||
1113 | tm6000_ir_init(dev); | 1142 | tm6000_ir_init(dev); |
1114 | 1143 | ||
1144 | request_modules(dev); | ||
1145 | |||
1115 | mutex_unlock(&dev->lock); | 1146 | mutex_unlock(&dev->lock); |
1116 | return 0; | 1147 | return 0; |
1117 | 1148 | ||
@@ -1324,6 +1355,8 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) | |||
1324 | 1355 | ||
1325 | printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name); | 1356 | printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name); |
1326 | 1357 | ||
1358 | flush_request_modules(dev); | ||
1359 | |||
1327 | tm6000_ir_fini(dev); | 1360 | tm6000_ir_fini(dev); |
1328 | 1361 | ||
1329 | if (dev->gpio.power_led) { | 1362 | if (dev->gpio.power_led) { |
diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c index 9783616a0da2..979c85b73814 100644 --- a/drivers/media/video/tm6000/tm6000-core.c +++ b/drivers/media/video/tm6000/tm6000-core.c | |||
@@ -88,7 +88,9 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req, | |||
88 | } | 88 | } |
89 | 89 | ||
90 | kfree(data); | 90 | kfree(data); |
91 | msleep(5); | 91 | |
92 | if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0) | ||
93 | msleep(5); | ||
92 | 94 | ||
93 | mutex_unlock(&dev->usb_lock); | 95 | mutex_unlock(&dev->usb_lock); |
94 | return ret; | 96 | return ret; |
@@ -125,14 +127,14 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value, | |||
125 | u8 new_index; | 127 | u8 new_index; |
126 | 128 | ||
127 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, | 129 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, |
128 | value, index, buf, 1); | 130 | value, 0, buf, 1); |
129 | 131 | ||
130 | if (rc < 0) | 132 | if (rc < 0) |
131 | return rc; | 133 | return rc; |
132 | 134 | ||
133 | new_index = (buf[0] & ~mask) | (index & mask); | 135 | new_index = (buf[0] & ~mask) | (index & mask); |
134 | 136 | ||
135 | if (new_index == index) | 137 | if (new_index == buf[0]) |
136 | return 0; | 138 | return 0; |
137 | 139 | ||
138 | return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, | 140 | return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, |
@@ -536,16 +538,16 @@ static struct reg_init tm6010_init_tab[] = { | |||
536 | 538 | ||
537 | { TM6010_REQ05_R18_IMASK7, 0x00 }, | 539 | { TM6010_REQ05_R18_IMASK7, 0x00 }, |
538 | 540 | ||
539 | { TM6010_REQ07_RD8_IR_LEADER1, 0xaa }, | 541 | { TM6010_REQ07_RDC_IR_LEADER1, 0xaa }, |
540 | { TM6010_REQ07_RD8_IR_LEADER0, 0x30 }, | 542 | { TM6010_REQ07_RDD_IR_LEADER0, 0x30 }, |
541 | { TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20 }, | 543 | { TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20 }, |
542 | { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0 }, | 544 | { TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0 }, |
543 | { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 }, | 545 | { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 }, |
544 | { TM6010_REQ07_RD8_IR, 0x2f }, | 546 | { TM6010_REQ07_RD8_IR, 0x0f }, |
545 | 547 | ||
546 | /* set remote wakeup key:any key wakeup */ | 548 | /* set remote wakeup key:any key wakeup */ |
547 | { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe }, | 549 | { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe }, |
548 | { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff }, | 550 | { TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff }, |
549 | }; | 551 | }; |
550 | 552 | ||
551 | int tm6000_init(struct tm6000_core *dev) | 553 | int tm6000_init(struct tm6000_core *dev) |
@@ -599,55 +601,6 @@ int tm6000_init(struct tm6000_core *dev) | |||
599 | return rc; | 601 | return rc; |
600 | } | 602 | } |
601 | 603 | ||
602 | int tm6000_reset(struct tm6000_core *dev) | ||
603 | { | ||
604 | int pipe; | ||
605 | int err; | ||
606 | |||
607 | msleep(500); | ||
608 | |||
609 | err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0); | ||
610 | if (err < 0) { | ||
611 | tm6000_err("failed to select interface %d, alt. setting 0\n", | ||
612 | dev->isoc_in.bInterfaceNumber); | ||
613 | return err; | ||
614 | } | ||
615 | |||
616 | err = usb_reset_configuration(dev->udev); | ||
617 | if (err < 0) { | ||
618 | tm6000_err("failed to reset configuration\n"); | ||
619 | return err; | ||
620 | } | ||
621 | |||
622 | if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0) | ||
623 | msleep(5); | ||
624 | |||
625 | /* | ||
626 | * Not all devices have int_in defined | ||
627 | */ | ||
628 | if (!dev->int_in.endp) | ||
629 | return 0; | ||
630 | |||
631 | err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2); | ||
632 | if (err < 0) { | ||
633 | tm6000_err("failed to select interface %d, alt. setting 2\n", | ||
634 | dev->isoc_in.bInterfaceNumber); | ||
635 | return err; | ||
636 | } | ||
637 | |||
638 | msleep(5); | ||
639 | |||
640 | pipe = usb_rcvintpipe(dev->udev, | ||
641 | dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | ||
642 | |||
643 | err = usb_clear_halt(dev->udev, pipe); | ||
644 | if (err < 0) { | ||
645 | tm6000_err("usb_clear_halt failed: %d\n", err); | ||
646 | return err; | ||
647 | } | ||
648 | |||
649 | return 0; | ||
650 | } | ||
651 | 604 | ||
652 | int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate) | 605 | int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate) |
653 | { | 606 | { |
@@ -696,11 +649,13 @@ int tm6000_set_audio_rinput(struct tm6000_core *dev) | |||
696 | if (dev->dev_type == TM6010) { | 649 | if (dev->dev_type == TM6010) { |
697 | /* Audio crossbar setting, default SIF1 */ | 650 | /* Audio crossbar setting, default SIF1 */ |
698 | u8 areg_f0; | 651 | u8 areg_f0; |
652 | u8 areg_07 = 0x10; | ||
699 | 653 | ||
700 | switch (dev->rinput.amux) { | 654 | switch (dev->rinput.amux) { |
701 | case TM6000_AMUX_SIF1: | 655 | case TM6000_AMUX_SIF1: |
702 | case TM6000_AMUX_SIF2: | 656 | case TM6000_AMUX_SIF2: |
703 | areg_f0 = 0x03; | 657 | areg_f0 = 0x03; |
658 | areg_07 = 0x30; | ||
704 | break; | 659 | break; |
705 | case TM6000_AMUX_ADC1: | 660 | case TM6000_AMUX_ADC1: |
706 | areg_f0 = 0x00; | 661 | areg_f0 = 0x00; |
@@ -720,6 +675,9 @@ int tm6000_set_audio_rinput(struct tm6000_core *dev) | |||
720 | /* Set audio input crossbar */ | 675 | /* Set audio input crossbar */ |
721 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, | 676 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, |
722 | areg_f0, 0x0f); | 677 | areg_f0, 0x0f); |
678 | /* Mux overflow workaround */ | ||
679 | tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, | ||
680 | areg_07, 0xf0); | ||
723 | } else { | 681 | } else { |
724 | u8 areg_eb; | 682 | u8 areg_eb; |
725 | /* Audio setting, default LINE1 */ | 683 | /* Audio setting, default LINE1 */ |
diff --git a/drivers/media/video/tm6000/tm6000-dvb.c b/drivers/media/video/tm6000/tm6000-dvb.c index 5e6c129a4beb..db6a561bca3e 100644 --- a/drivers/media/video/tm6000/tm6000-dvb.c +++ b/drivers/media/video/tm6000/tm6000-dvb.c | |||
@@ -89,9 +89,19 @@ static void tm6000_urb_received(struct urb *urb) | |||
89 | int ret; | 89 | int ret; |
90 | struct tm6000_core *dev = urb->context; | 90 | struct tm6000_core *dev = urb->context; |
91 | 91 | ||
92 | if (urb->status != 0) | 92 | switch (urb->status) { |
93 | case 0: | ||
94 | case -ETIMEDOUT: | ||
95 | break; | ||
96 | case -ENOENT: | ||
97 | case -ECONNRESET: | ||
98 | case -ESHUTDOWN: | ||
99 | return; | ||
100 | default: | ||
93 | print_err_status(dev, 0, urb->status); | 101 | print_err_status(dev, 0, urb->status); |
94 | else if (urb->actual_length > 0) | 102 | } |
103 | |||
104 | if (urb->actual_length > 0) | ||
95 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, | 105 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, |
96 | urb->actual_length); | 106 | urb->actual_length); |
97 | 107 | ||
@@ -151,7 +161,7 @@ static int tm6000_start_stream(struct tm6000_core *dev) | |||
151 | printk(KERN_ERR "tm6000: pipe resetted\n"); | 161 | printk(KERN_ERR "tm6000: pipe resetted\n"); |
152 | 162 | ||
153 | /* mutex_lock(&tm6000_driver.open_close_mutex); */ | 163 | /* mutex_lock(&tm6000_driver.open_close_mutex); */ |
154 | ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL); | 164 | ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC); |
155 | 165 | ||
156 | /* mutex_unlock(&tm6000_driver.open_close_mutex); */ | 166 | /* mutex_unlock(&tm6000_driver.open_close_mutex); */ |
157 | if (ret) { | 167 | if (ret) { |
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index 405d12729d05..8d925274c8d6 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c | |||
@@ -31,22 +31,25 @@ | |||
31 | 31 | ||
32 | static unsigned int ir_debug; | 32 | static unsigned int ir_debug; |
33 | module_param(ir_debug, int, 0644); | 33 | module_param(ir_debug, int, 0644); |
34 | MODULE_PARM_DESC(ir_debug, "enable debug message [IR]"); | 34 | MODULE_PARM_DESC(ir_debug, "debug message level"); |
35 | 35 | ||
36 | static unsigned int enable_ir = 1; | 36 | static unsigned int enable_ir = 1; |
37 | module_param(enable_ir, int, 0644); | 37 | module_param(enable_ir, int, 0644); |
38 | MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)"); | 38 | MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)"); |
39 | 39 | ||
40 | /* number of 50ms for ON-OFF-ON power led */ | 40 | static unsigned int ir_clock_mhz = 12; |
41 | /* show IR activity */ | 41 | module_param(ir_clock_mhz, int, 0644); |
42 | #define PWLED_OFF 2 | 42 | MODULE_PARM_DESC(enable_ir, "ir clock, in MHz"); |
43 | |||
44 | #define URB_SUBMIT_DELAY 100 /* ms - Delay to submit an URB request on retrial and init */ | ||
45 | #define URB_INT_LED_DELAY 100 /* ms - Delay to turn led on again on int mode */ | ||
43 | 46 | ||
44 | #undef dprintk | 47 | #undef dprintk |
45 | 48 | ||
46 | #define dprintk(fmt, arg...) \ | 49 | #define dprintk(level, fmt, arg...) do {\ |
47 | if (ir_debug) { \ | 50 | if (ir_debug >= level) \ |
48 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | 51 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ |
49 | } | 52 | } while (0) |
50 | 53 | ||
51 | struct tm6000_ir_poll_result { | 54 | struct tm6000_ir_poll_result { |
52 | u16 rc_data; | 55 | u16 rc_data; |
@@ -62,20 +65,15 @@ struct tm6000_IR { | |||
62 | int polling; | 65 | int polling; |
63 | struct delayed_work work; | 66 | struct delayed_work work; |
64 | u8 wait:1; | 67 | u8 wait:1; |
65 | u8 key:1; | 68 | u8 pwled:2; |
66 | u8 pwled:1; | 69 | u8 submit_urb:1; |
67 | u8 pwledcnt; | ||
68 | u16 key_addr; | 70 | u16 key_addr; |
69 | struct urb *int_urb; | 71 | struct urb *int_urb; |
70 | u8 *urb_data; | ||
71 | |||
72 | int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); | ||
73 | 72 | ||
74 | /* IR device properties */ | 73 | /* IR device properties */ |
75 | u64 rc_type; | 74 | u64 rc_type; |
76 | }; | 75 | }; |
77 | 76 | ||
78 | |||
79 | void tm6000_ir_wait(struct tm6000_core *dev, u8 state) | 77 | void tm6000_ir_wait(struct tm6000_core *dev, u8 state) |
80 | { | 78 | { |
81 | struct tm6000_IR *ir = dev->ir; | 79 | struct tm6000_IR *ir = dev->ir; |
@@ -83,62 +81,84 @@ void tm6000_ir_wait(struct tm6000_core *dev, u8 state) | |||
83 | if (!dev->ir) | 81 | if (!dev->ir) |
84 | return; | 82 | return; |
85 | 83 | ||
84 | dprintk(2, "%s: %i\n",__func__, ir->wait); | ||
85 | |||
86 | if (state) | 86 | if (state) |
87 | ir->wait = 1; | 87 | ir->wait = 1; |
88 | else | 88 | else |
89 | ir->wait = 0; | 89 | ir->wait = 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | |||
93 | static int tm6000_ir_config(struct tm6000_IR *ir) | 92 | static int tm6000_ir_config(struct tm6000_IR *ir) |
94 | { | 93 | { |
95 | struct tm6000_core *dev = ir->dev; | 94 | struct tm6000_core *dev = ir->dev; |
96 | u8 buf[10]; | 95 | u32 pulse = 0, leader = 0; |
97 | int rc; | 96 | |
97 | dprintk(2, "%s\n",__func__); | ||
98 | |||
99 | /* | ||
100 | * The IR decoder supports RC-5 or NEC, with a configurable timing. | ||
101 | * The timing configuration there is not that accurate, as it uses | ||
102 | * approximate values. The NEC spec mentions a 562.5 unit period, | ||
103 | * and RC-5 uses a 888.8 period. | ||
104 | * Currently, driver assumes a clock provided by a 12 MHz XTAL, but | ||
105 | * a modprobe parameter can adjust it. | ||
106 | * Adjustments are required for other timings. | ||
107 | * It seems that the 900ms timing for NEC is used to detect a RC-5 | ||
108 | * IR, in order to discard such decoding | ||
109 | */ | ||
98 | 110 | ||
99 | switch (ir->rc_type) { | 111 | switch (ir->rc_type) { |
100 | case RC_TYPE_NEC: | 112 | case RC_TYPE_NEC: |
101 | /* Setup IR decoder for NEC standard 12MHz system clock */ | 113 | leader = 900; /* ms */ |
102 | /* IR_LEADER_CNT = 0.9ms */ | 114 | pulse = 700; /* ms - the actual value would be 562 */ |
103 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER1, 0xaa); | ||
104 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER0, 0x30); | ||
105 | /* IR_PULSE_CNT = 0.7ms */ | ||
106 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20); | ||
107 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0); | ||
108 | /* Remote WAKEUP = enable */ | ||
109 | tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe); | ||
110 | /* IR_WKUP_SEL = Low byte in decoded IR data */ | ||
111 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff); | ||
112 | /* IR_WKU_ADD code */ | ||
113 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0xff); | ||
114 | tm6000_flash_led(dev, 0); | ||
115 | msleep(100); | ||
116 | tm6000_flash_led(dev, 1); | ||
117 | break; | 115 | break; |
118 | default: | 116 | default: |
119 | /* hack */ | 117 | case RC_TYPE_RC5: |
120 | buf[0] = 0xff; | 118 | leader = 900; /* ms - from the NEC decoding */ |
121 | buf[1] = 0xff; | 119 | pulse = 1780; /* ms - The actual value would be 1776 */ |
122 | buf[2] = 0xf2; | ||
123 | buf[3] = 0x2b; | ||
124 | buf[4] = 0x20; | ||
125 | buf[5] = 0x35; | ||
126 | buf[6] = 0x60; | ||
127 | buf[7] = 0x04; | ||
128 | buf[8] = 0xc0; | ||
129 | buf[9] = 0x08; | ||
130 | |||
131 | rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | | ||
132 | USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a); | ||
133 | msleep(100); | ||
134 | |||
135 | if (rc < 0) { | ||
136 | printk(KERN_INFO "IR configuration failed"); | ||
137 | return rc; | ||
138 | } | ||
139 | break; | 120 | break; |
140 | } | 121 | } |
141 | 122 | ||
123 | pulse = ir_clock_mhz * pulse; | ||
124 | leader = ir_clock_mhz * leader; | ||
125 | if (ir->rc_type == RC_TYPE_NEC) | ||
126 | leader = leader | 0x8000; | ||
127 | |||
128 | dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n", | ||
129 | __func__, | ||
130 | (ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5", | ||
131 | ir_clock_mhz, leader, pulse); | ||
132 | |||
133 | /* Remote WAKEUP = enable, normal mode, from IR decoder output */ | ||
134 | tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe); | ||
135 | |||
136 | /* Enable IR reception on non-busrt mode */ | ||
137 | tm6000_set_reg(dev, TM6010_REQ07_RD8_IR, 0x2f); | ||
138 | |||
139 | /* IR_WKUP_SEL = Low byte in decoded IR data */ | ||
140 | tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff); | ||
141 | /* IR_WKU_ADD code */ | ||
142 | tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff); | ||
143 | |||
144 | tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, leader >> 8); | ||
145 | tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, leader); | ||
146 | |||
147 | tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, pulse >> 8); | ||
148 | tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, pulse); | ||
149 | |||
150 | if (!ir->polling) | ||
151 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); | ||
152 | else | ||
153 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); | ||
154 | msleep(10); | ||
155 | |||
156 | /* Shows that IR is working via the LED */ | ||
157 | tm6000_flash_led(dev, 0); | ||
158 | msleep(100); | ||
159 | tm6000_flash_led(dev, 1); | ||
160 | ir->pwled = 1; | ||
161 | |||
142 | return 0; | 162 | return 0; |
143 | } | 163 | } |
144 | 164 | ||
@@ -146,132 +166,124 @@ static void tm6000_ir_urb_received(struct urb *urb) | |||
146 | { | 166 | { |
147 | struct tm6000_core *dev = urb->context; | 167 | struct tm6000_core *dev = urb->context; |
148 | struct tm6000_IR *ir = dev->ir; | 168 | struct tm6000_IR *ir = dev->ir; |
169 | struct tm6000_ir_poll_result poll_result; | ||
170 | char *buf; | ||
149 | int rc; | 171 | int rc; |
150 | 172 | ||
151 | if (urb->status != 0) | 173 | dprintk(2, "%s\n",__func__); |
152 | printk(KERN_INFO "not ready\n"); | 174 | if (urb->status < 0 || urb->actual_length <= 0) { |
153 | else if (urb->actual_length > 0) { | 175 | printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n", |
154 | memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); | 176 | urb->status, urb->actual_length); |
177 | ir->submit_urb = 1; | ||
178 | schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); | ||
179 | return; | ||
180 | } | ||
181 | buf = urb->transfer_buffer; | ||
155 | 182 | ||
156 | dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], | 183 | if (ir_debug) |
157 | ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); | 184 | print_hex_dump(KERN_DEBUG, "tm6000: IR data: ", |
185 | DUMP_PREFIX_OFFSET,16, 1, | ||
186 | buf, urb->actual_length, false); | ||
158 | 187 | ||
159 | ir->key = 1; | 188 | poll_result.rc_data = buf[0]; |
160 | } | 189 | if (urb->actual_length > 1) |
190 | poll_result.rc_data |= buf[1] << 8; | ||
191 | |||
192 | dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); | ||
193 | rc_keydown(ir->rc, poll_result.rc_data, 0); | ||
161 | 194 | ||
162 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 195 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
196 | /* | ||
197 | * Flash the led. We can't do it here, as it is running on IRQ context. | ||
198 | * So, use the scheduler to do it, in a few ms. | ||
199 | */ | ||
200 | ir->pwled = 2; | ||
201 | schedule_delayed_work(&ir->work, msecs_to_jiffies(10)); | ||
163 | } | 202 | } |
164 | 203 | ||
165 | static int default_polling_getkey(struct tm6000_IR *ir, | 204 | static void tm6000_ir_handle_key(struct work_struct *work) |
166 | struct tm6000_ir_poll_result *poll_result) | ||
167 | { | 205 | { |
206 | struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); | ||
168 | struct tm6000_core *dev = ir->dev; | 207 | struct tm6000_core *dev = ir->dev; |
208 | struct tm6000_ir_poll_result poll_result; | ||
169 | int rc; | 209 | int rc; |
170 | u8 buf[2]; | 210 | u8 buf[2]; |
171 | 211 | ||
172 | if (ir->wait && !&dev->int_in) | 212 | if (ir->wait) |
173 | return 0; | 213 | return; |
174 | |||
175 | if (&dev->int_in) { | ||
176 | switch (ir->rc_type) { | ||
177 | case RC_TYPE_RC5: | ||
178 | poll_result->rc_data = ir->urb_data[0]; | ||
179 | break; | ||
180 | case RC_TYPE_NEC: | ||
181 | if (ir->urb_data[1] == ((ir->key_addr >> 8) & 0xff)) { | ||
182 | poll_result->rc_data = ir->urb_data[0] | ||
183 | | ir->urb_data[1] << 8; | ||
184 | } | ||
185 | break; | ||
186 | default: | ||
187 | poll_result->rc_data = ir->urb_data[0] | ||
188 | | ir->urb_data[1] << 8; | ||
189 | break; | ||
190 | } | ||
191 | } else { | ||
192 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); | ||
193 | msleep(10); | ||
194 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); | ||
195 | msleep(10); | ||
196 | |||
197 | if (ir->rc_type == RC_TYPE_RC5) { | ||
198 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | | ||
199 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
200 | REQ_02_GET_IR_CODE, 0, 0, buf, 1); | ||
201 | |||
202 | msleep(10); | ||
203 | |||
204 | dprintk("read data=%02x\n", buf[0]); | ||
205 | if (rc < 0) | ||
206 | return rc; | ||
207 | 214 | ||
208 | poll_result->rc_data = buf[0]; | 215 | dprintk(3, "%s\n",__func__); |
209 | } else { | ||
210 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | | ||
211 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
212 | REQ_02_GET_IR_CODE, 0, 0, buf, 2); | ||
213 | 216 | ||
214 | msleep(10); | 217 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | |
218 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
219 | REQ_02_GET_IR_CODE, 0, 0, buf, 2); | ||
220 | if (rc < 0) | ||
221 | return; | ||
215 | 222 | ||
216 | dprintk("read data=%04x\n", buf[0] | buf[1] << 8); | 223 | if (rc > 1) |
217 | if (rc < 0) | 224 | poll_result.rc_data = buf[0] | buf[1] << 8; |
218 | return rc; | 225 | else |
226 | poll_result.rc_data = buf[0]; | ||
219 | 227 | ||
220 | poll_result->rc_data = buf[0] | buf[1] << 8; | 228 | /* Check if something was read */ |
229 | if ((poll_result.rc_data & 0xff) == 0xff) { | ||
230 | if (!ir->pwled) { | ||
231 | tm6000_flash_led(dev, 1); | ||
232 | ir->pwled = 1; | ||
221 | } | 233 | } |
222 | if ((poll_result->rc_data & 0x00ff) != 0xff) | 234 | return; |
223 | ir->key = 1; | ||
224 | } | 235 | } |
225 | return 0; | 236 | |
237 | dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); | ||
238 | rc_keydown(ir->rc, poll_result.rc_data, 0); | ||
239 | tm6000_flash_led(dev, 0); | ||
240 | ir->pwled = 0; | ||
241 | |||
242 | /* Re-schedule polling */ | ||
243 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); | ||
226 | } | 244 | } |
227 | 245 | ||
228 | static void tm6000_ir_handle_key(struct tm6000_IR *ir) | 246 | static void tm6000_ir_int_work(struct work_struct *work) |
229 | { | 247 | { |
248 | struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); | ||
230 | struct tm6000_core *dev = ir->dev; | 249 | struct tm6000_core *dev = ir->dev; |
231 | int result; | 250 | int rc; |
232 | struct tm6000_ir_poll_result poll_result; | ||
233 | 251 | ||
234 | /* read the registers containing the IR status */ | 252 | dprintk(3, "%s, submit_urb = %d, pwled = %d\n",__func__, ir->submit_urb, |
235 | result = ir->get_key(ir, &poll_result); | 253 | ir->pwled); |
236 | if (result < 0) { | ||
237 | printk(KERN_INFO "ir->get_key() failed %d\n", result); | ||
238 | return; | ||
239 | } | ||
240 | 254 | ||
241 | dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); | 255 | if (ir->submit_urb) { |
256 | dprintk(3, "Resubmit urb\n"); | ||
257 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); | ||
242 | 258 | ||
243 | if (ir->pwled) { | 259 | rc = usb_submit_urb(ir->int_urb, GFP_ATOMIC); |
244 | if (ir->pwledcnt >= PWLED_OFF) { | 260 | if (rc < 0) { |
245 | ir->pwled = 0; | 261 | printk(KERN_ERR "tm6000: Can't submit an IR interrupt. Error %i\n", |
246 | ir->pwledcnt = 0; | 262 | rc); |
247 | tm6000_flash_led(dev, 1); | 263 | /* Retry in 100 ms */ |
248 | } else | 264 | schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); |
249 | ir->pwledcnt += 1; | 265 | return; |
266 | } | ||
267 | ir->submit_urb = 0; | ||
250 | } | 268 | } |
251 | 269 | ||
252 | if (ir->key) { | 270 | /* Led is enabled only if USB submit doesn't fail */ |
253 | rc_keydown(ir->rc, poll_result.rc_data, 0); | 271 | if (ir->pwled == 2) { |
254 | ir->key = 0; | ||
255 | ir->pwled = 1; | ||
256 | ir->pwledcnt = 0; | ||
257 | tm6000_flash_led(dev, 0); | 272 | tm6000_flash_led(dev, 0); |
273 | ir->pwled = 0; | ||
274 | schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_INT_LED_DELAY)); | ||
275 | } else if (!ir->pwled) { | ||
276 | tm6000_flash_led(dev, 1); | ||
277 | ir->pwled = 1; | ||
258 | } | 278 | } |
259 | return; | ||
260 | } | ||
261 | |||
262 | static void tm6000_ir_work(struct work_struct *work) | ||
263 | { | ||
264 | struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); | ||
265 | |||
266 | tm6000_ir_handle_key(ir); | ||
267 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); | ||
268 | } | 279 | } |
269 | 280 | ||
270 | static int tm6000_ir_start(struct rc_dev *rc) | 281 | static int tm6000_ir_start(struct rc_dev *rc) |
271 | { | 282 | { |
272 | struct tm6000_IR *ir = rc->priv; | 283 | struct tm6000_IR *ir = rc->priv; |
273 | 284 | ||
274 | INIT_DELAYED_WORK(&ir->work, tm6000_ir_work); | 285 | dprintk(2, "%s\n",__func__); |
286 | |||
275 | schedule_delayed_work(&ir->work, 0); | 287 | schedule_delayed_work(&ir->work, 0); |
276 | 288 | ||
277 | return 0; | 289 | return 0; |
@@ -281,6 +293,8 @@ static void tm6000_ir_stop(struct rc_dev *rc) | |||
281 | { | 293 | { |
282 | struct tm6000_IR *ir = rc->priv; | 294 | struct tm6000_IR *ir = rc->priv; |
283 | 295 | ||
296 | dprintk(2, "%s\n",__func__); | ||
297 | |||
284 | cancel_delayed_work_sync(&ir->work); | 298 | cancel_delayed_work_sync(&ir->work); |
285 | } | 299 | } |
286 | 300 | ||
@@ -291,10 +305,11 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type) | |||
291 | if (!ir) | 305 | if (!ir) |
292 | return 0; | 306 | return 0; |
293 | 307 | ||
308 | dprintk(2, "%s\n",__func__); | ||
309 | |||
294 | if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC)) | 310 | if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC)) |
295 | ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff); | 311 | ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff); |
296 | 312 | ||
297 | ir->get_key = default_polling_getkey; | ||
298 | ir->rc_type = rc_type; | 313 | ir->rc_type = rc_type; |
299 | 314 | ||
300 | tm6000_ir_config(ir); | 315 | tm6000_ir_config(ir); |
@@ -302,17 +317,19 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type) | |||
302 | return 0; | 317 | return 0; |
303 | } | 318 | } |
304 | 319 | ||
305 | int tm6000_ir_int_start(struct tm6000_core *dev) | 320 | static int __tm6000_ir_int_start(struct rc_dev *rc) |
306 | { | 321 | { |
307 | struct tm6000_IR *ir = dev->ir; | 322 | struct tm6000_IR *ir = rc->priv; |
323 | struct tm6000_core *dev = ir->dev; | ||
308 | int pipe, size; | 324 | int pipe, size; |
309 | int err = -ENOMEM; | 325 | int err = -ENOMEM; |
310 | 326 | ||
311 | |||
312 | if (!ir) | 327 | if (!ir) |
313 | return -ENODEV; | 328 | return -ENODEV; |
314 | 329 | ||
315 | ir->int_urb = usb_alloc_urb(0, GFP_KERNEL); | 330 | dprintk(2, "%s\n",__func__); |
331 | |||
332 | ir->int_urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
316 | if (!ir->int_urb) | 333 | if (!ir->int_urb) |
317 | return -ENOMEM; | 334 | return -ENOMEM; |
318 | 335 | ||
@@ -321,42 +338,59 @@ int tm6000_ir_int_start(struct tm6000_core *dev) | |||
321 | & USB_ENDPOINT_NUMBER_MASK); | 338 | & USB_ENDPOINT_NUMBER_MASK); |
322 | 339 | ||
323 | size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); | 340 | size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); |
324 | dprintk("IR max size: %d\n", size); | 341 | dprintk(1, "IR max size: %d\n", size); |
325 | 342 | ||
326 | ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); | 343 | ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC); |
327 | if (ir->int_urb->transfer_buffer == NULL) { | 344 | if (ir->int_urb->transfer_buffer == NULL) { |
328 | usb_free_urb(ir->int_urb); | 345 | usb_free_urb(ir->int_urb); |
329 | return err; | 346 | return err; |
330 | } | 347 | } |
331 | dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval); | 348 | dprintk(1, "int interval: %d\n", dev->int_in.endp->desc.bInterval); |
349 | |||
332 | usb_fill_int_urb(ir->int_urb, dev->udev, pipe, | 350 | usb_fill_int_urb(ir->int_urb, dev->udev, pipe, |
333 | ir->int_urb->transfer_buffer, size, | 351 | ir->int_urb->transfer_buffer, size, |
334 | tm6000_ir_urb_received, dev, | 352 | tm6000_ir_urb_received, dev, |
335 | dev->int_in.endp->desc.bInterval); | 353 | dev->int_in.endp->desc.bInterval); |
336 | err = usb_submit_urb(ir->int_urb, GFP_KERNEL); | 354 | |
337 | if (err) { | 355 | ir->submit_urb = 1; |
338 | kfree(ir->int_urb->transfer_buffer); | 356 | schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); |
339 | usb_free_urb(ir->int_urb); | ||
340 | return err; | ||
341 | } | ||
342 | ir->urb_data = kzalloc(size, GFP_KERNEL); | ||
343 | 357 | ||
344 | return 0; | 358 | return 0; |
345 | } | 359 | } |
346 | 360 | ||
347 | void tm6000_ir_int_stop(struct tm6000_core *dev) | 361 | static void __tm6000_ir_int_stop(struct rc_dev *rc) |
348 | { | 362 | { |
349 | struct tm6000_IR *ir = dev->ir; | 363 | struct tm6000_IR *ir = rc->priv; |
350 | 364 | ||
351 | if (!ir) | 365 | if (!ir || !ir->int_urb) |
352 | return; | 366 | return; |
353 | 367 | ||
368 | dprintk(2, "%s\n",__func__); | ||
369 | |||
354 | usb_kill_urb(ir->int_urb); | 370 | usb_kill_urb(ir->int_urb); |
355 | kfree(ir->int_urb->transfer_buffer); | 371 | kfree(ir->int_urb->transfer_buffer); |
356 | usb_free_urb(ir->int_urb); | 372 | usb_free_urb(ir->int_urb); |
357 | ir->int_urb = NULL; | 373 | ir->int_urb = NULL; |
358 | kfree(ir->urb_data); | 374 | } |
359 | ir->urb_data = NULL; | 375 | |
376 | int tm6000_ir_int_start(struct tm6000_core *dev) | ||
377 | { | ||
378 | struct tm6000_IR *ir = dev->ir; | ||
379 | |||
380 | if (!ir) | ||
381 | return 0; | ||
382 | |||
383 | return __tm6000_ir_int_start(ir->rc); | ||
384 | } | ||
385 | |||
386 | void tm6000_ir_int_stop(struct tm6000_core *dev) | ||
387 | { | ||
388 | struct tm6000_IR *ir = dev->ir; | ||
389 | |||
390 | if (!ir || !ir->rc) | ||
391 | return; | ||
392 | |||
393 | __tm6000_ir_int_stop(ir->rc); | ||
360 | } | 394 | } |
361 | 395 | ||
362 | int tm6000_ir_init(struct tm6000_core *dev) | 396 | int tm6000_ir_init(struct tm6000_core *dev) |
@@ -374,7 +408,9 @@ int tm6000_ir_init(struct tm6000_core *dev) | |||
374 | if (!dev->ir_codes) | 408 | if (!dev->ir_codes) |
375 | return 0; | 409 | return 0; |
376 | 410 | ||
377 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 411 | dprintk(2, "%s\n",__func__); |
412 | |||
413 | ir = kzalloc(sizeof(*ir), GFP_ATOMIC); | ||
378 | rc = rc_allocate_device(); | 414 | rc = rc_allocate_device(); |
379 | if (!ir || !rc) | 415 | if (!ir || !rc) |
380 | goto out; | 416 | goto out; |
@@ -384,19 +420,24 @@ int tm6000_ir_init(struct tm6000_core *dev) | |||
384 | dev->ir = ir; | 420 | dev->ir = ir; |
385 | ir->rc = rc; | 421 | ir->rc = rc; |
386 | 422 | ||
387 | /* input einrichten */ | 423 | /* input setup */ |
388 | rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; | 424 | rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; |
425 | /* Neded, in order to support NEC remotes with 24 or 32 bits */ | ||
426 | rc->scanmask = 0xffff; | ||
389 | rc->priv = ir; | 427 | rc->priv = ir; |
390 | rc->change_protocol = tm6000_ir_change_protocol; | 428 | rc->change_protocol = tm6000_ir_change_protocol; |
391 | rc->open = tm6000_ir_start; | 429 | if (dev->int_in.endp) { |
392 | rc->close = tm6000_ir_stop; | 430 | rc->open = __tm6000_ir_int_start; |
431 | rc->close = __tm6000_ir_int_stop; | ||
432 | INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work); | ||
433 | } else { | ||
434 | rc->open = tm6000_ir_start; | ||
435 | rc->close = tm6000_ir_stop; | ||
436 | ir->polling = 50; | ||
437 | INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key); | ||
438 | } | ||
393 | rc->driver_type = RC_DRIVER_SCANCODE; | 439 | rc->driver_type = RC_DRIVER_SCANCODE; |
394 | 440 | ||
395 | ir->polling = 50; | ||
396 | ir->pwled = 0; | ||
397 | ir->pwledcnt = 0; | ||
398 | |||
399 | |||
400 | snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)", | 441 | snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)", |
401 | dev->name); | 442 | dev->name); |
402 | 443 | ||
@@ -415,15 +456,6 @@ int tm6000_ir_init(struct tm6000_core *dev) | |||
415 | rc->driver_name = "tm6000"; | 456 | rc->driver_name = "tm6000"; |
416 | rc->dev.parent = &dev->udev->dev; | 457 | rc->dev.parent = &dev->udev->dev; |
417 | 458 | ||
418 | if (&dev->int_in) { | ||
419 | dprintk("IR over int\n"); | ||
420 | |||
421 | err = tm6000_ir_int_start(dev); | ||
422 | |||
423 | if (err) | ||
424 | goto out; | ||
425 | } | ||
426 | |||
427 | /* ir register */ | 459 | /* ir register */ |
428 | err = rc_register_device(rc); | 460 | err = rc_register_device(rc); |
429 | if (err) | 461 | if (err) |
@@ -447,10 +479,19 @@ int tm6000_ir_fini(struct tm6000_core *dev) | |||
447 | if (!ir) | 479 | if (!ir) |
448 | return 0; | 480 | return 0; |
449 | 481 | ||
482 | dprintk(2, "%s\n",__func__); | ||
483 | |||
450 | rc_unregister_device(ir->rc); | 484 | rc_unregister_device(ir->rc); |
451 | 485 | ||
452 | if (ir->int_urb) | 486 | if (!ir->polling) |
453 | tm6000_ir_int_stop(dev); | 487 | __tm6000_ir_int_stop(ir->rc); |
488 | |||
489 | tm6000_ir_stop(ir->rc); | ||
490 | |||
491 | /* Turn off the led */ | ||
492 | tm6000_flash_led(dev, 0); | ||
493 | ir->pwled = 0; | ||
494 | |||
454 | 495 | ||
455 | kfree(ir); | 496 | kfree(ir); |
456 | dev->ir = NULL; | 497 | dev->ir = NULL; |
diff --git a/drivers/media/video/tm6000/tm6000-regs.h b/drivers/media/video/tm6000/tm6000-regs.h index 7f491b6de933..a38c251ed57b 100644 --- a/drivers/media/video/tm6000/tm6000-regs.h +++ b/drivers/media/video/tm6000/tm6000-regs.h | |||
@@ -284,19 +284,19 @@ enum { | |||
284 | /* ONLY for TM6010 */ | 284 | /* ONLY for TM6010 */ |
285 | #define TM6010_REQ07_RD8_IR 0x07, 0xd8 | 285 | #define TM6010_REQ07_RD8_IR 0x07, 0xd8 |
286 | /* ONLY for TM6010 */ | 286 | /* ONLY for TM6010 */ |
287 | #define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9 | 287 | #define TM6010_REQ07_RD9_IR_BSIZE 0x07, 0xd9 |
288 | /* ONLY for TM6010 */ | 288 | /* ONLY for TM6010 */ |
289 | #define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda | 289 | #define TM6010_REQ07_RDA_IR_WAKEUP_SEL 0x07, 0xda |
290 | /* ONLY for TM6010 */ | 290 | /* ONLY for TM6010 */ |
291 | #define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb | 291 | #define TM6010_REQ07_RDB_IR_WAKEUP_ADD 0x07, 0xdb |
292 | /* ONLY for TM6010 */ | 292 | /* ONLY for TM6010 */ |
293 | #define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc | 293 | #define TM6010_REQ07_RDC_IR_LEADER1 0x07, 0xdc |
294 | /* ONLY for TM6010 */ | 294 | /* ONLY for TM6010 */ |
295 | #define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd | 295 | #define TM6010_REQ07_RDD_IR_LEADER0 0x07, 0xdd |
296 | /* ONLY for TM6010 */ | 296 | /* ONLY for TM6010 */ |
297 | #define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde | 297 | #define TM6010_REQ07_RDE_IR_PULSE_CNT1 0x07, 0xde |
298 | /* ONLY for TM6010 */ | 298 | /* ONLY for TM6010 */ |
299 | #define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf | 299 | #define TM6010_REQ07_RDF_IR_PULSE_CNT0 0x07, 0xdf |
300 | /* ONLY for TM6010 */ | 300 | /* ONLY for TM6010 */ |
301 | #define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0 | 301 | #define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0 |
302 | /* ONLY for TM6010 */ | 302 | /* ONLY for TM6010 */ |
diff --git a/drivers/media/video/tm6000/tm6000-stds.c b/drivers/media/video/tm6000/tm6000-stds.c index 9a4145dc3d87..9dc0831d813f 100644 --- a/drivers/media/video/tm6000/tm6000-stds.c +++ b/drivers/media/video/tm6000/tm6000-stds.c | |||
@@ -361,82 +361,51 @@ static int tm6000_set_audio_std(struct tm6000_core *dev) | |||
361 | return 0; | 361 | return 0; |
362 | } | 362 | } |
363 | 363 | ||
364 | switch (tm6010_a_mode) { | 364 | /* |
365 | * STD/MN shouldn't be affected by tm6010_a_mode, as there's just one | ||
366 | * audio standard for each V4L2_STD type. | ||
367 | */ | ||
368 | if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_KR) { | ||
369 | areg_05 |= 0x04; | ||
370 | } else if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_JP) { | ||
371 | areg_05 |= 0x43; | ||
372 | } else if (dev->norm & V4L2_STD_MN) { | ||
373 | areg_05 |= 0x22; | ||
374 | } else switch (tm6010_a_mode) { | ||
365 | /* auto */ | 375 | /* auto */ |
366 | case 0: | 376 | case 0: |
367 | switch (dev->norm) { | 377 | if ((dev->norm & V4L2_STD_SECAM) == V4L2_STD_SECAM_L) |
368 | case V4L2_STD_NTSC_M_KR: | ||
369 | areg_05 |= 0x00; | 378 | areg_05 |= 0x00; |
370 | break; | 379 | else /* Other PAL/SECAM standards */ |
371 | case V4L2_STD_NTSC_M_JP: | ||
372 | areg_05 |= 0x40; | ||
373 | break; | ||
374 | case V4L2_STD_NTSC_M: | ||
375 | case V4L2_STD_PAL_M: | ||
376 | case V4L2_STD_PAL_N: | ||
377 | areg_05 |= 0x20; | ||
378 | break; | ||
379 | case V4L2_STD_PAL_Nc: | ||
380 | areg_05 |= 0x60; | ||
381 | break; | ||
382 | case V4L2_STD_SECAM_L: | ||
383 | areg_05 |= 0x00; | ||
384 | break; | ||
385 | case V4L2_STD_DK: | ||
386 | areg_05 |= 0x10; | 380 | areg_05 |= 0x10; |
387 | break; | ||
388 | } | ||
389 | break; | 381 | break; |
390 | /* A2 */ | 382 | /* A2 */ |
391 | case 1: | 383 | case 1: |
392 | switch (dev->norm) { | 384 | if (dev->norm & V4L2_STD_DK) |
393 | case V4L2_STD_B: | ||
394 | case V4L2_STD_GH: | ||
395 | areg_05 = 0x05; | ||
396 | break; | ||
397 | case V4L2_STD_DK: | ||
398 | areg_05 = 0x09; | 385 | areg_05 = 0x09; |
399 | break; | 386 | else |
400 | } | 387 | areg_05 = 0x05; |
401 | break; | 388 | break; |
402 | /* NICAM */ | 389 | /* NICAM */ |
403 | case 2: | 390 | case 2: |
404 | switch (dev->norm) { | 391 | if (dev->norm & V4L2_STD_DK) { |
405 | case V4L2_STD_B: | ||
406 | case V4L2_STD_GH: | ||
407 | areg_05 = 0x07; | ||
408 | break; | ||
409 | case V4L2_STD_DK: | ||
410 | areg_05 = 0x06; | 392 | areg_05 = 0x06; |
411 | break; | 393 | } else if (dev->norm & V4L2_STD_PAL_I) { |
412 | case V4L2_STD_PAL_I: | ||
413 | areg_05 = 0x08; | 394 | areg_05 = 0x08; |
414 | break; | 395 | } else if (dev->norm & V4L2_STD_SECAM_L) { |
415 | case V4L2_STD_SECAM_L: | ||
416 | areg_05 = 0x0a; | 396 | areg_05 = 0x0a; |
417 | areg_02 = 0x02; | 397 | areg_02 = 0x02; |
418 | break; | 398 | } else { |
399 | areg_05 = 0x07; | ||
419 | } | 400 | } |
420 | nicam_flag = 1; | 401 | nicam_flag = 1; |
421 | break; | 402 | break; |
422 | /* other */ | 403 | /* other */ |
423 | case 3: | 404 | case 3: |
424 | switch (dev->norm) { | 405 | if (dev->norm & V4L2_STD_DK) { |
425 | /* DK3_A2 */ | ||
426 | case V4L2_STD_DK: | ||
427 | areg_05 = 0x0b; | 406 | areg_05 = 0x0b; |
428 | break; | 407 | } else { |
429 | /* Korea */ | ||
430 | case V4L2_STD_NTSC_M_KR: | ||
431 | areg_05 = 0x04; | ||
432 | break; | ||
433 | /* EIAJ */ | ||
434 | case V4L2_STD_NTSC_M_JP: | ||
435 | areg_05 = 0x03; | ||
436 | break; | ||
437 | default: | ||
438 | areg_05 = 0x02; | 408 | areg_05 = 0x02; |
439 | break; | ||
440 | } | 409 | } |
441 | break; | 410 | break; |
442 | } | 411 | } |
@@ -557,10 +526,16 @@ int tm6000_set_standard(struct tm6000_core *dev) | |||
557 | case TM6000_AMUX_ADC1: | 526 | case TM6000_AMUX_ADC1: |
558 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, | 527 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, |
559 | 0x00, 0x0f); | 528 | 0x00, 0x0f); |
529 | /* Mux overflow workaround */ | ||
530 | tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, | ||
531 | 0x10, 0xf0); | ||
560 | break; | 532 | break; |
561 | case TM6000_AMUX_ADC2: | 533 | case TM6000_AMUX_ADC2: |
562 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, | 534 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, |
563 | 0x08, 0x0f); | 535 | 0x08, 0x0f); |
536 | /* Mux overflow workaround */ | ||
537 | tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, | ||
538 | 0x10, 0xf0); | ||
564 | break; | 539 | break; |
565 | case TM6000_AMUX_SIF1: | 540 | case TM6000_AMUX_SIF1: |
566 | reg_08_e2 |= 0x02; | 541 | reg_08_e2 |= 0x02; |
@@ -570,6 +545,9 @@ int tm6000_set_standard(struct tm6000_core *dev) | |||
570 | tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3); | 545 | tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3); |
571 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, | 546 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, |
572 | 0x02, 0x0f); | 547 | 0x02, 0x0f); |
548 | /* Mux overflow workaround */ | ||
549 | tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, | ||
550 | 0x30, 0xf0); | ||
573 | break; | 551 | break; |
574 | case TM6000_AMUX_SIF2: | 552 | case TM6000_AMUX_SIF2: |
575 | reg_08_e2 |= 0x02; | 553 | reg_08_e2 |= 0x02; |
@@ -579,6 +557,9 @@ int tm6000_set_standard(struct tm6000_core *dev) | |||
579 | tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7); | 557 | tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7); |
580 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, | 558 | tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, |
581 | 0x02, 0x0f); | 559 | 0x02, 0x0f); |
560 | /* Mux overflow workaround */ | ||
561 | tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, | ||
562 | 0x30, 0xf0); | ||
582 | break; | 563 | break; |
583 | default: | 564 | default: |
584 | break; | 565 | break; |
diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c index 1e5ace0b5d10..bc13db736e24 100644 --- a/drivers/media/video/tm6000/tm6000-video.c +++ b/drivers/media/video/tm6000/tm6000-video.c | |||
@@ -1605,16 +1605,25 @@ static int tm6000_release(struct file *file) | |||
1605 | res_free(dev, fh); | 1605 | res_free(dev, fh); |
1606 | 1606 | ||
1607 | if (!dev->users) { | 1607 | if (!dev->users) { |
1608 | int err; | ||
1609 | |||
1610 | tm6000_uninit_isoc(dev); | 1608 | tm6000_uninit_isoc(dev); |
1611 | 1609 | ||
1610 | /* Stop interrupt USB pipe */ | ||
1611 | tm6000_ir_int_stop(dev); | ||
1612 | |||
1613 | usb_reset_configuration(dev->udev); | ||
1614 | |||
1615 | if (dev->int_in.endp) | ||
1616 | usb_set_interface(dev->udev, | ||
1617 | dev->isoc_in.bInterfaceNumber, 2); | ||
1618 | else | ||
1619 | usb_set_interface(dev->udev, | ||
1620 | dev->isoc_in.bInterfaceNumber, 0); | ||
1621 | |||
1622 | /* Start interrupt USB pipe */ | ||
1623 | tm6000_ir_int_start(dev); | ||
1624 | |||
1612 | if (!fh->radio) | 1625 | if (!fh->radio) |
1613 | videobuf_mmap_free(&fh->vb_vidq); | 1626 | videobuf_mmap_free(&fh->vb_vidq); |
1614 | |||
1615 | err = tm6000_reset(dev); | ||
1616 | if (err < 0) | ||
1617 | dev_err(&vdev->dev, "reset failed: %d\n", err); | ||
1618 | } | 1627 | } |
1619 | 1628 | ||
1620 | kfree(fh); | 1629 | kfree(fh); |
diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/video/tm6000/tm6000.h index 2777e514eff2..27ba659cfa85 100644 --- a/drivers/media/video/tm6000/tm6000.h +++ b/drivers/media/video/tm6000/tm6000.h | |||
@@ -188,6 +188,9 @@ struct tm6000_core { | |||
188 | /* Device Capabilities*/ | 188 | /* Device Capabilities*/ |
189 | struct tm6000_capabilities caps; | 189 | struct tm6000_capabilities caps; |
190 | 190 | ||
191 | /* Used to load alsa/dvb */ | ||
192 | struct work_struct request_module_wk; | ||
193 | |||
191 | /* Tuner configuration */ | 194 | /* Tuner configuration */ |
192 | int tuner_type; /* type of the tuner */ | 195 | int tuner_type; /* type of the tuner */ |
193 | int tuner_addr; /* tuner address */ | 196 | int tuner_addr; /* tuner address */ |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 6abaa16ae136..fc91a1ec54a0 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -703,21 +703,21 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std) | |||
703 | /* First tests should be against specific std */ | 703 | /* First tests should be against specific std */ |
704 | 704 | ||
705 | if (std == V4L2_STD_ALL) { | 705 | if (std == V4L2_STD_ALL) { |
706 | fmt = 0; /* Autodetect mode */ | 706 | fmt = VIDEO_STD_AUTO_SWITCH_BIT; /* Autodetect mode */ |
707 | } else if (std & V4L2_STD_NTSC_443) { | 707 | } else if (std & V4L2_STD_NTSC_443) { |
708 | fmt = 0xa; | 708 | fmt = VIDEO_STD_NTSC_4_43_BIT; |
709 | } else if (std & V4L2_STD_PAL_M) { | 709 | } else if (std & V4L2_STD_PAL_M) { |
710 | fmt = 0x6; | 710 | fmt = VIDEO_STD_PAL_M_BIT; |
711 | } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) { | 711 | } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) { |
712 | fmt = 0x8; | 712 | fmt = VIDEO_STD_PAL_COMBINATION_N_BIT; |
713 | } else { | 713 | } else { |
714 | /* Then, test against generic ones */ | 714 | /* Then, test against generic ones */ |
715 | if (std & V4L2_STD_NTSC) | 715 | if (std & V4L2_STD_NTSC) |
716 | fmt = 0x2; | 716 | fmt = VIDEO_STD_NTSC_MJ_BIT; |
717 | else if (std & V4L2_STD_PAL) | 717 | else if (std & V4L2_STD_PAL) |
718 | fmt = 0x4; | 718 | fmt = VIDEO_STD_PAL_BDGHIN_BIT; |
719 | else if (std & V4L2_STD_SECAM) | 719 | else if (std & V4L2_STD_SECAM) |
720 | fmt = 0xc; | 720 | fmt = VIDEO_STD_SECAM_BIT; |
721 | } | 721 | } |
722 | 722 | ||
723 | v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt); | 723 | v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt); |
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index d7f97513b289..89fec029e924 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c | |||
@@ -110,42 +110,20 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap, | |||
110 | 110 | ||
111 | unsigned char addr; | 111 | unsigned char addr; |
112 | int ret; | 112 | int ret; |
113 | if ((flags & I2C_M_TEN)) { | ||
114 | /* a ten bit address */ | ||
115 | addr = 0xf0 | ((msg->addr >> 7) & 0x03); | ||
116 | /* try extended address code... */ | ||
117 | ret = try_write_address(i2c_adap, addr, retries); | ||
118 | if (ret != 1) { | ||
119 | dev_err(&i2c_adap->dev, | ||
120 | "died at extended address code, while writing\n"); | ||
121 | return -EREMOTEIO; | ||
122 | } | ||
123 | add[0] = addr; | ||
124 | if (flags & I2C_M_RD) { | ||
125 | /* okay, now switch into reading mode */ | ||
126 | addr |= 0x01; | ||
127 | ret = try_read_address(i2c_adap, addr, retries); | ||
128 | if (ret != 1) { | ||
129 | dev_err(&i2c_adap->dev, | ||
130 | "died at extended address code, while reading\n"); | ||
131 | return -EREMOTEIO; | ||
132 | } | ||
133 | } | ||
134 | 113 | ||
135 | } else { /* normal 7bit address */ | 114 | addr = (msg->addr << 1); |
136 | addr = (msg->addr << 1); | 115 | if (flags & I2C_M_RD) |
137 | if (flags & I2C_M_RD) | 116 | addr |= 1; |
138 | addr |= 1; | ||
139 | 117 | ||
140 | add[0] = addr; | 118 | add[0] = addr; |
141 | if (flags & I2C_M_RD) | 119 | if (flags & I2C_M_RD) |
142 | ret = try_read_address(i2c_adap, addr, retries); | 120 | ret = try_read_address(i2c_adap, addr, retries); |
143 | else | 121 | else |
144 | ret = try_write_address(i2c_adap, addr, retries); | 122 | ret = try_write_address(i2c_adap, addr, retries); |
123 | |||
124 | if (ret != 1) | ||
125 | return -EREMOTEIO; | ||
145 | 126 | ||
146 | if (ret != 1) | ||
147 | return -EREMOTEIO; | ||
148 | } | ||
149 | return 0; | 127 | return 0; |
150 | } | 128 | } |
151 | 129 | ||
@@ -184,7 +162,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) | |||
184 | 162 | ||
185 | static u32 functionality(struct i2c_adapter *adap) | 163 | static u32 functionality(struct i2c_adapter *adap) |
186 | { | 164 | { |
187 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; | 165 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
188 | } | 166 | } |
189 | 167 | ||
190 | /* -----exported algorithm data: ------------------------------------- */ | 168 | /* -----exported algorithm data: ------------------------------------- */ |
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig index 2956a7637219..6c197da531b2 100644 --- a/drivers/media/video/uvc/Kconfig +++ b/drivers/media/video/uvc/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config USB_VIDEO_CLASS | 1 | config USB_VIDEO_CLASS |
2 | tristate "USB Video Class (UVC)" | 2 | tristate "USB Video Class (UVC)" |
3 | select VIDEOBUF2_VMALLOC | ||
3 | ---help--- | 4 | ---help--- |
4 | Support for the USB Video Class (UVC). Currently only video | 5 | Support for the USB Video Class (UVC). Currently only video |
5 | input devices, such as webcams, are supported. | 6 | input devices, such as webcams, are supported. |
diff --git a/drivers/media/video/uvc/Makefile b/drivers/media/video/uvc/Makefile index 2071ca8a2f03..c26d12fdb8f4 100644 --- a/drivers/media/video/uvc/Makefile +++ b/drivers/media/video/uvc/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \ | 1 | uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \ |
2 | uvc_status.o uvc_isight.o | 2 | uvc_status.o uvc_isight.o uvc_debugfs.o |
3 | ifeq ($(CONFIG_MEDIA_CONTROLLER),y) | 3 | ifeq ($(CONFIG_MEDIA_CONTROLLER),y) |
4 | uvcvideo-objs += uvc_entity.o | 4 | uvcvideo-objs += uvc_entity.o |
5 | endif | 5 | endif |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 254d32688843..3e849d977bd4 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -878,8 +878,21 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, | |||
878 | chain->dev->intfnum, ctrl->info.selector, | 878 | chain->dev->intfnum, ctrl->info.selector, |
879 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), | 879 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), |
880 | ctrl->info.size); | 880 | ctrl->info.size); |
881 | if (ret < 0) | 881 | if (ret < 0) { |
882 | return ret; | 882 | if (UVC_ENTITY_TYPE(ctrl->entity) != |
883 | UVC_VC_EXTENSION_UNIT) | ||
884 | return ret; | ||
885 | |||
886 | /* GET_RES is mandatory for XU controls, but some | ||
887 | * cameras still choke on it. Ignore errors and set the | ||
888 | * resolution value to zero. | ||
889 | */ | ||
890 | uvc_warn_once(chain->dev, UVC_WARN_XU_GET_RES, | ||
891 | "UVC non compliance - GET_RES failed on " | ||
892 | "an XU control. Enabling workaround.\n"); | ||
893 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 0, | ||
894 | ctrl->info.size); | ||
895 | } | ||
883 | } | 896 | } |
884 | 897 | ||
885 | ctrl->cached = 1; | 898 | ctrl->cached = 1; |
diff --git a/drivers/media/video/uvc/uvc_debugfs.c b/drivers/media/video/uvc/uvc_debugfs.c new file mode 100644 index 000000000000..14561a5abb79 --- /dev/null +++ b/drivers/media/video/uvc/uvc_debugfs.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * uvc_debugfs.c -- USB Video Class driver - Debugging support | ||
3 | * | ||
4 | * Copyright (C) 2011 | ||
5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/debugfs.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/usb.h> | ||
18 | |||
19 | #include "uvcvideo.h" | ||
20 | |||
21 | /* ----------------------------------------------------------------------------- | ||
22 | * Statistics | ||
23 | */ | ||
24 | |||
25 | #define UVC_DEBUGFS_BUF_SIZE 1024 | ||
26 | |||
27 | struct uvc_debugfs_buffer { | ||
28 | size_t count; | ||
29 | char data[UVC_DEBUGFS_BUF_SIZE]; | ||
30 | }; | ||
31 | |||
32 | static int uvc_debugfs_stats_open(struct inode *inode, struct file *file) | ||
33 | { | ||
34 | struct uvc_streaming *stream = inode->i_private; | ||
35 | struct uvc_debugfs_buffer *buf; | ||
36 | |||
37 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); | ||
38 | if (buf == NULL) | ||
39 | return -ENOMEM; | ||
40 | |||
41 | buf->count = uvc_video_stats_dump(stream, buf->data, sizeof(buf->data)); | ||
42 | |||
43 | file->private_data = buf; | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static ssize_t uvc_debugfs_stats_read(struct file *file, char __user *user_buf, | ||
48 | size_t nbytes, loff_t *ppos) | ||
49 | { | ||
50 | struct uvc_debugfs_buffer *buf = file->private_data; | ||
51 | |||
52 | return simple_read_from_buffer(user_buf, nbytes, ppos, buf->data, | ||
53 | buf->count); | ||
54 | } | ||
55 | |||
56 | static int uvc_debugfs_stats_release(struct inode *inode, struct file *file) | ||
57 | { | ||
58 | kfree(file->private_data); | ||
59 | file->private_data = NULL; | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static const struct file_operations uvc_debugfs_stats_fops = { | ||
65 | .owner = THIS_MODULE, | ||
66 | .open = uvc_debugfs_stats_open, | ||
67 | .llseek = no_llseek, | ||
68 | .read = uvc_debugfs_stats_read, | ||
69 | .release = uvc_debugfs_stats_release, | ||
70 | }; | ||
71 | |||
72 | /* ----------------------------------------------------------------------------- | ||
73 | * Global and stream initialization/cleanup | ||
74 | */ | ||
75 | |||
76 | static struct dentry *uvc_debugfs_root_dir; | ||
77 | |||
78 | int uvc_debugfs_init_stream(struct uvc_streaming *stream) | ||
79 | { | ||
80 | struct usb_device *udev = stream->dev->udev; | ||
81 | struct dentry *dent; | ||
82 | char dir_name[32]; | ||
83 | |||
84 | if (uvc_debugfs_root_dir == NULL) | ||
85 | return -ENODEV; | ||
86 | |||
87 | sprintf(dir_name, "%u-%u", udev->bus->busnum, udev->devnum); | ||
88 | |||
89 | dent = debugfs_create_dir(dir_name, uvc_debugfs_root_dir); | ||
90 | if (IS_ERR_OR_NULL(dent)) { | ||
91 | uvc_printk(KERN_INFO, "Unable to create debugfs %s " | ||
92 | "directory.\n", dir_name); | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | stream->debugfs_dir = dent; | ||
97 | |||
98 | dent = debugfs_create_file("stats", 0444, stream->debugfs_dir, | ||
99 | stream, &uvc_debugfs_stats_fops); | ||
100 | if (IS_ERR_OR_NULL(dent)) { | ||
101 | uvc_printk(KERN_INFO, "Unable to create debugfs stats file.\n"); | ||
102 | uvc_debugfs_cleanup_stream(stream); | ||
103 | return -ENODEV; | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream) | ||
110 | { | ||
111 | if (stream->debugfs_dir == NULL) | ||
112 | return; | ||
113 | |||
114 | debugfs_remove_recursive(stream->debugfs_dir); | ||
115 | stream->debugfs_dir = NULL; | ||
116 | } | ||
117 | |||
118 | int uvc_debugfs_init(void) | ||
119 | { | ||
120 | struct dentry *dir; | ||
121 | |||
122 | dir = debugfs_create_dir("uvcvideo", usb_debug_root); | ||
123 | if (IS_ERR_OR_NULL(dir)) { | ||
124 | uvc_printk(KERN_INFO, "Unable to create debugfs directory\n"); | ||
125 | return -ENODATA; | ||
126 | } | ||
127 | |||
128 | uvc_debugfs_root_dir = dir; | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | void uvc_debugfs_cleanup(void) | ||
133 | { | ||
134 | if (uvc_debugfs_root_dir != NULL) | ||
135 | debugfs_remove_recursive(uvc_debugfs_root_dir); | ||
136 | } | ||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 656d4c9e3b9f..a240d43d15d1 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -1675,6 +1675,8 @@ static void uvc_unregister_video(struct uvc_device *dev) | |||
1675 | 1675 | ||
1676 | video_unregister_device(stream->vdev); | 1676 | video_unregister_device(stream->vdev); |
1677 | stream->vdev = NULL; | 1677 | stream->vdev = NULL; |
1678 | |||
1679 | uvc_debugfs_cleanup_stream(stream); | ||
1678 | } | 1680 | } |
1679 | 1681 | ||
1680 | /* Decrement the stream count and call uvc_delete explicitly if there | 1682 | /* Decrement the stream count and call uvc_delete explicitly if there |
@@ -1700,6 +1702,8 @@ static int uvc_register_video(struct uvc_device *dev, | |||
1700 | return ret; | 1702 | return ret; |
1701 | } | 1703 | } |
1702 | 1704 | ||
1705 | uvc_debugfs_init_stream(stream); | ||
1706 | |||
1703 | /* Register the device with V4L. */ | 1707 | /* Register the device with V4L. */ |
1704 | vdev = video_device_alloc(); | 1708 | vdev = video_device_alloc(); |
1705 | if (vdev == NULL) { | 1709 | if (vdev == NULL) { |
@@ -2033,6 +2037,15 @@ MODULE_PARM_DESC(timeout, "Streaming control requests timeout"); | |||
2033 | * though they are compliant. | 2037 | * though they are compliant. |
2034 | */ | 2038 | */ |
2035 | static struct usb_device_id uvc_ids[] = { | 2039 | static struct usb_device_id uvc_ids[] = { |
2040 | /* LogiLink Wireless Webcam */ | ||
2041 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
2042 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
2043 | .idVendor = 0x0416, | ||
2044 | .idProduct = 0xa91a, | ||
2045 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
2046 | .bInterfaceSubClass = 1, | ||
2047 | .bInterfaceProtocol = 0, | ||
2048 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
2036 | /* Genius eFace 2025 */ | 2049 | /* Genius eFace 2025 */ |
2037 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2050 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2038 | | USB_DEVICE_ID_MATCH_INT_INFO, | 2051 | | USB_DEVICE_ID_MATCH_INT_INFO, |
@@ -2396,17 +2409,24 @@ struct uvc_driver uvc_driver = { | |||
2396 | 2409 | ||
2397 | static int __init uvc_init(void) | 2410 | static int __init uvc_init(void) |
2398 | { | 2411 | { |
2399 | int result; | 2412 | int ret; |
2413 | |||
2414 | uvc_debugfs_init(); | ||
2400 | 2415 | ||
2401 | result = usb_register(&uvc_driver.driver); | 2416 | ret = usb_register(&uvc_driver.driver); |
2402 | if (result == 0) | 2417 | if (ret < 0) { |
2403 | printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n"); | 2418 | uvc_debugfs_cleanup(); |
2404 | return result; | 2419 | return ret; |
2420 | } | ||
2421 | |||
2422 | printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n"); | ||
2423 | return 0; | ||
2405 | } | 2424 | } |
2406 | 2425 | ||
2407 | static void __exit uvc_cleanup(void) | 2426 | static void __exit uvc_cleanup(void) |
2408 | { | 2427 | { |
2409 | usb_deregister(&uvc_driver.driver); | 2428 | usb_deregister(&uvc_driver.driver); |
2429 | uvc_debugfs_cleanup(); | ||
2410 | } | 2430 | } |
2411 | 2431 | ||
2412 | module_init(uvc_init); | 2432 | module_init(uvc_init); |
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c index 74bbe8f18f3e..8510e7259e76 100644 --- a/drivers/media/video/uvc/uvc_isight.c +++ b/drivers/media/video/uvc/uvc_isight.c | |||
@@ -74,7 +74,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, | |||
74 | * Empty buffers (bytesused == 0) don't trigger end of frame detection | 74 | * Empty buffers (bytesused == 0) don't trigger end of frame detection |
75 | * as it doesn't make sense to return an empty buffer. | 75 | * as it doesn't make sense to return an empty buffer. |
76 | */ | 76 | */ |
77 | if (is_header && buf->buf.bytesused != 0) { | 77 | if (is_header && buf->bytesused != 0) { |
78 | buf->state = UVC_BUF_STATE_DONE; | 78 | buf->state = UVC_BUF_STATE_DONE; |
79 | return -EAGAIN; | 79 | return -EAGAIN; |
80 | } | 80 | } |
@@ -83,13 +83,13 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, | |||
83 | * contain no data. | 83 | * contain no data. |
84 | */ | 84 | */ |
85 | if (!is_header) { | 85 | if (!is_header) { |
86 | maxlen = buf->buf.length - buf->buf.bytesused; | 86 | maxlen = buf->length - buf->bytesused; |
87 | mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; | 87 | mem = buf->mem + buf->bytesused; |
88 | nbytes = min(len, maxlen); | 88 | nbytes = min(len, maxlen); |
89 | memcpy(mem, data, nbytes); | 89 | memcpy(mem, data, nbytes); |
90 | buf->buf.bytesused += nbytes; | 90 | buf->bytesused += nbytes; |
91 | 91 | ||
92 | if (len > maxlen || buf->buf.bytesused == buf->buf.length) { | 92 | if (len > maxlen || buf->bytesused == buf->length) { |
93 | uvc_trace(UVC_TRACE_FRAME, "Frame complete " | 93 | uvc_trace(UVC_TRACE_FRAME, "Frame complete " |
94 | "(overflow).\n"); | 94 | "(overflow).\n"); |
95 | buf->state = UVC_BUF_STATE_DONE; | 95 | buf->state = UVC_BUF_STATE_DONE; |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 677691c44500..518f77d3a4d8 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/atomic.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
@@ -19,7 +20,7 @@ | |||
19 | #include <linux/videodev2.h> | 20 | #include <linux/videodev2.h> |
20 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
21 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
22 | #include <linux/atomic.h> | 23 | #include <media/videobuf2-vmalloc.h> |
23 | 24 | ||
24 | #include "uvcvideo.h" | 25 | #include "uvcvideo.h" |
25 | 26 | ||
@@ -29,467 +30,211 @@ | |||
29 | * Video queues is initialized by uvc_queue_init(). The function performs | 30 | * Video queues is initialized by uvc_queue_init(). The function performs |
30 | * basic initialization of the uvc_video_queue struct and never fails. | 31 | * basic initialization of the uvc_video_queue struct and never fails. |
31 | * | 32 | * |
32 | * Video buffer allocation and freeing are performed by uvc_alloc_buffers and | 33 | * Video buffers are managed by videobuf2. The driver uses a mutex to protect |
33 | * uvc_free_buffers respectively. The former acquires the video queue lock, | 34 | * the videobuf2 queue operations by serializing calls to videobuf2 and a |
34 | * while the later must be called with the lock held (so that allocation can | 35 | * spinlock to protect the IRQ queue that holds the buffers to be processed by |
35 | * free previously allocated buffers). Trying to free buffers that are mapped | 36 | * the driver. |
36 | * to user space will return -EBUSY. | ||
37 | * | ||
38 | * Video buffers are managed using two queues. However, unlike most USB video | ||
39 | * drivers that use an in queue and an out queue, we use a main queue to hold | ||
40 | * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to | ||
41 | * hold empty buffers. This design (copied from video-buf) minimizes locking | ||
42 | * in interrupt, as only one queue is shared between interrupt and user | ||
43 | * contexts. | ||
44 | * | ||
45 | * Use cases | ||
46 | * --------- | ||
47 | * | ||
48 | * Unless stated otherwise, all operations that modify the irq buffers queue | ||
49 | * are protected by the irq spinlock. | ||
50 | * | ||
51 | * 1. The user queues the buffers, starts streaming and dequeues a buffer. | ||
52 | * | ||
53 | * The buffers are added to the main and irq queues. Both operations are | ||
54 | * protected by the queue lock, and the later is protected by the irq | ||
55 | * spinlock as well. | ||
56 | * | ||
57 | * The completion handler fetches a buffer from the irq queue and fills it | ||
58 | * with video data. If no buffer is available (irq queue empty), the handler | ||
59 | * returns immediately. | ||
60 | * | ||
61 | * When the buffer is full, the completion handler removes it from the irq | ||
62 | * queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue. | ||
63 | * At that point, any process waiting on the buffer will be woken up. If a | ||
64 | * process tries to dequeue a buffer after it has been marked done, the | ||
65 | * dequeing will succeed immediately. | ||
66 | * | ||
67 | * 2. Buffers are queued, user is waiting on a buffer and the device gets | ||
68 | * disconnected. | ||
69 | * | ||
70 | * When the device is disconnected, the kernel calls the completion handler | ||
71 | * with an appropriate status code. The handler marks all buffers in the | ||
72 | * irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so | ||
73 | * that any process waiting on a buffer gets woken up. | ||
74 | * | ||
75 | * Waking up up the first buffer on the irq list is not enough, as the | ||
76 | * process waiting on the buffer might restart the dequeue operation | ||
77 | * immediately. | ||
78 | * | ||
79 | */ | 37 | */ |
80 | 38 | ||
81 | void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | 39 | /* ----------------------------------------------------------------------------- |
82 | int drop_corrupted) | 40 | * videobuf2 queue operations |
83 | { | ||
84 | mutex_init(&queue->mutex); | ||
85 | spin_lock_init(&queue->irqlock); | ||
86 | INIT_LIST_HEAD(&queue->mainqueue); | ||
87 | INIT_LIST_HEAD(&queue->irqqueue); | ||
88 | queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; | ||
89 | queue->type = type; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Free the video buffers. | ||
94 | * | ||
95 | * This function must be called with the queue lock held. | ||
96 | */ | 41 | */ |
97 | static int __uvc_free_buffers(struct uvc_video_queue *queue) | 42 | |
43 | static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | ||
44 | unsigned int *nbuffers, unsigned int *nplanes, | ||
45 | unsigned int sizes[], void *alloc_ctxs[]) | ||
98 | { | 46 | { |
99 | unsigned int i; | 47 | struct uvc_video_queue *queue = vb2_get_drv_priv(vq); |
48 | struct uvc_streaming *stream = | ||
49 | container_of(queue, struct uvc_streaming, queue); | ||
100 | 50 | ||
101 | for (i = 0; i < queue->count; ++i) { | 51 | if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) |
102 | if (queue->buffer[i].vma_use_count != 0) | 52 | *nbuffers = UVC_MAX_VIDEO_BUFFERS; |
103 | return -EBUSY; | ||
104 | } | ||
105 | 53 | ||
106 | if (queue->count) { | 54 | *nplanes = 1; |
107 | uvc_queue_cancel(queue, 0); | 55 | |
108 | INIT_LIST_HEAD(&queue->mainqueue); | 56 | sizes[0] = stream->ctrl.dwMaxVideoFrameSize; |
109 | vfree(queue->mem); | ||
110 | queue->count = 0; | ||
111 | } | ||
112 | 57 | ||
113 | return 0; | 58 | return 0; |
114 | } | 59 | } |
115 | 60 | ||
116 | int uvc_free_buffers(struct uvc_video_queue *queue) | 61 | static int uvc_buffer_prepare(struct vb2_buffer *vb) |
117 | { | 62 | { |
118 | int ret; | 63 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); |
64 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); | ||
119 | 65 | ||
120 | mutex_lock(&queue->mutex); | 66 | if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && |
121 | ret = __uvc_free_buffers(queue); | 67 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { |
122 | mutex_unlock(&queue->mutex); | 68 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); |
69 | return -EINVAL; | ||
70 | } | ||
123 | 71 | ||
124 | return ret; | 72 | if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED)) |
125 | } | 73 | return -ENODEV; |
126 | 74 | ||
127 | /* | 75 | buf->state = UVC_BUF_STATE_QUEUED; |
128 | * Allocate the video buffers. | 76 | buf->error = 0; |
129 | * | 77 | buf->mem = vb2_plane_vaddr(vb, 0); |
130 | * Pages are reserved to make sure they will not be swapped, as they will be | 78 | buf->length = vb2_plane_size(vb, 0); |
131 | * filled in the URB completion handler. | 79 | if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
132 | * | 80 | buf->bytesused = 0; |
133 | * Buffers will be individually mapped, so they must all be page aligned. | 81 | else |
134 | */ | 82 | buf->bytesused = vb2_get_plane_payload(vb, 0); |
135 | int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | ||
136 | unsigned int buflength) | ||
137 | { | ||
138 | unsigned int bufsize = PAGE_ALIGN(buflength); | ||
139 | unsigned int i; | ||
140 | void *mem = NULL; | ||
141 | int ret; | ||
142 | 83 | ||
143 | if (nbuffers > UVC_MAX_VIDEO_BUFFERS) | 84 | return 0; |
144 | nbuffers = UVC_MAX_VIDEO_BUFFERS; | 85 | } |
145 | 86 | ||
146 | mutex_lock(&queue->mutex); | 87 | static void uvc_buffer_queue(struct vb2_buffer *vb) |
88 | { | ||
89 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); | ||
90 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); | ||
91 | unsigned long flags; | ||
147 | 92 | ||
148 | if ((ret = __uvc_free_buffers(queue)) < 0) | 93 | spin_lock_irqsave(&queue->irqlock, flags); |
149 | goto done; | 94 | if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) { |
95 | list_add_tail(&buf->queue, &queue->irqqueue); | ||
96 | } else { | ||
97 | /* If the device is disconnected return the buffer to userspace | ||
98 | * directly. The next QBUF call will fail with -ENODEV. | ||
99 | */ | ||
100 | buf->state = UVC_BUF_STATE_ERROR; | ||
101 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); | ||
102 | } | ||
150 | 103 | ||
151 | /* Bail out if no buffers should be allocated. */ | 104 | spin_unlock_irqrestore(&queue->irqlock, flags); |
152 | if (nbuffers == 0) | 105 | } |
153 | goto done; | ||
154 | 106 | ||
155 | /* Decrement the number of buffers until allocation succeeds. */ | 107 | static int uvc_buffer_finish(struct vb2_buffer *vb) |
156 | for (; nbuffers > 0; --nbuffers) { | 108 | { |
157 | mem = vmalloc_32(nbuffers * bufsize); | 109 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); |
158 | if (mem != NULL) | 110 | struct uvc_streaming *stream = |
159 | break; | 111 | container_of(queue, struct uvc_streaming, queue); |
160 | } | 112 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); |
161 | 113 | ||
162 | if (mem == NULL) { | 114 | uvc_video_clock_update(stream, &vb->v4l2_buf, buf); |
163 | ret = -ENOMEM; | 115 | return 0; |
164 | goto done; | 116 | } |
165 | } | ||
166 | 117 | ||
167 | for (i = 0; i < nbuffers; ++i) { | 118 | static struct vb2_ops uvc_queue_qops = { |
168 | memset(&queue->buffer[i], 0, sizeof queue->buffer[i]); | 119 | .queue_setup = uvc_queue_setup, |
169 | queue->buffer[i].buf.index = i; | 120 | .buf_prepare = uvc_buffer_prepare, |
170 | queue->buffer[i].buf.m.offset = i * bufsize; | 121 | .buf_queue = uvc_buffer_queue, |
171 | queue->buffer[i].buf.length = buflength; | 122 | .buf_finish = uvc_buffer_finish, |
172 | queue->buffer[i].buf.type = queue->type; | 123 | }; |
173 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; | ||
174 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; | ||
175 | queue->buffer[i].buf.flags = 0; | ||
176 | init_waitqueue_head(&queue->buffer[i].wait); | ||
177 | } | ||
178 | 124 | ||
179 | queue->mem = mem; | 125 | void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, |
180 | queue->count = nbuffers; | 126 | int drop_corrupted) |
181 | queue->buf_size = bufsize; | 127 | { |
182 | ret = nbuffers; | 128 | queue->queue.type = type; |
129 | queue->queue.io_modes = VB2_MMAP; | ||
130 | queue->queue.drv_priv = queue; | ||
131 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); | ||
132 | queue->queue.ops = &uvc_queue_qops; | ||
133 | queue->queue.mem_ops = &vb2_vmalloc_memops; | ||
134 | vb2_queue_init(&queue->queue); | ||
183 | 135 | ||
184 | done: | 136 | mutex_init(&queue->mutex); |
185 | mutex_unlock(&queue->mutex); | 137 | spin_lock_init(&queue->irqlock); |
186 | return ret; | 138 | INIT_LIST_HEAD(&queue->irqqueue); |
139 | queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; | ||
187 | } | 140 | } |
188 | 141 | ||
189 | /* | 142 | /* ----------------------------------------------------------------------------- |
190 | * Check if buffers have been allocated. | 143 | * V4L2 queue operations |
191 | */ | 144 | */ |
192 | int uvc_queue_allocated(struct uvc_video_queue *queue) | 145 | |
146 | int uvc_alloc_buffers(struct uvc_video_queue *queue, | ||
147 | struct v4l2_requestbuffers *rb) | ||
193 | { | 148 | { |
194 | int allocated; | 149 | int ret; |
195 | 150 | ||
196 | mutex_lock(&queue->mutex); | 151 | mutex_lock(&queue->mutex); |
197 | allocated = queue->count != 0; | 152 | ret = vb2_reqbufs(&queue->queue, rb); |
198 | mutex_unlock(&queue->mutex); | 153 | mutex_unlock(&queue->mutex); |
199 | 154 | ||
200 | return allocated; | 155 | return ret ? ret : rb->count; |
201 | } | 156 | } |
202 | 157 | ||
203 | static void __uvc_query_buffer(struct uvc_buffer *buf, | 158 | void uvc_free_buffers(struct uvc_video_queue *queue) |
204 | struct v4l2_buffer *v4l2_buf) | ||
205 | { | 159 | { |
206 | memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf); | 160 | mutex_lock(&queue->mutex); |
207 | 161 | vb2_queue_release(&queue->queue); | |
208 | if (buf->vma_use_count) | 162 | mutex_unlock(&queue->mutex); |
209 | v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED; | ||
210 | |||
211 | switch (buf->state) { | ||
212 | case UVC_BUF_STATE_ERROR: | ||
213 | case UVC_BUF_STATE_DONE: | ||
214 | v4l2_buf->flags |= V4L2_BUF_FLAG_DONE; | ||
215 | break; | ||
216 | case UVC_BUF_STATE_QUEUED: | ||
217 | case UVC_BUF_STATE_ACTIVE: | ||
218 | case UVC_BUF_STATE_READY: | ||
219 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
220 | break; | ||
221 | case UVC_BUF_STATE_IDLE: | ||
222 | default: | ||
223 | break; | ||
224 | } | ||
225 | } | 163 | } |
226 | 164 | ||
227 | int uvc_query_buffer(struct uvc_video_queue *queue, | 165 | int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) |
228 | struct v4l2_buffer *v4l2_buf) | ||
229 | { | 166 | { |
230 | int ret = 0; | 167 | int ret; |
231 | 168 | ||
232 | mutex_lock(&queue->mutex); | 169 | mutex_lock(&queue->mutex); |
233 | if (v4l2_buf->index >= queue->count) { | 170 | ret = vb2_querybuf(&queue->queue, buf); |
234 | ret = -EINVAL; | ||
235 | goto done; | ||
236 | } | ||
237 | |||
238 | __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); | ||
239 | |||
240 | done: | ||
241 | mutex_unlock(&queue->mutex); | 171 | mutex_unlock(&queue->mutex); |
172 | |||
242 | return ret; | 173 | return ret; |
243 | } | 174 | } |
244 | 175 | ||
245 | /* | 176 | int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) |
246 | * Queue a video buffer. Attempting to queue a buffer that has already been | ||
247 | * queued will return -EINVAL. | ||
248 | */ | ||
249 | int uvc_queue_buffer(struct uvc_video_queue *queue, | ||
250 | struct v4l2_buffer *v4l2_buf) | ||
251 | { | 177 | { |
252 | struct uvc_buffer *buf; | 178 | int ret; |
253 | unsigned long flags; | ||
254 | int ret = 0; | ||
255 | |||
256 | uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); | ||
257 | |||
258 | if (v4l2_buf->type != queue->type || | ||
259 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { | ||
260 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " | ||
261 | "and/or memory (%u).\n", v4l2_buf->type, | ||
262 | v4l2_buf->memory); | ||
263 | return -EINVAL; | ||
264 | } | ||
265 | 179 | ||
266 | mutex_lock(&queue->mutex); | 180 | mutex_lock(&queue->mutex); |
267 | if (v4l2_buf->index >= queue->count) { | 181 | ret = vb2_qbuf(&queue->queue, buf); |
268 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); | ||
269 | ret = -EINVAL; | ||
270 | goto done; | ||
271 | } | ||
272 | |||
273 | buf = &queue->buffer[v4l2_buf->index]; | ||
274 | if (buf->state != UVC_BUF_STATE_IDLE) { | ||
275 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state " | ||
276 | "(%u).\n", buf->state); | ||
277 | ret = -EINVAL; | ||
278 | goto done; | ||
279 | } | ||
280 | |||
281 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
282 | v4l2_buf->bytesused > buf->buf.length) { | ||
283 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); | ||
284 | ret = -EINVAL; | ||
285 | goto done; | ||
286 | } | ||
287 | |||
288 | spin_lock_irqsave(&queue->irqlock, flags); | ||
289 | if (queue->flags & UVC_QUEUE_DISCONNECTED) { | ||
290 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
291 | ret = -ENODEV; | ||
292 | goto done; | ||
293 | } | ||
294 | buf->state = UVC_BUF_STATE_QUEUED; | ||
295 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
296 | buf->buf.bytesused = 0; | ||
297 | else | ||
298 | buf->buf.bytesused = v4l2_buf->bytesused; | ||
299 | |||
300 | list_add_tail(&buf->stream, &queue->mainqueue); | ||
301 | list_add_tail(&buf->queue, &queue->irqqueue); | ||
302 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
303 | |||
304 | done: | ||
305 | mutex_unlock(&queue->mutex); | 182 | mutex_unlock(&queue->mutex); |
306 | return ret; | ||
307 | } | ||
308 | 183 | ||
309 | static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking) | 184 | return ret; |
310 | { | ||
311 | if (nonblocking) { | ||
312 | return (buf->state != UVC_BUF_STATE_QUEUED && | ||
313 | buf->state != UVC_BUF_STATE_ACTIVE && | ||
314 | buf->state != UVC_BUF_STATE_READY) | ||
315 | ? 0 : -EAGAIN; | ||
316 | } | ||
317 | |||
318 | return wait_event_interruptible(buf->wait, | ||
319 | buf->state != UVC_BUF_STATE_QUEUED && | ||
320 | buf->state != UVC_BUF_STATE_ACTIVE && | ||
321 | buf->state != UVC_BUF_STATE_READY); | ||
322 | } | 185 | } |
323 | 186 | ||
324 | /* | 187 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, |
325 | * Dequeue a video buffer. If nonblocking is false, block until a buffer is | 188 | int nonblocking) |
326 | * available. | ||
327 | */ | ||
328 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, | ||
329 | struct v4l2_buffer *v4l2_buf, int nonblocking) | ||
330 | { | 189 | { |
331 | struct uvc_buffer *buf; | 190 | int ret; |
332 | int ret = 0; | ||
333 | |||
334 | if (v4l2_buf->type != queue->type || | ||
335 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { | ||
336 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " | ||
337 | "and/or memory (%u).\n", v4l2_buf->type, | ||
338 | v4l2_buf->memory); | ||
339 | return -EINVAL; | ||
340 | } | ||
341 | 191 | ||
342 | mutex_lock(&queue->mutex); | 192 | mutex_lock(&queue->mutex); |
343 | if (list_empty(&queue->mainqueue)) { | 193 | ret = vb2_dqbuf(&queue->queue, buf, nonblocking); |
344 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n"); | ||
345 | ret = -EINVAL; | ||
346 | goto done; | ||
347 | } | ||
348 | |||
349 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); | ||
350 | if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0) | ||
351 | goto done; | ||
352 | |||
353 | uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n", | ||
354 | buf->buf.index, buf->state, buf->buf.bytesused); | ||
355 | |||
356 | switch (buf->state) { | ||
357 | case UVC_BUF_STATE_ERROR: | ||
358 | uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data " | ||
359 | "(transmission error).\n"); | ||
360 | ret = -EIO; | ||
361 | case UVC_BUF_STATE_DONE: | ||
362 | buf->state = UVC_BUF_STATE_IDLE; | ||
363 | break; | ||
364 | |||
365 | case UVC_BUF_STATE_IDLE: | ||
366 | case UVC_BUF_STATE_QUEUED: | ||
367 | case UVC_BUF_STATE_ACTIVE: | ||
368 | case UVC_BUF_STATE_READY: | ||
369 | default: | ||
370 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " | ||
371 | "(driver bug?).\n", buf->state); | ||
372 | ret = -EINVAL; | ||
373 | goto done; | ||
374 | } | ||
375 | |||
376 | list_del(&buf->stream); | ||
377 | __uvc_query_buffer(buf, v4l2_buf); | ||
378 | |||
379 | done: | ||
380 | mutex_unlock(&queue->mutex); | 194 | mutex_unlock(&queue->mutex); |
381 | return ret; | ||
382 | } | ||
383 | 195 | ||
384 | /* | 196 | return ret; |
385 | * VMA operations. | ||
386 | */ | ||
387 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
388 | { | ||
389 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
390 | buffer->vma_use_count++; | ||
391 | } | ||
392 | |||
393 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
394 | { | ||
395 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
396 | buffer->vma_use_count--; | ||
397 | } | 197 | } |
398 | 198 | ||
399 | static const struct vm_operations_struct uvc_vm_ops = { | ||
400 | .open = uvc_vm_open, | ||
401 | .close = uvc_vm_close, | ||
402 | }; | ||
403 | |||
404 | /* | ||
405 | * Memory-map a video buffer. | ||
406 | * | ||
407 | * This function implements video buffers memory mapping and is intended to be | ||
408 | * used by the device mmap handler. | ||
409 | */ | ||
410 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | 199 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) |
411 | { | 200 | { |
412 | struct uvc_buffer *uninitialized_var(buffer); | 201 | int ret; |
413 | struct page *page; | ||
414 | unsigned long addr, start, size; | ||
415 | unsigned int i; | ||
416 | int ret = 0; | ||
417 | |||
418 | start = vma->vm_start; | ||
419 | size = vma->vm_end - vma->vm_start; | ||
420 | 202 | ||
421 | mutex_lock(&queue->mutex); | 203 | mutex_lock(&queue->mutex); |
204 | ret = vb2_mmap(&queue->queue, vma); | ||
205 | mutex_unlock(&queue->mutex); | ||
422 | 206 | ||
423 | for (i = 0; i < queue->count; ++i) { | 207 | return ret; |
424 | buffer = &queue->buffer[i]; | 208 | } |
425 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
426 | break; | ||
427 | } | ||
428 | |||
429 | if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) { | ||
430 | ret = -EINVAL; | ||
431 | goto done; | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
436 | * device. It also prevents the region from being core dumped. | ||
437 | */ | ||
438 | vma->vm_flags |= VM_IO; | ||
439 | |||
440 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
441 | #ifdef CONFIG_MMU | ||
442 | while (size > 0) { | ||
443 | page = vmalloc_to_page((void *)addr); | ||
444 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
445 | goto done; | ||
446 | |||
447 | start += PAGE_SIZE; | ||
448 | addr += PAGE_SIZE; | ||
449 | size -= PAGE_SIZE; | ||
450 | } | ||
451 | #endif | ||
452 | 209 | ||
453 | vma->vm_ops = &uvc_vm_ops; | 210 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, |
454 | vma->vm_private_data = buffer; | 211 | poll_table *wait) |
455 | uvc_vm_open(vma); | 212 | { |
213 | unsigned int ret; | ||
456 | 214 | ||
457 | done: | 215 | mutex_lock(&queue->mutex); |
216 | ret = vb2_poll(&queue->queue, file, wait); | ||
458 | mutex_unlock(&queue->mutex); | 217 | mutex_unlock(&queue->mutex); |
218 | |||
459 | return ret; | 219 | return ret; |
460 | } | 220 | } |
461 | 221 | ||
462 | /* | 222 | /* ----------------------------------------------------------------------------- |
463 | * Poll the video queue. | ||
464 | * | 223 | * |
465 | * This function implements video queue polling and is intended to be used by | ||
466 | * the device poll handler. | ||
467 | */ | 224 | */ |
468 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, | 225 | |
469 | poll_table *wait) | 226 | /* |
227 | * Check if buffers have been allocated. | ||
228 | */ | ||
229 | int uvc_queue_allocated(struct uvc_video_queue *queue) | ||
470 | { | 230 | { |
471 | struct uvc_buffer *buf; | 231 | int allocated; |
472 | unsigned int mask = 0; | ||
473 | 232 | ||
474 | mutex_lock(&queue->mutex); | 233 | mutex_lock(&queue->mutex); |
475 | if (list_empty(&queue->mainqueue)) { | 234 | allocated = vb2_is_busy(&queue->queue); |
476 | mask |= POLLERR; | ||
477 | goto done; | ||
478 | } | ||
479 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); | ||
480 | |||
481 | poll_wait(file, &buf->wait, wait); | ||
482 | if (buf->state == UVC_BUF_STATE_DONE || | ||
483 | buf->state == UVC_BUF_STATE_ERROR) { | ||
484 | if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
485 | mask |= POLLIN | POLLRDNORM; | ||
486 | else | ||
487 | mask |= POLLOUT | POLLWRNORM; | ||
488 | } | ||
489 | |||
490 | done: | ||
491 | mutex_unlock(&queue->mutex); | 235 | mutex_unlock(&queue->mutex); |
492 | return mask; | 236 | |
237 | return allocated; | ||
493 | } | 238 | } |
494 | 239 | ||
495 | #ifndef CONFIG_MMU | 240 | #ifndef CONFIG_MMU |
@@ -515,7 +260,7 @@ unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | |||
515 | ret = -EINVAL; | 260 | ret = -EINVAL; |
516 | goto done; | 261 | goto done; |
517 | } | 262 | } |
518 | ret = (unsigned long)queue->mem + buffer->buf.m.offset; | 263 | ret = (unsigned long)buf->mem; |
519 | done: | 264 | done: |
520 | mutex_unlock(&queue->mutex); | 265 | mutex_unlock(&queue->mutex); |
521 | return ret; | 266 | return ret; |
@@ -540,27 +285,24 @@ done: | |||
540 | */ | 285 | */ |
541 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) | 286 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) |
542 | { | 287 | { |
543 | unsigned int i; | 288 | unsigned long flags; |
544 | int ret = 0; | 289 | int ret; |
545 | 290 | ||
546 | mutex_lock(&queue->mutex); | 291 | mutex_lock(&queue->mutex); |
547 | if (enable) { | 292 | if (enable) { |
548 | if (uvc_queue_streaming(queue)) { | 293 | ret = vb2_streamon(&queue->queue, queue->queue.type); |
549 | ret = -EBUSY; | 294 | if (ret < 0) |
550 | goto done; | 295 | goto done; |
551 | } | 296 | |
552 | queue->flags |= UVC_QUEUE_STREAMING; | ||
553 | queue->buf_used = 0; | 297 | queue->buf_used = 0; |
554 | } else { | 298 | } else { |
555 | uvc_queue_cancel(queue, 0); | 299 | ret = vb2_streamoff(&queue->queue, queue->queue.type); |
556 | INIT_LIST_HEAD(&queue->mainqueue); | 300 | if (ret < 0) |
557 | 301 | goto done; | |
558 | for (i = 0; i < queue->count; ++i) { | ||
559 | queue->buffer[i].error = 0; | ||
560 | queue->buffer[i].state = UVC_BUF_STATE_IDLE; | ||
561 | } | ||
562 | 302 | ||
563 | queue->flags &= ~UVC_QUEUE_STREAMING; | 303 | spin_lock_irqsave(&queue->irqlock, flags); |
304 | INIT_LIST_HEAD(&queue->irqqueue); | ||
305 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
564 | } | 306 | } |
565 | 307 | ||
566 | done: | 308 | done: |
@@ -591,12 +333,12 @@ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) | |||
591 | queue); | 333 | queue); |
592 | list_del(&buf->queue); | 334 | list_del(&buf->queue); |
593 | buf->state = UVC_BUF_STATE_ERROR; | 335 | buf->state = UVC_BUF_STATE_ERROR; |
594 | wake_up(&buf->wait); | 336 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); |
595 | } | 337 | } |
596 | /* This must be protected by the irqlock spinlock to avoid race | 338 | /* This must be protected by the irqlock spinlock to avoid race |
597 | * conditions between uvc_queue_buffer and the disconnection event that | 339 | * conditions between uvc_buffer_queue and the disconnection event that |
598 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not | 340 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not |
599 | * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED | 341 | * blindly replace this logic by checking for the UVC_QUEUE_DISCONNECTED |
600 | * state outside the queue code. | 342 | * state outside the queue code. |
601 | */ | 343 | */ |
602 | if (disconnect) | 344 | if (disconnect) |
@@ -613,14 +355,12 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
613 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { | 355 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { |
614 | buf->error = 0; | 356 | buf->error = 0; |
615 | buf->state = UVC_BUF_STATE_QUEUED; | 357 | buf->state = UVC_BUF_STATE_QUEUED; |
616 | buf->buf.bytesused = 0; | 358 | vb2_set_plane_payload(&buf->buf, 0, 0); |
617 | return buf; | 359 | return buf; |
618 | } | 360 | } |
619 | 361 | ||
620 | spin_lock_irqsave(&queue->irqlock, flags); | 362 | spin_lock_irqsave(&queue->irqlock, flags); |
621 | list_del(&buf->queue); | 363 | list_del(&buf->queue); |
622 | buf->error = 0; | ||
623 | buf->state = UVC_BUF_STATE_DONE; | ||
624 | if (!list_empty(&queue->irqqueue)) | 364 | if (!list_empty(&queue->irqqueue)) |
625 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | 365 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, |
626 | queue); | 366 | queue); |
@@ -628,7 +368,9 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
628 | nextbuf = NULL; | 368 | nextbuf = NULL; |
629 | spin_unlock_irqrestore(&queue->irqlock, flags); | 369 | spin_unlock_irqrestore(&queue->irqlock, flags); |
630 | 370 | ||
631 | wake_up(&buf->wait); | 371 | buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; |
372 | vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); | ||
373 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); | ||
374 | |||
632 | return nextbuf; | 375 | return nextbuf; |
633 | } | 376 | } |
634 | |||
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index dadf11f704dc..2ae4f880ea05 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -58,6 +58,15 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, | |||
58 | break; | 58 | break; |
59 | 59 | ||
60 | case V4L2_CTRL_TYPE_MENU: | 60 | case V4L2_CTRL_TYPE_MENU: |
61 | /* Prevent excessive memory consumption, as well as integer | ||
62 | * overflows. | ||
63 | */ | ||
64 | if (xmap->menu_count == 0 || | ||
65 | xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) { | ||
66 | ret = -EINVAL; | ||
67 | goto done; | ||
68 | } | ||
69 | |||
61 | size = xmap->menu_count * sizeof(*map->menu_info); | 70 | size = xmap->menu_count * sizeof(*map->menu_info); |
62 | map->menu_info = kmalloc(size, GFP_KERNEL); | 71 | map->menu_info = kmalloc(size, GFP_KERNEL); |
63 | if (map->menu_info == NULL) { | 72 | if (map->menu_info == NULL) { |
@@ -513,10 +522,7 @@ static int uvc_v4l2_release(struct file *file) | |||
513 | /* Only free resources if this is a privileged handle. */ | 522 | /* Only free resources if this is a privileged handle. */ |
514 | if (uvc_has_privileges(handle)) { | 523 | if (uvc_has_privileges(handle)) { |
515 | uvc_video_enable(stream, 0); | 524 | uvc_video_enable(stream, 0); |
516 | 525 | uvc_free_buffers(&stream->queue); | |
517 | if (uvc_free_buffers(&stream->queue) < 0) | ||
518 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | ||
519 | "free buffers.\n"); | ||
520 | } | 526 | } |
521 | 527 | ||
522 | /* Release the file handle. */ | 528 | /* Release the file handle. */ |
@@ -914,19 +920,11 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
914 | 920 | ||
915 | /* Buffers & streaming */ | 921 | /* Buffers & streaming */ |
916 | case VIDIOC_REQBUFS: | 922 | case VIDIOC_REQBUFS: |
917 | { | ||
918 | struct v4l2_requestbuffers *rb = arg; | ||
919 | |||
920 | if (rb->type != stream->type || | ||
921 | rb->memory != V4L2_MEMORY_MMAP) | ||
922 | return -EINVAL; | ||
923 | |||
924 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 923 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
925 | return ret; | 924 | return ret; |
926 | 925 | ||
927 | mutex_lock(&stream->mutex); | 926 | mutex_lock(&stream->mutex); |
928 | ret = uvc_alloc_buffers(&stream->queue, rb->count, | 927 | ret = uvc_alloc_buffers(&stream->queue, arg); |
929 | stream->ctrl.dwMaxVideoFrameSize); | ||
930 | mutex_unlock(&stream->mutex); | 928 | mutex_unlock(&stream->mutex); |
931 | if (ret < 0) | 929 | if (ret < 0) |
932 | return ret; | 930 | return ret; |
@@ -934,18 +932,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
934 | if (ret == 0) | 932 | if (ret == 0) |
935 | uvc_dismiss_privileges(handle); | 933 | uvc_dismiss_privileges(handle); |
936 | 934 | ||
937 | rb->count = ret; | ||
938 | ret = 0; | 935 | ret = 0; |
939 | break; | 936 | break; |
940 | } | ||
941 | 937 | ||
942 | case VIDIOC_QUERYBUF: | 938 | case VIDIOC_QUERYBUF: |
943 | { | 939 | { |
944 | struct v4l2_buffer *buf = arg; | 940 | struct v4l2_buffer *buf = arg; |
945 | 941 | ||
946 | if (buf->type != stream->type) | ||
947 | return -EINVAL; | ||
948 | |||
949 | if (!uvc_has_privileges(handle)) | 942 | if (!uvc_has_privileges(handle)) |
950 | return -EBUSY; | 943 | return -EBUSY; |
951 | 944 | ||
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index b015e8e5e8b0..c7e69b8f81c9 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -351,25 +351,553 @@ done: | |||
351 | return ret; | 351 | return ret; |
352 | } | 352 | } |
353 | 353 | ||
354 | int uvc_commit_video(struct uvc_streaming *stream, | 354 | static int uvc_commit_video(struct uvc_streaming *stream, |
355 | struct uvc_streaming_control *probe) | 355 | struct uvc_streaming_control *probe) |
356 | { | 356 | { |
357 | return uvc_set_video_ctrl(stream, probe, 0); | 357 | return uvc_set_video_ctrl(stream, probe, 0); |
358 | } | 358 | } |
359 | 359 | ||
360 | /* ----------------------------------------------------------------------------- | ||
361 | * Clocks and timestamps | ||
362 | */ | ||
363 | |||
364 | static void | ||
365 | uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, | ||
366 | const __u8 *data, int len) | ||
367 | { | ||
368 | struct uvc_clock_sample *sample; | ||
369 | unsigned int header_size; | ||
370 | bool has_pts = false; | ||
371 | bool has_scr = false; | ||
372 | unsigned long flags; | ||
373 | struct timespec ts; | ||
374 | u16 host_sof; | ||
375 | u16 dev_sof; | ||
376 | |||
377 | switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { | ||
378 | case UVC_STREAM_PTS | UVC_STREAM_SCR: | ||
379 | header_size = 12; | ||
380 | has_pts = true; | ||
381 | has_scr = true; | ||
382 | break; | ||
383 | case UVC_STREAM_PTS: | ||
384 | header_size = 6; | ||
385 | has_pts = true; | ||
386 | break; | ||
387 | case UVC_STREAM_SCR: | ||
388 | header_size = 8; | ||
389 | has_scr = true; | ||
390 | break; | ||
391 | default: | ||
392 | header_size = 2; | ||
393 | break; | ||
394 | } | ||
395 | |||
396 | /* Check for invalid headers. */ | ||
397 | if (len < header_size) | ||
398 | return; | ||
399 | |||
400 | /* Extract the timestamps: | ||
401 | * | ||
402 | * - store the frame PTS in the buffer structure | ||
403 | * - if the SCR field is present, retrieve the host SOF counter and | ||
404 | * kernel timestamps and store them with the SCR STC and SOF fields | ||
405 | * in the ring buffer | ||
406 | */ | ||
407 | if (has_pts && buf != NULL) | ||
408 | buf->pts = get_unaligned_le32(&data[2]); | ||
409 | |||
410 | if (!has_scr) | ||
411 | return; | ||
412 | |||
413 | /* To limit the amount of data, drop SCRs with an SOF identical to the | ||
414 | * previous one. | ||
415 | */ | ||
416 | dev_sof = get_unaligned_le16(&data[header_size - 2]); | ||
417 | if (dev_sof == stream->clock.last_sof) | ||
418 | return; | ||
419 | |||
420 | stream->clock.last_sof = dev_sof; | ||
421 | |||
422 | host_sof = usb_get_current_frame_number(stream->dev->udev); | ||
423 | ktime_get_ts(&ts); | ||
424 | |||
425 | /* The UVC specification allows device implementations that can't obtain | ||
426 | * the USB frame number to keep their own frame counters as long as they | ||
427 | * match the size and frequency of the frame number associated with USB | ||
428 | * SOF tokens. The SOF values sent by such devices differ from the USB | ||
429 | * SOF tokens by a fixed offset that needs to be estimated and accounted | ||
430 | * for to make timestamp recovery as accurate as possible. | ||
431 | * | ||
432 | * The offset is estimated the first time a device SOF value is received | ||
433 | * as the difference between the host and device SOF values. As the two | ||
434 | * SOF values can differ slightly due to transmission delays, consider | ||
435 | * that the offset is null if the difference is not higher than 10 ms | ||
436 | * (negative differences can not happen and are thus considered as an | ||
437 | * offset). The video commit control wDelay field should be used to | ||
438 | * compute a dynamic threshold instead of using a fixed 10 ms value, but | ||
439 | * devices don't report reliable wDelay values. | ||
440 | * | ||
441 | * See uvc_video_clock_host_sof() for an explanation regarding why only | ||
442 | * the 8 LSBs of the delta are kept. | ||
443 | */ | ||
444 | if (stream->clock.sof_offset == (u16)-1) { | ||
445 | u16 delta_sof = (host_sof - dev_sof) & 255; | ||
446 | if (delta_sof >= 10) | ||
447 | stream->clock.sof_offset = delta_sof; | ||
448 | else | ||
449 | stream->clock.sof_offset = 0; | ||
450 | } | ||
451 | |||
452 | dev_sof = (dev_sof + stream->clock.sof_offset) & 2047; | ||
453 | |||
454 | spin_lock_irqsave(&stream->clock.lock, flags); | ||
455 | |||
456 | sample = &stream->clock.samples[stream->clock.head]; | ||
457 | sample->dev_stc = get_unaligned_le32(&data[header_size - 6]); | ||
458 | sample->dev_sof = dev_sof; | ||
459 | sample->host_sof = host_sof; | ||
460 | sample->host_ts = ts; | ||
461 | |||
462 | /* Update the sliding window head and count. */ | ||
463 | stream->clock.head = (stream->clock.head + 1) % stream->clock.size; | ||
464 | |||
465 | if (stream->clock.count < stream->clock.size) | ||
466 | stream->clock.count++; | ||
467 | |||
468 | spin_unlock_irqrestore(&stream->clock.lock, flags); | ||
469 | } | ||
470 | |||
471 | static int uvc_video_clock_init(struct uvc_streaming *stream) | ||
472 | { | ||
473 | struct uvc_clock *clock = &stream->clock; | ||
474 | |||
475 | spin_lock_init(&clock->lock); | ||
476 | clock->head = 0; | ||
477 | clock->count = 0; | ||
478 | clock->size = 32; | ||
479 | clock->last_sof = -1; | ||
480 | clock->sof_offset = -1; | ||
481 | |||
482 | clock->samples = kmalloc(clock->size * sizeof(*clock->samples), | ||
483 | GFP_KERNEL); | ||
484 | if (clock->samples == NULL) | ||
485 | return -ENOMEM; | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static void uvc_video_clock_cleanup(struct uvc_streaming *stream) | ||
491 | { | ||
492 | kfree(stream->clock.samples); | ||
493 | stream->clock.samples = NULL; | ||
494 | } | ||
495 | |||
496 | /* | ||
497 | * uvc_video_clock_host_sof - Return the host SOF value for a clock sample | ||
498 | * | ||
499 | * Host SOF counters reported by usb_get_current_frame_number() usually don't | ||
500 | * cover the whole 11-bits SOF range (0-2047) but are limited to the HCI frame | ||
501 | * schedule window. They can be limited to 8, 9 or 10 bits depending on the host | ||
502 | * controller and its configuration. | ||
503 | * | ||
504 | * We thus need to recover the SOF value corresponding to the host frame number. | ||
505 | * As the device and host frame numbers are sampled in a short interval, the | ||
506 | * difference between their values should be equal to a small delta plus an | ||
507 | * integer multiple of 256 caused by the host frame number limited precision. | ||
508 | * | ||
509 | * To obtain the recovered host SOF value, compute the small delta by masking | ||
510 | * the high bits of the host frame counter and device SOF difference and add it | ||
511 | * to the device SOF value. | ||
512 | */ | ||
513 | static u16 uvc_video_clock_host_sof(const struct uvc_clock_sample *sample) | ||
514 | { | ||
515 | /* The delta value can be negative. */ | ||
516 | s8 delta_sof; | ||
517 | |||
518 | delta_sof = (sample->host_sof - sample->dev_sof) & 255; | ||
519 | |||
520 | return (sample->dev_sof + delta_sof) & 2047; | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * uvc_video_clock_update - Update the buffer timestamp | ||
525 | * | ||
526 | * This function converts the buffer PTS timestamp to the host clock domain by | ||
527 | * going through the USB SOF clock domain and stores the result in the V4L2 | ||
528 | * buffer timestamp field. | ||
529 | * | ||
530 | * The relationship between the device clock and the host clock isn't known. | ||
531 | * However, the device and the host share the common USB SOF clock which can be | ||
532 | * used to recover that relationship. | ||
533 | * | ||
534 | * The relationship between the device clock and the USB SOF clock is considered | ||
535 | * to be linear over the clock samples sliding window and is given by | ||
536 | * | ||
537 | * SOF = m * PTS + p | ||
538 | * | ||
539 | * Several methods to compute the slope (m) and intercept (p) can be used. As | ||
540 | * the clock drift should be small compared to the sliding window size, we | ||
541 | * assume that the line that goes through the points at both ends of the window | ||
542 | * is a good approximation. Naming those points P1 and P2, we get | ||
543 | * | ||
544 | * SOF = (SOF2 - SOF1) / (STC2 - STC1) * PTS | ||
545 | * + (SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1) | ||
546 | * | ||
547 | * or | ||
548 | * | ||
549 | * SOF = ((SOF2 - SOF1) * PTS + SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1) (1) | ||
550 | * | ||
551 | * to avoid loosing precision in the division. Similarly, the host timestamp is | ||
552 | * computed with | ||
553 | * | ||
554 | * TS = ((TS2 - TS1) * PTS + TS1 * SOF2 - TS2 * SOF1) / (SOF2 - SOF1) (2) | ||
555 | * | ||
556 | * SOF values are coded on 11 bits by USB. We extend their precision with 16 | ||
557 | * decimal bits, leading to a 11.16 coding. | ||
558 | * | ||
559 | * TODO: To avoid surprises with device clock values, PTS/STC timestamps should | ||
560 | * be normalized using the nominal device clock frequency reported through the | ||
561 | * UVC descriptors. | ||
562 | * | ||
563 | * Both the PTS/STC and SOF counters roll over, after a fixed but device | ||
564 | * specific amount of time for PTS/STC and after 2048ms for SOF. As long as the | ||
565 | * sliding window size is smaller than the rollover period, differences computed | ||
566 | * on unsigned integers will produce the correct result. However, the p term in | ||
567 | * the linear relations will be miscomputed. | ||
568 | * | ||
569 | * To fix the issue, we subtract a constant from the PTS and STC values to bring | ||
570 | * PTS to half the 32 bit STC range. The sliding window STC values then fit into | ||
571 | * the 32 bit range without any rollover. | ||
572 | * | ||
573 | * Similarly, we add 2048 to the device SOF values to make sure that the SOF | ||
574 | * computed by (1) will never be smaller than 0. This offset is then compensated | ||
575 | * by adding 2048 to the SOF values used in (2). However, this doesn't prevent | ||
576 | * rollovers between (1) and (2): the SOF value computed by (1) can be slightly | ||
577 | * lower than 4096, and the host SOF counters can have rolled over to 2048. This | ||
578 | * case is handled by subtracting 2048 from the SOF value if it exceeds the host | ||
579 | * SOF value at the end of the sliding window. | ||
580 | * | ||
581 | * Finally we subtract a constant from the host timestamps to bring the first | ||
582 | * timestamp of the sliding window to 1s. | ||
583 | */ | ||
584 | void uvc_video_clock_update(struct uvc_streaming *stream, | ||
585 | struct v4l2_buffer *v4l2_buf, | ||
586 | struct uvc_buffer *buf) | ||
587 | { | ||
588 | struct uvc_clock *clock = &stream->clock; | ||
589 | struct uvc_clock_sample *first; | ||
590 | struct uvc_clock_sample *last; | ||
591 | unsigned long flags; | ||
592 | struct timespec ts; | ||
593 | u32 delta_stc; | ||
594 | u32 y1, y2; | ||
595 | u32 x1, x2; | ||
596 | u32 mean; | ||
597 | u32 sof; | ||
598 | u32 div; | ||
599 | u32 rem; | ||
600 | u64 y; | ||
601 | |||
602 | spin_lock_irqsave(&clock->lock, flags); | ||
603 | |||
604 | if (clock->count < clock->size) | ||
605 | goto done; | ||
606 | |||
607 | first = &clock->samples[clock->head]; | ||
608 | last = &clock->samples[(clock->head - 1) % clock->size]; | ||
609 | |||
610 | /* First step, PTS to SOF conversion. */ | ||
611 | delta_stc = buf->pts - (1UL << 31); | ||
612 | x1 = first->dev_stc - delta_stc; | ||
613 | x2 = last->dev_stc - delta_stc; | ||
614 | y1 = (first->dev_sof + 2048) << 16; | ||
615 | y2 = (last->dev_sof + 2048) << 16; | ||
616 | |||
617 | if (y2 < y1) | ||
618 | y2 += 2048 << 16; | ||
619 | |||
620 | y = (u64)(y2 - y1) * (1ULL << 31) + (u64)y1 * (u64)x2 | ||
621 | - (u64)y2 * (u64)x1; | ||
622 | y = div_u64(y, x2 - x1); | ||
623 | |||
624 | sof = y; | ||
625 | |||
626 | uvc_trace(UVC_TRACE_CLOCK, "%s: PTS %u y %llu.%06llu SOF %u.%06llu " | ||
627 | "(x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n", | ||
628 | stream->dev->name, buf->pts, | ||
629 | y >> 16, div_u64((y & 0xffff) * 1000000, 65536), | ||
630 | sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), | ||
631 | x1, x2, y1, y2, clock->sof_offset); | ||
632 | |||
633 | /* Second step, SOF to host clock conversion. */ | ||
634 | ts = timespec_sub(last->host_ts, first->host_ts); | ||
635 | x1 = (uvc_video_clock_host_sof(first) + 2048) << 16; | ||
636 | x2 = (uvc_video_clock_host_sof(last) + 2048) << 16; | ||
637 | y1 = NSEC_PER_SEC; | ||
638 | y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec; | ||
639 | |||
640 | if (x2 < x1) | ||
641 | x2 += 2048 << 16; | ||
642 | |||
643 | /* Interpolated and host SOF timestamps can wrap around at slightly | ||
644 | * different times. Handle this by adding or removing 2048 to or from | ||
645 | * the computed SOF value to keep it close to the SOF samples mean | ||
646 | * value. | ||
647 | */ | ||
648 | mean = (x1 + x2) / 2; | ||
649 | if (mean - (1024 << 16) > sof) | ||
650 | sof += 2048 << 16; | ||
651 | else if (sof > mean + (1024 << 16)) | ||
652 | sof -= 2048 << 16; | ||
653 | |||
654 | y = (u64)(y2 - y1) * (u64)sof + (u64)y1 * (u64)x2 | ||
655 | - (u64)y2 * (u64)x1; | ||
656 | y = div_u64(y, x2 - x1); | ||
657 | |||
658 | div = div_u64_rem(y, NSEC_PER_SEC, &rem); | ||
659 | ts.tv_sec = first->host_ts.tv_sec - 1 + div; | ||
660 | ts.tv_nsec = first->host_ts.tv_nsec + rem; | ||
661 | if (ts.tv_nsec >= NSEC_PER_SEC) { | ||
662 | ts.tv_sec++; | ||
663 | ts.tv_nsec -= NSEC_PER_SEC; | ||
664 | } | ||
665 | |||
666 | uvc_trace(UVC_TRACE_CLOCK, "%s: SOF %u.%06llu y %llu ts %lu.%06lu " | ||
667 | "buf ts %lu.%06lu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n", | ||
668 | stream->dev->name, | ||
669 | sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), | ||
670 | y, ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC, | ||
671 | v4l2_buf->timestamp.tv_sec, v4l2_buf->timestamp.tv_usec, | ||
672 | x1, first->host_sof, first->dev_sof, | ||
673 | x2, last->host_sof, last->dev_sof, y1, y2); | ||
674 | |||
675 | /* Update the V4L2 buffer. */ | ||
676 | v4l2_buf->timestamp.tv_sec = ts.tv_sec; | ||
677 | v4l2_buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; | ||
678 | |||
679 | done: | ||
680 | spin_unlock_irqrestore(&stream->clock.lock, flags); | ||
681 | } | ||
682 | |||
360 | /* ------------------------------------------------------------------------ | 683 | /* ------------------------------------------------------------------------ |
361 | * Video codecs | 684 | * Stream statistics |
362 | */ | 685 | */ |
363 | 686 | ||
364 | /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ | 687 | static void uvc_video_stats_decode(struct uvc_streaming *stream, |
365 | #define UVC_STREAM_EOH (1 << 7) | 688 | const __u8 *data, int len) |
366 | #define UVC_STREAM_ERR (1 << 6) | 689 | { |
367 | #define UVC_STREAM_STI (1 << 5) | 690 | unsigned int header_size; |
368 | #define UVC_STREAM_RES (1 << 4) | 691 | bool has_pts = false; |
369 | #define UVC_STREAM_SCR (1 << 3) | 692 | bool has_scr = false; |
370 | #define UVC_STREAM_PTS (1 << 2) | 693 | u16 uninitialized_var(scr_sof); |
371 | #define UVC_STREAM_EOF (1 << 1) | 694 | u32 uninitialized_var(scr_stc); |
372 | #define UVC_STREAM_FID (1 << 0) | 695 | u32 uninitialized_var(pts); |
696 | |||
697 | if (stream->stats.stream.nb_frames == 0 && | ||
698 | stream->stats.frame.nb_packets == 0) | ||
699 | ktime_get_ts(&stream->stats.stream.start_ts); | ||
700 | |||
701 | switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { | ||
702 | case UVC_STREAM_PTS | UVC_STREAM_SCR: | ||
703 | header_size = 12; | ||
704 | has_pts = true; | ||
705 | has_scr = true; | ||
706 | break; | ||
707 | case UVC_STREAM_PTS: | ||
708 | header_size = 6; | ||
709 | has_pts = true; | ||
710 | break; | ||
711 | case UVC_STREAM_SCR: | ||
712 | header_size = 8; | ||
713 | has_scr = true; | ||
714 | break; | ||
715 | default: | ||
716 | header_size = 2; | ||
717 | break; | ||
718 | } | ||
719 | |||
720 | /* Check for invalid headers. */ | ||
721 | if (len < header_size || data[0] < header_size) { | ||
722 | stream->stats.frame.nb_invalid++; | ||
723 | return; | ||
724 | } | ||
725 | |||
726 | /* Extract the timestamps. */ | ||
727 | if (has_pts) | ||
728 | pts = get_unaligned_le32(&data[2]); | ||
729 | |||
730 | if (has_scr) { | ||
731 | scr_stc = get_unaligned_le32(&data[header_size - 6]); | ||
732 | scr_sof = get_unaligned_le16(&data[header_size - 2]); | ||
733 | } | ||
734 | |||
735 | /* Is PTS constant through the whole frame ? */ | ||
736 | if (has_pts && stream->stats.frame.nb_pts) { | ||
737 | if (stream->stats.frame.pts != pts) { | ||
738 | stream->stats.frame.nb_pts_diffs++; | ||
739 | stream->stats.frame.last_pts_diff = | ||
740 | stream->stats.frame.nb_packets; | ||
741 | } | ||
742 | } | ||
743 | |||
744 | if (has_pts) { | ||
745 | stream->stats.frame.nb_pts++; | ||
746 | stream->stats.frame.pts = pts; | ||
747 | } | ||
748 | |||
749 | /* Do all frames have a PTS in their first non-empty packet, or before | ||
750 | * their first empty packet ? | ||
751 | */ | ||
752 | if (stream->stats.frame.size == 0) { | ||
753 | if (len > header_size) | ||
754 | stream->stats.frame.has_initial_pts = has_pts; | ||
755 | if (len == header_size && has_pts) | ||
756 | stream->stats.frame.has_early_pts = true; | ||
757 | } | ||
758 | |||
759 | /* Do the SCR.STC and SCR.SOF fields vary through the frame ? */ | ||
760 | if (has_scr && stream->stats.frame.nb_scr) { | ||
761 | if (stream->stats.frame.scr_stc != scr_stc) | ||
762 | stream->stats.frame.nb_scr_diffs++; | ||
763 | } | ||
764 | |||
765 | if (has_scr) { | ||
766 | /* Expand the SOF counter to 32 bits and store its value. */ | ||
767 | if (stream->stats.stream.nb_frames > 0 || | ||
768 | stream->stats.frame.nb_scr > 0) | ||
769 | stream->stats.stream.scr_sof_count += | ||
770 | (scr_sof - stream->stats.stream.scr_sof) % 2048; | ||
771 | stream->stats.stream.scr_sof = scr_sof; | ||
772 | |||
773 | stream->stats.frame.nb_scr++; | ||
774 | stream->stats.frame.scr_stc = scr_stc; | ||
775 | stream->stats.frame.scr_sof = scr_sof; | ||
776 | |||
777 | if (scr_sof < stream->stats.stream.min_sof) | ||
778 | stream->stats.stream.min_sof = scr_sof; | ||
779 | if (scr_sof > stream->stats.stream.max_sof) | ||
780 | stream->stats.stream.max_sof = scr_sof; | ||
781 | } | ||
782 | |||
783 | /* Record the first non-empty packet number. */ | ||
784 | if (stream->stats.frame.size == 0 && len > header_size) | ||
785 | stream->stats.frame.first_data = stream->stats.frame.nb_packets; | ||
786 | |||
787 | /* Update the frame size. */ | ||
788 | stream->stats.frame.size += len - header_size; | ||
789 | |||
790 | /* Update the packets counters. */ | ||
791 | stream->stats.frame.nb_packets++; | ||
792 | if (len > header_size) | ||
793 | stream->stats.frame.nb_empty++; | ||
794 | |||
795 | if (data[1] & UVC_STREAM_ERR) | ||
796 | stream->stats.frame.nb_errors++; | ||
797 | } | ||
798 | |||
799 | static void uvc_video_stats_update(struct uvc_streaming *stream) | ||
800 | { | ||
801 | struct uvc_stats_frame *frame = &stream->stats.frame; | ||
802 | |||
803 | uvc_trace(UVC_TRACE_STATS, "frame %u stats: %u/%u/%u packets, " | ||
804 | "%u/%u/%u pts (%searly %sinitial), %u/%u scr, " | ||
805 | "last pts/stc/sof %u/%u/%u\n", | ||
806 | stream->sequence, frame->first_data, | ||
807 | frame->nb_packets - frame->nb_empty, frame->nb_packets, | ||
808 | frame->nb_pts_diffs, frame->last_pts_diff, frame->nb_pts, | ||
809 | frame->has_early_pts ? "" : "!", | ||
810 | frame->has_initial_pts ? "" : "!", | ||
811 | frame->nb_scr_diffs, frame->nb_scr, | ||
812 | frame->pts, frame->scr_stc, frame->scr_sof); | ||
813 | |||
814 | stream->stats.stream.nb_frames++; | ||
815 | stream->stats.stream.nb_packets += stream->stats.frame.nb_packets; | ||
816 | stream->stats.stream.nb_empty += stream->stats.frame.nb_empty; | ||
817 | stream->stats.stream.nb_errors += stream->stats.frame.nb_errors; | ||
818 | stream->stats.stream.nb_invalid += stream->stats.frame.nb_invalid; | ||
819 | |||
820 | if (frame->has_early_pts) | ||
821 | stream->stats.stream.nb_pts_early++; | ||
822 | if (frame->has_initial_pts) | ||
823 | stream->stats.stream.nb_pts_initial++; | ||
824 | if (frame->last_pts_diff <= frame->first_data) | ||
825 | stream->stats.stream.nb_pts_constant++; | ||
826 | if (frame->nb_scr >= frame->nb_packets - frame->nb_empty) | ||
827 | stream->stats.stream.nb_scr_count_ok++; | ||
828 | if (frame->nb_scr_diffs + 1 == frame->nb_scr) | ||
829 | stream->stats.stream.nb_scr_diffs_ok++; | ||
830 | |||
831 | memset(&stream->stats.frame, 0, sizeof(stream->stats.frame)); | ||
832 | } | ||
833 | |||
834 | size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf, | ||
835 | size_t size) | ||
836 | { | ||
837 | unsigned int scr_sof_freq; | ||
838 | unsigned int duration; | ||
839 | struct timespec ts; | ||
840 | size_t count = 0; | ||
841 | |||
842 | ts.tv_sec = stream->stats.stream.stop_ts.tv_sec | ||
843 | - stream->stats.stream.start_ts.tv_sec; | ||
844 | ts.tv_nsec = stream->stats.stream.stop_ts.tv_nsec | ||
845 | - stream->stats.stream.start_ts.tv_nsec; | ||
846 | if (ts.tv_nsec < 0) { | ||
847 | ts.tv_sec--; | ||
848 | ts.tv_nsec += 1000000000; | ||
849 | } | ||
850 | |||
851 | /* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF | ||
852 | * frequency this will not overflow before more than 1h. | ||
853 | */ | ||
854 | duration = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; | ||
855 | if (duration != 0) | ||
856 | scr_sof_freq = stream->stats.stream.scr_sof_count * 1000 | ||
857 | / duration; | ||
858 | else | ||
859 | scr_sof_freq = 0; | ||
860 | |||
861 | count += scnprintf(buf + count, size - count, | ||
862 | "frames: %u\npackets: %u\nempty: %u\n" | ||
863 | "errors: %u\ninvalid: %u\n", | ||
864 | stream->stats.stream.nb_frames, | ||
865 | stream->stats.stream.nb_packets, | ||
866 | stream->stats.stream.nb_empty, | ||
867 | stream->stats.stream.nb_errors, | ||
868 | stream->stats.stream.nb_invalid); | ||
869 | count += scnprintf(buf + count, size - count, | ||
870 | "pts: %u early, %u initial, %u ok\n", | ||
871 | stream->stats.stream.nb_pts_early, | ||
872 | stream->stats.stream.nb_pts_initial, | ||
873 | stream->stats.stream.nb_pts_constant); | ||
874 | count += scnprintf(buf + count, size - count, | ||
875 | "scr: %u count ok, %u diff ok\n", | ||
876 | stream->stats.stream.nb_scr_count_ok, | ||
877 | stream->stats.stream.nb_scr_diffs_ok); | ||
878 | count += scnprintf(buf + count, size - count, | ||
879 | "sof: %u <= sof <= %u, freq %u.%03u kHz\n", | ||
880 | stream->stats.stream.min_sof, | ||
881 | stream->stats.stream.max_sof, | ||
882 | scr_sof_freq / 1000, scr_sof_freq % 1000); | ||
883 | |||
884 | return count; | ||
885 | } | ||
886 | |||
887 | static void uvc_video_stats_start(struct uvc_streaming *stream) | ||
888 | { | ||
889 | memset(&stream->stats, 0, sizeof(stream->stats)); | ||
890 | stream->stats.stream.min_sof = 2048; | ||
891 | } | ||
892 | |||
893 | static void uvc_video_stats_stop(struct uvc_streaming *stream) | ||
894 | { | ||
895 | ktime_get_ts(&stream->stats.stream.stop_ts); | ||
896 | } | ||
897 | |||
898 | /* ------------------------------------------------------------------------ | ||
899 | * Video codecs | ||
900 | */ | ||
373 | 901 | ||
374 | /* Video payload decoding is handled by uvc_video_decode_start(), | 902 | /* Video payload decoding is handled by uvc_video_decode_start(), |
375 | * uvc_video_decode_data() and uvc_video_decode_end(). | 903 | * uvc_video_decode_data() and uvc_video_decode_end(). |
@@ -416,14 +944,9 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
416 | * - bHeaderLength value must be at least 2 bytes (see above) | 944 | * - bHeaderLength value must be at least 2 bytes (see above) |
417 | * - bHeaderLength value can't be larger than the packet size. | 945 | * - bHeaderLength value can't be larger than the packet size. |
418 | */ | 946 | */ |
419 | if (len < 2 || data[0] < 2 || data[0] > len) | 947 | if (len < 2 || data[0] < 2 || data[0] > len) { |
948 | stream->stats.frame.nb_invalid++; | ||
420 | return -EINVAL; | 949 | return -EINVAL; |
421 | |||
422 | /* Skip payloads marked with the error bit ("error frames"). */ | ||
423 | if (data[1] & UVC_STREAM_ERR) { | ||
424 | uvc_trace(UVC_TRACE_FRAME, "Dropping payload (error bit " | ||
425 | "set).\n"); | ||
426 | return -ENODATA; | ||
427 | } | 950 | } |
428 | 951 | ||
429 | fid = data[1] & UVC_STREAM_FID; | 952 | fid = data[1] & UVC_STREAM_FID; |
@@ -431,8 +954,14 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
431 | /* Increase the sequence number regardless of any buffer states, so | 954 | /* Increase the sequence number regardless of any buffer states, so |
432 | * that discontinuous sequence numbers always indicate lost frames. | 955 | * that discontinuous sequence numbers always indicate lost frames. |
433 | */ | 956 | */ |
434 | if (stream->last_fid != fid) | 957 | if (stream->last_fid != fid) { |
435 | stream->sequence++; | 958 | stream->sequence++; |
959 | if (stream->sequence) | ||
960 | uvc_video_stats_update(stream); | ||
961 | } | ||
962 | |||
963 | uvc_video_clock_decode(stream, buf, data, len); | ||
964 | uvc_video_stats_decode(stream, data, len); | ||
436 | 965 | ||
437 | /* Store the payload FID bit and return immediately when the buffer is | 966 | /* Store the payload FID bit and return immediately when the buffer is |
438 | * NULL. | 967 | * NULL. |
@@ -442,6 +971,13 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
442 | return -ENODATA; | 971 | return -ENODATA; |
443 | } | 972 | } |
444 | 973 | ||
974 | /* Mark the buffer as bad if the error bit is set. */ | ||
975 | if (data[1] & UVC_STREAM_ERR) { | ||
976 | uvc_trace(UVC_TRACE_FRAME, "Marking buffer as bad (error bit " | ||
977 | "set).\n"); | ||
978 | buf->error = 1; | ||
979 | } | ||
980 | |||
445 | /* Synchronize to the input stream by waiting for the FID bit to be | 981 | /* Synchronize to the input stream by waiting for the FID bit to be |
446 | * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. | 982 | * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. |
447 | * stream->last_fid is initialized to -1, so the first isochronous | 983 | * stream->last_fid is initialized to -1, so the first isochronous |
@@ -467,9 +1003,10 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
467 | else | 1003 | else |
468 | ktime_get_real_ts(&ts); | 1004 | ktime_get_real_ts(&ts); |
469 | 1005 | ||
470 | buf->buf.sequence = stream->sequence; | 1006 | buf->buf.v4l2_buf.sequence = stream->sequence; |
471 | buf->buf.timestamp.tv_sec = ts.tv_sec; | 1007 | buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec; |
472 | buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; | 1008 | buf->buf.v4l2_buf.timestamp.tv_usec = |
1009 | ts.tv_nsec / NSEC_PER_USEC; | ||
473 | 1010 | ||
474 | /* TODO: Handle PTS and SCR. */ | 1011 | /* TODO: Handle PTS and SCR. */ |
475 | buf->state = UVC_BUF_STATE_ACTIVE; | 1012 | buf->state = UVC_BUF_STATE_ACTIVE; |
@@ -490,7 +1027,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
490 | * avoids detecting end of frame conditions at FID toggling if the | 1027 | * avoids detecting end of frame conditions at FID toggling if the |
491 | * previous payload had the EOF bit set. | 1028 | * previous payload had the EOF bit set. |
492 | */ | 1029 | */ |
493 | if (fid != stream->last_fid && buf->buf.bytesused != 0) { | 1030 | if (fid != stream->last_fid && buf->bytesused != 0) { |
494 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " | 1031 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " |
495 | "toggled).\n"); | 1032 | "toggled).\n"); |
496 | buf->state = UVC_BUF_STATE_READY; | 1033 | buf->state = UVC_BUF_STATE_READY; |
@@ -505,7 +1042,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
505 | static void uvc_video_decode_data(struct uvc_streaming *stream, | 1042 | static void uvc_video_decode_data(struct uvc_streaming *stream, |
506 | struct uvc_buffer *buf, const __u8 *data, int len) | 1043 | struct uvc_buffer *buf, const __u8 *data, int len) |
507 | { | 1044 | { |
508 | struct uvc_video_queue *queue = &stream->queue; | ||
509 | unsigned int maxlen, nbytes; | 1045 | unsigned int maxlen, nbytes; |
510 | void *mem; | 1046 | void *mem; |
511 | 1047 | ||
@@ -513,11 +1049,11 @@ static void uvc_video_decode_data(struct uvc_streaming *stream, | |||
513 | return; | 1049 | return; |
514 | 1050 | ||
515 | /* Copy the video data to the buffer. */ | 1051 | /* Copy the video data to the buffer. */ |
516 | maxlen = buf->buf.length - buf->buf.bytesused; | 1052 | maxlen = buf->length - buf->bytesused; |
517 | mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; | 1053 | mem = buf->mem + buf->bytesused; |
518 | nbytes = min((unsigned int)len, maxlen); | 1054 | nbytes = min((unsigned int)len, maxlen); |
519 | memcpy(mem, data, nbytes); | 1055 | memcpy(mem, data, nbytes); |
520 | buf->buf.bytesused += nbytes; | 1056 | buf->bytesused += nbytes; |
521 | 1057 | ||
522 | /* Complete the current frame if the buffer size was exceeded. */ | 1058 | /* Complete the current frame if the buffer size was exceeded. */ |
523 | if (len > maxlen) { | 1059 | if (len > maxlen) { |
@@ -530,7 +1066,7 @@ static void uvc_video_decode_end(struct uvc_streaming *stream, | |||
530 | struct uvc_buffer *buf, const __u8 *data, int len) | 1066 | struct uvc_buffer *buf, const __u8 *data, int len) |
531 | { | 1067 | { |
532 | /* Mark the buffer as done if the EOF marker is set. */ | 1068 | /* Mark the buffer as done if the EOF marker is set. */ |
533 | if (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) { | 1069 | if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { |
534 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); | 1070 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); |
535 | if (data[0] == len) | 1071 | if (data[0] == len) |
536 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); | 1072 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); |
@@ -568,8 +1104,8 @@ static int uvc_video_encode_data(struct uvc_streaming *stream, | |||
568 | void *mem; | 1104 | void *mem; |
569 | 1105 | ||
570 | /* Copy video data to the URB buffer. */ | 1106 | /* Copy video data to the URB buffer. */ |
571 | mem = queue->mem + buf->buf.m.offset + queue->buf_used; | 1107 | mem = buf->mem + queue->buf_used; |
572 | nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used); | 1108 | nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used); |
573 | nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size, | 1109 | nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size, |
574 | nbytes); | 1110 | nbytes); |
575 | memcpy(data, mem, nbytes); | 1111 | memcpy(data, mem, nbytes); |
@@ -624,7 +1160,7 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, | |||
624 | urb->iso_frame_desc[i].actual_length); | 1160 | urb->iso_frame_desc[i].actual_length); |
625 | 1161 | ||
626 | if (buf->state == UVC_BUF_STATE_READY) { | 1162 | if (buf->state == UVC_BUF_STATE_READY) { |
627 | if (buf->buf.length != buf->buf.bytesused && | 1163 | if (buf->length != buf->bytesused && |
628 | !(stream->cur_format->flags & | 1164 | !(stream->cur_format->flags & |
629 | UVC_FMT_FLAG_COMPRESSED)) | 1165 | UVC_FMT_FLAG_COMPRESSED)) |
630 | buf->error = 1; | 1166 | buf->error = 1; |
@@ -724,12 +1260,12 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, | |||
724 | stream->bulk.payload_size += ret; | 1260 | stream->bulk.payload_size += ret; |
725 | len -= ret; | 1261 | len -= ret; |
726 | 1262 | ||
727 | if (buf->buf.bytesused == stream->queue.buf_used || | 1263 | if (buf->bytesused == stream->queue.buf_used || |
728 | stream->bulk.payload_size == stream->bulk.max_payload_size) { | 1264 | stream->bulk.payload_size == stream->bulk.max_payload_size) { |
729 | if (buf->buf.bytesused == stream->queue.buf_used) { | 1265 | if (buf->bytesused == stream->queue.buf_used) { |
730 | stream->queue.buf_used = 0; | 1266 | stream->queue.buf_used = 0; |
731 | buf->state = UVC_BUF_STATE_READY; | 1267 | buf->state = UVC_BUF_STATE_READY; |
732 | buf->buf.sequence = ++stream->sequence; | 1268 | buf->buf.v4l2_buf.sequence = ++stream->sequence; |
733 | uvc_queue_next_buffer(&stream->queue, buf); | 1269 | uvc_queue_next_buffer(&stream->queue, buf); |
734 | stream->last_fid ^= UVC_STREAM_FID; | 1270 | stream->last_fid ^= UVC_STREAM_FID; |
735 | } | 1271 | } |
@@ -870,6 +1406,8 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) | |||
870 | struct urb *urb; | 1406 | struct urb *urb; |
871 | unsigned int i; | 1407 | unsigned int i; |
872 | 1408 | ||
1409 | uvc_video_stats_stop(stream); | ||
1410 | |||
873 | for (i = 0; i < UVC_URBS; ++i) { | 1411 | for (i = 0; i < UVC_URBS; ++i) { |
874 | urb = stream->urb[i]; | 1412 | urb = stream->urb[i]; |
875 | if (urb == NULL) | 1413 | if (urb == NULL) |
@@ -882,6 +1420,8 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) | |||
882 | 1420 | ||
883 | if (free_buffers) | 1421 | if (free_buffers) |
884 | uvc_free_urb_buffers(stream); | 1422 | uvc_free_urb_buffers(stream); |
1423 | |||
1424 | uvc_video_clock_cleanup(stream); | ||
885 | } | 1425 | } |
886 | 1426 | ||
887 | /* | 1427 | /* |
@@ -1009,6 +1549,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
1009 | stream->bulk.skip_payload = 0; | 1549 | stream->bulk.skip_payload = 0; |
1010 | stream->bulk.payload_size = 0; | 1550 | stream->bulk.payload_size = 0; |
1011 | 1551 | ||
1552 | uvc_video_stats_start(stream); | ||
1553 | |||
1554 | ret = uvc_video_clock_init(stream); | ||
1555 | if (ret < 0) | ||
1556 | return ret; | ||
1557 | |||
1012 | if (intf->num_altsetting > 1) { | 1558 | if (intf->num_altsetting > 1) { |
1013 | struct usb_host_endpoint *best_ep = NULL; | 1559 | struct usb_host_endpoint *best_ep = NULL; |
1014 | unsigned int best_psize = 3 * 1024; | 1560 | unsigned int best_psize = 3 * 1024; |
@@ -1283,6 +1829,11 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) | |||
1283 | return ret; | 1829 | return ret; |
1284 | } | 1830 | } |
1285 | 1831 | ||
1286 | return uvc_init_video(stream, GFP_KERNEL); | 1832 | ret = uvc_init_video(stream, GFP_KERNEL); |
1287 | } | 1833 | if (ret < 0) { |
1834 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); | ||
1835 | uvc_queue_enable(&stream->queue, 0); | ||
1836 | } | ||
1288 | 1837 | ||
1838 | return ret; | ||
1839 | } | ||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 4c1392ebcd4b..67f88d85bb16 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/videodev2.h> | 13 | #include <linux/videodev2.h> |
14 | #include <media/media-device.h> | 14 | #include <media/media-device.h> |
15 | #include <media/v4l2-device.h> | 15 | #include <media/v4l2-device.h> |
16 | #include <media/videobuf2-core.h> | ||
16 | 17 | ||
17 | /* -------------------------------------------------------------------------- | 18 | /* -------------------------------------------------------------------------- |
18 | * UVC constants | 19 | * UVC constants |
@@ -113,6 +114,7 @@ | |||
113 | 114 | ||
114 | /* Maximum allowed number of control mappings per device */ | 115 | /* Maximum allowed number of control mappings per device */ |
115 | #define UVC_MAX_CONTROL_MAPPINGS 1024 | 116 | #define UVC_MAX_CONTROL_MAPPINGS 1024 |
117 | #define UVC_MAX_CONTROL_MENU_ENTRIES 32 | ||
116 | 118 | ||
117 | /* Devices quirks */ | 119 | /* Devices quirks */ |
118 | #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 | 120 | #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 |
@@ -319,35 +321,30 @@ enum uvc_buffer_state { | |||
319 | }; | 321 | }; |
320 | 322 | ||
321 | struct uvc_buffer { | 323 | struct uvc_buffer { |
322 | unsigned long vma_use_count; | 324 | struct vb2_buffer buf; |
323 | struct list_head stream; | ||
324 | |||
325 | /* Touched by interrupt handler. */ | ||
326 | struct v4l2_buffer buf; | ||
327 | struct list_head queue; | 325 | struct list_head queue; |
328 | wait_queue_head_t wait; | 326 | |
329 | enum uvc_buffer_state state; | 327 | enum uvc_buffer_state state; |
330 | unsigned int error; | 328 | unsigned int error; |
329 | |||
330 | void *mem; | ||
331 | unsigned int length; | ||
332 | unsigned int bytesused; | ||
333 | |||
334 | u32 pts; | ||
331 | }; | 335 | }; |
332 | 336 | ||
333 | #define UVC_QUEUE_STREAMING (1 << 0) | 337 | #define UVC_QUEUE_DISCONNECTED (1 << 0) |
334 | #define UVC_QUEUE_DISCONNECTED (1 << 1) | 338 | #define UVC_QUEUE_DROP_CORRUPTED (1 << 1) |
335 | #define UVC_QUEUE_DROP_CORRUPTED (1 << 2) | ||
336 | 339 | ||
337 | struct uvc_video_queue { | 340 | struct uvc_video_queue { |
338 | enum v4l2_buf_type type; | 341 | struct vb2_queue queue; |
342 | struct mutex mutex; /* Protects queue */ | ||
339 | 343 | ||
340 | void *mem; | ||
341 | unsigned int flags; | 344 | unsigned int flags; |
342 | |||
343 | unsigned int count; | ||
344 | unsigned int buf_size; | ||
345 | unsigned int buf_used; | 345 | unsigned int buf_used; |
346 | struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; | ||
347 | struct mutex mutex; /* protects buffers and mainqueue */ | ||
348 | spinlock_t irqlock; /* protects irqqueue */ | ||
349 | 346 | ||
350 | struct list_head mainqueue; | 347 | spinlock_t irqlock; /* Protects irqqueue */ |
351 | struct list_head irqqueue; | 348 | struct list_head irqqueue; |
352 | }; | 349 | }; |
353 | 350 | ||
@@ -362,6 +359,51 @@ struct uvc_video_chain { | |||
362 | struct mutex ctrl_mutex; /* Protects ctrl.info */ | 359 | struct mutex ctrl_mutex; /* Protects ctrl.info */ |
363 | }; | 360 | }; |
364 | 361 | ||
362 | struct uvc_stats_frame { | ||
363 | unsigned int size; /* Number of bytes captured */ | ||
364 | unsigned int first_data; /* Index of the first non-empty packet */ | ||
365 | |||
366 | unsigned int nb_packets; /* Number of packets */ | ||
367 | unsigned int nb_empty; /* Number of empty packets */ | ||
368 | unsigned int nb_invalid; /* Number of packets with an invalid header */ | ||
369 | unsigned int nb_errors; /* Number of packets with the error bit set */ | ||
370 | |||
371 | unsigned int nb_pts; /* Number of packets with a PTS timestamp */ | ||
372 | unsigned int nb_pts_diffs; /* Number of PTS differences inside a frame */ | ||
373 | unsigned int last_pts_diff; /* Index of the last PTS difference */ | ||
374 | bool has_initial_pts; /* Whether the first non-empty packet has a PTS */ | ||
375 | bool has_early_pts; /* Whether a PTS is present before the first non-empty packet */ | ||
376 | u32 pts; /* PTS of the last packet */ | ||
377 | |||
378 | unsigned int nb_scr; /* Number of packets with a SCR timestamp */ | ||
379 | unsigned int nb_scr_diffs; /* Number of SCR.STC differences inside a frame */ | ||
380 | u16 scr_sof; /* SCR.SOF of the last packet */ | ||
381 | u32 scr_stc; /* SCR.STC of the last packet */ | ||
382 | }; | ||
383 | |||
384 | struct uvc_stats_stream { | ||
385 | struct timespec start_ts; /* Stream start timestamp */ | ||
386 | struct timespec stop_ts; /* Stream stop timestamp */ | ||
387 | |||
388 | unsigned int nb_frames; /* Number of frames */ | ||
389 | |||
390 | unsigned int nb_packets; /* Number of packets */ | ||
391 | unsigned int nb_empty; /* Number of empty packets */ | ||
392 | unsigned int nb_invalid; /* Number of packets with an invalid header */ | ||
393 | unsigned int nb_errors; /* Number of packets with the error bit set */ | ||
394 | |||
395 | unsigned int nb_pts_constant; /* Number of frames with constant PTS */ | ||
396 | unsigned int nb_pts_early; /* Number of frames with early PTS */ | ||
397 | unsigned int nb_pts_initial; /* Number of frames with initial PTS */ | ||
398 | |||
399 | unsigned int nb_scr_count_ok; /* Number of frames with at least one SCR per non empty packet */ | ||
400 | unsigned int nb_scr_diffs_ok; /* Number of frames with varying SCR.STC */ | ||
401 | unsigned int scr_sof_count; /* STC.SOF counter accumulated since stream start */ | ||
402 | unsigned int scr_sof; /* STC.SOF of the last packet */ | ||
403 | unsigned int min_sof; /* Minimum STC.SOF value */ | ||
404 | unsigned int max_sof; /* Maximum STC.SOF value */ | ||
405 | }; | ||
406 | |||
365 | struct uvc_streaming { | 407 | struct uvc_streaming { |
366 | struct list_head list; | 408 | struct list_head list; |
367 | struct uvc_device *dev; | 409 | struct uvc_device *dev; |
@@ -387,6 +429,7 @@ struct uvc_streaming { | |||
387 | */ | 429 | */ |
388 | struct mutex mutex; | 430 | struct mutex mutex; |
389 | 431 | ||
432 | /* Buffers queue. */ | ||
390 | unsigned int frozen : 1; | 433 | unsigned int frozen : 1; |
391 | struct uvc_video_queue queue; | 434 | struct uvc_video_queue queue; |
392 | void (*decode) (struct urb *urb, struct uvc_streaming *video, | 435 | void (*decode) (struct urb *urb, struct uvc_streaming *video, |
@@ -408,6 +451,32 @@ struct uvc_streaming { | |||
408 | 451 | ||
409 | __u32 sequence; | 452 | __u32 sequence; |
410 | __u8 last_fid; | 453 | __u8 last_fid; |
454 | |||
455 | /* debugfs */ | ||
456 | struct dentry *debugfs_dir; | ||
457 | struct { | ||
458 | struct uvc_stats_frame frame; | ||
459 | struct uvc_stats_stream stream; | ||
460 | } stats; | ||
461 | |||
462 | /* Timestamps support. */ | ||
463 | struct uvc_clock { | ||
464 | struct uvc_clock_sample { | ||
465 | u32 dev_stc; | ||
466 | u16 dev_sof; | ||
467 | struct timespec host_ts; | ||
468 | u16 host_sof; | ||
469 | } *samples; | ||
470 | |||
471 | unsigned int head; | ||
472 | unsigned int count; | ||
473 | unsigned int size; | ||
474 | |||
475 | u16 last_sof; | ||
476 | u16 sof_offset; | ||
477 | |||
478 | spinlock_t lock; | ||
479 | } clock; | ||
411 | }; | 480 | }; |
412 | 481 | ||
413 | enum uvc_device_state { | 482 | enum uvc_device_state { |
@@ -479,9 +548,12 @@ struct uvc_driver { | |||
479 | #define UVC_TRACE_SUSPEND (1 << 8) | 548 | #define UVC_TRACE_SUSPEND (1 << 8) |
480 | #define UVC_TRACE_STATUS (1 << 9) | 549 | #define UVC_TRACE_STATUS (1 << 9) |
481 | #define UVC_TRACE_VIDEO (1 << 10) | 550 | #define UVC_TRACE_VIDEO (1 << 10) |
551 | #define UVC_TRACE_STATS (1 << 11) | ||
552 | #define UVC_TRACE_CLOCK (1 << 12) | ||
482 | 553 | ||
483 | #define UVC_WARN_MINMAX 0 | 554 | #define UVC_WARN_MINMAX 0 |
484 | #define UVC_WARN_PROBE_DEF 1 | 555 | #define UVC_WARN_PROBE_DEF 1 |
556 | #define UVC_WARN_XU_GET_RES 2 | ||
485 | 557 | ||
486 | extern unsigned int uvc_clock_param; | 558 | extern unsigned int uvc_clock_param; |
487 | extern unsigned int uvc_no_drop_param; | 559 | extern unsigned int uvc_no_drop_param; |
@@ -516,8 +588,8 @@ extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); | |||
516 | extern void uvc_queue_init(struct uvc_video_queue *queue, | 588 | extern void uvc_queue_init(struct uvc_video_queue *queue, |
517 | enum v4l2_buf_type type, int drop_corrupted); | 589 | enum v4l2_buf_type type, int drop_corrupted); |
518 | extern int uvc_alloc_buffers(struct uvc_video_queue *queue, | 590 | extern int uvc_alloc_buffers(struct uvc_video_queue *queue, |
519 | unsigned int nbuffers, unsigned int buflength); | 591 | struct v4l2_requestbuffers *rb); |
520 | extern int uvc_free_buffers(struct uvc_video_queue *queue); | 592 | extern void uvc_free_buffers(struct uvc_video_queue *queue); |
521 | extern int uvc_query_buffer(struct uvc_video_queue *queue, | 593 | extern int uvc_query_buffer(struct uvc_video_queue *queue, |
522 | struct v4l2_buffer *v4l2_buf); | 594 | struct v4l2_buffer *v4l2_buf); |
523 | extern int uvc_queue_buffer(struct uvc_video_queue *queue, | 595 | extern int uvc_queue_buffer(struct uvc_video_queue *queue, |
@@ -539,7 +611,7 @@ extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | |||
539 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 611 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); |
540 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | 612 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) |
541 | { | 613 | { |
542 | return queue->flags & UVC_QUEUE_STREAMING; | 614 | return vb2_is_streaming(&queue->queue); |
543 | } | 615 | } |
544 | 616 | ||
545 | /* V4L2 interface */ | 617 | /* V4L2 interface */ |
@@ -556,10 +628,11 @@ extern int uvc_video_resume(struct uvc_streaming *stream, int reset); | |||
556 | extern int uvc_video_enable(struct uvc_streaming *stream, int enable); | 628 | extern int uvc_video_enable(struct uvc_streaming *stream, int enable); |
557 | extern int uvc_probe_video(struct uvc_streaming *stream, | 629 | extern int uvc_probe_video(struct uvc_streaming *stream, |
558 | struct uvc_streaming_control *probe); | 630 | struct uvc_streaming_control *probe); |
559 | extern int uvc_commit_video(struct uvc_streaming *stream, | ||
560 | struct uvc_streaming_control *ctrl); | ||
561 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 631 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, |
562 | __u8 intfnum, __u8 cs, void *data, __u16 size); | 632 | __u8 intfnum, __u8 cs, void *data, __u16 size); |
633 | void uvc_video_clock_update(struct uvc_streaming *stream, | ||
634 | struct v4l2_buffer *v4l2_buf, | ||
635 | struct uvc_buffer *buf); | ||
563 | 636 | ||
564 | /* Status */ | 637 | /* Status */ |
565 | extern int uvc_status_init(struct uvc_device *dev); | 638 | extern int uvc_status_init(struct uvc_device *dev); |
@@ -612,4 +685,13 @@ extern struct usb_host_endpoint *uvc_find_endpoint( | |||
612 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, | 685 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, |
613 | struct uvc_buffer *buf); | 686 | struct uvc_buffer *buf); |
614 | 687 | ||
688 | /* debugfs and statistics */ | ||
689 | int uvc_debugfs_init(void); | ||
690 | void uvc_debugfs_cleanup(void); | ||
691 | int uvc_debugfs_init_stream(struct uvc_streaming *stream); | ||
692 | void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream); | ||
693 | |||
694 | size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf, | ||
695 | size_t size); | ||
696 | |||
615 | #endif | 697 | #endif |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index a5c9ed128b97..96e9615663e9 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -146,10 +146,9 @@ static void v4l2_device_release(struct device *cd) | |||
146 | struct v4l2_device *v4l2_dev = vdev->v4l2_dev; | 146 | struct v4l2_device *v4l2_dev = vdev->v4l2_dev; |
147 | 147 | ||
148 | mutex_lock(&videodev_lock); | 148 | mutex_lock(&videodev_lock); |
149 | if (video_device[vdev->minor] != vdev) { | 149 | if (WARN_ON(video_device[vdev->minor] != vdev)) { |
150 | mutex_unlock(&videodev_lock); | ||
151 | /* should not happen */ | 150 | /* should not happen */ |
152 | WARN_ON(1); | 151 | mutex_unlock(&videodev_lock); |
153 | return; | 152 | return; |
154 | } | 153 | } |
155 | 154 | ||
@@ -168,7 +167,7 @@ static void v4l2_device_release(struct device *cd) | |||
168 | mutex_unlock(&videodev_lock); | 167 | mutex_unlock(&videodev_lock); |
169 | 168 | ||
170 | #if defined(CONFIG_MEDIA_CONTROLLER) | 169 | #if defined(CONFIG_MEDIA_CONTROLLER) |
171 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | 170 | if (v4l2_dev && v4l2_dev->mdev && |
172 | vdev->vfl_type != VFL_TYPE_SUBDEV) | 171 | vdev->vfl_type != VFL_TYPE_SUBDEV) |
173 | media_device_unregister_entity(&vdev->entity); | 172 | media_device_unregister_entity(&vdev->entity); |
174 | #endif | 173 | #endif |
@@ -556,8 +555,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
556 | vdev->minor = -1; | 555 | vdev->minor = -1; |
557 | 556 | ||
558 | /* the release callback MUST be present */ | 557 | /* the release callback MUST be present */ |
559 | WARN_ON(!vdev->release); | 558 | if (WARN_ON(!vdev->release)) |
560 | if (!vdev->release) | ||
561 | return -EINVAL; | 559 | return -EINVAL; |
562 | 560 | ||
563 | /* v4l2_fh support */ | 561 | /* v4l2_fh support */ |
@@ -703,8 +701,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
703 | vdev->vfl_type != VFL_TYPE_SUBDEV) { | 701 | vdev->vfl_type != VFL_TYPE_SUBDEV) { |
704 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; | 702 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; |
705 | vdev->entity.name = vdev->name; | 703 | vdev->entity.name = vdev->name; |
706 | vdev->entity.v4l.major = VIDEO_MAJOR; | 704 | vdev->entity.info.v4l.major = VIDEO_MAJOR; |
707 | vdev->entity.v4l.minor = vdev->minor; | 705 | vdev->entity.info.v4l.minor = vdev->minor; |
708 | ret = media_device_register_entity(vdev->v4l2_dev->mdev, | 706 | ret = media_device_register_entity(vdev->v4l2_dev->mdev, |
709 | &vdev->entity); | 707 | &vdev->entity); |
710 | if (ret < 0) | 708 | if (ret < 0) |
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 0edd618b9ddf..1f203b85a637 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
@@ -234,8 +234,8 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) | |||
234 | goto clean_up; | 234 | goto clean_up; |
235 | } | 235 | } |
236 | #if defined(CONFIG_MEDIA_CONTROLLER) | 236 | #if defined(CONFIG_MEDIA_CONTROLLER) |
237 | sd->entity.v4l.major = VIDEO_MAJOR; | 237 | sd->entity.info.v4l.major = VIDEO_MAJOR; |
238 | sd->entity.v4l.minor = vdev->minor; | 238 | sd->entity.info.v4l.minor = vdev->minor; |
239 | #endif | 239 | #endif |
240 | sd->devnode = vdev; | 240 | sd->devnode = vdev; |
241 | } | 241 | } |
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index cbf13d09b4ac..6a828759e387 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c | |||
@@ -156,14 +156,10 @@ static struct via_format { | |||
156 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, | 156 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, |
157 | .bpp = 2, | 157 | .bpp = 2, |
158 | }, | 158 | }, |
159 | { | ||
160 | .desc = "RGB 565", | ||
161 | .pixelformat = V4L2_PIX_FMT_RGB565, | ||
162 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
163 | .bpp = 2, | ||
164 | }, | ||
165 | /* RGB444 and Bayer should be doable, but have never been | 159 | /* RGB444 and Bayer should be doable, but have never been |
166 | tested with this driver. */ | 160 | tested with this driver. RGB565 seems to work at the default |
161 | resolution, but results in color corruption when being scaled by | ||
162 | viacam_set_scaled(), and is disabled as a result. */ | ||
167 | }; | 163 | }; |
168 | #define N_VIA_FMTS ARRAY_SIZE(via_formats) | 164 | #define N_VIA_FMTS ARRAY_SIZE(via_formats) |
169 | 165 | ||
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 52a0a3736c82..4d7391ec8001 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -708,7 +708,7 @@ static int vino_allocate_buffer(struct vino_framebuffer *fb, | |||
708 | size, count); | 708 | size, count); |
709 | 709 | ||
710 | /* allocate memory for table with virtual (page) addresses */ | 710 | /* allocate memory for table with virtual (page) addresses */ |
711 | fb->desc_table.virtual = (unsigned long *) | 711 | fb->desc_table.virtual = |
712 | kmalloc(count * sizeof(unsigned long), GFP_KERNEL); | 712 | kmalloc(count * sizeof(unsigned long), GFP_KERNEL); |
713 | if (!fb->desc_table.virtual) | 713 | if (!fb->desc_table.virtual) |
714 | return -ENOMEM; | 714 | return -ENOMEM; |
diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig index 5865029db0f6..28aba00dc629 100644 --- a/drivers/staging/media/as102/Kconfig +++ b/drivers/staging/media/as102/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config DVB_AS102 | 1 | config DVB_AS102 |
2 | tristate "Abilis AS102 DVB receiver" | 2 | tristate "Abilis AS102 DVB receiver" |
3 | depends on DVB_CORE && USB && I2C && INPUT | 3 | depends on DVB_CORE && USB && I2C && INPUT |
4 | select FW_LOADER | ||
4 | help | 5 | help |
5 | Choose Y or M here if you have a device containing an AS102 | 6 | Choose Y or M here if you have a device containing an AS102 |
6 | 7 | ||
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile index e7dbb6f814d5..1bca43e847c7 100644 --- a/drivers/staging/media/as102/Makefile +++ b/drivers/staging/media/as102/Makefile | |||
@@ -3,4 +3,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \ | |||
3 | 3 | ||
4 | obj-$(CONFIG_DVB_AS102) += dvb-as102.o | 4 | obj-$(CONFIG_DVB_AS102) += dvb-as102.o |
5 | 5 | ||
6 | EXTRA_CFLAGS += -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core | 6 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index 828526d4c289..aae0505a36c4 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/kref.h> | 26 | #include <linux/kref.h> |
27 | #include <asm/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | 29 | ||
30 | /* header file for Usb device driver*/ | 30 | /* header file for Usb device driver*/ |
@@ -56,13 +56,11 @@ int elna_enable = 1; | |||
56 | module_param_named(elna_enable, elna_enable, int, 0644); | 56 | module_param_named(elna_enable, elna_enable, int, 0644); |
57 | MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)"); | 57 | MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)"); |
58 | 58 | ||
59 | #ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR | ||
60 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 59 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
61 | #endif | ||
62 | 60 | ||
63 | static void as102_stop_stream(struct as102_dev_t *dev) | 61 | static void as102_stop_stream(struct as102_dev_t *dev) |
64 | { | 62 | { |
65 | struct as102_bus_adapter_t *bus_adap; | 63 | struct as10x_bus_adapter_t *bus_adap; |
66 | 64 | ||
67 | if (dev != NULL) | 65 | if (dev != NULL) |
68 | bus_adap = &dev->bus_adap; | 66 | bus_adap = &dev->bus_adap; |
@@ -85,7 +83,7 @@ static void as102_stop_stream(struct as102_dev_t *dev) | |||
85 | 83 | ||
86 | static int as102_start_stream(struct as102_dev_t *dev) | 84 | static int as102_start_stream(struct as102_dev_t *dev) |
87 | { | 85 | { |
88 | struct as102_bus_adapter_t *bus_adap; | 86 | struct as10x_bus_adapter_t *bus_adap; |
89 | int ret = -EFAULT; | 87 | int ret = -EFAULT; |
90 | 88 | ||
91 | if (dev != NULL) | 89 | if (dev != NULL) |
@@ -111,7 +109,7 @@ static int as102_start_stream(struct as102_dev_t *dev) | |||
111 | static int as10x_pid_filter(struct as102_dev_t *dev, | 109 | static int as10x_pid_filter(struct as102_dev_t *dev, |
112 | int index, u16 pid, int onoff) { | 110 | int index, u16 pid, int onoff) { |
113 | 111 | ||
114 | struct as102_bus_adapter_t *bus_adap = &dev->bus_adap; | 112 | struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap; |
115 | int ret = -EFAULT; | 113 | int ret = -EFAULT; |
116 | 114 | ||
117 | ENTER(); | 115 | ENTER(); |
@@ -123,22 +121,22 @@ static int as10x_pid_filter(struct as102_dev_t *dev, | |||
123 | 121 | ||
124 | switch (onoff) { | 122 | switch (onoff) { |
125 | case 0: | 123 | case 0: |
126 | ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid); | 124 | ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid); |
127 | dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n", | 125 | dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n", |
128 | index, pid, ret); | 126 | index, pid, ret); |
129 | break; | 127 | break; |
130 | case 1: | 128 | case 1: |
131 | { | 129 | { |
132 | struct as10x_ts_filter filter; | 130 | struct as10x_ts_filter filter; |
133 | 131 | ||
134 | filter.type = TS_PID_TYPE_TS; | 132 | filter.type = TS_PID_TYPE_TS; |
135 | filter.idx = 0xFF; | 133 | filter.idx = 0xFF; |
136 | filter.pid = pid; | 134 | filter.pid = pid; |
137 | 135 | ||
138 | ret = as10x_cmd_add_PID_filter(bus_adap, &filter); | 136 | ret = as10x_cmd_add_PID_filter(bus_adap, &filter); |
139 | dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n", | 137 | dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n", |
140 | index, filter.idx, filter.pid, ret); | 138 | index, filter.idx, filter.pid, ret); |
141 | break; | 139 | break; |
142 | } | 140 | } |
143 | } | 141 | } |
144 | 142 | ||
@@ -159,10 +157,9 @@ static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
159 | if (mutex_lock_interruptible(&as102_dev->sem)) | 157 | if (mutex_lock_interruptible(&as102_dev->sem)) |
160 | return -ERESTARTSYS; | 158 | return -ERESTARTSYS; |
161 | 159 | ||
162 | if (pid_filtering) { | 160 | if (pid_filtering) |
163 | as10x_pid_filter(as102_dev, | 161 | as10x_pid_filter(as102_dev, dvbdmxfeed->index, |
164 | dvbdmxfeed->index, dvbdmxfeed->pid, 1); | 162 | dvbdmxfeed->pid, 1); |
165 | } | ||
166 | 163 | ||
167 | if (as102_dev->streaming++ == 0) | 164 | if (as102_dev->streaming++ == 0) |
168 | ret = as102_start_stream(as102_dev); | 165 | ret = as102_start_stream(as102_dev); |
@@ -185,10 +182,9 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
185 | if (--as102_dev->streaming == 0) | 182 | if (--as102_dev->streaming == 0) |
186 | as102_stop_stream(as102_dev); | 183 | as102_stop_stream(as102_dev); |
187 | 184 | ||
188 | if (pid_filtering) { | 185 | if (pid_filtering) |
189 | as10x_pid_filter(as102_dev, | 186 | as10x_pid_filter(as102_dev, dvbdmxfeed->index, |
190 | dvbdmxfeed->index, dvbdmxfeed->pid, 0); | 187 | dvbdmxfeed->pid, 0); |
191 | } | ||
192 | 188 | ||
193 | mutex_unlock(&as102_dev->sem); | 189 | mutex_unlock(&as102_dev->sem); |
194 | LEAVE(); | 190 | LEAVE(); |
@@ -197,27 +193,16 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
197 | 193 | ||
198 | int as102_dvb_register(struct as102_dev_t *as102_dev) | 194 | int as102_dvb_register(struct as102_dev_t *as102_dev) |
199 | { | 195 | { |
200 | int ret = 0; | 196 | struct device *dev = &as102_dev->bus_adap.usb_dev->dev; |
201 | ENTER(); | 197 | int ret; |
202 | 198 | ||
203 | ret = dvb_register_adapter(&as102_dev->dvb_adap, | 199 | ret = dvb_register_adapter(&as102_dev->dvb_adap, |
204 | as102_dev->name, | 200 | as102_dev->name, THIS_MODULE, |
205 | THIS_MODULE, | 201 | dev, adapter_nr); |
206 | #if defined(CONFIG_AS102_USB) | ||
207 | &as102_dev->bus_adap.usb_dev->dev | ||
208 | #elif defined(CONFIG_AS102_SPI) | ||
209 | &as102_dev->bus_adap.spi_dev->dev | ||
210 | #else | ||
211 | #error >>> dvb_register_adapter <<< | ||
212 | #endif | ||
213 | #ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR | ||
214 | , adapter_nr | ||
215 | #endif | ||
216 | ); | ||
217 | if (ret < 0) { | 202 | if (ret < 0) { |
218 | err("%s: dvb_register_adapter() failed (errno = %d)", | 203 | dev_err(dev, "%s: dvb_register_adapter() failed: %d\n", |
219 | __func__, ret); | 204 | __func__, ret); |
220 | goto failed; | 205 | return ret; |
221 | } | 206 | } |
222 | 207 | ||
223 | as102_dev->dvb_dmx.priv = as102_dev; | 208 | as102_dev->dvb_dmx.priv = as102_dev; |
@@ -235,22 +220,22 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) | |||
235 | 220 | ||
236 | ret = dvb_dmx_init(&as102_dev->dvb_dmx); | 221 | ret = dvb_dmx_init(&as102_dev->dvb_dmx); |
237 | if (ret < 0) { | 222 | if (ret < 0) { |
238 | err("%s: dvb_dmx_init() failed (errno = %d)", __func__, ret); | 223 | dev_err(dev, "%s: dvb_dmx_init() failed: %d\n", __func__, ret); |
239 | goto failed; | 224 | goto edmxinit; |
240 | } | 225 | } |
241 | 226 | ||
242 | ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap); | 227 | ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap); |
243 | if (ret < 0) { | 228 | if (ret < 0) { |
244 | err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__, | 229 | dev_err(dev, "%s: dvb_dmxdev_init() failed: %d\n", |
245 | ret); | 230 | __func__, ret); |
246 | goto failed; | 231 | goto edmxdinit; |
247 | } | 232 | } |
248 | 233 | ||
249 | ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe); | 234 | ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe); |
250 | if (ret < 0) { | 235 | if (ret < 0) { |
251 | err("%s: as102_dvb_register_frontend() failed (errno = %d)", | 236 | dev_err(dev, "%s: as102_dvb_register_frontend() failed: %d", |
252 | __func__, ret); | 237 | __func__, ret); |
253 | goto failed; | 238 | goto efereg; |
254 | } | 239 | } |
255 | 240 | ||
256 | /* init bus mutex for token locking */ | 241 | /* init bus mutex for token locking */ |
@@ -259,7 +244,6 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) | |||
259 | /* init start / stop stream mutex */ | 244 | /* init start / stop stream mutex */ |
260 | mutex_init(&as102_dev->sem); | 245 | mutex_init(&as102_dev->sem); |
261 | 246 | ||
262 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | ||
263 | /* | 247 | /* |
264 | * try to load as102 firmware. If firmware upload failed, we'll be | 248 | * try to load as102 firmware. If firmware upload failed, we'll be |
265 | * able to upload it later. | 249 | * able to upload it later. |
@@ -267,18 +251,21 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) | |||
267 | if (fw_upload) | 251 | if (fw_upload) |
268 | try_then_request_module(as102_fw_upload(&as102_dev->bus_adap), | 252 | try_then_request_module(as102_fw_upload(&as102_dev->bus_adap), |
269 | "firmware_class"); | 253 | "firmware_class"); |
270 | #endif | ||
271 | 254 | ||
272 | failed: | 255 | pr_info("Registered device %s", as102_dev->name); |
273 | LEAVE(); | 256 | return 0; |
274 | /* FIXME: free dvb_XXX */ | 257 | |
258 | efereg: | ||
259 | dvb_dmxdev_release(&as102_dev->dvb_dmxdev); | ||
260 | edmxdinit: | ||
261 | dvb_dmx_release(&as102_dev->dvb_dmx); | ||
262 | edmxinit: | ||
263 | dvb_unregister_adapter(&as102_dev->dvb_adap); | ||
275 | return ret; | 264 | return ret; |
276 | } | 265 | } |
277 | 266 | ||
278 | void as102_dvb_unregister(struct as102_dev_t *as102_dev) | 267 | void as102_dvb_unregister(struct as102_dev_t *as102_dev) |
279 | { | 268 | { |
280 | ENTER(); | ||
281 | |||
282 | /* unregister as102 frontend */ | 269 | /* unregister as102 frontend */ |
283 | as102_dvb_unregister_fe(&as102_dev->dvb_fe); | 270 | as102_dvb_unregister_fe(&as102_dev->dvb_fe); |
284 | 271 | ||
@@ -289,28 +276,18 @@ void as102_dvb_unregister(struct as102_dev_t *as102_dev) | |||
289 | /* unregister dvb adapter */ | 276 | /* unregister dvb adapter */ |
290 | dvb_unregister_adapter(&as102_dev->dvb_adap); | 277 | dvb_unregister_adapter(&as102_dev->dvb_adap); |
291 | 278 | ||
292 | LEAVE(); | 279 | pr_info("Unregistered device %s", as102_dev->name); |
293 | } | 280 | } |
294 | 281 | ||
295 | static int __init as102_driver_init(void) | 282 | static int __init as102_driver_init(void) |
296 | { | 283 | { |
297 | int ret = 0; | 284 | int ret; |
298 | |||
299 | ENTER(); | ||
300 | 285 | ||
301 | /* register this driver with the low level subsystem */ | 286 | /* register this driver with the low level subsystem */ |
302 | #if defined(CONFIG_AS102_USB) | ||
303 | ret = usb_register(&as102_usb_driver); | 287 | ret = usb_register(&as102_usb_driver); |
304 | if (ret) | 288 | if (ret) |
305 | err("usb_register failed (ret = %d)", ret); | 289 | err("usb_register failed (ret = %d)", ret); |
306 | #endif | ||
307 | #if defined(CONFIG_AS102_SPI) | ||
308 | ret = spi_register_driver(&as102_spi_driver); | ||
309 | if (ret) | ||
310 | printk(KERN_ERR "spi_register failed (ret = %d)", ret); | ||
311 | #endif | ||
312 | 290 | ||
313 | LEAVE(); | ||
314 | return ret; | 291 | return ret; |
315 | } | 292 | } |
316 | 293 | ||
@@ -327,15 +304,8 @@ module_init(as102_driver_init); | |||
327 | */ | 304 | */ |
328 | static void __exit as102_driver_exit(void) | 305 | static void __exit as102_driver_exit(void) |
329 | { | 306 | { |
330 | ENTER(); | ||
331 | /* deregister this driver with the low level bus subsystem */ | 307 | /* deregister this driver with the low level bus subsystem */ |
332 | #if defined(CONFIG_AS102_USB) | ||
333 | usb_deregister(&as102_usb_driver); | 308 | usb_deregister(&as102_usb_driver); |
334 | #endif | ||
335 | #if defined(CONFIG_AS102_SPI) | ||
336 | spi_unregister_driver(&as102_spi_driver); | ||
337 | #endif | ||
338 | LEAVE(); | ||
339 | } | 309 | } |
340 | 310 | ||
341 | /* | 311 | /* |
@@ -347,5 +317,3 @@ module_exit(as102_driver_exit); | |||
347 | MODULE_DESCRIPTION(DRIVER_FULL_NAME); | 317 | MODULE_DESCRIPTION(DRIVER_FULL_NAME); |
348 | MODULE_LICENSE("GPL"); | 318 | MODULE_LICENSE("GPL"); |
349 | MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>"); | 319 | MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>"); |
350 | |||
351 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index fd33f5a12dcc..957f0ed0d81a 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h | |||
@@ -17,38 +17,30 @@ | |||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #if defined(CONFIG_AS102_USB) | ||
21 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
22 | extern struct usb_driver as102_usb_driver; | 21 | #include <dvb_demux.h> |
23 | #endif | 22 | #include <dvb_frontend.h> |
24 | 23 | #include <dmxdev.h> | |
25 | #if defined(CONFIG_AS102_SPI) | 24 | #include "as10x_cmd.h" |
26 | #include <linux/platform_device.h> | 25 | #include "as102_usb_drv.h" |
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/cdev.h> | ||
29 | |||
30 | extern struct spi_driver as102_spi_driver; | ||
31 | #endif | ||
32 | |||
33 | #include "dvb_demux.h" | ||
34 | #include "dvb_frontend.h" | ||
35 | #include "dmxdev.h" | ||
36 | 26 | ||
37 | #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver" | 27 | #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver" |
38 | #define DRIVER_NAME "as10x_usb" | 28 | #define DRIVER_NAME "as10x_usb" |
39 | 29 | ||
40 | extern int as102_debug; | 30 | extern int as102_debug; |
41 | #define debug as102_debug | 31 | #define debug as102_debug |
32 | extern struct usb_driver as102_usb_driver; | ||
33 | extern int elna_enable; | ||
42 | 34 | ||
43 | #define dprintk(debug, args...) \ | 35 | #define dprintk(debug, args...) \ |
44 | do { if (debug) { \ | 36 | do { if (debug) { \ |
45 | printk(KERN_DEBUG "%s: ",__FUNCTION__); \ | 37 | pr_debug("%s: ", __func__); \ |
46 | printk(args); \ | 38 | printk(args); \ |
47 | } } while (0) | 39 | } } while (0) |
48 | 40 | ||
49 | #ifdef TRACE | 41 | #ifdef TRACE |
50 | #define ENTER() printk(">> enter %s\n", __FUNCTION__) | 42 | #define ENTER() pr_debug(">> enter %s\n", __func__) |
51 | #define LEAVE() printk("<< leave %s\n", __FUNCTION__) | 43 | #define LEAVE() pr_debug("<< leave %s\n", __func__) |
52 | #else | 44 | #else |
53 | #define ENTER() | 45 | #define ENTER() |
54 | #define LEAVE() | 46 | #define LEAVE() |
@@ -59,39 +51,14 @@ extern int as102_debug; | |||
59 | #define AS102_USB_BUF_SIZE 512 | 51 | #define AS102_USB_BUF_SIZE 512 |
60 | #define MAX_STREAM_URB 32 | 52 | #define MAX_STREAM_URB 32 |
61 | 53 | ||
62 | #include "as10x_cmd.h" | 54 | struct as10x_bus_adapter_t { |
63 | |||
64 | #if defined(CONFIG_AS102_USB) | ||
65 | #include "as102_usb_drv.h" | ||
66 | #endif | ||
67 | |||
68 | #if defined(CONFIG_AS102_SPI) | ||
69 | #include "as10x_spi_drv.h" | ||
70 | #endif | ||
71 | |||
72 | |||
73 | struct as102_bus_adapter_t { | ||
74 | #if defined(CONFIG_AS102_USB) | ||
75 | struct usb_device *usb_dev; | 55 | struct usb_device *usb_dev; |
76 | #elif defined(CONFIG_AS102_SPI) | ||
77 | struct spi_device *spi_dev; | ||
78 | struct cdev cdev; /* spidev raw device */ | ||
79 | |||
80 | struct timer_list timer; | ||
81 | struct completion xfer_done; | ||
82 | #endif | ||
83 | /* bus token lock */ | 56 | /* bus token lock */ |
84 | struct mutex lock; | 57 | struct mutex lock; |
85 | /* low level interface for bus adapter */ | 58 | /* low level interface for bus adapter */ |
86 | union as10x_bus_token_t { | 59 | union as10x_bus_token_t { |
87 | #if defined(CONFIG_AS102_USB) | ||
88 | /* usb token */ | 60 | /* usb token */ |
89 | struct as10x_usb_token_cmd_t usb; | 61 | struct as10x_usb_token_cmd_t usb; |
90 | #endif | ||
91 | #if defined(CONFIG_AS102_SPI) | ||
92 | /* spi token */ | ||
93 | struct as10x_spi_token_cmd_t spi; | ||
94 | #endif | ||
95 | } token; | 62 | } token; |
96 | 63 | ||
97 | /* token cmd xfer id */ | 64 | /* token cmd xfer id */ |
@@ -106,7 +73,7 @@ struct as102_bus_adapter_t { | |||
106 | 73 | ||
107 | struct as102_dev_t { | 74 | struct as102_dev_t { |
108 | const char *name; | 75 | const char *name; |
109 | struct as102_bus_adapter_t bus_adap; | 76 | struct as10x_bus_adapter_t bus_adap; |
110 | struct list_head device_entry; | 77 | struct list_head device_entry; |
111 | struct kref kref; | 78 | struct kref kref; |
112 | unsigned long minor; | 79 | unsigned long minor; |
@@ -138,5 +105,3 @@ void as102_dvb_unregister(struct as102_dev_t *dev); | |||
138 | 105 | ||
139 | int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe); | 106 | int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe); |
140 | int as102_dvb_unregister_fe(struct dvb_frontend *dev); | 107 | int as102_dvb_unregister_fe(struct dvb_frontend *dev); |
141 | |||
142 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c index 3550f905367e..c2adfe5607c6 100644 --- a/drivers/staging/media/as102/as102_fe.c +++ b/drivers/staging/media/as102/as102_fe.c | |||
@@ -23,8 +23,6 @@ | |||
23 | #include "as10x_types.h" | 23 | #include "as10x_types.h" |
24 | #include "as10x_cmd.h" | 24 | #include "as10x_cmd.h" |
25 | 25 | ||
26 | extern int elna_enable; | ||
27 | |||
28 | static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst, | 26 | static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst, |
29 | struct as10x_tps *src); | 27 | struct as10x_tps *src); |
30 | 28 | ||
@@ -599,5 +597,3 @@ static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args, | |||
599 | as102_fe_get_code_rate(params->u.ofdm.code_rate_HP); | 597 | as102_fe_get_code_rate(params->u.ofdm.code_rate_HP); |
600 | } | 598 | } |
601 | } | 599 | } |
602 | |||
603 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index c019df933cc9..43ebc43e6b9a 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "as102_drv.h" | 26 | #include "as102_drv.h" |
27 | #include "as102_fw.h" | 27 | #include "as102_fw.h" |
28 | 28 | ||
29 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | ||
30 | char as102_st_fw1[] = "as102_data1_st.hex"; | 29 | char as102_st_fw1[] = "as102_data1_st.hex"; |
31 | char as102_st_fw2[] = "as102_data2_st.hex"; | 30 | char as102_st_fw2[] = "as102_data2_st.hex"; |
32 | char as102_dt_fw1[] = "as102_data1_dt.hex"; | 31 | char as102_dt_fw1[] = "as102_data1_dt.hex"; |
@@ -59,7 +58,7 @@ static int parse_hex_line(unsigned char *fw_data, unsigned char *addr, | |||
59 | unsigned char *src, dst; | 58 | unsigned char *src, dst; |
60 | 59 | ||
61 | if (*fw_data++ != ':') { | 60 | if (*fw_data++ != ':') { |
62 | printk(KERN_ERR "invalid firmware file\n"); | 61 | pr_err("invalid firmware file\n"); |
63 | return -EFAULT; | 62 | return -EFAULT; |
64 | } | 63 | } |
65 | 64 | ||
@@ -102,7 +101,7 @@ static int parse_hex_line(unsigned char *fw_data, unsigned char *addr, | |||
102 | return (count * 2) + 2; | 101 | return (count * 2) + 2; |
103 | } | 102 | } |
104 | 103 | ||
105 | static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap, | 104 | static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, |
106 | unsigned char *cmd, | 105 | unsigned char *cmd, |
107 | const struct firmware *firmware) { | 106 | const struct firmware *firmware) { |
108 | 107 | ||
@@ -163,19 +162,14 @@ error: | |||
163 | return (errno == 0) ? total_read_bytes : errno; | 162 | return (errno == 0) ? total_read_bytes : errno; |
164 | } | 163 | } |
165 | 164 | ||
166 | int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) | 165 | int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) |
167 | { | 166 | { |
168 | int errno = -EFAULT; | 167 | int errno = -EFAULT; |
169 | const struct firmware *firmware; | 168 | const struct firmware *firmware; |
170 | unsigned char *cmd_buf = NULL; | 169 | unsigned char *cmd_buf = NULL; |
171 | char *fw1, *fw2; | 170 | char *fw1, *fw2; |
172 | |||
173 | #if defined(CONFIG_AS102_USB) | ||
174 | struct usb_device *dev = bus_adap->usb_dev; | 171 | struct usb_device *dev = bus_adap->usb_dev; |
175 | #endif | 172 | |
176 | #if defined(CONFIG_AS102_SPI) | ||
177 | struct spi_device *dev = bus_adap->spi_dev; | ||
178 | #endif | ||
179 | ENTER(); | 173 | ENTER(); |
180 | 174 | ||
181 | /* select fw file to upload */ | 175 | /* select fw file to upload */ |
@@ -187,7 +181,6 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) | |||
187 | fw2 = as102_st_fw2; | 181 | fw2 = as102_st_fw2; |
188 | } | 182 | } |
189 | 183 | ||
190 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | ||
191 | /* allocate buffer to store firmware upload command and data */ | 184 | /* allocate buffer to store firmware upload command and data */ |
192 | cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL); | 185 | cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL); |
193 | if (cmd_buf == NULL) { | 186 | if (cmd_buf == NULL) { |
@@ -198,21 +191,21 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) | |||
198 | /* request kernel to locate firmware file: part1 */ | 191 | /* request kernel to locate firmware file: part1 */ |
199 | errno = request_firmware(&firmware, fw1, &dev->dev); | 192 | errno = request_firmware(&firmware, fw1, &dev->dev); |
200 | if (errno < 0) { | 193 | if (errno < 0) { |
201 | printk(KERN_ERR "%s: unable to locate firmware file: %s\n", | 194 | pr_err("%s: unable to locate firmware file: %s\n", |
202 | DRIVER_NAME, fw1); | 195 | DRIVER_NAME, fw1); |
203 | goto error; | 196 | goto error; |
204 | } | 197 | } |
205 | 198 | ||
206 | /* initiate firmware upload */ | 199 | /* initiate firmware upload */ |
207 | errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); | 200 | errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); |
208 | if (errno < 0) { | 201 | if (errno < 0) { |
209 | printk(KERN_ERR "%s: error during firmware upload part1\n", | 202 | pr_err("%s: error during firmware upload part1\n", |
210 | DRIVER_NAME); | 203 | DRIVER_NAME); |
211 | goto error; | 204 | goto error; |
212 | } | 205 | } |
213 | 206 | ||
214 | printk(KERN_INFO "%s: fimrware: %s loaded with success\n", | 207 | pr_info("%s: firmware: %s loaded with success\n", |
215 | DRIVER_NAME, fw1); | 208 | DRIVER_NAME, fw1); |
216 | release_firmware(firmware); | 209 | release_firmware(firmware); |
217 | 210 | ||
218 | /* wait for boot to complete */ | 211 | /* wait for boot to complete */ |
@@ -221,31 +214,28 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) | |||
221 | /* request kernel to locate firmware file: part2 */ | 214 | /* request kernel to locate firmware file: part2 */ |
222 | errno = request_firmware(&firmware, fw2, &dev->dev); | 215 | errno = request_firmware(&firmware, fw2, &dev->dev); |
223 | if (errno < 0) { | 216 | if (errno < 0) { |
224 | printk(KERN_ERR "%s: unable to locate firmware file: %s\n", | 217 | pr_err("%s: unable to locate firmware file: %s\n", |
225 | DRIVER_NAME, fw2); | 218 | DRIVER_NAME, fw2); |
226 | goto error; | 219 | goto error; |
227 | } | 220 | } |
228 | 221 | ||
229 | /* initiate firmware upload */ | 222 | /* initiate firmware upload */ |
230 | errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); | 223 | errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); |
231 | if (errno < 0) { | 224 | if (errno < 0) { |
232 | printk(KERN_ERR "%s: error during firmware upload part2\n", | 225 | pr_err("%s: error during firmware upload part2\n", |
233 | DRIVER_NAME); | 226 | DRIVER_NAME); |
234 | goto error; | 227 | goto error; |
235 | } | 228 | } |
236 | 229 | ||
237 | printk(KERN_INFO "%s: fimrware: %s loaded with success\n", | 230 | pr_info("%s: firmware: %s loaded with success\n", |
238 | DRIVER_NAME, fw2); | 231 | DRIVER_NAME, fw2); |
239 | error: | 232 | error: |
240 | /* free data buffer */ | 233 | /* free data buffer */ |
241 | kfree(cmd_buf); | 234 | kfree(cmd_buf); |
242 | /* release firmware if needed */ | 235 | /* release firmware if needed */ |
243 | if (firmware != NULL) | 236 | if (firmware != NULL) |
244 | release_firmware(firmware); | 237 | release_firmware(firmware); |
245 | #endif | 238 | |
246 | LEAVE(); | 239 | LEAVE(); |
247 | return errno; | 240 | return errno; |
248 | } | 241 | } |
249 | #endif | ||
250 | |||
251 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h index 27e5347e2e19..bd21f0554392 100644 --- a/drivers/staging/media/as102/as102_fw.h +++ b/drivers/staging/media/as102/as102_fw.h | |||
@@ -20,11 +20,10 @@ | |||
20 | 20 | ||
21 | extern int dual_tuner; | 21 | extern int dual_tuner; |
22 | 22 | ||
23 | #pragma pack(1) | ||
24 | struct as10x_raw_fw_pkt { | 23 | struct as10x_raw_fw_pkt { |
25 | unsigned char address[4]; | 24 | unsigned char address[4]; |
26 | unsigned char data[MAX_FW_PKT_SIZE - 6]; | 25 | unsigned char data[MAX_FW_PKT_SIZE - 6]; |
27 | }; | 26 | } __packed; |
28 | 27 | ||
29 | struct as10x_fw_pkt_t { | 28 | struct as10x_fw_pkt_t { |
30 | union { | 29 | union { |
@@ -32,11 +31,8 @@ struct as10x_fw_pkt_t { | |||
32 | unsigned char length[2]; | 31 | unsigned char length[2]; |
33 | } u; | 32 | } u; |
34 | struct as10x_raw_fw_pkt raw; | 33 | struct as10x_raw_fw_pkt raw; |
35 | }; | 34 | } __packed; |
36 | #pragma pack() | ||
37 | 35 | ||
38 | #ifdef __KERNEL__ | 36 | #ifdef __KERNEL__ |
39 | int as102_fw_upload(struct as102_bus_adapter_t *bus_adap); | 37 | int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap); |
40 | #endif | 38 | #endif |
41 | |||
42 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 264be2dbd2a4..7bcb28cdbabe 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c | |||
@@ -42,30 +42,32 @@ static struct usb_device_id as102_usb_id_table[] = { | |||
42 | { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) }, | 42 | { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) }, |
43 | { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) }, | 43 | { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) }, |
44 | { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) }, | 44 | { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) }, |
45 | { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) }, | ||
45 | { } /* Terminating entry */ | 46 | { } /* Terminating entry */ |
46 | }; | 47 | }; |
47 | 48 | ||
48 | /* Note that this table must always have the same number of entries as the | 49 | /* Note that this table must always have the same number of entries as the |
49 | as102_usb_id_table struct */ | 50 | as102_usb_id_table struct */ |
50 | static const char *as102_device_names[] = { | 51 | static const char * const as102_device_names[] = { |
51 | AS102_REFERENCE_DESIGN, | 52 | AS102_REFERENCE_DESIGN, |
52 | AS102_PCTV_74E, | 53 | AS102_PCTV_74E, |
53 | AS102_ELGATO_EYETV_DTT_NAME, | 54 | AS102_ELGATO_EYETV_DTT_NAME, |
54 | AS102_NBOX_DVBT_DONGLE_NAME, | 55 | AS102_NBOX_DVBT_DONGLE_NAME, |
56 | AS102_SKY_IT_DIGITAL_KEY_NAME, | ||
55 | NULL /* Terminating entry */ | 57 | NULL /* Terminating entry */ |
56 | }; | 58 | }; |
57 | 59 | ||
58 | struct usb_driver as102_usb_driver = { | 60 | struct usb_driver as102_usb_driver = { |
59 | .name = DRIVER_FULL_NAME, | 61 | .name = DRIVER_FULL_NAME, |
60 | .probe = as102_usb_probe, | 62 | .probe = as102_usb_probe, |
61 | .disconnect = as102_usb_disconnect, | 63 | .disconnect = as102_usb_disconnect, |
62 | .id_table = as102_usb_id_table | 64 | .id_table = as102_usb_id_table |
63 | }; | 65 | }; |
64 | 66 | ||
65 | static const struct file_operations as102_dev_fops = { | 67 | static const struct file_operations as102_dev_fops = { |
66 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
67 | .open = as102_open, | 69 | .open = as102_open, |
68 | .release = as102_release, | 70 | .release = as102_release, |
69 | }; | 71 | }; |
70 | 72 | ||
71 | static struct usb_class_driver as102_usb_class_driver = { | 73 | static struct usb_class_driver as102_usb_class_driver = { |
@@ -74,7 +76,7 @@ static struct usb_class_driver as102_usb_class_driver = { | |||
74 | .minor_base = AS102_DEVICE_MAJOR, | 76 | .minor_base = AS102_DEVICE_MAJOR, |
75 | }; | 77 | }; |
76 | 78 | ||
77 | static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap, | 79 | static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap, |
78 | unsigned char *send_buf, int send_buf_len, | 80 | unsigned char *send_buf, int send_buf_len, |
79 | unsigned char *recv_buf, int recv_buf_len) | 81 | unsigned char *recv_buf, int recv_buf_len) |
80 | { | 82 | { |
@@ -131,7 +133,7 @@ static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap, | |||
131 | return ret; | 133 | return ret; |
132 | } | 134 | } |
133 | 135 | ||
134 | static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap, | 136 | static int as102_send_ep1(struct as10x_bus_adapter_t *bus_adap, |
135 | unsigned char *send_buf, | 137 | unsigned char *send_buf, |
136 | int send_buf_len, | 138 | int send_buf_len, |
137 | int swap32) | 139 | int swap32) |
@@ -154,7 +156,7 @@ static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap, | |||
154 | return ret ? ret : actual_len; | 156 | return ret ? ret : actual_len; |
155 | } | 157 | } |
156 | 158 | ||
157 | static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap, | 159 | static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap, |
158 | unsigned char *recv_buf, int recv_buf_len) | 160 | unsigned char *recv_buf, int recv_buf_len) |
159 | { | 161 | { |
160 | int ret = 0, actual_len; | 162 | int ret = 0, actual_len; |
@@ -337,7 +339,7 @@ static void as102_usb_disconnect(struct usb_interface *intf) | |||
337 | /* decrement usage counter */ | 339 | /* decrement usage counter */ |
338 | kref_put(&as102_dev->kref, as102_usb_release); | 340 | kref_put(&as102_dev->kref, as102_usb_release); |
339 | 341 | ||
340 | printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME); | 342 | pr_info("%s: device has been disconnected\n", DRIVER_NAME); |
341 | 343 | ||
342 | LEAVE(); | 344 | LEAVE(); |
343 | } | 345 | } |
@@ -360,7 +362,7 @@ static int as102_usb_probe(struct usb_interface *intf, | |||
360 | /* This should never actually happen */ | 362 | /* This should never actually happen */ |
361 | if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) != | 363 | if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) != |
362 | (sizeof(as102_device_names) / sizeof(const char *))) { | 364 | (sizeof(as102_device_names) / sizeof(const char *))) { |
363 | printk(KERN_ERR "Device names table invalid size"); | 365 | pr_err("Device names table invalid size"); |
364 | return -EINVAL; | 366 | return -EINVAL; |
365 | } | 367 | } |
366 | 368 | ||
@@ -399,7 +401,7 @@ static int as102_usb_probe(struct usb_interface *intf, | |||
399 | goto failed; | 401 | goto failed; |
400 | } | 402 | } |
401 | 403 | ||
402 | printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME); | 404 | pr_info("%s: device has been detected\n", DRIVER_NAME); |
403 | 405 | ||
404 | /* request buffer allocation for streaming */ | 406 | /* request buffer allocation for streaming */ |
405 | ret = as102_alloc_usb_stream_buffer(as102_dev); | 407 | ret = as102_alloc_usb_stream_buffer(as102_dev); |
@@ -432,8 +434,8 @@ static int as102_open(struct inode *inode, struct file *file) | |||
432 | /* fetch device from usb interface */ | 434 | /* fetch device from usb interface */ |
433 | intf = usb_find_interface(&as102_usb_driver, minor); | 435 | intf = usb_find_interface(&as102_usb_driver, minor); |
434 | if (intf == NULL) { | 436 | if (intf == NULL) { |
435 | printk(KERN_ERR "%s: can't find device for minor %d\n", | 437 | pr_err("%s: can't find device for minor %d\n", |
436 | __func__, minor); | 438 | __func__, minor); |
437 | ret = -ENODEV; | 439 | ret = -ENODEV; |
438 | goto exit; | 440 | goto exit; |
439 | } | 441 | } |
@@ -474,5 +476,3 @@ static int as102_release(struct inode *inode, struct file *file) | |||
474 | } | 476 | } |
475 | 477 | ||
476 | MODULE_DEVICE_TABLE(usb, as102_usb_id_table); | 478 | MODULE_DEVICE_TABLE(usb, as102_usb_id_table); |
477 | |||
478 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h index fb1fc41dcd79..fc2884ab02a2 100644 --- a/drivers/staging/media/as102/as102_usb_drv.h +++ b/drivers/staging/media/as102/as102_usb_drv.h | |||
@@ -47,6 +47,11 @@ | |||
47 | #define NBOX_DVBT_DONGLE_USB_VID 0x0b89 | 47 | #define NBOX_DVBT_DONGLE_USB_VID 0x0b89 |
48 | #define NBOX_DVBT_DONGLE_USB_PID 0x0007 | 48 | #define NBOX_DVBT_DONGLE_USB_PID 0x0007 |
49 | 49 | ||
50 | /* Sky Italia: Digital Key (green led) */ | ||
51 | #define AS102_SKY_IT_DIGITAL_KEY_NAME "Sky IT Digital Key (green led)" | ||
52 | #define SKY_IT_DIGITAL_KEY_USB_VID 0x2137 | ||
53 | #define SKY_IT_DIGITAL_KEY_USB_PID 0x0001 | ||
54 | |||
50 | void as102_urb_stream_irq(struct urb *urb); | 55 | void as102_urb_stream_irq(struct urb *urb); |
51 | 56 | ||
52 | struct as10x_usb_token_cmd_t { | 57 | struct as10x_usb_token_cmd_t { |
@@ -56,4 +61,3 @@ struct as10x_usb_token_cmd_t { | |||
56 | struct as10x_cmd_t r; | 61 | struct as10x_cmd_t r; |
57 | }; | 62 | }; |
58 | #endif | 63 | #endif |
59 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ | ||
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c index 0dcba8065780..0387bb85cafe 100644 --- a/drivers/staging/media/as102/as10x_cmd.c +++ b/drivers/staging/media/as102/as10x_cmd.c | |||
@@ -25,35 +25,35 @@ | |||
25 | 25 | ||
26 | /** | 26 | /** |
27 | * as10x_cmd_turn_on - send turn on command to AS10x | 27 | * as10x_cmd_turn_on - send turn on command to AS10x |
28 | * @phandle: pointer to AS10x handle | 28 | * @adap: pointer to AS10x bus adapter |
29 | * | 29 | * |
30 | * Return 0 when no error, < 0 in case of error. | 30 | * Return 0 when no error, < 0 in case of error. |
31 | */ | 31 | */ |
32 | int as10x_cmd_turn_on(as10x_handle_t *phandle) | 32 | int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap) |
33 | { | 33 | { |
34 | int error; | 34 | int error; |
35 | struct as10x_cmd_t *pcmd, *prsp; | 35 | struct as10x_cmd_t *pcmd, *prsp; |
36 | 36 | ||
37 | ENTER(); | 37 | ENTER(); |
38 | 38 | ||
39 | pcmd = phandle->cmd; | 39 | pcmd = adap->cmd; |
40 | prsp = phandle->rsp; | 40 | prsp = adap->rsp; |
41 | 41 | ||
42 | /* prepare command */ | 42 | /* prepare command */ |
43 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 43 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
44 | sizeof(pcmd->body.turn_on.req)); | 44 | sizeof(pcmd->body.turn_on.req)); |
45 | 45 | ||
46 | /* fill command */ | 46 | /* fill command */ |
47 | pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON); | 47 | pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON); |
48 | 48 | ||
49 | /* send command */ | 49 | /* send command */ |
50 | if (phandle->ops->xfer_cmd) { | 50 | if (adap->ops->xfer_cmd) { |
51 | error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, | 51 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
52 | sizeof(pcmd->body.turn_on.req) + | 52 | sizeof(pcmd->body.turn_on.req) + |
53 | HEADER_SIZE, | 53 | HEADER_SIZE, |
54 | (uint8_t *) prsp, | 54 | (uint8_t *) prsp, |
55 | sizeof(prsp->body.turn_on.rsp) + | 55 | sizeof(prsp->body.turn_on.rsp) + |
56 | HEADER_SIZE); | 56 | HEADER_SIZE); |
57 | } else { | 57 | } else { |
58 | error = AS10X_CMD_ERROR; | 58 | error = AS10X_CMD_ERROR; |
59 | } | 59 | } |
@@ -71,31 +71,31 @@ out: | |||
71 | 71 | ||
72 | /** | 72 | /** |
73 | * as10x_cmd_turn_off - send turn off command to AS10x | 73 | * as10x_cmd_turn_off - send turn off command to AS10x |
74 | * @phandle: pointer to AS10x handle | 74 | * @adap: pointer to AS10x bus adapter |
75 | * | 75 | * |
76 | * Return 0 on success or negative value in case of error. | 76 | * Return 0 on success or negative value in case of error. |
77 | */ | 77 | */ |
78 | int as10x_cmd_turn_off(as10x_handle_t *phandle) | 78 | int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap) |
79 | { | 79 | { |
80 | int error; | 80 | int error; |
81 | struct as10x_cmd_t *pcmd, *prsp; | 81 | struct as10x_cmd_t *pcmd, *prsp; |
82 | 82 | ||
83 | ENTER(); | 83 | ENTER(); |
84 | 84 | ||
85 | pcmd = phandle->cmd; | 85 | pcmd = adap->cmd; |
86 | prsp = phandle->rsp; | 86 | prsp = adap->rsp; |
87 | 87 | ||
88 | /* prepare command */ | 88 | /* prepare command */ |
89 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 89 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
90 | sizeof(pcmd->body.turn_off.req)); | 90 | sizeof(pcmd->body.turn_off.req)); |
91 | 91 | ||
92 | /* fill command */ | 92 | /* fill command */ |
93 | pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF); | 93 | pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF); |
94 | 94 | ||
95 | /* send command */ | 95 | /* send command */ |
96 | if (phandle->ops->xfer_cmd) { | 96 | if (adap->ops->xfer_cmd) { |
97 | error = phandle->ops->xfer_cmd( | 97 | error = adap->ops->xfer_cmd( |
98 | phandle, (uint8_t *) pcmd, | 98 | adap, (uint8_t *) pcmd, |
99 | sizeof(pcmd->body.turn_off.req) + HEADER_SIZE, | 99 | sizeof(pcmd->body.turn_off.req) + HEADER_SIZE, |
100 | (uint8_t *) prsp, | 100 | (uint8_t *) prsp, |
101 | sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE); | 101 | sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE); |
@@ -116,23 +116,24 @@ out: | |||
116 | 116 | ||
117 | /** | 117 | /** |
118 | * as10x_cmd_set_tune - send set tune command to AS10x | 118 | * as10x_cmd_set_tune - send set tune command to AS10x |
119 | * @phandle: pointer to AS10x handle | 119 | * @adap: pointer to AS10x bus adapter |
120 | * @ptune: tune parameters | 120 | * @ptune: tune parameters |
121 | * | 121 | * |
122 | * Return 0 on success or negative value in case of error. | 122 | * Return 0 on success or negative value in case of error. |
123 | */ | 123 | */ |
124 | int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune) | 124 | int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap, |
125 | struct as10x_tune_args *ptune) | ||
125 | { | 126 | { |
126 | int error; | 127 | int error; |
127 | struct as10x_cmd_t *preq, *prsp; | 128 | struct as10x_cmd_t *preq, *prsp; |
128 | 129 | ||
129 | ENTER(); | 130 | ENTER(); |
130 | 131 | ||
131 | preq = phandle->cmd; | 132 | preq = adap->cmd; |
132 | prsp = phandle->rsp; | 133 | prsp = adap->rsp; |
133 | 134 | ||
134 | /* prepare command */ | 135 | /* prepare command */ |
135 | as10x_cmd_build(preq, (++phandle->cmd_xid), | 136 | as10x_cmd_build(preq, (++adap->cmd_xid), |
136 | sizeof(preq->body.set_tune.req)); | 137 | sizeof(preq->body.set_tune.req)); |
137 | 138 | ||
138 | /* fill command */ | 139 | /* fill command */ |
@@ -150,14 +151,14 @@ int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune) | |||
150 | ptune->transmission_mode; | 151 | ptune->transmission_mode; |
151 | 152 | ||
152 | /* send command */ | 153 | /* send command */ |
153 | if (phandle->ops->xfer_cmd) { | 154 | if (adap->ops->xfer_cmd) { |
154 | error = phandle->ops->xfer_cmd(phandle, | 155 | error = adap->ops->xfer_cmd(adap, |
155 | (uint8_t *) preq, | 156 | (uint8_t *) preq, |
156 | sizeof(preq->body.set_tune.req) | 157 | sizeof(preq->body.set_tune.req) |
157 | + HEADER_SIZE, | 158 | + HEADER_SIZE, |
158 | (uint8_t *) prsp, | 159 | (uint8_t *) prsp, |
159 | sizeof(prsp->body.set_tune.rsp) | 160 | sizeof(prsp->body.set_tune.rsp) |
160 | + HEADER_SIZE); | 161 | + HEADER_SIZE); |
161 | } else { | 162 | } else { |
162 | error = AS10X_CMD_ERROR; | 163 | error = AS10X_CMD_ERROR; |
163 | } | 164 | } |
@@ -175,12 +176,12 @@ out: | |||
175 | 176 | ||
176 | /** | 177 | /** |
177 | * as10x_cmd_get_tune_status - send get tune status command to AS10x | 178 | * as10x_cmd_get_tune_status - send get tune status command to AS10x |
178 | * @phandle: pointer to AS10x handle | 179 | * @adap: pointer to AS10x bus adapter |
179 | * @pstatus: pointer to updated status structure of the current tune | 180 | * @pstatus: pointer to updated status structure of the current tune |
180 | * | 181 | * |
181 | * Return 0 on success or negative value in case of error. | 182 | * Return 0 on success or negative value in case of error. |
182 | */ | 183 | */ |
183 | int as10x_cmd_get_tune_status(as10x_handle_t *phandle, | 184 | int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap, |
184 | struct as10x_tune_status *pstatus) | 185 | struct as10x_tune_status *pstatus) |
185 | { | 186 | { |
186 | int error; | 187 | int error; |
@@ -188,11 +189,11 @@ int as10x_cmd_get_tune_status(as10x_handle_t *phandle, | |||
188 | 189 | ||
189 | ENTER(); | 190 | ENTER(); |
190 | 191 | ||
191 | preq = phandle->cmd; | 192 | preq = adap->cmd; |
192 | prsp = phandle->rsp; | 193 | prsp = adap->rsp; |
193 | 194 | ||
194 | /* prepare command */ | 195 | /* prepare command */ |
195 | as10x_cmd_build(preq, (++phandle->cmd_xid), | 196 | as10x_cmd_build(preq, (++adap->cmd_xid), |
196 | sizeof(preq->body.get_tune_status.req)); | 197 | sizeof(preq->body.get_tune_status.req)); |
197 | 198 | ||
198 | /* fill command */ | 199 | /* fill command */ |
@@ -200,9 +201,9 @@ int as10x_cmd_get_tune_status(as10x_handle_t *phandle, | |||
200 | cpu_to_le16(CONTROL_PROC_GETTUNESTAT); | 201 | cpu_to_le16(CONTROL_PROC_GETTUNESTAT); |
201 | 202 | ||
202 | /* send command */ | 203 | /* send command */ |
203 | if (phandle->ops->xfer_cmd) { | 204 | if (adap->ops->xfer_cmd) { |
204 | error = phandle->ops->xfer_cmd( | 205 | error = adap->ops->xfer_cmd( |
205 | phandle, | 206 | adap, |
206 | (uint8_t *) preq, | 207 | (uint8_t *) preq, |
207 | sizeof(preq->body.get_tune_status.req) + HEADER_SIZE, | 208 | sizeof(preq->body.get_tune_status.req) + HEADER_SIZE, |
208 | (uint8_t *) prsp, | 209 | (uint8_t *) prsp, |
@@ -232,24 +233,24 @@ out: | |||
232 | } | 233 | } |
233 | 234 | ||
234 | /** | 235 | /** |
235 | * send get TPS command to AS10x | 236 | * as10x_cmd_get_tps - send get TPS command to AS10x |
236 | * @phandle: pointer to AS10x handle | 237 | * @adap: pointer to AS10x handle |
237 | * @ptps: pointer to TPS parameters structure | 238 | * @ptps: pointer to TPS parameters structure |
238 | * | 239 | * |
239 | * Return 0 on success or negative value in case of error. | 240 | * Return 0 on success or negative value in case of error. |
240 | */ | 241 | */ |
241 | int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps) | 242 | int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps) |
242 | { | 243 | { |
243 | int error; | 244 | int error; |
244 | struct as10x_cmd_t *pcmd, *prsp; | 245 | struct as10x_cmd_t *pcmd, *prsp; |
245 | 246 | ||
246 | ENTER(); | 247 | ENTER(); |
247 | 248 | ||
248 | pcmd = phandle->cmd; | 249 | pcmd = adap->cmd; |
249 | prsp = phandle->rsp; | 250 | prsp = adap->rsp; |
250 | 251 | ||
251 | /* prepare command */ | 252 | /* prepare command */ |
252 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 253 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
253 | sizeof(pcmd->body.get_tps.req)); | 254 | sizeof(pcmd->body.get_tps.req)); |
254 | 255 | ||
255 | /* fill command */ | 256 | /* fill command */ |
@@ -257,14 +258,14 @@ int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps) | |||
257 | cpu_to_le16(CONTROL_PROC_GETTPS); | 258 | cpu_to_le16(CONTROL_PROC_GETTPS); |
258 | 259 | ||
259 | /* send command */ | 260 | /* send command */ |
260 | if (phandle->ops->xfer_cmd) { | 261 | if (adap->ops->xfer_cmd) { |
261 | error = phandle->ops->xfer_cmd(phandle, | 262 | error = adap->ops->xfer_cmd(adap, |
262 | (uint8_t *) pcmd, | 263 | (uint8_t *) pcmd, |
263 | sizeof(pcmd->body.get_tps.req) + | 264 | sizeof(pcmd->body.get_tps.req) + |
264 | HEADER_SIZE, | 265 | HEADER_SIZE, |
265 | (uint8_t *) prsp, | 266 | (uint8_t *) prsp, |
266 | sizeof(prsp->body.get_tps.rsp) + | 267 | sizeof(prsp->body.get_tps.rsp) + |
267 | HEADER_SIZE); | 268 | HEADER_SIZE); |
268 | } else { | 269 | } else { |
269 | error = AS10X_CMD_ERROR; | 270 | error = AS10X_CMD_ERROR; |
270 | } | 271 | } |
@@ -296,12 +297,12 @@ out: | |||
296 | 297 | ||
297 | /** | 298 | /** |
298 | * as10x_cmd_get_demod_stats - send get demod stats command to AS10x | 299 | * as10x_cmd_get_demod_stats - send get demod stats command to AS10x |
299 | * @phandle: pointer to AS10x handle | 300 | * @adap: pointer to AS10x bus adapter |
300 | * @pdemod_stats: pointer to demod stats parameters structure | 301 | * @pdemod_stats: pointer to demod stats parameters structure |
301 | * | 302 | * |
302 | * Return 0 on success or negative value in case of error. | 303 | * Return 0 on success or negative value in case of error. |
303 | */ | 304 | */ |
304 | int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, | 305 | int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap, |
305 | struct as10x_demod_stats *pdemod_stats) | 306 | struct as10x_demod_stats *pdemod_stats) |
306 | { | 307 | { |
307 | int error; | 308 | int error; |
@@ -309,11 +310,11 @@ int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, | |||
309 | 310 | ||
310 | ENTER(); | 311 | ENTER(); |
311 | 312 | ||
312 | pcmd = phandle->cmd; | 313 | pcmd = adap->cmd; |
313 | prsp = phandle->rsp; | 314 | prsp = adap->rsp; |
314 | 315 | ||
315 | /* prepare command */ | 316 | /* prepare command */ |
316 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 317 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
317 | sizeof(pcmd->body.get_demod_stats.req)); | 318 | sizeof(pcmd->body.get_demod_stats.req)); |
318 | 319 | ||
319 | /* fill command */ | 320 | /* fill command */ |
@@ -321,8 +322,8 @@ int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, | |||
321 | cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS); | 322 | cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS); |
322 | 323 | ||
323 | /* send command */ | 324 | /* send command */ |
324 | if (phandle->ops->xfer_cmd) { | 325 | if (adap->ops->xfer_cmd) { |
325 | error = phandle->ops->xfer_cmd(phandle, | 326 | error = adap->ops->xfer_cmd(adap, |
326 | (uint8_t *) pcmd, | 327 | (uint8_t *) pcmd, |
327 | sizeof(pcmd->body.get_demod_stats.req) | 328 | sizeof(pcmd->body.get_demod_stats.req) |
328 | + HEADER_SIZE, | 329 | + HEADER_SIZE, |
@@ -360,13 +361,13 @@ out: | |||
360 | 361 | ||
361 | /** | 362 | /** |
362 | * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x | 363 | * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x |
363 | * @phandle: pointer to AS10x handle | 364 | * @adap: pointer to AS10x bus adapter |
364 | * @is_ready: pointer to value indicating when impulse | 365 | * @is_ready: pointer to value indicating when impulse |
365 | * response data is ready | 366 | * response data is ready |
366 | * | 367 | * |
367 | * Return 0 on success or negative value in case of error. | 368 | * Return 0 on success or negative value in case of error. |
368 | */ | 369 | */ |
369 | int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, | 370 | int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap, |
370 | uint8_t *is_ready) | 371 | uint8_t *is_ready) |
371 | { | 372 | { |
372 | int error; | 373 | int error; |
@@ -374,11 +375,11 @@ int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, | |||
374 | 375 | ||
375 | ENTER(); | 376 | ENTER(); |
376 | 377 | ||
377 | pcmd = phandle->cmd; | 378 | pcmd = adap->cmd; |
378 | prsp = phandle->rsp; | 379 | prsp = adap->rsp; |
379 | 380 | ||
380 | /* prepare command */ | 381 | /* prepare command */ |
381 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 382 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
382 | sizeof(pcmd->body.get_impulse_rsp.req)); | 383 | sizeof(pcmd->body.get_impulse_rsp.req)); |
383 | 384 | ||
384 | /* fill command */ | 385 | /* fill command */ |
@@ -386,8 +387,8 @@ int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, | |||
386 | cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP); | 387 | cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP); |
387 | 388 | ||
388 | /* send command */ | 389 | /* send command */ |
389 | if (phandle->ops->xfer_cmd) { | 390 | if (adap->ops->xfer_cmd) { |
390 | error = phandle->ops->xfer_cmd(phandle, | 391 | error = adap->ops->xfer_cmd(adap, |
391 | (uint8_t *) pcmd, | 392 | (uint8_t *) pcmd, |
392 | sizeof(pcmd->body.get_impulse_rsp.req) | 393 | sizeof(pcmd->body.get_impulse_rsp.req) |
393 | + HEADER_SIZE, | 394 | + HEADER_SIZE, |
diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index 01a716380e0a..4ea249e7adab 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h | |||
@@ -28,459 +28,456 @@ | |||
28 | /*********************************/ | 28 | /*********************************/ |
29 | /* MACRO DEFINITIONS */ | 29 | /* MACRO DEFINITIONS */ |
30 | /*********************************/ | 30 | /*********************************/ |
31 | #define AS10X_CMD_ERROR -1 | 31 | #define AS10X_CMD_ERROR -1 |
32 | 32 | ||
33 | #define SERVICE_PROG_ID 0x0002 | 33 | #define SERVICE_PROG_ID 0x0002 |
34 | #define SERVICE_PROG_VERSION 0x0001 | 34 | #define SERVICE_PROG_VERSION 0x0001 |
35 | 35 | ||
36 | #define HIER_NONE 0x00 | 36 | #define HIER_NONE 0x00 |
37 | #define HIER_LOW_PRIORITY 0x01 | 37 | #define HIER_LOW_PRIORITY 0x01 |
38 | 38 | ||
39 | #define HEADER_SIZE (sizeof(struct as10x_cmd_header_t)) | 39 | #define HEADER_SIZE (sizeof(struct as10x_cmd_header_t)) |
40 | 40 | ||
41 | /* context request types */ | 41 | /* context request types */ |
42 | #define GET_CONTEXT_DATA 1 | 42 | #define GET_CONTEXT_DATA 1 |
43 | #define SET_CONTEXT_DATA 2 | 43 | #define SET_CONTEXT_DATA 2 |
44 | 44 | ||
45 | /* ODSP suspend modes */ | 45 | /* ODSP suspend modes */ |
46 | #define CFG_MODE_ODSP_RESUME 0 | 46 | #define CFG_MODE_ODSP_RESUME 0 |
47 | #define CFG_MODE_ODSP_SUSPEND 1 | 47 | #define CFG_MODE_ODSP_SUSPEND 1 |
48 | 48 | ||
49 | /* Dump memory size */ | 49 | /* Dump memory size */ |
50 | #define DUMP_BLOCK_SIZE_MAX 0x20 | 50 | #define DUMP_BLOCK_SIZE_MAX 0x20 |
51 | 51 | ||
52 | /*********************************/ | 52 | /*********************************/ |
53 | /* TYPE DEFINITION */ | 53 | /* TYPE DEFINITION */ |
54 | /*********************************/ | 54 | /*********************************/ |
55 | typedef enum { | 55 | enum control_proc { |
56 | CONTROL_PROC_TURNON = 0x0001, | 56 | CONTROL_PROC_TURNON = 0x0001, |
57 | CONTROL_PROC_TURNON_RSP = 0x0100, | 57 | CONTROL_PROC_TURNON_RSP = 0x0100, |
58 | CONTROL_PROC_SET_REGISTER = 0x0002, | 58 | CONTROL_PROC_SET_REGISTER = 0x0002, |
59 | CONTROL_PROC_SET_REGISTER_RSP = 0x0200, | 59 | CONTROL_PROC_SET_REGISTER_RSP = 0x0200, |
60 | CONTROL_PROC_GET_REGISTER = 0x0003, | 60 | CONTROL_PROC_GET_REGISTER = 0x0003, |
61 | CONTROL_PROC_GET_REGISTER_RSP = 0x0300, | 61 | CONTROL_PROC_GET_REGISTER_RSP = 0x0300, |
62 | CONTROL_PROC_SETTUNE = 0x000A, | 62 | CONTROL_PROC_SETTUNE = 0x000A, |
63 | CONTROL_PROC_SETTUNE_RSP = 0x0A00, | 63 | CONTROL_PROC_SETTUNE_RSP = 0x0A00, |
64 | CONTROL_PROC_GETTUNESTAT = 0x000B, | 64 | CONTROL_PROC_GETTUNESTAT = 0x000B, |
65 | CONTROL_PROC_GETTUNESTAT_RSP = 0x0B00, | 65 | CONTROL_PROC_GETTUNESTAT_RSP = 0x0B00, |
66 | CONTROL_PROC_GETTPS = 0x000D, | 66 | CONTROL_PROC_GETTPS = 0x000D, |
67 | CONTROL_PROC_GETTPS_RSP = 0x0D00, | 67 | CONTROL_PROC_GETTPS_RSP = 0x0D00, |
68 | CONTROL_PROC_SETFILTER = 0x000E, | 68 | CONTROL_PROC_SETFILTER = 0x000E, |
69 | CONTROL_PROC_SETFILTER_RSP = 0x0E00, | 69 | CONTROL_PROC_SETFILTER_RSP = 0x0E00, |
70 | CONTROL_PROC_REMOVEFILTER = 0x000F, | 70 | CONTROL_PROC_REMOVEFILTER = 0x000F, |
71 | CONTROL_PROC_REMOVEFILTER_RSP = 0x0F00, | 71 | CONTROL_PROC_REMOVEFILTER_RSP = 0x0F00, |
72 | CONTROL_PROC_GET_IMPULSE_RESP = 0x0012, | 72 | CONTROL_PROC_GET_IMPULSE_RESP = 0x0012, |
73 | CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200, | 73 | CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200, |
74 | CONTROL_PROC_START_STREAMING = 0x0013, | 74 | CONTROL_PROC_START_STREAMING = 0x0013, |
75 | CONTROL_PROC_START_STREAMING_RSP = 0x1300, | 75 | CONTROL_PROC_START_STREAMING_RSP = 0x1300, |
76 | CONTROL_PROC_STOP_STREAMING = 0x0014, | 76 | CONTROL_PROC_STOP_STREAMING = 0x0014, |
77 | CONTROL_PROC_STOP_STREAMING_RSP = 0x1400, | 77 | CONTROL_PROC_STOP_STREAMING_RSP = 0x1400, |
78 | CONTROL_PROC_GET_DEMOD_STATS = 0x0015, | 78 | CONTROL_PROC_GET_DEMOD_STATS = 0x0015, |
79 | CONTROL_PROC_GET_DEMOD_STATS_RSP = 0x1500, | 79 | CONTROL_PROC_GET_DEMOD_STATS_RSP = 0x1500, |
80 | CONTROL_PROC_ELNA_CHANGE_MODE = 0x0016, | 80 | CONTROL_PROC_ELNA_CHANGE_MODE = 0x0016, |
81 | CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600, | 81 | CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600, |
82 | CONTROL_PROC_ODSP_CHANGE_MODE = 0x0017, | 82 | CONTROL_PROC_ODSP_CHANGE_MODE = 0x0017, |
83 | CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700, | 83 | CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700, |
84 | CONTROL_PROC_AGC_CHANGE_MODE = 0x0018, | 84 | CONTROL_PROC_AGC_CHANGE_MODE = 0x0018, |
85 | CONTROL_PROC_AGC_CHANGE_MODE_RSP = 0x1800, | 85 | CONTROL_PROC_AGC_CHANGE_MODE_RSP = 0x1800, |
86 | 86 | ||
87 | CONTROL_PROC_CONTEXT = 0x00FC, | 87 | CONTROL_PROC_CONTEXT = 0x00FC, |
88 | CONTROL_PROC_CONTEXT_RSP = 0xFC00, | 88 | CONTROL_PROC_CONTEXT_RSP = 0xFC00, |
89 | CONTROL_PROC_DUMP_MEMORY = 0x00FD, | 89 | CONTROL_PROC_DUMP_MEMORY = 0x00FD, |
90 | CONTROL_PROC_DUMP_MEMORY_RSP = 0xFD00, | 90 | CONTROL_PROC_DUMP_MEMORY_RSP = 0xFD00, |
91 | CONTROL_PROC_DUMPLOG_MEMORY = 0x00FE, | 91 | CONTROL_PROC_DUMPLOG_MEMORY = 0x00FE, |
92 | CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00, | 92 | CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00, |
93 | CONTROL_PROC_TURNOFF = 0x00FF, | 93 | CONTROL_PROC_TURNOFF = 0x00FF, |
94 | CONTROL_PROC_TURNOFF_RSP = 0xFF00 | 94 | CONTROL_PROC_TURNOFF_RSP = 0xFF00 |
95 | } control_proc; | 95 | }; |
96 | 96 | ||
97 | 97 | union as10x_turn_on { | |
98 | #pragma pack(1) | 98 | /* request */ |
99 | typedef union { | 99 | struct { |
100 | /* request */ | 100 | /* request identifier */ |
101 | struct { | 101 | uint16_t proc_id; |
102 | /* request identifier */ | 102 | } req; |
103 | uint16_t proc_id; | 103 | /* response */ |
104 | } req; | 104 | struct { |
105 | /* response */ | 105 | /* response identifier */ |
106 | struct { | 106 | uint16_t proc_id; |
107 | /* response identifier */ | 107 | /* error */ |
108 | uint16_t proc_id; | 108 | uint8_t error; |
109 | /* error */ | 109 | } rsp; |
110 | uint8_t error; | 110 | } __packed; |
111 | } rsp; | 111 | |
112 | } TURN_ON; | 112 | union as10x_turn_off { |
113 | 113 | /* request */ | |
114 | typedef union { | 114 | struct { |
115 | /* request */ | 115 | /* request identifier */ |
116 | struct { | 116 | uint16_t proc_id; |
117 | /* request identifier */ | 117 | } req; |
118 | uint16_t proc_id; | 118 | /* response */ |
119 | } req; | 119 | struct { |
120 | /* response */ | 120 | /* response identifier */ |
121 | struct { | 121 | uint16_t proc_id; |
122 | /* response identifier */ | 122 | /* error */ |
123 | uint16_t proc_id; | 123 | uint8_t err; |
124 | /* error */ | 124 | } rsp; |
125 | uint8_t err; | 125 | } __packed; |
126 | } rsp; | 126 | |
127 | } TURN_OFF; | 127 | union as10x_set_tune { |
128 | 128 | /* request */ | |
129 | typedef union { | 129 | struct { |
130 | /* request */ | 130 | /* request identifier */ |
131 | struct { | 131 | uint16_t proc_id; |
132 | /* request identifier */ | 132 | /* tune params */ |
133 | uint16_t proc_id; | 133 | struct as10x_tune_args args; |
134 | /* tune params */ | 134 | } req; |
135 | struct as10x_tune_args args; | 135 | /* response */ |
136 | } req; | 136 | struct { |
137 | /* response */ | 137 | /* response identifier */ |
138 | struct { | 138 | uint16_t proc_id; |
139 | /* response identifier */ | 139 | /* response error */ |
140 | uint16_t proc_id; | 140 | uint8_t error; |
141 | /* response error */ | 141 | } rsp; |
142 | uint8_t error; | 142 | } __packed; |
143 | } rsp; | 143 | |
144 | } SET_TUNE; | 144 | union as10x_get_tune_status { |
145 | 145 | /* request */ | |
146 | typedef union { | 146 | struct { |
147 | /* request */ | 147 | /* request identifier */ |
148 | struct { | 148 | uint16_t proc_id; |
149 | /* request identifier */ | 149 | } req; |
150 | uint16_t proc_id; | 150 | /* response */ |
151 | } req; | 151 | struct { |
152 | /* response */ | 152 | /* response identifier */ |
153 | struct { | 153 | uint16_t proc_id; |
154 | /* response identifier */ | 154 | /* response error */ |
155 | uint16_t proc_id; | 155 | uint8_t error; |
156 | /* response error */ | 156 | /* tune status */ |
157 | uint8_t error; | 157 | struct as10x_tune_status sts; |
158 | /* tune status */ | 158 | } rsp; |
159 | struct as10x_tune_status sts; | 159 | } __packed; |
160 | } rsp; | 160 | |
161 | } GET_TUNE_STATUS; | 161 | union as10x_get_tps { |
162 | 162 | /* request */ | |
163 | typedef union { | 163 | struct { |
164 | /* request */ | 164 | /* request identifier */ |
165 | struct { | 165 | uint16_t proc_id; |
166 | /* request identifier */ | 166 | } req; |
167 | uint16_t proc_id; | 167 | /* response */ |
168 | } req; | 168 | struct { |
169 | /* response */ | 169 | /* response identifier */ |
170 | struct { | 170 | uint16_t proc_id; |
171 | /* response identifier */ | 171 | /* response error */ |
172 | uint16_t proc_id; | 172 | uint8_t error; |
173 | /* response error */ | 173 | /* tps details */ |
174 | uint8_t error; | 174 | struct as10x_tps tps; |
175 | /* tps details */ | 175 | } rsp; |
176 | struct as10x_tps tps; | 176 | } __packed; |
177 | } rsp; | 177 | |
178 | } GET_TPS; | 178 | union as10x_common { |
179 | 179 | /* request */ | |
180 | typedef union { | 180 | struct { |
181 | /* request */ | 181 | /* request identifier */ |
182 | struct { | 182 | uint16_t proc_id; |
183 | /* request identifier */ | 183 | } req; |
184 | uint16_t proc_id; | 184 | /* response */ |
185 | } req; | 185 | struct { |
186 | /* response */ | 186 | /* response identifier */ |
187 | struct { | 187 | uint16_t proc_id; |
188 | /* response identifier */ | 188 | /* response error */ |
189 | uint16_t proc_id; | 189 | uint8_t error; |
190 | /* response error */ | 190 | } rsp; |
191 | uint8_t error; | 191 | } __packed; |
192 | } rsp; | 192 | |
193 | } COMMON; | 193 | union as10x_add_pid_filter { |
194 | 194 | /* request */ | |
195 | typedef union { | 195 | struct { |
196 | /* request */ | 196 | /* request identifier */ |
197 | struct { | 197 | uint16_t proc_id; |
198 | /* request identifier */ | 198 | /* PID to filter */ |
199 | uint16_t proc_id; | 199 | uint16_t pid; |
200 | /* PID to filter */ | 200 | /* stream type (MPE, PSI/SI or PES )*/ |
201 | uint16_t pid; | 201 | uint8_t stream_type; |
202 | /* stream type (MPE, PSI/SI or PES )*/ | 202 | /* PID index in filter table */ |
203 | uint8_t stream_type; | 203 | uint8_t idx; |
204 | /* PID index in filter table */ | 204 | } req; |
205 | uint8_t idx; | 205 | /* response */ |
206 | } req; | 206 | struct { |
207 | /* response */ | 207 | /* response identifier */ |
208 | struct { | 208 | uint16_t proc_id; |
209 | /* response identifier */ | 209 | /* response error */ |
210 | uint16_t proc_id; | 210 | uint8_t error; |
211 | /* response error */ | 211 | /* Filter id */ |
212 | uint8_t error; | 212 | uint8_t filter_id; |
213 | /* Filter id */ | 213 | } rsp; |
214 | uint8_t filter_id; | 214 | } __packed; |
215 | } rsp; | 215 | |
216 | } ADD_PID_FILTER; | 216 | union as10x_del_pid_filter { |
217 | 217 | /* request */ | |
218 | typedef union { | 218 | struct { |
219 | /* request */ | 219 | /* request identifier */ |
220 | struct { | 220 | uint16_t proc_id; |
221 | /* request identifier */ | 221 | /* PID to remove */ |
222 | uint16_t proc_id; | 222 | uint16_t pid; |
223 | /* PID to remove */ | 223 | } req; |
224 | uint16_t pid; | 224 | /* response */ |
225 | } req; | 225 | struct { |
226 | /* response */ | 226 | /* response identifier */ |
227 | struct { | 227 | uint16_t proc_id; |
228 | /* response identifier */ | 228 | /* response error */ |
229 | uint16_t proc_id; | 229 | uint8_t error; |
230 | /* response error */ | 230 | } rsp; |
231 | uint8_t error; | 231 | } __packed; |
232 | } rsp; | 232 | |
233 | } DEL_PID_FILTER; | 233 | union as10x_start_streaming { |
234 | 234 | /* request */ | |
235 | typedef union { | 235 | struct { |
236 | /* request */ | 236 | /* request identifier */ |
237 | struct { | 237 | uint16_t proc_id; |
238 | /* request identifier */ | 238 | } req; |
239 | uint16_t proc_id; | 239 | /* response */ |
240 | } req; | 240 | struct { |
241 | /* response */ | 241 | /* response identifier */ |
242 | struct { | 242 | uint16_t proc_id; |
243 | /* response identifier */ | 243 | /* error */ |
244 | uint16_t proc_id; | 244 | uint8_t error; |
245 | /* error */ | 245 | } rsp; |
246 | uint8_t error; | 246 | } __packed; |
247 | } rsp; | 247 | |
248 | } START_STREAMING; | 248 | union as10x_stop_streaming { |
249 | 249 | /* request */ | |
250 | typedef union { | 250 | struct { |
251 | /* request */ | 251 | /* request identifier */ |
252 | struct { | 252 | uint16_t proc_id; |
253 | /* request identifier */ | 253 | } req; |
254 | uint16_t proc_id; | 254 | /* response */ |
255 | } req; | 255 | struct { |
256 | /* response */ | 256 | /* response identifier */ |
257 | struct { | 257 | uint16_t proc_id; |
258 | /* response identifier */ | 258 | /* error */ |
259 | uint16_t proc_id; | 259 | uint8_t error; |
260 | /* error */ | 260 | } rsp; |
261 | uint8_t error; | 261 | } __packed; |
262 | } rsp; | 262 | |
263 | } STOP_STREAMING; | 263 | union as10x_get_demod_stats { |
264 | 264 | /* request */ | |
265 | typedef union { | 265 | struct { |
266 | /* request */ | 266 | /* request identifier */ |
267 | struct { | 267 | uint16_t proc_id; |
268 | /* request identifier */ | 268 | } req; |
269 | uint16_t proc_id; | 269 | /* response */ |
270 | } req; | 270 | struct { |
271 | /* response */ | 271 | /* response identifier */ |
272 | struct { | 272 | uint16_t proc_id; |
273 | /* response identifier */ | 273 | /* error */ |
274 | uint16_t proc_id; | 274 | uint8_t error; |
275 | /* error */ | 275 | /* demod stats */ |
276 | uint8_t error; | 276 | struct as10x_demod_stats stats; |
277 | /* demod stats */ | 277 | } rsp; |
278 | struct as10x_demod_stats stats; | 278 | } __packed; |
279 | } rsp; | 279 | |
280 | } GET_DEMOD_STATS; | 280 | union as10x_get_impulse_resp { |
281 | 281 | /* request */ | |
282 | typedef union { | 282 | struct { |
283 | /* request */ | 283 | /* request identifier */ |
284 | struct { | 284 | uint16_t proc_id; |
285 | /* request identifier */ | 285 | } req; |
286 | uint16_t proc_id; | 286 | /* response */ |
287 | } req; | 287 | struct { |
288 | /* response */ | 288 | /* response identifier */ |
289 | struct { | 289 | uint16_t proc_id; |
290 | /* response identifier */ | 290 | /* error */ |
291 | uint16_t proc_id; | 291 | uint8_t error; |
292 | /* error */ | 292 | /* impulse response ready */ |
293 | uint8_t error; | 293 | uint8_t is_ready; |
294 | /* impulse response ready */ | 294 | } rsp; |
295 | uint8_t is_ready; | 295 | } __packed; |
296 | } rsp; | 296 | |
297 | } GET_IMPULSE_RESP; | 297 | union as10x_fw_context { |
298 | 298 | /* request */ | |
299 | typedef union { | 299 | struct { |
300 | /* request */ | 300 | /* request identifier */ |
301 | struct { | 301 | uint16_t proc_id; |
302 | /* request identifier */ | 302 | /* value to write (for set context)*/ |
303 | uint16_t proc_id; | 303 | struct as10x_register_value reg_val; |
304 | /* value to write (for set context)*/ | 304 | /* context tag */ |
305 | struct as10x_register_value reg_val; | 305 | uint16_t tag; |
306 | /* context tag */ | 306 | /* context request type */ |
307 | uint16_t tag; | 307 | uint16_t type; |
308 | /* context request type */ | 308 | } req; |
309 | uint16_t type; | 309 | /* response */ |
310 | } req; | 310 | struct { |
311 | /* response */ | 311 | /* response identifier */ |
312 | struct { | 312 | uint16_t proc_id; |
313 | /* response identifier */ | 313 | /* value read (for get context) */ |
314 | uint16_t proc_id; | 314 | struct as10x_register_value reg_val; |
315 | /* value read (for get context) */ | 315 | /* context request type */ |
316 | struct as10x_register_value reg_val; | 316 | uint16_t type; |
317 | /* context request type */ | 317 | /* error */ |
318 | uint16_t type; | 318 | uint8_t error; |
319 | /* error */ | 319 | } rsp; |
320 | uint8_t error; | 320 | } __packed; |
321 | } rsp; | 321 | |
322 | } FW_CONTEXT; | 322 | union as10x_set_register { |
323 | 323 | /* request */ | |
324 | typedef union { | 324 | struct { |
325 | /* request */ | 325 | /* response identifier */ |
326 | struct { | 326 | uint16_t proc_id; |
327 | /* response identifier */ | 327 | /* register description */ |
328 | uint16_t proc_id; | 328 | struct as10x_register_addr reg_addr; |
329 | /* register description */ | 329 | /* register content */ |
330 | struct as10x_register_addr reg_addr; | 330 | struct as10x_register_value reg_val; |
331 | /* register content */ | 331 | } req; |
332 | struct as10x_register_value reg_val; | 332 | /* response */ |
333 | } req; | 333 | struct { |
334 | /* response */ | 334 | /* response identifier */ |
335 | struct { | 335 | uint16_t proc_id; |
336 | /* response identifier */ | 336 | /* error */ |
337 | uint16_t proc_id; | 337 | uint8_t error; |
338 | /* error */ | 338 | } rsp; |
339 | uint8_t error; | 339 | } __packed; |
340 | } rsp; | 340 | |
341 | } SET_REGISTER; | 341 | union as10x_get_register { |
342 | 342 | /* request */ | |
343 | typedef union { | 343 | struct { |
344 | /* request */ | 344 | /* response identifier */ |
345 | struct { | 345 | uint16_t proc_id; |
346 | /* response identifier */ | 346 | /* register description */ |
347 | uint16_t proc_id; | 347 | struct as10x_register_addr reg_addr; |
348 | /* register description */ | 348 | } req; |
349 | struct as10x_register_addr reg_addr; | 349 | /* response */ |
350 | } req; | 350 | struct { |
351 | /* response */ | 351 | /* response identifier */ |
352 | struct { | 352 | uint16_t proc_id; |
353 | /* response identifier */ | 353 | /* error */ |
354 | uint16_t proc_id; | 354 | uint8_t error; |
355 | /* error */ | 355 | /* register content */ |
356 | uint8_t error; | 356 | struct as10x_register_value reg_val; |
357 | /* register content */ | 357 | } rsp; |
358 | struct as10x_register_value reg_val; | 358 | } __packed; |
359 | } rsp; | 359 | |
360 | } GET_REGISTER; | 360 | union as10x_cfg_change_mode { |
361 | 361 | /* request */ | |
362 | typedef union { | 362 | struct { |
363 | /* request */ | 363 | /* request identifier */ |
364 | struct { | 364 | uint16_t proc_id; |
365 | /* request identifier */ | 365 | /* mode */ |
366 | uint16_t proc_id; | 366 | uint8_t mode; |
367 | /* mode */ | 367 | } req; |
368 | uint8_t mode; | 368 | /* response */ |
369 | } req; | 369 | struct { |
370 | /* response */ | 370 | /* response identifier */ |
371 | struct { | 371 | uint16_t proc_id; |
372 | /* response identifier */ | 372 | /* error */ |
373 | uint16_t proc_id; | 373 | uint8_t error; |
374 | /* error */ | 374 | } rsp; |
375 | uint8_t error; | 375 | } __packed; |
376 | } rsp; | ||
377 | } CFG_CHANGE_MODE; | ||
378 | 376 | ||
379 | struct as10x_cmd_header_t { | 377 | struct as10x_cmd_header_t { |
380 | uint16_t req_id; | 378 | uint16_t req_id; |
381 | uint16_t prog; | 379 | uint16_t prog; |
382 | uint16_t version; | 380 | uint16_t version; |
383 | uint16_t data_len; | 381 | uint16_t data_len; |
384 | }; | 382 | } __packed; |
385 | 383 | ||
386 | #define DUMP_BLOCK_SIZE 16 | 384 | #define DUMP_BLOCK_SIZE 16 |
387 | typedef union { | 385 | |
388 | /* request */ | 386 | union as10x_dump_memory { |
389 | struct { | 387 | /* request */ |
390 | /* request identifier */ | 388 | struct { |
391 | uint16_t proc_id; | 389 | /* request identifier */ |
392 | /* dump memory type request */ | 390 | uint16_t proc_id; |
393 | uint8_t dump_req; | 391 | /* dump memory type request */ |
394 | /* register description */ | 392 | uint8_t dump_req; |
395 | struct as10x_register_addr reg_addr; | 393 | /* register description */ |
396 | /* nb blocks to read */ | 394 | struct as10x_register_addr reg_addr; |
397 | uint16_t num_blocks; | 395 | /* nb blocks to read */ |
398 | } req; | 396 | uint16_t num_blocks; |
399 | /* response */ | 397 | } req; |
400 | struct { | 398 | /* response */ |
401 | /* response identifier */ | 399 | struct { |
402 | uint16_t proc_id; | 400 | /* response identifier */ |
403 | /* error */ | 401 | uint16_t proc_id; |
404 | uint8_t error; | 402 | /* error */ |
405 | /* dump response */ | 403 | uint8_t error; |
406 | uint8_t dump_rsp; | 404 | /* dump response */ |
407 | /* data */ | 405 | uint8_t dump_rsp; |
408 | union { | 406 | /* data */ |
409 | uint8_t data8[DUMP_BLOCK_SIZE]; | 407 | union { |
410 | uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)]; | 408 | uint8_t data8[DUMP_BLOCK_SIZE]; |
411 | uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; | 409 | uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)]; |
412 | } u; | 410 | uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; |
413 | } rsp; | 411 | } u; |
414 | } DUMP_MEMORY; | 412 | } rsp; |
415 | 413 | } __packed; | |
416 | typedef union { | 414 | |
417 | struct { | 415 | union as10x_dumplog_memory { |
418 | /* request identifier */ | 416 | struct { |
419 | uint16_t proc_id; | 417 | /* request identifier */ |
420 | /* dump memory type request */ | 418 | uint16_t proc_id; |
421 | uint8_t dump_req; | 419 | /* dump memory type request */ |
422 | } req; | 420 | uint8_t dump_req; |
423 | struct { | 421 | } req; |
424 | /* request identifier */ | 422 | struct { |
425 | uint16_t proc_id; | 423 | /* request identifier */ |
426 | /* error */ | 424 | uint16_t proc_id; |
427 | uint8_t error; | 425 | /* error */ |
428 | /* dump response */ | 426 | uint8_t error; |
429 | uint8_t dump_rsp; | 427 | /* dump response */ |
430 | /* dump data */ | 428 | uint8_t dump_rsp; |
431 | uint8_t data[DUMP_BLOCK_SIZE]; | 429 | /* dump data */ |
432 | } rsp; | 430 | uint8_t data[DUMP_BLOCK_SIZE]; |
433 | } DUMPLOG_MEMORY; | 431 | } rsp; |
434 | 432 | } __packed; | |
435 | typedef union { | 433 | |
436 | /* request */ | 434 | union as10x_raw_data { |
437 | struct { | 435 | /* request */ |
438 | uint16_t proc_id; | 436 | struct { |
439 | uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */]; | 437 | uint16_t proc_id; |
440 | } req; | 438 | uint8_t data[64 - sizeof(struct as10x_cmd_header_t) |
441 | /* response */ | 439 | - 2 /* proc_id */]; |
442 | struct { | 440 | } req; |
443 | uint16_t proc_id; | 441 | /* response */ |
444 | uint8_t error; | 442 | struct { |
445 | uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */ | 443 | uint16_t proc_id; |
446 | - 2 /* proc_id */ - 1 /* rc */]; | 444 | uint8_t error; |
447 | } rsp; | 445 | uint8_t data[64 - sizeof(struct as10x_cmd_header_t) |
448 | } RAW_DATA; | 446 | - 2 /* proc_id */ - 1 /* rc */]; |
447 | } rsp; | ||
448 | } __packed; | ||
449 | 449 | ||
450 | struct as10x_cmd_t { | 450 | struct as10x_cmd_t { |
451 | /* header */ | 451 | struct as10x_cmd_header_t header; |
452 | struct as10x_cmd_header_t header; | 452 | union { |
453 | /* body */ | 453 | union as10x_turn_on turn_on; |
454 | union { | 454 | union as10x_turn_off turn_off; |
455 | TURN_ON turn_on; | 455 | union as10x_set_tune set_tune; |
456 | TURN_OFF turn_off; | 456 | union as10x_get_tune_status get_tune_status; |
457 | SET_TUNE set_tune; | 457 | union as10x_get_tps get_tps; |
458 | GET_TUNE_STATUS get_tune_status; | 458 | union as10x_common common; |
459 | GET_TPS get_tps; | 459 | union as10x_add_pid_filter add_pid_filter; |
460 | COMMON common; | 460 | union as10x_del_pid_filter del_pid_filter; |
461 | ADD_PID_FILTER add_pid_filter; | 461 | union as10x_start_streaming start_streaming; |
462 | DEL_PID_FILTER del_pid_filter; | 462 | union as10x_stop_streaming stop_streaming; |
463 | START_STREAMING start_streaming; | 463 | union as10x_get_demod_stats get_demod_stats; |
464 | STOP_STREAMING stop_streaming; | 464 | union as10x_get_impulse_resp get_impulse_rsp; |
465 | GET_DEMOD_STATS get_demod_stats; | 465 | union as10x_fw_context context; |
466 | GET_IMPULSE_RESP get_impulse_rsp; | 466 | union as10x_set_register set_register; |
467 | FW_CONTEXT context; | 467 | union as10x_get_register get_register; |
468 | SET_REGISTER set_register; | 468 | union as10x_cfg_change_mode cfg_change_mode; |
469 | GET_REGISTER get_register; | 469 | union as10x_dump_memory dump_memory; |
470 | CFG_CHANGE_MODE cfg_change_mode; | 470 | union as10x_dumplog_memory dumplog_memory; |
471 | DUMP_MEMORY dump_memory; | 471 | union as10x_raw_data raw_data; |
472 | DUMPLOG_MEMORY dumplog_memory; | 472 | } body; |
473 | RAW_DATA raw_data; | 473 | } __packed; |
474 | } body; | ||
475 | }; | ||
476 | 474 | ||
477 | struct as10x_token_cmd_t { | 475 | struct as10x_token_cmd_t { |
478 | /* token cmd */ | 476 | /* token cmd */ |
479 | struct as10x_cmd_t c; | 477 | struct as10x_cmd_t c; |
480 | /* token response */ | 478 | /* token response */ |
481 | struct as10x_cmd_t r; | 479 | struct as10x_cmd_t r; |
482 | }; | 480 | } __packed; |
483 | #pragma pack() | ||
484 | 481 | ||
485 | 482 | ||
486 | /**************************/ | 483 | /**************************/ |
@@ -491,50 +488,42 @@ void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id, | |||
491 | uint16_t cmd_len); | 488 | uint16_t cmd_len); |
492 | int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id); | 489 | int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id); |
493 | 490 | ||
494 | #ifdef __cplusplus | ||
495 | extern "C" { | ||
496 | #endif | ||
497 | |||
498 | /* as10x cmd */ | 491 | /* as10x cmd */ |
499 | int as10x_cmd_turn_on(as10x_handle_t *phandle); | 492 | int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap); |
500 | int as10x_cmd_turn_off(as10x_handle_t *phandle); | 493 | int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap); |
501 | 494 | ||
502 | int as10x_cmd_set_tune(as10x_handle_t *phandle, | 495 | int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap, |
503 | struct as10x_tune_args *ptune); | 496 | struct as10x_tune_args *ptune); |
504 | 497 | ||
505 | int as10x_cmd_get_tune_status(as10x_handle_t *phandle, | 498 | int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap, |
506 | struct as10x_tune_status *pstatus); | 499 | struct as10x_tune_status *pstatus); |
507 | 500 | ||
508 | int as10x_cmd_get_tps(as10x_handle_t *phandle, | 501 | int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, |
509 | struct as10x_tps *ptps); | 502 | struct as10x_tps *ptps); |
510 | 503 | ||
511 | int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, | 504 | int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap, |
512 | struct as10x_demod_stats *pdemod_stats); | 505 | struct as10x_demod_stats *pdemod_stats); |
513 | 506 | ||
514 | int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, | 507 | int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap, |
515 | uint8_t *is_ready); | 508 | uint8_t *is_ready); |
516 | 509 | ||
517 | /* as10x cmd stream */ | 510 | /* as10x cmd stream */ |
518 | int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, | 511 | int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap, |
519 | struct as10x_ts_filter *filter); | 512 | struct as10x_ts_filter *filter); |
520 | int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, | 513 | int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap, |
521 | uint16_t pid_value); | 514 | uint16_t pid_value); |
522 | 515 | ||
523 | int as10x_cmd_start_streaming(as10x_handle_t *phandle); | 516 | int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap); |
524 | int as10x_cmd_stop_streaming(as10x_handle_t *phandle); | 517 | int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap); |
525 | 518 | ||
526 | /* as10x cmd cfg */ | 519 | /* as10x cmd cfg */ |
527 | int as10x_cmd_set_context(as10x_handle_t *phandle, | 520 | int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, |
528 | uint16_t tag, | 521 | uint16_t tag, |
529 | uint32_t value); | 522 | uint32_t value); |
530 | int as10x_cmd_get_context(as10x_handle_t *phandle, | 523 | int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, |
531 | uint16_t tag, | 524 | uint16_t tag, |
532 | uint32_t *pvalue); | 525 | uint32_t *pvalue); |
533 | 526 | ||
534 | int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode); | 527 | int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode); |
535 | int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id); | 528 | int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id); |
536 | #ifdef __cplusplus | ||
537 | } | ||
538 | #endif | ||
539 | #endif | 529 | #endif |
540 | /* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */ | ||
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c index ec6f69fcf399..d2a4bce89623 100644 --- a/drivers/staging/media/as102/as10x_cmd_cfg.c +++ b/drivers/staging/media/as102/as10x_cmd_cfg.c | |||
@@ -28,13 +28,13 @@ | |||
28 | 28 | ||
29 | /** | 29 | /** |
30 | * as10x_cmd_get_context - Send get context command to AS10x | 30 | * as10x_cmd_get_context - Send get context command to AS10x |
31 | * @phandle: pointer to AS10x handle | 31 | * @adap: pointer to AS10x bus adapter |
32 | * @tag: context tag | 32 | * @tag: context tag |
33 | * @pvalue: pointer where to store context value read | 33 | * @pvalue: pointer where to store context value read |
34 | * | 34 | * |
35 | * Return 0 on success or negative value in case of error. | 35 | * Return 0 on success or negative value in case of error. |
36 | */ | 36 | */ |
37 | int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag, | 37 | int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag, |
38 | uint32_t *pvalue) | 38 | uint32_t *pvalue) |
39 | { | 39 | { |
40 | int error; | 40 | int error; |
@@ -42,11 +42,11 @@ int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag, | |||
42 | 42 | ||
43 | ENTER(); | 43 | ENTER(); |
44 | 44 | ||
45 | pcmd = phandle->cmd; | 45 | pcmd = adap->cmd; |
46 | prsp = phandle->rsp; | 46 | prsp = adap->rsp; |
47 | 47 | ||
48 | /* prepare command */ | 48 | /* prepare command */ |
49 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 49 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
50 | sizeof(pcmd->body.context.req)); | 50 | sizeof(pcmd->body.context.req)); |
51 | 51 | ||
52 | /* fill command */ | 52 | /* fill command */ |
@@ -55,14 +55,14 @@ int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag, | |||
55 | pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA); | 55 | pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA); |
56 | 56 | ||
57 | /* send command */ | 57 | /* send command */ |
58 | if (phandle->ops->xfer_cmd) { | 58 | if (adap->ops->xfer_cmd) { |
59 | error = phandle->ops->xfer_cmd(phandle, | 59 | error = adap->ops->xfer_cmd(adap, |
60 | (uint8_t *) pcmd, | 60 | (uint8_t *) pcmd, |
61 | sizeof(pcmd->body.context.req) | 61 | sizeof(pcmd->body.context.req) |
62 | + HEADER_SIZE, | 62 | + HEADER_SIZE, |
63 | (uint8_t *) prsp, | 63 | (uint8_t *) prsp, |
64 | sizeof(prsp->body.context.rsp) | 64 | sizeof(prsp->body.context.rsp) |
65 | + HEADER_SIZE); | 65 | + HEADER_SIZE); |
66 | } else { | 66 | } else { |
67 | error = AS10X_CMD_ERROR; | 67 | error = AS10X_CMD_ERROR; |
68 | } | 68 | } |
@@ -87,13 +87,13 @@ out: | |||
87 | 87 | ||
88 | /** | 88 | /** |
89 | * as10x_cmd_set_context - send set context command to AS10x | 89 | * as10x_cmd_set_context - send set context command to AS10x |
90 | * @phandle: pointer to AS10x handle | 90 | * @adap: pointer to AS10x bus adapter |
91 | * @tag: context tag | 91 | * @tag: context tag |
92 | * @value: value to set in context | 92 | * @value: value to set in context |
93 | * | 93 | * |
94 | * Return 0 on success or negative value in case of error. | 94 | * Return 0 on success or negative value in case of error. |
95 | */ | 95 | */ |
96 | int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag, | 96 | int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag, |
97 | uint32_t value) | 97 | uint32_t value) |
98 | { | 98 | { |
99 | int error; | 99 | int error; |
@@ -101,11 +101,11 @@ int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag, | |||
101 | 101 | ||
102 | ENTER(); | 102 | ENTER(); |
103 | 103 | ||
104 | pcmd = phandle->cmd; | 104 | pcmd = adap->cmd; |
105 | prsp = phandle->rsp; | 105 | prsp = adap->rsp; |
106 | 106 | ||
107 | /* prepare command */ | 107 | /* prepare command */ |
108 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 108 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
109 | sizeof(pcmd->body.context.req)); | 109 | sizeof(pcmd->body.context.req)); |
110 | 110 | ||
111 | /* fill command */ | 111 | /* fill command */ |
@@ -116,14 +116,14 @@ int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag, | |||
116 | pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA); | 116 | pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA); |
117 | 117 | ||
118 | /* send command */ | 118 | /* send command */ |
119 | if (phandle->ops->xfer_cmd) { | 119 | if (adap->ops->xfer_cmd) { |
120 | error = phandle->ops->xfer_cmd(phandle, | 120 | error = adap->ops->xfer_cmd(adap, |
121 | (uint8_t *) pcmd, | 121 | (uint8_t *) pcmd, |
122 | sizeof(pcmd->body.context.req) | 122 | sizeof(pcmd->body.context.req) |
123 | + HEADER_SIZE, | 123 | + HEADER_SIZE, |
124 | (uint8_t *) prsp, | 124 | (uint8_t *) prsp, |
125 | sizeof(prsp->body.context.rsp) | 125 | sizeof(prsp->body.context.rsp) |
126 | + HEADER_SIZE); | 126 | + HEADER_SIZE); |
127 | } else { | 127 | } else { |
128 | error = AS10X_CMD_ERROR; | 128 | error = AS10X_CMD_ERROR; |
129 | } | 129 | } |
@@ -142,7 +142,7 @@ out: | |||
142 | 142 | ||
143 | /** | 143 | /** |
144 | * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x | 144 | * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x |
145 | * @phandle: pointer to AS10x handle | 145 | * @adap: pointer to AS10x bus adapter |
146 | * @mode: mode selected: | 146 | * @mode: mode selected: |
147 | * - ON : 0x0 => eLNA always ON | 147 | * - ON : 0x0 => eLNA always ON |
148 | * - OFF : 0x1 => eLNA always OFF | 148 | * - OFF : 0x1 => eLNA always OFF |
@@ -151,18 +151,18 @@ out: | |||
151 | * | 151 | * |
152 | * Return 0 on success or negative value in case of error. | 152 | * Return 0 on success or negative value in case of error. |
153 | */ | 153 | */ |
154 | int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode) | 154 | int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode) |
155 | { | 155 | { |
156 | int error; | 156 | int error; |
157 | struct as10x_cmd_t *pcmd, *prsp; | 157 | struct as10x_cmd_t *pcmd, *prsp; |
158 | 158 | ||
159 | ENTER(); | 159 | ENTER(); |
160 | 160 | ||
161 | pcmd = phandle->cmd; | 161 | pcmd = adap->cmd; |
162 | prsp = phandle->rsp; | 162 | prsp = adap->rsp; |
163 | 163 | ||
164 | /* prepare command */ | 164 | /* prepare command */ |
165 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 165 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
166 | sizeof(pcmd->body.cfg_change_mode.req)); | 166 | sizeof(pcmd->body.cfg_change_mode.req)); |
167 | 167 | ||
168 | /* fill command */ | 168 | /* fill command */ |
@@ -171,8 +171,8 @@ int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode) | |||
171 | pcmd->body.cfg_change_mode.req.mode = mode; | 171 | pcmd->body.cfg_change_mode.req.mode = mode; |
172 | 172 | ||
173 | /* send command */ | 173 | /* send command */ |
174 | if (phandle->ops->xfer_cmd) { | 174 | if (adap->ops->xfer_cmd) { |
175 | error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, | 175 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
176 | sizeof(pcmd->body.cfg_change_mode.req) | 176 | sizeof(pcmd->body.cfg_change_mode.req) |
177 | + HEADER_SIZE, (uint8_t *) prsp, | 177 | + HEADER_SIZE, (uint8_t *) prsp, |
178 | sizeof(prsp->body.cfg_change_mode.rsp) | 178 | sizeof(prsp->body.cfg_change_mode.rsp) |
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c index 045c70683193..6d000f60fb0e 100644 --- a/drivers/staging/media/as102/as10x_cmd_stream.c +++ b/drivers/staging/media/as102/as10x_cmd_stream.c | |||
@@ -23,12 +23,12 @@ | |||
23 | 23 | ||
24 | /** | 24 | /** |
25 | * as10x_cmd_add_PID_filter - send add filter command to AS10x | 25 | * as10x_cmd_add_PID_filter - send add filter command to AS10x |
26 | * @phandle: pointer to AS10x handle | 26 | * @adap: pointer to AS10x bus adapter |
27 | * @filter: TSFilter filter for DVB-T | 27 | * @filter: TSFilter filter for DVB-T |
28 | * | 28 | * |
29 | * Return 0 on success or negative value in case of error. | 29 | * Return 0 on success or negative value in case of error. |
30 | */ | 30 | */ |
31 | int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, | 31 | int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap, |
32 | struct as10x_ts_filter *filter) | 32 | struct as10x_ts_filter *filter) |
33 | { | 33 | { |
34 | int error; | 34 | int error; |
@@ -36,11 +36,11 @@ int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, | |||
36 | 36 | ||
37 | ENTER(); | 37 | ENTER(); |
38 | 38 | ||
39 | pcmd = phandle->cmd; | 39 | pcmd = adap->cmd; |
40 | prsp = phandle->rsp; | 40 | prsp = adap->rsp; |
41 | 41 | ||
42 | /* prepare command */ | 42 | /* prepare command */ |
43 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 43 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
44 | sizeof(pcmd->body.add_pid_filter.req)); | 44 | sizeof(pcmd->body.add_pid_filter.req)); |
45 | 45 | ||
46 | /* fill command */ | 46 | /* fill command */ |
@@ -55,8 +55,8 @@ int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, | |||
55 | pcmd->body.add_pid_filter.req.idx = 0xFF; | 55 | pcmd->body.add_pid_filter.req.idx = 0xFF; |
56 | 56 | ||
57 | /* send command */ | 57 | /* send command */ |
58 | if (phandle->ops->xfer_cmd) { | 58 | if (adap->ops->xfer_cmd) { |
59 | error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, | 59 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
60 | sizeof(pcmd->body.add_pid_filter.req) | 60 | sizeof(pcmd->body.add_pid_filter.req) |
61 | + HEADER_SIZE, (uint8_t *) prsp, | 61 | + HEADER_SIZE, (uint8_t *) prsp, |
62 | sizeof(prsp->body.add_pid_filter.rsp) | 62 | sizeof(prsp->body.add_pid_filter.rsp) |
@@ -83,12 +83,12 @@ out: | |||
83 | 83 | ||
84 | /** | 84 | /** |
85 | * as10x_cmd_del_PID_filter - Send delete filter command to AS10x | 85 | * as10x_cmd_del_PID_filter - Send delete filter command to AS10x |
86 | * @phandle: pointer to AS10x handle | 86 | * @adap: pointer to AS10x bus adapte |
87 | * @pid_value: PID to delete | 87 | * @pid_value: PID to delete |
88 | * | 88 | * |
89 | * Return 0 on success or negative value in case of error. | 89 | * Return 0 on success or negative value in case of error. |
90 | */ | 90 | */ |
91 | int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, | 91 | int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap, |
92 | uint16_t pid_value) | 92 | uint16_t pid_value) |
93 | { | 93 | { |
94 | int error; | 94 | int error; |
@@ -96,11 +96,11 @@ int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, | |||
96 | 96 | ||
97 | ENTER(); | 97 | ENTER(); |
98 | 98 | ||
99 | pcmd = phandle->cmd; | 99 | pcmd = adap->cmd; |
100 | prsp = phandle->rsp; | 100 | prsp = adap->rsp; |
101 | 101 | ||
102 | /* prepare command */ | 102 | /* prepare command */ |
103 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 103 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
104 | sizeof(pcmd->body.del_pid_filter.req)); | 104 | sizeof(pcmd->body.del_pid_filter.req)); |
105 | 105 | ||
106 | /* fill command */ | 106 | /* fill command */ |
@@ -109,8 +109,8 @@ int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, | |||
109 | pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value); | 109 | pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value); |
110 | 110 | ||
111 | /* send command */ | 111 | /* send command */ |
112 | if (phandle->ops->xfer_cmd) { | 112 | if (adap->ops->xfer_cmd) { |
113 | error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, | 113 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
114 | sizeof(pcmd->body.del_pid_filter.req) | 114 | sizeof(pcmd->body.del_pid_filter.req) |
115 | + HEADER_SIZE, (uint8_t *) prsp, | 115 | + HEADER_SIZE, (uint8_t *) prsp, |
116 | sizeof(prsp->body.del_pid_filter.rsp) | 116 | sizeof(prsp->body.del_pid_filter.rsp) |
@@ -132,22 +132,22 @@ out: | |||
132 | 132 | ||
133 | /** | 133 | /** |
134 | * as10x_cmd_start_streaming - Send start streaming command to AS10x | 134 | * as10x_cmd_start_streaming - Send start streaming command to AS10x |
135 | * @phandle: pointer to AS10x handle | 135 | * @adap: pointer to AS10x bus adapter |
136 | * | 136 | * |
137 | * Return 0 on success or negative value in case of error. | 137 | * Return 0 on success or negative value in case of error. |
138 | */ | 138 | */ |
139 | int as10x_cmd_start_streaming(as10x_handle_t *phandle) | 139 | int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap) |
140 | { | 140 | { |
141 | int error; | 141 | int error; |
142 | struct as10x_cmd_t *pcmd, *prsp; | 142 | struct as10x_cmd_t *pcmd, *prsp; |
143 | 143 | ||
144 | ENTER(); | 144 | ENTER(); |
145 | 145 | ||
146 | pcmd = phandle->cmd; | 146 | pcmd = adap->cmd; |
147 | prsp = phandle->rsp; | 147 | prsp = adap->rsp; |
148 | 148 | ||
149 | /* prepare command */ | 149 | /* prepare command */ |
150 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 150 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
151 | sizeof(pcmd->body.start_streaming.req)); | 151 | sizeof(pcmd->body.start_streaming.req)); |
152 | 152 | ||
153 | /* fill command */ | 153 | /* fill command */ |
@@ -155,8 +155,8 @@ int as10x_cmd_start_streaming(as10x_handle_t *phandle) | |||
155 | cpu_to_le16(CONTROL_PROC_START_STREAMING); | 155 | cpu_to_le16(CONTROL_PROC_START_STREAMING); |
156 | 156 | ||
157 | /* send command */ | 157 | /* send command */ |
158 | if (phandle->ops->xfer_cmd) { | 158 | if (adap->ops->xfer_cmd) { |
159 | error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, | 159 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
160 | sizeof(pcmd->body.start_streaming.req) | 160 | sizeof(pcmd->body.start_streaming.req) |
161 | + HEADER_SIZE, (uint8_t *) prsp, | 161 | + HEADER_SIZE, (uint8_t *) prsp, |
162 | sizeof(prsp->body.start_streaming.rsp) | 162 | sizeof(prsp->body.start_streaming.rsp) |
@@ -178,22 +178,22 @@ out: | |||
178 | 178 | ||
179 | /** | 179 | /** |
180 | * as10x_cmd_stop_streaming - Send stop streaming command to AS10x | 180 | * as10x_cmd_stop_streaming - Send stop streaming command to AS10x |
181 | * @phandle: pointer to AS10x handle | 181 | * @adap: pointer to AS10x bus adapter |
182 | * | 182 | * |
183 | * Return 0 on success or negative value in case of error. | 183 | * Return 0 on success or negative value in case of error. |
184 | */ | 184 | */ |
185 | int as10x_cmd_stop_streaming(as10x_handle_t *phandle) | 185 | int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap) |
186 | { | 186 | { |
187 | int8_t error; | 187 | int8_t error; |
188 | struct as10x_cmd_t *pcmd, *prsp; | 188 | struct as10x_cmd_t *pcmd, *prsp; |
189 | 189 | ||
190 | ENTER(); | 190 | ENTER(); |
191 | 191 | ||
192 | pcmd = phandle->cmd; | 192 | pcmd = adap->cmd; |
193 | prsp = phandle->rsp; | 193 | prsp = adap->rsp; |
194 | 194 | ||
195 | /* prepare command */ | 195 | /* prepare command */ |
196 | as10x_cmd_build(pcmd, (++phandle->cmd_xid), | 196 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
197 | sizeof(pcmd->body.stop_streaming.req)); | 197 | sizeof(pcmd->body.stop_streaming.req)); |
198 | 198 | ||
199 | /* fill command */ | 199 | /* fill command */ |
@@ -201,8 +201,8 @@ int as10x_cmd_stop_streaming(as10x_handle_t *phandle) | |||
201 | cpu_to_le16(CONTROL_PROC_STOP_STREAMING); | 201 | cpu_to_le16(CONTROL_PROC_STOP_STREAMING); |
202 | 202 | ||
203 | /* send command */ | 203 | /* send command */ |
204 | if (phandle->ops->xfer_cmd) { | 204 | if (adap->ops->xfer_cmd) { |
205 | error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, | 205 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
206 | sizeof(pcmd->body.stop_streaming.req) | 206 | sizeof(pcmd->body.stop_streaming.req) |
207 | + HEADER_SIZE, (uint8_t *) prsp, | 207 | + HEADER_SIZE, (uint8_t *) prsp, |
208 | sizeof(prsp->body.stop_streaming.rsp) | 208 | sizeof(prsp->body.stop_streaming.rsp) |
diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h index 4f01a76e9829..62b9795ee424 100644 --- a/drivers/staging/media/as102/as10x_handle.h +++ b/drivers/staging/media/as102/as10x_handle.h | |||
@@ -17,41 +17,37 @@ | |||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 | */ | 18 | */ |
19 | #ifdef __KERNEL__ | 19 | #ifdef __KERNEL__ |
20 | struct as102_bus_adapter_t; | 20 | struct as10x_bus_adapter_t; |
21 | struct as102_dev_t; | 21 | struct as102_dev_t; |
22 | 22 | ||
23 | #define as10x_handle_t struct as102_bus_adapter_t | ||
24 | #include "as10x_cmd.h" | 23 | #include "as10x_cmd.h" |
25 | 24 | ||
26 | /* values for "mode" field */ | 25 | /* values for "mode" field */ |
27 | #define REGMODE8 8 | 26 | #define REGMODE8 8 |
28 | #define REGMODE16 16 | 27 | #define REGMODE16 16 |
29 | #define REGMODE32 32 | 28 | #define REGMODE32 32 |
30 | 29 | ||
31 | struct as102_priv_ops_t { | 30 | struct as102_priv_ops_t { |
32 | int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap, | 31 | int (*upload_fw_pkt) (struct as10x_bus_adapter_t *bus_adap, |
33 | unsigned char *buf, int buflen, int swap32); | 32 | unsigned char *buf, int buflen, int swap32); |
34 | 33 | ||
35 | int (*send_cmd) (struct as102_bus_adapter_t *bus_adap, | 34 | int (*send_cmd) (struct as10x_bus_adapter_t *bus_adap, |
36 | unsigned char *buf, int buflen); | 35 | unsigned char *buf, int buflen); |
37 | 36 | ||
38 | int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap, | 37 | int (*xfer_cmd) (struct as10x_bus_adapter_t *bus_adap, |
39 | unsigned char *send_buf, int send_buf_len, | 38 | unsigned char *send_buf, int send_buf_len, |
40 | unsigned char *recv_buf, int recv_buf_len); | 39 | unsigned char *recv_buf, int recv_buf_len); |
41 | /* | 40 | |
42 | int (*pid_filter) (struct as102_bus_adapter_t *bus_adap, | ||
43 | int index, u16 pid, int onoff); | ||
44 | */ | ||
45 | int (*start_stream) (struct as102_dev_t *dev); | 41 | int (*start_stream) (struct as102_dev_t *dev); |
46 | void (*stop_stream) (struct as102_dev_t *dev); | 42 | void (*stop_stream) (struct as102_dev_t *dev); |
47 | 43 | ||
48 | int (*reset_target) (struct as102_bus_adapter_t *bus_adap); | 44 | int (*reset_target) (struct as10x_bus_adapter_t *bus_adap); |
49 | 45 | ||
50 | int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode, | 46 | int (*read_write)(struct as10x_bus_adapter_t *bus_adap, uint8_t mode, |
51 | uint32_t rd_addr, uint16_t rd_len, | 47 | uint32_t rd_addr, uint16_t rd_len, |
52 | uint32_t wr_addr, uint16_t wr_len); | 48 | uint32_t wr_addr, uint16_t wr_len); |
53 | 49 | ||
54 | int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap, | 50 | int (*as102_read_ep2) (struct as10x_bus_adapter_t *bus_adap, |
55 | unsigned char *recv_buf, | 51 | unsigned char *recv_buf, |
56 | int recv_buf_len); | 52 | int recv_buf_len); |
57 | }; | 53 | }; |
diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h index 3dedb3c1420a..c40c8128cb76 100644 --- a/drivers/staging/media/as102/as10x_types.h +++ b/drivers/staging/media/as102/as10x_types.h | |||
@@ -26,173 +26,169 @@ | |||
26 | /*********************************/ | 26 | /*********************************/ |
27 | 27 | ||
28 | /* bandwidth constant values */ | 28 | /* bandwidth constant values */ |
29 | #define BW_5_MHZ 0x00 | 29 | #define BW_5_MHZ 0x00 |
30 | #define BW_6_MHZ 0x01 | 30 | #define BW_6_MHZ 0x01 |
31 | #define BW_7_MHZ 0x02 | 31 | #define BW_7_MHZ 0x02 |
32 | #define BW_8_MHZ 0x03 | 32 | #define BW_8_MHZ 0x03 |
33 | 33 | ||
34 | /* hierarchy priority selection values */ | 34 | /* hierarchy priority selection values */ |
35 | #define HIER_NO_PRIORITY 0x00 | 35 | #define HIER_NO_PRIORITY 0x00 |
36 | #define HIER_LOW_PRIORITY 0x01 | 36 | #define HIER_LOW_PRIORITY 0x01 |
37 | #define HIER_HIGH_PRIORITY 0x02 | 37 | #define HIER_HIGH_PRIORITY 0x02 |
38 | 38 | ||
39 | /* constellation available values */ | 39 | /* constellation available values */ |
40 | #define CONST_QPSK 0x00 | 40 | #define CONST_QPSK 0x00 |
41 | #define CONST_QAM16 0x01 | 41 | #define CONST_QAM16 0x01 |
42 | #define CONST_QAM64 0x02 | 42 | #define CONST_QAM64 0x02 |
43 | #define CONST_UNKNOWN 0xFF | 43 | #define CONST_UNKNOWN 0xFF |
44 | 44 | ||
45 | /* hierarchy available values */ | 45 | /* hierarchy available values */ |
46 | #define HIER_NONE 0x00 | 46 | #define HIER_NONE 0x00 |
47 | #define HIER_ALPHA_1 0x01 | 47 | #define HIER_ALPHA_1 0x01 |
48 | #define HIER_ALPHA_2 0x02 | 48 | #define HIER_ALPHA_2 0x02 |
49 | #define HIER_ALPHA_4 0x03 | 49 | #define HIER_ALPHA_4 0x03 |
50 | #define HIER_UNKNOWN 0xFF | 50 | #define HIER_UNKNOWN 0xFF |
51 | 51 | ||
52 | /* interleaving available values */ | 52 | /* interleaving available values */ |
53 | #define INTLV_NATIVE 0x00 | 53 | #define INTLV_NATIVE 0x00 |
54 | #define INTLV_IN_DEPTH 0x01 | 54 | #define INTLV_IN_DEPTH 0x01 |
55 | #define INTLV_UNKNOWN 0xFF | 55 | #define INTLV_UNKNOWN 0xFF |
56 | 56 | ||
57 | /* code rate available values */ | 57 | /* code rate available values */ |
58 | #define CODE_RATE_1_2 0x00 | 58 | #define CODE_RATE_1_2 0x00 |
59 | #define CODE_RATE_2_3 0x01 | 59 | #define CODE_RATE_2_3 0x01 |
60 | #define CODE_RATE_3_4 0x02 | 60 | #define CODE_RATE_3_4 0x02 |
61 | #define CODE_RATE_5_6 0x03 | 61 | #define CODE_RATE_5_6 0x03 |
62 | #define CODE_RATE_7_8 0x04 | 62 | #define CODE_RATE_7_8 0x04 |
63 | #define CODE_RATE_UNKNOWN 0xFF | 63 | #define CODE_RATE_UNKNOWN 0xFF |
64 | 64 | ||
65 | /* guard interval available values */ | 65 | /* guard interval available values */ |
66 | #define GUARD_INT_1_32 0x00 | 66 | #define GUARD_INT_1_32 0x00 |
67 | #define GUARD_INT_1_16 0x01 | 67 | #define GUARD_INT_1_16 0x01 |
68 | #define GUARD_INT_1_8 0x02 | 68 | #define GUARD_INT_1_8 0x02 |
69 | #define GUARD_INT_1_4 0x03 | 69 | #define GUARD_INT_1_4 0x03 |
70 | #define GUARD_UNKNOWN 0xFF | 70 | #define GUARD_UNKNOWN 0xFF |
71 | 71 | ||
72 | /* transmission mode available values */ | 72 | /* transmission mode available values */ |
73 | #define TRANS_MODE_2K 0x00 | 73 | #define TRANS_MODE_2K 0x00 |
74 | #define TRANS_MODE_8K 0x01 | 74 | #define TRANS_MODE_8K 0x01 |
75 | #define TRANS_MODE_4K 0x02 | 75 | #define TRANS_MODE_4K 0x02 |
76 | #define TRANS_MODE_UNKNOWN 0xFF | 76 | #define TRANS_MODE_UNKNOWN 0xFF |
77 | 77 | ||
78 | /* DVBH signalling available values */ | 78 | /* DVBH signalling available values */ |
79 | #define TIMESLICING_PRESENT 0x01 | 79 | #define TIMESLICING_PRESENT 0x01 |
80 | #define MPE_FEC_PRESENT 0x02 | 80 | #define MPE_FEC_PRESENT 0x02 |
81 | 81 | ||
82 | /* tune state available */ | 82 | /* tune state available */ |
83 | #define TUNE_STATUS_NOT_TUNED 0x00 | 83 | #define TUNE_STATUS_NOT_TUNED 0x00 |
84 | #define TUNE_STATUS_IDLE 0x01 | 84 | #define TUNE_STATUS_IDLE 0x01 |
85 | #define TUNE_STATUS_LOCKING 0x02 | 85 | #define TUNE_STATUS_LOCKING 0x02 |
86 | #define TUNE_STATUS_SIGNAL_DVB_OK 0x03 | 86 | #define TUNE_STATUS_SIGNAL_DVB_OK 0x03 |
87 | #define TUNE_STATUS_STREAM_DETECTED 0x04 | 87 | #define TUNE_STATUS_STREAM_DETECTED 0x04 |
88 | #define TUNE_STATUS_STREAM_TUNED 0x05 | 88 | #define TUNE_STATUS_STREAM_TUNED 0x05 |
89 | #define TUNE_STATUS_ERROR 0xFF | 89 | #define TUNE_STATUS_ERROR 0xFF |
90 | 90 | ||
91 | /* available TS FID filter types */ | 91 | /* available TS FID filter types */ |
92 | #define TS_PID_TYPE_TS 0 | 92 | #define TS_PID_TYPE_TS 0 |
93 | #define TS_PID_TYPE_PSI_SI 1 | 93 | #define TS_PID_TYPE_PSI_SI 1 |
94 | #define TS_PID_TYPE_MPE 2 | 94 | #define TS_PID_TYPE_MPE 2 |
95 | 95 | ||
96 | /* number of echos available */ | 96 | /* number of echos available */ |
97 | #define MAX_ECHOS 15 | 97 | #define MAX_ECHOS 15 |
98 | 98 | ||
99 | /* Context types */ | 99 | /* Context types */ |
100 | #define CONTEXT_LNA 1010 | 100 | #define CONTEXT_LNA 1010 |
101 | #define CONTEXT_ELNA_HYSTERESIS 4003 | 101 | #define CONTEXT_ELNA_HYSTERESIS 4003 |
102 | #define CONTEXT_ELNA_GAIN 4004 | 102 | #define CONTEXT_ELNA_GAIN 4004 |
103 | #define CONTEXT_MER_THRESHOLD 5005 | 103 | #define CONTEXT_MER_THRESHOLD 5005 |
104 | #define CONTEXT_MER_OFFSET 5006 | 104 | #define CONTEXT_MER_OFFSET 5006 |
105 | #define CONTEXT_IR_STATE 7000 | 105 | #define CONTEXT_IR_STATE 7000 |
106 | #define CONTEXT_TSOUT_MSB_FIRST 7004 | 106 | #define CONTEXT_TSOUT_MSB_FIRST 7004 |
107 | #define CONTEXT_TSOUT_FALLING_EDGE 7005 | 107 | #define CONTEXT_TSOUT_FALLING_EDGE 7005 |
108 | 108 | ||
109 | /* Configuration modes */ | 109 | /* Configuration modes */ |
110 | #define CFG_MODE_ON 0 | 110 | #define CFG_MODE_ON 0 |
111 | #define CFG_MODE_OFF 1 | 111 | #define CFG_MODE_OFF 1 |
112 | #define CFG_MODE_AUTO 2 | 112 | #define CFG_MODE_AUTO 2 |
113 | 113 | ||
114 | #pragma pack(1) | ||
115 | struct as10x_tps { | 114 | struct as10x_tps { |
116 | uint8_t constellation; | 115 | uint8_t constellation; |
117 | uint8_t hierarchy; | 116 | uint8_t hierarchy; |
118 | uint8_t interleaving_mode; | 117 | uint8_t interleaving_mode; |
119 | uint8_t code_rate_HP; | 118 | uint8_t code_rate_HP; |
120 | uint8_t code_rate_LP; | 119 | uint8_t code_rate_LP; |
121 | uint8_t guard_interval; | 120 | uint8_t guard_interval; |
122 | uint8_t transmission_mode; | 121 | uint8_t transmission_mode; |
123 | uint8_t DVBH_mask_HP; | 122 | uint8_t DVBH_mask_HP; |
124 | uint8_t DVBH_mask_LP; | 123 | uint8_t DVBH_mask_LP; |
125 | uint16_t cell_ID; | 124 | uint16_t cell_ID; |
126 | }; | 125 | } __packed; |
127 | 126 | ||
128 | struct as10x_tune_args { | 127 | struct as10x_tune_args { |
129 | /* frequency */ | 128 | /* frequency */ |
130 | uint32_t freq; | 129 | uint32_t freq; |
131 | /* bandwidth */ | 130 | /* bandwidth */ |
132 | uint8_t bandwidth; | 131 | uint8_t bandwidth; |
133 | /* hierarchy selection */ | 132 | /* hierarchy selection */ |
134 | uint8_t hier_select; | 133 | uint8_t hier_select; |
135 | /* constellation */ | 134 | /* constellation */ |
136 | uint8_t constellation; | 135 | uint8_t constellation; |
137 | /* hierarchy */ | 136 | /* hierarchy */ |
138 | uint8_t hierarchy; | 137 | uint8_t hierarchy; |
139 | /* interleaving mode */ | 138 | /* interleaving mode */ |
140 | uint8_t interleaving_mode; | 139 | uint8_t interleaving_mode; |
141 | /* code rate */ | 140 | /* code rate */ |
142 | uint8_t code_rate; | 141 | uint8_t code_rate; |
143 | /* guard interval */ | 142 | /* guard interval */ |
144 | uint8_t guard_interval; | 143 | uint8_t guard_interval; |
145 | /* transmission mode */ | 144 | /* transmission mode */ |
146 | uint8_t transmission_mode; | 145 | uint8_t transmission_mode; |
147 | }; | 146 | } __packed; |
148 | 147 | ||
149 | struct as10x_tune_status { | 148 | struct as10x_tune_status { |
150 | /* tune status */ | 149 | /* tune status */ |
151 | uint8_t tune_state; | 150 | uint8_t tune_state; |
152 | /* signal strength */ | 151 | /* signal strength */ |
153 | int16_t signal_strength; | 152 | int16_t signal_strength; |
154 | /* packet error rate 10^-4 */ | 153 | /* packet error rate 10^-4 */ |
155 | uint16_t PER; | 154 | uint16_t PER; |
156 | /* bit error rate 10^-4 */ | 155 | /* bit error rate 10^-4 */ |
157 | uint16_t BER; | 156 | uint16_t BER; |
158 | }; | 157 | } __packed; |
159 | 158 | ||
160 | struct as10x_demod_stats { | 159 | struct as10x_demod_stats { |
161 | /* frame counter */ | 160 | /* frame counter */ |
162 | uint32_t frame_count; | 161 | uint32_t frame_count; |
163 | /* Bad frame counter */ | 162 | /* Bad frame counter */ |
164 | uint32_t bad_frame_count; | 163 | uint32_t bad_frame_count; |
165 | /* Number of wrong bytes fixed by Reed-Solomon */ | 164 | /* Number of wrong bytes fixed by Reed-Solomon */ |
166 | uint32_t bytes_fixed_by_rs; | 165 | uint32_t bytes_fixed_by_rs; |
167 | /* Averaged MER */ | 166 | /* Averaged MER */ |
168 | uint16_t mer; | 167 | uint16_t mer; |
169 | /* statistics calculation state indicator (started or not) */ | 168 | /* statistics calculation state indicator (started or not) */ |
170 | uint8_t has_started; | 169 | uint8_t has_started; |
171 | }; | 170 | } __packed; |
172 | 171 | ||
173 | struct as10x_ts_filter { | 172 | struct as10x_ts_filter { |
174 | uint16_t pid; /** valid PID value 0x00 : 0x2000 */ | 173 | uint16_t pid; /* valid PID value 0x00 : 0x2000 */ |
175 | uint8_t type; /** Red TS_PID_TYPE_<N> values */ | 174 | uint8_t type; /* Red TS_PID_TYPE_<N> values */ |
176 | uint8_t idx; /** index in filtering table */ | 175 | uint8_t idx; /* index in filtering table */ |
177 | }; | 176 | } __packed; |
178 | 177 | ||
179 | struct as10x_register_value { | 178 | struct as10x_register_value { |
180 | uint8_t mode; | 179 | uint8_t mode; |
181 | union { | 180 | union { |
182 | uint8_t value8; /* 8 bit value */ | 181 | uint8_t value8; /* 8 bit value */ |
183 | uint16_t value16; /* 16 bit value */ | 182 | uint16_t value16; /* 16 bit value */ |
184 | uint32_t value32; /* 32 bit value */ | 183 | uint32_t value32; /* 32 bit value */ |
185 | }u; | 184 | } u; |
186 | }; | 185 | } __packed; |
187 | |||
188 | #pragma pack() | ||
189 | 186 | ||
190 | struct as10x_register_addr { | 187 | struct as10x_register_addr { |
191 | /* register addr */ | 188 | /* register addr */ |
192 | uint32_t addr; | 189 | uint32_t addr; |
193 | /* register mode access */ | 190 | /* register mode access */ |
194 | uint8_t mode; | 191 | uint8_t mode; |
195 | }; | 192 | }; |
196 | 193 | ||
197 | |||
198 | #endif | 194 | #endif |
diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index 7b256a948c27..a007e7442be8 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h | |||
@@ -98,7 +98,6 @@ | |||
98 | #define EASYCAP_DRIVER_VERSION "0.9.01" | 98 | #define EASYCAP_DRIVER_VERSION "0.9.01" |
99 | #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" | 99 | #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" |
100 | 100 | ||
101 | #define USB_SKEL_MINOR_BASE 192 | ||
102 | #define DONGLE_MANY 8 | 101 | #define DONGLE_MANY 8 |
103 | #define INPUT_MANY 6 | 102 | #define INPUT_MANY 6 |
104 | /*---------------------------------------------------------------------------*/ | 103 | /*---------------------------------------------------------------------------*/ |
@@ -324,8 +323,6 @@ struct easycap { | |||
324 | int lost[INPUT_MANY]; | 323 | int lost[INPUT_MANY]; |
325 | int merit[180]; | 324 | int merit[180]; |
326 | 325 | ||
327 | long long int dnbydt; | ||
328 | |||
329 | int video_interface; | 326 | int video_interface; |
330 | int video_altsetting_on; | 327 | int video_altsetting_on; |
331 | int video_altsetting_off; | 328 | int video_altsetting_off; |
@@ -353,7 +350,6 @@ struct easycap { | |||
353 | u8 *pcache; | 350 | u8 *pcache; |
354 | int video_mt; | 351 | int video_mt; |
355 | int audio_mt; | 352 | int audio_mt; |
356 | long long audio_bytes; | ||
357 | u32 isequence; | 353 | u32 isequence; |
358 | 354 | ||
359 | int vma_many; | 355 | int vma_many; |
@@ -450,9 +446,6 @@ struct easycap { | |||
450 | * SOUND PROPERTIES | 446 | * SOUND PROPERTIES |
451 | */ | 447 | */ |
452 | /*---------------------------------------------------------------------------*/ | 448 | /*---------------------------------------------------------------------------*/ |
453 | |||
454 | int audio_buffer_many; | ||
455 | |||
456 | int allocation_audio_urb; | 449 | int allocation_audio_urb; |
457 | int allocation_audio_page; | 450 | int allocation_audio_page; |
458 | int allocation_audio_struct; | 451 | int allocation_audio_struct; |
@@ -469,72 +462,53 @@ struct easycap { | |||
469 | * VIDEO FUNCTION PROTOTYPES | 462 | * VIDEO FUNCTION PROTOTYPES |
470 | */ | 463 | */ |
471 | /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ | 464 | /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ |
465 | int easycap_newinput(struct easycap *, int); | ||
466 | void easycap_testcard(struct easycap *, int); | ||
467 | int easycap_isdongle(struct easycap *); | ||
468 | |||
472 | long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long); | 469 | long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long); |
473 | int easycap_dqbuf(struct easycap *, int); | 470 | |
474 | int submit_video_urbs(struct easycap *); | 471 | int easycap_video_dqbuf(struct easycap *, int); |
475 | int kill_video_urbs(struct easycap *); | 472 | int easycap_video_submit_urbs(struct easycap *); |
476 | int field2frame(struct easycap *); | 473 | int easycap_video_kill_urbs(struct easycap *); |
477 | int redaub(struct easycap *, void *, void *, | 474 | int easycap_video_fillin_formats(void); |
478 | int, int, u8, u8, bool); | 475 | |
479 | void easycap_testcard(struct easycap *, int); | 476 | int adjust_standard(struct easycap *, v4l2_std_id); |
480 | int fillin_formats(void); | 477 | int adjust_format(struct easycap *, u32, u32, u32, int, bool); |
481 | int newinput(struct easycap *, int); | 478 | int adjust_brightness(struct easycap *, int); |
482 | int adjust_standard(struct easycap *, v4l2_std_id); | 479 | int adjust_contrast(struct easycap *, int); |
483 | int adjust_format(struct easycap *, u32, u32, u32, | 480 | int adjust_saturation(struct easycap *, int); |
484 | int, bool); | 481 | int adjust_hue(struct easycap *, int); |
485 | int adjust_brightness(struct easycap *, int); | ||
486 | int adjust_contrast(struct easycap *, int); | ||
487 | int adjust_saturation(struct easycap *, int); | ||
488 | int adjust_hue(struct easycap *, int); | ||
489 | int adjust_volume(struct easycap *, int); | ||
490 | /*---------------------------------------------------------------------------*/ | 482 | /*---------------------------------------------------------------------------*/ |
491 | /* | 483 | /* |
492 | * AUDIO FUNCTION PROTOTYPES | 484 | * AUDIO FUNCTION PROTOTYPES |
493 | */ | 485 | */ |
494 | /*---------------------------------------------------------------------------*/ | 486 | /*---------------------------------------------------------------------------*/ |
495 | int easycap_alsa_probe(struct easycap *); | 487 | int easycap_alsa_probe(struct easycap *); |
496 | void easycap_alsa_complete(struct urb *); | 488 | int easycap_audio_kill_urbs(struct easycap *); |
497 | 489 | void easycap_alsa_complete(struct urb *); | |
498 | int easycap_sound_setup(struct easycap *); | ||
499 | int submit_audio_urbs(struct easycap *); | ||
500 | int kill_audio_urbs(struct easycap *); | ||
501 | void easyoss_testtone(struct easycap *, int); | ||
502 | int audio_setup(struct easycap *); | ||
503 | /*---------------------------------------------------------------------------*/ | 490 | /*---------------------------------------------------------------------------*/ |
504 | /* | 491 | /* |
505 | * LOW-LEVEL FUNCTION PROTOTYPES | 492 | * LOW-LEVEL FUNCTION PROTOTYPES |
506 | */ | 493 | */ |
507 | /*---------------------------------------------------------------------------*/ | 494 | /*---------------------------------------------------------------------------*/ |
508 | int audio_gainget(struct usb_device *); | 495 | int easycap_audio_gainset(struct usb_device *, s8); |
509 | int audio_gainset(struct usb_device *, s8); | 496 | int easycap_audio_setup(struct easycap *); |
510 | 497 | ||
511 | int set_interface(struct usb_device *, u16); | 498 | int easycap_wakeup_device(struct usb_device *); |
512 | int wakeup_device(struct usb_device *); | ||
513 | int confirm_resolution(struct usb_device *); | ||
514 | int confirm_stream(struct usb_device *); | ||
515 | 499 | ||
516 | int setup_stk(struct usb_device *, bool); | 500 | int setup_stk(struct usb_device *, bool); |
517 | int setup_saa(struct usb_device *, bool); | 501 | int setup_saa(struct usb_device *, bool); |
518 | int setup_vt(struct usb_device *); | 502 | int ready_saa(struct usb_device *); |
519 | int check_stk(struct usb_device *, bool); | 503 | int merit_saa(struct usb_device *); |
520 | int check_saa(struct usb_device *, bool); | 504 | int check_vt(struct usb_device *); |
521 | int ready_saa(struct usb_device *); | 505 | int select_input(struct usb_device *, int, int); |
522 | int merit_saa(struct usb_device *); | 506 | int set_resolution(struct usb_device *, u16, u16, u16, u16); |
523 | int check_vt(struct usb_device *); | ||
524 | int select_input(struct usb_device *, int, int); | ||
525 | int set_resolution(struct usb_device *, | ||
526 | u16, u16, u16, u16); | ||
527 | 507 | ||
528 | int read_saa(struct usb_device *, u16); | 508 | int read_saa(struct usb_device *, u16); |
529 | int read_stk(struct usb_device *, u32); | 509 | int write_saa(struct usb_device *, u16, u16); |
530 | int write_saa(struct usb_device *, u16, u16); | 510 | int start_100(struct usb_device *); |
531 | int write_000(struct usb_device *, u16, u16); | 511 | int stop_100(struct usb_device *); |
532 | int start_100(struct usb_device *); | ||
533 | int stop_100(struct usb_device *); | ||
534 | int write_300(struct usb_device *); | ||
535 | int read_vt(struct usb_device *, u16); | ||
536 | int write_vt(struct usb_device *, u16, u16); | ||
537 | int isdongle(struct easycap *); | ||
538 | /*---------------------------------------------------------------------------*/ | 512 | /*---------------------------------------------------------------------------*/ |
539 | 513 | ||
540 | 514 | ||
@@ -588,7 +562,6 @@ extern bool easycap_readback; | |||
588 | extern const struct easycap_standard easycap_standard[]; | 562 | extern const struct easycap_standard easycap_standard[]; |
589 | extern struct easycap_format easycap_format[]; | 563 | extern struct easycap_format easycap_format[]; |
590 | extern struct v4l2_queryctrl easycap_control[]; | 564 | extern struct v4l2_queryctrl easycap_control[]; |
591 | extern struct usb_driver easycap_usb_driver; | ||
592 | extern struct easycap_dongle easycapdc60_dongle[]; | 565 | extern struct easycap_dongle easycapdc60_dongle[]; |
593 | 566 | ||
594 | #endif /* !__EASYCAP_H__ */ | 567 | #endif /* !__EASYCAP_H__ */ |
diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index c99addfb6242..9413b37490c2 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c | |||
@@ -25,7 +25,6 @@ | |||
25 | */ | 25 | */ |
26 | /*****************************************************************************/ | 26 | /*****************************************************************************/ |
27 | 27 | ||
28 | #include <linux/version.h> | ||
29 | #include "easycap.h" | 28 | #include "easycap.h" |
30 | 29 | ||
31 | /*--------------------------------------------------------------------------*/ | 30 | /*--------------------------------------------------------------------------*/ |
@@ -125,7 +124,7 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) | |||
125 | } | 124 | } |
126 | if (peasycap->video_isoc_streaming) { | 125 | if (peasycap->video_isoc_streaming) { |
127 | resubmit = true; | 126 | resubmit = true; |
128 | kill_video_urbs(peasycap); | 127 | easycap_video_kill_urbs(peasycap); |
129 | } else | 128 | } else |
130 | resubmit = false; | 129 | resubmit = false; |
131 | /*--------------------------------------------------------------------------*/ | 130 | /*--------------------------------------------------------------------------*/ |
@@ -331,7 +330,7 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) | |||
331 | "from 0x%02X to 0x%02X\n", reg, itwas, isnow); | 330 | "from 0x%02X to 0x%02X\n", reg, itwas, isnow); |
332 | } | 331 | } |
333 | if (resubmit) | 332 | if (resubmit) |
334 | submit_video_urbs(peasycap); | 333 | easycap_video_submit_urbs(peasycap); |
335 | return 0; | 334 | return 0; |
336 | } | 335 | } |
337 | /*****************************************************************************/ | 336 | /*****************************************************************************/ |
@@ -558,7 +557,7 @@ int adjust_format(struct easycap *peasycap, | |||
558 | peasycap->bytesperpixel * peasycap->width * peasycap->height; | 557 | peasycap->bytesperpixel * peasycap->width * peasycap->height; |
559 | if (peasycap->video_isoc_streaming) { | 558 | if (peasycap->video_isoc_streaming) { |
560 | resubmit = true; | 559 | resubmit = true; |
561 | kill_video_urbs(peasycap); | 560 | easycap_video_kill_urbs(peasycap); |
562 | } else | 561 | } else |
563 | resubmit = false; | 562 | resubmit = false; |
564 | /*---------------------------------------------------------------------------*/ | 563 | /*---------------------------------------------------------------------------*/ |
@@ -622,7 +621,7 @@ int adjust_format(struct easycap *peasycap, | |||
622 | } | 621 | } |
623 | /*---------------------------------------------------------------------------*/ | 622 | /*---------------------------------------------------------------------------*/ |
624 | if (resubmit) | 623 | if (resubmit) |
625 | submit_video_urbs(peasycap); | 624 | easycap_video_submit_urbs(peasycap); |
626 | 625 | ||
627 | return peasycap_best_format - easycap_format; | 626 | return peasycap_best_format - easycap_format; |
628 | } | 627 | } |
@@ -667,16 +666,15 @@ int adjust_brightness(struct easycap *peasycap, int value) | |||
667 | peasycap->inputset[peasycap->input].brightness_ok = 1; | 666 | peasycap->inputset[peasycap->input].brightness_ok = 1; |
668 | } else | 667 | } else |
669 | JOM(8, "%i=peasycap->input\n", peasycap->input); | 668 | JOM(8, "%i=peasycap->input\n", peasycap->input); |
669 | |||
670 | mood = 0x00FF & (unsigned int)peasycap->brightness; | 670 | mood = 0x00FF & (unsigned int)peasycap->brightness; |
671 | if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { | 671 | if (write_saa(peasycap->pusb_device, 0x0A, mood)) { |
672 | SAM("adjusting brightness to 0x%02X\n", mood); | ||
673 | return 0; | ||
674 | } else { | ||
675 | SAM("WARNING: failed to adjust brightness " | 672 | SAM("WARNING: failed to adjust brightness " |
676 | "to 0x%02X\n", mood); | 673 | "to 0x%02X\n", mood); |
677 | return -ENOENT; | 674 | return -ENOENT; |
678 | } | 675 | } |
679 | break; | 676 | SAM("adjusting brightness to 0x%02X\n", mood); |
677 | return 0; | ||
680 | } | 678 | } |
681 | i1++; | 679 | i1++; |
682 | } | 680 | } |
@@ -726,15 +724,13 @@ int adjust_contrast(struct easycap *peasycap, int value) | |||
726 | JOM(8, "%i=peasycap->input\n", peasycap->input); | 724 | JOM(8, "%i=peasycap->input\n", peasycap->input); |
727 | 725 | ||
728 | mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); | 726 | mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); |
729 | if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { | 727 | if (write_saa(peasycap->pusb_device, 0x0B, mood)) { |
730 | SAM("adjusting contrast to 0x%02X\n", mood); | ||
731 | return 0; | ||
732 | } else { | ||
733 | SAM("WARNING: failed to adjust contrast to " | 728 | SAM("WARNING: failed to adjust contrast to " |
734 | "0x%02X\n", mood); | 729 | "0x%02X\n", mood); |
735 | return -ENOENT; | 730 | return -ENOENT; |
736 | } | 731 | } |
737 | break; | 732 | SAM("adjusting contrast to 0x%02X\n", mood); |
733 | return 0; | ||
738 | } | 734 | } |
739 | i1++; | 735 | i1++; |
740 | } | 736 | } |
@@ -784,14 +780,13 @@ int adjust_saturation(struct easycap *peasycap, int value) | |||
784 | } else | 780 | } else |
785 | JOM(8, "%i=peasycap->input\n", peasycap->input); | 781 | JOM(8, "%i=peasycap->input\n", peasycap->input); |
786 | mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); | 782 | mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); |
787 | if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { | 783 | if (write_saa(peasycap->pusb_device, 0x0C, mood)) { |
788 | SAM("adjusting saturation to 0x%02X\n", mood); | ||
789 | return 0; | ||
790 | } else { | ||
791 | SAM("WARNING: failed to adjust saturation to " | 784 | SAM("WARNING: failed to adjust saturation to " |
792 | "0x%02X\n", mood); | 785 | "0x%02X\n", mood); |
793 | return -ENOENT; | 786 | return -ENOENT; |
794 | } | 787 | } |
788 | SAM("adjusting saturation to 0x%02X\n", mood); | ||
789 | return 0; | ||
795 | break; | 790 | break; |
796 | } | 791 | } |
797 | i1++; | 792 | i1++; |
@@ -839,13 +834,12 @@ int adjust_hue(struct easycap *peasycap, int value) | |||
839 | JOM(8, "%i=peasycap->input\n", peasycap->input); | 834 | JOM(8, "%i=peasycap->input\n", peasycap->input); |
840 | i2 = peasycap->hue - 128; | 835 | i2 = peasycap->hue - 128; |
841 | mood = 0x00FF & ((int) i2); | 836 | mood = 0x00FF & ((int) i2); |
842 | if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { | 837 | if (write_saa(peasycap->pusb_device, 0x0D, mood)) { |
843 | SAM("adjusting hue to 0x%02X\n", mood); | ||
844 | return 0; | ||
845 | } else { | ||
846 | SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); | 838 | SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); |
847 | return -ENOENT; | 839 | return -ENOENT; |
848 | } | 840 | } |
841 | SAM("adjusting hue to 0x%02X\n", mood); | ||
842 | return 0; | ||
849 | break; | 843 | break; |
850 | } | 844 | } |
851 | i1++; | 845 | i1++; |
@@ -854,7 +848,7 @@ int adjust_hue(struct easycap *peasycap, int value) | |||
854 | return -ENOENT; | 848 | return -ENOENT; |
855 | } | 849 | } |
856 | /*****************************************************************************/ | 850 | /*****************************************************************************/ |
857 | int adjust_volume(struct easycap *peasycap, int value) | 851 | static int adjust_volume(struct easycap *peasycap, int value) |
858 | { | 852 | { |
859 | s8 mood; | 853 | s8 mood; |
860 | int i1; | 854 | int i1; |
@@ -885,15 +879,13 @@ int adjust_volume(struct easycap *peasycap, int value) | |||
885 | mood = (16 > peasycap->volume) ? 16 : | 879 | mood = (16 > peasycap->volume) ? 16 : |
886 | ((31 < peasycap->volume) ? 31 : | 880 | ((31 < peasycap->volume) ? 31 : |
887 | (s8) peasycap->volume); | 881 | (s8) peasycap->volume); |
888 | if (!audio_gainset(peasycap->pusb_device, mood)) { | 882 | if (!easycap_audio_gainset(peasycap->pusb_device, mood)) { |
889 | SAM("adjusting volume to 0x%02X\n", mood); | ||
890 | return 0; | ||
891 | } else { | ||
892 | SAM("WARNING: failed to adjust volume to " | 883 | SAM("WARNING: failed to adjust volume to " |
893 | "0x%2X\n", mood); | 884 | "0x%2X\n", mood); |
894 | return -ENOENT; | 885 | return -ENOENT; |
895 | } | 886 | } |
896 | break; | 887 | SAM("adjusting volume to 0x%02X\n", mood); |
888 | return 0; | ||
897 | } | 889 | } |
898 | i1++; | 890 | i1++; |
899 | } | 891 | } |
@@ -971,7 +963,7 @@ long easycap_unlocked_ioctl(struct file *file, | |||
971 | SAM("ERROR: peasycap->pusb_device is NULL\n"); | 963 | SAM("ERROR: peasycap->pusb_device is NULL\n"); |
972 | return -EFAULT; | 964 | return -EFAULT; |
973 | } | 965 | } |
974 | kd = isdongle(peasycap); | 966 | kd = easycap_isdongle(peasycap); |
975 | if (0 <= kd && DONGLE_MANY > kd) { | 967 | if (0 <= kd && DONGLE_MANY > kd) { |
976 | if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { | 968 | if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { |
977 | SAY("ERROR: cannot lock " | 969 | SAY("ERROR: cannot lock " |
@@ -986,7 +978,7 @@ long easycap_unlocked_ioctl(struct file *file, | |||
986 | * IF NECESSARY, BAIL OUT. | 978 | * IF NECESSARY, BAIL OUT. |
987 | */ | 979 | */ |
988 | /*---------------------------------------------------------------------------*/ | 980 | /*---------------------------------------------------------------------------*/ |
989 | if (kd != isdongle(peasycap)) | 981 | if (kd != easycap_isdongle(peasycap)) |
990 | return -ERESTARTSYS; | 982 | return -ERESTARTSYS; |
991 | if (!file) { | 983 | if (!file) { |
992 | SAY("ERROR: file is NULL\n"); | 984 | SAY("ERROR: file is NULL\n"); |
@@ -1226,7 +1218,7 @@ long easycap_unlocked_ioctl(struct file *file, | |||
1226 | return -EINVAL; | 1218 | return -EINVAL; |
1227 | } | 1219 | } |
1228 | 1220 | ||
1229 | rc = newinput(peasycap, (int)index); | 1221 | rc = easycap_newinput(peasycap, (int)index); |
1230 | if (0 == rc) { | 1222 | if (0 == rc) { |
1231 | JOM(8, "newinput(.,%i) OK\n", (int)index); | 1223 | JOM(8, "newinput(.,%i) OK\n", (int)index); |
1232 | } else { | 1224 | } else { |
@@ -2209,7 +2201,7 @@ long easycap_unlocked_ioctl(struct file *file, | |||
2209 | 2201 | ||
2210 | if (!peasycap->polled) { | 2202 | if (!peasycap->polled) { |
2211 | do { | 2203 | do { |
2212 | rcdq = easycap_dqbuf(peasycap, 0); | 2204 | rcdq = easycap_video_dqbuf(peasycap, 0); |
2213 | if (-EIO == rcdq) { | 2205 | if (-EIO == rcdq) { |
2214 | JOM(8, "returning -EIO because " | 2206 | JOM(8, "returning -EIO because " |
2215 | "dqbuf() returned -EIO\n"); | 2207 | "dqbuf() returned -EIO\n"); |
@@ -2313,7 +2305,7 @@ long easycap_unlocked_ioctl(struct file *file, | |||
2313 | mutex_unlock(&easycapdc60_dongle[kd].mutex_video); | 2305 | mutex_unlock(&easycapdc60_dongle[kd].mutex_video); |
2314 | return -EFAULT; | 2306 | return -EFAULT; |
2315 | } | 2307 | } |
2316 | submit_video_urbs(peasycap); | 2308 | easycap_video_submit_urbs(peasycap); |
2317 | peasycap->video_idle = 0; | 2309 | peasycap->video_idle = 0; |
2318 | peasycap->audio_idle = 0; | 2310 | peasycap->audio_idle = 0; |
2319 | peasycap->video_eof = 0; | 2311 | peasycap->video_eof = 0; |
diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c index 0385735ac6df..0380babed22c 100644 --- a/drivers/staging/media/easycap/easycap_low.c +++ b/drivers/staging/media/easycap/easycap_low.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | #include "easycap.h" | 41 | #include "easycap.h" |
42 | 42 | ||
43 | |||
43 | #define GET(X, Y, Z) do { \ | 44 | #define GET(X, Y, Z) do { \ |
44 | int __rc; \ | 45 | int __rc; \ |
45 | *(Z) = (u16)0; \ | 46 | *(Z) = (u16)0; \ |
@@ -59,9 +60,9 @@ | |||
59 | 60 | ||
60 | /*--------------------------------------------------------------------------*/ | 61 | /*--------------------------------------------------------------------------*/ |
61 | static const struct stk1160config { | 62 | static const struct stk1160config { |
62 | int reg; | 63 | u16 reg; |
63 | int set; | 64 | u16 set; |
64 | } stk1160configPAL[256] = { | 65 | } stk1160configPAL[] = { |
65 | {0x000, 0x0098}, | 66 | {0x000, 0x0098}, |
66 | {0x002, 0x0093}, | 67 | {0x002, 0x0093}, |
67 | 68 | ||
@@ -103,7 +104,7 @@ static const struct stk1160config { | |||
103 | {0xFFF, 0xFFFF} | 104 | {0xFFF, 0xFFFF} |
104 | }; | 105 | }; |
105 | /*--------------------------------------------------------------------------*/ | 106 | /*--------------------------------------------------------------------------*/ |
106 | static const struct stk1160config stk1160configNTSC[256] = { | 107 | static const struct stk1160config stk1160configNTSC[] = { |
107 | {0x000, 0x0098}, | 108 | {0x000, 0x0098}, |
108 | {0x002, 0x0093}, | 109 | {0x002, 0x0093}, |
109 | 110 | ||
@@ -146,9 +147,9 @@ static const struct stk1160config stk1160configNTSC[256] = { | |||
146 | }; | 147 | }; |
147 | /*--------------------------------------------------------------------------*/ | 148 | /*--------------------------------------------------------------------------*/ |
148 | static const struct saa7113config { | 149 | static const struct saa7113config { |
149 | int reg; | 150 | u8 reg; |
150 | int set; | 151 | u8 set; |
151 | } saa7113configPAL[256] = { | 152 | } saa7113configPAL[] = { |
152 | {0x01, 0x08}, | 153 | {0x01, 0x08}, |
153 | {0x02, 0x80}, | 154 | {0x02, 0x80}, |
154 | {0x03, 0x33}, | 155 | {0x03, 0x33}, |
@@ -202,7 +203,7 @@ static const struct saa7113config { | |||
202 | {0xFF, 0xFF} | 203 | {0xFF, 0xFF} |
203 | }; | 204 | }; |
204 | /*--------------------------------------------------------------------------*/ | 205 | /*--------------------------------------------------------------------------*/ |
205 | static const struct saa7113config saa7113configNTSC[256] = { | 206 | static const struct saa7113config saa7113configNTSC[] = { |
206 | {0x01, 0x08}, | 207 | {0x01, 0x08}, |
207 | {0x02, 0x80}, | 208 | {0x02, 0x80}, |
208 | {0x03, 0x33}, | 209 | {0x03, 0x33}, |
@@ -355,101 +356,6 @@ static int wait_i2c(struct usb_device *p) | |||
355 | } | 356 | } |
356 | 357 | ||
357 | /****************************************************************************/ | 358 | /****************************************************************************/ |
358 | int confirm_resolution(struct usb_device *p) | ||
359 | { | ||
360 | u8 get0, get1, get2, get3, get4, get5, get6, get7; | ||
361 | |||
362 | if (!p) | ||
363 | return -ENODEV; | ||
364 | GET(p, 0x0110, &get0); | ||
365 | GET(p, 0x0111, &get1); | ||
366 | GET(p, 0x0112, &get2); | ||
367 | GET(p, 0x0113, &get3); | ||
368 | GET(p, 0x0114, &get4); | ||
369 | GET(p, 0x0115, &get5); | ||
370 | GET(p, 0x0116, &get6); | ||
371 | GET(p, 0x0117, &get7); | ||
372 | JOT(8, "0x%03X, 0x%03X, " | ||
373 | "0x%03X, 0x%03X, " | ||
374 | "0x%03X, 0x%03X, " | ||
375 | "0x%03X, 0x%03X\n", | ||
376 | get0, get1, get2, get3, get4, get5, get6, get7); | ||
377 | JOT(8, "....cf PAL_720x526: " | ||
378 | "0x%03X, 0x%03X, " | ||
379 | "0x%03X, 0x%03X, " | ||
380 | "0x%03X, 0x%03X, " | ||
381 | "0x%03X, 0x%03X\n", | ||
382 | 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); | ||
383 | JOT(8, "....cf PAL_704x526: " | ||
384 | "0x%03X, 0x%03X, " | ||
385 | "0x%03X, 0x%03X, " | ||
386 | "0x%03X, 0x%03X, " | ||
387 | "0x%03X, 0x%03X\n", | ||
388 | 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); | ||
389 | JOT(8, "....cf VGA_640x480: " | ||
390 | "0x%03X, 0x%03X, " | ||
391 | "0x%03X, 0x%03X, " | ||
392 | "0x%03X, 0x%03X, " | ||
393 | "0x%03X, 0x%03X\n", | ||
394 | 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); | ||
395 | return 0; | ||
396 | } | ||
397 | /****************************************************************************/ | ||
398 | int confirm_stream(struct usb_device *p) | ||
399 | { | ||
400 | u16 get2; | ||
401 | u8 igot; | ||
402 | |||
403 | if (!p) | ||
404 | return -ENODEV; | ||
405 | GET(p, 0x0100, &igot); get2 = 0x80 & igot; | ||
406 | if (0x80 == get2) | ||
407 | JOT(8, "confirm_stream: OK\n"); | ||
408 | else | ||
409 | JOT(8, "confirm_stream: STUCK\n"); | ||
410 | return 0; | ||
411 | } | ||
412 | /****************************************************************************/ | ||
413 | int setup_stk(struct usb_device *p, bool ntsc) | ||
414 | { | ||
415 | int i; | ||
416 | const struct stk1160config *cfg; | ||
417 | if (!p) | ||
418 | return -ENODEV; | ||
419 | cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; | ||
420 | for (i = 0; cfg[i].reg != 0xFFF; i++) | ||
421 | SET(p, cfg[i].reg, cfg[i].set); | ||
422 | |||
423 | write_300(p); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | /****************************************************************************/ | ||
428 | int setup_saa(struct usb_device *p, bool ntsc) | ||
429 | { | ||
430 | int i, ir; | ||
431 | const struct saa7113config *cfg; | ||
432 | if (!p) | ||
433 | return -ENODEV; | ||
434 | cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; | ||
435 | for (i = 0; cfg[i].reg != 0xFF; i++) | ||
436 | ir = write_saa(p, cfg[i].reg, cfg[i].set); | ||
437 | return 0; | ||
438 | } | ||
439 | /****************************************************************************/ | ||
440 | int write_000(struct usb_device *p, u16 set2, u16 set0) | ||
441 | { | ||
442 | u8 igot0, igot2; | ||
443 | |||
444 | if (!p) | ||
445 | return -ENODEV; | ||
446 | GET(p, 0x0002, &igot2); | ||
447 | GET(p, 0x0000, &igot0); | ||
448 | SET(p, 0x0002, set2); | ||
449 | SET(p, 0x0000, set0); | ||
450 | return 0; | ||
451 | } | ||
452 | /****************************************************************************/ | ||
453 | int write_saa(struct usb_device *p, u16 reg0, u16 set0) | 359 | int write_saa(struct usb_device *p, u16 reg0, u16 set0) |
454 | { | 360 | { |
455 | if (!p) | 361 | if (!p) |
@@ -470,8 +376,7 @@ int write_saa(struct usb_device *p, u16 reg0, u16 set0) | |||
470 | * REGISTER 504: TARGET ADDRESS ON VT1612A | 376 | * REGISTER 504: TARGET ADDRESS ON VT1612A |
471 | */ | 377 | */ |
472 | /*--------------------------------------------------------------------------*/ | 378 | /*--------------------------------------------------------------------------*/ |
473 | int | 379 | static int write_vt(struct usb_device *p, u16 reg0, u16 set0) |
474 | write_vt(struct usb_device *p, u16 reg0, u16 set0) | ||
475 | { | 380 | { |
476 | u8 igot; | 381 | u8 igot; |
477 | u16 got502, got503; | 382 | u16 got502, got503; |
@@ -508,7 +413,7 @@ write_vt(struct usb_device *p, u16 reg0, u16 set0) | |||
508 | * REGISTER 504: TARGET ADDRESS ON VT1612A | 413 | * REGISTER 504: TARGET ADDRESS ON VT1612A |
509 | */ | 414 | */ |
510 | /*--------------------------------------------------------------------------*/ | 415 | /*--------------------------------------------------------------------------*/ |
511 | int read_vt(struct usb_device *p, u16 reg0) | 416 | static int read_vt(struct usb_device *p, u16 reg0) |
512 | { | 417 | { |
513 | u8 igot; | 418 | u8 igot; |
514 | u16 got502, got503; | 419 | u16 got502, got503; |
@@ -532,7 +437,7 @@ int read_vt(struct usb_device *p, u16 reg0) | |||
532 | * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO. | 437 | * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO. |
533 | */ | 438 | */ |
534 | /*--------------------------------------------------------------------------*/ | 439 | /*--------------------------------------------------------------------------*/ |
535 | int write_300(struct usb_device *p) | 440 | static int write_300(struct usb_device *p) |
536 | { | 441 | { |
537 | if (!p) | 442 | if (!p) |
538 | return -ENODEV; | 443 | return -ENODEV; |
@@ -545,32 +450,36 @@ int write_300(struct usb_device *p) | |||
545 | return 0; | 450 | return 0; |
546 | } | 451 | } |
547 | /****************************************************************************/ | 452 | /****************************************************************************/ |
548 | /*--------------------------------------------------------------------------*/ | 453 | /****************************************************************************/ |
549 | /* | 454 | int setup_stk(struct usb_device *p, bool ntsc) |
550 | * NOTE: THE FOLLOWING IS NOT CHECKED: | ||
551 | * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL. | ||
552 | */ | ||
553 | /*--------------------------------------------------------------------------*/ | ||
554 | int check_saa(struct usb_device *p, bool ntsc) | ||
555 | { | 455 | { |
556 | int i, ir, rc = 0; | 456 | int i; |
557 | struct saa7113config const *cfg; | 457 | const struct stk1160config *cfg; |
558 | if (!p) | 458 | if (!p) |
559 | return -ENODEV; | 459 | return -ENODEV; |
460 | cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; | ||
461 | for (i = 0; cfg[i].reg != 0xFFF; i++) | ||
462 | SET(p, cfg[i].reg, cfg[i].set); | ||
463 | |||
464 | write_300(p); | ||
560 | 465 | ||
561 | cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; | 466 | return 0; |
467 | } | ||
468 | /****************************************************************************/ | ||
469 | int setup_saa(struct usb_device *p, bool ntsc) | ||
470 | { | ||
471 | int i, rc; | ||
472 | const struct saa7113config *cfg; | ||
473 | if (!p) | ||
474 | return -ENODEV; | ||
475 | cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; | ||
562 | for (i = 0; cfg[i].reg != 0xFF; i++) { | 476 | for (i = 0; cfg[i].reg != 0xFF; i++) { |
563 | if (0x0F == cfg[i].reg) | 477 | rc = write_saa(p, cfg[i].reg, cfg[i].set); |
564 | continue; | 478 | if (rc) |
565 | ir = read_saa(p, cfg[i].reg); | 479 | dev_err(&p->dev, |
566 | if (ir != cfg[i].set) { | 480 | "Failed to set SAA register %d", cfg[i].reg); |
567 | SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", | ||
568 | cfg[i].reg, ir, cfg[i].set); | ||
569 | rc--; | ||
570 | } | ||
571 | } | 481 | } |
572 | 482 | return 0; | |
573 | return (rc < -8) ? rc : 0; | ||
574 | } | 483 | } |
575 | /****************************************************************************/ | 484 | /****************************************************************************/ |
576 | int merit_saa(struct usb_device *p) | 485 | int merit_saa(struct usb_device *p) |
@@ -609,60 +518,22 @@ int ready_saa(struct usb_device *p) | |||
609 | msleep(marktime); | 518 | msleep(marktime); |
610 | j++; | 519 | j++; |
611 | } | 520 | } |
521 | |||
612 | if (max == j) | 522 | if (max == j) |
613 | return -1; | 523 | return -1; |
614 | else { | ||
615 | if (0x20 & rc) { | ||
616 | rate = 2; | ||
617 | JOT(8, "hardware detects 60 Hz\n"); | ||
618 | } else { | ||
619 | rate = 0; | ||
620 | JOT(8, "hardware detects 50 Hz\n"); | ||
621 | } | ||
622 | if (0x80 & rc) | ||
623 | JOT(8, "hardware detects interlacing\n"); | ||
624 | else { | ||
625 | rate++; | ||
626 | JOT(8, "hardware detects no interlacing\n"); | ||
627 | } | ||
628 | } | ||
629 | return 0; | ||
630 | } | ||
631 | /****************************************************************************/ | ||
632 | /*--------------------------------------------------------------------------*/ | ||
633 | /* | ||
634 | * NOTE: THE FOLLOWING ARE NOT CHECKED: | ||
635 | * REGISTERS 0x000, 0x002: FUNCTIONALITY IS NOT KNOWN | ||
636 | * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set) | ||
637 | */ | ||
638 | /*--------------------------------------------------------------------------*/ | ||
639 | int check_stk(struct usb_device *p, bool ntsc) | ||
640 | { | ||
641 | int i, ir; | ||
642 | const struct stk1160config *cfg; | ||
643 | |||
644 | if (!p) | ||
645 | return -ENODEV; | ||
646 | cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; | ||
647 | |||
648 | for (i = 0; 0xFFF != cfg[i].reg; i++) { | ||
649 | if (0x000 == cfg[i].reg || 0x002 == cfg[i].reg) | ||
650 | continue; | ||
651 | 524 | ||
652 | 525 | if (0x20 & rc) { | |
653 | ir = read_stk(p, cfg[i].reg); | 526 | rate = 2; |
654 | if (0x100 == cfg[i].reg) { | 527 | JOT(8, "hardware detects 60 Hz\n"); |
655 | if ((ir != (0xFF & cfg[i].set)) && | 528 | } else { |
656 | (ir != (0x80 | (0xFF & cfg[i].set))) && | 529 | rate = 0; |
657 | (0xFFFF != cfg[i].set)) { | 530 | JOT(8, "hardware detects 50 Hz\n"); |
658 | SAY("STK reg[0x%03X]=0x%02X expected 0x%02X\n", | 531 | } |
659 | cfg[i].reg, ir, cfg[i].set); | 532 | if (0x80 & rc) |
660 | } | 533 | JOT(8, "hardware detects interlacing\n"); |
661 | continue; | 534 | else { |
662 | } | 535 | rate++; |
663 | if ((ir != (0xFF & cfg[i].set)) && (0xFFFF != cfg[i].set)) | 536 | JOT(8, "hardware detects no interlacing\n"); |
664 | SAY("STK register 0x%03X has 0x%02X,expected 0x%02X\n", | ||
665 | cfg[i].reg, ir, cfg[i].set); | ||
666 | } | 537 | } |
667 | return 0; | 538 | return 0; |
668 | } | 539 | } |
@@ -682,7 +553,7 @@ int read_saa(struct usb_device *p, u16 reg0) | |||
682 | return igot; | 553 | return igot; |
683 | } | 554 | } |
684 | /****************************************************************************/ | 555 | /****************************************************************************/ |
685 | int read_stk(struct usb_device *p, u32 reg0) | 556 | static int read_stk(struct usb_device *p, u32 reg0) |
686 | { | 557 | { |
687 | u8 igot; | 558 | u8 igot; |
688 | 559 | ||
@@ -692,27 +563,7 @@ int read_stk(struct usb_device *p, u32 reg0) | |||
692 | GET(p, reg0, &igot); | 563 | GET(p, reg0, &igot); |
693 | return igot; | 564 | return igot; |
694 | } | 565 | } |
695 | /****************************************************************************/ | 566 | int select_input(struct usb_device *p, int input, int mode) |
696 | /*--------------------------------------------------------------------------*/ | ||
697 | /* | ||
698 | * HARDWARE USERSPACE INPUT NUMBER PHYSICAL INPUT DRIVER input VALUE | ||
699 | * | ||
700 | * CVBS+S-VIDEO 0 or 1 CVBS 1 | ||
701 | * FOUR-CVBS 0 or 1 CVBS1 1 | ||
702 | * FOUR-CVBS 2 CVBS2 2 | ||
703 | * FOUR-CVBS 3 CVBS3 3 | ||
704 | * FOUR-CVBS 4 CVBS4 4 | ||
705 | * CVBS+S-VIDEO 5 S-VIDEO 5 | ||
706 | * | ||
707 | * WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED: | ||
708 | * | ||
709 | * mode 7 => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED) | ||
710 | * mode 9 => USE AUTOMATIC GAIN CONTROL (DEFAULT) | ||
711 | * | ||
712 | */ | ||
713 | /*---------------------------------------------------------------------------*/ | ||
714 | int | ||
715 | select_input(struct usb_device *p, int input, int mode) | ||
716 | { | 567 | { |
717 | int ir; | 568 | int ir; |
718 | 569 | ||
@@ -877,10 +728,11 @@ int stop_100(struct usb_device *p) | |||
877 | /****************************************************************************/ | 728 | /****************************************************************************/ |
878 | /****************************************************************************/ | 729 | /****************************************************************************/ |
879 | /*****************************************************************************/ | 730 | /*****************************************************************************/ |
880 | int wakeup_device(struct usb_device *pusb_device) | 731 | int easycap_wakeup_device(struct usb_device *pusb_device) |
881 | { | 732 | { |
882 | if (!pusb_device) | 733 | if (!pusb_device) |
883 | return -ENODEV; | 734 | return -ENODEV; |
735 | |||
884 | return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), | 736 | return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), |
885 | USB_REQ_SET_FEATURE, | 737 | USB_REQ_SET_FEATURE, |
886 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | 738 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
@@ -888,8 +740,7 @@ int wakeup_device(struct usb_device *pusb_device) | |||
888 | 0, NULL, 0, 50000); | 740 | 0, NULL, 0, 50000); |
889 | } | 741 | } |
890 | /*****************************************************************************/ | 742 | /*****************************************************************************/ |
891 | int | 743 | int easycap_audio_setup(struct easycap *peasycap) |
892 | audio_setup(struct easycap *peasycap) | ||
893 | { | 744 | { |
894 | struct usb_device *pusb_device; | 745 | struct usb_device *pusb_device; |
895 | u8 buffer[1]; | 746 | u8 buffer[1]; |
@@ -970,7 +821,7 @@ audio_setup(struct easycap *peasycap) | |||
970 | * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. | 821 | * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. |
971 | */ | 822 | */ |
972 | /*---------------------------------------------------------------------------*/ | 823 | /*---------------------------------------------------------------------------*/ |
973 | if (0 != audio_gainset(pusb_device, peasycap->gain)) | 824 | if (easycap_audio_gainset(pusb_device, peasycap->gain)) |
974 | SAY("ERROR: audio_gainset() failed\n"); | 825 | SAY("ERROR: audio_gainset() failed\n"); |
975 | check_vt(pusb_device); | 826 | check_vt(pusb_device); |
976 | return 0; | 827 | return 0; |
@@ -1047,7 +898,7 @@ int check_vt(struct usb_device *pusb_device) | |||
1047 | * 31 12.0 22.5 34.5 | 898 | * 31 12.0 22.5 34.5 |
1048 | */ | 899 | */ |
1049 | /*---------------------------------------------------------------------------*/ | 900 | /*---------------------------------------------------------------------------*/ |
1050 | int audio_gainset(struct usb_device *pusb_device, s8 loud) | 901 | int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud) |
1051 | { | 902 | { |
1052 | int igot; | 903 | int igot; |
1053 | u8 tmp; | 904 | u8 tmp; |
@@ -1115,15 +966,3 @@ int audio_gainset(struct usb_device *pusb_device, s8 loud) | |||
1115 | return 0; | 966 | return 0; |
1116 | } | 967 | } |
1117 | /*****************************************************************************/ | 968 | /*****************************************************************************/ |
1118 | int audio_gainget(struct usb_device *pusb_device) | ||
1119 | { | ||
1120 | int igot; | ||
1121 | |||
1122 | if (!pusb_device) | ||
1123 | return -ENODEV; | ||
1124 | igot = read_vt(pusb_device, 0x001C); | ||
1125 | if (0 > igot) | ||
1126 | SAY("ERROR: failed to read VT1612A register 0x1C\n"); | ||
1127 | return igot; | ||
1128 | } | ||
1129 | /*****************************************************************************/ | ||
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index a45c0b507067..8ff5f38ea196 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c | |||
@@ -66,6 +66,10 @@ struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; | |||
66 | static struct mutex mutex_dongle; | 66 | static struct mutex mutex_dongle; |
67 | static void easycap_complete(struct urb *purb); | 67 | static void easycap_complete(struct urb *purb); |
68 | static int reset(struct easycap *peasycap); | 68 | static int reset(struct easycap *peasycap); |
69 | static int field2frame(struct easycap *peasycap); | ||
70 | static int redaub(struct easycap *peasycap, | ||
71 | void *pad, void *pex, int much, int more, | ||
72 | u8 mask, u8 margin, bool isuy); | ||
69 | 73 | ||
70 | const char *strerror(int err) | 74 | const char *strerror(int err) |
71 | { | 75 | { |
@@ -109,23 +113,13 @@ const char *strerror(int err) | |||
109 | #undef ERRNOSTR | 113 | #undef ERRNOSTR |
110 | } | 114 | } |
111 | 115 | ||
112 | /*---------------------------------------------------------------------------*/ | ||
113 | /* | ||
114 | * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE | ||
115 | * | ||
116 | * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY | ||
117 | * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253. | ||
118 | * THIS IS THE CASE FOR OpenSUSE. | ||
119 | */ | ||
120 | /*---------------------------------------------------------------------------*/ | ||
121 | /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ | ||
122 | /****************************************************************************/ | 116 | /****************************************************************************/ |
123 | /*---------------------------------------------------------------------------*/ | 117 | /*---------------------------------------------------------------------------*/ |
124 | /* | 118 | /* |
125 | * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap | 119 | * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap |
126 | */ | 120 | */ |
127 | /*---------------------------------------------------------------------------*/ | 121 | /*---------------------------------------------------------------------------*/ |
128 | int isdongle(struct easycap *peasycap) | 122 | int easycap_isdongle(struct easycap *peasycap) |
129 | { | 123 | { |
130 | int k; | 124 | int k; |
131 | if (!peasycap) | 125 | if (!peasycap) |
@@ -161,14 +155,13 @@ static int easycap_open(struct inode *inode, struct file *file) | |||
161 | if (!peasycap->pusb_device) { | 155 | if (!peasycap->pusb_device) { |
162 | SAM("ERROR: peasycap->pusb_device is NULL\n"); | 156 | SAM("ERROR: peasycap->pusb_device is NULL\n"); |
163 | return -EFAULT; | 157 | return -EFAULT; |
164 | } else { | ||
165 | JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); | ||
166 | } | 158 | } |
159 | |||
160 | JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); | ||
161 | |||
167 | file->private_data = peasycap; | 162 | file->private_data = peasycap; |
168 | rc = wakeup_device(peasycap->pusb_device); | 163 | rc = easycap_wakeup_device(peasycap->pusb_device); |
169 | if (0 == rc) | 164 | if (rc) { |
170 | JOM(8, "wakeup_device() OK\n"); | ||
171 | else { | ||
172 | SAM("ERROR: wakeup_device() rc = %i\n", rc); | 165 | SAM("ERROR: wakeup_device() rc = %i\n", rc); |
173 | if (-ENODEV == rc) | 166 | if (-ENODEV == rc) |
174 | SAM("ERROR: wakeup_device() returned -ENODEV\n"); | 167 | SAM("ERROR: wakeup_device() returned -ENODEV\n"); |
@@ -176,6 +169,7 @@ static int easycap_open(struct inode *inode, struct file *file) | |||
176 | SAM("ERROR: wakeup_device() rc = %i\n", rc); | 169 | SAM("ERROR: wakeup_device() rc = %i\n", rc); |
177 | return rc; | 170 | return rc; |
178 | } | 171 | } |
172 | JOM(8, "wakeup_device() OK\n"); | ||
179 | peasycap->input = 0; | 173 | peasycap->input = 0; |
180 | rc = reset(peasycap); | 174 | rc = reset(peasycap); |
181 | if (rc) { | 175 | if (rc) { |
@@ -303,7 +297,7 @@ static int reset(struct easycap *peasycap) | |||
303 | peasycap->saturation = -8192; | 297 | peasycap->saturation = -8192; |
304 | peasycap->hue = -8192; | 298 | peasycap->hue = -8192; |
305 | 299 | ||
306 | rc = newinput(peasycap, input); | 300 | rc = easycap_newinput(peasycap, input); |
307 | 301 | ||
308 | if (rc) { | 302 | if (rc) { |
309 | SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); | 303 | SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); |
@@ -364,8 +358,7 @@ static int reset(struct easycap *peasycap) | |||
364 | * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE. | 358 | * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE. |
365 | */ | 359 | */ |
366 | /*---------------------------------------------------------------------------*/ | 360 | /*---------------------------------------------------------------------------*/ |
367 | int | 361 | int easycap_newinput(struct easycap *peasycap, int input) |
368 | newinput(struct easycap *peasycap, int input) | ||
369 | { | 362 | { |
370 | int rc, k, m, mood, off; | 363 | int rc, k, m, mood, off; |
371 | int inputnow, video_idlenow, audio_idlenow; | 364 | int inputnow, video_idlenow, audio_idlenow; |
@@ -397,7 +390,7 @@ newinput(struct easycap *peasycap, int input) | |||
397 | peasycap->audio_idle = 1; | 390 | peasycap->audio_idle = 1; |
398 | if (peasycap->video_isoc_streaming) { | 391 | if (peasycap->video_isoc_streaming) { |
399 | resubmit = true; | 392 | resubmit = true; |
400 | kill_video_urbs(peasycap); | 393 | easycap_video_kill_urbs(peasycap); |
401 | } else { | 394 | } else { |
402 | resubmit = false; | 395 | resubmit = false; |
403 | } | 396 | } |
@@ -532,7 +525,7 @@ newinput(struct easycap *peasycap, int input) | |||
532 | return -EFAULT; | 525 | return -EFAULT; |
533 | } | 526 | } |
534 | if (resubmit) | 527 | if (resubmit) |
535 | submit_video_urbs(peasycap); | 528 | easycap_video_submit_urbs(peasycap); |
536 | 529 | ||
537 | peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; | 530 | peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; |
538 | peasycap->video_idle = video_idlenow; | 531 | peasycap->video_idle = video_idlenow; |
@@ -542,7 +535,7 @@ newinput(struct easycap *peasycap, int input) | |||
542 | return 0; | 535 | return 0; |
543 | } | 536 | } |
544 | /*****************************************************************************/ | 537 | /*****************************************************************************/ |
545 | int submit_video_urbs(struct easycap *peasycap) | 538 | int easycap_video_submit_urbs(struct easycap *peasycap) |
546 | { | 539 | { |
547 | struct data_urb *pdata_urb; | 540 | struct data_urb *pdata_urb; |
548 | struct urb *purb; | 541 | struct urb *purb; |
@@ -616,43 +609,53 @@ int submit_video_urbs(struct easycap *peasycap) | |||
616 | peasycap->video_eof = 1; | 609 | peasycap->video_eof = 1; |
617 | } | 610 | } |
618 | 611 | ||
619 | if (isbad) { | 612 | if (isbad) |
620 | JOM(4, "attempting cleanup instead of submitting\n"); | 613 | easycap_video_kill_urbs(peasycap); |
621 | list_for_each(plist_head, (peasycap->purb_video_head)) { | 614 | else |
622 | pdata_urb = list_entry(plist_head, | ||
623 | struct data_urb, list_head); | ||
624 | if (pdata_urb) { | ||
625 | purb = pdata_urb->purb; | ||
626 | if (purb) | ||
627 | usb_kill_urb(purb); | ||
628 | } | ||
629 | } | ||
630 | peasycap->video_isoc_streaming = 0; | ||
631 | } else { | ||
632 | peasycap->video_isoc_streaming = 1; | 615 | peasycap->video_isoc_streaming = 1; |
633 | JOM(4, "submitted %i video urbs\n", m); | ||
634 | } | ||
635 | } else { | 616 | } else { |
636 | JOM(4, "already streaming video urbs\n"); | 617 | JOM(4, "already streaming video urbs\n"); |
637 | } | 618 | } |
638 | return 0; | 619 | return 0; |
639 | } | 620 | } |
640 | /*****************************************************************************/ | 621 | /*****************************************************************************/ |
641 | int kill_video_urbs(struct easycap *peasycap) | 622 | int easycap_audio_kill_urbs(struct easycap *peasycap) |
642 | { | 623 | { |
643 | int m; | 624 | int m; |
644 | struct list_head *plist_head; | 625 | struct list_head *plist_head; |
645 | struct data_urb *pdata_urb; | 626 | struct data_urb *pdata_urb; |
646 | 627 | ||
647 | if (!peasycap) { | 628 | if (!peasycap->audio_isoc_streaming) |
648 | SAY("ERROR: peasycap is NULL\n"); | 629 | return 0; |
630 | |||
631 | if (!peasycap->purb_audio_head) { | ||
632 | SAM("ERROR: peasycap->purb_audio_head is NULL\n"); | ||
649 | return -EFAULT; | 633 | return -EFAULT; |
650 | } | 634 | } |
651 | if (!peasycap->video_isoc_streaming) { | 635 | |
652 | JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", | 636 | peasycap->audio_isoc_streaming = 0; |
653 | peasycap->video_isoc_streaming); | 637 | m = 0; |
654 | return 0; | 638 | list_for_each(plist_head, peasycap->purb_audio_head) { |
639 | pdata_urb = list_entry(plist_head, struct data_urb, list_head); | ||
640 | if (pdata_urb && pdata_urb->purb) { | ||
641 | usb_kill_urb(pdata_urb->purb); | ||
642 | m++; | ||
643 | } | ||
655 | } | 644 | } |
645 | |||
646 | JOM(4, "%i audio urbs killed\n", m); | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | int easycap_video_kill_urbs(struct easycap *peasycap) | ||
651 | { | ||
652 | int m; | ||
653 | struct list_head *plist_head; | ||
654 | struct data_urb *pdata_urb; | ||
655 | |||
656 | if (!peasycap->video_isoc_streaming) | ||
657 | return 0; | ||
658 | |||
656 | if (!peasycap->purb_video_head) { | 659 | if (!peasycap->purb_video_head) { |
657 | SAM("ERROR: peasycap->purb_video_head is NULL\n"); | 660 | SAM("ERROR: peasycap->purb_video_head is NULL\n"); |
658 | return -EFAULT; | 661 | return -EFAULT; |
@@ -690,8 +693,8 @@ static int videodev_release(struct video_device *pvideo_device) | |||
690 | SAY("ending unsuccessfully\n"); | 693 | SAY("ending unsuccessfully\n"); |
691 | return -EFAULT; | 694 | return -EFAULT; |
692 | } | 695 | } |
693 | if (0 != kill_video_urbs(peasycap)) { | 696 | if (easycap_video_kill_urbs(peasycap)) { |
694 | SAM("ERROR: kill_video_urbs() failed\n"); | 697 | SAM("ERROR: easycap_video_kill_urbs() failed\n"); |
695 | return -EFAULT; | 698 | return -EFAULT; |
696 | } | 699 | } |
697 | JOM(4, "ending successfully\n"); | 700 | JOM(4, "ending successfully\n"); |
@@ -727,27 +730,22 @@ static void easycap_delete(struct kref *pkref) | |||
727 | SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); | 730 | SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); |
728 | return; | 731 | return; |
729 | } | 732 | } |
730 | kd = isdongle(peasycap); | 733 | kd = easycap_isdongle(peasycap); |
731 | /*---------------------------------------------------------------------------*/ | 734 | /*---------------------------------------------------------------------------*/ |
732 | /* | 735 | /* |
733 | * FREE VIDEO. | 736 | * FREE VIDEO. |
734 | */ | 737 | */ |
735 | /*---------------------------------------------------------------------------*/ | 738 | /*---------------------------------------------------------------------------*/ |
736 | if (peasycap->purb_video_head) { | 739 | if (peasycap->purb_video_head) { |
737 | JOM(4, "freeing video urbs\n"); | ||
738 | m = 0; | 740 | m = 0; |
739 | list_for_each(plist_head, (peasycap->purb_video_head)) { | 741 | list_for_each(plist_head, peasycap->purb_video_head) { |
740 | pdata_urb = list_entry(plist_head, | 742 | pdata_urb = list_entry(plist_head, |
741 | struct data_urb, list_head); | 743 | struct data_urb, list_head); |
742 | if (!pdata_urb) { | 744 | if (pdata_urb && pdata_urb->purb) { |
743 | JOM(4, "ERROR: pdata_urb is NULL\n"); | 745 | usb_free_urb(pdata_urb->purb); |
744 | } else { | 746 | pdata_urb->purb = NULL; |
745 | if (pdata_urb->purb) { | 747 | peasycap->allocation_video_urb--; |
746 | usb_free_urb(pdata_urb->purb); | 748 | m++; |
747 | pdata_urb->purb = NULL; | ||
748 | peasycap->allocation_video_urb -= 1; | ||
749 | m++; | ||
750 | } | ||
751 | } | 749 | } |
752 | } | 750 | } |
753 | 751 | ||
@@ -763,7 +761,6 @@ static void easycap_delete(struct kref *pkref) | |||
763 | peasycap->allocation_video_struct -= | 761 | peasycap->allocation_video_struct -= |
764 | sizeof(struct data_urb); | 762 | sizeof(struct data_urb); |
765 | kfree(pdata_urb); | 763 | kfree(pdata_urb); |
766 | pdata_urb = NULL; | ||
767 | m++; | 764 | m++; |
768 | } | 765 | } |
769 | } | 766 | } |
@@ -828,15 +825,11 @@ static void easycap_delete(struct kref *pkref) | |||
828 | list_for_each(plist_head, (peasycap->purb_audio_head)) { | 825 | list_for_each(plist_head, (peasycap->purb_audio_head)) { |
829 | pdata_urb = list_entry(plist_head, | 826 | pdata_urb = list_entry(plist_head, |
830 | struct data_urb, list_head); | 827 | struct data_urb, list_head); |
831 | if (!pdata_urb) | 828 | if (pdata_urb && pdata_urb->purb) { |
832 | JOM(4, "ERROR: pdata_urb is NULL\n"); | 829 | usb_free_urb(pdata_urb->purb); |
833 | else { | 830 | pdata_urb->purb = NULL; |
834 | if (pdata_urb->purb) { | 831 | peasycap->allocation_audio_urb--; |
835 | usb_free_urb(pdata_urb->purb); | 832 | m++; |
836 | pdata_urb->purb = NULL; | ||
837 | peasycap->allocation_audio_urb -= 1; | ||
838 | m++; | ||
839 | } | ||
840 | } | 833 | } |
841 | } | 834 | } |
842 | JOM(4, "%i audio urbs freed\n", m); | 835 | JOM(4, "%i audio urbs freed\n", m); |
@@ -851,7 +844,6 @@ static void easycap_delete(struct kref *pkref) | |||
851 | peasycap->allocation_audio_struct -= | 844 | peasycap->allocation_audio_struct -= |
852 | sizeof(struct data_urb); | 845 | sizeof(struct data_urb); |
853 | kfree(pdata_urb); | 846 | kfree(pdata_urb); |
854 | pdata_urb = NULL; | ||
855 | m++; | 847 | m++; |
856 | } | 848 | } |
857 | } | 849 | } |
@@ -940,7 +932,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) | |||
940 | return -EFAULT; | 932 | return -EFAULT; |
941 | } | 933 | } |
942 | /*---------------------------------------------------------------------------*/ | 934 | /*---------------------------------------------------------------------------*/ |
943 | kd = isdongle(peasycap); | 935 | kd = easycap_isdongle(peasycap); |
944 | if (0 <= kd && DONGLE_MANY > kd) { | 936 | if (0 <= kd && DONGLE_MANY > kd) { |
945 | if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { | 937 | if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { |
946 | SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); | 938 | SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); |
@@ -952,7 +944,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) | |||
952 | * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. | 944 | * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. |
953 | * IF NECESSARY, BAIL OUT. | 945 | * IF NECESSARY, BAIL OUT. |
954 | */ | 946 | */ |
955 | if (kd != isdongle(peasycap)) { | 947 | if (kd != easycap_isdongle(peasycap)) { |
956 | mutex_unlock(&easycapdc60_dongle[kd].mutex_video); | 948 | mutex_unlock(&easycapdc60_dongle[kd].mutex_video); |
957 | return -ERESTARTSYS; | 949 | return -ERESTARTSYS; |
958 | } | 950 | } |
@@ -980,21 +972,21 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) | |||
980 | */ | 972 | */ |
981 | return -ERESTARTSYS; | 973 | return -ERESTARTSYS; |
982 | /*---------------------------------------------------------------------------*/ | 974 | /*---------------------------------------------------------------------------*/ |
983 | rc = easycap_dqbuf(peasycap, 0); | 975 | rc = easycap_video_dqbuf(peasycap, 0); |
984 | peasycap->polled = 1; | 976 | peasycap->polled = 1; |
985 | mutex_unlock(&easycapdc60_dongle[kd].mutex_video); | 977 | mutex_unlock(&easycapdc60_dongle[kd].mutex_video); |
986 | if (0 == rc) | 978 | if (rc) |
987 | return POLLIN | POLLRDNORM; | ||
988 | else | ||
989 | return POLLERR; | 979 | return POLLERR; |
990 | } | 980 | |
981 | return POLLIN | POLLRDNORM; | ||
982 | } | ||
991 | /*****************************************************************************/ | 983 | /*****************************************************************************/ |
992 | /*---------------------------------------------------------------------------*/ | 984 | /*---------------------------------------------------------------------------*/ |
993 | /* | 985 | /* |
994 | * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. | 986 | * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. |
995 | */ | 987 | */ |
996 | /*---------------------------------------------------------------------------*/ | 988 | /*---------------------------------------------------------------------------*/ |
997 | int easycap_dqbuf(struct easycap *peasycap, int mode) | 989 | int easycap_video_dqbuf(struct easycap *peasycap, int mode) |
998 | { | 990 | { |
999 | int input, ifield, miss, rc; | 991 | int input, ifield, miss, rc; |
1000 | 992 | ||
@@ -1080,7 +1072,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) | |||
1080 | JOM(8, " ... failed returning -EIO\n"); | 1072 | JOM(8, " ... failed returning -EIO\n"); |
1081 | peasycap->video_eof = 1; | 1073 | peasycap->video_eof = 1; |
1082 | peasycap->audio_eof = 1; | 1074 | peasycap->audio_eof = 1; |
1083 | kill_video_urbs(peasycap); | 1075 | easycap_video_kill_urbs(peasycap); |
1084 | return -EIO; | 1076 | return -EIO; |
1085 | } | 1077 | } |
1086 | peasycap->status = 0; | 1078 | peasycap->status = 0; |
@@ -1090,7 +1082,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) | |||
1090 | #endif /*PERSEVERE*/ | 1082 | #endif /*PERSEVERE*/ |
1091 | peasycap->video_eof = 1; | 1083 | peasycap->video_eof = 1; |
1092 | peasycap->audio_eof = 1; | 1084 | peasycap->audio_eof = 1; |
1093 | kill_video_urbs(peasycap); | 1085 | easycap_video_kill_urbs(peasycap); |
1094 | JOM(8, "returning -EIO\n"); | 1086 | JOM(8, "returning -EIO\n"); |
1095 | return -EIO; | 1087 | return -EIO; |
1096 | } | 1088 | } |
@@ -1143,7 +1135,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) | |||
1143 | JOM(8, " ... failed returning -EIO\n"); | 1135 | JOM(8, " ... failed returning -EIO\n"); |
1144 | peasycap->video_eof = 1; | 1136 | peasycap->video_eof = 1; |
1145 | peasycap->audio_eof = 1; | 1137 | peasycap->audio_eof = 1; |
1146 | kill_video_urbs(peasycap); | 1138 | easycap_video_kill_urbs(peasycap); |
1147 | return -EIO; | 1139 | return -EIO; |
1148 | } | 1140 | } |
1149 | peasycap->status = 0; | 1141 | peasycap->status = 0; |
@@ -1153,7 +1145,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) | |||
1153 | #endif /*PERSEVERE*/ | 1145 | #endif /*PERSEVERE*/ |
1154 | peasycap->video_eof = 1; | 1146 | peasycap->video_eof = 1; |
1155 | peasycap->audio_eof = 1; | 1147 | peasycap->audio_eof = 1; |
1156 | kill_video_urbs(peasycap); | 1148 | easycap_video_kill_urbs(peasycap); |
1157 | JOM(8, "returning -EIO\n"); | 1149 | JOM(8, "returning -EIO\n"); |
1158 | return -EIO; | 1150 | return -EIO; |
1159 | } | 1151 | } |
@@ -1207,12 +1199,9 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) | |||
1207 | * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH | 1199 | * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH |
1208 | * odd==false IS TRANSFERRED TO THE FRAME BUFFER. | 1200 | * odd==false IS TRANSFERRED TO THE FRAME BUFFER. |
1209 | * | 1201 | * |
1210 | * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM | ||
1211 | * CHOOSES THE OPTION V4L2_FIELD_INTERLACED. | ||
1212 | */ | 1202 | */ |
1213 | /*---------------------------------------------------------------------------*/ | 1203 | /*---------------------------------------------------------------------------*/ |
1214 | int | 1204 | static int field2frame(struct easycap *peasycap) |
1215 | field2frame(struct easycap *peasycap) | ||
1216 | { | 1205 | { |
1217 | 1206 | ||
1218 | void *pex, *pad; | 1207 | void *pex, *pad; |
@@ -1221,7 +1210,7 @@ field2frame(struct easycap *peasycap) | |||
1221 | int rc, bytesperpixel, multiplier; | 1210 | int rc, bytesperpixel, multiplier; |
1222 | int much, more, over, rump, caches, input; | 1211 | int much, more, over, rump, caches, input; |
1223 | u8 mask, margin; | 1212 | u8 mask, margin; |
1224 | bool odd, isuy, decimatepixel, offerfields, badinput; | 1213 | bool odd, isuy, decimatepixel, badinput; |
1225 | 1214 | ||
1226 | if (!peasycap) { | 1215 | if (!peasycap) { |
1227 | SAY("ERROR: peasycap is NULL\n"); | 1216 | SAY("ERROR: peasycap is NULL\n"); |
@@ -1237,8 +1226,6 @@ field2frame(struct easycap *peasycap) | |||
1237 | peasycap->field_buffer[peasycap->field_read][0].input, | 1226 | peasycap->field_buffer[peasycap->field_read][0].input, |
1238 | peasycap->field_read, peasycap->frame_fill); | 1227 | peasycap->field_read, peasycap->frame_fill); |
1239 | JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); | 1228 | JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); |
1240 | if (peasycap->offerfields) | ||
1241 | JOM(8, "===== offerfields\n"); | ||
1242 | 1229 | ||
1243 | /*---------------------------------------------------------------------------*/ | 1230 | /*---------------------------------------------------------------------------*/ |
1244 | /* | 1231 | /* |
@@ -1260,7 +1247,6 @@ field2frame(struct easycap *peasycap) | |||
1260 | #endif /*EASYCAP_TESTCARD*/ | 1247 | #endif /*EASYCAP_TESTCARD*/ |
1261 | /*---------------------------------------------------------------------------*/ | 1248 | /*---------------------------------------------------------------------------*/ |
1262 | 1249 | ||
1263 | offerfields = peasycap->offerfields; | ||
1264 | bytesperpixel = peasycap->bytesperpixel; | 1250 | bytesperpixel = peasycap->bytesperpixel; |
1265 | decimatepixel = peasycap->decimatepixel; | 1251 | decimatepixel = peasycap->decimatepixel; |
1266 | 1252 | ||
@@ -1601,9 +1587,9 @@ field2frame(struct easycap *peasycap) | |||
1601 | * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE. | 1587 | * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE. |
1602 | */ | 1588 | */ |
1603 | /*---------------------------------------------------------------------------*/ | 1589 | /*---------------------------------------------------------------------------*/ |
1604 | int | 1590 | static int redaub(struct easycap *peasycap, |
1605 | redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, | 1591 | void *pad, void *pex, int much, int more, |
1606 | u8 mask, u8 margin, bool isuy) | 1592 | u8 mask, u8 margin, bool isuy) |
1607 | { | 1593 | { |
1608 | static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; | 1594 | static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; |
1609 | u8 *pcache; | 1595 | u8 *pcache; |
@@ -2855,20 +2841,7 @@ static void easycap_complete(struct urb *purb) | |||
2855 | } | 2841 | } |
2856 | return; | 2842 | return; |
2857 | } | 2843 | } |
2858 | static const struct file_operations easycap_fops = { | 2844 | |
2859 | .owner = THIS_MODULE, | ||
2860 | .open = easycap_open, | ||
2861 | .unlocked_ioctl = easycap_unlocked_ioctl, | ||
2862 | .poll = easycap_poll, | ||
2863 | .mmap = easycap_mmap, | ||
2864 | .llseek = no_llseek, | ||
2865 | }; | ||
2866 | static const struct usb_class_driver easycap_class = { | ||
2867 | .name = "usb/easycap%d", | ||
2868 | .fops = &easycap_fops, | ||
2869 | .minor_base = USB_SKEL_MINOR_BASE, | ||
2870 | }; | ||
2871 | /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ | ||
2872 | static const struct v4l2_file_operations v4l2_fops = { | 2845 | static const struct v4l2_file_operations v4l2_fops = { |
2873 | .owner = THIS_MODULE, | 2846 | .owner = THIS_MODULE, |
2874 | .open = easycap_open_noinode, | 2847 | .open = easycap_open_noinode, |
@@ -2917,6 +2890,7 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
2917 | SAY("ERROR: usb_host_interface not found\n"); | 2890 | SAY("ERROR: usb_host_interface not found\n"); |
2918 | return -EFAULT; | 2891 | return -EFAULT; |
2919 | } | 2892 | } |
2893 | |||
2920 | interface = &alt->desc; | 2894 | interface = &alt->desc; |
2921 | if (!interface) { | 2895 | if (!interface) { |
2922 | SAY("ERROR: intf_descriptor is NULL\n"); | 2896 | SAY("ERROR: intf_descriptor is NULL\n"); |
@@ -2976,44 +2950,31 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
2976 | if (mutex_lock_interruptible(&mutex_dongle)) { | 2950 | if (mutex_lock_interruptible(&mutex_dongle)) { |
2977 | SAY("ERROR: cannot down mutex_dongle\n"); | 2951 | SAY("ERROR: cannot down mutex_dongle\n"); |
2978 | return -ERESTARTSYS; | 2952 | return -ERESTARTSYS; |
2979 | } else { | 2953 | } |
2980 | /*---------------------------------------------------------------------------*/ | 2954 | |
2981 | /* | 2955 | for (ndong = 0; ndong < DONGLE_MANY; ndong++) { |
2982 | * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO | 2956 | if ((!easycapdc60_dongle[ndong].peasycap) && |
2983 | * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0. | 2957 | (!mutex_is_locked(&easycapdc60_dongle |
2984 | * | 2958 | [ndong].mutex_video)) && |
2985 | * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS | 2959 | (!mutex_is_locked(&easycapdc60_dongle |
2986 | * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO | 2960 | [ndong].mutex_audio))) { |
2987 | * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY. | 2961 | easycapdc60_dongle[ndong].peasycap = peasycap; |
2988 | */ | 2962 | peasycap->isdongle = ndong; |
2989 | /*---------------------------------------------------------------------------*/ | 2963 | JOM(8, "intf[%i]: peasycap-->easycap" |
2990 | for (ndong = 0; ndong < DONGLE_MANY; ndong++) { | 2964 | "_dongle[%i].peasycap\n", |
2991 | if ((!easycapdc60_dongle[ndong].peasycap) && | 2965 | bInterfaceNumber, ndong); |
2992 | (!mutex_is_locked(&easycapdc60_dongle | 2966 | break; |
2993 | [ndong].mutex_video)) && | ||
2994 | (!mutex_is_locked(&easycapdc60_dongle | ||
2995 | [ndong].mutex_audio))) { | ||
2996 | easycapdc60_dongle[ndong].peasycap = peasycap; | ||
2997 | peasycap->isdongle = ndong; | ||
2998 | JOM(8, "intf[%i]: peasycap-->easycap" | ||
2999 | "_dongle[%i].peasycap\n", | ||
3000 | bInterfaceNumber, ndong); | ||
3001 | break; | ||
3002 | } | ||
3003 | } | ||
3004 | if (DONGLE_MANY <= ndong) { | ||
3005 | SAM("ERROR: too many dongles\n"); | ||
3006 | mutex_unlock(&mutex_dongle); | ||
3007 | return -ENOMEM; | ||
3008 | } | 2967 | } |
2968 | } | ||
2969 | |||
2970 | if (DONGLE_MANY <= ndong) { | ||
2971 | SAM("ERROR: too many dongles\n"); | ||
3009 | mutex_unlock(&mutex_dongle); | 2972 | mutex_unlock(&mutex_dongle); |
2973 | return -ENOMEM; | ||
3010 | } | 2974 | } |
2975 | mutex_unlock(&mutex_dongle); | ||
2976 | |||
3011 | peasycap->allocation_video_struct = sizeof(struct easycap); | 2977 | peasycap->allocation_video_struct = sizeof(struct easycap); |
3012 | peasycap->allocation_video_page = 0; | ||
3013 | peasycap->allocation_video_urb = 0; | ||
3014 | peasycap->allocation_audio_struct = 0; | ||
3015 | peasycap->allocation_audio_page = 0; | ||
3016 | peasycap->allocation_audio_urb = 0; | ||
3017 | 2978 | ||
3018 | /*---------------------------------------------------------------------------*/ | 2979 | /*---------------------------------------------------------------------------*/ |
3019 | /* | 2980 | /* |
@@ -3023,7 +2984,6 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3023 | peasycap->pusb_device = usbdev; | 2984 | peasycap->pusb_device = usbdev; |
3024 | peasycap->pusb_interface = intf; | 2985 | peasycap->pusb_interface = intf; |
3025 | 2986 | ||
3026 | peasycap->ilk = 0; | ||
3027 | peasycap->microphone = false; | 2987 | peasycap->microphone = false; |
3028 | 2988 | ||
3029 | peasycap->video_interface = -1; | 2989 | peasycap->video_interface = -1; |
@@ -3042,38 +3002,21 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3042 | 3002 | ||
3043 | peasycap->frame_buffer_many = FRAME_BUFFER_MANY; | 3003 | peasycap->frame_buffer_many = FRAME_BUFFER_MANY; |
3044 | 3004 | ||
3045 | for (k = 0; k < INPUT_MANY; k++) | ||
3046 | peasycap->lost[k] = 0; | ||
3047 | peasycap->skip = 0; | ||
3048 | peasycap->skipped = 0; | ||
3049 | peasycap->offerfields = 0; | ||
3050 | /*---------------------------------------------------------------------------*/ | 3005 | /*---------------------------------------------------------------------------*/ |
3051 | /* | 3006 | /* |
3052 | * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... | 3007 | * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... |
3053 | */ | 3008 | */ |
3054 | /*---------------------------------------------------------------------------*/ | 3009 | /*---------------------------------------------------------------------------*/ |
3055 | rc = fillin_formats(); | 3010 | rc = easycap_video_fillin_formats(); |
3056 | if (0 > rc) { | 3011 | if (0 > rc) { |
3057 | SAM("ERROR: fillin_formats() rc = %i\n", rc); | 3012 | SAM("ERROR: fillin_formats() rc = %i\n", rc); |
3058 | return -EFAULT; | 3013 | return -EFAULT; |
3059 | } | 3014 | } |
3060 | JOM(4, "%i formats available\n", rc); | 3015 | JOM(4, "%i formats available\n", rc); |
3061 | /*---------------------------------------------------------------------------*/ | 3016 | |
3062 | /* | 3017 | /* ... AND POPULATE easycap.inputset[] */ |
3063 | * ... AND POPULATE easycap.inputset[] | 3018 | |
3064 | */ | ||
3065 | /*---------------------------------------------------------------------------*/ | ||
3066 | /* FIXME: maybe we just use memset 0 */ | ||
3067 | inputset = peasycap->inputset; | 3019 | inputset = peasycap->inputset; |
3068 | for (k = 0; k < INPUT_MANY; k++) { | ||
3069 | inputset[k].input_ok = 0; | ||
3070 | inputset[k].standard_offset_ok = 0; | ||
3071 | inputset[k].format_offset_ok = 0; | ||
3072 | inputset[k].brightness_ok = 0; | ||
3073 | inputset[k].contrast_ok = 0; | ||
3074 | inputset[k].saturation_ok = 0; | ||
3075 | inputset[k].hue_ok = 0; | ||
3076 | } | ||
3077 | 3020 | ||
3078 | fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; | 3021 | fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; |
3079 | m = 0; | 3022 | m = 0; |
@@ -3390,11 +3333,10 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3390 | if (!isokalt) { | 3333 | if (!isokalt) { |
3391 | SAM("ERROR: no viable video_altsetting_on\n"); | 3334 | SAM("ERROR: no viable video_altsetting_on\n"); |
3392 | return -ENOENT; | 3335 | return -ENOENT; |
3393 | } else { | ||
3394 | peasycap->video_altsetting_on = okalt[isokalt - 1]; | ||
3395 | JOM(4, "%i=video_altsetting_on <====\n", | ||
3396 | peasycap->video_altsetting_on); | ||
3397 | } | 3336 | } |
3337 | peasycap->video_altsetting_on = okalt[isokalt - 1]; | ||
3338 | JOM(4, "%i=video_altsetting_on <====\n", | ||
3339 | peasycap->video_altsetting_on); | ||
3398 | /*---------------------------------------------------------------------------*/ | 3340 | /*---------------------------------------------------------------------------*/ |
3399 | /* | 3341 | /* |
3400 | * DECIDE THE VIDEO STREAMING PARAMETERS | 3342 | * DECIDE THE VIDEO STREAMING PARAMETERS |
@@ -3480,8 +3422,9 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3480 | SAM("ERROR: Could not allocate frame " | 3422 | SAM("ERROR: Could not allocate frame " |
3481 | "buffer %i page %i\n", k, m); | 3423 | "buffer %i page %i\n", k, m); |
3482 | return -ENOMEM; | 3424 | return -ENOMEM; |
3483 | } else | 3425 | } |
3484 | peasycap->allocation_video_page += 1; | 3426 | |
3427 | peasycap->allocation_video_page += 1; | ||
3485 | peasycap->frame_buffer[k][m].pgo = pbuf; | 3428 | peasycap->frame_buffer[k][m].pgo = pbuf; |
3486 | } | 3429 | } |
3487 | peasycap->frame_buffer[k][m].pto = | 3430 | peasycap->frame_buffer[k][m].pto = |
@@ -3510,11 +3453,11 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3510 | SAM("ERROR: Could not allocate field" | 3453 | SAM("ERROR: Could not allocate field" |
3511 | " buffer %i page %i\n", k, m); | 3454 | " buffer %i page %i\n", k, m); |
3512 | return -ENOMEM; | 3455 | return -ENOMEM; |
3513 | } | ||
3514 | else | ||
3515 | peasycap->allocation_video_page += 1; | ||
3516 | peasycap->field_buffer[k][m].pgo = pbuf; | ||
3517 | } | 3456 | } |
3457 | |||
3458 | peasycap->allocation_video_page += 1; | ||
3459 | peasycap->field_buffer[k][m].pgo = pbuf; | ||
3460 | } | ||
3518 | peasycap->field_buffer[k][m].pto = | 3461 | peasycap->field_buffer[k][m].pto = |
3519 | peasycap->field_buffer[k][m].pgo; | 3462 | peasycap->field_buffer[k][m].pgo; |
3520 | } | 3463 | } |
@@ -3538,9 +3481,9 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3538 | SAM("ERROR: Could not allocate isoc video buffer " | 3481 | SAM("ERROR: Could not allocate isoc video buffer " |
3539 | "%i\n", k); | 3482 | "%i\n", k); |
3540 | return -ENOMEM; | 3483 | return -ENOMEM; |
3541 | } else | 3484 | } |
3542 | peasycap->allocation_video_page += | 3485 | peasycap->allocation_video_page += |
3543 | BIT(VIDEO_ISOC_ORDER); | 3486 | BIT(VIDEO_ISOC_ORDER); |
3544 | 3487 | ||
3545 | peasycap->video_isoc_buffer[k].pgo = pbuf; | 3488 | peasycap->video_isoc_buffer[k].pgo = pbuf; |
3546 | peasycap->video_isoc_buffer[k].pto = | 3489 | peasycap->video_isoc_buffer[k].pto = |
@@ -3569,15 +3512,17 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3569 | SAM("ERROR: usb_alloc_urb returned NULL for buffer " | 3512 | SAM("ERROR: usb_alloc_urb returned NULL for buffer " |
3570 | "%i\n", k); | 3513 | "%i\n", k); |
3571 | return -ENOMEM; | 3514 | return -ENOMEM; |
3572 | } else | 3515 | } |
3573 | peasycap->allocation_video_urb += 1; | 3516 | |
3517 | peasycap->allocation_video_urb += 1; | ||
3574 | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 3518 | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
3575 | pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); | 3519 | pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); |
3576 | if (!pdata_urb) { | 3520 | if (!pdata_urb) { |
3577 | SAM("ERROR: Could not allocate struct data_urb.\n"); | 3521 | SAM("ERROR: Could not allocate struct data_urb.\n"); |
3578 | return -ENOMEM; | 3522 | return -ENOMEM; |
3579 | } else | 3523 | } |
3580 | peasycap->allocation_video_struct += | 3524 | |
3525 | peasycap->allocation_video_struct += | ||
3581 | sizeof(struct data_urb); | 3526 | sizeof(struct data_urb); |
3582 | 3527 | ||
3583 | pdata_urb->purb = purb; | 3528 | pdata_urb->purb = purb; |
@@ -3694,13 +3639,12 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3694 | err("Not able to register with videodev"); | 3639 | err("Not able to register with videodev"); |
3695 | videodev_release(&(peasycap->video_device)); | 3640 | videodev_release(&(peasycap->video_device)); |
3696 | return -ENODEV; | 3641 | return -ENODEV; |
3697 | } else { | ||
3698 | (peasycap->registered_video)++; | ||
3699 | SAM("registered with videodev: %i=minor\n", | ||
3700 | peasycap->video_device.minor); | ||
3701 | peasycap->minor = peasycap->video_device.minor; | ||
3702 | } | 3642 | } |
3703 | /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ | 3643 | |
3644 | peasycap->registered_video++; | ||
3645 | SAM("registered with videodev: %i=minor\n", | ||
3646 | peasycap->video_device.minor); | ||
3647 | peasycap->minor = peasycap->video_device.minor; | ||
3704 | 3648 | ||
3705 | break; | 3649 | break; |
3706 | } | 3650 | } |
@@ -3734,11 +3678,10 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3734 | if (!isokalt) { | 3678 | if (!isokalt) { |
3735 | SAM("ERROR: no viable audio_altsetting_on\n"); | 3679 | SAM("ERROR: no viable audio_altsetting_on\n"); |
3736 | return -ENOENT; | 3680 | return -ENOENT; |
3737 | } else { | ||
3738 | peasycap->audio_altsetting_on = okalt[isokalt - 1]; | ||
3739 | JOM(4, "%i=audio_altsetting_on <====\n", | ||
3740 | peasycap->audio_altsetting_on); | ||
3741 | } | 3681 | } |
3682 | peasycap->audio_altsetting_on = okalt[isokalt - 1]; | ||
3683 | JOM(4, "%i=audio_altsetting_on <====\n", | ||
3684 | peasycap->audio_altsetting_on); | ||
3742 | 3685 | ||
3743 | peasycap->audio_endpointnumber = okepn[isokalt - 1]; | 3686 | peasycap->audio_endpointnumber = okepn[isokalt - 1]; |
3744 | JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); | 3687 | JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); |
@@ -3847,8 +3790,8 @@ static int easycap_usb_probe(struct usb_interface *intf, | |||
3847 | SAM("ERROR: Could not allocate isoc audio buffer " | 3790 | SAM("ERROR: Could not allocate isoc audio buffer " |
3848 | "%i\n", k); | 3791 | "%i\n", k); |
3849 | return -ENOMEM; | 3792 | return -ENOMEM; |
3850 | } else | 3793 | } |
3851 | peasycap->allocation_audio_page += | 3794 | peasycap->allocation_audio_page += |
3852 | BIT(AUDIO_ISOC_ORDER); | 3795 | BIT(AUDIO_ISOC_ORDER); |
3853 | 3796 | ||
3854 | peasycap->audio_isoc_buffer[k].pgo = pbuf; | 3797 | peasycap->audio_isoc_buffer[k].pgo = pbuf; |
@@ -3996,12 +3939,9 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) | |||
3996 | { | 3939 | { |
3997 | struct usb_host_interface *pusb_host_interface; | 3940 | struct usb_host_interface *pusb_host_interface; |
3998 | struct usb_interface_descriptor *pusb_interface_descriptor; | 3941 | struct usb_interface_descriptor *pusb_interface_descriptor; |
3999 | u8 bInterfaceNumber; | ||
4000 | struct easycap *peasycap; | 3942 | struct easycap *peasycap; |
4001 | 3943 | int minor, kd; | |
4002 | struct list_head *plist_head; | 3944 | u8 bInterfaceNumber; |
4003 | struct data_urb *pdata_urb; | ||
4004 | int minor, m, kd; | ||
4005 | 3945 | ||
4006 | JOT(4, "\n"); | 3946 | JOT(4, "\n"); |
4007 | 3947 | ||
@@ -4036,45 +3976,14 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) | |||
4036 | peasycap->audio_eof = 1; | 3976 | peasycap->audio_eof = 1; |
4037 | wake_up_interruptible(&(peasycap->wq_video)); | 3977 | wake_up_interruptible(&(peasycap->wq_video)); |
4038 | wake_up_interruptible(&(peasycap->wq_audio)); | 3978 | wake_up_interruptible(&(peasycap->wq_audio)); |
4039 | /*---------------------------------------------------------------------------*/ | 3979 | |
4040 | switch (bInterfaceNumber) { | 3980 | switch (bInterfaceNumber) { |
4041 | case 0: { | 3981 | case 0: |
4042 | if (peasycap->purb_video_head) { | 3982 | easycap_video_kill_urbs(peasycap); |
4043 | JOM(4, "killing video urbs\n"); | ||
4044 | m = 0; | ||
4045 | list_for_each(plist_head, peasycap->purb_video_head) { | ||
4046 | pdata_urb = list_entry(plist_head, | ||
4047 | struct data_urb, list_head); | ||
4048 | if (pdata_urb) { | ||
4049 | if (pdata_urb->purb) { | ||
4050 | usb_kill_urb(pdata_urb->purb); | ||
4051 | m++; | ||
4052 | } | ||
4053 | } | ||
4054 | } | ||
4055 | JOM(4, "%i video urbs killed\n", m); | ||
4056 | } | ||
4057 | break; | 3983 | break; |
4058 | } | 3984 | case 2: |
4059 | /*---------------------------------------------------------------------------*/ | 3985 | easycap_audio_kill_urbs(peasycap); |
4060 | case 2: { | ||
4061 | if (peasycap->purb_audio_head) { | ||
4062 | JOM(4, "killing audio urbs\n"); | ||
4063 | m = 0; | ||
4064 | list_for_each(plist_head, peasycap->purb_audio_head) { | ||
4065 | pdata_urb = list_entry(plist_head, | ||
4066 | struct data_urb, list_head); | ||
4067 | if (pdata_urb) { | ||
4068 | if (pdata_urb->purb) { | ||
4069 | usb_kill_urb(pdata_urb->purb); | ||
4070 | m++; | ||
4071 | } | ||
4072 | } | ||
4073 | } | ||
4074 | JOM(4, "%i audio urbs killed\n", m); | ||
4075 | } | ||
4076 | break; | 3986 | break; |
4077 | } | ||
4078 | default: | 3987 | default: |
4079 | break; | 3988 | break; |
4080 | } | 3989 | } |
@@ -4087,7 +3996,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) | |||
4087 | * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. | 3996 | * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. |
4088 | */ | 3997 | */ |
4089 | /*--------------------------------------------------------------------------*/ | 3998 | /*--------------------------------------------------------------------------*/ |
4090 | kd = isdongle(peasycap); | 3999 | kd = easycap_isdongle(peasycap); |
4091 | switch (bInterfaceNumber) { | 4000 | switch (bInterfaceNumber) { |
4092 | case 0: { | 4001 | case 0: { |
4093 | if (0 <= kd && DONGLE_MANY > kd) { | 4002 | if (0 <= kd && DONGLE_MANY > kd) { |
@@ -4212,7 +4121,7 @@ static struct usb_device_id easycap_usb_device_id_table[] = { | |||
4212 | }; | 4121 | }; |
4213 | 4122 | ||
4214 | MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); | 4123 | MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); |
4215 | struct usb_driver easycap_usb_driver = { | 4124 | static struct usb_driver easycap_usb_driver = { |
4216 | .name = "easycap", | 4125 | .name = "easycap", |
4217 | .id_table = easycap_usb_device_id_table, | 4126 | .id_table = easycap_usb_device_id_table, |
4218 | .probe = easycap_usb_probe, | 4127 | .probe = easycap_usb_probe, |
diff --git a/drivers/staging/media/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c index 70f59b13c34d..3f5f5b3e5a35 100644 --- a/drivers/staging/media/easycap/easycap_settings.c +++ b/drivers/staging/media/easycap/easycap_settings.c | |||
@@ -313,7 +313,7 @@ const struct easycap_standard easycap_standard[] = { | |||
313 | 313 | ||
314 | struct easycap_format easycap_format[1 + SETTINGS_MANY]; | 314 | struct easycap_format easycap_format[1 + SETTINGS_MANY]; |
315 | 315 | ||
316 | int fillin_formats(void) | 316 | int easycap_video_fillin_formats(void) |
317 | { | 317 | { |
318 | const char *name1, *name2, *name3, *name4; | 318 | const char *name1, *name2, *name3, *name4; |
319 | struct v4l2_format *fmt; | 319 | struct v4l2_format *fmt; |
diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c index b22bb39b5f69..8c8bcae8ded8 100644 --- a/drivers/staging/media/easycap/easycap_sound.c +++ b/drivers/staging/media/easycap/easycap_sound.c | |||
@@ -56,6 +56,141 @@ static const struct snd_pcm_hardware alsa_hardware = { | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | 58 | ||
59 | /*---------------------------------------------------------------------------*/ | ||
60 | /* | ||
61 | * SUBMIT ALL AUDIO URBS. | ||
62 | */ | ||
63 | /*---------------------------------------------------------------------------*/ | ||
64 | static int easycap_audio_submit_urbs(struct easycap *peasycap) | ||
65 | { | ||
66 | struct data_urb *pdata_urb; | ||
67 | struct urb *purb; | ||
68 | struct list_head *plist_head; | ||
69 | int j, isbad, nospc, m, rc; | ||
70 | int isbuf; | ||
71 | |||
72 | if (!peasycap->purb_audio_head) { | ||
73 | SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); | ||
74 | return -EFAULT; | ||
75 | } | ||
76 | if (!peasycap->pusb_device) { | ||
77 | SAM("ERROR: peasycap->pusb_device is NULL\n"); | ||
78 | return -EFAULT; | ||
79 | } | ||
80 | |||
81 | if (peasycap->audio_isoc_streaming) { | ||
82 | JOM(4, "already streaming audio urbs\n"); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | JOM(4, "initial submission of all audio urbs\n"); | ||
87 | rc = usb_set_interface(peasycap->pusb_device, | ||
88 | peasycap->audio_interface, | ||
89 | peasycap->audio_altsetting_on); | ||
90 | JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", | ||
91 | peasycap->audio_interface, | ||
92 | peasycap->audio_altsetting_on, rc); | ||
93 | |||
94 | isbad = 0; | ||
95 | nospc = 0; | ||
96 | m = 0; | ||
97 | list_for_each(plist_head, peasycap->purb_audio_head) { | ||
98 | pdata_urb = list_entry(plist_head, struct data_urb, list_head); | ||
99 | if (pdata_urb && pdata_urb->purb) { | ||
100 | purb = pdata_urb->purb; | ||
101 | isbuf = pdata_urb->isbuf; | ||
102 | |||
103 | purb->interval = 1; | ||
104 | purb->dev = peasycap->pusb_device; | ||
105 | purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, | ||
106 | peasycap->audio_endpointnumber); | ||
107 | purb->transfer_flags = URB_ISO_ASAP; | ||
108 | purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; | ||
109 | purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; | ||
110 | purb->complete = easycap_alsa_complete; | ||
111 | purb->context = peasycap; | ||
112 | purb->start_frame = 0; | ||
113 | purb->number_of_packets = peasycap->audio_isoc_framesperdesc; | ||
114 | for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { | ||
115 | purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; | ||
116 | purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; | ||
117 | } | ||
118 | |||
119 | rc = usb_submit_urb(purb, GFP_KERNEL); | ||
120 | if (rc) { | ||
121 | isbad++; | ||
122 | SAM("ERROR: usb_submit_urb() failed" | ||
123 | " for urb with rc: -%s: %d\n", | ||
124 | strerror(rc), rc); | ||
125 | } else { | ||
126 | m++; | ||
127 | } | ||
128 | } else { | ||
129 | isbad++; | ||
130 | } | ||
131 | } | ||
132 | if (nospc) { | ||
133 | SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); | ||
134 | SAM("..... possibly inadequate USB bandwidth\n"); | ||
135 | peasycap->audio_eof = 1; | ||
136 | } | ||
137 | |||
138 | if (isbad) | ||
139 | easycap_audio_kill_urbs(peasycap); | ||
140 | else | ||
141 | peasycap->audio_isoc_streaming = m; | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | /*---------------------------------------------------------------------------*/ | ||
146 | /* | ||
147 | * COMMON AUDIO INITIALIZATION | ||
148 | */ | ||
149 | /*---------------------------------------------------------------------------*/ | ||
150 | static int easycap_sound_setup(struct easycap *peasycap) | ||
151 | { | ||
152 | int rc; | ||
153 | |||
154 | JOM(4, "starting initialization\n"); | ||
155 | |||
156 | if (!peasycap) { | ||
157 | SAY("ERROR: peasycap is NULL.\n"); | ||
158 | return -EFAULT; | ||
159 | } | ||
160 | if (!peasycap->pusb_device) { | ||
161 | SAM("ERROR: peasycap->pusb_device is NULL\n"); | ||
162 | return -ENODEV; | ||
163 | } | ||
164 | JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); | ||
165 | |||
166 | rc = easycap_audio_setup(peasycap); | ||
167 | JOM(8, "audio_setup() returned %i\n", rc); | ||
168 | |||
169 | if (!peasycap->pusb_device) { | ||
170 | SAM("ERROR: peasycap->pusb_device has become NULL\n"); | ||
171 | return -ENODEV; | ||
172 | } | ||
173 | /*---------------------------------------------------------------------------*/ | ||
174 | if (!peasycap->pusb_device) { | ||
175 | SAM("ERROR: peasycap->pusb_device has become NULL\n"); | ||
176 | return -ENODEV; | ||
177 | } | ||
178 | rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, | ||
179 | peasycap->audio_altsetting_on); | ||
180 | JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, | ||
181 | peasycap->audio_altsetting_on, rc); | ||
182 | |||
183 | rc = easycap_wakeup_device(peasycap->pusb_device); | ||
184 | JOM(8, "wakeup_device() returned %i\n", rc); | ||
185 | |||
186 | peasycap->audio_eof = 0; | ||
187 | peasycap->audio_idle = 0; | ||
188 | |||
189 | easycap_audio_submit_urbs(peasycap); | ||
190 | |||
191 | JOM(4, "finished initialization\n"); | ||
192 | return 0; | ||
193 | } | ||
59 | /*****************************************************************************/ | 194 | /*****************************************************************************/ |
60 | /*---------------------------------------------------------------------------*/ | 195 | /*---------------------------------------------------------------------------*/ |
61 | /* | 196 | /* |
@@ -64,8 +199,7 @@ static const struct snd_pcm_hardware alsa_hardware = { | |||
64 | * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. | 199 | * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. |
65 | */ | 200 | */ |
66 | /*---------------------------------------------------------------------------*/ | 201 | /*---------------------------------------------------------------------------*/ |
67 | void | 202 | void easycap_alsa_complete(struct urb *purb) |
68 | easycap_alsa_complete(struct urb *purb) | ||
69 | { | 203 | { |
70 | struct easycap *peasycap; | 204 | struct easycap *peasycap; |
71 | struct snd_pcm_substream *pss; | 205 | struct snd_pcm_substream *pss; |
@@ -458,7 +592,6 @@ static int easycap_alsa_ack(struct snd_pcm_substream *pss) | |||
458 | static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) | 592 | static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) |
459 | { | 593 | { |
460 | struct easycap *peasycap; | 594 | struct easycap *peasycap; |
461 | int retval; | ||
462 | 595 | ||
463 | JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, | 596 | JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, |
464 | SNDRV_PCM_TRIGGER_STOP); | 597 | SNDRV_PCM_TRIGGER_STOP); |
@@ -481,7 +614,7 @@ static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) | |||
481 | break; | 614 | break; |
482 | } | 615 | } |
483 | default: | 616 | default: |
484 | retval = -EINVAL; | 617 | return -EINVAL; |
485 | } | 618 | } |
486 | return 0; | 619 | return 0; |
487 | } | 620 | } |
@@ -615,202 +748,3 @@ int easycap_alsa_probe(struct easycap *peasycap) | |||
615 | return 0; | 748 | return 0; |
616 | } | 749 | } |
617 | 750 | ||
618 | /*****************************************************************************/ | ||
619 | /*****************************************************************************/ | ||
620 | /*****************************************************************************/ | ||
621 | /*****************************************************************************/ | ||
622 | /*****************************************************************************/ | ||
623 | /*****************************************************************************/ | ||
624 | /*---------------------------------------------------------------------------*/ | ||
625 | /* | ||
626 | * COMMON AUDIO INITIALIZATION | ||
627 | */ | ||
628 | /*---------------------------------------------------------------------------*/ | ||
629 | int | ||
630 | easycap_sound_setup(struct easycap *peasycap) | ||
631 | { | ||
632 | int rc; | ||
633 | |||
634 | JOM(4, "starting initialization\n"); | ||
635 | |||
636 | if (!peasycap) { | ||
637 | SAY("ERROR: peasycap is NULL.\n"); | ||
638 | return -EFAULT; | ||
639 | } | ||
640 | if (!peasycap->pusb_device) { | ||
641 | SAM("ERROR: peasycap->pusb_device is NULL\n"); | ||
642 | return -ENODEV; | ||
643 | } | ||
644 | JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); | ||
645 | |||
646 | rc = audio_setup(peasycap); | ||
647 | JOM(8, "audio_setup() returned %i\n", rc); | ||
648 | |||
649 | if (!peasycap->pusb_device) { | ||
650 | SAM("ERROR: peasycap->pusb_device has become NULL\n"); | ||
651 | return -ENODEV; | ||
652 | } | ||
653 | /*---------------------------------------------------------------------------*/ | ||
654 | if (!peasycap->pusb_device) { | ||
655 | SAM("ERROR: peasycap->pusb_device has become NULL\n"); | ||
656 | return -ENODEV; | ||
657 | } | ||
658 | rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, | ||
659 | peasycap->audio_altsetting_on); | ||
660 | JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, | ||
661 | peasycap->audio_altsetting_on, rc); | ||
662 | |||
663 | rc = wakeup_device(peasycap->pusb_device); | ||
664 | JOM(8, "wakeup_device() returned %i\n", rc); | ||
665 | |||
666 | peasycap->audio_eof = 0; | ||
667 | peasycap->audio_idle = 0; | ||
668 | |||
669 | submit_audio_urbs(peasycap); | ||
670 | |||
671 | JOM(4, "finished initialization\n"); | ||
672 | return 0; | ||
673 | } | ||
674 | /*****************************************************************************/ | ||
675 | /*---------------------------------------------------------------------------*/ | ||
676 | /* | ||
677 | * SUBMIT ALL AUDIO URBS. | ||
678 | */ | ||
679 | /*---------------------------------------------------------------------------*/ | ||
680 | int | ||
681 | submit_audio_urbs(struct easycap *peasycap) | ||
682 | { | ||
683 | struct data_urb *pdata_urb; | ||
684 | struct urb *purb; | ||
685 | struct list_head *plist_head; | ||
686 | int j, isbad, nospc, m, rc; | ||
687 | int isbuf; | ||
688 | |||
689 | if (!peasycap) { | ||
690 | SAY("ERROR: peasycap is NULL\n"); | ||
691 | return -EFAULT; | ||
692 | } | ||
693 | if (!peasycap->purb_audio_head) { | ||
694 | SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); | ||
695 | return -EFAULT; | ||
696 | } | ||
697 | if (!peasycap->pusb_device) { | ||
698 | SAM("ERROR: peasycap->pusb_device is NULL\n"); | ||
699 | return -EFAULT; | ||
700 | } | ||
701 | |||
702 | if (peasycap->audio_isoc_streaming) { | ||
703 | JOM(4, "already streaming audio urbs\n"); | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | JOM(4, "initial submission of all audio urbs\n"); | ||
708 | rc = usb_set_interface(peasycap->pusb_device, | ||
709 | peasycap->audio_interface, | ||
710 | peasycap->audio_altsetting_on); | ||
711 | JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", | ||
712 | peasycap->audio_interface, | ||
713 | peasycap->audio_altsetting_on, rc); | ||
714 | |||
715 | isbad = 0; | ||
716 | nospc = 0; | ||
717 | m = 0; | ||
718 | list_for_each(plist_head, peasycap->purb_audio_head) { | ||
719 | pdata_urb = list_entry(plist_head, struct data_urb, list_head); | ||
720 | if (pdata_urb && pdata_urb->purb) { | ||
721 | purb = pdata_urb->purb; | ||
722 | isbuf = pdata_urb->isbuf; | ||
723 | |||
724 | purb->interval = 1; | ||
725 | purb->dev = peasycap->pusb_device; | ||
726 | purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, | ||
727 | peasycap->audio_endpointnumber); | ||
728 | purb->transfer_flags = URB_ISO_ASAP; | ||
729 | purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; | ||
730 | purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; | ||
731 | purb->complete = easycap_alsa_complete; | ||
732 | purb->context = peasycap; | ||
733 | purb->start_frame = 0; | ||
734 | purb->number_of_packets = peasycap->audio_isoc_framesperdesc; | ||
735 | for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { | ||
736 | purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; | ||
737 | purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; | ||
738 | } | ||
739 | |||
740 | rc = usb_submit_urb(purb, GFP_KERNEL); | ||
741 | if (rc) { | ||
742 | isbad++; | ||
743 | SAM("ERROR: usb_submit_urb() failed" | ||
744 | " for urb with rc: -%s: %d\n", | ||
745 | strerror(rc), rc); | ||
746 | } else { | ||
747 | m++; | ||
748 | } | ||
749 | } else { | ||
750 | isbad++; | ||
751 | } | ||
752 | } | ||
753 | if (nospc) { | ||
754 | SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); | ||
755 | SAM("..... possibly inadequate USB bandwidth\n"); | ||
756 | peasycap->audio_eof = 1; | ||
757 | } | ||
758 | if (isbad) { | ||
759 | JOM(4, "attempting cleanup instead of submitting\n"); | ||
760 | list_for_each(plist_head, (peasycap->purb_audio_head)) { | ||
761 | pdata_urb = list_entry(plist_head, struct data_urb, list_head); | ||
762 | if (pdata_urb && pdata_urb->purb) | ||
763 | usb_kill_urb(pdata_urb->purb); | ||
764 | } | ||
765 | peasycap->audio_isoc_streaming = 0; | ||
766 | } else { | ||
767 | peasycap->audio_isoc_streaming = m; | ||
768 | JOM(4, "submitted %i audio urbs\n", m); | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | /*****************************************************************************/ | ||
774 | /*---------------------------------------------------------------------------*/ | ||
775 | /* | ||
776 | * KILL ALL AUDIO URBS. | ||
777 | */ | ||
778 | /*---------------------------------------------------------------------------*/ | ||
779 | int | ||
780 | kill_audio_urbs(struct easycap *peasycap) | ||
781 | { | ||
782 | int m; | ||
783 | struct list_head *plist_head; | ||
784 | struct data_urb *pdata_urb; | ||
785 | |||
786 | if (!peasycap) { | ||
787 | SAY("ERROR: peasycap is NULL\n"); | ||
788 | return -EFAULT; | ||
789 | } | ||
790 | |||
791 | if (!peasycap->audio_isoc_streaming) { | ||
792 | JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", | ||
793 | peasycap->audio_isoc_streaming); | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | if (!peasycap->purb_audio_head) { | ||
798 | SAM("ERROR: peasycap->purb_audio_head is NULL\n"); | ||
799 | return -EFAULT; | ||
800 | } | ||
801 | |||
802 | peasycap->audio_isoc_streaming = 0; | ||
803 | JOM(4, "killing audio urbs\n"); | ||
804 | m = 0; | ||
805 | list_for_each(plist_head, (peasycap->purb_audio_head)) { | ||
806 | pdata_urb = list_entry(plist_head, struct data_urb, list_head); | ||
807 | if (pdata_urb && pdata_urb->purb) { | ||
808 | usb_kill_urb(pdata_urb->purb); | ||
809 | m++; | ||
810 | } | ||
811 | } | ||
812 | JOM(4, "%i audio urbs killed\n", m); | ||
813 | |||
814 | return 0; | ||
815 | } | ||
816 | /*****************************************************************************/ | ||
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 3db3b0a91cc1..cffb0b3b93e8 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c | |||
@@ -1054,7 +1054,13 @@ static int go7007_usb_probe(struct usb_interface *intf, | |||
1054 | else | 1054 | else |
1055 | go->hpi_ops = &go7007_usb_onboard_hpi_ops; | 1055 | go->hpi_ops = &go7007_usb_onboard_hpi_ops; |
1056 | go->hpi_context = usb; | 1056 | go->hpi_context = usb; |
1057 | usb_fill_int_urb(usb->intr_urb, usb->usbdev, | 1057 | if (go->board_id == GO7007_BOARDID_SENSORAY_2250) |
1058 | usb_fill_bulk_urb(usb->intr_urb, usb->usbdev, | ||
1059 | usb_rcvbulkpipe(usb->usbdev, 4), | ||
1060 | usb->intr_urb->transfer_buffer, 2*sizeof(u16), | ||
1061 | go7007_usb_readinterrupt_complete, go); | ||
1062 | else | ||
1063 | usb_fill_int_urb(usb->intr_urb, usb->usbdev, | ||
1058 | usb_rcvintpipe(usb->usbdev, 4), | 1064 | usb_rcvintpipe(usb->usbdev, 4), |
1059 | usb->intr_urb->transfer_buffer, 2*sizeof(u16), | 1065 | usb->intr_urb->transfer_buffer, 2*sizeof(u16), |
1060 | go7007_usb_readinterrupt_complete, go, 8); | 1066 | go7007_usb_readinterrupt_complete, go, 8); |
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index f5308d5929c6..c1654b18610e 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c | |||
@@ -63,7 +63,7 @@ static int display_open(struct inode *inode, struct file *file); | |||
63 | static int display_close(struct inode *inode, struct file *file); | 63 | static int display_close(struct inode *inode, struct file *file); |
64 | 64 | ||
65 | /* VFD write operation */ | 65 | /* VFD write operation */ |
66 | static ssize_t vfd_write(struct file *file, const char *buf, | 66 | static ssize_t vfd_write(struct file *file, const char __user *buf, |
67 | size_t n_bytes, loff_t *pos); | 67 | size_t n_bytes, loff_t *pos); |
68 | 68 | ||
69 | /* LIRC driver function prototypes */ | 69 | /* LIRC driver function prototypes */ |
@@ -369,7 +369,7 @@ static int send_packet(struct imon_context *context) | |||
369 | * than 32 bytes are provided spaces will be appended to | 369 | * than 32 bytes are provided spaces will be appended to |
370 | * generate a full screen. | 370 | * generate a full screen. |
371 | */ | 371 | */ |
372 | static ssize_t vfd_write(struct file *file, const char *buf, | 372 | static ssize_t vfd_write(struct file *file, const char __user *buf, |
373 | size_t n_bytes, loff_t *pos) | 373 | size_t n_bytes, loff_t *pos) |
374 | { | 374 | { |
375 | int i; | 375 | int i; |
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 8a060a8a7224..0ca308a1183c 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c | |||
@@ -773,7 +773,7 @@ static int hardware_init_port(void) | |||
773 | /* we fail, there's nothing here */ | 773 | /* we fail, there's nothing here */ |
774 | printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test " | 774 | printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test " |
775 | "failed, cannot continue\n"); | 775 | "failed, cannot continue\n"); |
776 | return -EINVAL; | 776 | return -ENODEV; |
777 | } | 777 | } |
778 | 778 | ||
779 | 779 | ||
@@ -836,25 +836,22 @@ static int hardware_init_port(void) | |||
836 | return 0; | 836 | return 0; |
837 | } | 837 | } |
838 | 838 | ||
839 | static int init_port(void) | 839 | static int __devinit lirc_serial_probe(struct platform_device *dev) |
840 | { | 840 | { |
841 | int i, nlow, nhigh, result; | 841 | int i, nlow, nhigh, result; |
842 | 842 | ||
843 | result = request_irq(irq, irq_handler, | 843 | result = request_irq(irq, irq_handler, |
844 | (share_irq ? IRQF_SHARED : 0), | 844 | (share_irq ? IRQF_SHARED : 0), |
845 | LIRC_DRIVER_NAME, (void *)&hardware); | 845 | LIRC_DRIVER_NAME, (void *)&hardware); |
846 | 846 | if (result < 0) { | |
847 | switch (result) { | 847 | if (result == -EBUSY) |
848 | case -EBUSY: | 848 | printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", |
849 | printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); | 849 | irq); |
850 | return -EBUSY; | 850 | else if (result == -EINVAL) |
851 | case -EINVAL: | 851 | printk(KERN_ERR LIRC_DRIVER_NAME |
852 | printk(KERN_ERR LIRC_DRIVER_NAME | 852 | ": Bad irq number or handler\n"); |
853 | ": Bad irq number or handler\n"); | 853 | return result; |
854 | return -EINVAL; | 854 | } |
855 | default: | ||
856 | break; | ||
857 | }; | ||
858 | 855 | ||
859 | /* Reserve io region. */ | 856 | /* Reserve io region. */ |
860 | /* | 857 | /* |
@@ -875,11 +872,13 @@ static int init_port(void) | |||
875 | ": or compile the serial port driver as module and\n"); | 872 | ": or compile the serial port driver as module and\n"); |
876 | printk(KERN_WARNING LIRC_DRIVER_NAME | 873 | printk(KERN_WARNING LIRC_DRIVER_NAME |
877 | ": make sure this module is loaded first\n"); | 874 | ": make sure this module is loaded first\n"); |
878 | return -EBUSY; | 875 | result = -EBUSY; |
876 | goto exit_free_irq; | ||
879 | } | 877 | } |
880 | 878 | ||
881 | if (hardware_init_port() < 0) | 879 | result = hardware_init_port(); |
882 | return -EINVAL; | 880 | if (result < 0) |
881 | goto exit_release_region; | ||
883 | 882 | ||
884 | /* Initialize pulse/space widths */ | 883 | /* Initialize pulse/space widths */ |
885 | init_timing_params(duty_cycle, freq); | 884 | init_timing_params(duty_cycle, freq); |
@@ -911,6 +910,28 @@ static int init_port(void) | |||
911 | 910 | ||
912 | dprintk("Interrupt %d, port %04x obtained\n", irq, io); | 911 | dprintk("Interrupt %d, port %04x obtained\n", irq, io); |
913 | return 0; | 912 | return 0; |
913 | |||
914 | exit_release_region: | ||
915 | if (iommap != 0) | ||
916 | release_mem_region(iommap, 8 << ioshift); | ||
917 | else | ||
918 | release_region(io, 8); | ||
919 | exit_free_irq: | ||
920 | free_irq(irq, (void *)&hardware); | ||
921 | |||
922 | return result; | ||
923 | } | ||
924 | |||
925 | static int __devexit lirc_serial_remove(struct platform_device *dev) | ||
926 | { | ||
927 | free_irq(irq, (void *)&hardware); | ||
928 | |||
929 | if (iommap != 0) | ||
930 | release_mem_region(iommap, 8 << ioshift); | ||
931 | else | ||
932 | release_region(io, 8); | ||
933 | |||
934 | return 0; | ||
914 | } | 935 | } |
915 | 936 | ||
916 | static int set_use_inc(void *data) | 937 | static int set_use_inc(void *data) |
@@ -955,7 +976,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, | |||
955 | int *wbuf; | 976 | int *wbuf; |
956 | 977 | ||
957 | if (!(hardware[type].features & LIRC_CAN_SEND_PULSE)) | 978 | if (!(hardware[type].features & LIRC_CAN_SEND_PULSE)) |
958 | return -EBADF; | 979 | return -EPERM; |
959 | 980 | ||
960 | count = n / sizeof(int); | 981 | count = n / sizeof(int); |
961 | if (n % sizeof(int) || count % 2 == 0) | 982 | if (n % sizeof(int) || count % 2 == 0) |
@@ -1006,11 +1027,11 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
1006 | return result; | 1027 | return result; |
1007 | /* only LIRC_MODE_PULSE supported */ | 1028 | /* only LIRC_MODE_PULSE supported */ |
1008 | if (value != LIRC_MODE_PULSE) | 1029 | if (value != LIRC_MODE_PULSE) |
1009 | return -ENOSYS; | 1030 | return -EINVAL; |
1010 | break; | 1031 | break; |
1011 | 1032 | ||
1012 | case LIRC_GET_LENGTH: | 1033 | case LIRC_GET_LENGTH: |
1013 | return -ENOSYS; | 1034 | return -ENOIOCTLCMD; |
1014 | break; | 1035 | break; |
1015 | 1036 | ||
1016 | case LIRC_SET_SEND_DUTY_CYCLE: | 1037 | case LIRC_SET_SEND_DUTY_CYCLE: |
@@ -1076,16 +1097,6 @@ static struct lirc_driver driver = { | |||
1076 | 1097 | ||
1077 | static struct platform_device *lirc_serial_dev; | 1098 | static struct platform_device *lirc_serial_dev; |
1078 | 1099 | ||
1079 | static int __devinit lirc_serial_probe(struct platform_device *dev) | ||
1080 | { | ||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static int __devexit lirc_serial_remove(struct platform_device *dev) | ||
1085 | { | ||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | static int lirc_serial_suspend(struct platform_device *dev, | 1100 | static int lirc_serial_suspend(struct platform_device *dev, |
1090 | pm_message_t state) | 1101 | pm_message_t state) |
1091 | { | 1102 | { |
@@ -1111,11 +1122,11 @@ static void lirc_serial_exit(void); | |||
1111 | static int lirc_serial_resume(struct platform_device *dev) | 1122 | static int lirc_serial_resume(struct platform_device *dev) |
1112 | { | 1123 | { |
1113 | unsigned long flags; | 1124 | unsigned long flags; |
1125 | int result; | ||
1114 | 1126 | ||
1115 | if (hardware_init_port() < 0) { | 1127 | result = hardware_init_port(); |
1116 | lirc_serial_exit(); | 1128 | if (result < 0) |
1117 | return -EINVAL; | 1129 | return result; |
1118 | } | ||
1119 | 1130 | ||
1120 | spin_lock_irqsave(&hardware[type].lock, flags); | 1131 | spin_lock_irqsave(&hardware[type].lock, flags); |
1121 | /* Enable Interrupt */ | 1132 | /* Enable Interrupt */ |
@@ -1148,7 +1159,7 @@ static int __init lirc_serial_init(void) | |||
1148 | /* Init read buffer. */ | 1159 | /* Init read buffer. */ |
1149 | result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); | 1160 | result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); |
1150 | if (result < 0) | 1161 | if (result < 0) |
1151 | return -ENOMEM; | 1162 | return result; |
1152 | 1163 | ||
1153 | result = platform_driver_register(&lirc_serial_driver); | 1164 | result = platform_driver_register(&lirc_serial_driver); |
1154 | if (result) { | 1165 | if (result) { |
@@ -1188,10 +1199,6 @@ static int __init lirc_serial_init_module(void) | |||
1188 | { | 1199 | { |
1189 | int result; | 1200 | int result; |
1190 | 1201 | ||
1191 | result = lirc_serial_init(); | ||
1192 | if (result) | ||
1193 | return result; | ||
1194 | |||
1195 | switch (type) { | 1202 | switch (type) { |
1196 | case LIRC_HOMEBREW: | 1203 | case LIRC_HOMEBREW: |
1197 | case LIRC_IRDEO: | 1204 | case LIRC_IRDEO: |
@@ -1211,8 +1218,7 @@ static int __init lirc_serial_init_module(void) | |||
1211 | break; | 1218 | break; |
1212 | #endif | 1219 | #endif |
1213 | default: | 1220 | default: |
1214 | result = -EINVAL; | 1221 | return -EINVAL; |
1215 | goto exit_serial_exit; | ||
1216 | } | 1222 | } |
1217 | if (!softcarrier) { | 1223 | if (!softcarrier) { |
1218 | switch (type) { | 1224 | switch (type) { |
@@ -1228,37 +1234,26 @@ static int __init lirc_serial_init_module(void) | |||
1228 | } | 1234 | } |
1229 | } | 1235 | } |
1230 | 1236 | ||
1231 | result = init_port(); | 1237 | result = lirc_serial_init(); |
1232 | if (result < 0) | 1238 | if (result) |
1233 | goto exit_serial_exit; | 1239 | return result; |
1240 | |||
1234 | driver.features = hardware[type].features; | 1241 | driver.features = hardware[type].features; |
1235 | driver.dev = &lirc_serial_dev->dev; | 1242 | driver.dev = &lirc_serial_dev->dev; |
1236 | driver.minor = lirc_register_driver(&driver); | 1243 | driver.minor = lirc_register_driver(&driver); |
1237 | if (driver.minor < 0) { | 1244 | if (driver.minor < 0) { |
1238 | printk(KERN_ERR LIRC_DRIVER_NAME | 1245 | printk(KERN_ERR LIRC_DRIVER_NAME |
1239 | ": register_chrdev failed!\n"); | 1246 | ": register_chrdev failed!\n"); |
1240 | result = -EIO; | 1247 | lirc_serial_exit(); |
1241 | goto exit_release; | 1248 | return driver.minor; |
1242 | } | 1249 | } |
1243 | return 0; | 1250 | return 0; |
1244 | exit_release: | ||
1245 | release_region(io, 8); | ||
1246 | exit_serial_exit: | ||
1247 | lirc_serial_exit(); | ||
1248 | return result; | ||
1249 | } | 1251 | } |
1250 | 1252 | ||
1251 | static void __exit lirc_serial_exit_module(void) | 1253 | static void __exit lirc_serial_exit_module(void) |
1252 | { | 1254 | { |
1253 | lirc_serial_exit(); | ||
1254 | |||
1255 | free_irq(irq, (void *)&hardware); | ||
1256 | |||
1257 | if (iommap != 0) | ||
1258 | release_mem_region(iommap, 8 << ioshift); | ||
1259 | else | ||
1260 | release_region(io, 8); | ||
1261 | lirc_unregister_driver(driver.minor); | 1255 | lirc_unregister_driver(driver.minor); |
1256 | lirc_serial_exit(); | ||
1262 | dprintk("cleaned up module\n"); | 1257 | dprintk("cleaned up module\n"); |
1263 | } | 1258 | } |
1264 | 1259 | ||
diff --git a/drivers/staging/media/solo6x10/Makefile b/drivers/staging/media/solo6x10/Makefile index 72816cf16704..337e38c3a0f0 100644 --- a/drivers/staging/media/solo6x10/Makefile +++ b/drivers/staging/media/solo6x10/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | solo6x10-y := core.o i2c.o p2m.o v4l2.o tw28.o gpio.o disp.o enc.o v4l2-enc.o g723.o | 1 | solo6x10-y := core.o i2c.o p2m.o v4l2.o tw28.o gpio.o disp.o enc.o v4l2-enc.o g723.o |
2 | 2 | ||
3 | obj-$(CONFIG_SOLO6X10) := solo6x10.o | 3 | obj-$(CONFIG_SOLO6X10) += solo6x10.o |
diff --git a/drivers/staging/media/solo6x10/jpeg.h b/drivers/staging/media/solo6x10/solo6x10-jpeg.h index 50defec318cc..50defec318cc 100644 --- a/drivers/staging/media/solo6x10/jpeg.h +++ b/drivers/staging/media/solo6x10/solo6x10-jpeg.h | |||
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c index bee7280bbed9..f8f0da952288 100644 --- a/drivers/staging/media/solo6x10/v4l2-enc.c +++ b/drivers/staging/media/solo6x10/v4l2-enc.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <media/videobuf-dma-sg.h> | 26 | #include <media/videobuf-dma-sg.h> |
27 | #include "solo6x10.h" | 27 | #include "solo6x10.h" |
28 | #include "tw28.h" | 28 | #include "tw28.h" |
29 | #include "jpeg.h" | 29 | #include "solo6x10-jpeg.h" |
30 | 30 | ||
31 | #define MIN_VID_BUFFERS 4 | 31 | #define MIN_VID_BUFFERS 4 |
32 | #define FRAME_BUF_SIZE (128 * 1024) | 32 | #define FRAME_BUF_SIZE (128 * 1024) |
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 1b1094c35e4f..a3c762383f88 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h | |||
@@ -316,7 +316,9 @@ struct dvb_frontend_event { | |||
316 | 316 | ||
317 | #define DTV_DVBT2_PLP_ID 43 | 317 | #define DTV_DVBT2_PLP_ID 43 |
318 | 318 | ||
319 | #define DTV_MAX_COMMAND DTV_DVBT2_PLP_ID | 319 | #define DTV_ENUM_DELSYS 44 |
320 | |||
321 | #define DTV_MAX_COMMAND DTV_ENUM_DELSYS | ||
320 | 322 | ||
321 | typedef enum fe_pilot { | 323 | typedef enum fe_pilot { |
322 | PILOT_ON, | 324 | PILOT_ON, |
@@ -333,7 +335,7 @@ typedef enum fe_rolloff { | |||
333 | 335 | ||
334 | typedef enum fe_delivery_system { | 336 | typedef enum fe_delivery_system { |
335 | SYS_UNDEFINED, | 337 | SYS_UNDEFINED, |
336 | SYS_DVBC_ANNEX_AC, | 338 | SYS_DVBC_ANNEX_A, |
337 | SYS_DVBC_ANNEX_B, | 339 | SYS_DVBC_ANNEX_B, |
338 | SYS_DVBT, | 340 | SYS_DVBT, |
339 | SYS_DSS, | 341 | SYS_DSS, |
@@ -350,8 +352,13 @@ typedef enum fe_delivery_system { | |||
350 | SYS_DAB, | 352 | SYS_DAB, |
351 | SYS_DVBT2, | 353 | SYS_DVBT2, |
352 | SYS_TURBO, | 354 | SYS_TURBO, |
355 | SYS_DVBC_ANNEX_C, | ||
353 | } fe_delivery_system_t; | 356 | } fe_delivery_system_t; |
354 | 357 | ||
358 | |||
359 | #define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A | ||
360 | |||
361 | |||
355 | struct dtv_cmds_h { | 362 | struct dtv_cmds_h { |
356 | char *name; /* A display name for debugging purposes */ | 363 | char *name; /* A display name for debugging purposes */ |
357 | 364 | ||
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h index 66594b1d5d7b..0559e2bd38f9 100644 --- a/include/linux/dvb/version.h +++ b/include/linux/dvb/version.h | |||
@@ -24,6 +24,6 @@ | |||
24 | #define _DVBVERSION_H_ | 24 | #define _DVBVERSION_H_ |
25 | 25 | ||
26 | #define DVB_API_VERSION 5 | 26 | #define DVB_API_VERSION 5 |
27 | #define DVB_API_VERSION_MINOR 4 | 27 | #define DVB_API_VERSION_MINOR 5 |
28 | 28 | ||
29 | #endif /*_DVBVERSION_H_*/ | 29 | #endif /*_DVBVERSION_H_*/ |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4b752d5ee80e..3d62631839bc 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
@@ -1682,6 +1682,8 @@ enum v4l2_flash_strobe_source { | |||
1682 | #define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) | 1682 | #define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) |
1683 | #define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) | 1683 | #define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) |
1684 | #define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) | 1684 | #define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) |
1685 | #define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) | ||
1686 | #define V4L2_FLASH_FAULT_INDICATOR (1 << 5) | ||
1685 | 1687 | ||
1686 | #define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) | 1688 | #define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) |
1687 | #define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) | 1689 | #define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) |
diff --git a/include/media/as3645a.h b/include/media/as3645a.h new file mode 100644 index 000000000000..5075496d2c9e --- /dev/null +++ b/include/media/as3645a.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * include/media/as3645a.h | ||
3 | * | ||
4 | * Copyright (C) 2008-2011 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef __AS3645A_H__ | ||
25 | #define __AS3645A_H__ | ||
26 | |||
27 | #include <media/v4l2-subdev.h> | ||
28 | |||
29 | #define AS3645A_NAME "as3645a" | ||
30 | #define AS3645A_I2C_ADDR (0x60 >> 1) /* W:0x60, R:0x61 */ | ||
31 | |||
32 | #define AS3645A_FLASH_TIMEOUT_MIN 100000 /* us */ | ||
33 | #define AS3645A_FLASH_TIMEOUT_MAX 850000 | ||
34 | #define AS3645A_FLASH_TIMEOUT_STEP 50000 | ||
35 | |||
36 | #define AS3645A_FLASH_INTENSITY_MIN 200 /* mA */ | ||
37 | #define AS3645A_FLASH_INTENSITY_MAX_1LED 500 | ||
38 | #define AS3645A_FLASH_INTENSITY_MAX_2LEDS 400 | ||
39 | #define AS3645A_FLASH_INTENSITY_STEP 20 | ||
40 | |||
41 | #define AS3645A_TORCH_INTENSITY_MIN 20 /* mA */ | ||
42 | #define AS3645A_TORCH_INTENSITY_MAX 160 | ||
43 | #define AS3645A_TORCH_INTENSITY_STEP 20 | ||
44 | |||
45 | #define AS3645A_INDICATOR_INTENSITY_MIN 0 /* uA */ | ||
46 | #define AS3645A_INDICATOR_INTENSITY_MAX 10000 | ||
47 | #define AS3645A_INDICATOR_INTENSITY_STEP 2500 | ||
48 | |||
49 | /* | ||
50 | * as3645a_platform_data - Flash controller platform data | ||
51 | * @set_power: Set power callback | ||
52 | * @vref: VREF offset (0=0V, 1=+0.3V, 2=-0.3V, 3=+0.6V) | ||
53 | * @peak: Inductor peak current limit (0=1.25A, 1=1.5A, 2=1.75A, 3=2.0A) | ||
54 | * @ext_strobe: True if external flash strobe can be used | ||
55 | * @flash_max_current: Max flash current (mA, <= AS3645A_FLASH_INTENSITY_MAX) | ||
56 | * @torch_max_current: Max torch current (mA, >= AS3645A_TORCH_INTENSITY_MAX) | ||
57 | * @timeout_max: Max flash timeout (us, <= AS3645A_FLASH_TIMEOUT_MAX) | ||
58 | */ | ||
59 | struct as3645a_platform_data { | ||
60 | int (*set_power)(struct v4l2_subdev *subdev, int on); | ||
61 | unsigned int vref; | ||
62 | unsigned int peak; | ||
63 | bool ext_strobe; | ||
64 | |||
65 | /* Flash and torch currents and timeout limits */ | ||
66 | unsigned int flash_max_current; | ||
67 | unsigned int torch_max_current; | ||
68 | unsigned int timeout_max; | ||
69 | }; | ||
70 | |||
71 | #endif /* __AS3645A_H__ */ | ||
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index cd8bca63a502..29e7bba78ffe 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h | |||
@@ -98,7 +98,7 @@ struct media_entity { | |||
98 | 98 | ||
99 | /* Sub-device specifications */ | 99 | /* Sub-device specifications */ |
100 | /* Nothing needed yet */ | 100 | /* Nothing needed yet */ |
101 | }; | 101 | } info; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static inline u32 media_entity_type(struct media_entity *entity) | 104 | static inline u32 media_entity_type(struct media_entity *entity) |
diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h index e917b1da6577..042849a34640 100644 --- a/include/media/omap3isp.h +++ b/include/media/omap3isp.h | |||
@@ -58,7 +58,7 @@ enum { | |||
58 | * ISP_LANE_SHIFT_4 - CAMEXT[13:4] -> CAM[9:0] | 58 | * ISP_LANE_SHIFT_4 - CAMEXT[13:4] -> CAM[9:0] |
59 | * ISP_LANE_SHIFT_6 - CAMEXT[13:6] -> CAM[7:0] | 59 | * ISP_LANE_SHIFT_6 - CAMEXT[13:6] -> CAM[7:0] |
60 | * @clk_pol: Pixel clock polarity | 60 | * @clk_pol: Pixel clock polarity |
61 | * 0 - Non Inverted, 1 - Inverted | 61 | * 0 - Sample on rising edge, 1 - Sample on falling edge |
62 | * @hs_pol: Horizontal synchronization polarity | 62 | * @hs_pol: Horizontal synchronization polarity |
63 | * 0 - Active high, 1 - Active low | 63 | * 0 - Active high, 1 - Active low |
64 | * @vs_pol: Vertical synchronization polarity | 64 | * @vs_pol: Vertical synchronization polarity |
diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 26a3bd0fe57c..183d701eb3ce 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h | |||
@@ -18,13 +18,15 @@ | |||
18 | #define RC_TYPE_JVC (1 << 3) /* JVC protocol */ | 18 | #define RC_TYPE_JVC (1 << 3) /* JVC protocol */ |
19 | #define RC_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */ | 19 | #define RC_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */ |
20 | #define RC_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */ | 20 | #define RC_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */ |
21 | #define RC_TYPE_SANYO (1 << 6) /* Sanyo protocol */ | ||
21 | #define RC_TYPE_MCE_KBD (1 << 29) /* RC6-ish MCE keyboard/mouse */ | 22 | #define RC_TYPE_MCE_KBD (1 << 29) /* RC6-ish MCE keyboard/mouse */ |
22 | #define RC_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */ | 23 | #define RC_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */ |
23 | #define RC_TYPE_OTHER (1u << 31) | 24 | #define RC_TYPE_OTHER (1u << 31) |
24 | 25 | ||
25 | #define RC_TYPE_ALL (RC_TYPE_RC5 | RC_TYPE_NEC | RC_TYPE_RC6 | \ | 26 | #define RC_TYPE_ALL (RC_TYPE_RC5 | RC_TYPE_NEC | RC_TYPE_RC6 | \ |
26 | RC_TYPE_JVC | RC_TYPE_SONY | RC_TYPE_LIRC | \ | 27 | RC_TYPE_JVC | RC_TYPE_SONY | RC_TYPE_LIRC | \ |
27 | RC_TYPE_RC5_SZ | RC_TYPE_MCE_KBD | RC_TYPE_OTHER) | 28 | RC_TYPE_RC5_SZ | RC_TYPE_SANYO | RC_TYPE_MCE_KBD | \ |
29 | RC_TYPE_OTHER) | ||
28 | 30 | ||
29 | struct rc_map_table { | 31 | struct rc_map_table { |
30 | u32 scancode; | 32 | u32 scancode; |