diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-28 12:35:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-28 12:35:11 -0400 |
commit | 0851668fdd97e526b2a41f794b785c204dd3d3e0 (patch) | |
tree | 4ef7c20a8be8393006c6fe9627eb29dd30877d61 | |
parent | 00ebb6382b8d9c7c15b5f8ad230670d8161d38dd (diff) | |
parent | 7655e594945289b418af39f6669fea4666a7b520 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (505 commits)
[media] af9015: Fix max I2C message size when used with tda18271
[media] IR: initialize ir_raw_event in few more drivers
[media] Guard a divide in v4l1 compat layer
[media] imon: fix nomouse modprobe option
[media] imon: remove redundant change_protocol call
[media] imon: fix my egregious brown paper bag w/rdev/idev split
[media] cafe_ccic: Configure ov7670 correctly
[media] ov7670: allow configuration of image size, clock speed, and I/O method
[media] af9015: support for DigitalNow TinyTwin v3 [1f4d:9016]
[media] af9015: map DigitalNow TinyTwin v2 remote
[media] DigitalNow TinyTwin remote controller
[media] af9015: RC fixes and improvements
videodev2.h.xml: Update to reflect the latest changes at videodev2.h
[media] v4l: document new Bayer and monochrome pixel formats
[media] DocBook/v4l: Add missing formats used on gspca cpia1 and sn9c2028
[media] firedtv: add parameter to fake ca_system_ids in CA_INFO
[media] tm6000: fix a macro coding style issue
tm6000: Remove some ugly debug code
[media] Nova-S-Plus audio line input
[media] [RFC,1/1] V4L2: Use new CAP bits in existing RDS capable drivers
...
531 files changed, 41145 insertions, 13099 deletions
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index 6ae97157b1c..be34dcbe0d9 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl | |||
@@ -250,6 +250,9 @@ | |||
250 | <!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> | 250 | <!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> |
251 | <!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> | 251 | <!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> |
252 | <!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> | 252 | <!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> |
253 | <!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml"> | ||
254 | <!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml"> | ||
255 | <!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml"> | ||
253 | <!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml"> | 256 | <!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml"> |
254 | <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml"> | 257 | <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml"> |
255 | <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml"> | 258 | <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml"> |
@@ -347,6 +350,9 @@ | |||
347 | <!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> | 350 | <!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> |
348 | <!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> | 351 | <!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> |
349 | <!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> | 352 | <!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> |
353 | <!ENTITY srggb10 SYSTEM "v4l/pixfmt-srggb10.xml"> | ||
354 | <!ENTITY srggb8 SYSTEM "v4l/pixfmt-srggb8.xml"> | ||
355 | <!ENTITY y10 SYSTEM "v4l/pixfmt-y10.xml"> | ||
350 | <!ENTITY cropcap SYSTEM "v4l/vidioc-cropcap.xml"> | 356 | <!ENTITY cropcap SYSTEM "v4l/vidioc-cropcap.xml"> |
351 | <!ENTITY dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml"> | 357 | <!ENTITY dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml"> |
352 | <!ENTITY encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml"> | 358 | <!ENTITY encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml"> |
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml index 54447f0d078..c9ce61d981f 100644 --- a/Documentation/DocBook/v4l/compat.xml +++ b/Documentation/DocBook/v4l/compat.xml | |||
@@ -21,11 +21,15 @@ API.</para> | |||
21 | <title>Opening and Closing Devices</title> | 21 | <title>Opening and Closing Devices</title> |
22 | 22 | ||
23 | <para>For compatibility reasons the character device file names | 23 | <para>For compatibility reasons the character device file names |
24 | recommended for V4L2 video capture, overlay, radio, teletext and raw | 24 | recommended for V4L2 video capture, overlay, radio and raw |
25 | vbi capture devices did not change from those used by V4L. They are | 25 | vbi capture devices did not change from those used by V4L. They are |
26 | listed in <xref linkend="devices" /> and below in <xref | 26 | listed in <xref linkend="devices" /> and below in <xref |
27 | linkend="v4l-dev" />.</para> | 27 | linkend="v4l-dev" />.</para> |
28 | 28 | ||
29 | <para>The teletext devices (minor range 192-223) have been removed in | ||
30 | V4L2 and no longer exist. There is no hardware available anymore for handling | ||
31 | pure teletext. Instead raw or sliced VBI is used.</para> | ||
32 | |||
29 | <para>The V4L <filename>videodev</filename> module automatically | 33 | <para>The V4L <filename>videodev</filename> module automatically |
30 | assigns minor numbers to drivers in load order, depending on the | 34 | assigns minor numbers to drivers in load order, depending on the |
31 | registered device type. We recommend that V4L2 drivers by default | 35 | registered device type. We recommend that V4L2 drivers by default |
@@ -66,13 +70,6 @@ not compatible with V4L or V4L2.</para> </footnote>, | |||
66 | <entry>64-127</entry> | 70 | <entry>64-127</entry> |
67 | </row> | 71 | </row> |
68 | <row> | 72 | <row> |
69 | <entry>Teletext decoder</entry> | ||
70 | <entry><para><filename>/dev/vtx</filename>, | ||
71 | <filename>/dev/vtx0</filename> to | ||
72 | <filename>/dev/vtx31</filename></para></entry> | ||
73 | <entry>192-223</entry> | ||
74 | </row> | ||
75 | <row> | ||
76 | <entry>Raw VBI capture</entry> | 73 | <entry>Raw VBI capture</entry> |
77 | <entry><para><filename>/dev/vbi</filename>, | 74 | <entry><para><filename>/dev/vbi</filename>, |
78 | <filename>/dev/vbi0</filename> to | 75 | <filename>/dev/vbi0</filename> to |
@@ -2345,6 +2342,17 @@ more information.</para> | |||
2345 | </listitem> | 2342 | </listitem> |
2346 | </orderedlist> | 2343 | </orderedlist> |
2347 | </section> | 2344 | </section> |
2345 | <section> | ||
2346 | <title>V4L2 in Linux 2.6.37</title> | ||
2347 | <orderedlist> | ||
2348 | <listitem> | ||
2349 | <para>Remove the vtx (videotext/teletext) API. This API was no longer | ||
2350 | used and no hardware exists to verify the API. Nor were any userspace applications found | ||
2351 | that used it. It was originally scheduled for removal in 2.6.35. | ||
2352 | </para> | ||
2353 | </listitem> | ||
2354 | </orderedlist> | ||
2355 | </section> | ||
2348 | 2356 | ||
2349 | <section id="other"> | 2357 | <section id="other"> |
2350 | <title>Relation of V4L2 to other Linux multimedia APIs</title> | 2358 | <title>Relation of V4L2 to other Linux multimedia APIs</title> |
diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml index 8408caaee27..2fae3e87ce7 100644 --- a/Documentation/DocBook/v4l/controls.xml +++ b/Documentation/DocBook/v4l/controls.xml | |||
@@ -312,10 +312,17 @@ minimum value disables backlight compensation.</entry> | |||
312 | information and bits 24-31 must be zero.</entry> | 312 | information and bits 24-31 must be zero.</entry> |
313 | </row> | 313 | </row> |
314 | <row> | 314 | <row> |
315 | <entry><constant>V4L2_CID_ILLUMINATORS_1</constant> | ||
316 | <constant>V4L2_CID_ILLUMINATORS_2</constant></entry> | ||
317 | <entry>boolean</entry> | ||
318 | <entry>Switch on or off the illuminator 1 or 2 of the device | ||
319 | (usually a microscope).</entry> | ||
320 | </row> | ||
321 | <row> | ||
315 | <entry><constant>V4L2_CID_LASTP1</constant></entry> | 322 | <entry><constant>V4L2_CID_LASTP1</constant></entry> |
316 | <entry></entry> | 323 | <entry></entry> |
317 | <entry>End of the predefined control IDs (currently | 324 | <entry>End of the predefined control IDs (currently |
318 | <constant>V4L2_CID_BG_COLOR</constant> + 1).</entry> | 325 | <constant>V4L2_CID_ILLUMINATORS_2</constant> + 1).</entry> |
319 | </row> | 326 | </row> |
320 | <row> | 327 | <row> |
321 | <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry> | 328 | <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry> |
@@ -357,9 +364,6 @@ enumerate_menu (void) | |||
357 | querymenu.index++) { | 364 | querymenu.index++) { |
358 | if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &querymenu)) { | 365 | if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &querymenu)) { |
359 | printf (" %s\n", querymenu.name); | 366 | printf (" %s\n", querymenu.name); |
360 | } else { | ||
361 | perror ("VIDIOC_QUERYMENU"); | ||
362 | exit (EXIT_FAILURE); | ||
363 | } | 367 | } |
364 | } | 368 | } |
365 | } | 369 | } |
diff --git a/Documentation/DocBook/v4l/dev-rds.xml b/Documentation/DocBook/v4l/dev-rds.xml index 0869d701b1e..360d2737e64 100644 --- a/Documentation/DocBook/v4l/dev-rds.xml +++ b/Documentation/DocBook/v4l/dev-rds.xml | |||
@@ -3,15 +3,16 @@ | |||
3 | <para>The Radio Data System transmits supplementary | 3 | <para>The Radio Data System transmits supplementary |
4 | information in binary format, for example the station name or travel | 4 | information in binary format, for example the station name or travel |
5 | information, on an inaudible audio subcarrier of a radio program. This | 5 | information, on an inaudible audio subcarrier of a radio program. This |
6 | interface is aimed at devices capable of receiving and decoding RDS | 6 | interface is aimed at devices capable of receiving and/or transmitting RDS |
7 | information.</para> | 7 | information.</para> |
8 | 8 | ||
9 | <para>For more information see the core RDS standard <xref linkend="en50067" /> | 9 | <para>For more information see the core RDS standard <xref linkend="en50067" /> |
10 | and the RBDS standard <xref linkend="nrsc4" />.</para> | 10 | and the RBDS standard <xref linkend="nrsc4" />.</para> |
11 | 11 | ||
12 | <para>Note that the RBDS standard as is used in the USA is almost identical | 12 | <para>Note that the RBDS standard as is used in the USA is almost identical |
13 | to the RDS standard. Any RDS decoder can also handle RBDS. Only some of the fields | 13 | to the RDS standard. Any RDS decoder/encoder can also handle RBDS. Only some of the |
14 | have slightly different meanings. See the RBDS standard for more information.</para> | 14 | fields have slightly different meanings. See the RBDS standard for more |
15 | information.</para> | ||
15 | 16 | ||
16 | <para>The RBDS standard also specifies support for MMBS (Modified Mobile Search). | 17 | <para>The RBDS standard also specifies support for MMBS (Modified Mobile Search). |
17 | This is a proprietary format which seems to be discontinued. The RDS interface does not | 18 | This is a proprietary format which seems to be discontinued. The RDS interface does not |
@@ -21,16 +22,25 @@ be needed, then please contact the linux-media mailing list: &v4l-ml;.</para> | |||
21 | <section> | 22 | <section> |
22 | <title>Querying Capabilities</title> | 23 | <title>Querying Capabilities</title> |
23 | 24 | ||
24 | <para>Devices supporting the RDS capturing API | 25 | <para>Devices supporting the RDS capturing API set |
25 | set the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in | 26 | the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in |
26 | the <structfield>capabilities</structfield> field of &v4l2-capability; | 27 | the <structfield>capabilities</structfield> field of &v4l2-capability; |
27 | returned by the &VIDIOC-QUERYCAP; ioctl. | 28 | returned by the &VIDIOC-QUERYCAP; ioctl. Any tuner that supports RDS |
28 | Any tuner that supports RDS will set the | 29 | will set the <constant>V4L2_TUNER_CAP_RDS</constant> flag in |
29 | <constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield> | 30 | the <structfield>capability</structfield> field of &v4l2-tuner;. If |
30 | field of &v4l2-tuner;. | 31 | the driver only passes RDS blocks without interpreting the data |
31 | Whether an RDS signal is present can be detected by looking at | 32 | the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be |
32 | the <structfield>rxsubchans</structfield> field of &v4l2-tuner;: the | 33 | set, see <link linkend="reading-rds-data">Reading RDS data</link>. |
33 | <constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data was detected.</para> | 34 | For future use the |
35 | flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> has also been | ||
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 | ||
38 | should discuss this on the linux-media mailing list: &v4l-ml;.</para> | ||
39 | |||
40 | <para> Whether an RDS signal is present can be detected by looking | ||
41 | at the <structfield>rxsubchans</structfield> field of &v4l2-tuner;: | ||
42 | the <constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data | ||
43 | was detected.</para> | ||
34 | 44 | ||
35 | <para>Devices supporting the RDS output API | 45 | <para>Devices supporting the RDS output API |
36 | set the <constant>V4L2_CAP_RDS_OUTPUT</constant> flag in | 46 | set the <constant>V4L2_CAP_RDS_OUTPUT</constant> flag in |
@@ -40,16 +50,31 @@ Any modulator that supports RDS will set the | |||
40 | <constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield> | 50 | <constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield> |
41 | field of &v4l2-modulator;. | 51 | field of &v4l2-modulator;. |
42 | 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> |
43 | bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.</para> | 53 | bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;. |
44 | 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 | ||
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, | ||
58 | see <link linkend="writing-rds-data">Writing RDS data</link> and | ||
59 | <link linkend="fm-tx-controls">FM Transmitter Control Reference</link>.</para> | ||
45 | </section> | 60 | </section> |
46 | 61 | ||
47 | <section> | 62 | <section id="reading-rds-data"> |
48 | <title>Reading RDS data</title> | 63 | <title>Reading RDS data</title> |
49 | 64 | ||
50 | <para>RDS data can be read from the radio device | 65 | <para>RDS data can be read from the radio device |
51 | with the &func-read; function. The data is packed in groups of three bytes, | 66 | with the &func-read; function. The data is packed in groups of three bytes.</para> |
67 | </section> | ||
68 | |||
69 | <section id="writing-rds-data"> | ||
70 | <title>Writing RDS data</title> | ||
71 | |||
72 | <para>RDS data can be written to the radio device | ||
73 | with the &func-write; function. The data is packed in groups of three bytes, | ||
52 | as follows:</para> | 74 | as follows:</para> |
75 | </section> | ||
76 | |||
77 | <section> | ||
53 | <table frame="none" pgwide="1" id="v4l2-rds-data"> | 78 | <table frame="none" pgwide="1" id="v4l2-rds-data"> |
54 | <title>struct | 79 | <title>struct |
55 | <structname>v4l2_rds_data</structname></title> | 80 | <structname>v4l2_rds_data</structname></title> |
@@ -111,48 +136,57 @@ as follows:</para> | |||
111 | <tbody valign="top"> | 136 | <tbody valign="top"> |
112 | <row> | 137 | <row> |
113 | <entry>V4L2_RDS_BLOCK_MSK</entry> | 138 | <entry>V4L2_RDS_BLOCK_MSK</entry> |
139 | <entry> </entry> | ||
114 | <entry>7</entry> | 140 | <entry>7</entry> |
115 | <entry>Mask for bits 0-2 to get the block ID.</entry> | 141 | <entry>Mask for bits 0-2 to get the block ID.</entry> |
116 | </row> | 142 | </row> |
117 | <row> | 143 | <row> |
118 | <entry>V4L2_RDS_BLOCK_A</entry> | 144 | <entry>V4L2_RDS_BLOCK_A</entry> |
145 | <entry> </entry> | ||
119 | <entry>0</entry> | 146 | <entry>0</entry> |
120 | <entry>Block A.</entry> | 147 | <entry>Block A.</entry> |
121 | </row> | 148 | </row> |
122 | <row> | 149 | <row> |
123 | <entry>V4L2_RDS_BLOCK_B</entry> | 150 | <entry>V4L2_RDS_BLOCK_B</entry> |
151 | <entry> </entry> | ||
124 | <entry>1</entry> | 152 | <entry>1</entry> |
125 | <entry>Block B.</entry> | 153 | <entry>Block B.</entry> |
126 | </row> | 154 | </row> |
127 | <row> | 155 | <row> |
128 | <entry>V4L2_RDS_BLOCK_C</entry> | 156 | <entry>V4L2_RDS_BLOCK_C</entry> |
157 | <entry> </entry> | ||
129 | <entry>2</entry> | 158 | <entry>2</entry> |
130 | <entry>Block C.</entry> | 159 | <entry>Block C.</entry> |
131 | </row> | 160 | </row> |
132 | <row> | 161 | <row> |
133 | <entry>V4L2_RDS_BLOCK_D</entry> | 162 | <entry>V4L2_RDS_BLOCK_D</entry> |
163 | <entry> </entry> | ||
134 | <entry>3</entry> | 164 | <entry>3</entry> |
135 | <entry>Block D.</entry> | 165 | <entry>Block D.</entry> |
136 | </row> | 166 | </row> |
137 | <row> | 167 | <row> |
138 | <entry>V4L2_RDS_BLOCK_C_ALT</entry> | 168 | <entry>V4L2_RDS_BLOCK_C_ALT</entry> |
169 | <entry> </entry> | ||
139 | <entry>4</entry> | 170 | <entry>4</entry> |
140 | <entry>Block C'.</entry> | 171 | <entry>Block C'.</entry> |
141 | </row> | 172 | </row> |
142 | <row> | 173 | <row> |
143 | <entry>V4L2_RDS_BLOCK_INVALID</entry> | 174 | <entry>V4L2_RDS_BLOCK_INVALID</entry> |
175 | <entry>read-only</entry> | ||
144 | <entry>7</entry> | 176 | <entry>7</entry> |
145 | <entry>An invalid block.</entry> | 177 | <entry>An invalid block.</entry> |
146 | </row> | 178 | </row> |
147 | <row> | 179 | <row> |
148 | <entry>V4L2_RDS_BLOCK_CORRECTED</entry> | 180 | <entry>V4L2_RDS_BLOCK_CORRECTED</entry> |
181 | <entry>read-only</entry> | ||
149 | <entry>0x40</entry> | 182 | <entry>0x40</entry> |
150 | <entry>A bit error was detected but corrected.</entry> | 183 | <entry>A bit error was detected but corrected.</entry> |
151 | </row> | 184 | </row> |
152 | <row> | 185 | <row> |
153 | <entry>V4L2_RDS_BLOCK_ERROR</entry> | 186 | <entry>V4L2_RDS_BLOCK_ERROR</entry> |
187 | <entry>read-only</entry> | ||
154 | <entry>0x80</entry> | 188 | <entry>0x80</entry> |
155 | <entry>An incorrectable error occurred.</entry> | 189 | <entry>An uncorrectable error occurred.</entry> |
156 | </row> | 190 | </row> |
157 | </tbody> | 191 | </tbody> |
158 | </tgroup> | 192 | </tgroup> |
diff --git a/Documentation/DocBook/v4l/dev-teletext.xml b/Documentation/DocBook/v4l/dev-teletext.xml index 76184e8ed61..414b1cfff9f 100644 --- a/Documentation/DocBook/v4l/dev-teletext.xml +++ b/Documentation/DocBook/v4l/dev-teletext.xml | |||
@@ -1,35 +1,32 @@ | |||
1 | <title>Teletext Interface</title> | 1 | <title>Teletext Interface</title> |
2 | 2 | ||
3 | <para>This interface aims at devices receiving and demodulating | 3 | <para>This interface was aimed at devices receiving and demodulating |
4 | Teletext data [<xref linkend="ets300706" />, <xref linkend="itu653" />], evaluating the | 4 | Teletext data [<xref linkend="ets300706" />, <xref linkend="itu653" />], evaluating the |
5 | Teletext packages and storing formatted pages in cache memory. Such | 5 | Teletext packages and storing formatted pages in cache memory. Such |
6 | devices are usually implemented as microcontrollers with serial | 6 | devices are usually implemented as microcontrollers with serial |
7 | interface (I<superscript>2</superscript>C) and can be found on older | 7 | interface (I<superscript>2</superscript>C) and could be found on old |
8 | TV cards, dedicated Teletext decoding cards and home-brew devices | 8 | TV cards, dedicated Teletext decoding cards and home-brew devices |
9 | connected to the PC parallel port.</para> | 9 | connected to the PC parallel port.</para> |
10 | 10 | ||
11 | <para>The Teletext API was designed by Martin Buck. It is defined in | 11 | <para>The Teletext API was designed by Martin Buck. It was defined in |
12 | the kernel header file <filename>linux/videotext.h</filename>, the | 12 | the kernel header file <filename>linux/videotext.h</filename>, the |
13 | specification is available from <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/videotext/"> | 13 | specification is available from <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/videotext/"> |
14 | ftp://ftp.gwdg.de/pub/linux/misc/videotext/</ulink>. (Videotext is the name of | 14 | ftp://ftp.gwdg.de/pub/linux/misc/videotext/</ulink>. (Videotext is the name of |
15 | the German public television Teletext service.) Conventional character | 15 | the German public television Teletext service.)</para> |
16 | device file names are <filename>/dev/vtx</filename> and | ||
17 | <filename>/dev/vttuner</filename>, with device number 83, 0 and 83, 16 | ||
18 | respectively. A similar interface exists for the Philips SAA5249 | ||
19 | Teletext decoder [specification?] with character device file names | ||
20 | <filename>/dev/tlkN</filename>, device number 102, N.</para> | ||
21 | 16 | ||
22 | <para>Eventually the Teletext API was integrated into the V4L API | 17 | <para>Eventually the Teletext API was integrated into the V4L API |
23 | with character device file names <filename>/dev/vtx0</filename> to | 18 | with character device file names <filename>/dev/vtx0</filename> to |
24 | <filename>/dev/vtx31</filename>, device major number 81, minor numbers | 19 | <filename>/dev/vtx31</filename>, device major number 81, minor numbers |
25 | 192 to 223. For reference the V4L Teletext API specification is | 20 | 192 to 223.</para> |
26 | reproduced here in full: "Teletext interfaces talk the existing VTX | ||
27 | API." Teletext devices with major number 83 and 102 will be removed in | ||
28 | Linux 2.6.</para> | ||
29 | 21 | ||
30 | <para>There are no plans to replace the Teletext API or to integrate | 22 | <para>However, teletext decoders were quickly replaced by more |
31 | it into V4L2. Please write to the linux-media mailing list: &v4l-ml; | 23 | generic VBI demodulators and those dedicated teletext decoders no longer exist. |
32 | when the need arises.</para> | 24 | For many years the vtx devices were still around, even though nobody used |
25 | them. So the decision was made to finally remove support for the Teletext API in | ||
26 | kernel 2.6.37.</para> | ||
27 | |||
28 | <para>Modern devices all use the <link linkend="raw-vbi">raw</link> or | ||
29 | <link linkend="sliced">sliced</link> VBI API.</para> | ||
33 | 30 | ||
34 | <!-- | 31 | <!-- |
35 | Local Variables: | 32 | Local Variables: |
diff --git a/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml b/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml index 26e87923108..4db272b8a0d 100644 --- a/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml +++ b/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml | |||
@@ -739,7 +739,7 @@ defined in error. Drivers may interpret them as in <xref | |||
739 | <entry>b<subscript>1</subscript></entry> | 739 | <entry>b<subscript>1</subscript></entry> |
740 | <entry>b<subscript>0</subscript></entry> | 740 | <entry>b<subscript>0</subscript></entry> |
741 | </row> | 741 | </row> |
742 | <row id="V4L2-PIX-FMT-BGR666"> | 742 | <row><!-- id="V4L2-PIX-FMT-BGR666" --> |
743 | <entry><constant>V4L2_PIX_FMT_BGR666</constant></entry> | 743 | <entry><constant>V4L2_PIX_FMT_BGR666</constant></entry> |
744 | <entry>'BGRH'</entry> | 744 | <entry>'BGRH'</entry> |
745 | <entry></entry> | 745 | <entry></entry> |
diff --git a/Documentation/DocBook/v4l/pixfmt-srggb10.xml b/Documentation/DocBook/v4l/pixfmt-srggb10.xml new file mode 100644 index 00000000000..7b274092e60 --- /dev/null +++ b/Documentation/DocBook/v4l/pixfmt-srggb10.xml | |||
@@ -0,0 +1,90 @@ | |||
1 | <refentry> | ||
2 | <refmeta> | ||
3 | <refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'), | ||
4 | V4L2_PIX_FMT_SGRBG10 ('BA10'), | ||
5 | V4L2_PIX_FMT_SGBRG10 ('GB10'), | ||
6 | V4L2_PIX_FMT_SBGGR10 ('BG10'), | ||
7 | </refentrytitle> | ||
8 | &manvol; | ||
9 | </refmeta> | ||
10 | <refnamediv> | ||
11 | <refname id="V4L2-PIX-FMT-SRGGB10"><constant>V4L2_PIX_FMT_SRGGB10</constant></refname> | ||
12 | <refname id="V4L2-PIX-FMT-SGRBG10"><constant>V4L2_PIX_FMT_SGRBG10</constant></refname> | ||
13 | <refname id="V4L2-PIX-FMT-SGBRG10"><constant>V4L2_PIX_FMT_SGBRG10</constant></refname> | ||
14 | <refname id="V4L2-PIX-FMT-SBGGR10"><constant>V4L2_PIX_FMT_SBGGR10</constant></refname> | ||
15 | <refpurpose>10-bit Bayer formats expanded to 16 bits</refpurpose> | ||
16 | </refnamediv> | ||
17 | <refsect1> | ||
18 | <title>Description</title> | ||
19 | |||
20 | <para>The following four pixel formats are raw sRGB / Bayer formats with | ||
21 | 10 bits per colour. Each colour component is stored in a 16-bit word, with 6 | ||
22 | unused high bits filled with zeros. Each n-pixel row contains n/2 green samples | ||
23 | and n/2 blue or red samples, with alternating red and blue rows. Bytes are | ||
24 | stored in memory in little endian order. They are conventionally described | ||
25 | as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of these | ||
26 | formats</para> | ||
27 | |||
28 | <example> | ||
29 | <title><constant>V4L2_PIX_FMT_SBGGR10</constant> 4 × 4 | ||
30 | pixel image</title> | ||
31 | |||
32 | <formalpara> | ||
33 | <title>Byte Order.</title> | ||
34 | <para>Each cell is one byte, high 6 bits in high bytes are 0. | ||
35 | <informaltable frame="none"> | ||
36 | <tgroup cols="5" align="center"> | ||
37 | <colspec align="left" colwidth="2*" /> | ||
38 | <tbody valign="top"> | ||
39 | <row> | ||
40 | <entry>start + 0:</entry> | ||
41 | <entry>B<subscript>00low</subscript></entry> | ||
42 | <entry>B<subscript>00high</subscript></entry> | ||
43 | <entry>G<subscript>01low</subscript></entry> | ||
44 | <entry>G<subscript>01high</subscript></entry> | ||
45 | <entry>B<subscript>02low</subscript></entry> | ||
46 | <entry>B<subscript>02high</subscript></entry> | ||
47 | <entry>G<subscript>03low</subscript></entry> | ||
48 | <entry>G<subscript>03high</subscript></entry> | ||
49 | </row> | ||
50 | <row> | ||
51 | <entry>start + 8:</entry> | ||
52 | <entry>G<subscript>10low</subscript></entry> | ||
53 | <entry>G<subscript>10high</subscript></entry> | ||
54 | <entry>R<subscript>11low</subscript></entry> | ||
55 | <entry>R<subscript>11high</subscript></entry> | ||
56 | <entry>G<subscript>12low</subscript></entry> | ||
57 | <entry>G<subscript>12high</subscript></entry> | ||
58 | <entry>R<subscript>13low</subscript></entry> | ||
59 | <entry>R<subscript>13high</subscript></entry> | ||
60 | </row> | ||
61 | <row> | ||
62 | <entry>start + 16:</entry> | ||
63 | <entry>B<subscript>20low</subscript></entry> | ||
64 | <entry>B<subscript>20high</subscript></entry> | ||
65 | <entry>G<subscript>21low</subscript></entry> | ||
66 | <entry>G<subscript>21high</subscript></entry> | ||
67 | <entry>B<subscript>22low</subscript></entry> | ||
68 | <entry>B<subscript>22high</subscript></entry> | ||
69 | <entry>G<subscript>23low</subscript></entry> | ||
70 | <entry>G<subscript>23high</subscript></entry> | ||
71 | </row> | ||
72 | <row> | ||
73 | <entry>start + 24:</entry> | ||
74 | <entry>G<subscript>30low</subscript></entry> | ||
75 | <entry>G<subscript>30high</subscript></entry> | ||
76 | <entry>R<subscript>31low</subscript></entry> | ||
77 | <entry>R<subscript>31high</subscript></entry> | ||
78 | <entry>G<subscript>32low</subscript></entry> | ||
79 | <entry>G<subscript>32high</subscript></entry> | ||
80 | <entry>R<subscript>33low</subscript></entry> | ||
81 | <entry>R<subscript>33high</subscript></entry> | ||
82 | </row> | ||
83 | </tbody> | ||
84 | </tgroup> | ||
85 | </informaltable> | ||
86 | </para> | ||
87 | </formalpara> | ||
88 | </example> | ||
89 | </refsect1> | ||
90 | </refentry> | ||
diff --git a/Documentation/DocBook/v4l/pixfmt-srggb8.xml b/Documentation/DocBook/v4l/pixfmt-srggb8.xml new file mode 100644 index 00000000000..2570e3be3cf --- /dev/null +++ b/Documentation/DocBook/v4l/pixfmt-srggb8.xml | |||
@@ -0,0 +1,67 @@ | |||
1 | <refentry id="V4L2-PIX-FMT-SRGGB8"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>V4L2_PIX_FMT_SRGGB8 ('RGGB')</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | <refnamediv> | ||
7 | <refname><constant>V4L2_PIX_FMT_SRGGB8</constant></refname> | ||
8 | <refpurpose>Bayer RGB format</refpurpose> | ||
9 | </refnamediv> | ||
10 | <refsect1> | ||
11 | <title>Description</title> | ||
12 | |||
13 | <para>This is commonly the native format of digital cameras, | ||
14 | reflecting the arrangement of sensors on the CCD device. Only one red, | ||
15 | green or blue value is given for each pixel. Missing components must | ||
16 | be interpolated from neighbouring pixels. From left to right the first | ||
17 | row consists of a red and green value, the second row of a green and | ||
18 | blue value. This scheme repeats to the right and down for every two | ||
19 | columns and rows.</para> | ||
20 | |||
21 | <example> | ||
22 | <title><constant>V4L2_PIX_FMT_SRGGB8</constant> 4 × 4 | ||
23 | pixel image</title> | ||
24 | |||
25 | <formalpara> | ||
26 | <title>Byte Order.</title> | ||
27 | <para>Each cell is one byte. | ||
28 | <informaltable frame="none"> | ||
29 | <tgroup cols="5" align="center"> | ||
30 | <colspec align="left" colwidth="2*" /> | ||
31 | <tbody valign="top"> | ||
32 | <row> | ||
33 | <entry>start + 0:</entry> | ||
34 | <entry>R<subscript>00</subscript></entry> | ||
35 | <entry>G<subscript>01</subscript></entry> | ||
36 | <entry>R<subscript>02</subscript></entry> | ||
37 | <entry>G<subscript>03</subscript></entry> | ||
38 | </row> | ||
39 | <row> | ||
40 | <entry>start + 4:</entry> | ||
41 | <entry>G<subscript>10</subscript></entry> | ||
42 | <entry>B<subscript>11</subscript></entry> | ||
43 | <entry>G<subscript>12</subscript></entry> | ||
44 | <entry>B<subscript>13</subscript></entry> | ||
45 | </row> | ||
46 | <row> | ||
47 | <entry>start + 8:</entry> | ||
48 | <entry>R<subscript>20</subscript></entry> | ||
49 | <entry>G<subscript>21</subscript></entry> | ||
50 | <entry>R<subscript>22</subscript></entry> | ||
51 | <entry>G<subscript>23</subscript></entry> | ||
52 | </row> | ||
53 | <row> | ||
54 | <entry>start + 12:</entry> | ||
55 | <entry>G<subscript>30</subscript></entry> | ||
56 | <entry>B<subscript>31</subscript></entry> | ||
57 | <entry>G<subscript>32</subscript></entry> | ||
58 | <entry>B<subscript>33</subscript></entry> | ||
59 | </row> | ||
60 | </tbody> | ||
61 | </tgroup> | ||
62 | </informaltable> | ||
63 | </para> | ||
64 | </formalpara> | ||
65 | </example> | ||
66 | </refsect1> | ||
67 | </refentry> | ||
diff --git a/Documentation/DocBook/v4l/pixfmt-y10.xml b/Documentation/DocBook/v4l/pixfmt-y10.xml new file mode 100644 index 00000000000..d065043db8d --- /dev/null +++ b/Documentation/DocBook/v4l/pixfmt-y10.xml | |||
@@ -0,0 +1,79 @@ | |||
1 | <refentry id="V4L2-PIX-FMT-Y10"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>V4L2_PIX_FMT_Y10 ('Y10 ')</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | <refnamediv> | ||
7 | <refname><constant>V4L2_PIX_FMT_Y10</constant></refname> | ||
8 | <refpurpose>Grey-scale image</refpurpose> | ||
9 | </refnamediv> | ||
10 | <refsect1> | ||
11 | <title>Description</title> | ||
12 | |||
13 | <para>This is a grey-scale image with a depth of 10 bits per pixel. Pixels | ||
14 | are stored in 16-bit words with unused high bits padded with 0. The least | ||
15 | significant byte is stored at lower memory addresses (little-endian).</para> | ||
16 | |||
17 | <example> | ||
18 | <title><constant>V4L2_PIX_FMT_Y10</constant> 4 × 4 | ||
19 | pixel image</title> | ||
20 | |||
21 | <formalpara> | ||
22 | <title>Byte Order.</title> | ||
23 | <para>Each cell is one byte. | ||
24 | <informaltable frame="none"> | ||
25 | <tgroup cols="9" align="center"> | ||
26 | <colspec align="left" colwidth="2*" /> | ||
27 | <tbody valign="top"> | ||
28 | <row> | ||
29 | <entry>start + 0:</entry> | ||
30 | <entry>Y'<subscript>00low</subscript></entry> | ||
31 | <entry>Y'<subscript>00high</subscript></entry> | ||
32 | <entry>Y'<subscript>01low</subscript></entry> | ||
33 | <entry>Y'<subscript>01high</subscript></entry> | ||
34 | <entry>Y'<subscript>02low</subscript></entry> | ||
35 | <entry>Y'<subscript>02high</subscript></entry> | ||
36 | <entry>Y'<subscript>03low</subscript></entry> | ||
37 | <entry>Y'<subscript>03high</subscript></entry> | ||
38 | </row> | ||
39 | <row> | ||
40 | <entry>start + 8:</entry> | ||
41 | <entry>Y'<subscript>10low</subscript></entry> | ||
42 | <entry>Y'<subscript>10high</subscript></entry> | ||
43 | <entry>Y'<subscript>11low</subscript></entry> | ||
44 | <entry>Y'<subscript>11high</subscript></entry> | ||
45 | <entry>Y'<subscript>12low</subscript></entry> | ||
46 | <entry>Y'<subscript>12high</subscript></entry> | ||
47 | <entry>Y'<subscript>13low</subscript></entry> | ||
48 | <entry>Y'<subscript>13high</subscript></entry> | ||
49 | </row> | ||
50 | <row> | ||
51 | <entry>start + 16:</entry> | ||
52 | <entry>Y'<subscript>20low</subscript></entry> | ||
53 | <entry>Y'<subscript>20high</subscript></entry> | ||
54 | <entry>Y'<subscript>21low</subscript></entry> | ||
55 | <entry>Y'<subscript>21high</subscript></entry> | ||
56 | <entry>Y'<subscript>22low</subscript></entry> | ||
57 | <entry>Y'<subscript>22high</subscript></entry> | ||
58 | <entry>Y'<subscript>23low</subscript></entry> | ||
59 | <entry>Y'<subscript>23high</subscript></entry> | ||
60 | </row> | ||
61 | <row> | ||
62 | <entry>start + 24:</entry> | ||
63 | <entry>Y'<subscript>30low</subscript></entry> | ||
64 | <entry>Y'<subscript>30high</subscript></entry> | ||
65 | <entry>Y'<subscript>31low</subscript></entry> | ||
66 | <entry>Y'<subscript>31high</subscript></entry> | ||
67 | <entry>Y'<subscript>32low</subscript></entry> | ||
68 | <entry>Y'<subscript>32high</subscript></entry> | ||
69 | <entry>Y'<subscript>33low</subscript></entry> | ||
70 | <entry>Y'<subscript>33high</subscript></entry> | ||
71 | </row> | ||
72 | </tbody> | ||
73 | </tgroup> | ||
74 | </informaltable> | ||
75 | </para> | ||
76 | </formalpara> | ||
77 | </example> | ||
78 | </refsect1> | ||
79 | </refentry> | ||
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml index c4ad0a8e42d..d7c46718709 100644 --- a/Documentation/DocBook/v4l/pixfmt.xml +++ b/Documentation/DocBook/v4l/pixfmt.xml | |||
@@ -566,7 +566,9 @@ access the palette, this must be done with ioctls of the Linux framebuffer API.< | |||
566 | &sub-sbggr8; | 566 | &sub-sbggr8; |
567 | &sub-sgbrg8; | 567 | &sub-sgbrg8; |
568 | &sub-sgrbg8; | 568 | &sub-sgrbg8; |
569 | &sub-srggb8; | ||
569 | &sub-sbggr16; | 570 | &sub-sbggr16; |
571 | &sub-srggb10; | ||
570 | </section> | 572 | </section> |
571 | 573 | ||
572 | <section id="yuv-formats"> | 574 | <section id="yuv-formats"> |
@@ -589,6 +591,7 @@ information.</para> | |||
589 | 591 | ||
590 | &sub-packed-yuv; | 592 | &sub-packed-yuv; |
591 | &sub-grey; | 593 | &sub-grey; |
594 | &sub-y10; | ||
592 | &sub-y16; | 595 | &sub-y16; |
593 | &sub-yuyv; | 596 | &sub-yuyv; |
594 | &sub-uyvy; | 597 | &sub-uyvy; |
@@ -685,6 +688,11 @@ http://www.ivtvdriver.org/</ulink></para><para>The format is documented in the | |||
685 | kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm12</filename> | 688 | kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm12</filename> |
686 | </para></entry> | 689 | </para></entry> |
687 | </row> | 690 | </row> |
691 | <row id="V4L2-PIX-FMT-CPIA1"> | ||
692 | <entry><constant>V4L2_PIX_FMT_CPIA1</constant></entry> | ||
693 | <entry>'CPIA'</entry> | ||
694 | <entry>YUV format used by the gspca cpia1 driver.</entry> | ||
695 | </row> | ||
688 | <row id="V4L2-PIX-FMT-SPCA501"> | 696 | <row id="V4L2-PIX-FMT-SPCA501"> |
689 | <entry><constant>V4L2_PIX_FMT_SPCA501</constant></entry> | 697 | <entry><constant>V4L2_PIX_FMT_SPCA501</constant></entry> |
690 | <entry>'S501'</entry> | 698 | <entry>'S501'</entry> |
@@ -705,11 +713,6 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm | |||
705 | <entry>'S561'</entry> | 713 | <entry>'S561'</entry> |
706 | <entry>Compressed GBRG Bayer format used by the gspca driver.</entry> | 714 | <entry>Compressed GBRG Bayer format used by the gspca driver.</entry> |
707 | </row> | 715 | </row> |
708 | <row id="V4L2-PIX-FMT-SGRBG10"> | ||
709 | <entry><constant>V4L2_PIX_FMT_SGRBG10</constant></entry> | ||
710 | <entry>'DA10'</entry> | ||
711 | <entry>10 bit raw Bayer, expanded to 16 bits.</entry> | ||
712 | </row> | ||
713 | <row id="V4L2-PIX-FMT-SGRBG10DPCM8"> | 716 | <row id="V4L2-PIX-FMT-SGRBG10DPCM8"> |
714 | <entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry> | 717 | <entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry> |
715 | <entry>'DB10'</entry> | 718 | <entry>'DB10'</entry> |
@@ -770,6 +773,11 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm | |||
770 | <entry>'S920'</entry> | 773 | <entry>'S920'</entry> |
771 | <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry> | 774 | <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry> |
772 | </row> | 775 | </row> |
776 | <row id="V4L2-PIX-FMT-SN9C2028"> | ||
777 | <entry><constant>V4L2_PIX_FMT_SN9C2028</constant></entry> | ||
778 | <entry>'SONX'</entry> | ||
779 | <entry>Compressed GBRG bayer format of the gspca sn9c2028 driver.</entry> | ||
780 | </row> | ||
773 | <row id="V4L2-PIX-FMT-STV0680"> | 781 | <row id="V4L2-PIX-FMT-STV0680"> |
774 | <entry><constant>V4L2_PIX_FMT_STV0680</constant></entry> | 782 | <entry><constant>V4L2_PIX_FMT_STV0680</constant></entry> |
775 | <entry>'S680'</entry> | 783 | <entry>'S680'</entry> |
@@ -787,6 +795,20 @@ http://www.thedirks.org/winnov/</ulink></para></entry> | |||
787 | <entry>'TM60'</entry> | 795 | <entry>'TM60'</entry> |
788 | <entry><para>Used by Trident tm6000</para></entry> | 796 | <entry><para>Used by Trident tm6000</para></entry> |
789 | </row> | 797 | </row> |
798 | <row id="V4L2-PIX-FMT-CIT-YYVYUY"> | ||
799 | <entry><constant>V4L2_PIX_FMT_CIT_YYVYUY</constant></entry> | ||
800 | <entry>'CITV'</entry> | ||
801 | <entry><para>Used by xirlink CIT, found at IBM webcams.</para> | ||
802 | <para>Uses one line of Y then 1 line of VYUY</para> | ||
803 | </entry> | ||
804 | </row> | ||
805 | <row id="V4L2-PIX-FMT-KONICA420"> | ||
806 | <entry><constant>V4L2_PIX_FMT_KONICA420</constant></entry> | ||
807 | <entry>'KONI'</entry> | ||
808 | <entry><para>Used by Konica webcams.</para> | ||
809 | <para>YUV420 planar in blocks of 256 pixels.</para> | ||
810 | </entry> | ||
811 | </row> | ||
790 | <row id="V4L2-PIX-FMT-YYUV"> | 812 | <row id="V4L2-PIX-FMT-YYUV"> |
791 | <entry><constant>V4L2_PIX_FMT_YYUV</constant></entry> | 813 | <entry><constant>V4L2_PIX_FMT_YYUV</constant></entry> |
792 | <entry>'YYUV'</entry> | 814 | <entry>'YYUV'</entry> |
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml index 7c3c098d5d0..839e93e875a 100644 --- a/Documentation/DocBook/v4l/v4l2.xml +++ b/Documentation/DocBook/v4l/v4l2.xml | |||
@@ -99,6 +99,7 @@ Remote Controller chapter.</contrib> | |||
99 | <year>2007</year> | 99 | <year>2007</year> |
100 | <year>2008</year> | 100 | <year>2008</year> |
101 | <year>2009</year> | 101 | <year>2009</year> |
102 | <year>2010</year> | ||
102 | <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin | 103 | <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin |
103 | Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> | 104 | Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> |
104 | </copyright> | 105 | </copyright> |
@@ -110,10 +111,17 @@ Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> | |||
110 | <!-- Put document revisions here, newest first. --> | 111 | <!-- Put document revisions here, newest first. --> |
111 | <!-- API revisions (changes and additions of defines, enums, | 112 | <!-- API revisions (changes and additions of defines, enums, |
112 | structs, ioctls) must be noted in more detail in the history chapter | 113 | structs, ioctls) must be noted in more detail in the history chapter |
113 | (compat.sgml), along with the possible impact on existing drivers and | 114 | (compat.xml), along with the possible impact on existing drivers and |
114 | applications. --> | 115 | applications. --> |
115 | 116 | ||
116 | <revision> | 117 | <revision> |
118 | <revnumber>2.6.37</revnumber> | ||
119 | <date>2010-08-06</date> | ||
120 | <authorinitials>hv</authorinitials> | ||
121 | <revremark>Removed obsolete vtx (videotext) API.</revremark> | ||
122 | </revision> | ||
123 | |||
124 | <revision> | ||
117 | <revnumber>2.6.33</revnumber> | 125 | <revnumber>2.6.33</revnumber> |
118 | <date>2009-12-03</date> | 126 | <date>2009-12-03</date> |
119 | <authorinitials>mk</authorinitials> | 127 | <authorinitials>mk</authorinitials> |
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml index 865b06d9e67..325b23b6964 100644 --- a/Documentation/DocBook/v4l/videodev2.h.xml +++ b/Documentation/DocBook/v4l/videodev2.h.xml | |||
@@ -154,23 +154,13 @@ enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> { | |||
154 | V4L2_BUF_TYPE_VBI_OUTPUT = 5, | 154 | V4L2_BUF_TYPE_VBI_OUTPUT = 5, |
155 | V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, | 155 | V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, |
156 | V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, | 156 | V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, |
157 | #if 1 /*KEEP*/ | 157 | #if 1 |
158 | /* Experimental */ | 158 | /* Experimental */ |
159 | V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, | 159 | V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, |
160 | #endif | 160 | #endif |
161 | V4L2_BUF_TYPE_PRIVATE = 0x80, | 161 | V4L2_BUF_TYPE_PRIVATE = 0x80, |
162 | }; | 162 | }; |
163 | 163 | ||
164 | enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> { | ||
165 | V4L2_CTRL_TYPE_INTEGER = 1, | ||
166 | V4L2_CTRL_TYPE_BOOLEAN = 2, | ||
167 | V4L2_CTRL_TYPE_MENU = 3, | ||
168 | V4L2_CTRL_TYPE_BUTTON = 4, | ||
169 | V4L2_CTRL_TYPE_INTEGER64 = 5, | ||
170 | V4L2_CTRL_TYPE_CTRL_CLASS = 6, | ||
171 | V4L2_CTRL_TYPE_STRING = 7, | ||
172 | }; | ||
173 | |||
174 | enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> { | 164 | enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> { |
175 | V4L2_TUNER_RADIO = 1, | 165 | V4L2_TUNER_RADIO = 1, |
176 | V4L2_TUNER_ANALOG_TV = 2, | 166 | V4L2_TUNER_ANALOG_TV = 2, |
@@ -288,6 +278,7 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> { | |||
288 | #define <link linkend="V4L2-PIX-FMT-RGB565">V4L2_PIX_FMT_RGB565</link> v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ | 278 | #define <link linkend="V4L2-PIX-FMT-RGB565">V4L2_PIX_FMT_RGB565</link> v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ |
289 | #define <link linkend="V4L2-PIX-FMT-RGB555X">V4L2_PIX_FMT_RGB555X</link> v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ | 279 | #define <link linkend="V4L2-PIX-FMT-RGB555X">V4L2_PIX_FMT_RGB555X</link> v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ |
290 | #define <link linkend="V4L2-PIX-FMT-RGB565X">V4L2_PIX_FMT_RGB565X</link> v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ | 280 | #define <link linkend="V4L2-PIX-FMT-RGB565X">V4L2_PIX_FMT_RGB565X</link> v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ |
281 | #define <link linkend="V4L2-PIX-FMT-BGR666">V4L2_PIX_FMT_BGR666</link> v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ | ||
291 | #define <link linkend="V4L2-PIX-FMT-BGR24">V4L2_PIX_FMT_BGR24</link> v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ | 282 | #define <link linkend="V4L2-PIX-FMT-BGR24">V4L2_PIX_FMT_BGR24</link> v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ |
292 | #define <link linkend="V4L2-PIX-FMT-RGB24">V4L2_PIX_FMT_RGB24</link> v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ | 283 | #define <link linkend="V4L2-PIX-FMT-RGB24">V4L2_PIX_FMT_RGB24</link> v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ |
293 | #define <link linkend="V4L2-PIX-FMT-BGR32">V4L2_PIX_FMT_BGR32</link> v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ | 284 | #define <link linkend="V4L2-PIX-FMT-BGR32">V4L2_PIX_FMT_BGR32</link> v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ |
@@ -295,6 +286,9 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> { | |||
295 | 286 | ||
296 | /* Grey formats */ | 287 | /* Grey formats */ |
297 | #define <link linkend="V4L2-PIX-FMT-GREY">V4L2_PIX_FMT_GREY</link> v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ | 288 | #define <link linkend="V4L2-PIX-FMT-GREY">V4L2_PIX_FMT_GREY</link> v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ |
289 | #define <link linkend="V4L2-PIX-FMT-Y4">V4L2_PIX_FMT_Y4</link> v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ | ||
290 | #define <link linkend="V4L2-PIX-FMT-Y6">V4L2_PIX_FMT_Y6</link> v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ | ||
291 | #define <link linkend="V4L2-PIX-FMT-Y10">V4L2_PIX_FMT_Y10</link> v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ | ||
298 | #define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link> v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ | 292 | #define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link> v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ |
299 | 293 | ||
300 | /* Palette formats */ | 294 | /* Palette formats */ |
@@ -330,7 +324,11 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> { | |||
330 | #define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ | 324 | #define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ |
331 | #define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ | 325 | #define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ |
332 | #define <link linkend="V4L2-PIX-FMT-SGRBG8">V4L2_PIX_FMT_SGRBG8</link> v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ | 326 | #define <link linkend="V4L2-PIX-FMT-SGRBG8">V4L2_PIX_FMT_SGRBG8</link> v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ |
333 | #define <link linkend="V4L2-PIX-FMT-SGRBG10">V4L2_PIX_FMT_SGRBG10</link> v4l2_fourcc('B', 'A', '1', '0') /* 10bit raw bayer */ | 327 | #define <link linkend="V4L2-PIX-FMT-SRGGB8">V4L2_PIX_FMT_SRGGB8</link> v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ |
328 | #define <link linkend="V4L2-PIX-FMT-SBGGR10">V4L2_PIX_FMT_SBGGR10</link> v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ | ||
329 | #define <link linkend="V4L2-PIX-FMT-SGBRG10">V4L2_PIX_FMT_SGBRG10</link> v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ | ||
330 | #define <link linkend="V4L2-PIX-FMT-SGRBG10">V4L2_PIX_FMT_SGRBG10</link> v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ | ||
331 | #define <link linkend="V4L2-PIX-FMT-SRGGB10">V4L2_PIX_FMT_SRGGB10</link> v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ | ||
334 | /* 10bit raw bayer DPCM compressed to 8 bits */ | 332 | /* 10bit raw bayer DPCM compressed to 8 bits */ |
335 | #define <link linkend="V4L2-PIX-FMT-SGRBG10DPCM8">V4L2_PIX_FMT_SGRBG10DPCM8</link> v4l2_fourcc('B', 'D', '1', '0') | 333 | #define <link linkend="V4L2-PIX-FMT-SGRBG10DPCM8">V4L2_PIX_FMT_SGRBG10DPCM8</link> v4l2_fourcc('B', 'D', '1', '0') |
336 | /* | 334 | /* |
@@ -346,6 +344,7 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> { | |||
346 | #define <link linkend="V4L2-PIX-FMT-MPEG">V4L2_PIX_FMT_MPEG</link> v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */ | 344 | #define <link linkend="V4L2-PIX-FMT-MPEG">V4L2_PIX_FMT_MPEG</link> v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */ |
347 | 345 | ||
348 | /* Vendor-specific formats */ | 346 | /* Vendor-specific formats */ |
347 | #define <link linkend="V4L2-PIX-FMT-CPIA1">V4L2_PIX_FMT_CPIA1</link> v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ | ||
349 | #define <link linkend="V4L2-PIX-FMT-WNVA">V4L2_PIX_FMT_WNVA</link> v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ | 348 | #define <link linkend="V4L2-PIX-FMT-WNVA">V4L2_PIX_FMT_WNVA</link> v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ |
350 | #define <link linkend="V4L2-PIX-FMT-SN9C10X">V4L2_PIX_FMT_SN9C10X</link> v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ | 349 | #define <link linkend="V4L2-PIX-FMT-SN9C10X">V4L2_PIX_FMT_SN9C10X</link> v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ |
351 | #define <link linkend="V4L2-PIX-FMT-SN9C20X-I420">V4L2_PIX_FMT_SN9C20X_I420</link> v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ | 350 | #define <link linkend="V4L2-PIX-FMT-SN9C20X-I420">V4L2_PIX_FMT_SN9C20X_I420</link> v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ |
@@ -358,12 +357,15 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> { | |||
358 | #define <link linkend="V4L2-PIX-FMT-SPCA561">V4L2_PIX_FMT_SPCA561</link> v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ | 357 | #define <link linkend="V4L2-PIX-FMT-SPCA561">V4L2_PIX_FMT_SPCA561</link> v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ |
359 | #define <link linkend="V4L2-PIX-FMT-PAC207">V4L2_PIX_FMT_PAC207</link> v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ | 358 | #define <link linkend="V4L2-PIX-FMT-PAC207">V4L2_PIX_FMT_PAC207</link> v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ |
360 | #define <link linkend="V4L2-PIX-FMT-MR97310A">V4L2_PIX_FMT_MR97310A</link> v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ | 359 | #define <link linkend="V4L2-PIX-FMT-MR97310A">V4L2_PIX_FMT_MR97310A</link> v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ |
360 | #define <link linkend="V4L2-PIX-FMT-SN9C2028">V4L2_PIX_FMT_SN9C2028</link> v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ | ||
361 | #define <link linkend="V4L2-PIX-FMT-SQ905C">V4L2_PIX_FMT_SQ905C</link> v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ | 361 | #define <link linkend="V4L2-PIX-FMT-SQ905C">V4L2_PIX_FMT_SQ905C</link> v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ |
362 | #define <link linkend="V4L2-PIX-FMT-PJPG">V4L2_PIX_FMT_PJPG</link> v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ | 362 | #define <link linkend="V4L2-PIX-FMT-PJPG">V4L2_PIX_FMT_PJPG</link> v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ |
363 | #define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link> v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ | 363 | #define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link> v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ |
364 | #define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link> v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ | 364 | #define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link> v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ |
365 | #define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ | ||
366 | #define <link linkend="V4L2-PIX-FMT-STV0680">V4L2_PIX_FMT_STV0680</link> v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ | 365 | #define <link linkend="V4L2-PIX-FMT-STV0680">V4L2_PIX_FMT_STV0680</link> v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ |
366 | #define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ | ||
367 | #define <link linkend="V4L2-PIX-FMT-CIT-YYVYUY">V4L2_PIX_FMT_CIT_YYVYUY</link> v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ | ||
368 | #define <link linkend="V4L2-PIX-FMT-KONICA420">V4L2_PIX_FMT_KONICA420</link> v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ | ||
367 | 369 | ||
368 | /* | 370 | /* |
369 | * F O R M A T E N U M E R A T I O N | 371 | * F O R M A T E N U M E R A T I O N |
@@ -380,7 +382,7 @@ struct <link linkend="v4l2-fmtdesc">v4l2_fmtdesc</link> { | |||
380 | #define V4L2_FMT_FLAG_COMPRESSED 0x0001 | 382 | #define V4L2_FMT_FLAG_COMPRESSED 0x0001 |
381 | #define V4L2_FMT_FLAG_EMULATED 0x0002 | 383 | #define V4L2_FMT_FLAG_EMULATED 0x0002 |
382 | 384 | ||
383 | #if 1 /*KEEP*/ | 385 | #if 1 |
384 | /* Experimental Frame Size and frame rate enumeration */ | 386 | /* Experimental Frame Size and frame rate enumeration */ |
385 | /* | 387 | /* |
386 | * F R A M E S I Z E E N U M E R A T I O N | 388 | * F R A M E S I Z E E N U M E R A T I O N |
@@ -544,6 +546,8 @@ struct <link linkend="v4l2-buffer">v4l2_buffer</link> { | |||
544 | #define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ | 546 | #define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ |
545 | #define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ | 547 | #define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ |
546 | #define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ | 548 | #define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ |
549 | /* Buffer is ready, but the data contained within is corrupted. */ | ||
550 | #define V4L2_BUF_FLAG_ERROR 0x0040 | ||
547 | #define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ | 551 | #define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ |
548 | #define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ | 552 | #define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ |
549 | 553 | ||
@@ -934,6 +938,16 @@ struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link> { | |||
934 | #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) | 938 | #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) |
935 | #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) | 939 | #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) |
936 | 940 | ||
941 | enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> { | ||
942 | V4L2_CTRL_TYPE_INTEGER = 1, | ||
943 | V4L2_CTRL_TYPE_BOOLEAN = 2, | ||
944 | V4L2_CTRL_TYPE_MENU = 3, | ||
945 | V4L2_CTRL_TYPE_BUTTON = 4, | ||
946 | V4L2_CTRL_TYPE_INTEGER64 = 5, | ||
947 | V4L2_CTRL_TYPE_CTRL_CLASS = 6, | ||
948 | V4L2_CTRL_TYPE_STRING = 7, | ||
949 | }; | ||
950 | |||
937 | /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ | 951 | /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ |
938 | struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link> { | 952 | struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link> { |
939 | __u32 id; | 953 | __u32 id; |
@@ -1018,21 +1032,27 @@ enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> { | |||
1018 | V4L2_COLORFX_NONE = 0, | 1032 | V4L2_COLORFX_NONE = 0, |
1019 | V4L2_COLORFX_BW = 1, | 1033 | V4L2_COLORFX_BW = 1, |
1020 | V4L2_COLORFX_SEPIA = 2, | 1034 | V4L2_COLORFX_SEPIA = 2, |
1021 | V4L2_COLORFX_NEGATIVE = 3, | 1035 | V4L2_COLORFX_NEGATIVE = 3, |
1022 | V4L2_COLORFX_EMBOSS = 4, | 1036 | V4L2_COLORFX_EMBOSS = 4, |
1023 | V4L2_COLORFX_SKETCH = 5, | 1037 | V4L2_COLORFX_SKETCH = 5, |
1024 | V4L2_COLORFX_SKY_BLUE = 6, | 1038 | V4L2_COLORFX_SKY_BLUE = 6, |
1025 | V4L2_COLORFX_GRASS_GREEN = 7, | 1039 | V4L2_COLORFX_GRASS_GREEN = 7, |
1026 | V4L2_COLORFX_SKIN_WHITEN = 8, | 1040 | V4L2_COLORFX_SKIN_WHITEN = 8, |
1027 | V4L2_COLORFX_VIVID = 9. | 1041 | V4L2_COLORFX_VIVID = 9, |
1028 | }; | 1042 | }; |
1029 | #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) | 1043 | #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) |
1030 | #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) | 1044 | #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) |
1031 | 1045 | ||
1032 | #define V4L2_CID_ROTATE (V4L2_CID_BASE+34) | 1046 | #define V4L2_CID_ROTATE (V4L2_CID_BASE+34) |
1033 | #define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) | 1047 | #define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) |
1048 | |||
1049 | #define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) | ||
1050 | |||
1051 | #define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) | ||
1052 | #define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) | ||
1053 | |||
1034 | /* last CID + 1 */ | 1054 | /* last CID + 1 */ |
1035 | #define V4L2_CID_LASTP1 (V4L2_CID_BASE+36) | 1055 | #define V4L2_CID_LASTP1 (V4L2_CID_BASE+39) |
1036 | 1056 | ||
1037 | /* MPEG-class control IDs defined by V4L2 */ | 1057 | /* MPEG-class control IDs defined by V4L2 */ |
1038 | #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) | 1058 | #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) |
@@ -1349,6 +1369,8 @@ struct <link linkend="v4l2-modulator">v4l2_modulator</link> { | |||
1349 | #define V4L2_TUNER_CAP_SAP 0x0020 | 1369 | #define V4L2_TUNER_CAP_SAP 0x0020 |
1350 | #define V4L2_TUNER_CAP_LANG1 0x0040 | 1370 | #define V4L2_TUNER_CAP_LANG1 0x0040 |
1351 | #define V4L2_TUNER_CAP_RDS 0x0080 | 1371 | #define V4L2_TUNER_CAP_RDS 0x0080 |
1372 | #define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 | ||
1373 | #define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 | ||
1352 | 1374 | ||
1353 | /* Flags for the 'rxsubchans' field */ | 1375 | /* Flags for the 'rxsubchans' field */ |
1354 | #define V4L2_TUNER_SUB_MONO 0x0001 | 1376 | #define V4L2_TUNER_SUB_MONO 0x0001 |
@@ -1378,7 +1400,8 @@ struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link> { | |||
1378 | enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> type; | 1400 | enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> type; |
1379 | __u32 seek_upward; | 1401 | __u32 seek_upward; |
1380 | __u32 wrap_around; | 1402 | __u32 wrap_around; |
1381 | __u32 reserved[8]; | 1403 | __u32 spacing; |
1404 | __u32 reserved[7]; | ||
1382 | }; | 1405 | }; |
1383 | 1406 | ||
1384 | /* | 1407 | /* |
@@ -1433,7 +1456,7 @@ struct <link linkend="v4l2-audioout">v4l2_audioout</link> { | |||
1433 | * | 1456 | * |
1434 | * NOTE: EXPERIMENTAL API | 1457 | * NOTE: EXPERIMENTAL API |
1435 | */ | 1458 | */ |
1436 | #if 1 /*KEEP*/ | 1459 | #if 1 |
1437 | #define V4L2_ENC_IDX_FRAME_I (0) | 1460 | #define V4L2_ENC_IDX_FRAME_I (0) |
1438 | #define V4L2_ENC_IDX_FRAME_P (1) | 1461 | #define V4L2_ENC_IDX_FRAME_P (1) |
1439 | #define V4L2_ENC_IDX_FRAME_B (2) | 1462 | #define V4L2_ENC_IDX_FRAME_B (2) |
@@ -1626,6 +1649,38 @@ struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> { | |||
1626 | }; | 1649 | }; |
1627 | 1650 | ||
1628 | /* | 1651 | /* |
1652 | * E V E N T S | ||
1653 | */ | ||
1654 | |||
1655 | #define V4L2_EVENT_ALL 0 | ||
1656 | #define V4L2_EVENT_VSYNC 1 | ||
1657 | #define V4L2_EVENT_EOS 2 | ||
1658 | #define V4L2_EVENT_PRIVATE_START 0x08000000 | ||
1659 | |||
1660 | /* Payload for V4L2_EVENT_VSYNC */ | ||
1661 | struct <link linkend="v4l2-event-vsync">v4l2_event_vsync</link> { | ||
1662 | /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ | ||
1663 | __u8 field; | ||
1664 | } __attribute__ ((packed)); | ||
1665 | |||
1666 | struct <link linkend="v4l2-event">v4l2_event</link> { | ||
1667 | __u32 type; | ||
1668 | union { | ||
1669 | struct <link linkend="v4l2-event-vsync">v4l2_event_vsync</link> vsync; | ||
1670 | __u8 data[64]; | ||
1671 | } u; | ||
1672 | __u32 pending; | ||
1673 | __u32 sequence; | ||
1674 | struct timespec timestamp; | ||
1675 | __u32 reserved[9]; | ||
1676 | }; | ||
1677 | |||
1678 | struct <link linkend="v4l2-event-subscription">v4l2_event_subscription</link> { | ||
1679 | __u32 type; | ||
1680 | __u32 reserved[7]; | ||
1681 | }; | ||
1682 | |||
1683 | /* | ||
1629 | * A D V A N C E D D E B U G G I N G | 1684 | * A D V A N C E D D E B U G G I N G |
1630 | * | 1685 | * |
1631 | * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! | 1686 | * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! |
@@ -1720,7 +1775,7 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> { | |||
1720 | #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>) | 1775 | #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>) |
1721 | #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>) | 1776 | #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>) |
1722 | #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>) | 1777 | #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>) |
1723 | #if 1 /*KEEP*/ | 1778 | #if 1 |
1724 | #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link>) | 1779 | #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link>) |
1725 | #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link>) | 1780 | #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link>) |
1726 | #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link>) | 1781 | #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link>) |
@@ -1728,7 +1783,7 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> { | |||
1728 | #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>) | 1783 | #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>) |
1729 | #endif | 1784 | #endif |
1730 | 1785 | ||
1731 | #if 1 /*KEEP*/ | 1786 | #if 1 |
1732 | /* Experimental, meant for debugging, testing and internal use. | 1787 | /* Experimental, meant for debugging, testing and internal use. |
1733 | Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. | 1788 | Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. |
1734 | You must be root to use these ioctls. Never use these in applications! */ | 1789 | You must be root to use these ioctls. Never use these in applications! */ |
@@ -1747,6 +1802,9 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> { | |||
1747 | #define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>) | 1802 | #define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>) |
1748 | #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>) | 1803 | #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>) |
1749 | #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>) | 1804 | #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>) |
1805 | #define VIDIOC_DQEVENT _IOR('V', 89, struct <link linkend="v4l2-event">v4l2_event</link>) | ||
1806 | #define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct <link linkend="v4l2-event-subscription">v4l2_event_subscription</link>) | ||
1807 | #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct <link linkend="v4l2-event-subscription">v4l2_event_subscription</link>) | ||
1750 | 1808 | ||
1751 | /* Reminder: when adding new ioctls please add support for them to | 1809 | /* Reminder: when adding new ioctls please add support for them to |
1752 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ | 1810 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ |
diff --git a/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml index 3c6784e132f..d733721a751 100644 --- a/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml +++ b/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml | |||
@@ -16,8 +16,7 @@ | |||
16 | <funcdef>int <function>ioctl</function></funcdef> | 16 | <funcdef>int <function>ioctl</function></funcdef> |
17 | <paramdef>int <parameter>fd</parameter></paramdef> | 17 | <paramdef>int <parameter>fd</parameter></paramdef> |
18 | <paramdef>int <parameter>request</parameter></paramdef> | 18 | <paramdef>int <parameter>request</parameter></paramdef> |
19 | <paramdef>&v4l2-dv-preset; | 19 | <paramdef>struct v4l2_dv_preset *<parameter>argp</parameter></paramdef> |
20 | *<parameter>argp</parameter></paramdef> | ||
21 | </funcprototype> | 20 | </funcprototype> |
22 | </funcsynopsis> | 21 | </funcsynopsis> |
23 | </refsynopsisdiv> | 22 | </refsynopsisdiv> |
diff --git a/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml b/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml index ecc19576bb8..d5ec6abf0ce 100644 --- a/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml +++ b/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml | |||
@@ -16,8 +16,7 @@ | |||
16 | <funcdef>int <function>ioctl</function></funcdef> | 16 | <funcdef>int <function>ioctl</function></funcdef> |
17 | <paramdef>int <parameter>fd</parameter></paramdef> | 17 | <paramdef>int <parameter>fd</parameter></paramdef> |
18 | <paramdef>int <parameter>request</parameter></paramdef> | 18 | <paramdef>int <parameter>request</parameter></paramdef> |
19 | <paramdef>&v4l2-dv-timings; | 19 | <paramdef>struct v4l2_dv_timings *<parameter>argp</parameter></paramdef> |
20 | *<parameter>argp</parameter></paramdef> | ||
21 | </funcprototype> | 20 | </funcprototype> |
22 | </funcsynopsis> | 21 | </funcsynopsis> |
23 | </refsynopsisdiv> | 22 | </refsynopsisdiv> |
diff --git a/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml index 402229ee06f..d272f7ab91b 100644 --- a/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml +++ b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml | |||
@@ -16,7 +16,7 @@ input</refpurpose> | |||
16 | <funcdef>int <function>ioctl</function></funcdef> | 16 | <funcdef>int <function>ioctl</function></funcdef> |
17 | <paramdef>int <parameter>fd</parameter></paramdef> | 17 | <paramdef>int <parameter>fd</parameter></paramdef> |
18 | <paramdef>int <parameter>request</parameter></paramdef> | 18 | <paramdef>int <parameter>request</parameter></paramdef> |
19 | <paramdef>&v4l2-dv-preset; *<parameter>argp</parameter></paramdef> | 19 | <paramdef>struct v4l2_dv_preset *<parameter>argp</parameter></paramdef> |
20 | </funcprototype> | 20 | </funcprototype> |
21 | </funcsynopsis> | 21 | </funcsynopsis> |
22 | </refsynopsisdiv> | 22 | </refsynopsisdiv> |
diff --git a/Documentation/DocBook/v4l/vidioc-querycap.xml b/Documentation/DocBook/v4l/vidioc-querycap.xml index 6ab7e25b31b..d499da93a45 100644 --- a/Documentation/DocBook/v4l/vidioc-querycap.xml +++ b/Documentation/DocBook/v4l/vidioc-querycap.xml | |||
@@ -184,7 +184,7 @@ data.</entry> | |||
184 | <row> | 184 | <row> |
185 | <entry><constant>V4L2_CAP_RDS_CAPTURE</constant></entry> | 185 | <entry><constant>V4L2_CAP_RDS_CAPTURE</constant></entry> |
186 | <entry>0x00000100</entry> | 186 | <entry>0x00000100</entry> |
187 | <entry>The device supports the <link linkend="rds">RDS</link> interface.</entry> | 187 | <entry>The device supports the <link linkend="rds">RDS</link> capture interface.</entry> |
188 | </row> | 188 | </row> |
189 | <row> | 189 | <row> |
190 | <entry><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant></entry> | 190 | <entry><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant></entry> |
@@ -206,6 +206,11 @@ driver capabilities.</para></footnote></entry> | |||
206 | hardware frequency seeking.</entry> | 206 | hardware frequency seeking.</entry> |
207 | </row> | 207 | </row> |
208 | <row> | 208 | <row> |
209 | <entry><constant>V4L2_CAP_RDS_OUTPUT</constant></entry> | ||
210 | <entry>0x00000800</entry> | ||
211 | <entry>The device supports the <link linkend="rds">RDS</link> output interface.</entry> | ||
212 | </row> | ||
213 | <row> | ||
209 | <entry><constant>V4L2_CAP_TUNER</constant></entry> | 214 | <entry><constant>V4L2_CAP_TUNER</constant></entry> |
210 | <entry>0x00010000</entry> | 215 | <entry>0x00010000</entry> |
211 | <entry>The device has some sort of tuner to | 216 | <entry>The device has some sort of tuner to |
diff --git a/Documentation/DocBook/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/v4l/vidioc-queryctrl.xml index 8e0e055ac93..0d5e8283cf3 100644 --- a/Documentation/DocBook/v4l/vidioc-queryctrl.xml +++ b/Documentation/DocBook/v4l/vidioc-queryctrl.xml | |||
@@ -103,8 +103,12 @@ structure. The driver fills the rest of the structure or returns an | |||
103 | <structfield>index</structfield> is invalid. Menu items are enumerated | 103 | <structfield>index</structfield> is invalid. Menu items are enumerated |
104 | by calling <constant>VIDIOC_QUERYMENU</constant> with successive | 104 | by calling <constant>VIDIOC_QUERYMENU</constant> with successive |
105 | <structfield>index</structfield> values from &v4l2-queryctrl; | 105 | <structfield>index</structfield> values from &v4l2-queryctrl; |
106 | <structfield>minimum</structfield> (0) to | 106 | <structfield>minimum</structfield> to |
107 | <structfield>maximum</structfield>, inclusive.</para> | 107 | <structfield>maximum</structfield>, inclusive. Note that it is possible |
108 | for <constant>VIDIOC_QUERYMENU</constant> to return an &EINVAL; for some | ||
109 | indices between <structfield>minimum</structfield> and <structfield>maximum</structfield>. | ||
110 | In that case that particular menu item is not supported by this driver. Also note that | ||
111 | the <structfield>minimum</structfield> value is not necessarily 0.</para> | ||
108 | 112 | ||
109 | <para>See also the examples in <xref linkend="control" />.</para> | 113 | <para>See also the examples in <xref linkend="control" />.</para> |
110 | 114 | ||
@@ -139,7 +143,7 @@ string. This information is intended for the user.</entry> | |||
139 | <entry><structfield>minimum</structfield></entry> | 143 | <entry><structfield>minimum</structfield></entry> |
140 | <entry>Minimum value, inclusive. This field gives a lower | 144 | <entry>Minimum value, inclusive. This field gives a lower |
141 | bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the | 145 | bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the |
142 | lowest valid index (always 0) for <constant>V4L2_CTRL_TYPE_MENU</constant> controls. | 146 | lowest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant> controls. |
143 | For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value | 147 | For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value |
144 | gives the minimum length of the string. This length <emphasis>does not include the terminating | 148 | gives the minimum length of the string. This length <emphasis>does not include the terminating |
145 | zero</emphasis>. It may not be valid for any other type of control, including | 149 | zero</emphasis>. It may not be valid for any other type of control, including |
@@ -279,7 +283,7 @@ values which are actually different on the hardware.</entry> | |||
279 | </row> | 283 | </row> |
280 | <row> | 284 | <row> |
281 | <entry><constant>V4L2_CTRL_TYPE_MENU</constant></entry> | 285 | <entry><constant>V4L2_CTRL_TYPE_MENU</constant></entry> |
282 | <entry>0</entry> | 286 | <entry>≥ 0</entry> |
283 | <entry>1</entry> | 287 | <entry>1</entry> |
284 | <entry>N-1</entry> | 288 | <entry>N-1</entry> |
285 | <entry>The control has a menu of N choices. The names of | 289 | <entry>The control has a menu of N choices. The names of |
@@ -405,8 +409,10 @@ writing a value will cause the device to carry out a given action | |||
405 | <term><errorcode>EINVAL</errorcode></term> | 409 | <term><errorcode>EINVAL</errorcode></term> |
406 | <listitem> | 410 | <listitem> |
407 | <para>The &v4l2-queryctrl; <structfield>id</structfield> | 411 | <para>The &v4l2-queryctrl; <structfield>id</structfield> |
408 | is invalid. The &v4l2-querymenu; <structfield>id</structfield> or | 412 | is invalid. The &v4l2-querymenu; <structfield>id</structfield> is |
409 | <structfield>index</structfield> is invalid.</para> | 413 | invalid or <structfield>index</structfield> is out of range (less than |
414 | <structfield>minimum</structfield> or greater than <structfield>maximum</structfield>) | ||
415 | or this particular menu item is not supported by the driver.</para> | ||
410 | </listitem> | 416 | </listitem> |
411 | </varlistentry> | 417 | </varlistentry> |
412 | <varlistentry> | 418 | <varlistentry> |
diff --git a/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml index 14b3ec7ed75..c30dcc4232c 100644 --- a/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml +++ b/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml | |||
@@ -51,7 +51,8 @@ | |||
51 | 51 | ||
52 | <para>Start a hardware frequency seek from the current frequency. | 52 | <para>Start a hardware frequency seek from the current frequency. |
53 | To do this applications initialize the <structfield>tuner</structfield>, | 53 | To do this applications initialize the <structfield>tuner</structfield>, |
54 | <structfield>type</structfield>, <structfield>seek_upward</structfield> and | 54 | <structfield>type</structfield>, <structfield>seek_upward</structfield>, |
55 | <structfield>spacing</structfield> and | ||
55 | <structfield>wrap_around</structfield> fields, and zero out the | 56 | <structfield>wrap_around</structfield> fields, and zero out the |
56 | <structfield>reserved</structfield> array of a &v4l2-hw-freq-seek; and | 57 | <structfield>reserved</structfield> array of a &v4l2-hw-freq-seek; and |
57 | call the <constant>VIDIOC_S_HW_FREQ_SEEK</constant> ioctl with a pointer | 58 | call the <constant>VIDIOC_S_HW_FREQ_SEEK</constant> ioctl with a pointer |
@@ -89,7 +90,12 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry> | |||
89 | </row> | 90 | </row> |
90 | <row> | 91 | <row> |
91 | <entry>__u32</entry> | 92 | <entry>__u32</entry> |
92 | <entry><structfield>reserved</structfield>[8]</entry> | 93 | <entry><structfield>spacing</structfield></entry> |
94 | <entry>If non-zero, defines the hardware seek resolution in Hz. The driver selects the nearest value that is supported by the device. If spacing is zero a reasonable default value is used.</entry> | ||
95 | </row> | ||
96 | <row> | ||
97 | <entry>__u32</entry> | ||
98 | <entry><structfield>reserved</structfield>[7]</entry> | ||
93 | <entry>Reserved for future extensions. Drivers and | 99 | <entry>Reserved for future extensions. Drivers and |
94 | applications must set the array to zero.</entry> | 100 | applications must set the array to zero.</entry> |
95 | </row> | 101 | </row> |
diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 170cc1e7e13..eccffe71522 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt | |||
@@ -1496,9 +1496,6 @@ Your cooperation is appreciated. | |||
1496 | 64 = /dev/radio0 Radio device | 1496 | 64 = /dev/radio0 Radio device |
1497 | ... | 1497 | ... |
1498 | 127 = /dev/radio63 Radio device | 1498 | 127 = /dev/radio63 Radio device |
1499 | 192 = /dev/vtx0 Teletext device | ||
1500 | ... | ||
1501 | 223 = /dev/vtx31 Teletext device | ||
1502 | 224 = /dev/vbi0 Vertical blank interrupt | 1499 | 224 = /dev/vbi0 Vertical blank interrupt |
1503 | ... | 1500 | ... |
1504 | 255 = /dev/vbi31 Vertical blank interrupt | 1501 | 255 = /dev/vbi31 Vertical blank interrupt |
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index 350959f4e41..59690de8ebf 100644 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware | |||
@@ -26,7 +26,8 @@ use IO::Handle; | |||
26 | "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", | 26 | "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", |
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"); | 29 | "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", |
30 | "lme2510c_s7395_old"); | ||
30 | 31 | ||
31 | # Check args | 32 | # Check args |
32 | syntax() if (scalar(@ARGV) != 1); | 33 | syntax() if (scalar(@ARGV) != 1); |
@@ -584,6 +585,49 @@ sub az6027{ | |||
584 | 585 | ||
585 | $firmware; | 586 | $firmware; |
586 | } | 587 | } |
588 | |||
589 | sub lme2510_lg { | ||
590 | my $sourcefile = "LMEBDA_DVBS.sys"; | ||
591 | my $hash = "fc6017ad01e79890a97ec53bea157ed2"; | ||
592 | my $outfile = "dvb-usb-lme2510-lg.fw"; | ||
593 | my $hasho = "caa065d5fdbd2c09ad57b399bbf55cad"; | ||
594 | |||
595 | checkstandard(); | ||
596 | |||
597 | verify($sourcefile, $hash); | ||
598 | extract($sourcefile, 4168, 3841, $outfile); | ||
599 | verify($outfile, $hasho); | ||
600 | $outfile; | ||
601 | } | ||
602 | |||
603 | sub lme2510c_s7395 { | ||
604 | my $sourcefile = "US2A0D.sys"; | ||
605 | my $hash = "b0155a8083fb822a3bd47bc360e74601"; | ||
606 | my $outfile = "dvb-usb-lme2510c-s7395.fw"; | ||
607 | my $hasho = "3a3cf1aeebd17b6ddc04cebe131e94cf"; | ||
608 | |||
609 | checkstandard(); | ||
610 | |||
611 | verify($sourcefile, $hash); | ||
612 | extract($sourcefile, 37248, 3720, $outfile); | ||
613 | verify($outfile, $hasho); | ||
614 | $outfile; | ||
615 | } | ||
616 | |||
617 | sub lme2510c_s7395_old { | ||
618 | my $sourcefile = "LMEBDA_DVBS7395C.sys"; | ||
619 | my $hash = "7572ae0eb9cdf91baabd7c0ba9e09b31"; | ||
620 | my $outfile = "dvb-usb-lme2510c-s7395.fw"; | ||
621 | my $hasho = "90430c5b435eb5c6f88fd44a9d950674"; | ||
622 | |||
623 | checkstandard(); | ||
624 | |||
625 | verify($sourcefile, $hash); | ||
626 | extract($sourcefile, 4208, 3881, $outfile); | ||
627 | verify($outfile, $hasho); | ||
628 | $outfile; | ||
629 | } | ||
630 | |||
587 | # --------------------------------------------------------------- | 631 | # --------------------------------------------------------------- |
588 | # Utilities | 632 | # Utilities |
589 | 633 | ||
diff --git a/Documentation/dvb/lmedm04.txt b/Documentation/dvb/lmedm04.txt new file mode 100644 index 00000000000..e175784b89b --- /dev/null +++ b/Documentation/dvb/lmedm04.txt | |||
@@ -0,0 +1,58 @@ | |||
1 | To extract firmware for the DM04/QQBOX you need to copy the | ||
2 | following file(s) to this directory. | ||
3 | |||
4 | for DM04+/QQBOX LME2510C (Sharp 7395 Tuner) | ||
5 | ------------------------------------------- | ||
6 | |||
7 | The Sharp 7395 driver can be found in windows/system32/driver | ||
8 | |||
9 | US2A0D.sys (dated 17 Mar 2009) | ||
10 | |||
11 | |||
12 | and run | ||
13 | ./get_dvb_firmware lme2510c_s7395 | ||
14 | |||
15 | will produce | ||
16 | dvb-usb-lme2510c-s7395.fw | ||
17 | |||
18 | An alternative but older firmware can be found on the driver | ||
19 | disk DVB-S_EN_3.5A in BDADriver/driver | ||
20 | |||
21 | LMEBDA_DVBS7395C.sys (dated 18 Jan 2008) | ||
22 | |||
23 | and run | ||
24 | ./get_dvb_firmware lme2510c_s7395_old | ||
25 | |||
26 | will produce | ||
27 | dvb-usb-lme2510c-s7395.fw | ||
28 | |||
29 | -------------------------------------------------------------------- | ||
30 | |||
31 | The LG firmware can be found on the driver | ||
32 | disk DM04+_5.1A[LG] in BDADriver/driver | ||
33 | |||
34 | for DM04 LME2510 (LG Tuner) | ||
35 | --------------------------- | ||
36 | |||
37 | LMEBDA_DVBS.sys (dated 13 Nov 2007) | ||
38 | |||
39 | and run | ||
40 | ./get_dvb_firmware lme2510_lg | ||
41 | |||
42 | will produce | ||
43 | dvb-usb-lme2510-lg.fw | ||
44 | |||
45 | |||
46 | Other LG firmware can be extracted manually from US280D.sys | ||
47 | only found in windows/system32/driver. | ||
48 | |||
49 | dd if=US280D.sys ibs=1 skip=42616 count=3668 of=dvb-usb-lme2510-lg.fw | ||
50 | |||
51 | for DM04 LME2510C (LG Tuner) | ||
52 | --------------------------- | ||
53 | |||
54 | dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw | ||
55 | |||
56 | --------------------------------------------------------------------- | ||
57 | |||
58 | Copy the firmware file(s) to /lib/firmware | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index f3da8c0a3af..d8f36f984fa 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -98,7 +98,7 @@ Who: Pavel Machek <pavel@ucw.cz> | |||
98 | --------------------------- | 98 | --------------------------- |
99 | 99 | ||
100 | What: Video4Linux API 1 ioctls and from Video devices. | 100 | What: Video4Linux API 1 ioctls and from Video devices. |
101 | When: July 2009 | 101 | When: kernel 2.6.38 |
102 | Files: include/linux/videodev.h | 102 | Files: include/linux/videodev.h |
103 | Check: include/linux/videodev.h | 103 | Check: include/linux/videodev.h |
104 | Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6 | 104 | Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6 |
@@ -116,6 +116,21 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org> | |||
116 | 116 | ||
117 | --------------------------- | 117 | --------------------------- |
118 | 118 | ||
119 | What: Video4Linux obsolete drivers using V4L1 API | ||
120 | When: kernel 2.6.38 | ||
121 | Files: drivers/staging/cpia/* drivers/staging/stradis/* | ||
122 | Check: drivers/staging/cpia/cpia.c drivers/staging/stradis/stradis.c | ||
123 | Why: There are some drivers still using V4L1 API, despite all efforts we've done | ||
124 | to migrate. Those drivers are for obsolete hardware that the old maintainer | ||
125 | didn't care (or not have the hardware anymore), and that no other developer | ||
126 | could find any hardware to buy. They probably have no practical usage today, | ||
127 | and people with such old hardware could probably keep using an older version | ||
128 | of the kernel. Those drivers will be moved to staging on 2.6.37 and, if nobody | ||
129 | care enough to port and test them with V4L2 API, they'll be removed on 2.6.38. | ||
130 | Who: Mauro Carvalho Chehab <mchehab@infradead.org> | ||
131 | |||
132 | --------------------------- | ||
133 | |||
119 | What: sys_sysctl | 134 | What: sys_sysctl |
120 | When: September 2010 | 135 | When: September 2010 |
121 | Option: CONFIG_SYSCTL_SYSCALL | 136 | Option: CONFIG_SYSCTL_SYSCALL |
@@ -470,29 +485,6 @@ When: April 2011 | |||
470 | Why: Superseded by xt_CT | 485 | Why: Superseded by xt_CT |
471 | Who: Netfilter developer team <netfilter-devel@vger.kernel.org> | 486 | Who: Netfilter developer team <netfilter-devel@vger.kernel.org> |
472 | 487 | ||
473 | --------------------------- | ||
474 | |||
475 | What: video4linux /dev/vtx teletext API support | ||
476 | When: 2.6.35 | ||
477 | Files: drivers/media/video/saa5246a.c drivers/media/video/saa5249.c | ||
478 | include/linux/videotext.h | ||
479 | Why: The vtx device nodes have been superseded by vbi device nodes | ||
480 | for many years. No applications exist that use the vtx support. | ||
481 | Of the two i2c drivers that actually support this API the saa5249 | ||
482 | has been impossible to use for a year now and no known hardware | ||
483 | that supports this device exists. The saa5246a is theoretically | ||
484 | supported by the old mxb boards, but it never actually worked. | ||
485 | |||
486 | In summary: there is no hardware that can use this API and there | ||
487 | are no applications actually implementing this API. | ||
488 | |||
489 | The vtx support still reserves minors 192-223 and we would really | ||
490 | like to reuse those for upcoming new functionality. In the unlikely | ||
491 | event that new hardware appears that wants to use the functionality | ||
492 | provided by the vtx API, then that functionality should be build | ||
493 | around the sliced VBI API instead. | ||
494 | Who: Hans Verkuil <hverkuil@xs4all.nl> | ||
495 | |||
496 | ---------------------------- | 488 | ---------------------------- |
497 | 489 | ||
498 | What: IRQF_DISABLED | 490 | What: IRQF_DISABLED |
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 33223ff121d..10f5af8b73f 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt | |||
@@ -278,7 +278,6 @@ Code Seq#(hex) Include File Comments | |||
278 | <mailto:oe@port.de> | 278 | <mailto:oe@port.de> |
279 | 'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! | 279 | 'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! |
280 | 0x80 00-1F linux/fb.h | 280 | 0x80 00-1F linux/fb.h |
281 | 0x81 00-1F linux/videotext.h | ||
282 | 0x88 00-3F media/ovcamchip.h | 281 | 0x88 00-3F media/ovcamchip.h |
283 | 0x89 00-06 arch/x86/include/asm/sockios.h | 282 | 0x89 00-06 arch/x86/include/asm/sockios.h |
284 | 0x89 0B-DF linux/sockios.h | 283 | 0x89 0B-DF linux/sockios.h |
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index f2510541373..42517d9121d 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 | |||
@@ -83,3 +83,4 @@ | |||
83 | 82 -> WinFast DTV2000 H rev. J [107d:6f2b] | 83 | 82 -> WinFast DTV2000 H rev. J [107d:6f2b] |
84 | 83 -> Prof 7301 DVB-S/S2 [b034:3034] | 84 | 83 -> Prof 7301 DVB-S/S2 [b034:3034] |
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] | ||
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 5c568757c30..ac2616a62fc 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx | |||
@@ -31,6 +31,7 @@ | |||
31 | 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) | 31 | 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) |
32 | 31 -> Usbgear VD204v9 (em2821) | 32 | 31 -> Usbgear VD204v9 (em2821) |
33 | 32 -> Supercomp USB 2.0 TV (em2821) | 33 | 32 -> Supercomp USB 2.0 TV (em2821) |
34 | 33 -> Elgato Video Capture (em2860) [0fd9:0033] | ||
34 | 34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f] | 35 | 34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f] |
35 | 35 -> Typhoon DVD Maker (em2860) | 36 | 35 -> Typhoon DVD Maker (em2860) |
36 | 36 -> NetGMBH Cam (em2860) | 37 | 36 -> NetGMBH Cam (em2860) |
@@ -45,7 +46,7 @@ | |||
45 | 45 -> Pinnacle PCTV DVB-T (em2870) | 46 | 45 -> Pinnacle PCTV DVB-T (em2870) |
46 | 46 -> Compro, VideoMate U3 (em2870) [185b:2870] | 47 | 46 -> Compro, VideoMate U3 (em2870) [185b:2870] |
47 | 47 -> KWorld DVB-T 305U (em2880) [eb1a:e305] | 48 | 47 -> KWorld DVB-T 305U (em2880) [eb1a:e305] |
48 | 48 -> KWorld DVB-T 310U (em2880) [eb1a:e310] | 49 | 48 -> KWorld DVB-T 310U (em2880) |
49 | 49 -> MSI DigiVox A/D (em2880) [eb1a:e310] | 50 | 49 -> MSI DigiVox A/D (em2880) [eb1a:e310] |
50 | 50 -> MSI DigiVox A/D II (em2880) [eb1a:e320] | 51 | 50 -> MSI DigiVox A/D II (em2880) [eb1a:e320] |
51 | 51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c] | 52 | 51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c] |
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 4000c29fcfb..8d9afc7d801 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 | |||
@@ -126,7 +126,7 @@ | |||
126 | 125 -> Beholder BeholdTV 409 [0000:4090] | 126 | 125 -> Beholder BeholdTV 409 [0000:4090] |
127 | 126 -> Beholder BeholdTV 505 FM [5ace:5050] | 127 | 126 -> Beholder BeholdTV 505 FM [5ace:5050] |
128 | 127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090] | 128 | 127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090] |
129 | 128 -> Beholder BeholdTV Columbus TVFM [0000:5201] | 129 | 128 -> Beholder BeholdTV Columbus TV/FM [0000:5201] |
130 | 129 -> Beholder BeholdTV 607 FM [5ace:6070] | 130 | 129 -> Beholder BeholdTV 607 FM [5ace:6070] |
131 | 130 -> Beholder BeholdTV M6 [5ace:6190] | 131 | 130 -> Beholder BeholdTV M6 [5ace:6190] |
132 | 131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] | 132 | 131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] |
diff --git a/Documentation/video4linux/bttv/MAKEDEV b/Documentation/video4linux/bttv/MAKEDEV index 9d112f7fd5f..093c0cd1804 100644 --- a/Documentation/video4linux/bttv/MAKEDEV +++ b/Documentation/video4linux/bttv/MAKEDEV | |||
@@ -19,7 +19,6 @@ function makedev () { | |||
19 | echo "*** new device names ***" | 19 | echo "*** new device names ***" |
20 | makedev video 0 | 20 | makedev video 0 |
21 | makedev radio 64 | 21 | makedev radio 64 |
22 | makedev vtx 192 | ||
23 | makedev vbi 224 | 22 | makedev vbi 224 |
24 | 23 | ||
25 | #echo "*** old device names (for compatibility only) ***" | 24 | #echo "*** old device names (for compatibility only) ***" |
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 56ba7bba716..6a562eeeb4c 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt | |||
@@ -302,12 +302,14 @@ sonixj 0c45:60fb Surfer NoName | |||
302 | sonixj 0c45:60fc LG-LIC300 | 302 | sonixj 0c45:60fc LG-LIC300 |
303 | sonixj 0c45:60fe Microdia Audio | 303 | sonixj 0c45:60fe Microdia Audio |
304 | sonixj 0c45:6100 PC Camera (SN9C128) | 304 | sonixj 0c45:6100 PC Camera (SN9C128) |
305 | sonixj 0c45:6102 PC Camera (SN9C128) | ||
305 | sonixj 0c45:610a PC Camera (SN9C128) | 306 | sonixj 0c45:610a PC Camera (SN9C128) |
306 | sonixj 0c45:610b PC Camera (SN9C128) | 307 | sonixj 0c45:610b PC Camera (SN9C128) |
307 | sonixj 0c45:610c PC Camera (SN9C128) | 308 | sonixj 0c45:610c PC Camera (SN9C128) |
308 | sonixj 0c45:610e PC Camera (SN9C128) | 309 | sonixj 0c45:610e PC Camera (SN9C128) |
309 | sonixj 0c45:6128 Microdia/Sonix SNP325 | 310 | sonixj 0c45:6128 Microdia/Sonix SNP325 |
310 | sonixj 0c45:612a Avant Camera | 311 | sonixj 0c45:612a Avant Camera |
312 | sonixj 0c45:612b Speed-Link REFLECT2 | ||
311 | sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix | 313 | sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix |
312 | sonixj 0c45:6130 Sonix Pccam | 314 | sonixj 0c45:6130 Sonix Pccam |
313 | sonixj 0c45:6138 Sn9c120 Mo4000 | 315 | sonixj 0c45:6138 Sn9c120 Mo4000 |
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index e831aaca66f..f22f35c271f 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt | |||
@@ -44,8 +44,8 @@ All drivers have the following structure: | |||
44 | 44 | ||
45 | 2) A way of initializing and commanding sub-devices (if any). | 45 | 2) A way of initializing and commanding sub-devices (if any). |
46 | 46 | ||
47 | 3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and | 47 | 3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX and /dev/radioX) |
48 | /dev/vtxX) and keeping track of device-node specific data. | 48 | and keeping track of device-node specific data. |
49 | 49 | ||
50 | 4) Filehandle-specific structs containing per-filehandle data; | 50 | 4) Filehandle-specific structs containing per-filehandle data; |
51 | 51 | ||
@@ -192,6 +192,11 @@ You also need a way to go from the low-level struct to v4l2_subdev. For the | |||
192 | common i2c_client struct the i2c_set_clientdata() call is used to store a | 192 | common i2c_client struct the i2c_set_clientdata() call is used to store a |
193 | v4l2_subdev pointer, for other busses you may have to use other methods. | 193 | v4l2_subdev pointer, for other busses you may have to use other methods. |
194 | 194 | ||
195 | Bridges might also need to store per-subdev private data, such as a pointer to | ||
196 | bridge-specific per-subdev private data. The v4l2_subdev structure provides | ||
197 | host private data for that purpose that can be accessed with | ||
198 | v4l2_get_subdev_hostdata() and v4l2_set_subdev_hostdata(). | ||
199 | |||
195 | From the bridge driver perspective you load the sub-device module and somehow | 200 | From the bridge driver perspective you load the sub-device module and somehow |
196 | obtain the v4l2_subdev pointer. For i2c devices this is easy: you call | 201 | obtain the v4l2_subdev pointer. For i2c devices this is easy: you call |
197 | i2c_get_clientdata(). For other busses something similar needs to be done. | 202 | i2c_get_clientdata(). For other busses something similar needs to be done. |
@@ -448,6 +453,10 @@ You should also set these fields: | |||
448 | - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance | 453 | - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance |
449 | (highly recommended to use this and it might become compulsory in the | 454 | (highly recommended to use this and it might become compulsory in the |
450 | future!), then set this to your v4l2_ioctl_ops struct. | 455 | future!), then set this to your v4l2_ioctl_ops struct. |
456 | - lock: leave to NULL if you want to do all the locking in the driver. | ||
457 | Otherwise you give it a pointer to a struct mutex_lock and before any | ||
458 | of the v4l2_file_operations is called this lock will be taken by the | ||
459 | core and released afterwards. | ||
451 | - parent: you only set this if v4l2_device was registered with NULL as | 460 | - parent: you only set this if v4l2_device was registered with NULL as |
452 | the parent device struct. This only happens in cases where one hardware | 461 | the parent device struct. This only happens in cases where one hardware |
453 | device has multiple PCI devices that all share the same v4l2_device core. | 462 | device has multiple PCI devices that all share the same v4l2_device core. |
@@ -464,6 +473,22 @@ If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or | |||
464 | The v4l2_file_operations struct is a subset of file_operations. The main | 473 | The v4l2_file_operations struct is a subset of file_operations. The main |
465 | difference is that the inode argument is omitted since it is never used. | 474 | difference is that the inode argument is omitted since it is never used. |
466 | 475 | ||
476 | v4l2_file_operations and locking | ||
477 | -------------------------------- | ||
478 | |||
479 | You can set a pointer to a mutex_lock in struct video_device. Usually this | ||
480 | will be either a top-level mutex or a mutex per device node. If you want | ||
481 | finer-grained locking then you have to set it to NULL and do you own locking. | ||
482 | |||
483 | If a lock is specified then all file operations will be serialized on that | ||
484 | lock. If you use videobuf then you must pass the same lock to the videobuf | ||
485 | queue initialize function: if videobuf has to wait for a frame to arrive, then | ||
486 | it will temporarily unlock the lock and relock it afterwards. If your driver | ||
487 | also waits in the code, then you should do the same to allow other processes | ||
488 | to access the device node while the first process is waiting for something. | ||
489 | |||
490 | The implementation of a hotplug disconnect should also take the lock before | ||
491 | calling v4l2_device_disconnect. | ||
467 | 492 | ||
468 | video_device registration | 493 | video_device registration |
469 | ------------------------- | 494 | ------------------------- |
@@ -483,7 +508,6 @@ types exist: | |||
483 | VFL_TYPE_GRABBER: videoX for video input/output devices | 508 | VFL_TYPE_GRABBER: videoX for video input/output devices |
484 | VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext) | 509 | VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext) |
485 | VFL_TYPE_RADIO: radioX for radio tuners | 510 | VFL_TYPE_RADIO: radioX for radio tuners |
486 | VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use) | ||
487 | 511 | ||
488 | The last argument gives you a certain amount of control over the device | 512 | The last argument gives you a certain amount of control over the device |
489 | device node number used (i.e. the X in videoX). Normally you will pass -1 | 513 | device node number used (i.e. the X in videoX). Normally you will pass -1 |
@@ -547,9 +571,8 @@ from /dev). | |||
547 | 571 | ||
548 | After video_unregister_device() returns no new opens can be done. However, | 572 | After video_unregister_device() returns no new opens can be done. However, |
549 | in the case of USB devices some application might still have one of these | 573 | in the case of USB devices some application might still have one of these |
550 | device nodes open. So after the unregister all file operations will return | 574 | device nodes open. So after the unregister all file operations (except |
551 | an error as well, except for the ioctl and unlocked_ioctl file operations: | 575 | release, of course) will return an error as well. |
552 | those will still be passed on since some buffer ioctls may still be needed. | ||
553 | 576 | ||
554 | When the last user of the video device node exits, then the vdev->release() | 577 | When the last user of the video device node exits, then the vdev->release() |
555 | callback is called and you can do the final cleanup there. | 578 | callback is called and you can do the final cleanup there. |
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 86e86c1300d..2ff3f661a48 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c | |||
@@ -311,7 +311,6 @@ static struct soc_camera_link iclink_mt9v022 = { | |||
311 | .bus_id = 0, /* Must match with the camera ID */ | 311 | .bus_id = 0, /* Must match with the camera ID */ |
312 | .board_info = &pcm037_i2c_camera[1], | 312 | .board_info = &pcm037_i2c_camera[1], |
313 | .i2c_adapter_id = 2, | 313 | .i2c_adapter_id = 2, |
314 | .module_name = "mt9v022", | ||
315 | }; | 314 | }; |
316 | 315 | ||
317 | static struct soc_camera_link iclink_mt9t031 = { | 316 | static struct soc_camera_link iclink_mt9t031 = { |
@@ -319,7 +318,6 @@ static struct soc_camera_link iclink_mt9t031 = { | |||
319 | .power = pcm037_camera_power, | 318 | .power = pcm037_camera_power, |
320 | .board_info = &pcm037_i2c_camera[0], | 319 | .board_info = &pcm037_i2c_camera[0], |
321 | .i2c_adapter_id = 2, | 320 | .i2c_adapter_id = 2, |
322 | .module_name = "mt9t031", | ||
323 | }; | 321 | }; |
324 | 322 | ||
325 | static struct i2c_board_info pcm037_i2c_devices[] = { | 323 | static struct i2c_board_info pcm037_i2c_devices[] = { |
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 0551eb39d97..18069cb7d06 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c | |||
@@ -179,7 +179,6 @@ static struct soc_camera_link base_iclink = { | |||
179 | .reset = marxbot_basecam_reset, | 179 | .reset = marxbot_basecam_reset, |
180 | .board_info = &marxbot_i2c_devices[0], | 180 | .board_info = &marxbot_i2c_devices[0], |
181 | .i2c_adapter_id = 0, | 181 | .i2c_adapter_id = 0, |
182 | .module_name = "mt9t031", | ||
183 | }; | 182 | }; |
184 | 183 | ||
185 | static struct platform_device marxbot_camera[] = { | 184 | static struct platform_device marxbot_camera[] = { |
diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c index 417757e78c6..04760a53005 100644 --- a/arch/arm/mach-mx3/mx31moboard-smartbot.c +++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c | |||
@@ -88,7 +88,6 @@ static struct soc_camera_link base_iclink = { | |||
88 | .reset = smartbot_cam_reset, | 88 | .reset = smartbot_cam_reset, |
89 | .board_info = &smartbot_i2c_devices[0], | 89 | .board_info = &smartbot_i2c_devices[0], |
90 | .i2c_adapter_id = 0, | 90 | .i2c_adapter_id = 0, |
91 | .module_name = "mt9t031", | ||
92 | }; | 91 | }; |
93 | 92 | ||
94 | static struct platform_device smartbot_camera[] = { | 93 | static struct platform_device smartbot_camera[] = { |
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index ab48bb81b57..ed0dbfdb22e 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -1015,7 +1015,6 @@ static struct soc_camera_link iclink = { | |||
1015 | .power = em_x270_sensor_power, | 1015 | .power = em_x270_sensor_power, |
1016 | .board_info = &em_x270_i2c_cam_info[0], | 1016 | .board_info = &em_x270_i2c_cam_info[0], |
1017 | .i2c_adapter_id = 0, | 1017 | .i2c_adapter_id = 0, |
1018 | .module_name = "mt9m111", | ||
1019 | }; | 1018 | }; |
1020 | 1019 | ||
1021 | static struct platform_device em_x270_camera = { | 1020 | static struct platform_device em_x270_camera = { |
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 80a9352d43f..142c711f4cd 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c | |||
@@ -755,7 +755,6 @@ static struct soc_camera_link a780_iclink = { | |||
755 | .flags = SOCAM_SENSOR_INVERT_PCLK, | 755 | .flags = SOCAM_SENSOR_INVERT_PCLK, |
756 | .i2c_adapter_id = 0, | 756 | .i2c_adapter_id = 0, |
757 | .board_info = &a780_camera_i2c_board_info, | 757 | .board_info = &a780_camera_i2c_board_info, |
758 | .module_name = "mt9m111", | ||
759 | .power = a780_camera_power, | 758 | .power = a780_camera_power, |
760 | .reset = a780_camera_reset, | 759 | .reset = a780_camera_reset, |
761 | }; | 760 | }; |
@@ -1024,7 +1023,6 @@ static struct soc_camera_link a910_iclink = { | |||
1024 | .bus_id = 0, | 1023 | .bus_id = 0, |
1025 | .i2c_adapter_id = 0, | 1024 | .i2c_adapter_id = 0, |
1026 | .board_info = &a910_camera_i2c_board_info, | 1025 | .board_info = &a910_camera_i2c_board_info, |
1027 | .module_name = "mt9m111", | ||
1028 | .power = a910_camera_power, | 1026 | .power = a910_camera_power, |
1029 | .reset = a910_camera_reset, | 1027 | .reset = a910_camera_reset, |
1030 | }; | 1028 | }; |
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 0c31fabfc7f..f5fb915e131 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c | |||
@@ -711,7 +711,6 @@ static struct soc_camera_link iclink = { | |||
711 | .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */ | 711 | .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */ |
712 | .board_info = &mioa701_i2c_devices[0], | 712 | .board_info = &mioa701_i2c_devices[0], |
713 | .i2c_adapter_id = 0, | 713 | .i2c_adapter_id = 0, |
714 | .module_name = "mt9m111", | ||
715 | }; | 714 | }; |
716 | 715 | ||
717 | struct i2c_pxa_platform_data i2c_pdata = { | 716 | struct i2c_pxa_platform_data i2c_pdata = { |
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index f56ae100875..f33647a8e0b 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c | |||
@@ -453,7 +453,6 @@ static struct soc_camera_link iclink[] = { | |||
453 | .query_bus_param = pcm990_camera_query_bus_param, | 453 | .query_bus_param = pcm990_camera_query_bus_param, |
454 | .set_bus_param = pcm990_camera_set_bus_param, | 454 | .set_bus_param = pcm990_camera_set_bus_param, |
455 | .free_bus = pcm990_camera_free_bus, | 455 | .free_bus = pcm990_camera_free_bus, |
456 | .module_name = "mt9v022", | ||
457 | }, { | 456 | }, { |
458 | .bus_id = 0, /* Must match with the camera ID */ | 457 | .bus_id = 0, /* Must match with the camera ID */ |
459 | .board_info = &pcm990_camera_i2c[1], | 458 | .board_info = &pcm990_camera_i2c[1], |
@@ -461,7 +460,6 @@ static struct soc_camera_link iclink[] = { | |||
461 | .query_bus_param = pcm990_camera_query_bus_param, | 460 | .query_bus_param = pcm990_camera_query_bus_param, |
462 | .set_bus_param = pcm990_camera_set_bus_param, | 461 | .set_bus_param = pcm990_camera_set_bus_param, |
463 | .free_bus = pcm990_camera_free_bus, | 462 | .free_bus = pcm990_camera_free_bus, |
464 | .module_name = "mt9m001", | ||
465 | }, | 463 | }, |
466 | }; | 464 | }; |
467 | 465 | ||
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 3da116f47f0..881a3a5f564 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -481,7 +481,6 @@ static struct soc_camera_link ov7725_link = { | |||
481 | .power = ov7725_power, | 481 | .power = ov7725_power, |
482 | .board_info = &ap325rxa_i2c_camera[0], | 482 | .board_info = &ap325rxa_i2c_camera[0], |
483 | .i2c_adapter_id = 0, | 483 | .i2c_adapter_id = 0, |
484 | .module_name = "ov772x", | ||
485 | .priv = &ov7725_info, | 484 | .priv = &ov7725_info, |
486 | }; | 485 | }; |
487 | 486 | ||
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 71a3368ab1f..ddc7e4e4d2a 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -620,7 +620,6 @@ static struct soc_camera_link tw9910_link = { | |||
620 | .bus_id = 1, | 620 | .bus_id = 1, |
621 | .power = tw9910_power, | 621 | .power = tw9910_power, |
622 | .board_info = &i2c_camera[0], | 622 | .board_info = &i2c_camera[0], |
623 | .module_name = "tw9910", | ||
624 | .priv = &tw9910_info, | 623 | .priv = &tw9910_info, |
625 | }; | 624 | }; |
626 | 625 | ||
@@ -644,7 +643,6 @@ static struct soc_camera_link mt9t112_link1 = { | |||
644 | .power = mt9t112_power1, | 643 | .power = mt9t112_power1, |
645 | .bus_id = 0, | 644 | .bus_id = 0, |
646 | .board_info = &i2c_camera[1], | 645 | .board_info = &i2c_camera[1], |
647 | .module_name = "mt9t112", | ||
648 | .priv = &mt9t112_info1, | 646 | .priv = &mt9t112_info1, |
649 | }; | 647 | }; |
650 | 648 | ||
@@ -667,7 +665,6 @@ static struct soc_camera_link mt9t112_link2 = { | |||
667 | .power = mt9t112_power2, | 665 | .power = mt9t112_power2, |
668 | .bus_id = 1, | 666 | .bus_id = 1, |
669 | .board_info = &i2c_camera[2], | 667 | .board_info = &i2c_camera[2], |
670 | .module_name = "mt9t112", | ||
671 | .priv = &mt9t112_info2, | 668 | .priv = &mt9t112_info2, |
672 | }; | 669 | }; |
673 | 670 | ||
@@ -793,7 +790,6 @@ static struct sh_vou_pdata sh_vou_pdata = { | |||
793 | .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, | 790 | .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, |
794 | .board_info = &ak8813, | 791 | .board_info = &ak8813, |
795 | .i2c_adap = 0, | 792 | .i2c_adap = 0, |
796 | .module_name = "ak881x", | ||
797 | }; | 793 | }; |
798 | 794 | ||
799 | static struct resource sh_vou_resources[] = { | 795 | static struct resource sh_vou_resources[] = { |
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 68994a163f6..1742849db64 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -333,7 +333,6 @@ static struct soc_camera_link rj54n1_link = { | |||
333 | .power = camera_power, | 333 | .power = camera_power, |
334 | .board_info = &kfr2r09_i2c_camera, | 334 | .board_info = &kfr2r09_i2c_camera, |
335 | .i2c_adapter_id = 1, | 335 | .i2c_adapter_id = 1, |
336 | .module_name = "rj54n1cb0c", | ||
337 | .priv = &rj54n1_priv, | 336 | .priv = &rj54n1_priv, |
338 | }; | 337 | }; |
339 | 338 | ||
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 662debe4ead..03af8484255 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -450,7 +450,6 @@ static struct soc_camera_link ov7725_link = { | |||
450 | .power = ov7725_power, | 450 | .power = ov7725_power, |
451 | .board_info = &migor_i2c_camera[0], | 451 | .board_info = &migor_i2c_camera[0], |
452 | .i2c_adapter_id = 0, | 452 | .i2c_adapter_id = 0, |
453 | .module_name = "ov772x", | ||
454 | .priv = &ov7725_info, | 453 | .priv = &ov7725_info, |
455 | }; | 454 | }; |
456 | 455 | ||
@@ -463,7 +462,6 @@ static struct soc_camera_link tw9910_link = { | |||
463 | .power = tw9910_power, | 462 | .power = tw9910_power, |
464 | .board_info = &migor_i2c_camera[1], | 463 | .board_info = &migor_i2c_camera[1], |
465 | .i2c_adapter_id = 0, | 464 | .i2c_adapter_id = 0, |
466 | .module_name = "tw9910", | ||
467 | .priv = &tw9910_info, | 465 | .priv = &tw9910_info, |
468 | }; | 466 | }; |
469 | 467 | ||
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 552ebd9ba82..8cc1d7295d8 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -550,7 +550,6 @@ static struct sh_vou_pdata sh_vou_pdata = { | |||
550 | .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, | 550 | .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, |
551 | .board_info = &ak8813, | 551 | .board_info = &ak8813, |
552 | .i2c_adap = 0, | 552 | .i2c_adap = 0, |
553 | .module_name = "ak881x", | ||
554 | }; | 553 | }; |
555 | 554 | ||
556 | static struct resource sh_vou_resources[] = { | 555 | static struct resource sh_vou_resources[] = { |
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index 490c57cc4cf..aa4163eb7a8 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig | |||
@@ -79,6 +79,18 @@ config IR_SONY_DECODER | |||
79 | Enable this option if you have an infrared remote control which | 79 | Enable this option if you have an infrared remote control which |
80 | uses the Sony protocol, and you need software decoding support. | 80 | uses the Sony protocol, and you need software decoding support. |
81 | 81 | ||
82 | config IR_RC5_SZ_DECODER | ||
83 | tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol" | ||
84 | depends on IR_CORE | ||
85 | select BITREVERSE | ||
86 | default y | ||
87 | |||
88 | ---help--- | ||
89 | Enable this option if you have IR with RC-5 (streamzap) protocol, | ||
90 | and if the IR is decoded in software. (The Streamzap PC Remote | ||
91 | uses an IR protocol that is almost standard RC-5, but not quite, | ||
92 | as it uses an additional bit). | ||
93 | |||
82 | config IR_LIRC_CODEC | 94 | config IR_LIRC_CODEC |
83 | tristate "Enable IR to LIRC bridge" | 95 | tristate "Enable IR to LIRC bridge" |
84 | depends on IR_CORE | 96 | depends on IR_CORE |
@@ -89,6 +101,20 @@ config IR_LIRC_CODEC | |||
89 | Enable this option to pass raw IR to and from userspace via | 101 | Enable this option to pass raw IR to and from userspace via |
90 | the LIRC interface. | 102 | the LIRC interface. |
91 | 103 | ||
104 | config IR_ENE | ||
105 | tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" | ||
106 | depends on PNP | ||
107 | depends on IR_CORE | ||
108 | ---help--- | ||
109 | Say Y here to enable support for integrated infrared receiver | ||
110 | /transceiver made by ENE. | ||
111 | |||
112 | You can see if you have it by looking at lspnp output. | ||
113 | Output should include ENE0100 ENE0200 or something similar. | ||
114 | |||
115 | To compile this driver as a module, choose M here: the | ||
116 | module will be called ene_ir. | ||
117 | |||
92 | config IR_IMON | 118 | config IR_IMON |
93 | tristate "SoundGraph iMON Receiver and Display" | 119 | tristate "SoundGraph iMON Receiver and Display" |
94 | depends on USB_ARCH_HAS_HCD | 120 | depends on USB_ARCH_HAS_HCD |
@@ -113,19 +139,18 @@ config IR_MCEUSB | |||
113 | To compile this driver as a module, choose M here: the | 139 | To compile this driver as a module, choose M here: the |
114 | module will be called mceusb. | 140 | module will be called mceusb. |
115 | 141 | ||
116 | config IR_ENE | 142 | config IR_NUVOTON |
117 | tristate "ENE eHome Receiver/Transciever (pnp id: ENE0100/ENE02xxx)" | 143 | tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" |
118 | depends on PNP | 144 | depends on PNP |
119 | depends on IR_CORE | 145 | depends on IR_CORE |
120 | ---help--- | 146 | ---help--- |
121 | Say Y here to enable support for integrated infrared receiver | 147 | Say Y here to enable support for integrated infrared receiver |
122 | /transciever made by ENE. | 148 | /transciever made by Nuvoton (formerly Winbond). This chip is |
123 | 149 | found in the ASRock ION 330HT, as well as assorted Intel | |
124 | You can see if you have it by looking at lspnp output. | 150 | DP55-series motherboards (and of course, possibly others). |
125 | Output should include ENE0100 ENE0200 or something similiar. | ||
126 | 151 | ||
127 | To compile this driver as a module, choose M here: the | 152 | To compile this driver as a module, choose M here: the |
128 | module will be called ene_ir. | 153 | module will be called nuvoton-cir. |
129 | 154 | ||
130 | config IR_STREAMZAP | 155 | config IR_STREAMZAP |
131 | tristate "Streamzap PC Remote IR Receiver" | 156 | tristate "Streamzap PC Remote IR Receiver" |
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 53676838fe9..f9574adab82 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -11,10 +11,12 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o | |||
11 | obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o | 11 | obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o |
12 | obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o | 12 | obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o |
13 | obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o | 13 | obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o |
14 | obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o | ||
14 | obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o | 15 | obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o |
15 | 16 | ||
16 | # stand-alone IR receivers/transmitters | 17 | # stand-alone IR receivers/transmitters |
17 | obj-$(CONFIG_IR_IMON) += imon.o | 18 | obj-$(CONFIG_IR_IMON) += imon.o |
18 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o | 19 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o |
20 | obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o | ||
19 | obj-$(CONFIG_IR_ENE) += ene_ir.o | 21 | obj-$(CONFIG_IR_ENE) += ene_ir.o |
20 | obj-$(CONFIG_IR_STREAMZAP) += streamzap.o | 22 | obj-$(CONFIG_IR_STREAMZAP) += streamzap.o |
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c index 5447750f5e3..7637babcd26 100644 --- a/drivers/media/IR/ene_ir.c +++ b/drivers/media/IR/ene_ir.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * driver for ENE KB3926 B/C/D CIR (pnp id: ENE0XXX) | 2 | * driver for ENE KB3926 B/C/D/E/F CIR (pnp id: ENE0XXX) |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> | 4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> |
5 | * | 5 | * |
@@ -17,6 +17,17 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
19 | * USA | 19 | * USA |
20 | * | ||
21 | * Special thanks to: | ||
22 | * Sami R. <maesesami@gmail.com> for lot of help in debugging and therefore | ||
23 | * bringing to life support for transmission & learning mode. | ||
24 | * | ||
25 | * Charlie Andrews <charliethepilot@googlemail.com> for lots of help in | ||
26 | * bringing up the support of new firmware buffer that is popular | ||
27 | * on latest notebooks | ||
28 | * | ||
29 | * ENE for partial device documentation | ||
30 | * | ||
20 | */ | 31 | */ |
21 | 32 | ||
22 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
@@ -31,51 +42,59 @@ | |||
31 | #include <media/ir-common.h> | 42 | #include <media/ir-common.h> |
32 | #include "ene_ir.h" | 43 | #include "ene_ir.h" |
33 | 44 | ||
34 | 45 | static int sample_period; | |
35 | static int sample_period = -1; | 46 | static bool learning_mode_force; |
36 | static int enable_idle = 1; | ||
37 | static int input = 1; | ||
38 | static int debug; | 47 | static int debug; |
39 | static int txsim; | 48 | static bool txsim; |
40 | 49 | ||
41 | static int ene_irq_status(struct ene_device *dev); | 50 | static void ene_set_reg_addr(struct ene_device *dev, u16 reg) |
51 | { | ||
52 | outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); | ||
53 | outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); | ||
54 | } | ||
42 | 55 | ||
43 | /* read a hardware register */ | 56 | /* read a hardware register */ |
44 | static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg) | 57 | static u8 ene_read_reg(struct ene_device *dev, u16 reg) |
45 | { | 58 | { |
46 | u8 retval; | 59 | u8 retval; |
47 | outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); | 60 | ene_set_reg_addr(dev, reg); |
48 | outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); | ||
49 | retval = inb(dev->hw_io + ENE_IO); | 61 | retval = inb(dev->hw_io + ENE_IO); |
50 | 62 | dbg_regs("reg %04x == %02x", reg, retval); | |
51 | ene_dbg_verbose("reg %04x == %02x", reg, retval); | ||
52 | return retval; | 63 | return retval; |
53 | } | 64 | } |
54 | 65 | ||
55 | /* write a hardware register */ | 66 | /* write a hardware register */ |
56 | static void ene_hw_write_reg(struct ene_device *dev, u16 reg, u8 value) | 67 | static void ene_write_reg(struct ene_device *dev, u16 reg, u8 value) |
57 | { | 68 | { |
58 | outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); | 69 | dbg_regs("reg %04x <- %02x", reg, value); |
59 | outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); | 70 | ene_set_reg_addr(dev, reg); |
60 | outb(value, dev->hw_io + ENE_IO); | 71 | outb(value, dev->hw_io + ENE_IO); |
61 | |||
62 | ene_dbg_verbose("reg %04x <- %02x", reg, value); | ||
63 | } | 72 | } |
64 | 73 | ||
65 | /* change specific bits in hardware register */ | 74 | /* Set bits in hardware register */ |
66 | static void ene_hw_write_reg_mask(struct ene_device *dev, | 75 | static void ene_set_reg_mask(struct ene_device *dev, u16 reg, u8 mask) |
67 | u16 reg, u8 value, u8 mask) | ||
68 | { | 76 | { |
69 | u8 regvalue; | 77 | dbg_regs("reg %04x |= %02x", reg, mask); |
70 | 78 | ene_set_reg_addr(dev, reg); | |
71 | outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); | 79 | outb(inb(dev->hw_io + ENE_IO) | mask, dev->hw_io + ENE_IO); |
72 | outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); | 80 | } |
73 | 81 | ||
74 | regvalue = inb(dev->hw_io + ENE_IO) & ~mask; | 82 | /* Clear bits in hardware register */ |
75 | regvalue |= (value & mask); | 83 | static void ene_clear_reg_mask(struct ene_device *dev, u16 reg, u8 mask) |
76 | outb(regvalue, dev->hw_io + ENE_IO); | 84 | { |
85 | dbg_regs("reg %04x &= ~%02x ", reg, mask); | ||
86 | ene_set_reg_addr(dev, reg); | ||
87 | outb(inb(dev->hw_io + ENE_IO) & ~mask, dev->hw_io + ENE_IO); | ||
88 | } | ||
77 | 89 | ||
78 | ene_dbg_verbose("reg %04x <- %02x (mask=%02x)", reg, value, mask); | 90 | /* A helper to set/clear a bit in register according to boolean variable */ |
91 | static void ene_set_clear_reg_mask(struct ene_device *dev, u16 reg, u8 mask, | ||
92 | bool set) | ||
93 | { | ||
94 | if (set) | ||
95 | ene_set_reg_mask(dev, reg, mask); | ||
96 | else | ||
97 | ene_clear_reg_mask(dev, reg, mask); | ||
79 | } | 98 | } |
80 | 99 | ||
81 | /* detect hardware features */ | 100 | /* detect hardware features */ |
@@ -83,194 +102,378 @@ static int ene_hw_detect(struct ene_device *dev) | |||
83 | { | 102 | { |
84 | u8 chip_major, chip_minor; | 103 | u8 chip_major, chip_minor; |
85 | u8 hw_revision, old_ver; | 104 | u8 hw_revision, old_ver; |
86 | u8 tmp; | 105 | u8 fw_reg2, fw_reg1; |
87 | u8 fw_capabilities; | ||
88 | int pll_freq; | ||
89 | 106 | ||
90 | tmp = ene_hw_read_reg(dev, ENE_HW_UNK); | 107 | ene_clear_reg_mask(dev, ENE_ECSTS, ENE_ECSTS_RSRVD); |
91 | ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR); | 108 | chip_major = ene_read_reg(dev, ENE_ECVER_MAJOR); |
109 | chip_minor = ene_read_reg(dev, ENE_ECVER_MINOR); | ||
110 | ene_set_reg_mask(dev, ENE_ECSTS, ENE_ECSTS_RSRVD); | ||
92 | 111 | ||
93 | chip_major = ene_hw_read_reg(dev, ENE_HW_VER_MAJOR); | 112 | hw_revision = ene_read_reg(dev, ENE_ECHV); |
94 | chip_minor = ene_hw_read_reg(dev, ENE_HW_VER_MINOR); | 113 | old_ver = ene_read_reg(dev, ENE_HW_VER_OLD); |
95 | 114 | ||
96 | ene_hw_write_reg(dev, ENE_HW_UNK, tmp); | 115 | dev->pll_freq = (ene_read_reg(dev, ENE_PLLFRH) << 4) + |
97 | hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); | 116 | (ene_read_reg(dev, ENE_PLLFRL) >> 4); |
98 | old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); | ||
99 | 117 | ||
100 | pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) << 4) + | 118 | if (sample_period != ENE_DEFAULT_SAMPLE_PERIOD) |
101 | (ene_hw_read_reg(dev, ENE_PLLFRL) >> 4); | 119 | dev->rx_period_adjust = |
102 | 120 | dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 2 : 4; | |
103 | if (pll_freq != 1000) | ||
104 | dev->rx_period_adjust = 4; | ||
105 | else | ||
106 | dev->rx_period_adjust = 2; | ||
107 | |||
108 | |||
109 | ene_printk(KERN_NOTICE, "PLL freq = %d\n", pll_freq); | ||
110 | 121 | ||
111 | if (hw_revision == 0xFF) { | 122 | if (hw_revision == 0xFF) { |
112 | 123 | ene_warn("device seems to be disabled"); | |
113 | ene_printk(KERN_WARNING, "device seems to be disabled\n"); | 124 | ene_warn("send a mail to lirc-list@lists.sourceforge.net"); |
114 | ene_printk(KERN_WARNING, | 125 | ene_warn("please attach output of acpidump and dmidecode"); |
115 | "send a mail to lirc-list@lists.sourceforge.net\n"); | ||
116 | ene_printk(KERN_WARNING, "please attach output of acpidump\n"); | ||
117 | return -ENODEV; | 126 | return -ENODEV; |
118 | } | 127 | } |
119 | 128 | ||
129 | ene_notice("chip is 0x%02x%02x - kbver = 0x%02x, rev = 0x%02x", | ||
130 | chip_major, chip_minor, old_ver, hw_revision); | ||
131 | |||
132 | ene_notice("PLL freq = %d", dev->pll_freq); | ||
133 | |||
120 | if (chip_major == 0x33) { | 134 | if (chip_major == 0x33) { |
121 | ene_printk(KERN_WARNING, "chips 0x33xx aren't supported\n"); | 135 | ene_warn("chips 0x33xx aren't supported"); |
122 | return -ENODEV; | 136 | return -ENODEV; |
123 | } | 137 | } |
124 | 138 | ||
125 | if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) { | 139 | if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) { |
126 | dev->hw_revision = ENE_HW_C; | 140 | dev->hw_revision = ENE_HW_C; |
141 | ene_notice("KB3926C detected"); | ||
127 | } else if (old_ver == 0x24 && hw_revision == 0xC0) { | 142 | } else if (old_ver == 0x24 && hw_revision == 0xC0) { |
128 | dev->hw_revision = ENE_HW_B; | 143 | dev->hw_revision = ENE_HW_B; |
129 | ene_printk(KERN_NOTICE, "KB3926B detected\n"); | 144 | ene_notice("KB3926B detected"); |
130 | } else { | 145 | } else { |
131 | dev->hw_revision = ENE_HW_D; | 146 | dev->hw_revision = ENE_HW_D; |
132 | ene_printk(KERN_WARNING, | 147 | ene_notice("KB3926D or higher detected"); |
133 | "unknown ENE chip detected, assuming KB3926D\n"); | ||
134 | ene_printk(KERN_WARNING, | ||
135 | "driver support might be not complete"); | ||
136 | |||
137 | } | 148 | } |
138 | 149 | ||
139 | ene_printk(KERN_DEBUG, | ||
140 | "chip is 0x%02x%02x - kbver = 0x%02x, rev = 0x%02x\n", | ||
141 | chip_major, chip_minor, old_ver, hw_revision); | ||
142 | |||
143 | /* detect features hardware supports */ | 150 | /* detect features hardware supports */ |
144 | if (dev->hw_revision < ENE_HW_C) | 151 | if (dev->hw_revision < ENE_HW_C) |
145 | return 0; | 152 | return 0; |
146 | 153 | ||
147 | fw_capabilities = ene_hw_read_reg(dev, ENE_FW2); | 154 | fw_reg1 = ene_read_reg(dev, ENE_FW1); |
148 | ene_dbg("Firmware capabilities: %02x", fw_capabilities); | 155 | fw_reg2 = ene_read_reg(dev, ENE_FW2); |
156 | |||
157 | ene_notice("Firmware regs: %02x %02x", fw_reg1, fw_reg2); | ||
149 | 158 | ||
150 | dev->hw_gpio40_learning = fw_capabilities & ENE_FW2_GP40_AS_LEARN; | 159 | dev->hw_use_gpio_0a = !!(fw_reg2 & ENE_FW2_GP0A); |
151 | dev->hw_learning_and_tx_capable = fw_capabilities & ENE_FW2_LEARNING; | 160 | dev->hw_learning_and_tx_capable = !!(fw_reg2 & ENE_FW2_LEARNING); |
161 | dev->hw_extra_buffer = !!(fw_reg1 & ENE_FW1_HAS_EXTRA_BUF); | ||
152 | 162 | ||
153 | dev->hw_fan_as_normal_input = dev->hw_learning_and_tx_capable && | 163 | if (dev->hw_learning_and_tx_capable) |
154 | (fw_capabilities & ENE_FW2_FAN_AS_NRML_IN); | 164 | dev->hw_fan_input = !!(fw_reg2 & ENE_FW2_FAN_INPUT); |
155 | 165 | ||
156 | ene_printk(KERN_NOTICE, "hardware features:\n"); | 166 | ene_notice("Hardware features:"); |
157 | ene_printk(KERN_NOTICE, | ||
158 | "learning and transmit %s, gpio40_learn %s, fan_in %s\n", | ||
159 | dev->hw_learning_and_tx_capable ? "on" : "off", | ||
160 | dev->hw_gpio40_learning ? "on" : "off", | ||
161 | dev->hw_fan_as_normal_input ? "on" : "off"); | ||
162 | 167 | ||
163 | if (dev->hw_learning_and_tx_capable) { | 168 | if (dev->hw_learning_and_tx_capable) { |
164 | ene_printk(KERN_WARNING, | 169 | ene_notice("* Supports transmitting & learning mode"); |
165 | "Device supports transmitting, but that support is\n"); | 170 | ene_notice(" This feature is rare and therefore,"); |
166 | ene_printk(KERN_WARNING, | 171 | ene_notice(" you are welcome to test it,"); |
167 | "lightly tested. Please test it and mail\n"); | 172 | ene_notice(" and/or contact the author via:"); |
168 | ene_printk(KERN_WARNING, | 173 | ene_notice(" lirc-list@lists.sourceforge.net"); |
169 | "lirc-list@lists.sourceforge.net\n"); | 174 | ene_notice(" or maximlevitsky@gmail.com"); |
175 | |||
176 | ene_notice("* Uses GPIO %s for IR raw input", | ||
177 | dev->hw_use_gpio_0a ? "40" : "0A"); | ||
178 | |||
179 | if (dev->hw_fan_input) | ||
180 | ene_notice("* Uses unused fan feedback input as source" | ||
181 | " of demodulated IR data"); | ||
170 | } | 182 | } |
183 | |||
184 | if (!dev->hw_fan_input) | ||
185 | ene_notice("* Uses GPIO %s for IR demodulated input", | ||
186 | dev->hw_use_gpio_0a ? "0A" : "40"); | ||
187 | |||
188 | if (dev->hw_extra_buffer) | ||
189 | ene_notice("* Uses new style input buffer"); | ||
171 | return 0; | 190 | return 0; |
172 | } | 191 | } |
173 | 192 | ||
174 | /* this enables/disables IR input via gpio40*/ | 193 | /* Read properities of hw sample buffer */ |
175 | static void ene_enable_gpio40_receive(struct ene_device *dev, int enable) | 194 | static void ene_rx_setup_hw_buffer(struct ene_device *dev) |
176 | { | 195 | { |
177 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, enable ? | 196 | u16 tmp; |
178 | 0 : ENE_CIR_CONF2_GPIO40DIS, | 197 | |
179 | ENE_CIR_CONF2_GPIO40DIS); | 198 | ene_rx_read_hw_pointer(dev); |
199 | dev->r_pointer = dev->w_pointer; | ||
200 | |||
201 | if (!dev->hw_extra_buffer) { | ||
202 | dev->buffer_len = ENE_FW_PACKET_SIZE * 2; | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER); | ||
207 | tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8; | ||
208 | dev->extra_buf1_address = tmp; | ||
209 | |||
210 | dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2); | ||
211 | |||
212 | tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3); | ||
213 | tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8; | ||
214 | dev->extra_buf2_address = tmp; | ||
215 | |||
216 | dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5); | ||
217 | |||
218 | dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8; | ||
219 | |||
220 | ene_notice("Hardware uses 2 extended buffers:"); | ||
221 | ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address, | ||
222 | dev->extra_buf1_len); | ||
223 | ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address, | ||
224 | dev->extra_buf2_len); | ||
225 | |||
226 | ene_notice("Total buffer len = %d", dev->buffer_len); | ||
227 | |||
228 | if (dev->buffer_len > 64 || dev->buffer_len < 16) | ||
229 | goto error; | ||
230 | |||
231 | if (dev->extra_buf1_address > 0xFBFC || | ||
232 | dev->extra_buf1_address < 0xEC00) | ||
233 | goto error; | ||
234 | |||
235 | if (dev->extra_buf2_address > 0xFBFC || | ||
236 | dev->extra_buf2_address < 0xEC00) | ||
237 | goto error; | ||
238 | |||
239 | if (dev->r_pointer > dev->buffer_len) | ||
240 | goto error; | ||
241 | |||
242 | ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND); | ||
243 | return; | ||
244 | error: | ||
245 | ene_warn("Error validating extra buffers, device probably won't work"); | ||
246 | dev->hw_extra_buffer = false; | ||
247 | ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND); | ||
180 | } | 248 | } |
181 | 249 | ||
182 | /* this enables/disables IR via standard input */ | 250 | |
183 | static void ene_enable_normal_receive(struct ene_device *dev, int enable) | 251 | /* Restore the pointers to extra buffers - to make module reload work*/ |
252 | static void ene_rx_restore_hw_buffer(struct ene_device *dev) | ||
184 | { | 253 | { |
185 | ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_RX_ON : 0); | 254 | if (!dev->hw_extra_buffer) |
255 | return; | ||
256 | |||
257 | ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0, | ||
258 | dev->extra_buf1_address & 0xFF); | ||
259 | ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1, | ||
260 | dev->extra_buf1_address >> 8); | ||
261 | ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len); | ||
262 | |||
263 | ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3, | ||
264 | dev->extra_buf2_address & 0xFF); | ||
265 | ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4, | ||
266 | dev->extra_buf2_address >> 8); | ||
267 | ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5, | ||
268 | dev->extra_buf2_len); | ||
269 | ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND); | ||
186 | } | 270 | } |
187 | 271 | ||
188 | /* this enables/disables IR input via unused fan tachtometer input */ | 272 | /* Read hardware write pointer */ |
189 | static void ene_enable_fan_receive(struct ene_device *dev, int enable) | 273 | static void ene_rx_read_hw_pointer(struct ene_device *dev) |
190 | { | 274 | { |
191 | if (!enable) | 275 | if (dev->hw_extra_buffer) |
192 | ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0); | 276 | dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER); |
193 | else { | 277 | else |
194 | ene_hw_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN); | 278 | dev->w_pointer = ene_read_reg(dev, ENE_FW2) |
195 | ene_hw_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN); | 279 | & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE; |
196 | } | 280 | |
197 | dev->rx_fan_input_inuse = enable; | 281 | dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x", |
282 | dev->w_pointer, dev->r_pointer); | ||
198 | } | 283 | } |
199 | 284 | ||
285 | /* Gets address of next sample from HW ring buffer */ | ||
286 | static int ene_rx_get_sample_reg(struct ene_device *dev) | ||
287 | { | ||
288 | int r_pointer; | ||
289 | |||
290 | if (dev->r_pointer == dev->w_pointer) { | ||
291 | dbg_verbose("RB: hit end, try update w_pointer"); | ||
292 | ene_rx_read_hw_pointer(dev); | ||
293 | } | ||
294 | |||
295 | if (dev->r_pointer == dev->w_pointer) { | ||
296 | dbg_verbose("RB: end of data at %d", dev->r_pointer); | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | dbg_verbose("RB: reading at offset %d", dev->r_pointer); | ||
301 | r_pointer = dev->r_pointer; | ||
302 | |||
303 | dev->r_pointer++; | ||
304 | if (dev->r_pointer == dev->buffer_len) | ||
305 | dev->r_pointer = 0; | ||
306 | |||
307 | dbg_verbose("RB: next read will be from offset %d", dev->r_pointer); | ||
308 | |||
309 | if (r_pointer < 8) { | ||
310 | dbg_verbose("RB: read at main buffer at %d", r_pointer); | ||
311 | return ENE_FW_SAMPLE_BUFFER + r_pointer; | ||
312 | } | ||
313 | |||
314 | r_pointer -= 8; | ||
315 | |||
316 | if (r_pointer < dev->extra_buf1_len) { | ||
317 | dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer); | ||
318 | return dev->extra_buf1_address + r_pointer; | ||
319 | } | ||
320 | |||
321 | r_pointer -= dev->extra_buf1_len; | ||
322 | |||
323 | if (r_pointer < dev->extra_buf2_len) { | ||
324 | dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer); | ||
325 | return dev->extra_buf2_address + r_pointer; | ||
326 | } | ||
327 | |||
328 | dbg("attempt to read beyong ring bufer end"); | ||
329 | return 0; | ||
330 | } | ||
200 | 331 | ||
201 | /* Sense current received carrier */ | 332 | /* Sense current received carrier */ |
202 | static int ene_rx_sense_carrier(struct ene_device *dev) | 333 | void ene_rx_sense_carrier(struct ene_device *dev) |
203 | { | 334 | { |
204 | int period = ene_hw_read_reg(dev, ENE_RX_CARRIER); | 335 | DEFINE_IR_RAW_EVENT(ev); |
205 | int carrier; | ||
206 | ene_dbg("RX: hardware carrier period = %02x", period); | ||
207 | 336 | ||
208 | if (!(period & ENE_RX_CARRIER_VALID)) | 337 | int carrier, duty_cycle; |
209 | return 0; | 338 | int period = ene_read_reg(dev, ENE_CIRCAR_PRD); |
339 | int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD); | ||
340 | |||
341 | if (!(period & ENE_CIRCAR_PRD_VALID)) | ||
342 | return; | ||
210 | 343 | ||
211 | period &= ~ENE_RX_CARRIER_VALID; | 344 | period &= ~ENE_CIRCAR_PRD_VALID; |
212 | 345 | ||
213 | if (!period) | 346 | if (!period) |
214 | return 0; | 347 | return; |
348 | |||
349 | dbg("RX: hardware carrier period = %02x", period); | ||
350 | dbg("RX: hardware carrier pulse period = %02x", hperiod); | ||
215 | 351 | ||
216 | carrier = 2000000 / period; | 352 | carrier = 2000000 / period; |
217 | ene_dbg("RX: sensed carrier = %d Hz", carrier); | 353 | duty_cycle = (hperiod * 100) / period; |
218 | return carrier; | 354 | dbg("RX: sensed carrier = %d Hz, duty cycle %d%%", |
355 | carrier, duty_cycle); | ||
356 | if (dev->carrier_detect_enabled) { | ||
357 | ev.carrier_report = true; | ||
358 | ev.carrier = carrier; | ||
359 | ev.duty_cycle = duty_cycle; | ||
360 | ir_raw_event_store(dev->idev, &ev); | ||
361 | } | ||
219 | } | 362 | } |
220 | 363 | ||
221 | /* determine which input to use*/ | 364 | /* this enables/disables the CIR RX engine */ |
222 | static void ene_rx_set_inputs(struct ene_device *dev) | 365 | static void ene_rx_enable_cir_engine(struct ene_device *dev, bool enable) |
223 | { | 366 | { |
224 | int learning_mode = dev->learning_enabled; | 367 | ene_set_clear_reg_mask(dev, ENE_CIRCFG, |
225 | 368 | ENE_CIRCFG_RX_EN | ENE_CIRCFG_RX_IRQ, enable); | |
226 | ene_dbg("RX: setup receiver, learning mode = %d", learning_mode); | 369 | } |
227 | 370 | ||
228 | ene_enable_normal_receive(dev, 1); | 371 | /* this selects input for CIR engine. Ether GPIO 0A or GPIO40*/ |
372 | static void ene_rx_select_input(struct ene_device *dev, bool gpio_0a) | ||
373 | { | ||
374 | ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_GPIO0A, gpio_0a); | ||
375 | } | ||
229 | 376 | ||
230 | /* old hardware doesn't support learning mode for sure */ | 377 | /* |
231 | if (dev->hw_revision <= ENE_HW_B) | 378 | * this enables alternative input via fan tachometer sensor and bypasses |
379 | * the hw CIR engine | ||
380 | */ | ||
381 | static void ene_rx_enable_fan_input(struct ene_device *dev, bool enable) | ||
382 | { | ||
383 | if (!dev->hw_fan_input) | ||
232 | return; | 384 | return; |
233 | 385 | ||
234 | /* receiver not learning capable, still set gpio40 correctly */ | 386 | if (!enable) |
235 | if (!dev->hw_learning_and_tx_capable) { | 387 | ene_write_reg(dev, ENE_FAN_AS_IN1, 0); |
236 | ene_enable_gpio40_receive(dev, !dev->hw_gpio40_learning); | 388 | else { |
237 | return; | 389 | ene_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN); |
390 | ene_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN); | ||
238 | } | 391 | } |
392 | } | ||
393 | |||
394 | /* setup the receiver for RX*/ | ||
395 | static void ene_rx_setup(struct ene_device *dev) | ||
396 | { | ||
397 | bool learning_mode = dev->learning_mode_enabled || | ||
398 | dev->carrier_detect_enabled; | ||
399 | int sample_period_adjust = 0; | ||
400 | |||
401 | dbg("RX: setup receiver, learning mode = %d", learning_mode); | ||
402 | |||
403 | |||
404 | /* This selects RLC input and clears CFG2 settings */ | ||
405 | ene_write_reg(dev, ENE_CIRCFG2, 0x00); | ||
406 | |||
407 | /* set sample period*/ | ||
408 | if (sample_period == ENE_DEFAULT_SAMPLE_PERIOD) | ||
409 | sample_period_adjust = | ||
410 | dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 1 : 2; | ||
411 | |||
412 | ene_write_reg(dev, ENE_CIRRLC_CFG, | ||
413 | (sample_period + sample_period_adjust) | | ||
414 | ENE_CIRRLC_CFG_OVERFLOW); | ||
415 | /* revB doesn't support inputs */ | ||
416 | if (dev->hw_revision < ENE_HW_C) | ||
417 | goto select_timeout; | ||
239 | 418 | ||
240 | /* enable learning mode */ | ||
241 | if (learning_mode) { | 419 | if (learning_mode) { |
242 | ene_enable_gpio40_receive(dev, dev->hw_gpio40_learning); | ||
243 | 420 | ||
244 | /* fan input is not used for learning */ | 421 | WARN_ON(!dev->hw_learning_and_tx_capable); |
245 | if (dev->hw_fan_as_normal_input) | ||
246 | ene_enable_fan_receive(dev, 0); | ||
247 | 422 | ||
248 | /* disable learning mode */ | 423 | /* Enable the opposite of the normal input |
249 | } else { | 424 | That means that if GPIO40 is normally used, use GPIO0A |
250 | if (dev->hw_fan_as_normal_input) { | 425 | and vice versa. |
251 | ene_enable_fan_receive(dev, 1); | 426 | This input will carry non demodulated |
252 | ene_enable_normal_receive(dev, 0); | 427 | signal, and we will tell the hw to demodulate it itself */ |
253 | } else | 428 | ene_rx_select_input(dev, !dev->hw_use_gpio_0a); |
254 | ene_enable_gpio40_receive(dev, | 429 | dev->rx_fan_input_inuse = false; |
255 | !dev->hw_gpio40_learning); | ||
256 | } | ||
257 | 430 | ||
258 | /* set few additional settings for this mode */ | 431 | /* Enable carrier demodulation */ |
259 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, learning_mode ? | 432 | ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD); |
260 | ENE_CIR_CONF1_LEARN1 : 0, ENE_CIR_CONF1_LEARN1); | ||
261 | 433 | ||
262 | ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_mode ? | 434 | /* Enable carrier detection */ |
263 | ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2); | 435 | ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63); |
436 | ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT, | ||
437 | dev->carrier_detect_enabled || debug); | ||
438 | } else { | ||
439 | if (dev->hw_fan_input) | ||
440 | dev->rx_fan_input_inuse = true; | ||
441 | else | ||
442 | ene_rx_select_input(dev, dev->hw_use_gpio_0a); | ||
443 | |||
444 | /* Disable carrier detection & demodulation */ | ||
445 | ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD); | ||
446 | ene_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT); | ||
447 | } | ||
264 | 448 | ||
449 | select_timeout: | ||
265 | if (dev->rx_fan_input_inuse) { | 450 | if (dev->rx_fan_input_inuse) { |
266 | dev->props->rx_resolution = ENE_SAMPLE_PERIOD_FAN * 1000; | 451 | dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); |
267 | 452 | ||
268 | dev->props->timeout = | 453 | /* Fan input doesn't support timeouts, it just ends the |
269 | ENE_FAN_VALUE_MASK * ENE_SAMPLE_PERIOD_FAN * 1000; | 454 | input with a maximum sample */ |
455 | dev->props->min_timeout = dev->props->max_timeout = | ||
456 | MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * | ||
457 | ENE_FW_SAMPLE_PERIOD_FAN); | ||
270 | } else { | 458 | } else { |
271 | dev->props->rx_resolution = sample_period * 1000; | 459 | dev->props->rx_resolution = MS_TO_NS(sample_period); |
272 | dev->props->timeout = ENE_MAXGAP * 1000; | 460 | |
461 | /* Theoreticly timeout is unlimited, but we cap it | ||
462 | * because it was seen that on one device, it | ||
463 | * would stop sending spaces after around 250 msec. | ||
464 | * Besides, this is close to 2^32 anyway and timeout is u32. | ||
465 | */ | ||
466 | dev->props->min_timeout = MS_TO_NS(127 * sample_period); | ||
467 | dev->props->max_timeout = MS_TO_NS(200000); | ||
273 | } | 468 | } |
469 | |||
470 | if (dev->hw_learning_and_tx_capable) | ||
471 | dev->props->tx_resolution = MS_TO_NS(sample_period); | ||
472 | |||
473 | if (dev->props->timeout > dev->props->max_timeout) | ||
474 | dev->props->timeout = dev->props->max_timeout; | ||
475 | if (dev->props->timeout < dev->props->min_timeout) | ||
476 | dev->props->timeout = dev->props->min_timeout; | ||
274 | } | 477 | } |
275 | 478 | ||
276 | /* Enable the device for receive */ | 479 | /* Enable the device for receive */ |
@@ -278,145 +481,157 @@ static void ene_rx_enable(struct ene_device *dev) | |||
278 | { | 481 | { |
279 | u8 reg_value; | 482 | u8 reg_value; |
280 | 483 | ||
484 | /* Enable system interrupt */ | ||
281 | if (dev->hw_revision < ENE_HW_C) { | 485 | if (dev->hw_revision < ENE_HW_C) { |
282 | ene_hw_write_reg(dev, ENEB_IRQ, dev->irq << 1); | 486 | ene_write_reg(dev, ENEB_IRQ, dev->irq << 1); |
283 | ene_hw_write_reg(dev, ENEB_IRQ_UNK1, 0x01); | 487 | ene_write_reg(dev, ENEB_IRQ_UNK1, 0x01); |
284 | } else { | 488 | } else { |
285 | reg_value = ene_hw_read_reg(dev, ENEC_IRQ) & 0xF0; | 489 | reg_value = ene_read_reg(dev, ENE_IRQ) & 0xF0; |
286 | reg_value |= ENEC_IRQ_UNK_EN; | 490 | reg_value |= ENE_IRQ_UNK_EN; |
287 | reg_value &= ~ENEC_IRQ_STATUS; | 491 | reg_value &= ~ENE_IRQ_STATUS; |
288 | reg_value |= (dev->irq & ENEC_IRQ_MASK); | 492 | reg_value |= (dev->irq & ENE_IRQ_MASK); |
289 | ene_hw_write_reg(dev, ENEC_IRQ, reg_value); | 493 | ene_write_reg(dev, ENE_IRQ, reg_value); |
290 | ene_hw_write_reg(dev, ENE_TX_UNK1, 0x63); | ||
291 | } | 494 | } |
292 | 495 | ||
293 | ene_hw_write_reg(dev, ENE_CIR_CONF2, 0x00); | 496 | /* Enable inputs */ |
294 | ene_rx_set_inputs(dev); | 497 | ene_rx_enable_fan_input(dev, dev->rx_fan_input_inuse); |
295 | 498 | ene_rx_enable_cir_engine(dev, !dev->rx_fan_input_inuse); | |
296 | /* set sampling period */ | ||
297 | ene_hw_write_reg(dev, ENE_CIR_SAMPLE_PERIOD, sample_period); | ||
298 | 499 | ||
299 | /* ack any pending irqs - just in case */ | 500 | /* ack any pending irqs - just in case */ |
300 | ene_irq_status(dev); | 501 | ene_irq_status(dev); |
301 | 502 | ||
302 | /* enable firmware bits */ | 503 | /* enable firmware bits */ |
303 | ene_hw_write_reg_mask(dev, ENE_FW1, | 504 | ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); |
304 | ENE_FW1_ENABLE | ENE_FW1_IRQ, | ||
305 | ENE_FW1_ENABLE | ENE_FW1_IRQ); | ||
306 | 505 | ||
307 | /* enter idle mode */ | 506 | /* enter idle mode */ |
308 | ir_raw_event_set_idle(dev->idev, 1); | 507 | ir_raw_event_set_idle(dev->idev, true); |
309 | ir_raw_event_reset(dev->idev); | 508 | dev->rx_enabled = true; |
310 | |||
311 | } | 509 | } |
312 | 510 | ||
313 | /* Disable the device receiver */ | 511 | /* Disable the device receiver */ |
314 | static void ene_rx_disable(struct ene_device *dev) | 512 | static void ene_rx_disable(struct ene_device *dev) |
315 | { | 513 | { |
316 | /* disable inputs */ | 514 | /* disable inputs */ |
317 | ene_enable_normal_receive(dev, 0); | 515 | ene_rx_enable_cir_engine(dev, false); |
318 | 516 | ene_rx_enable_fan_input(dev, false); | |
319 | if (dev->hw_fan_as_normal_input) | ||
320 | ene_enable_fan_receive(dev, 0); | ||
321 | 517 | ||
322 | /* disable hardware IRQ and firmware flag */ | 518 | /* disable hardware IRQ and firmware flag */ |
323 | ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ); | 519 | ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); |
324 | 520 | ||
325 | ir_raw_event_set_idle(dev->idev, 1); | 521 | ir_raw_event_set_idle(dev->idev, true); |
326 | ir_raw_event_reset(dev->idev); | 522 | dev->rx_enabled = false; |
327 | } | 523 | } |
328 | 524 | ||
525 | /* This resets the receiver. Usefull to stop stream of spaces at end of | ||
526 | * transmission | ||
527 | */ | ||
528 | static void ene_rx_reset(struct ene_device *dev) | ||
529 | { | ||
530 | ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN); | ||
531 | ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN); | ||
532 | } | ||
329 | 533 | ||
330 | /* prepare transmission */ | 534 | /* Set up the TX carrier frequency and duty cycle */ |
331 | static void ene_tx_prepare(struct ene_device *dev) | 535 | static void ene_tx_set_carrier(struct ene_device *dev) |
332 | { | 536 | { |
333 | u8 conf1; | 537 | u8 tx_puls_width; |
538 | unsigned long flags; | ||
334 | 539 | ||
335 | conf1 = ene_hw_read_reg(dev, ENE_CIR_CONF1); | 540 | spin_lock_irqsave(&dev->hw_lock, flags); |
336 | dev->saved_conf1 = conf1; | ||
337 | 541 | ||
338 | if (dev->hw_revision == ENE_HW_C) | 542 | ene_set_clear_reg_mask(dev, ENE_CIRCFG, |
339 | conf1 &= ~ENE_CIR_CONF1_TX_CLEAR; | 543 | ENE_CIRCFG_TX_CARR, dev->tx_period > 0); |
340 | 544 | ||
341 | /* Enable TX engine */ | 545 | if (!dev->tx_period) |
342 | conf1 |= ENE_CIR_CONF1_TX_ON; | 546 | goto unlock; |
343 | 547 | ||
344 | /* Set carrier */ | 548 | BUG_ON(dev->tx_duty_cycle >= 100 || dev->tx_duty_cycle <= 0); |
345 | if (dev->tx_period) { | ||
346 | 549 | ||
347 | /* NOTE: duty cycle handling is just a guess, it might | 550 | tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle); |
348 | not be aviable. Default values were tested */ | ||
349 | int tx_period_in500ns = dev->tx_period * 2; | ||
350 | 551 | ||
351 | int tx_pulse_width_in_500ns = | 552 | if (!tx_puls_width) |
352 | tx_period_in500ns / (100 / dev->tx_duty_cycle); | 553 | tx_puls_width = 1; |
353 | 554 | ||
354 | if (!tx_pulse_width_in_500ns) | 555 | dbg("TX: pulse distance = %d * 500 ns", dev->tx_period); |
355 | tx_pulse_width_in_500ns = 1; | 556 | dbg("TX: pulse width = %d * 500 ns", tx_puls_width); |
356 | 557 | ||
357 | ene_dbg("TX: pulse distance = %d * 500 ns", tx_period_in500ns); | 558 | ene_write_reg(dev, ENE_CIRMOD_PRD, dev->tx_period | ENE_CIRMOD_PRD_POL); |
358 | ene_dbg("TX: pulse width = %d * 500 ns", | 559 | ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width); |
359 | tx_pulse_width_in_500ns); | 560 | unlock: |
561 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
562 | } | ||
360 | 563 | ||
361 | ene_hw_write_reg(dev, ENE_TX_PERIOD, ENE_TX_PERIOD_UNKBIT | | 564 | /* Enable/disable transmitters */ |
362 | tx_period_in500ns); | 565 | static void ene_tx_set_transmitters(struct ene_device *dev) |
566 | { | ||
567 | unsigned long flags; | ||
363 | 568 | ||
364 | ene_hw_write_reg(dev, ENE_TX_PERIOD_PULSE, | 569 | spin_lock_irqsave(&dev->hw_lock, flags); |
365 | tx_pulse_width_in_500ns); | 570 | ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41, |
571 | !!(dev->transmitter_mask & 0x01)); | ||
572 | ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D, | ||
573 | !!(dev->transmitter_mask & 0x02)); | ||
574 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
575 | } | ||
366 | 576 | ||
367 | conf1 |= ENE_CIR_CONF1_TX_CARR; | 577 | /* prepare transmission */ |
368 | } else | 578 | static void ene_tx_enable(struct ene_device *dev) |
369 | conf1 &= ~ENE_CIR_CONF1_TX_CARR; | 579 | { |
580 | u8 conf1 = ene_read_reg(dev, ENE_CIRCFG); | ||
581 | u8 fwreg2 = ene_read_reg(dev, ENE_FW2); | ||
582 | |||
583 | dev->saved_conf1 = conf1; | ||
584 | |||
585 | /* Show information about currently connected transmitter jacks */ | ||
586 | if (fwreg2 & ENE_FW2_EMMITER1_CONN) | ||
587 | dbg("TX: Transmitter #1 is connected"); | ||
588 | |||
589 | if (fwreg2 & ENE_FW2_EMMITER2_CONN) | ||
590 | dbg("TX: Transmitter #2 is connected"); | ||
370 | 591 | ||
371 | ene_hw_write_reg(dev, ENE_CIR_CONF1, conf1); | 592 | if (!(fwreg2 & (ENE_FW2_EMMITER1_CONN | ENE_FW2_EMMITER2_CONN))) |
593 | ene_warn("TX: transmitter cable isn't connected!"); | ||
372 | 594 | ||
595 | /* disable receive on revc */ | ||
596 | if (dev->hw_revision == ENE_HW_C) | ||
597 | conf1 &= ~ENE_CIRCFG_RX_EN; | ||
598 | |||
599 | /* Enable TX engine */ | ||
600 | conf1 |= ENE_CIRCFG_TX_EN | ENE_CIRCFG_TX_IRQ; | ||
601 | ene_write_reg(dev, ENE_CIRCFG, conf1); | ||
373 | } | 602 | } |
374 | 603 | ||
375 | /* end transmission */ | 604 | /* end transmission */ |
376 | static void ene_tx_complete(struct ene_device *dev) | 605 | static void ene_tx_disable(struct ene_device *dev) |
377 | { | 606 | { |
378 | ene_hw_write_reg(dev, ENE_CIR_CONF1, dev->saved_conf1); | 607 | ene_write_reg(dev, ENE_CIRCFG, dev->saved_conf1); |
379 | dev->tx_buffer = NULL; | 608 | dev->tx_buffer = NULL; |
380 | } | 609 | } |
381 | 610 | ||
382 | /* set transmit mask */ | ||
383 | static void ene_tx_hw_set_transmiter_mask(struct ene_device *dev) | ||
384 | { | ||
385 | u8 txport1 = ene_hw_read_reg(dev, ENE_TX_PORT1) & ~ENE_TX_PORT1_EN; | ||
386 | u8 txport2 = ene_hw_read_reg(dev, ENE_TX_PORT2) & ~ENE_TX_PORT2_EN; | ||
387 | |||
388 | if (dev->transmitter_mask & 0x01) | ||
389 | txport1 |= ENE_TX_PORT1_EN; | ||
390 | |||
391 | if (dev->transmitter_mask & 0x02) | ||
392 | txport2 |= ENE_TX_PORT2_EN; | ||
393 | |||
394 | ene_hw_write_reg(dev, ENE_TX_PORT1, txport1); | ||
395 | ene_hw_write_reg(dev, ENE_TX_PORT2, txport2); | ||
396 | } | ||
397 | 611 | ||
398 | /* TX one sample - must be called with dev->hw_lock*/ | 612 | /* TX one sample - must be called with dev->hw_lock*/ |
399 | static void ene_tx_sample(struct ene_device *dev) | 613 | static void ene_tx_sample(struct ene_device *dev) |
400 | { | 614 | { |
401 | u8 raw_tx; | 615 | u8 raw_tx; |
402 | u32 sample; | 616 | u32 sample; |
617 | bool pulse = dev->tx_sample_pulse; | ||
403 | 618 | ||
404 | if (!dev->tx_buffer) { | 619 | if (!dev->tx_buffer) { |
405 | ene_dbg("TX: attempt to transmit NULL buffer"); | 620 | ene_warn("TX: BUG: attempt to transmit NULL buffer"); |
406 | return; | 621 | return; |
407 | } | 622 | } |
408 | 623 | ||
409 | /* Grab next TX sample */ | 624 | /* Grab next TX sample */ |
410 | if (!dev->tx_sample) { | 625 | if (!dev->tx_sample) { |
411 | again: | 626 | |
412 | if (dev->tx_pos == dev->tx_len + 1) { | 627 | if (dev->tx_pos == dev->tx_len) { |
413 | if (!dev->tx_done) { | 628 | if (!dev->tx_done) { |
414 | ene_dbg("TX: no more data to send"); | 629 | dbg("TX: no more data to send"); |
415 | dev->tx_done = 1; | 630 | dev->tx_done = true; |
416 | goto exit; | 631 | goto exit; |
417 | } else { | 632 | } else { |
418 | ene_dbg("TX: last sample sent by hardware"); | 633 | dbg("TX: last sample sent by hardware"); |
419 | ene_tx_complete(dev); | 634 | ene_tx_disable(dev); |
420 | complete(&dev->tx_complete); | 635 | complete(&dev->tx_complete); |
421 | return; | 636 | return; |
422 | } | 637 | } |
@@ -425,23 +640,23 @@ again: | |||
425 | sample = dev->tx_buffer[dev->tx_pos++]; | 640 | sample = dev->tx_buffer[dev->tx_pos++]; |
426 | dev->tx_sample_pulse = !dev->tx_sample_pulse; | 641 | dev->tx_sample_pulse = !dev->tx_sample_pulse; |
427 | 642 | ||
428 | ene_dbg("TX: sample %8d (%s)", sample, dev->tx_sample_pulse ? | 643 | dev->tx_sample = DIV_ROUND_CLOSEST(sample, sample_period); |
429 | "pulse" : "space"); | ||
430 | 644 | ||
431 | dev->tx_sample = DIV_ROUND_CLOSEST(sample, ENE_TX_SMPL_PERIOD); | ||
432 | |||
433 | /* guard against too short samples */ | ||
434 | if (!dev->tx_sample) | 645 | if (!dev->tx_sample) |
435 | goto again; | 646 | dev->tx_sample = 1; |
436 | } | 647 | } |
437 | 648 | ||
438 | raw_tx = min(dev->tx_sample , (unsigned int)ENE_TX_SMLP_MASK); | 649 | raw_tx = min(dev->tx_sample , (unsigned int)ENE_CIRRLC_OUT_MASK); |
439 | dev->tx_sample -= raw_tx; | 650 | dev->tx_sample -= raw_tx; |
440 | 651 | ||
441 | if (dev->tx_sample_pulse) | 652 | dbg("TX: sample %8d (%s)", raw_tx * sample_period, |
442 | raw_tx |= ENE_TX_PULSE_MASK; | 653 | pulse ? "pulse" : "space"); |
654 | if (pulse) | ||
655 | raw_tx |= ENE_CIRRLC_OUT_PULSE; | ||
656 | |||
657 | ene_write_reg(dev, | ||
658 | dev->tx_reg ? ENE_CIRRLC_OUT1 : ENE_CIRRLC_OUT0, raw_tx); | ||
443 | 659 | ||
444 | ene_hw_write_reg(dev, ENE_TX_INPUT1 + dev->tx_reg, raw_tx); | ||
445 | dev->tx_reg = !dev->tx_reg; | 660 | dev->tx_reg = !dev->tx_reg; |
446 | exit: | 661 | exit: |
447 | /* simulate TX done interrupt */ | 662 | /* simulate TX done interrupt */ |
@@ -466,76 +681,59 @@ static int ene_irq_status(struct ene_device *dev) | |||
466 | { | 681 | { |
467 | u8 irq_status; | 682 | u8 irq_status; |
468 | u8 fw_flags1, fw_flags2; | 683 | u8 fw_flags1, fw_flags2; |
469 | int cur_rx_pointer; | ||
470 | int retval = 0; | 684 | int retval = 0; |
471 | 685 | ||
472 | fw_flags2 = ene_hw_read_reg(dev, ENE_FW2); | 686 | fw_flags2 = ene_read_reg(dev, ENE_FW2); |
473 | cur_rx_pointer = !!(fw_flags2 & ENE_FW2_BUF_HIGH); | ||
474 | 687 | ||
475 | if (dev->hw_revision < ENE_HW_C) { | 688 | if (dev->hw_revision < ENE_HW_C) { |
476 | irq_status = ene_hw_read_reg(dev, ENEB_IRQ_STATUS); | 689 | irq_status = ene_read_reg(dev, ENEB_IRQ_STATUS); |
477 | 690 | ||
478 | if (!(irq_status & ENEB_IRQ_STATUS_IR)) | 691 | if (!(irq_status & ENEB_IRQ_STATUS_IR)) |
479 | return 0; | 692 | return 0; |
480 | 693 | ||
481 | ene_hw_write_reg(dev, ENEB_IRQ_STATUS, | 694 | ene_clear_reg_mask(dev, ENEB_IRQ_STATUS, ENEB_IRQ_STATUS_IR); |
482 | irq_status & ~ENEB_IRQ_STATUS_IR); | ||
483 | dev->rx_pointer = cur_rx_pointer; | ||
484 | return ENE_IRQ_RX; | 695 | return ENE_IRQ_RX; |
485 | } | 696 | } |
486 | 697 | ||
487 | irq_status = ene_hw_read_reg(dev, ENEC_IRQ); | 698 | irq_status = ene_read_reg(dev, ENE_IRQ); |
488 | 699 | if (!(irq_status & ENE_IRQ_STATUS)) | |
489 | if (!(irq_status & ENEC_IRQ_STATUS)) | ||
490 | return 0; | 700 | return 0; |
491 | 701 | ||
492 | /* original driver does that twice - a workaround ? */ | 702 | /* original driver does that twice - a workaround ? */ |
493 | ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS); | 703 | ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS); |
494 | ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS); | 704 | ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS); |
495 | 705 | ||
496 | /* clear unknown flag in F8F9 */ | 706 | /* check RX interrupt */ |
497 | if (fw_flags2 & ENE_FW2_IRQ_CLR) | 707 | if (fw_flags2 & ENE_FW2_RXIRQ) { |
498 | ene_hw_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_IRQ_CLR); | 708 | retval |= ENE_IRQ_RX; |
709 | ene_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_RXIRQ); | ||
710 | } | ||
499 | 711 | ||
500 | /* check if this is a TX interrupt */ | 712 | /* check TX interrupt */ |
501 | fw_flags1 = ene_hw_read_reg(dev, ENE_FW1); | 713 | fw_flags1 = ene_read_reg(dev, ENE_FW1); |
502 | if (fw_flags1 & ENE_FW1_TXIRQ) { | 714 | if (fw_flags1 & ENE_FW1_TXIRQ) { |
503 | ene_hw_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ); | 715 | ene_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ); |
504 | retval |= ENE_IRQ_TX; | 716 | retval |= ENE_IRQ_TX; |
505 | } | 717 | } |
506 | 718 | ||
507 | /* Check if this is RX interrupt */ | ||
508 | if (dev->rx_pointer != cur_rx_pointer) { | ||
509 | retval |= ENE_IRQ_RX; | ||
510 | dev->rx_pointer = cur_rx_pointer; | ||
511 | |||
512 | } else if (!(retval & ENE_IRQ_TX)) { | ||
513 | ene_dbg("RX: interrupt without change in RX pointer(%d)", | ||
514 | dev->rx_pointer); | ||
515 | retval |= ENE_IRQ_RX; | ||
516 | } | ||
517 | |||
518 | if ((retval & ENE_IRQ_RX) && (retval & ENE_IRQ_TX)) | ||
519 | ene_dbg("both RX and TX interrupt at same time"); | ||
520 | |||
521 | return retval; | 719 | return retval; |
522 | } | 720 | } |
523 | 721 | ||
524 | /* interrupt handler */ | 722 | /* interrupt handler */ |
525 | static irqreturn_t ene_isr(int irq, void *data) | 723 | static irqreturn_t ene_isr(int irq, void *data) |
526 | { | 724 | { |
527 | u16 hw_value; | 725 | u16 hw_value, reg; |
528 | int i, hw_sample; | 726 | int hw_sample, irq_status; |
529 | int pulse; | 727 | bool pulse; |
530 | int irq_status; | ||
531 | unsigned long flags; | 728 | unsigned long flags; |
532 | int carrier = 0; | ||
533 | irqreturn_t retval = IRQ_NONE; | 729 | irqreturn_t retval = IRQ_NONE; |
534 | struct ene_device *dev = (struct ene_device *)data; | 730 | struct ene_device *dev = (struct ene_device *)data; |
535 | struct ir_raw_event ev; | 731 | DEFINE_IR_RAW_EVENT(ev); |
536 | |||
537 | 732 | ||
538 | spin_lock_irqsave(&dev->hw_lock, flags); | 733 | spin_lock_irqsave(&dev->hw_lock, flags); |
734 | |||
735 | dbg_verbose("ISR called"); | ||
736 | ene_rx_read_hw_pointer(dev); | ||
539 | irq_status = ene_irq_status(dev); | 737 | irq_status = ene_irq_status(dev); |
540 | 738 | ||
541 | if (!irq_status) | 739 | if (!irq_status) |
@@ -544,9 +742,9 @@ static irqreturn_t ene_isr(int irq, void *data) | |||
544 | retval = IRQ_HANDLED; | 742 | retval = IRQ_HANDLED; |
545 | 743 | ||
546 | if (irq_status & ENE_IRQ_TX) { | 744 | if (irq_status & ENE_IRQ_TX) { |
547 | 745 | dbg_verbose("TX interrupt"); | |
548 | if (!dev->hw_learning_and_tx_capable) { | 746 | if (!dev->hw_learning_and_tx_capable) { |
549 | ene_dbg("TX interrupt on unsupported device!"); | 747 | dbg("TX interrupt on unsupported device!"); |
550 | goto unlock; | 748 | goto unlock; |
551 | } | 749 | } |
552 | ene_tx_sample(dev); | 750 | ene_tx_sample(dev); |
@@ -555,48 +753,57 @@ static irqreturn_t ene_isr(int irq, void *data) | |||
555 | if (!(irq_status & ENE_IRQ_RX)) | 753 | if (!(irq_status & ENE_IRQ_RX)) |
556 | goto unlock; | 754 | goto unlock; |
557 | 755 | ||
756 | dbg_verbose("RX interrupt"); | ||
558 | 757 | ||
559 | if (dev->carrier_detect_enabled || debug) | 758 | if (dev->hw_learning_and_tx_capable) |
560 | carrier = ene_rx_sense_carrier(dev); | 759 | ene_rx_sense_carrier(dev); |
561 | #if 0 | 760 | |
562 | /* TODO */ | 761 | /* On hardware that don't support extra buffer we need to trust |
563 | if (dev->carrier_detect_enabled && carrier) | 762 | the interrupt and not track the read pointer */ |
564 | ir_raw_event_report_frequency(dev->idev, carrier); | 763 | if (!dev->hw_extra_buffer) |
565 | #endif | 764 | dev->r_pointer = dev->w_pointer == 0 ? ENE_FW_PACKET_SIZE : 0; |
765 | |||
766 | while (1) { | ||
767 | |||
768 | reg = ene_rx_get_sample_reg(dev); | ||
769 | |||
770 | dbg_verbose("next sample to read at: %04x", reg); | ||
771 | if (!reg) | ||
772 | break; | ||
566 | 773 | ||
567 | for (i = 0; i < ENE_SAMPLES_SIZE; i++) { | 774 | hw_value = ene_read_reg(dev, reg); |
568 | hw_value = ene_hw_read_reg(dev, | ||
569 | ENE_SAMPLE_BUFFER + dev->rx_pointer * 4 + i); | ||
570 | 775 | ||
571 | if (dev->rx_fan_input_inuse) { | 776 | if (dev->rx_fan_input_inuse) { |
777 | |||
778 | int offset = ENE_FW_SMPL_BUF_FAN - ENE_FW_SAMPLE_BUFFER; | ||
779 | |||
572 | /* read high part of the sample */ | 780 | /* read high part of the sample */ |
573 | hw_value |= ene_hw_read_reg(dev, | 781 | hw_value |= ene_read_reg(dev, reg + offset) << 8; |
574 | ENE_SAMPLE_BUFFER_FAN + | 782 | pulse = hw_value & ENE_FW_SMPL_BUF_FAN_PLS; |
575 | dev->rx_pointer * 4 + i) << 8; | ||
576 | pulse = hw_value & ENE_FAN_SMPL_PULS_MSK; | ||
577 | 783 | ||
578 | /* clear space bit, and other unused bits */ | 784 | /* clear space bit, and other unused bits */ |
579 | hw_value &= ENE_FAN_VALUE_MASK; | 785 | hw_value &= ENE_FW_SMPL_BUF_FAN_MSK; |
580 | hw_sample = hw_value * ENE_SAMPLE_PERIOD_FAN; | 786 | hw_sample = hw_value * ENE_FW_SAMPLE_PERIOD_FAN; |
581 | 787 | ||
582 | } else { | 788 | } else { |
583 | pulse = !(hw_value & ENE_SAMPLE_SPC_MASK); | 789 | pulse = !(hw_value & ENE_FW_SAMPLE_SPACE); |
584 | hw_value &= ENE_SAMPLE_VALUE_MASK; | 790 | hw_value &= ~ENE_FW_SAMPLE_SPACE; |
585 | hw_sample = hw_value * sample_period; | 791 | hw_sample = hw_value * sample_period; |
586 | 792 | ||
587 | if (dev->rx_period_adjust) { | 793 | if (dev->rx_period_adjust) { |
588 | hw_sample *= (100 - dev->rx_period_adjust); | 794 | hw_sample *= 100; |
589 | hw_sample /= 100; | 795 | hw_sample /= (100 + dev->rx_period_adjust); |
590 | } | 796 | } |
591 | } | 797 | } |
592 | /* no more data */ | ||
593 | if (!(hw_value)) | ||
594 | break; | ||
595 | 798 | ||
596 | ene_dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); | 799 | if (!dev->hw_extra_buffer && !hw_sample) { |
800 | dev->r_pointer = dev->w_pointer; | ||
801 | continue; | ||
802 | } | ||
597 | 803 | ||
804 | dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); | ||
598 | 805 | ||
599 | ev.duration = hw_sample * 1000; | 806 | ev.duration = MS_TO_NS(hw_sample); |
600 | ev.pulse = pulse; | 807 | ev.pulse = pulse; |
601 | ir_raw_event_store_with_filter(dev->idev, &ev); | 808 | ir_raw_event_store_with_filter(dev->idev, &ev); |
602 | } | 809 | } |
@@ -608,19 +815,26 @@ unlock: | |||
608 | } | 815 | } |
609 | 816 | ||
610 | /* Initialize default settings */ | 817 | /* Initialize default settings */ |
611 | static void ene_setup_settings(struct ene_device *dev) | 818 | static void ene_setup_default_settings(struct ene_device *dev) |
612 | { | 819 | { |
613 | dev->tx_period = 32; | 820 | dev->tx_period = 32; |
614 | dev->tx_duty_cycle = 25; /*%*/ | 821 | dev->tx_duty_cycle = 50; /*%*/ |
615 | dev->transmitter_mask = 3; | 822 | dev->transmitter_mask = 0x03; |
823 | dev->learning_mode_enabled = learning_mode_force; | ||
616 | 824 | ||
617 | /* Force learning mode if (input == 2), otherwise | 825 | /* Set reasonable default timeout */ |
618 | let user set it with LIRC_SET_REC_CARRIER */ | 826 | dev->props->timeout = MS_TO_NS(150000); |
619 | dev->learning_enabled = | 827 | } |
620 | (input == 2 && dev->hw_learning_and_tx_capable); | ||
621 | 828 | ||
622 | dev->rx_pointer = -1; | 829 | /* Upload all hardware settings at once. Used at load and resume time */ |
830 | static void ene_setup_hw_settings(struct ene_device *dev) | ||
831 | { | ||
832 | if (dev->hw_learning_and_tx_capable) { | ||
833 | ene_tx_set_carrier(dev); | ||
834 | ene_tx_set_transmitters(dev); | ||
835 | } | ||
623 | 836 | ||
837 | ene_rx_setup(dev); | ||
624 | } | 838 | } |
625 | 839 | ||
626 | /* outside interface: called on first open*/ | 840 | /* outside interface: called on first open*/ |
@@ -630,8 +844,6 @@ static int ene_open(void *data) | |||
630 | unsigned long flags; | 844 | unsigned long flags; |
631 | 845 | ||
632 | spin_lock_irqsave(&dev->hw_lock, flags); | 846 | spin_lock_irqsave(&dev->hw_lock, flags); |
633 | dev->in_use = 1; | ||
634 | ene_setup_settings(dev); | ||
635 | ene_rx_enable(dev); | 847 | ene_rx_enable(dev); |
636 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 848 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
637 | return 0; | 849 | return 0; |
@@ -645,7 +857,6 @@ static void ene_close(void *data) | |||
645 | spin_lock_irqsave(&dev->hw_lock, flags); | 857 | spin_lock_irqsave(&dev->hw_lock, flags); |
646 | 858 | ||
647 | ene_rx_disable(dev); | 859 | ene_rx_disable(dev); |
648 | dev->in_use = 0; | ||
649 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 860 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
650 | } | 861 | } |
651 | 862 | ||
@@ -653,19 +864,17 @@ static void ene_close(void *data) | |||
653 | static int ene_set_tx_mask(void *data, u32 tx_mask) | 864 | static int ene_set_tx_mask(void *data, u32 tx_mask) |
654 | { | 865 | { |
655 | struct ene_device *dev = (struct ene_device *)data; | 866 | struct ene_device *dev = (struct ene_device *)data; |
656 | unsigned long flags; | 867 | dbg("TX: attempt to set transmitter mask %02x", tx_mask); |
657 | ene_dbg("TX: attempt to set transmitter mask %02x", tx_mask); | ||
658 | 868 | ||
659 | /* invalid txmask */ | 869 | /* invalid txmask */ |
660 | if (!tx_mask || tx_mask & ~0x3) { | 870 | if (!tx_mask || tx_mask & ~0x03) { |
661 | ene_dbg("TX: invalid mask"); | 871 | dbg("TX: invalid mask"); |
662 | /* return count of transmitters */ | 872 | /* return count of transmitters */ |
663 | return 2; | 873 | return 2; |
664 | } | 874 | } |
665 | 875 | ||
666 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
667 | dev->transmitter_mask = tx_mask; | 876 | dev->transmitter_mask = tx_mask; |
668 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 877 | ene_tx_set_transmitters(dev); |
669 | return 0; | 878 | return 0; |
670 | } | 879 | } |
671 | 880 | ||
@@ -673,66 +882,76 @@ static int ene_set_tx_mask(void *data, u32 tx_mask) | |||
673 | static int ene_set_tx_carrier(void *data, u32 carrier) | 882 | static int ene_set_tx_carrier(void *data, u32 carrier) |
674 | { | 883 | { |
675 | struct ene_device *dev = (struct ene_device *)data; | 884 | struct ene_device *dev = (struct ene_device *)data; |
676 | unsigned long flags; | 885 | u32 period = 2000000 / carrier; |
677 | u32 period = 1000000 / carrier; /* (1 / freq) (* # usec in 1 sec) */ | ||
678 | |||
679 | ene_dbg("TX: attempt to set tx carrier to %d kHz", carrier); | ||
680 | 886 | ||
681 | if (period && (period > ENE_TX_PERIOD_MAX || | 887 | dbg("TX: attempt to set tx carrier to %d kHz", carrier); |
682 | period < ENE_TX_PERIOD_MIN)) { | ||
683 | 888 | ||
684 | ene_dbg("TX: out of range %d-%d carrier, " | 889 | if (period && (period > ENE_CIRMOD_PRD_MAX || |
685 | "falling back to 32 kHz", | 890 | period < ENE_CIRMOD_PRD_MIN)) { |
686 | 1000 / ENE_TX_PERIOD_MIN, | ||
687 | 1000 / ENE_TX_PERIOD_MAX); | ||
688 | 891 | ||
689 | period = 32; /* this is just a coincidence!!! */ | 892 | dbg("TX: out of range %d-%d kHz carrier", |
893 | 2000 / ENE_CIRMOD_PRD_MIN, 2000 / ENE_CIRMOD_PRD_MAX); | ||
894 | return -1; | ||
690 | } | 895 | } |
691 | ene_dbg("TX: set carrier to %d kHz", carrier); | ||
692 | 896 | ||
693 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
694 | dev->tx_period = period; | 897 | dev->tx_period = period; |
695 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 898 | ene_tx_set_carrier(dev); |
696 | return 0; | 899 | return 0; |
697 | } | 900 | } |
698 | 901 | ||
902 | /*outside interface : set tx duty cycle */ | ||
903 | static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle) | ||
904 | { | ||
905 | struct ene_device *dev = (struct ene_device *)data; | ||
906 | dbg("TX: setting duty cycle to %d%%", duty_cycle); | ||
907 | dev->tx_duty_cycle = duty_cycle; | ||
908 | ene_tx_set_carrier(dev); | ||
909 | return 0; | ||
910 | } | ||
699 | 911 | ||
700 | /* outside interface: enable learning mode */ | 912 | /* outside interface: enable learning mode */ |
701 | static int ene_set_learning_mode(void *data, int enable) | 913 | static int ene_set_learning_mode(void *data, int enable) |
702 | { | 914 | { |
703 | struct ene_device *dev = (struct ene_device *)data; | 915 | struct ene_device *dev = (struct ene_device *)data; |
704 | unsigned long flags; | 916 | unsigned long flags; |
705 | if (enable == dev->learning_enabled) | 917 | if (enable == dev->learning_mode_enabled) |
706 | return 0; | 918 | return 0; |
707 | 919 | ||
708 | spin_lock_irqsave(&dev->hw_lock, flags); | 920 | spin_lock_irqsave(&dev->hw_lock, flags); |
709 | dev->learning_enabled = enable; | 921 | dev->learning_mode_enabled = enable; |
710 | ene_rx_set_inputs(dev); | 922 | ene_rx_disable(dev); |
923 | ene_rx_setup(dev); | ||
924 | ene_rx_enable(dev); | ||
711 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 925 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
712 | return 0; | 926 | return 0; |
713 | } | 927 | } |
714 | 928 | ||
715 | /* outside interface: set rec carrier */ | 929 | static int ene_set_carrier_report(void *data, int enable) |
716 | static int ene_set_rec_carrier(void *data, u32 min, u32 max) | ||
717 | { | 930 | { |
718 | struct ene_device *dev = (struct ene_device *)data; | 931 | struct ene_device *dev = (struct ene_device *)data; |
719 | ene_set_learning_mode(dev, | 932 | unsigned long flags; |
720 | max > ENE_NORMAL_RX_HI || min < ENE_NORMAL_RX_LOW); | 933 | |
934 | if (enable == dev->carrier_detect_enabled) | ||
935 | return 0; | ||
936 | |||
937 | spin_lock_irqsave(&dev->hw_lock, flags); | ||
938 | dev->carrier_detect_enabled = enable; | ||
939 | ene_rx_disable(dev); | ||
940 | ene_rx_setup(dev); | ||
941 | ene_rx_enable(dev); | ||
942 | spin_unlock_irqrestore(&dev->hw_lock, flags); | ||
721 | return 0; | 943 | return 0; |
722 | } | 944 | } |
723 | 945 | ||
724 | /* outside interface: enable or disable idle mode */ | 946 | /* outside interface: enable or disable idle mode */ |
725 | static void ene_rx_set_idle(void *data, int idle) | 947 | static void ene_set_idle(void *data, bool idle) |
726 | { | 948 | { |
727 | struct ene_device *dev = (struct ene_device *)data; | 949 | if (idle) { |
728 | ene_dbg("%sabling idle mode", idle ? "en" : "dis"); | 950 | ene_rx_reset((struct ene_device *)data); |
729 | 951 | dbg("RX: end of data"); | |
730 | ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD, | 952 | } |
731 | (enable_idle && idle) ? 0 : ENE_CIR_SAMPLE_OVERFLOW, | ||
732 | ENE_CIR_SAMPLE_OVERFLOW); | ||
733 | } | 953 | } |
734 | 954 | ||
735 | |||
736 | /* outside interface: transmit */ | 955 | /* outside interface: transmit */ |
737 | static int ene_transmit(void *data, int *buf, u32 n) | 956 | static int ene_transmit(void *data, int *buf, u32 n) |
738 | { | 957 | { |
@@ -747,12 +966,11 @@ static int ene_transmit(void *data, int *buf, u32 n) | |||
747 | dev->tx_sample = 0; | 966 | dev->tx_sample = 0; |
748 | dev->tx_sample_pulse = 0; | 967 | dev->tx_sample_pulse = 0; |
749 | 968 | ||
750 | ene_dbg("TX: %d samples", dev->tx_len); | 969 | dbg("TX: %d samples", dev->tx_len); |
751 | 970 | ||
752 | spin_lock_irqsave(&dev->hw_lock, flags); | 971 | spin_lock_irqsave(&dev->hw_lock, flags); |
753 | 972 | ||
754 | ene_tx_hw_set_transmiter_mask(dev); | 973 | ene_tx_enable(dev); |
755 | ene_tx_prepare(dev); | ||
756 | 974 | ||
757 | /* Transmit first two samples */ | 975 | /* Transmit first two samples */ |
758 | ene_tx_sample(dev); | 976 | ene_tx_sample(dev); |
@@ -761,16 +979,15 @@ static int ene_transmit(void *data, int *buf, u32 n) | |||
761 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 979 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
762 | 980 | ||
763 | if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) { | 981 | if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) { |
764 | ene_dbg("TX: timeout"); | 982 | dbg("TX: timeout"); |
765 | spin_lock_irqsave(&dev->hw_lock, flags); | 983 | spin_lock_irqsave(&dev->hw_lock, flags); |
766 | ene_tx_complete(dev); | 984 | ene_tx_disable(dev); |
767 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 985 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
768 | } else | 986 | } else |
769 | ene_dbg("TX: done"); | 987 | dbg("TX: done"); |
770 | return n; | 988 | return n; |
771 | } | 989 | } |
772 | 990 | ||
773 | |||
774 | /* probe entry */ | 991 | /* probe entry */ |
775 | static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) | 992 | static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) |
776 | { | 993 | { |
@@ -785,121 +1002,103 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) | |||
785 | dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); | 1002 | dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); |
786 | 1003 | ||
787 | if (!input_dev || !ir_props || !dev) | 1004 | if (!input_dev || !ir_props || !dev) |
788 | goto error; | 1005 | goto error1; |
789 | 1006 | ||
790 | /* validate resources */ | 1007 | /* validate resources */ |
791 | error = -ENODEV; | 1008 | error = -ENODEV; |
792 | 1009 | ||
793 | if (!pnp_port_valid(pnp_dev, 0) || | 1010 | if (!pnp_port_valid(pnp_dev, 0) || |
794 | pnp_port_len(pnp_dev, 0) < ENE_MAX_IO) | 1011 | pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE) |
795 | goto error; | 1012 | goto error; |
796 | 1013 | ||
797 | if (!pnp_irq_valid(pnp_dev, 0)) | 1014 | if (!pnp_irq_valid(pnp_dev, 0)) |
798 | goto error; | 1015 | goto error; |
799 | 1016 | ||
800 | dev->hw_io = pnp_port_start(pnp_dev, 0); | ||
801 | dev->irq = pnp_irq(pnp_dev, 0); | ||
802 | spin_lock_init(&dev->hw_lock); | 1017 | spin_lock_init(&dev->hw_lock); |
803 | 1018 | ||
804 | /* claim the resources */ | 1019 | /* claim the resources */ |
805 | error = -EBUSY; | 1020 | error = -EBUSY; |
806 | if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME)) | 1021 | dev->hw_io = pnp_port_start(pnp_dev, 0); |
1022 | if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { | ||
1023 | dev->hw_io = -1; | ||
1024 | dev->irq = -1; | ||
807 | goto error; | 1025 | goto error; |
1026 | } | ||
808 | 1027 | ||
1028 | dev->irq = pnp_irq(pnp_dev, 0); | ||
809 | if (request_irq(dev->irq, ene_isr, | 1029 | if (request_irq(dev->irq, ene_isr, |
810 | IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) | 1030 | IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { |
1031 | dev->irq = -1; | ||
811 | goto error; | 1032 | goto error; |
1033 | } | ||
812 | 1034 | ||
813 | pnp_set_drvdata(pnp_dev, dev); | 1035 | pnp_set_drvdata(pnp_dev, dev); |
814 | dev->pnp_dev = pnp_dev; | 1036 | dev->pnp_dev = pnp_dev; |
815 | 1037 | ||
1038 | /* don't allow too short/long sample periods */ | ||
1039 | if (sample_period < 5 || sample_period > 0x7F) | ||
1040 | sample_period = ENE_DEFAULT_SAMPLE_PERIOD; | ||
1041 | |||
816 | /* detect hardware version and features */ | 1042 | /* detect hardware version and features */ |
817 | error = ene_hw_detect(dev); | 1043 | error = ene_hw_detect(dev); |
818 | if (error) | 1044 | if (error) |
819 | goto error; | 1045 | goto error; |
820 | 1046 | ||
821 | ene_setup_settings(dev); | ||
822 | |||
823 | if (!dev->hw_learning_and_tx_capable && txsim) { | 1047 | if (!dev->hw_learning_and_tx_capable && txsim) { |
824 | dev->hw_learning_and_tx_capable = 1; | 1048 | dev->hw_learning_and_tx_capable = true; |
825 | setup_timer(&dev->tx_sim_timer, ene_tx_irqsim, | 1049 | setup_timer(&dev->tx_sim_timer, ene_tx_irqsim, |
826 | (long unsigned int)dev); | 1050 | (long unsigned int)dev); |
827 | ene_printk(KERN_WARNING, | 1051 | ene_warn("Simulation of TX activated"); |
828 | "Simulation of TX activated\n"); | ||
829 | } | 1052 | } |
830 | 1053 | ||
1054 | if (!dev->hw_learning_and_tx_capable) | ||
1055 | learning_mode_force = false; | ||
1056 | |||
831 | ir_props->driver_type = RC_DRIVER_IR_RAW; | 1057 | ir_props->driver_type = RC_DRIVER_IR_RAW; |
832 | ir_props->allowed_protos = IR_TYPE_ALL; | 1058 | ir_props->allowed_protos = IR_TYPE_ALL; |
833 | ir_props->priv = dev; | 1059 | ir_props->priv = dev; |
834 | ir_props->open = ene_open; | 1060 | ir_props->open = ene_open; |
835 | ir_props->close = ene_close; | 1061 | ir_props->close = ene_close; |
836 | ir_props->min_timeout = ENE_MINGAP * 1000; | 1062 | ir_props->s_idle = ene_set_idle; |
837 | ir_props->max_timeout = ENE_MAXGAP * 1000; | ||
838 | ir_props->timeout = ENE_MAXGAP * 1000; | ||
839 | |||
840 | if (dev->hw_revision == ENE_HW_B) | ||
841 | ir_props->s_idle = ene_rx_set_idle; | ||
842 | |||
843 | 1063 | ||
844 | dev->props = ir_props; | 1064 | dev->props = ir_props; |
845 | dev->idev = input_dev; | 1065 | dev->idev = input_dev; |
846 | 1066 | ||
847 | /* don't allow too short/long sample periods */ | ||
848 | if (sample_period < 5 || sample_period > 0x7F) | ||
849 | sample_period = -1; | ||
850 | |||
851 | /* choose default sample period */ | ||
852 | if (sample_period == -1) { | ||
853 | |||
854 | sample_period = 50; | ||
855 | |||
856 | /* on revB, hardware idle mode eats first sample | ||
857 | if we set too low sample period */ | ||
858 | if (dev->hw_revision == ENE_HW_B && enable_idle) | ||
859 | sample_period = 75; | ||
860 | } | ||
861 | |||
862 | ir_props->rx_resolution = sample_period * 1000; | ||
863 | |||
864 | if (dev->hw_learning_and_tx_capable) { | 1067 | if (dev->hw_learning_and_tx_capable) { |
865 | |||
866 | ir_props->s_learning_mode = ene_set_learning_mode; | 1068 | ir_props->s_learning_mode = ene_set_learning_mode; |
867 | |||
868 | if (input == 0) | ||
869 | ir_props->s_rx_carrier_range = ene_set_rec_carrier; | ||
870 | |||
871 | init_completion(&dev->tx_complete); | 1069 | init_completion(&dev->tx_complete); |
872 | ir_props->tx_ir = ene_transmit; | 1070 | ir_props->tx_ir = ene_transmit; |
873 | ir_props->s_tx_mask = ene_set_tx_mask; | 1071 | ir_props->s_tx_mask = ene_set_tx_mask; |
874 | ir_props->s_tx_carrier = ene_set_tx_carrier; | 1072 | ir_props->s_tx_carrier = ene_set_tx_carrier; |
875 | ir_props->tx_resolution = ENE_TX_SMPL_PERIOD * 1000; | 1073 | ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle; |
876 | /* ir_props->s_carrier_report = ene_set_carrier_report; */ | 1074 | ir_props->s_carrier_report = ene_set_carrier_report; |
877 | } | 1075 | } |
878 | 1076 | ||
1077 | ene_rx_setup_hw_buffer(dev); | ||
1078 | ene_setup_default_settings(dev); | ||
1079 | ene_setup_hw_settings(dev); | ||
879 | 1080 | ||
880 | device_set_wakeup_capable(&pnp_dev->dev, 1); | 1081 | device_set_wakeup_capable(&pnp_dev->dev, true); |
881 | device_set_wakeup_enable(&pnp_dev->dev, 1); | 1082 | device_set_wakeup_enable(&pnp_dev->dev, true); |
882 | 1083 | ||
883 | if (dev->hw_learning_and_tx_capable) | 1084 | if (dev->hw_learning_and_tx_capable) |
884 | input_dev->name = "ENE eHome Infrared Remote Transceiver"; | 1085 | input_dev->name = "ENE eHome Infrared Remote Transceiver"; |
885 | else | 1086 | else |
886 | input_dev->name = "ENE eHome Infrared Remote Receiver"; | 1087 | input_dev->name = "ENE eHome Infrared Remote Receiver"; |
887 | 1088 | ||
888 | |||
889 | error = -ENODEV; | 1089 | error = -ENODEV; |
890 | if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props, | 1090 | if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props, |
891 | ENE_DRIVER_NAME)) | 1091 | ENE_DRIVER_NAME)) |
892 | goto error; | 1092 | goto error; |
893 | 1093 | ||
894 | 1094 | ene_notice("driver has been succesfully loaded"); | |
895 | ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n"); | ||
896 | return 0; | 1095 | return 0; |
897 | error: | 1096 | error: |
898 | if (dev->irq) | 1097 | if (dev && dev->irq >= 0) |
899 | free_irq(dev->irq, dev); | 1098 | free_irq(dev->irq, dev); |
900 | if (dev->hw_io) | 1099 | if (dev && dev->hw_io >= 0) |
901 | release_region(dev->hw_io, ENE_MAX_IO); | 1100 | release_region(dev->hw_io, ENE_IO_SIZE); |
902 | 1101 | error1: | |
903 | input_free_device(input_dev); | 1102 | input_free_device(input_dev); |
904 | kfree(ir_props); | 1103 | kfree(ir_props); |
905 | kfree(dev); | 1104 | kfree(dev); |
@@ -914,10 +1113,11 @@ static void ene_remove(struct pnp_dev *pnp_dev) | |||
914 | 1113 | ||
915 | spin_lock_irqsave(&dev->hw_lock, flags); | 1114 | spin_lock_irqsave(&dev->hw_lock, flags); |
916 | ene_rx_disable(dev); | 1115 | ene_rx_disable(dev); |
1116 | ene_rx_restore_hw_buffer(dev); | ||
917 | spin_unlock_irqrestore(&dev->hw_lock, flags); | 1117 | spin_unlock_irqrestore(&dev->hw_lock, flags); |
918 | 1118 | ||
919 | free_irq(dev->irq, dev); | 1119 | free_irq(dev->irq, dev); |
920 | release_region(dev->hw_io, ENE_MAX_IO); | 1120 | release_region(dev->hw_io, ENE_IO_SIZE); |
921 | ir_input_unregister(dev->idev); | 1121 | ir_input_unregister(dev->idev); |
922 | kfree(dev->props); | 1122 | kfree(dev->props); |
923 | kfree(dev); | 1123 | kfree(dev); |
@@ -927,28 +1127,29 @@ static void ene_remove(struct pnp_dev *pnp_dev) | |||
927 | static void ene_enable_wake(struct ene_device *dev, int enable) | 1127 | static void ene_enable_wake(struct ene_device *dev, int enable) |
928 | { | 1128 | { |
929 | enable = enable && device_may_wakeup(&dev->pnp_dev->dev); | 1129 | enable = enable && device_may_wakeup(&dev->pnp_dev->dev); |
930 | 1130 | dbg("wake on IR %s", enable ? "enabled" : "disabled"); | |
931 | ene_dbg("wake on IR %s", enable ? "enabled" : "disabled"); | 1131 | ene_set_clear_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, enable); |
932 | |||
933 | ene_hw_write_reg_mask(dev, ENE_FW1, enable ? | ||
934 | ENE_FW1_WAKE : 0, ENE_FW1_WAKE); | ||
935 | } | 1132 | } |
936 | 1133 | ||
937 | #ifdef CONFIG_PM | 1134 | #ifdef CONFIG_PM |
938 | static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state) | 1135 | static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state) |
939 | { | 1136 | { |
940 | struct ene_device *dev = pnp_get_drvdata(pnp_dev); | 1137 | struct ene_device *dev = pnp_get_drvdata(pnp_dev); |
941 | ene_enable_wake(dev, 1); | 1138 | ene_enable_wake(dev, true); |
1139 | |||
1140 | /* TODO: add support for wake pattern */ | ||
942 | return 0; | 1141 | return 0; |
943 | } | 1142 | } |
944 | 1143 | ||
945 | static int ene_resume(struct pnp_dev *pnp_dev) | 1144 | static int ene_resume(struct pnp_dev *pnp_dev) |
946 | { | 1145 | { |
947 | struct ene_device *dev = pnp_get_drvdata(pnp_dev); | 1146 | struct ene_device *dev = pnp_get_drvdata(pnp_dev); |
948 | if (dev->in_use) | 1147 | ene_setup_hw_settings(dev); |
1148 | |||
1149 | if (dev->rx_enabled) | ||
949 | ene_rx_enable(dev); | 1150 | ene_rx_enable(dev); |
950 | 1151 | ||
951 | ene_enable_wake(dev, 0); | 1152 | ene_enable_wake(dev, false); |
952 | return 0; | 1153 | return 0; |
953 | } | 1154 | } |
954 | #endif | 1155 | #endif |
@@ -956,7 +1157,7 @@ static int ene_resume(struct pnp_dev *pnp_dev) | |||
956 | static void ene_shutdown(struct pnp_dev *pnp_dev) | 1157 | static void ene_shutdown(struct pnp_dev *pnp_dev) |
957 | { | 1158 | { |
958 | struct ene_device *dev = pnp_get_drvdata(pnp_dev); | 1159 | struct ene_device *dev = pnp_get_drvdata(pnp_dev); |
959 | ene_enable_wake(dev, 1); | 1160 | ene_enable_wake(dev, true); |
960 | } | 1161 | } |
961 | 1162 | ||
962 | static const struct pnp_device_id ene_ids[] = { | 1163 | static const struct pnp_device_id ene_ids[] = { |
@@ -994,18 +1195,11 @@ static void ene_exit(void) | |||
994 | module_param(sample_period, int, S_IRUGO); | 1195 | module_param(sample_period, int, S_IRUGO); |
995 | MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)"); | 1196 | MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)"); |
996 | 1197 | ||
997 | module_param(enable_idle, bool, S_IRUGO | S_IWUSR); | 1198 | module_param(learning_mode_force, bool, S_IRUGO); |
998 | MODULE_PARM_DESC(enable_idle, | 1199 | MODULE_PARM_DESC(learning_mode_force, "Enable learning mode by default"); |
999 | "Enables turning off signal sampling after long inactivity time; " | ||
1000 | "if disabled might help detecting input signal (default: enabled)" | ||
1001 | " (KB3926B only)"); | ||
1002 | |||
1003 | module_param(input, bool, S_IRUGO); | ||
1004 | MODULE_PARM_DESC(input, "select which input to use " | ||
1005 | "0 - auto, 1 - standard, 2 - wideband(KB3926C+)"); | ||
1006 | 1200 | ||
1007 | module_param(debug, int, S_IRUGO | S_IWUSR); | 1201 | module_param(debug, int, S_IRUGO | S_IWUSR); |
1008 | MODULE_PARM_DESC(debug, "Enable debug (debug=2 verbose debug output)"); | 1202 | MODULE_PARM_DESC(debug, "Debug level"); |
1009 | 1203 | ||
1010 | module_param(txsim, bool, S_IRUGO); | 1204 | module_param(txsim, bool, S_IRUGO); |
1011 | MODULE_PARM_DESC(txsim, | 1205 | MODULE_PARM_DESC(txsim, |
@@ -1013,8 +1207,8 @@ MODULE_PARM_DESC(txsim, | |||
1013 | 1207 | ||
1014 | MODULE_DEVICE_TABLE(pnp, ene_ids); | 1208 | MODULE_DEVICE_TABLE(pnp, ene_ids); |
1015 | MODULE_DESCRIPTION | 1209 | MODULE_DESCRIPTION |
1016 | ("Infrared input driver for KB3926B/KB3926C/KB3926D " | 1210 | ("Infrared input driver for KB3926B/C/D/E/F " |
1017 | "(aka ENE0100/ENE0200/ENE0201) CIR port"); | 1211 | "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port"); |
1018 | 1212 | ||
1019 | MODULE_AUTHOR("Maxim Levitsky"); | 1213 | MODULE_AUTHOR("Maxim Levitsky"); |
1020 | MODULE_LICENSE("GPL"); | 1214 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/IR/ene_ir.h b/drivers/media/IR/ene_ir.h index 54c76af0d03..f5870667a43 100644 --- a/drivers/media/IR/ene_ir.h +++ b/drivers/media/IR/ene_ir.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * driver for ENE KB3926 B/C/D CIR (also known as ENE0XXX) | 2 | * driver for ENE KB3926 B/C/D/E/F CIR (also known as ENE0XXX) |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> | 4 | * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> |
5 | * | 5 | * |
@@ -26,43 +26,50 @@ | |||
26 | #define ENE_ADDR_HI 1 /* hi byte of register address */ | 26 | #define ENE_ADDR_HI 1 /* hi byte of register address */ |
27 | #define ENE_ADDR_LO 2 /* low byte of register address */ | 27 | #define ENE_ADDR_LO 2 /* low byte of register address */ |
28 | #define ENE_IO 3 /* read/write window */ | 28 | #define ENE_IO 3 /* read/write window */ |
29 | #define ENE_MAX_IO 4 | 29 | #define ENE_IO_SIZE 4 |
30 | 30 | ||
31 | /* 8 bytes of samples, divided in 2 halfs*/ | 31 | /* 8 bytes of samples, divided in 2 packets*/ |
32 | #define ENE_SAMPLE_BUFFER 0xF8F0 /* regular sample buffer */ | 32 | #define ENE_FW_SAMPLE_BUFFER 0xF8F0 /* sample buffer */ |
33 | #define ENE_SAMPLE_SPC_MASK 0x80 /* sample is space */ | 33 | #define ENE_FW_SAMPLE_SPACE 0x80 /* sample is space */ |
34 | #define ENE_SAMPLE_VALUE_MASK 0x7F | 34 | #define ENE_FW_PACKET_SIZE 4 |
35 | #define ENE_SAMPLE_OVERFLOW 0x7F | 35 | |
36 | #define ENE_SAMPLES_SIZE 4 | 36 | /* first firmware flag register */ |
37 | 37 | #define ENE_FW1 0xF8F8 /* flagr */ | |
38 | /* fan input sample buffer */ | ||
39 | #define ENE_SAMPLE_BUFFER_FAN 0xF8FB /* this buffer holds high byte of */ | ||
40 | /* each sample of normal buffer */ | ||
41 | #define ENE_FAN_SMPL_PULS_MSK 0x8000 /* this bit of combined sample */ | ||
42 | /* if set, says that sample is pulse */ | ||
43 | #define ENE_FAN_VALUE_MASK 0x0FFF /* mask for valid bits of the value */ | ||
44 | |||
45 | /* first firmware register */ | ||
46 | #define ENE_FW1 0xF8F8 | ||
47 | #define ENE_FW1_ENABLE 0x01 /* enable fw processing */ | 38 | #define ENE_FW1_ENABLE 0x01 /* enable fw processing */ |
48 | #define ENE_FW1_TXIRQ 0x02 /* TX interrupt pending */ | 39 | #define ENE_FW1_TXIRQ 0x02 /* TX interrupt pending */ |
40 | #define ENE_FW1_HAS_EXTRA_BUF 0x04 /* fw uses extra buffer*/ | ||
41 | #define ENE_FW1_EXTRA_BUF_HND 0x08 /* extra buffer handshake bit*/ | ||
42 | #define ENE_FW1_LED_ON 0x10 /* turn on a led */ | ||
43 | |||
44 | #define ENE_FW1_WPATTERN 0x20 /* enable wake pattern */ | ||
49 | #define ENE_FW1_WAKE 0x40 /* enable wake from S3 */ | 45 | #define ENE_FW1_WAKE 0x40 /* enable wake from S3 */ |
50 | #define ENE_FW1_IRQ 0x80 /* enable interrupt */ | 46 | #define ENE_FW1_IRQ 0x80 /* enable interrupt */ |
51 | 47 | ||
52 | /* second firmware register */ | 48 | /* second firmware flag register */ |
53 | #define ENE_FW2 0xF8F9 | 49 | #define ENE_FW2 0xF8F9 /* flagw */ |
54 | #define ENE_FW2_BUF_HIGH 0x01 /* which half of the buffer to read */ | 50 | #define ENE_FW2_BUF_WPTR 0x01 /* which half of the buffer to read */ |
55 | #define ENE_FW2_IRQ_CLR 0x04 /* clear this on IRQ */ | 51 | #define ENE_FW2_RXIRQ 0x04 /* RX IRQ pending*/ |
56 | #define ENE_FW2_GP40_AS_LEARN 0x08 /* normal input is used as */ | 52 | #define ENE_FW2_GP0A 0x08 /* Use GPIO0A for demodulated input */ |
57 | /* learning input */ | 53 | #define ENE_FW2_EMMITER1_CONN 0x10 /* TX emmiter 1 connected */ |
58 | #define ENE_FW2_FAN_AS_NRML_IN 0x40 /* fan is used as normal input */ | 54 | #define ENE_FW2_EMMITER2_CONN 0x20 /* TX emmiter 2 connected */ |
55 | |||
56 | #define ENE_FW2_FAN_INPUT 0x40 /* fan input used for demodulated data*/ | ||
59 | #define ENE_FW2_LEARNING 0x80 /* hardware supports learning and TX */ | 57 | #define ENE_FW2_LEARNING 0x80 /* hardware supports learning and TX */ |
60 | 58 | ||
59 | /* firmware RX pointer for new style buffer */ | ||
60 | #define ENE_FW_RX_POINTER 0xF8FA | ||
61 | |||
62 | /* high parts of samples for fan input (8 samples)*/ | ||
63 | #define ENE_FW_SMPL_BUF_FAN 0xF8FB | ||
64 | #define ENE_FW_SMPL_BUF_FAN_PLS 0x8000 /* combined sample is pulse */ | ||
65 | #define ENE_FW_SMPL_BUF_FAN_MSK 0x0FFF /* combined sample maximum value */ | ||
66 | #define ENE_FW_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */ | ||
67 | |||
61 | /* transmitter ports */ | 68 | /* transmitter ports */ |
62 | #define ENE_TX_PORT2 0xFC01 /* this enables one or both */ | 69 | #define ENE_GPIOFS1 0xFC01 |
63 | #define ENE_TX_PORT2_EN 0x20 /* TX ports */ | 70 | #define ENE_GPIOFS1_GPIO0D 0x20 /* enable tx output on GPIO0D */ |
64 | #define ENE_TX_PORT1 0xFC08 | 71 | #define ENE_GPIOFS8 0xFC08 |
65 | #define ENE_TX_PORT1_EN 0x02 | 72 | #define ENE_GPIOFS8_GPIO41 0x02 /* enable tx output on GPIO40 */ |
66 | 73 | ||
67 | /* IRQ registers block (for revision B) */ | 74 | /* IRQ registers block (for revision B) */ |
68 | #define ENEB_IRQ 0xFD09 /* IRQ number */ | 75 | #define ENEB_IRQ 0xFD09 /* IRQ number */ |
@@ -70,97 +77,99 @@ | |||
70 | #define ENEB_IRQ_STATUS 0xFD80 /* irq status */ | 77 | #define ENEB_IRQ_STATUS 0xFD80 /* irq status */ |
71 | #define ENEB_IRQ_STATUS_IR 0x20 /* IR irq */ | 78 | #define ENEB_IRQ_STATUS_IR 0x20 /* IR irq */ |
72 | 79 | ||
73 | /* fan as input settings - only if learning capable */ | 80 | /* fan as input settings */ |
74 | #define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */ | 81 | #define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */ |
75 | #define ENE_FAN_AS_IN1_EN 0xCD | 82 | #define ENE_FAN_AS_IN1_EN 0xCD |
76 | #define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */ | 83 | #define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */ |
77 | #define ENE_FAN_AS_IN2_EN 0x03 | 84 | #define ENE_FAN_AS_IN2_EN 0x03 |
78 | #define ENE_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */ | ||
79 | 85 | ||
80 | /* IRQ registers block (for revision C,D) */ | 86 | /* IRQ registers block (for revision C,D) */ |
81 | #define ENEC_IRQ 0xFE9B /* new irq settings register */ | 87 | #define ENE_IRQ 0xFE9B /* new irq settings register */ |
82 | #define ENEC_IRQ_MASK 0x0F /* irq number mask */ | 88 | #define ENE_IRQ_MASK 0x0F /* irq number mask */ |
83 | #define ENEC_IRQ_UNK_EN 0x10 /* always enabled */ | 89 | #define ENE_IRQ_UNK_EN 0x10 /* always enabled */ |
84 | #define ENEC_IRQ_STATUS 0x20 /* irq status and ACK */ | 90 | #define ENE_IRQ_STATUS 0x20 /* irq status and ACK */ |
85 | 91 | ||
86 | /* CIR block settings */ | 92 | /* CIR Config register #1 */ |
87 | #define ENE_CIR_CONF1 0xFEC0 | 93 | #define ENE_CIRCFG 0xFEC0 |
88 | #define ENE_CIR_CONF1_TX_CLEAR 0x01 /* clear that on revC */ | 94 | #define ENE_CIRCFG_RX_EN 0x01 /* RX enable */ |
89 | /* while transmitting */ | 95 | #define ENE_CIRCFG_RX_IRQ 0x02 /* Enable hardware interrupt */ |
90 | #define ENE_CIR_CONF1_RX_ON 0x07 /* normal receiver enabled */ | 96 | #define ENE_CIRCFG_REV_POL 0x04 /* Input polarity reversed */ |
91 | #define ENE_CIR_CONF1_LEARN1 0x08 /* enabled on learning mode */ | 97 | #define ENE_CIRCFG_CARR_DEMOD 0x08 /* Enable carrier demodulator */ |
92 | #define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */ | 98 | |
93 | #define ENE_CIR_CONF1_TX_CARR 0x80 /* send TX carrier or not */ | 99 | #define ENE_CIRCFG_TX_EN 0x10 /* TX enable */ |
94 | 100 | #define ENE_CIRCFG_TX_IRQ 0x20 /* Send interrupt on TX done */ | |
95 | #define ENE_CIR_CONF2 0xFEC1 /* unknown setting = 0 */ | 101 | #define ENE_CIRCFG_TX_POL_REV 0x40 /* TX polarity reversed */ |
96 | #define ENE_CIR_CONF2_LEARN2 0x10 /* set on enable learning */ | 102 | #define ENE_CIRCFG_TX_CARR 0x80 /* send TX carrier or not */ |
97 | #define ENE_CIR_CONF2_GPIO40DIS 0x20 /* disable input via gpio40 */ | 103 | |
98 | 104 | /* CIR config register #2 */ | |
99 | #define ENE_CIR_SAMPLE_PERIOD 0xFEC8 /* sample period in us */ | 105 | #define ENE_CIRCFG2 0xFEC1 |
100 | #define ENE_CIR_SAMPLE_OVERFLOW 0x80 /* interrupt on overflows if set */ | 106 | #define ENE_CIRCFG2_RLC 0x00 |
101 | 107 | #define ENE_CIRCFG2_RC5 0x01 | |
102 | 108 | #define ENE_CIRCFG2_RC6 0x02 | |
103 | /* Two byte tx buffer */ | 109 | #define ENE_CIRCFG2_NEC 0x03 |
104 | #define ENE_TX_INPUT1 0xFEC9 | 110 | #define ENE_CIRCFG2_CARR_DETECT 0x10 /* Enable carrier detection */ |
105 | #define ENE_TX_INPUT2 0xFECA | 111 | #define ENE_CIRCFG2_GPIO0A 0x20 /* Use GPIO0A instead of GPIO40 for input */ |
106 | #define ENE_TX_PULSE_MASK 0x80 /* Transmitted sample is pulse */ | 112 | #define ENE_CIRCFG2_FAST_SAMPL1 0x40 /* Fast leading pulse detection for RC6 */ |
107 | #define ENE_TX_SMLP_MASK 0x7F | 113 | #define ENE_CIRCFG2_FAST_SAMPL2 0x80 /* Fast data detection for RC6 */ |
108 | #define ENE_TX_SMPL_PERIOD 50 /* transmit sample period - fixed */ | 114 | |
115 | /* Knobs for protocol decoding - will document when/if will use them */ | ||
116 | #define ENE_CIRPF 0xFEC2 | ||
117 | #define ENE_CIRHIGH 0xFEC3 | ||
118 | #define ENE_CIRBIT 0xFEC4 | ||
119 | #define ENE_CIRSTART 0xFEC5 | ||
120 | #define ENE_CIRSTART2 0xFEC6 | ||
121 | |||
122 | /* Actual register which contains RLC RX data - read by firmware */ | ||
123 | #define ENE_CIRDAT_IN 0xFEC7 | ||
124 | |||
125 | |||
126 | /* RLC configuration - sample period (1us resulution) + idle mode */ | ||
127 | #define ENE_CIRRLC_CFG 0xFEC8 | ||
128 | #define ENE_CIRRLC_CFG_OVERFLOW 0x80 /* interrupt on overflows if set */ | ||
129 | #define ENE_DEFAULT_SAMPLE_PERIOD 50 | ||
130 | |||
131 | /* Two byte RLC TX buffer */ | ||
132 | #define ENE_CIRRLC_OUT0 0xFEC9 | ||
133 | #define ENE_CIRRLC_OUT1 0xFECA | ||
134 | #define ENE_CIRRLC_OUT_PULSE 0x80 /* Transmitted sample is pulse */ | ||
135 | #define ENE_CIRRLC_OUT_MASK 0x7F | ||
136 | |||
137 | |||
138 | /* Carrier detect setting | ||
139 | * Low nibble - number of carrier pulses to average | ||
140 | * High nibble - number of initial carrier pulses to discard | ||
141 | */ | ||
142 | #define ENE_CIRCAR_PULS 0xFECB | ||
109 | 143 | ||
144 | /* detected RX carrier period (resolution: 500 ns) */ | ||
145 | #define ENE_CIRCAR_PRD 0xFECC | ||
146 | #define ENE_CIRCAR_PRD_VALID 0x80 /* data valid content valid */ | ||
110 | 147 | ||
111 | /* Unknown TX setting - TX sample period ??? */ | 148 | /* detected RX carrier pulse width (resolution: 500 ns) */ |
112 | #define ENE_TX_UNK1 0xFECB /* set to 0x63 */ | 149 | #define ENE_CIRCAR_HPRD 0xFECD |
113 | 150 | ||
114 | /* Current received carrier period */ | 151 | /* TX period (resolution: 500 ns, minimum 2)*/ |
115 | #define ENE_RX_CARRIER 0xFECC /* RX period (500 ns) */ | 152 | #define ENE_CIRMOD_PRD 0xFECE |
116 | #define ENE_RX_CARRIER_VALID 0x80 /* Register content valid */ | 153 | #define ENE_CIRMOD_PRD_POL 0x80 /* TX carrier polarity*/ |
117 | 154 | ||
155 | #define ENE_CIRMOD_PRD_MAX 0x7F /* 15.87 kHz */ | ||
156 | #define ENE_CIRMOD_PRD_MIN 0x02 /* 1 Mhz */ | ||
118 | 157 | ||
119 | /* TX period (1/carrier) */ | 158 | /* TX pulse width (resolution: 500 ns)*/ |
120 | #define ENE_TX_PERIOD 0xFECE /* TX period (500 ns) */ | 159 | #define ENE_CIRMOD_HPRD 0xFECF |
121 | #define ENE_TX_PERIOD_UNKBIT 0x80 /* This bit set on transmit*/ | ||
122 | #define ENE_TX_PERIOD_PULSE 0xFECF /* TX pulse period (500 ns)*/ | ||
123 | 160 | ||
124 | /* Hardware versions */ | 161 | /* Hardware versions */ |
125 | #define ENE_HW_VERSION 0xFF00 /* hardware revision */ | 162 | #define ENE_ECHV 0xFF00 /* hardware revision */ |
126 | #define ENE_PLLFRH 0xFF16 | 163 | #define ENE_PLLFRH 0xFF16 |
127 | #define ENE_PLLFRL 0xFF17 | 164 | #define ENE_PLLFRL 0xFF17 |
165 | #define ENE_DEFAULT_PLL_FREQ 1000 | ||
128 | 166 | ||
129 | #define ENE_HW_UNK 0xFF1D | 167 | #define ENE_ECSTS 0xFF1D |
130 | #define ENE_HW_UNK_CLR 0x04 | 168 | #define ENE_ECSTS_RSRVD 0x04 |
131 | #define ENE_HW_VER_MAJOR 0xFF1E /* chip version */ | ||
132 | #define ENE_HW_VER_MINOR 0xFF1F | ||
133 | #define ENE_HW_VER_OLD 0xFD00 | ||
134 | |||
135 | /* Normal/Learning carrier ranges - only valid if we have learning input*/ | ||
136 | /* TODO: test */ | ||
137 | #define ENE_NORMAL_RX_LOW 34 | ||
138 | #define ENE_NORMAL_RX_HI 38 | ||
139 | 169 | ||
140 | /* Tx carrier range */ | 170 | #define ENE_ECVER_MAJOR 0xFF1E /* chip version */ |
141 | /* Hardware might be able to do more, but this range is enough for | 171 | #define ENE_ECVER_MINOR 0xFF1F |
142 | all purposes */ | 172 | #define ENE_HW_VER_OLD 0xFD00 |
143 | #define ENE_TX_PERIOD_MAX 32 /* corresponds to 29.4 kHz */ | ||
144 | #define ENE_TX_PERIOD_MIN 16 /* corrsponds to 62.5 kHz */ | ||
145 | |||
146 | |||
147 | |||
148 | /* Minimal and maximal gaps */ | ||
149 | |||
150 | /* Normal case: | ||
151 | Minimal gap is 0x7F * sample period | ||
152 | Maximum gap depends on hardware. | ||
153 | For KB3926B, it is unlimited, for newer models its around | ||
154 | 250000, after which HW stops sending samples, and that is | ||
155 | not possible to change */ | ||
156 | |||
157 | /* Fan case: | ||
158 | Both minimal and maximal gaps are same, and equal to 0xFFF * 0x61 | ||
159 | And there is nothing to change this setting | ||
160 | */ | ||
161 | |||
162 | #define ENE_MAXGAP 250000 | ||
163 | #define ENE_MINGAP (127 * sample_period) | ||
164 | 173 | ||
165 | /******************************************************************************/ | 174 | /******************************************************************************/ |
166 | 175 | ||
@@ -171,46 +180,60 @@ | |||
171 | 180 | ||
172 | #define ENE_HW_B 1 /* 3926B */ | 181 | #define ENE_HW_B 1 /* 3926B */ |
173 | #define ENE_HW_C 2 /* 3926C */ | 182 | #define ENE_HW_C 2 /* 3926C */ |
174 | #define ENE_HW_D 3 /* 3926D */ | 183 | #define ENE_HW_D 3 /* 3926D or later */ |
175 | 184 | ||
176 | #define ene_printk(level, text, ...) \ | 185 | #define ene_printk(level, text, ...) \ |
177 | printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__) | 186 | printk(level ENE_DRIVER_NAME ": " text "\n", ## __VA_ARGS__) |
178 | 187 | ||
179 | #define ene_dbg(text, ...) \ | 188 | #define ene_notice(text, ...) ene_printk(KERN_NOTICE, text, ## __VA_ARGS__) |
180 | if (debug) \ | 189 | #define ene_warn(text, ...) ene_printk(KERN_WARNING, text, ## __VA_ARGS__) |
181 | printk(KERN_DEBUG \ | ||
182 | ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__) | ||
183 | 190 | ||
184 | #define ene_dbg_verbose(text, ...) \ | ||
185 | if (debug > 1) \ | ||
186 | printk(KERN_DEBUG \ | ||
187 | ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__) | ||
188 | 191 | ||
192 | #define __dbg(level, format, ...) \ | ||
193 | do { \ | ||
194 | if (debug >= level) \ | ||
195 | printk(KERN_DEBUG ENE_DRIVER_NAME \ | ||
196 | ": " format "\n", ## __VA_ARGS__); \ | ||
197 | } while (0) | ||
198 | |||
199 | |||
200 | #define dbg(format, ...) __dbg(1, format, ## __VA_ARGS__) | ||
201 | #define dbg_verbose(format, ...) __dbg(2, format, ## __VA_ARGS__) | ||
202 | #define dbg_regs(format, ...) __dbg(3, format, ## __VA_ARGS__) | ||
203 | |||
204 | #define MS_TO_NS(msec) ((msec) * 1000) | ||
189 | 205 | ||
190 | struct ene_device { | 206 | struct ene_device { |
191 | struct pnp_dev *pnp_dev; | 207 | struct pnp_dev *pnp_dev; |
192 | struct input_dev *idev; | 208 | struct input_dev *idev; |
193 | struct ir_dev_props *props; | 209 | struct ir_dev_props *props; |
194 | int in_use; | ||
195 | 210 | ||
196 | /* hw IO settings */ | 211 | /* hw IO settings */ |
197 | unsigned long hw_io; | 212 | long hw_io; |
198 | int irq; | 213 | int irq; |
199 | spinlock_t hw_lock; | 214 | spinlock_t hw_lock; |
200 | 215 | ||
201 | /* HW features */ | 216 | /* HW features */ |
202 | int hw_revision; /* hardware revision */ | 217 | int hw_revision; /* hardware revision */ |
203 | bool hw_learning_and_tx_capable; /* learning capable */ | 218 | bool hw_use_gpio_0a; /* gpio0a is demodulated input*/ |
204 | bool hw_gpio40_learning; /* gpio40 is learning */ | 219 | bool hw_extra_buffer; /* hardware has 'extra buffer' */ |
205 | bool hw_fan_as_normal_input; /* fan input is used as */ | 220 | bool hw_fan_input; /* fan input is IR data source */ |
206 | /* regular input */ | 221 | bool hw_learning_and_tx_capable; /* learning & tx capable */ |
222 | int pll_freq; | ||
223 | int buffer_len; | ||
224 | |||
225 | /* Extra RX buffer location */ | ||
226 | int extra_buf1_address; | ||
227 | int extra_buf1_len; | ||
228 | int extra_buf2_address; | ||
229 | int extra_buf2_len; | ||
230 | |||
207 | /* HW state*/ | 231 | /* HW state*/ |
208 | int rx_pointer; /* hw pointer to rx buffer */ | 232 | int r_pointer; /* pointer to next sample to read */ |
233 | int w_pointer; /* pointer to next sample hw will write */ | ||
209 | bool rx_fan_input_inuse; /* is fan input in use for rx*/ | 234 | bool rx_fan_input_inuse; /* is fan input in use for rx*/ |
210 | int tx_reg; /* current reg used for TX */ | 235 | int tx_reg; /* current reg used for TX */ |
211 | u8 saved_conf1; /* saved FEC0 reg */ | 236 | u8 saved_conf1; /* saved FEC0 reg */ |
212 | |||
213 | /* TX sample handling */ | ||
214 | unsigned int tx_sample; /* current sample for TX */ | 237 | unsigned int tx_sample; /* current sample for TX */ |
215 | bool tx_sample_pulse; /* current sample is pulse */ | 238 | bool tx_sample_pulse; /* current sample is pulse */ |
216 | 239 | ||
@@ -229,7 +252,11 @@ struct ene_device { | |||
229 | int transmitter_mask; | 252 | int transmitter_mask; |
230 | 253 | ||
231 | /* RX settings */ | 254 | /* RX settings */ |
232 | bool learning_enabled; /* learning input enabled */ | 255 | bool learning_mode_enabled; /* learning input enabled */ |
233 | bool carrier_detect_enabled; /* carrier detect enabled */ | 256 | bool carrier_detect_enabled; /* carrier detect enabled */ |
234 | int rx_period_adjust; | 257 | int rx_period_adjust; |
258 | bool rx_enabled; | ||
235 | }; | 259 | }; |
260 | |||
261 | static int ene_irq_status(struct ene_device *dev); | ||
262 | static void ene_rx_read_hw_pointer(struct ene_device *dev); | ||
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c index faed5a332c7..bc118066bc3 100644 --- a/drivers/media/IR/imon.c +++ b/drivers/media/IR/imon.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD | 2 | * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD |
3 | * | 3 | * |
4 | * Copyright(C) 2009 Jarod Wilson <jarod@wilsonet.com> | 4 | * Copyright(C) 2010 Jarod Wilson <jarod@wilsonet.com> |
5 | * Portions based on the original lirc_imon driver, | 5 | * Portions based on the original lirc_imon driver, |
6 | * Copyright(C) 2004 Venky Raju(dev@venky.ws) | 6 | * Copyright(C) 2004 Venky Raju(dev@venky.ws) |
7 | * | 7 | * |
@@ -26,6 +26,8 @@ | |||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ | ||
30 | |||
29 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
30 | #include <linux/init.h> | 32 | #include <linux/init.h> |
31 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
@@ -44,7 +46,7 @@ | |||
44 | #define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" | 46 | #define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" |
45 | #define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" | 47 | #define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" |
46 | #define MOD_NAME "imon" | 48 | #define MOD_NAME "imon" |
47 | #define MOD_VERSION "0.9.1" | 49 | #define MOD_VERSION "0.9.2" |
48 | 50 | ||
49 | #define DISPLAY_MINOR_BASE 144 | 51 | #define DISPLAY_MINOR_BASE 144 |
50 | #define DEVICE_NAME "lcd%d" | 52 | #define DEVICE_NAME "lcd%d" |
@@ -121,21 +123,26 @@ struct imon_context { | |||
121 | u16 vendor; /* usb vendor ID */ | 123 | u16 vendor; /* usb vendor ID */ |
122 | u16 product; /* usb product ID */ | 124 | u16 product; /* usb product ID */ |
123 | 125 | ||
124 | struct input_dev *idev; /* input device for remote */ | 126 | struct input_dev *rdev; /* input device for remote */ |
127 | struct input_dev *idev; /* input device for panel & IR mouse */ | ||
125 | struct input_dev *touch; /* input device for touchscreen */ | 128 | struct input_dev *touch; /* input device for touchscreen */ |
126 | 129 | ||
130 | spinlock_t kc_lock; /* make sure we get keycodes right */ | ||
127 | u32 kc; /* current input keycode */ | 131 | u32 kc; /* current input keycode */ |
128 | u32 last_keycode; /* last reported input keycode */ | 132 | u32 last_keycode; /* last reported input keycode */ |
133 | u32 rc_scancode; /* the computed remote scancode */ | ||
134 | u8 rc_toggle; /* the computed remote toggle bit */ | ||
129 | u64 ir_type; /* iMON or MCE (RC6) IR protocol? */ | 135 | u64 ir_type; /* iMON or MCE (RC6) IR protocol? */ |
130 | u8 mce_toggle_bit; /* last mce toggle bit */ | ||
131 | bool release_code; /* some keys send a release code */ | 136 | bool release_code; /* some keys send a release code */ |
132 | 137 | ||
133 | u8 display_type; /* store the display type */ | 138 | u8 display_type; /* store the display type */ |
134 | bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */ | 139 | bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */ |
135 | 140 | ||
141 | char name_rdev[128]; /* rc input device name */ | ||
142 | char phys_rdev[64]; /* rc input device phys path */ | ||
143 | |||
136 | char name_idev[128]; /* input device name */ | 144 | char name_idev[128]; /* input device name */ |
137 | char phys_idev[64]; /* input device phys path */ | 145 | char phys_idev[64]; /* input device phys path */ |
138 | struct timer_list itimer; /* input device timer, need for rc6 */ | ||
139 | 146 | ||
140 | char name_touch[128]; /* touch screen name */ | 147 | char name_touch[128]; /* touch screen name */ |
141 | char phys_touch[64]; /* touch screen phys path */ | 148 | char phys_touch[64]; /* touch screen phys path */ |
@@ -289,6 +296,9 @@ static const struct { | |||
289 | { 0x000100000000ffeell, KEY_VOLUMEUP }, | 296 | { 0x000100000000ffeell, KEY_VOLUMEUP }, |
290 | { 0x010000000000ffeell, KEY_VOLUMEDOWN }, | 297 | { 0x010000000000ffeell, KEY_VOLUMEDOWN }, |
291 | { 0x000000000100ffeell, KEY_MUTE }, | 298 | { 0x000000000100ffeell, KEY_MUTE }, |
299 | /* 0xffdc iMON MCE VFD */ | ||
300 | { 0x00010000ffffffeell, KEY_VOLUMEUP }, | ||
301 | { 0x01000000ffffffeell, KEY_VOLUMEDOWN }, | ||
292 | /* iMON Knob values */ | 302 | /* iMON Knob values */ |
293 | { 0x000100ffffffffeell, KEY_VOLUMEUP }, | 303 | { 0x000100ffffffffeell, KEY_VOLUMEUP }, |
294 | { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, | 304 | { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, |
@@ -307,7 +317,7 @@ MODULE_DEVICE_TABLE(usb, imon_usb_id_table); | |||
307 | 317 | ||
308 | static bool debug; | 318 | static bool debug; |
309 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 319 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
310 | MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)"); | 320 | MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); |
311 | 321 | ||
312 | /* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */ | 322 | /* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */ |
313 | static int display_type; | 323 | static int display_type; |
@@ -365,15 +375,14 @@ static int display_open(struct inode *inode, struct file *file) | |||
365 | subminor = iminor(inode); | 375 | subminor = iminor(inode); |
366 | interface = usb_find_interface(&imon_driver, subminor); | 376 | interface = usb_find_interface(&imon_driver, subminor); |
367 | if (!interface) { | 377 | if (!interface) { |
368 | err("%s: could not find interface for minor %d", | 378 | pr_err("could not find interface for minor %d\n", subminor); |
369 | __func__, subminor); | ||
370 | retval = -ENODEV; | 379 | retval = -ENODEV; |
371 | goto exit; | 380 | goto exit; |
372 | } | 381 | } |
373 | ictx = usb_get_intfdata(interface); | 382 | ictx = usb_get_intfdata(interface); |
374 | 383 | ||
375 | if (!ictx) { | 384 | if (!ictx) { |
376 | err("%s: no context found for minor %d", __func__, subminor); | 385 | pr_err("no context found for minor %d\n", subminor); |
377 | retval = -ENODEV; | 386 | retval = -ENODEV; |
378 | goto exit; | 387 | goto exit; |
379 | } | 388 | } |
@@ -381,10 +390,10 @@ static int display_open(struct inode *inode, struct file *file) | |||
381 | mutex_lock(&ictx->lock); | 390 | mutex_lock(&ictx->lock); |
382 | 391 | ||
383 | if (!ictx->display_supported) { | 392 | if (!ictx->display_supported) { |
384 | err("%s: display not supported by device", __func__); | 393 | pr_err("display not supported by device\n"); |
385 | retval = -ENODEV; | 394 | retval = -ENODEV; |
386 | } else if (ictx->display_isopen) { | 395 | } else if (ictx->display_isopen) { |
387 | err("%s: display port is already open", __func__); | 396 | pr_err("display port is already open\n"); |
388 | retval = -EBUSY; | 397 | retval = -EBUSY; |
389 | } else { | 398 | } else { |
390 | ictx->display_isopen = true; | 399 | ictx->display_isopen = true; |
@@ -411,17 +420,17 @@ static int display_close(struct inode *inode, struct file *file) | |||
411 | ictx = file->private_data; | 420 | ictx = file->private_data; |
412 | 421 | ||
413 | if (!ictx) { | 422 | if (!ictx) { |
414 | err("%s: no context for device", __func__); | 423 | pr_err("no context for device\n"); |
415 | return -ENODEV; | 424 | return -ENODEV; |
416 | } | 425 | } |
417 | 426 | ||
418 | mutex_lock(&ictx->lock); | 427 | mutex_lock(&ictx->lock); |
419 | 428 | ||
420 | if (!ictx->display_supported) { | 429 | if (!ictx->display_supported) { |
421 | err("%s: display not supported by device", __func__); | 430 | pr_err("display not supported by device\n"); |
422 | retval = -ENODEV; | 431 | retval = -ENODEV; |
423 | } else if (!ictx->display_isopen) { | 432 | } else if (!ictx->display_isopen) { |
424 | err("%s: display is not open", __func__); | 433 | pr_err("display is not open\n"); |
425 | retval = -EIO; | 434 | retval = -EIO; |
426 | } else { | 435 | } else { |
427 | ictx->display_isopen = false; | 436 | ictx->display_isopen = false; |
@@ -500,19 +509,19 @@ static int send_packet(struct imon_context *ictx) | |||
500 | if (retval) { | 509 | if (retval) { |
501 | ictx->tx.busy = false; | 510 | ictx->tx.busy = false; |
502 | smp_rmb(); /* ensure later readers know we're not busy */ | 511 | smp_rmb(); /* ensure later readers know we're not busy */ |
503 | err("%s: error submitting urb(%d)", __func__, retval); | 512 | pr_err("error submitting urb(%d)\n", retval); |
504 | } else { | 513 | } else { |
505 | /* Wait for transmission to complete (or abort) */ | 514 | /* Wait for transmission to complete (or abort) */ |
506 | mutex_unlock(&ictx->lock); | 515 | mutex_unlock(&ictx->lock); |
507 | retval = wait_for_completion_interruptible( | 516 | retval = wait_for_completion_interruptible( |
508 | &ictx->tx.finished); | 517 | &ictx->tx.finished); |
509 | if (retval) | 518 | if (retval) |
510 | err("%s: task interrupted", __func__); | 519 | pr_err("task interrupted\n"); |
511 | mutex_lock(&ictx->lock); | 520 | mutex_lock(&ictx->lock); |
512 | 521 | ||
513 | retval = ictx->tx.status; | 522 | retval = ictx->tx.status; |
514 | if (retval) | 523 | if (retval) |
515 | err("%s: packet tx failed (%d)", __func__, retval); | 524 | pr_err("packet tx failed (%d)\n", retval); |
516 | } | 525 | } |
517 | 526 | ||
518 | kfree(control_req); | 527 | kfree(control_req); |
@@ -544,12 +553,12 @@ static int send_associate_24g(struct imon_context *ictx) | |||
544 | 0x00, 0x00, 0x00, 0x20 }; | 553 | 0x00, 0x00, 0x00, 0x20 }; |
545 | 554 | ||
546 | if (!ictx) { | 555 | if (!ictx) { |
547 | err("%s: no context for device", __func__); | 556 | pr_err("no context for device\n"); |
548 | return -ENODEV; | 557 | return -ENODEV; |
549 | } | 558 | } |
550 | 559 | ||
551 | if (!ictx->dev_present_intf0) { | 560 | if (!ictx->dev_present_intf0) { |
552 | err("%s: no iMON device present", __func__); | 561 | pr_err("no iMON device present\n"); |
553 | return -ENODEV; | 562 | return -ENODEV; |
554 | } | 563 | } |
555 | 564 | ||
@@ -577,7 +586,7 @@ static int send_set_imon_clock(struct imon_context *ictx, | |||
577 | int i; | 586 | int i; |
578 | 587 | ||
579 | if (!ictx) { | 588 | if (!ictx) { |
580 | err("%s: no context for device", __func__); | 589 | pr_err("no context for device\n"); |
581 | return -ENODEV; | 590 | return -ENODEV; |
582 | } | 591 | } |
583 | 592 | ||
@@ -638,8 +647,7 @@ static int send_set_imon_clock(struct imon_context *ictx, | |||
638 | memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8); | 647 | memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8); |
639 | retval = send_packet(ictx); | 648 | retval = send_packet(ictx); |
640 | if (retval) { | 649 | if (retval) { |
641 | err("%s: send_packet failed for packet %d", | 650 | pr_err("send_packet failed for packet %d\n", i); |
642 | __func__, i); | ||
643 | break; | 651 | break; |
644 | } | 652 | } |
645 | } | 653 | } |
@@ -778,7 +786,7 @@ static struct attribute *imon_display_sysfs_entries[] = { | |||
778 | NULL | 786 | NULL |
779 | }; | 787 | }; |
780 | 788 | ||
781 | static struct attribute_group imon_display_attribute_group = { | 789 | static struct attribute_group imon_display_attr_group = { |
782 | .attrs = imon_display_sysfs_entries | 790 | .attrs = imon_display_sysfs_entries |
783 | }; | 791 | }; |
784 | 792 | ||
@@ -787,7 +795,7 @@ static struct attribute *imon_rf_sysfs_entries[] = { | |||
787 | NULL | 795 | NULL |
788 | }; | 796 | }; |
789 | 797 | ||
790 | static struct attribute_group imon_rf_attribute_group = { | 798 | static struct attribute_group imon_rf_attr_group = { |
791 | .attrs = imon_rf_sysfs_entries | 799 | .attrs = imon_rf_sysfs_entries |
792 | }; | 800 | }; |
793 | 801 | ||
@@ -815,20 +823,20 @@ static ssize_t vfd_write(struct file *file, const char *buf, | |||
815 | 823 | ||
816 | ictx = file->private_data; | 824 | ictx = file->private_data; |
817 | if (!ictx) { | 825 | if (!ictx) { |
818 | err("%s: no context for device", __func__); | 826 | pr_err("no context for device\n"); |
819 | return -ENODEV; | 827 | return -ENODEV; |
820 | } | 828 | } |
821 | 829 | ||
822 | mutex_lock(&ictx->lock); | 830 | mutex_lock(&ictx->lock); |
823 | 831 | ||
824 | if (!ictx->dev_present_intf0) { | 832 | if (!ictx->dev_present_intf0) { |
825 | err("%s: no iMON device present", __func__); | 833 | pr_err("no iMON device present\n"); |
826 | retval = -ENODEV; | 834 | retval = -ENODEV; |
827 | goto exit; | 835 | goto exit; |
828 | } | 836 | } |
829 | 837 | ||
830 | if (n_bytes <= 0 || n_bytes > 32) { | 838 | if (n_bytes <= 0 || n_bytes > 32) { |
831 | err("%s: invalid payload size", __func__); | 839 | pr_err("invalid payload size\n"); |
832 | retval = -EINVAL; | 840 | retval = -EINVAL; |
833 | goto exit; | 841 | goto exit; |
834 | } | 842 | } |
@@ -854,8 +862,7 @@ static ssize_t vfd_write(struct file *file, const char *buf, | |||
854 | 862 | ||
855 | retval = send_packet(ictx); | 863 | retval = send_packet(ictx); |
856 | if (retval) { | 864 | if (retval) { |
857 | err("%s: send packet failed for packet #%d", | 865 | pr_err("send packet failed for packet #%d\n", seq / 2); |
858 | __func__, seq/2); | ||
859 | goto exit; | 866 | goto exit; |
860 | } else { | 867 | } else { |
861 | seq += 2; | 868 | seq += 2; |
@@ -869,8 +876,7 @@ static ssize_t vfd_write(struct file *file, const char *buf, | |||
869 | ictx->usb_tx_buf[7] = (unsigned char) seq; | 876 | ictx->usb_tx_buf[7] = (unsigned char) seq; |
870 | retval = send_packet(ictx); | 877 | retval = send_packet(ictx); |
871 | if (retval) | 878 | if (retval) |
872 | err("%s: send packet failed for packet #%d", | 879 | pr_err("send packet failed for packet #%d\n", seq / 2); |
873 | __func__, seq / 2); | ||
874 | 880 | ||
875 | exit: | 881 | exit: |
876 | mutex_unlock(&ictx->lock); | 882 | mutex_unlock(&ictx->lock); |
@@ -899,21 +905,20 @@ static ssize_t lcd_write(struct file *file, const char *buf, | |||
899 | 905 | ||
900 | ictx = file->private_data; | 906 | ictx = file->private_data; |
901 | if (!ictx) { | 907 | if (!ictx) { |
902 | err("%s: no context for device", __func__); | 908 | pr_err("no context for device\n"); |
903 | return -ENODEV; | 909 | return -ENODEV; |
904 | } | 910 | } |
905 | 911 | ||
906 | mutex_lock(&ictx->lock); | 912 | mutex_lock(&ictx->lock); |
907 | 913 | ||
908 | if (!ictx->display_supported) { | 914 | if (!ictx->display_supported) { |
909 | err("%s: no iMON display present", __func__); | 915 | pr_err("no iMON display present\n"); |
910 | retval = -ENODEV; | 916 | retval = -ENODEV; |
911 | goto exit; | 917 | goto exit; |
912 | } | 918 | } |
913 | 919 | ||
914 | if (n_bytes != 8) { | 920 | if (n_bytes != 8) { |
915 | err("%s: invalid payload size: %d (expecting 8)", | 921 | pr_err("invalid payload size: %d (expected 8)\n", (int)n_bytes); |
916 | __func__, (int) n_bytes); | ||
917 | retval = -EINVAL; | 922 | retval = -EINVAL; |
918 | goto exit; | 923 | goto exit; |
919 | } | 924 | } |
@@ -925,7 +930,7 @@ static ssize_t lcd_write(struct file *file, const char *buf, | |||
925 | 930 | ||
926 | retval = send_packet(ictx); | 931 | retval = send_packet(ictx); |
927 | if (retval) { | 932 | if (retval) { |
928 | err("%s: send packet failed!", __func__); | 933 | pr_err("send packet failed!\n"); |
929 | goto exit; | 934 | goto exit; |
930 | } else { | 935 | } else { |
931 | dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n", | 936 | dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n", |
@@ -958,17 +963,6 @@ static void usb_tx_callback(struct urb *urb) | |||
958 | } | 963 | } |
959 | 964 | ||
960 | /** | 965 | /** |
961 | * mce/rc6 keypresses have no distinct release code, use timer | ||
962 | */ | ||
963 | static void imon_mce_timeout(unsigned long data) | ||
964 | { | ||
965 | struct imon_context *ictx = (struct imon_context *)data; | ||
966 | |||
967 | input_report_key(ictx->idev, ictx->last_keycode, 0); | ||
968 | input_sync(ictx->idev); | ||
969 | } | ||
970 | |||
971 | /** | ||
972 | * report touchscreen input | 966 | * report touchscreen input |
973 | */ | 967 | */ |
974 | static void imon_touch_display_timeout(unsigned long data) | 968 | static void imon_touch_display_timeout(unsigned long data) |
@@ -1008,14 +1002,11 @@ int imon_ir_change_protocol(void *priv, u64 ir_type) | |||
1008 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); | 1002 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); |
1009 | ir_proto_packet[0] = 0x01; | 1003 | ir_proto_packet[0] = 0x01; |
1010 | pad_mouse = false; | 1004 | pad_mouse = false; |
1011 | init_timer(&ictx->itimer); | ||
1012 | ictx->itimer.data = (unsigned long)ictx; | ||
1013 | ictx->itimer.function = imon_mce_timeout; | ||
1014 | break; | 1005 | break; |
1015 | case IR_TYPE_UNKNOWN: | 1006 | case IR_TYPE_UNKNOWN: |
1016 | case IR_TYPE_OTHER: | 1007 | case IR_TYPE_OTHER: |
1017 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); | 1008 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); |
1018 | if (pad_stabilize) | 1009 | if (pad_stabilize && !nomouse) |
1019 | pad_mouse = true; | 1010 | pad_mouse = true; |
1020 | else { | 1011 | else { |
1021 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); | 1012 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); |
@@ -1027,7 +1018,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type) | |||
1027 | default: | 1018 | default: |
1028 | dev_warn(dev, "Unsupported IR protocol specified, overriding " | 1019 | dev_warn(dev, "Unsupported IR protocol specified, overriding " |
1029 | "to iMON IR protocol\n"); | 1020 | "to iMON IR protocol\n"); |
1030 | if (pad_stabilize) | 1021 | if (pad_stabilize && !nomouse) |
1031 | pad_mouse = true; | 1022 | pad_mouse = true; |
1032 | else { | 1023 | else { |
1033 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); | 1024 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); |
@@ -1149,20 +1140,21 @@ static int stabilize(int a, int b, u16 timeout, u16 threshold) | |||
1149 | return result; | 1140 | return result; |
1150 | } | 1141 | } |
1151 | 1142 | ||
1152 | static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code) | 1143 | static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode) |
1153 | { | 1144 | { |
1154 | u32 scancode = be32_to_cpu(hw_code); | ||
1155 | u32 keycode; | 1145 | u32 keycode; |
1156 | u32 release; | 1146 | u32 release; |
1157 | bool is_release_code = false; | 1147 | bool is_release_code = false; |
1158 | 1148 | ||
1159 | /* Look for the initial press of a button */ | 1149 | /* Look for the initial press of a button */ |
1160 | keycode = ir_g_keycode_from_table(ictx->idev, scancode); | 1150 | keycode = ir_g_keycode_from_table(ictx->rdev, scancode); |
1151 | ictx->rc_toggle = 0x0; | ||
1152 | ictx->rc_scancode = scancode; | ||
1161 | 1153 | ||
1162 | /* Look for the release of a button */ | 1154 | /* Look for the release of a button */ |
1163 | if (keycode == KEY_RESERVED) { | 1155 | if (keycode == KEY_RESERVED) { |
1164 | release = scancode & ~0x4000; | 1156 | release = scancode & ~0x4000; |
1165 | keycode = ir_g_keycode_from_table(ictx->idev, release); | 1157 | keycode = ir_g_keycode_from_table(ictx->rdev, release); |
1166 | if (keycode != KEY_RESERVED) | 1158 | if (keycode != KEY_RESERVED) |
1167 | is_release_code = true; | 1159 | is_release_code = true; |
1168 | } | 1160 | } |
@@ -1172,9 +1164,8 @@ static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code) | |||
1172 | return keycode; | 1164 | return keycode; |
1173 | } | 1165 | } |
1174 | 1166 | ||
1175 | static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code) | 1167 | static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode) |
1176 | { | 1168 | { |
1177 | u32 scancode = be32_to_cpu(hw_code); | ||
1178 | u32 keycode; | 1169 | u32 keycode; |
1179 | 1170 | ||
1180 | #define MCE_KEY_MASK 0x7000 | 1171 | #define MCE_KEY_MASK 0x7000 |
@@ -1188,18 +1179,21 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code) | |||
1188 | * but we can't or them into all codes, as some keys are decoded in | 1179 | * but we can't or them into all codes, as some keys are decoded in |
1189 | * a different way w/o the same use of the toggle bit... | 1180 | * a different way w/o the same use of the toggle bit... |
1190 | */ | 1181 | */ |
1191 | if ((scancode >> 24) & 0x80) | 1182 | if (scancode & 0x80000000) |
1192 | scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT; | 1183 | scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT; |
1193 | 1184 | ||
1194 | keycode = ir_g_keycode_from_table(ictx->idev, scancode); | 1185 | ictx->rc_scancode = scancode; |
1186 | keycode = ir_g_keycode_from_table(ictx->rdev, scancode); | ||
1187 | |||
1188 | /* not used in mce mode, but make sure we know its false */ | ||
1189 | ictx->release_code = false; | ||
1195 | 1190 | ||
1196 | return keycode; | 1191 | return keycode; |
1197 | } | 1192 | } |
1198 | 1193 | ||
1199 | static u32 imon_panel_key_lookup(u64 hw_code) | 1194 | static u32 imon_panel_key_lookup(u64 code) |
1200 | { | 1195 | { |
1201 | int i; | 1196 | int i; |
1202 | u64 code = be64_to_cpu(hw_code); | ||
1203 | u32 keycode = KEY_RESERVED; | 1197 | u32 keycode = KEY_RESERVED; |
1204 | 1198 | ||
1205 | for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) { | 1199 | for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) { |
@@ -1219,6 +1213,9 @@ static bool imon_mouse_event(struct imon_context *ictx, | |||
1219 | u8 right_shift = 1; | 1213 | u8 right_shift = 1; |
1220 | bool mouse_input = true; | 1214 | bool mouse_input = true; |
1221 | int dir = 0; | 1215 | int dir = 0; |
1216 | unsigned long flags; | ||
1217 | |||
1218 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1222 | 1219 | ||
1223 | /* newer iMON device PAD or mouse button */ | 1220 | /* newer iMON device PAD or mouse button */ |
1224 | if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) { | 1221 | if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) { |
@@ -1250,6 +1247,8 @@ static bool imon_mouse_event(struct imon_context *ictx, | |||
1250 | } else | 1247 | } else |
1251 | mouse_input = false; | 1248 | mouse_input = false; |
1252 | 1249 | ||
1250 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1251 | |||
1253 | if (mouse_input) { | 1252 | if (mouse_input) { |
1254 | dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); | 1253 | dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); |
1255 | 1254 | ||
@@ -1264,7 +1263,9 @@ static bool imon_mouse_event(struct imon_context *ictx, | |||
1264 | buf[1] >> right_shift & 0x1); | 1263 | buf[1] >> right_shift & 0x1); |
1265 | } | 1264 | } |
1266 | input_sync(ictx->idev); | 1265 | input_sync(ictx->idev); |
1266 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1267 | ictx->last_keycode = ictx->kc; | 1267 | ictx->last_keycode = ictx->kc; |
1268 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1268 | } | 1269 | } |
1269 | 1270 | ||
1270 | return mouse_input; | 1271 | return mouse_input; |
@@ -1286,8 +1287,8 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1286 | int dir = 0; | 1287 | int dir = 0; |
1287 | char rel_x = 0x00, rel_y = 0x00; | 1288 | char rel_x = 0x00, rel_y = 0x00; |
1288 | u16 timeout, threshold; | 1289 | u16 timeout, threshold; |
1289 | u64 temp_key; | 1290 | u32 scancode = KEY_RESERVED; |
1290 | u32 remote_key; | 1291 | unsigned long flags; |
1291 | 1292 | ||
1292 | /* | 1293 | /* |
1293 | * The imon directional pad functions more like a touchpad. Bytes 3 & 4 | 1294 | * The imon directional pad functions more like a touchpad. Bytes 3 & 4 |
@@ -1311,26 +1312,36 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1311 | dir = stabilize((int)rel_x, (int)rel_y, | 1312 | dir = stabilize((int)rel_x, (int)rel_y, |
1312 | timeout, threshold); | 1313 | timeout, threshold); |
1313 | if (!dir) { | 1314 | if (!dir) { |
1315 | spin_lock_irqsave(&ictx->kc_lock, | ||
1316 | flags); | ||
1314 | ictx->kc = KEY_UNKNOWN; | 1317 | ictx->kc = KEY_UNKNOWN; |
1318 | spin_unlock_irqrestore(&ictx->kc_lock, | ||
1319 | flags); | ||
1315 | return; | 1320 | return; |
1316 | } | 1321 | } |
1317 | buf[2] = dir & 0xFF; | 1322 | buf[2] = dir & 0xFF; |
1318 | buf[3] = (dir >> 8) & 0xFF; | 1323 | buf[3] = (dir >> 8) & 0xFF; |
1319 | memcpy(&temp_key, buf, sizeof(temp_key)); | 1324 | scancode = be32_to_cpu(*((u32 *)buf)); |
1320 | remote_key = (u32) (le64_to_cpu(temp_key) | ||
1321 | & 0xffffffff); | ||
1322 | ictx->kc = imon_remote_key_lookup(ictx, | ||
1323 | remote_key); | ||
1324 | } | 1325 | } |
1325 | } else { | 1326 | } else { |
1327 | /* | ||
1328 | * Hack alert: instead of using keycodes, we have | ||
1329 | * to use hard-coded scancodes here... | ||
1330 | */ | ||
1326 | if (abs(rel_y) > abs(rel_x)) { | 1331 | if (abs(rel_y) > abs(rel_x)) { |
1327 | buf[2] = (rel_y > 0) ? 0x7F : 0x80; | 1332 | buf[2] = (rel_y > 0) ? 0x7F : 0x80; |
1328 | buf[3] = 0; | 1333 | buf[3] = 0; |
1329 | ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP; | 1334 | if (rel_y > 0) |
1335 | scancode = 0x01007f00; /* KEY_DOWN */ | ||
1336 | else | ||
1337 | scancode = 0x01008000; /* KEY_UP */ | ||
1330 | } else { | 1338 | } else { |
1331 | buf[2] = 0; | 1339 | buf[2] = 0; |
1332 | buf[3] = (rel_x > 0) ? 0x7F : 0x80; | 1340 | buf[3] = (rel_x > 0) ? 0x7F : 0x80; |
1333 | ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT; | 1341 | if (rel_x > 0) |
1342 | scancode = 0x0100007f; /* KEY_RIGHT */ | ||
1343 | else | ||
1344 | scancode = 0x01000080; /* KEY_LEFT */ | ||
1334 | } | 1345 | } |
1335 | } | 1346 | } |
1336 | 1347 | ||
@@ -1367,34 +1378,56 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1367 | dir = stabilize((int)rel_x, (int)rel_y, | 1378 | dir = stabilize((int)rel_x, (int)rel_y, |
1368 | timeout, threshold); | 1379 | timeout, threshold); |
1369 | if (!dir) { | 1380 | if (!dir) { |
1381 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1370 | ictx->kc = KEY_UNKNOWN; | 1382 | ictx->kc = KEY_UNKNOWN; |
1383 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1371 | return; | 1384 | return; |
1372 | } | 1385 | } |
1373 | buf[2] = dir & 0xFF; | 1386 | buf[2] = dir & 0xFF; |
1374 | buf[3] = (dir >> 8) & 0xFF; | 1387 | buf[3] = (dir >> 8) & 0xFF; |
1375 | memcpy(&temp_key, buf, sizeof(temp_key)); | 1388 | scancode = be32_to_cpu(*((u32 *)buf)); |
1376 | remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); | ||
1377 | ictx->kc = imon_remote_key_lookup(ictx, remote_key); | ||
1378 | } else { | 1389 | } else { |
1390 | /* | ||
1391 | * Hack alert: instead of using keycodes, we have | ||
1392 | * to use hard-coded scancodes here... | ||
1393 | */ | ||
1379 | if (abs(rel_y) > abs(rel_x)) { | 1394 | if (abs(rel_y) > abs(rel_x)) { |
1380 | buf[2] = (rel_y > 0) ? 0x7F : 0x80; | 1395 | buf[2] = (rel_y > 0) ? 0x7F : 0x80; |
1381 | buf[3] = 0; | 1396 | buf[3] = 0; |
1382 | ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP; | 1397 | if (rel_y > 0) |
1398 | scancode = 0x01007f00; /* KEY_DOWN */ | ||
1399 | else | ||
1400 | scancode = 0x01008000; /* KEY_UP */ | ||
1383 | } else { | 1401 | } else { |
1384 | buf[2] = 0; | 1402 | buf[2] = 0; |
1385 | buf[3] = (rel_x > 0) ? 0x7F : 0x80; | 1403 | buf[3] = (rel_x > 0) ? 0x7F : 0x80; |
1386 | ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT; | 1404 | if (rel_x > 0) |
1405 | scancode = 0x0100007f; /* KEY_RIGHT */ | ||
1406 | else | ||
1407 | scancode = 0x01000080; /* KEY_LEFT */ | ||
1387 | } | 1408 | } |
1388 | } | 1409 | } |
1389 | } | 1410 | } |
1411 | |||
1412 | if (scancode) { | ||
1413 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1414 | ictx->kc = imon_remote_key_lookup(ictx, scancode); | ||
1415 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1416 | } | ||
1390 | } | 1417 | } |
1391 | 1418 | ||
1419 | /** | ||
1420 | * figure out if these is a press or a release. We don't actually | ||
1421 | * care about repeats, as those will be auto-generated within the IR | ||
1422 | * subsystem for repeating scancodes. | ||
1423 | */ | ||
1392 | static int imon_parse_press_type(struct imon_context *ictx, | 1424 | static int imon_parse_press_type(struct imon_context *ictx, |
1393 | unsigned char *buf, u8 ktype) | 1425 | unsigned char *buf, u8 ktype) |
1394 | { | 1426 | { |
1395 | int press_type = 0; | 1427 | int press_type = 0; |
1396 | int rep_delay = ictx->idev->rep[REP_DELAY]; | 1428 | unsigned long flags; |
1397 | int rep_period = ictx->idev->rep[REP_PERIOD]; | 1429 | |
1430 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1398 | 1431 | ||
1399 | /* key release of 0x02XXXXXX key */ | 1432 | /* key release of 0x02XXXXXX key */ |
1400 | if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00) | 1433 | if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00) |
@@ -1410,22 +1443,10 @@ static int imon_parse_press_type(struct imon_context *ictx, | |||
1410 | buf[2] == 0x81 && buf[3] == 0xb7) | 1443 | buf[2] == 0x81 && buf[3] == 0xb7) |
1411 | ictx->kc = ictx->last_keycode; | 1444 | ictx->kc = ictx->last_keycode; |
1412 | 1445 | ||
1413 | /* mce-specific button handling */ | 1446 | /* mce-specific button handling, no keyup events */ |
1414 | else if (ktype == IMON_KEY_MCE) { | 1447 | else if (ktype == IMON_KEY_MCE) { |
1415 | /* initial press */ | 1448 | ictx->rc_toggle = buf[2]; |
1416 | if (ictx->kc != ictx->last_keycode | 1449 | press_type = 1; |
1417 | || buf[2] != ictx->mce_toggle_bit) { | ||
1418 | ictx->last_keycode = ictx->kc; | ||
1419 | ictx->mce_toggle_bit = buf[2]; | ||
1420 | press_type = 1; | ||
1421 | mod_timer(&ictx->itimer, | ||
1422 | jiffies + msecs_to_jiffies(rep_delay)); | ||
1423 | /* repeat */ | ||
1424 | } else { | ||
1425 | press_type = 2; | ||
1426 | mod_timer(&ictx->itimer, | ||
1427 | jiffies + msecs_to_jiffies(rep_period)); | ||
1428 | } | ||
1429 | 1450 | ||
1430 | /* incoherent or irrelevant data */ | 1451 | /* incoherent or irrelevant data */ |
1431 | } else if (ictx->kc == KEY_RESERVED) | 1452 | } else if (ictx->kc == KEY_RESERVED) |
@@ -1439,6 +1460,8 @@ static int imon_parse_press_type(struct imon_context *ictx, | |||
1439 | else | 1460 | else |
1440 | press_type = 1; | 1461 | press_type = 1; |
1441 | 1462 | ||
1463 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1464 | |||
1442 | return press_type; | 1465 | return press_type; |
1443 | } | 1466 | } |
1444 | 1467 | ||
@@ -1451,41 +1474,45 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1451 | int len = urb->actual_length; | 1474 | int len = urb->actual_length; |
1452 | unsigned char *buf = urb->transfer_buffer; | 1475 | unsigned char *buf = urb->transfer_buffer; |
1453 | struct device *dev = ictx->dev; | 1476 | struct device *dev = ictx->dev; |
1477 | unsigned long flags; | ||
1454 | u32 kc; | 1478 | u32 kc; |
1455 | bool norelease = false; | 1479 | bool norelease = false; |
1456 | int i; | 1480 | int i; |
1457 | u64 temp_key; | 1481 | u64 scancode; |
1458 | u64 panel_key = 0; | 1482 | struct input_dev *rdev = NULL; |
1459 | u32 remote_key = 0; | 1483 | struct ir_input_dev *irdev = NULL; |
1460 | struct input_dev *idev = NULL; | ||
1461 | int press_type = 0; | 1484 | int press_type = 0; |
1462 | int msec; | 1485 | int msec; |
1463 | struct timeval t; | 1486 | struct timeval t; |
1464 | static struct timeval prev_time = { 0, 0 }; | 1487 | static struct timeval prev_time = { 0, 0 }; |
1465 | u8 ktype = IMON_KEY_IMON; | 1488 | u8 ktype; |
1466 | 1489 | ||
1467 | idev = ictx->idev; | 1490 | rdev = ictx->rdev; |
1491 | irdev = input_get_drvdata(rdev); | ||
1468 | 1492 | ||
1469 | /* filter out junk data on the older 0xffdc imon devices */ | 1493 | /* filter out junk data on the older 0xffdc imon devices */ |
1470 | if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)) | 1494 | if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)) |
1471 | return; | 1495 | return; |
1472 | 1496 | ||
1473 | /* Figure out what key was pressed */ | 1497 | /* Figure out what key was pressed */ |
1474 | memcpy(&temp_key, buf, sizeof(temp_key)); | ||
1475 | if (len == 8 && buf[7] == 0xee) { | 1498 | if (len == 8 && buf[7] == 0xee) { |
1499 | scancode = be64_to_cpu(*((u64 *)buf)); | ||
1476 | ktype = IMON_KEY_PANEL; | 1500 | ktype = IMON_KEY_PANEL; |
1477 | panel_key = le64_to_cpu(temp_key); | 1501 | kc = imon_panel_key_lookup(scancode); |
1478 | kc = imon_panel_key_lookup(panel_key); | ||
1479 | } else { | 1502 | } else { |
1480 | remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); | 1503 | scancode = be32_to_cpu(*((u32 *)buf)); |
1481 | if (ictx->ir_type == IR_TYPE_RC6) { | 1504 | if (ictx->ir_type == IR_TYPE_RC6) { |
1505 | ktype = IMON_KEY_IMON; | ||
1482 | if (buf[0] == 0x80) | 1506 | if (buf[0] == 0x80) |
1483 | ktype = IMON_KEY_MCE; | 1507 | ktype = IMON_KEY_MCE; |
1484 | kc = imon_mce_key_lookup(ictx, remote_key); | 1508 | kc = imon_mce_key_lookup(ictx, scancode); |
1485 | } else | 1509 | } else { |
1486 | kc = imon_remote_key_lookup(ictx, remote_key); | 1510 | ktype = IMON_KEY_IMON; |
1511 | kc = imon_remote_key_lookup(ictx, scancode); | ||
1512 | } | ||
1487 | } | 1513 | } |
1488 | 1514 | ||
1515 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1489 | /* keyboard/mouse mode toggle button */ | 1516 | /* keyboard/mouse mode toggle button */ |
1490 | if (kc == KEY_KEYBOARD && !ictx->release_code) { | 1517 | if (kc == KEY_KEYBOARD && !ictx->release_code) { |
1491 | ictx->last_keycode = kc; | 1518 | ictx->last_keycode = kc; |
@@ -1493,6 +1520,7 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1493 | ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1; | 1520 | ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1; |
1494 | dev_dbg(dev, "toggling to %s mode\n", | 1521 | dev_dbg(dev, "toggling to %s mode\n", |
1495 | ictx->pad_mouse ? "mouse" : "keyboard"); | 1522 | ictx->pad_mouse ? "mouse" : "keyboard"); |
1523 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1496 | return; | 1524 | return; |
1497 | } else { | 1525 | } else { |
1498 | ictx->pad_mouse = 0; | 1526 | ictx->pad_mouse = 0; |
@@ -1501,11 +1529,13 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1501 | } | 1529 | } |
1502 | 1530 | ||
1503 | ictx->kc = kc; | 1531 | ictx->kc = kc; |
1532 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1504 | 1533 | ||
1505 | /* send touchscreen events through input subsystem if touchpad data */ | 1534 | /* send touchscreen events through input subsystem if touchpad data */ |
1506 | if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 && | 1535 | if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 && |
1507 | buf[7] == 0x86) { | 1536 | buf[7] == 0x86) { |
1508 | imon_touch_event(ictx, buf); | 1537 | imon_touch_event(ictx, buf); |
1538 | return; | ||
1509 | 1539 | ||
1510 | /* look for mouse events with pad in mouse mode */ | 1540 | /* look for mouse events with pad in mouse mode */ |
1511 | } else if (ictx->pad_mouse) { | 1541 | } else if (ictx->pad_mouse) { |
@@ -1533,36 +1563,55 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1533 | if (press_type < 0) | 1563 | if (press_type < 0) |
1534 | goto not_input_data; | 1564 | goto not_input_data; |
1535 | 1565 | ||
1566 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1536 | if (ictx->kc == KEY_UNKNOWN) | 1567 | if (ictx->kc == KEY_UNKNOWN) |
1537 | goto unknown_key; | 1568 | goto unknown_key; |
1569 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1570 | |||
1571 | if (ktype != IMON_KEY_PANEL) { | ||
1572 | if (press_type == 0) | ||
1573 | ir_keyup(irdev); | ||
1574 | else { | ||
1575 | ir_keydown(rdev, ictx->rc_scancode, ictx->rc_toggle); | ||
1576 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1577 | ictx->last_keycode = ictx->kc; | ||
1578 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1579 | } | ||
1580 | return; | ||
1581 | } | ||
1538 | 1582 | ||
1539 | /* KEY_MUTE repeats from MCE and knob need to be suppressed */ | 1583 | /* Only panel type events left to process now */ |
1540 | if ((ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) | 1584 | spin_lock_irqsave(&ictx->kc_lock, flags); |
1541 | && (buf[7] == 0xee || ktype == IMON_KEY_MCE)) { | 1585 | |
1586 | /* KEY_MUTE repeats from knob need to be suppressed */ | ||
1587 | if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { | ||
1542 | do_gettimeofday(&t); | 1588 | do_gettimeofday(&t); |
1543 | msec = tv2int(&t, &prev_time); | 1589 | msec = tv2int(&t, &prev_time); |
1544 | prev_time = t; | 1590 | prev_time = t; |
1545 | if (msec < idev->rep[REP_DELAY]) | 1591 | if (msec < ictx->idev->rep[REP_DELAY]) { |
1592 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1546 | return; | 1593 | return; |
1594 | } | ||
1547 | } | 1595 | } |
1596 | kc = ictx->kc; | ||
1548 | 1597 | ||
1549 | input_report_key(idev, ictx->kc, press_type); | 1598 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
1550 | input_sync(idev); | ||
1551 | 1599 | ||
1552 | /* panel keys and some remote keys don't generate a release */ | 1600 | input_report_key(ictx->idev, kc, press_type); |
1553 | if (panel_key || norelease) { | 1601 | input_sync(ictx->idev); |
1554 | input_report_key(idev, ictx->kc, 0); | ||
1555 | input_sync(idev); | ||
1556 | } | ||
1557 | 1602 | ||
1558 | ictx->last_keycode = ictx->kc; | 1603 | /* panel keys don't generate a release */ |
1604 | input_report_key(ictx->idev, kc, 0); | ||
1605 | input_sync(ictx->idev); | ||
1606 | |||
1607 | ictx->last_keycode = kc; | ||
1559 | 1608 | ||
1560 | return; | 1609 | return; |
1561 | 1610 | ||
1562 | unknown_key: | 1611 | unknown_key: |
1612 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1563 | dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__, | 1613 | dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__, |
1564 | (panel_key ? be64_to_cpu(panel_key) : | 1614 | (long long)scancode); |
1565 | be32_to_cpu(remote_key))); | ||
1566 | return; | 1615 | return; |
1567 | 1616 | ||
1568 | not_input_data: | 1617 | not_input_data: |
@@ -1653,31 +1702,205 @@ static void usb_rx_callback_intf1(struct urb *urb) | |||
1653 | usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); | 1702 | usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); |
1654 | } | 1703 | } |
1655 | 1704 | ||
1705 | /* | ||
1706 | * The 0x15c2:0xffdc device ID was used for umpteen different imon | ||
1707 | * devices, and all of them constantly spew interrupts, even when there | ||
1708 | * is no actual data to report. However, byte 6 of this buffer looks like | ||
1709 | * its unique across device variants, so we're trying to key off that to | ||
1710 | * figure out which display type (if any) and what IR protocol the device | ||
1711 | * actually supports. These devices have their IR protocol hard-coded into | ||
1712 | * their firmware, they can't be changed on the fly like the newer hardware. | ||
1713 | */ | ||
1714 | static void imon_get_ffdc_type(struct imon_context *ictx) | ||
1715 | { | ||
1716 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; | ||
1717 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; | ||
1718 | u64 allowed_protos = IR_TYPE_OTHER; | ||
1719 | |||
1720 | switch (ffdc_cfg_byte) { | ||
1721 | /* iMON Knob, no display, iMON IR + vol knob */ | ||
1722 | case 0x21: | ||
1723 | dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR"); | ||
1724 | ictx->display_supported = false; | ||
1725 | break; | ||
1726 | /* iMON 2.4G LT (usb stick), no display, iMON RF */ | ||
1727 | case 0x4e: | ||
1728 | dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF"); | ||
1729 | ictx->display_supported = false; | ||
1730 | ictx->rf_device = true; | ||
1731 | break; | ||
1732 | /* iMON VFD, no IR (does have vol knob tho) */ | ||
1733 | case 0x35: | ||
1734 | dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); | ||
1735 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
1736 | break; | ||
1737 | /* iMON VFD, iMON IR */ | ||
1738 | case 0x24: | ||
1739 | case 0x85: | ||
1740 | dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR"); | ||
1741 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
1742 | break; | ||
1743 | /* iMON VFD, MCE IR */ | ||
1744 | case 0x9e: | ||
1745 | dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); | ||
1746 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
1747 | allowed_protos = IR_TYPE_RC6; | ||
1748 | break; | ||
1749 | /* iMON LCD, MCE IR */ | ||
1750 | case 0x9f: | ||
1751 | dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); | ||
1752 | detected_display_type = IMON_DISPLAY_TYPE_LCD; | ||
1753 | allowed_protos = IR_TYPE_RC6; | ||
1754 | break; | ||
1755 | default: | ||
1756 | dev_info(ictx->dev, "Unknown 0xffdc device, " | ||
1757 | "defaulting to VFD and iMON IR"); | ||
1758 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
1759 | break; | ||
1760 | } | ||
1761 | |||
1762 | printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); | ||
1763 | |||
1764 | ictx->display_type = detected_display_type; | ||
1765 | ictx->props->allowed_protos = allowed_protos; | ||
1766 | ictx->ir_type = allowed_protos; | ||
1767 | } | ||
1768 | |||
1769 | static void imon_set_display_type(struct imon_context *ictx) | ||
1770 | { | ||
1771 | u8 configured_display_type = IMON_DISPLAY_TYPE_VFD; | ||
1772 | |||
1773 | /* | ||
1774 | * Try to auto-detect the type of display if the user hasn't set | ||
1775 | * it by hand via the display_type modparam. Default is VFD. | ||
1776 | */ | ||
1777 | |||
1778 | if (display_type == IMON_DISPLAY_TYPE_AUTO) { | ||
1779 | switch (ictx->product) { | ||
1780 | case 0xffdc: | ||
1781 | /* set in imon_get_ffdc_type() */ | ||
1782 | configured_display_type = ictx->display_type; | ||
1783 | break; | ||
1784 | case 0x0034: | ||
1785 | case 0x0035: | ||
1786 | configured_display_type = IMON_DISPLAY_TYPE_VGA; | ||
1787 | break; | ||
1788 | case 0x0038: | ||
1789 | case 0x0039: | ||
1790 | case 0x0045: | ||
1791 | configured_display_type = IMON_DISPLAY_TYPE_LCD; | ||
1792 | break; | ||
1793 | case 0x003c: | ||
1794 | case 0x0041: | ||
1795 | case 0x0042: | ||
1796 | case 0x0043: | ||
1797 | configured_display_type = IMON_DISPLAY_TYPE_NONE; | ||
1798 | ictx->display_supported = false; | ||
1799 | break; | ||
1800 | case 0x0036: | ||
1801 | case 0x0044: | ||
1802 | default: | ||
1803 | configured_display_type = IMON_DISPLAY_TYPE_VFD; | ||
1804 | break; | ||
1805 | } | ||
1806 | } else { | ||
1807 | configured_display_type = display_type; | ||
1808 | if (display_type == IMON_DISPLAY_TYPE_NONE) | ||
1809 | ictx->display_supported = false; | ||
1810 | else | ||
1811 | ictx->display_supported = true; | ||
1812 | dev_info(ictx->dev, "%s: overriding display type to %d via " | ||
1813 | "modparam\n", __func__, display_type); | ||
1814 | } | ||
1815 | |||
1816 | ictx->display_type = configured_display_type; | ||
1817 | } | ||
1818 | |||
1819 | static struct input_dev *imon_init_rdev(struct imon_context *ictx) | ||
1820 | { | ||
1821 | struct input_dev *rdev; | ||
1822 | struct ir_dev_props *props; | ||
1823 | int ret; | ||
1824 | char *ir_codes = NULL; | ||
1825 | const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, | ||
1826 | 0x00, 0x00, 0x00, 0x88 }; | ||
1827 | |||
1828 | rdev = input_allocate_device(); | ||
1829 | props = kzalloc(sizeof(*props), GFP_KERNEL); | ||
1830 | if (!rdev || !props) { | ||
1831 | dev_err(ictx->dev, "remote control dev allocation failed\n"); | ||
1832 | goto out; | ||
1833 | } | ||
1834 | |||
1835 | snprintf(ictx->name_rdev, sizeof(ictx->name_rdev), | ||
1836 | "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product); | ||
1837 | usb_make_path(ictx->usbdev_intf0, ictx->phys_rdev, | ||
1838 | sizeof(ictx->phys_rdev)); | ||
1839 | strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev)); | ||
1840 | |||
1841 | rdev->name = ictx->name_rdev; | ||
1842 | rdev->phys = ictx->phys_rdev; | ||
1843 | usb_to_input_id(ictx->usbdev_intf0, &rdev->id); | ||
1844 | rdev->dev.parent = ictx->dev; | ||
1845 | rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
1846 | input_set_drvdata(rdev, ictx); | ||
1847 | |||
1848 | props->priv = ictx; | ||
1849 | props->driver_type = RC_DRIVER_SCANCODE; | ||
1850 | props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */ | ||
1851 | props->change_protocol = imon_ir_change_protocol; | ||
1852 | ictx->props = props; | ||
1853 | |||
1854 | /* Enable front-panel buttons and/or knobs */ | ||
1855 | memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); | ||
1856 | ret = send_packet(ictx); | ||
1857 | /* Not fatal, but warn about it */ | ||
1858 | if (ret) | ||
1859 | dev_info(ictx->dev, "panel buttons/knobs setup failed\n"); | ||
1860 | |||
1861 | if (ictx->product == 0xffdc) | ||
1862 | imon_get_ffdc_type(ictx); | ||
1863 | |||
1864 | imon_set_display_type(ictx); | ||
1865 | |||
1866 | if (ictx->ir_type == IR_TYPE_RC6) | ||
1867 | ir_codes = RC_MAP_IMON_MCE; | ||
1868 | else | ||
1869 | ir_codes = RC_MAP_IMON_PAD; | ||
1870 | |||
1871 | ret = ir_input_register(rdev, ir_codes, props, MOD_NAME); | ||
1872 | if (ret < 0) { | ||
1873 | dev_err(ictx->dev, "remote input dev register failed\n"); | ||
1874 | goto out; | ||
1875 | } | ||
1876 | |||
1877 | return rdev; | ||
1878 | |||
1879 | out: | ||
1880 | kfree(props); | ||
1881 | input_free_device(rdev); | ||
1882 | return NULL; | ||
1883 | } | ||
1884 | |||
1656 | static struct input_dev *imon_init_idev(struct imon_context *ictx) | 1885 | static struct input_dev *imon_init_idev(struct imon_context *ictx) |
1657 | { | 1886 | { |
1658 | struct input_dev *idev; | 1887 | struct input_dev *idev; |
1659 | struct ir_dev_props *props; | ||
1660 | int ret, i; | 1888 | int ret, i; |
1661 | 1889 | ||
1662 | idev = input_allocate_device(); | 1890 | idev = input_allocate_device(); |
1663 | if (!idev) { | 1891 | if (!idev) { |
1664 | dev_err(ictx->dev, "remote input dev allocation failed\n"); | 1892 | dev_err(ictx->dev, "input dev allocation failed\n"); |
1665 | goto idev_alloc_failed; | 1893 | goto out; |
1666 | } | ||
1667 | |||
1668 | props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); | ||
1669 | if (!props) { | ||
1670 | dev_err(ictx->dev, "remote ir dev props allocation failed\n"); | ||
1671 | goto props_alloc_failed; | ||
1672 | } | 1894 | } |
1673 | 1895 | ||
1674 | snprintf(ictx->name_idev, sizeof(ictx->name_idev), | 1896 | snprintf(ictx->name_idev, sizeof(ictx->name_idev), |
1675 | "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product); | 1897 | "iMON Panel, Knob and Mouse(%04x:%04x)", |
1898 | ictx->vendor, ictx->product); | ||
1676 | idev->name = ictx->name_idev; | 1899 | idev->name = ictx->name_idev; |
1677 | 1900 | ||
1678 | usb_make_path(ictx->usbdev_intf0, ictx->phys_idev, | 1901 | usb_make_path(ictx->usbdev_intf0, ictx->phys_idev, |
1679 | sizeof(ictx->phys_idev)); | 1902 | sizeof(ictx->phys_idev)); |
1680 | strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev)); | 1903 | strlcat(ictx->phys_idev, "/input1", sizeof(ictx->phys_idev)); |
1681 | idev->phys = ictx->phys_idev; | 1904 | idev->phys = ictx->phys_idev; |
1682 | 1905 | ||
1683 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); | 1906 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); |
@@ -1693,30 +1916,20 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) | |||
1693 | __set_bit(kc, idev->keybit); | 1916 | __set_bit(kc, idev->keybit); |
1694 | } | 1917 | } |
1695 | 1918 | ||
1696 | props->priv = ictx; | ||
1697 | props->driver_type = RC_DRIVER_SCANCODE; | ||
1698 | /* IR_TYPE_OTHER maps to iMON PAD remote, IR_TYPE_RC6 to MCE remote */ | ||
1699 | props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; | ||
1700 | props->change_protocol = imon_ir_change_protocol; | ||
1701 | ictx->props = props; | ||
1702 | |||
1703 | usb_to_input_id(ictx->usbdev_intf0, &idev->id); | 1919 | usb_to_input_id(ictx->usbdev_intf0, &idev->id); |
1704 | idev->dev.parent = ictx->dev; | 1920 | idev->dev.parent = ictx->dev; |
1921 | input_set_drvdata(idev, ictx); | ||
1705 | 1922 | ||
1706 | ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME); | 1923 | ret = input_register_device(idev); |
1707 | if (ret < 0) { | 1924 | if (ret < 0) { |
1708 | dev_err(ictx->dev, "remote input dev register failed\n"); | 1925 | dev_err(ictx->dev, "input dev register failed\n"); |
1709 | goto idev_register_failed; | 1926 | goto out; |
1710 | } | 1927 | } |
1711 | 1928 | ||
1712 | return idev; | 1929 | return idev; |
1713 | 1930 | ||
1714 | idev_register_failed: | 1931 | out: |
1715 | kfree(props); | ||
1716 | props_alloc_failed: | ||
1717 | input_free_device(idev); | 1932 | input_free_device(idev); |
1718 | idev_alloc_failed: | ||
1719 | |||
1720 | return NULL; | 1933 | return NULL; |
1721 | } | 1934 | } |
1722 | 1935 | ||
@@ -1738,7 +1951,7 @@ static struct input_dev *imon_init_touch(struct imon_context *ictx) | |||
1738 | 1951 | ||
1739 | usb_make_path(ictx->usbdev_intf1, ictx->phys_touch, | 1952 | usb_make_path(ictx->usbdev_intf1, ictx->phys_touch, |
1740 | sizeof(ictx->phys_touch)); | 1953 | sizeof(ictx->phys_touch)); |
1741 | strlcat(ictx->phys_touch, "/input1", sizeof(ictx->phys_touch)); | 1954 | strlcat(ictx->phys_touch, "/input2", sizeof(ictx->phys_touch)); |
1742 | touch->phys = ictx->phys_touch; | 1955 | touch->phys = ictx->phys_touch; |
1743 | 1956 | ||
1744 | touch->evbit[0] = | 1957 | touch->evbit[0] = |
@@ -1850,7 +2063,7 @@ static bool imon_find_endpoints(struct imon_context *ictx, | |||
1850 | 2063 | ||
1851 | /* Input endpoint is mandatory */ | 2064 | /* Input endpoint is mandatory */ |
1852 | if (!ir_ep_found) | 2065 | if (!ir_ep_found) |
1853 | err("%s: no valid input (IR) endpoint found.", __func__); | 2066 | pr_err("no valid input (IR) endpoint found\n"); |
1854 | 2067 | ||
1855 | ictx->tx_control = tx_control; | 2068 | ictx->tx_control = tx_control; |
1856 | 2069 | ||
@@ -1888,6 +2101,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) | |||
1888 | } | 2101 | } |
1889 | 2102 | ||
1890 | mutex_init(&ictx->lock); | 2103 | mutex_init(&ictx->lock); |
2104 | spin_lock_init(&ictx->kc_lock); | ||
1891 | 2105 | ||
1892 | mutex_lock(&ictx->lock); | 2106 | mutex_lock(&ictx->lock); |
1893 | 2107 | ||
@@ -1913,6 +2127,12 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) | |||
1913 | goto idev_setup_failed; | 2127 | goto idev_setup_failed; |
1914 | } | 2128 | } |
1915 | 2129 | ||
2130 | ictx->rdev = imon_init_rdev(ictx); | ||
2131 | if (!ictx->rdev) { | ||
2132 | dev_err(dev, "%s: rc device setup failed\n", __func__); | ||
2133 | goto rdev_setup_failed; | ||
2134 | } | ||
2135 | |||
1916 | usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, | 2136 | usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, |
1917 | usb_rcvintpipe(ictx->usbdev_intf0, | 2137 | usb_rcvintpipe(ictx->usbdev_intf0, |
1918 | ictx->rx_endpoint_intf0->bEndpointAddress), | 2138 | ictx->rx_endpoint_intf0->bEndpointAddress), |
@@ -1922,15 +2142,16 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) | |||
1922 | 2142 | ||
1923 | ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL); | 2143 | ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL); |
1924 | if (ret) { | 2144 | if (ret) { |
1925 | err("%s: usb_submit_urb failed for intf0 (%d)", | 2145 | pr_err("usb_submit_urb failed for intf0 (%d)\n", ret); |
1926 | __func__, ret); | ||
1927 | goto urb_submit_failed; | 2146 | goto urb_submit_failed; |
1928 | } | 2147 | } |
1929 | 2148 | ||
1930 | return ictx; | 2149 | return ictx; |
1931 | 2150 | ||
1932 | urb_submit_failed: | 2151 | urb_submit_failed: |
1933 | ir_input_unregister(ictx->idev); | 2152 | ir_input_unregister(ictx->rdev); |
2153 | rdev_setup_failed: | ||
2154 | input_unregister_device(ictx->idev); | ||
1934 | idev_setup_failed: | 2155 | idev_setup_failed: |
1935 | find_endpoint_failed: | 2156 | find_endpoint_failed: |
1936 | mutex_unlock(&ictx->lock); | 2157 | mutex_unlock(&ictx->lock); |
@@ -1954,7 +2175,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, | |||
1954 | 2175 | ||
1955 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2176 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); |
1956 | if (!rx_urb) { | 2177 | if (!rx_urb) { |
1957 | err("%s: usb_alloc_urb failed for IR urb", __func__); | 2178 | pr_err("usb_alloc_urb failed for IR urb\n"); |
1958 | goto rx_urb_alloc_failed; | 2179 | goto rx_urb_alloc_failed; |
1959 | } | 2180 | } |
1960 | 2181 | ||
@@ -1992,8 +2213,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, | |||
1992 | ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL); | 2213 | ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL); |
1993 | 2214 | ||
1994 | if (ret) { | 2215 | if (ret) { |
1995 | err("%s: usb_submit_urb failed for intf1 (%d)", | 2216 | pr_err("usb_submit_urb failed for intf1 (%d)\n", ret); |
1996 | __func__, ret); | ||
1997 | goto urb_submit_failed; | 2217 | goto urb_submit_failed; |
1998 | } | 2218 | } |
1999 | 2219 | ||
@@ -2012,116 +2232,6 @@ rx_urb_alloc_failed: | |||
2012 | return NULL; | 2232 | return NULL; |
2013 | } | 2233 | } |
2014 | 2234 | ||
2015 | /* | ||
2016 | * The 0x15c2:0xffdc device ID was used for umpteen different imon | ||
2017 | * devices, and all of them constantly spew interrupts, even when there | ||
2018 | * is no actual data to report. However, byte 6 of this buffer looks like | ||
2019 | * its unique across device variants, so we're trying to key off that to | ||
2020 | * figure out which display type (if any) and what IR protocol the device | ||
2021 | * actually supports. These devices have their IR protocol hard-coded into | ||
2022 | * their firmware, they can't be changed on the fly like the newer hardware. | ||
2023 | */ | ||
2024 | static void imon_get_ffdc_type(struct imon_context *ictx) | ||
2025 | { | ||
2026 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; | ||
2027 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; | ||
2028 | u64 allowed_protos = IR_TYPE_OTHER; | ||
2029 | |||
2030 | switch (ffdc_cfg_byte) { | ||
2031 | /* iMON Knob, no display, iMON IR + vol knob */ | ||
2032 | case 0x21: | ||
2033 | dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR"); | ||
2034 | ictx->display_supported = false; | ||
2035 | break; | ||
2036 | /* iMON 2.4G LT (usb stick), no display, iMON RF */ | ||
2037 | case 0x4e: | ||
2038 | dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF"); | ||
2039 | ictx->display_supported = false; | ||
2040 | ictx->rf_device = true; | ||
2041 | break; | ||
2042 | /* iMON VFD, no IR (does have vol knob tho) */ | ||
2043 | case 0x35: | ||
2044 | dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); | ||
2045 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
2046 | break; | ||
2047 | /* iMON VFD, iMON IR */ | ||
2048 | case 0x24: | ||
2049 | case 0x85: | ||
2050 | dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR"); | ||
2051 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
2052 | break; | ||
2053 | /* iMON LCD, MCE IR */ | ||
2054 | case 0x9e: | ||
2055 | case 0x9f: | ||
2056 | dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); | ||
2057 | detected_display_type = IMON_DISPLAY_TYPE_LCD; | ||
2058 | allowed_protos = IR_TYPE_RC6; | ||
2059 | break; | ||
2060 | default: | ||
2061 | dev_info(ictx->dev, "Unknown 0xffdc device, " | ||
2062 | "defaulting to VFD and iMON IR"); | ||
2063 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | ||
2064 | break; | ||
2065 | } | ||
2066 | |||
2067 | printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); | ||
2068 | |||
2069 | ictx->display_type = detected_display_type; | ||
2070 | ictx->props->allowed_protos = allowed_protos; | ||
2071 | ictx->ir_type = allowed_protos; | ||
2072 | } | ||
2073 | |||
2074 | static void imon_set_display_type(struct imon_context *ictx, | ||
2075 | struct usb_interface *intf) | ||
2076 | { | ||
2077 | u8 configured_display_type = IMON_DISPLAY_TYPE_VFD; | ||
2078 | |||
2079 | /* | ||
2080 | * Try to auto-detect the type of display if the user hasn't set | ||
2081 | * it by hand via the display_type modparam. Default is VFD. | ||
2082 | */ | ||
2083 | |||
2084 | if (display_type == IMON_DISPLAY_TYPE_AUTO) { | ||
2085 | switch (ictx->product) { | ||
2086 | case 0xffdc: | ||
2087 | /* set in imon_get_ffdc_type() */ | ||
2088 | configured_display_type = ictx->display_type; | ||
2089 | break; | ||
2090 | case 0x0034: | ||
2091 | case 0x0035: | ||
2092 | configured_display_type = IMON_DISPLAY_TYPE_VGA; | ||
2093 | break; | ||
2094 | case 0x0038: | ||
2095 | case 0x0039: | ||
2096 | case 0x0045: | ||
2097 | configured_display_type = IMON_DISPLAY_TYPE_LCD; | ||
2098 | break; | ||
2099 | case 0x003c: | ||
2100 | case 0x0041: | ||
2101 | case 0x0042: | ||
2102 | case 0x0043: | ||
2103 | configured_display_type = IMON_DISPLAY_TYPE_NONE; | ||
2104 | ictx->display_supported = false; | ||
2105 | break; | ||
2106 | case 0x0036: | ||
2107 | case 0x0044: | ||
2108 | default: | ||
2109 | configured_display_type = IMON_DISPLAY_TYPE_VFD; | ||
2110 | break; | ||
2111 | } | ||
2112 | } else { | ||
2113 | configured_display_type = display_type; | ||
2114 | if (display_type == IMON_DISPLAY_TYPE_NONE) | ||
2115 | ictx->display_supported = false; | ||
2116 | else | ||
2117 | ictx->display_supported = true; | ||
2118 | dev_info(ictx->dev, "%s: overriding display type to %d via " | ||
2119 | "modparam\n", __func__, display_type); | ||
2120 | } | ||
2121 | |||
2122 | ictx->display_type = configured_display_type; | ||
2123 | } | ||
2124 | |||
2125 | static void imon_init_display(struct imon_context *ictx, | 2235 | static void imon_init_display(struct imon_context *ictx, |
2126 | struct usb_interface *intf) | 2236 | struct usb_interface *intf) |
2127 | { | 2237 | { |
@@ -2130,8 +2240,7 @@ static void imon_init_display(struct imon_context *ictx, | |||
2130 | dev_dbg(ictx->dev, "Registering iMON display with sysfs\n"); | 2240 | dev_dbg(ictx->dev, "Registering iMON display with sysfs\n"); |
2131 | 2241 | ||
2132 | /* set up sysfs entry for built-in clock */ | 2242 | /* set up sysfs entry for built-in clock */ |
2133 | ret = sysfs_create_group(&intf->dev.kobj, | 2243 | ret = sysfs_create_group(&intf->dev.kobj, &imon_display_attr_group); |
2134 | &imon_display_attribute_group); | ||
2135 | if (ret) | 2244 | if (ret) |
2136 | dev_err(ictx->dev, "Could not create display sysfs " | 2245 | dev_err(ictx->dev, "Could not create display sysfs " |
2137 | "entries(%d)", ret); | 2246 | "entries(%d)", ret); |
@@ -2162,8 +2271,6 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2162 | struct imon_context *ictx = NULL; | 2271 | struct imon_context *ictx = NULL; |
2163 | struct imon_context *first_if_ctx = NULL; | 2272 | struct imon_context *first_if_ctx = NULL; |
2164 | u16 vendor, product; | 2273 | u16 vendor, product; |
2165 | const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, | ||
2166 | 0x00, 0x00, 0x00, 0x88 }; | ||
2167 | 2274 | ||
2168 | code_length = BUF_CHUNK_SIZE * 8; | 2275 | code_length = BUF_CHUNK_SIZE * 8; |
2169 | 2276 | ||
@@ -2185,7 +2292,7 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2185 | if (ifnum == 0) { | 2292 | if (ifnum == 0) { |
2186 | ictx = imon_init_intf0(interface); | 2293 | ictx = imon_init_intf0(interface); |
2187 | if (!ictx) { | 2294 | if (!ictx) { |
2188 | err("%s: failed to initialize context!\n", __func__); | 2295 | pr_err("failed to initialize context!\n"); |
2189 | ret = -ENODEV; | 2296 | ret = -ENODEV; |
2190 | goto fail; | 2297 | goto fail; |
2191 | } | 2298 | } |
@@ -2194,7 +2301,7 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2194 | /* this is the secondary interface on the device */ | 2301 | /* this is the secondary interface on the device */ |
2195 | ictx = imon_init_intf1(interface, first_if_ctx); | 2302 | ictx = imon_init_intf1(interface, first_if_ctx); |
2196 | if (!ictx) { | 2303 | if (!ictx) { |
2197 | err("%s: failed to attach to context!\n", __func__); | 2304 | pr_err("failed to attach to context!\n"); |
2198 | ret = -ENODEV; | 2305 | ret = -ENODEV; |
2199 | goto fail; | 2306 | goto fail; |
2200 | } | 2307 | } |
@@ -2204,39 +2311,18 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2204 | usb_set_intfdata(interface, ictx); | 2311 | usb_set_intfdata(interface, ictx); |
2205 | 2312 | ||
2206 | if (ifnum == 0) { | 2313 | if (ifnum == 0) { |
2207 | /* Enable front-panel buttons and/or knobs */ | ||
2208 | memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); | ||
2209 | ret = send_packet(ictx); | ||
2210 | /* Not fatal, but warn about it */ | ||
2211 | if (ret) | ||
2212 | dev_info(dev, "failed to enable panel buttons " | ||
2213 | "and/or knobs\n"); | ||
2214 | |||
2215 | if (product == 0xffdc) | ||
2216 | imon_get_ffdc_type(ictx); | ||
2217 | |||
2218 | imon_set_display_type(ictx, interface); | ||
2219 | |||
2220 | if (product == 0xffdc && ictx->rf_device) { | 2314 | if (product == 0xffdc && ictx->rf_device) { |
2221 | sysfs_err = sysfs_create_group(&interface->dev.kobj, | 2315 | sysfs_err = sysfs_create_group(&interface->dev.kobj, |
2222 | &imon_rf_attribute_group); | 2316 | &imon_rf_attr_group); |
2223 | if (sysfs_err) | 2317 | if (sysfs_err) |
2224 | err("%s: Could not create RF sysfs entries(%d)", | 2318 | pr_err("Could not create RF sysfs entries(%d)\n", |
2225 | __func__, sysfs_err); | 2319 | sysfs_err); |
2226 | } | 2320 | } |
2227 | 2321 | ||
2228 | if (ictx->display_supported) | 2322 | if (ictx->display_supported) |
2229 | imon_init_display(ictx, interface); | 2323 | imon_init_display(ictx, interface); |
2230 | } | 2324 | } |
2231 | 2325 | ||
2232 | /* set IR protocol/remote type */ | ||
2233 | ret = imon_ir_change_protocol(ictx, ictx->ir_type); | ||
2234 | if (ret) { | ||
2235 | dev_warn(dev, "%s: failed to set IR protocol, falling back " | ||
2236 | "to standard iMON protocol mode\n", __func__); | ||
2237 | ictx->ir_type = IR_TYPE_OTHER; | ||
2238 | } | ||
2239 | |||
2240 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " | 2326 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " |
2241 | "usb<%d:%d> initialized\n", vendor, product, ifnum, | 2327 | "usb<%d:%d> initialized\n", vendor, product, ifnum, |
2242 | usbdev->bus->busnum, usbdev->devnum); | 2328 | usbdev->bus->busnum, usbdev->devnum); |
@@ -2275,10 +2361,8 @@ static void __devexit imon_disconnect(struct usb_interface *interface) | |||
2275 | * sysfs_remove_group is safe to call even if sysfs_create_group | 2361 | * sysfs_remove_group is safe to call even if sysfs_create_group |
2276 | * hasn't been called | 2362 | * hasn't been called |
2277 | */ | 2363 | */ |
2278 | sysfs_remove_group(&interface->dev.kobj, | 2364 | sysfs_remove_group(&interface->dev.kobj, &imon_display_attr_group); |
2279 | &imon_display_attribute_group); | 2365 | sysfs_remove_group(&interface->dev.kobj, &imon_rf_attr_group); |
2280 | sysfs_remove_group(&interface->dev.kobj, | ||
2281 | &imon_rf_attribute_group); | ||
2282 | 2366 | ||
2283 | usb_set_intfdata(interface, NULL); | 2367 | usb_set_intfdata(interface, NULL); |
2284 | 2368 | ||
@@ -2291,7 +2375,8 @@ static void __devexit imon_disconnect(struct usb_interface *interface) | |||
2291 | if (ifnum == 0) { | 2375 | if (ifnum == 0) { |
2292 | ictx->dev_present_intf0 = false; | 2376 | ictx->dev_present_intf0 = false; |
2293 | usb_kill_urb(ictx->rx_urb_intf0); | 2377 | usb_kill_urb(ictx->rx_urb_intf0); |
2294 | ir_input_unregister(ictx->idev); | 2378 | input_unregister_device(ictx->idev); |
2379 | ir_input_unregister(ictx->rdev); | ||
2295 | if (ictx->display_supported) { | 2380 | if (ictx->display_supported) { |
2296 | if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) | 2381 | if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) |
2297 | usb_deregister_dev(interface, &imon_lcd_class); | 2382 | usb_deregister_dev(interface, &imon_lcd_class); |
@@ -2311,11 +2396,8 @@ static void __devexit imon_disconnect(struct usb_interface *interface) | |||
2311 | mutex_unlock(&ictx->lock); | 2396 | mutex_unlock(&ictx->lock); |
2312 | if (!ictx->display_isopen) | 2397 | if (!ictx->display_isopen) |
2313 | free_imon_context(ictx); | 2398 | free_imon_context(ictx); |
2314 | } else { | 2399 | } else |
2315 | if (ictx->ir_type == IR_TYPE_RC6) | ||
2316 | del_timer_sync(&ictx->itimer); | ||
2317 | mutex_unlock(&ictx->lock); | 2400 | mutex_unlock(&ictx->lock); |
2318 | } | ||
2319 | 2401 | ||
2320 | mutex_unlock(&driver_lock); | 2402 | mutex_unlock(&driver_lock); |
2321 | 2403 | ||
@@ -2372,7 +2454,7 @@ static int __init imon_init(void) | |||
2372 | 2454 | ||
2373 | rc = usb_register(&imon_driver); | 2455 | rc = usb_register(&imon_driver); |
2374 | if (rc) { | 2456 | if (rc) { |
2375 | err("%s: usb register failed(%d)", __func__, rc); | 2457 | pr_err("usb register failed(%d)\n", rc); |
2376 | rc = -ENODEV; | 2458 | rc = -ENODEV; |
2377 | } | 2459 | } |
2378 | 2460 | ||
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index a85a8c7c905..81c936bd793 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define _IR_RAW_EVENT | 17 | #define _IR_RAW_EVENT |
18 | 18 | ||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/spinlock.h> | ||
20 | #include <media/ir-core.h> | 21 | #include <media/ir-core.h> |
21 | 22 | ||
22 | struct ir_raw_handler { | 23 | struct ir_raw_handler { |
@@ -33,6 +34,7 @@ struct ir_raw_handler { | |||
33 | struct ir_raw_event_ctrl { | 34 | struct ir_raw_event_ctrl { |
34 | struct list_head list; /* to keep track of raw clients */ | 35 | struct list_head list; /* to keep track of raw clients */ |
35 | struct task_struct *thread; | 36 | struct task_struct *thread; |
37 | spinlock_t lock; | ||
36 | struct kfifo kfifo; /* fifo for the pulse/space durations */ | 38 | struct kfifo kfifo; /* fifo for the pulse/space durations */ |
37 | ktime_t last_event; /* when last event occurred */ | 39 | ktime_t last_event; /* when last event occurred */ |
38 | enum raw_event_type last_type; /* last event type */ | 40 | enum raw_event_type last_type; /* last event type */ |
@@ -76,10 +78,22 @@ struct ir_raw_event_ctrl { | |||
76 | bool first; | 78 | bool first; |
77 | bool toggle; | 79 | bool toggle; |
78 | } jvc; | 80 | } jvc; |
81 | struct rc5_sz_dec { | ||
82 | int state; | ||
83 | u32 bits; | ||
84 | unsigned count; | ||
85 | unsigned wanted_bits; | ||
86 | } rc5_sz; | ||
79 | struct lirc_codec { | 87 | struct lirc_codec { |
80 | struct ir_input_dev *ir_dev; | 88 | struct ir_input_dev *ir_dev; |
81 | struct lirc_driver *drv; | 89 | struct lirc_driver *drv; |
82 | int carrier_low; | 90 | int carrier_low; |
91 | |||
92 | ktime_t gap_start; | ||
93 | u64 gap_duration; | ||
94 | bool gap; | ||
95 | bool send_timeout_reports; | ||
96 | |||
83 | } lirc; | 97 | } lirc; |
84 | }; | 98 | }; |
85 | 99 | ||
@@ -107,13 +121,19 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) | |||
107 | ev->duration -= duration; | 121 | ev->duration -= duration; |
108 | } | 122 | } |
109 | 123 | ||
124 | /* Returns true if event is normal pulse/space event */ | ||
125 | static inline bool is_timing_event(struct ir_raw_event ev) | ||
126 | { | ||
127 | return !ev.carrier_report && !ev.reset; | ||
128 | } | ||
129 | |||
110 | #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) | 130 | #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) |
111 | #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") | 131 | #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") |
112 | #define IS_RESET(ev) (ev.duration == 0) | ||
113 | /* | 132 | /* |
114 | * Routines from ir-sysfs.c - Meant to be called only internally inside | 133 | * Routines from ir-sysfs.c - Meant to be called only internally inside |
115 | * ir-core | 134 | * ir-core |
116 | */ | 135 | */ |
136 | int ir_register_input(struct input_dev *input_dev); | ||
117 | 137 | ||
118 | int ir_register_class(struct input_dev *input_dev); | 138 | int ir_register_class(struct input_dev *input_dev); |
119 | void ir_unregister_class(struct input_dev *input_dev); | 139 | void ir_unregister_class(struct input_dev *input_dev); |
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c index 77a89c4de01..63dca6e5458 100644 --- a/drivers/media/IR/ir-jvc-decoder.c +++ b/drivers/media/IR/ir-jvc-decoder.c | |||
@@ -50,8 +50,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
50 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) | 50 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) |
51 | return 0; | 51 | return 0; |
52 | 52 | ||
53 | if (IS_RESET(ev)) { | 53 | if (!is_timing_event(ev)) { |
54 | data->state = STATE_INACTIVE; | 54 | if (ev.reset) |
55 | data->state = STATE_INACTIVE; | ||
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
57 | 58 | ||
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index c06b4d50a3d..9186b45132e 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -435,7 +435,7 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); | |||
435 | * This routine is used to signal that a key has been released on the | 435 | * This routine is used to signal that a key has been released on the |
436 | * remote control. It reports a keyup input event via input_report_key(). | 436 | * remote control. It reports a keyup input event via input_report_key(). |
437 | */ | 437 | */ |
438 | static void ir_keyup(struct ir_input_dev *ir) | 438 | void ir_keyup(struct ir_input_dev *ir) |
439 | { | 439 | { |
440 | if (!ir->keypressed) | 440 | if (!ir->keypressed) |
441 | return; | 441 | return; |
@@ -445,6 +445,7 @@ static void ir_keyup(struct ir_input_dev *ir) | |||
445 | input_sync(ir->input_dev); | 445 | input_sync(ir->input_dev); |
446 | ir->keypressed = false; | 446 | ir->keypressed = false; |
447 | } | 447 | } |
448 | EXPORT_SYMBOL_GPL(ir_keyup); | ||
448 | 449 | ||
449 | /** | 450 | /** |
450 | * ir_timer_keyup() - generates a keyup event after a timeout | 451 | * ir_timer_keyup() - generates a keyup event after a timeout |
@@ -640,6 +641,10 @@ int __ir_input_register(struct input_dev *input_dev, | |||
640 | goto out_event; | 641 | goto out_event; |
641 | } | 642 | } |
642 | 643 | ||
644 | rc = ir_register_input(input_dev); | ||
645 | if (rc < 0) | ||
646 | goto out_event; | ||
647 | |||
643 | IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", | 648 | IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", |
644 | driver_name, rc_tab->name, | 649 | driver_name, rc_tab->name, |
645 | (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? | 650 | (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? |
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 1983cd3f399..9fc0db9d344 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c | |||
@@ -32,6 +32,7 @@ | |||
32 | static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 32 | static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
33 | { | 33 | { |
34 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 34 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
35 | struct lirc_codec *lirc = &ir_dev->raw->lirc; | ||
35 | int sample; | 36 | int sample; |
36 | 37 | ||
37 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) | 38 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) |
@@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
40 | if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) | 41 | if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) |
41 | return -EINVAL; | 42 | return -EINVAL; |
42 | 43 | ||
43 | if (IS_RESET(ev)) | 44 | /* Packet start */ |
45 | if (ev.reset) | ||
44 | return 0; | 46 | return 0; |
45 | 47 | ||
46 | IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", | 48 | /* Carrier reports */ |
47 | TO_US(ev.duration), TO_STR(ev.pulse)); | 49 | if (ev.carrier_report) { |
50 | sample = LIRC_FREQUENCY(ev.carrier); | ||
51 | |||
52 | /* Packet end */ | ||
53 | } else if (ev.timeout) { | ||
54 | |||
55 | if (lirc->gap) | ||
56 | return 0; | ||
57 | |||
58 | lirc->gap_start = ktime_get(); | ||
59 | lirc->gap = true; | ||
60 | lirc->gap_duration = ev.duration; | ||
61 | |||
62 | if (!lirc->send_timeout_reports) | ||
63 | return 0; | ||
64 | |||
65 | sample = LIRC_TIMEOUT(ev.duration / 1000); | ||
48 | 66 | ||
49 | sample = ev.duration / 1000; | 67 | /* Normal sample */ |
50 | if (ev.pulse) | 68 | } else { |
51 | sample |= PULSE_BIT; | 69 | |
70 | if (lirc->gap) { | ||
71 | int gap_sample; | ||
72 | |||
73 | lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), | ||
74 | lirc->gap_start)); | ||
75 | |||
76 | /* Convert to ms and cap by LIRC_VALUE_MASK */ | ||
77 | do_div(lirc->gap_duration, 1000); | ||
78 | lirc->gap_duration = min(lirc->gap_duration, | ||
79 | (u64)LIRC_VALUE_MASK); | ||
80 | |||
81 | gap_sample = LIRC_SPACE(lirc->gap_duration); | ||
82 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, | ||
83 | (unsigned char *) &gap_sample); | ||
84 | lirc->gap = false; | ||
85 | } | ||
86 | |||
87 | sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : | ||
88 | LIRC_SPACE(ev.duration / 1000); | ||
89 | } | ||
52 | 90 | ||
53 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, | 91 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, |
54 | (unsigned char *) &sample); | 92 | (unsigned char *) &sample); |
55 | wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); | 93 | wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); |
56 | 94 | ||
57 | |||
58 | return 0; | 95 | return 0; |
59 | } | 96 | } |
60 | 97 | ||
@@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
102 | struct ir_input_dev *ir_dev; | 139 | struct ir_input_dev *ir_dev; |
103 | int ret = 0; | 140 | int ret = 0; |
104 | void *drv_data; | 141 | void *drv_data; |
105 | unsigned long val = 0; | 142 | __u32 val = 0, tmp; |
106 | 143 | ||
107 | lirc = lirc_get_pdata(filep); | 144 | lirc = lirc_get_pdata(filep); |
108 | if (!lirc) | 145 | if (!lirc) |
@@ -115,7 +152,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
115 | drv_data = ir_dev->props->priv; | 152 | drv_data = ir_dev->props->priv; |
116 | 153 | ||
117 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 154 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
118 | ret = get_user(val, (unsigned long *)arg); | 155 | ret = get_user(val, (__u32 *)arg); |
119 | if (ret) | 156 | if (ret) |
120 | return ret; | 157 | return ret; |
121 | } | 158 | } |
@@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
130 | case LIRC_SET_SEND_MODE: | 167 | case LIRC_SET_SEND_MODE: |
131 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) | 168 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) |
132 | return -EINVAL; | 169 | return -EINVAL; |
133 | break; | 170 | return 0; |
134 | 171 | ||
135 | /* TX settings */ | 172 | /* TX settings */ |
136 | case LIRC_SET_TRANSMITTER_MASK: | 173 | case LIRC_SET_TRANSMITTER_MASK: |
137 | if (ir_dev->props->s_tx_mask) | 174 | if (!ir_dev->props->s_tx_mask) |
138 | ret = ir_dev->props->s_tx_mask(drv_data, (u32)val); | ||
139 | else | ||
140 | return -EINVAL; | 175 | return -EINVAL; |
141 | break; | 176 | |
177 | return ir_dev->props->s_tx_mask(drv_data, val); | ||
142 | 178 | ||
143 | case LIRC_SET_SEND_CARRIER: | 179 | case LIRC_SET_SEND_CARRIER: |
144 | if (ir_dev->props->s_tx_carrier) | 180 | if (!ir_dev->props->s_tx_carrier) |
145 | ir_dev->props->s_tx_carrier(drv_data, (u32)val); | ||
146 | else | ||
147 | return -EINVAL; | 181 | return -EINVAL; |
148 | break; | 182 | |
183 | return ir_dev->props->s_tx_carrier(drv_data, val); | ||
149 | 184 | ||
150 | case LIRC_SET_SEND_DUTY_CYCLE: | 185 | case LIRC_SET_SEND_DUTY_CYCLE: |
151 | if (!ir_dev->props->s_tx_duty_cycle) | 186 | if (!ir_dev->props->s_tx_duty_cycle) |
@@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
154 | if (val <= 0 || val >= 100) | 189 | if (val <= 0 || val >= 100) |
155 | return -EINVAL; | 190 | return -EINVAL; |
156 | 191 | ||
157 | ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val); | 192 | return ir_dev->props->s_tx_duty_cycle(drv_data, val); |
158 | break; | ||
159 | 193 | ||
160 | /* RX settings */ | 194 | /* RX settings */ |
161 | case LIRC_SET_REC_CARRIER: | 195 | case LIRC_SET_REC_CARRIER: |
162 | if (ir_dev->props->s_rx_carrier_range) | 196 | if (!ir_dev->props->s_rx_carrier_range) |
163 | ret = ir_dev->props->s_rx_carrier_range( | ||
164 | ir_dev->props->priv, | ||
165 | ir_dev->raw->lirc.carrier_low, val); | ||
166 | else | ||
167 | return -ENOSYS; | 197 | return -ENOSYS; |
168 | 198 | ||
169 | if (!ret) | 199 | if (val <= 0) |
170 | ir_dev->raw->lirc.carrier_low = 0; | 200 | return -EINVAL; |
171 | break; | 201 | |
202 | return ir_dev->props->s_rx_carrier_range(drv_data, | ||
203 | ir_dev->raw->lirc.carrier_low, val); | ||
172 | 204 | ||
173 | case LIRC_SET_REC_CARRIER_RANGE: | 205 | case LIRC_SET_REC_CARRIER_RANGE: |
174 | if (val >= 0) | 206 | if (val <= 0) |
175 | ir_dev->raw->lirc.carrier_low = val; | 207 | return -EINVAL; |
176 | break; | ||
177 | 208 | ||
209 | ir_dev->raw->lirc.carrier_low = val; | ||
210 | return 0; | ||
178 | 211 | ||
179 | case LIRC_GET_REC_RESOLUTION: | 212 | case LIRC_GET_REC_RESOLUTION: |
180 | val = ir_dev->props->rx_resolution; | 213 | val = ir_dev->props->rx_resolution; |
181 | break; | 214 | break; |
182 | 215 | ||
183 | case LIRC_SET_WIDEBAND_RECEIVER: | 216 | case LIRC_SET_WIDEBAND_RECEIVER: |
184 | if (ir_dev->props->s_learning_mode) | 217 | if (!ir_dev->props->s_learning_mode) |
185 | return ir_dev->props->s_learning_mode( | ||
186 | ir_dev->props->priv, !!val); | ||
187 | else | ||
188 | return -ENOSYS; | 218 | return -ENOSYS; |
189 | 219 | ||
220 | return ir_dev->props->s_learning_mode(drv_data, !!val); | ||
221 | |||
222 | case LIRC_SET_MEASURE_CARRIER_MODE: | ||
223 | if (!ir_dev->props->s_carrier_report) | ||
224 | return -ENOSYS; | ||
225 | |||
226 | return ir_dev->props->s_carrier_report(drv_data, !!val); | ||
227 | |||
190 | /* Generic timeout support */ | 228 | /* Generic timeout support */ |
191 | case LIRC_GET_MIN_TIMEOUT: | 229 | case LIRC_GET_MIN_TIMEOUT: |
192 | if (!ir_dev->props->max_timeout) | 230 | if (!ir_dev->props->max_timeout) |
@@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
201 | break; | 239 | break; |
202 | 240 | ||
203 | case LIRC_SET_REC_TIMEOUT: | 241 | case LIRC_SET_REC_TIMEOUT: |
204 | if (val < ir_dev->props->min_timeout || | 242 | if (!ir_dev->props->max_timeout) |
205 | val > ir_dev->props->max_timeout) | 243 | return -ENOSYS; |
206 | return -EINVAL; | 244 | |
207 | ir_dev->props->timeout = val * 1000; | 245 | tmp = val * 1000; |
246 | |||
247 | if (tmp < ir_dev->props->min_timeout || | ||
248 | tmp > ir_dev->props->max_timeout) | ||
249 | return -EINVAL; | ||
250 | |||
251 | ir_dev->props->timeout = tmp; | ||
252 | break; | ||
253 | |||
254 | case LIRC_SET_REC_TIMEOUT_REPORTS: | ||
255 | lirc->send_timeout_reports = !!val; | ||
208 | break; | 256 | break; |
209 | 257 | ||
210 | default: | 258 | default: |
@@ -212,7 +260,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
212 | } | 260 | } |
213 | 261 | ||
214 | if (_IOC_DIR(cmd) & _IOC_READ) | 262 | if (_IOC_DIR(cmd) & _IOC_READ) |
215 | ret = put_user(val, (unsigned long *)arg); | 263 | ret = put_user(val, (__u32 *)arg); |
216 | 264 | ||
217 | return ret; | 265 | return ret; |
218 | } | 266 | } |
@@ -231,6 +279,9 @@ static struct file_operations lirc_fops = { | |||
231 | .owner = THIS_MODULE, | 279 | .owner = THIS_MODULE, |
232 | .write = ir_lirc_transmit_ir, | 280 | .write = ir_lirc_transmit_ir, |
233 | .unlocked_ioctl = ir_lirc_ioctl, | 281 | .unlocked_ioctl = ir_lirc_ioctl, |
282 | #ifdef CONFIG_COMPAT | ||
283 | .compat_ioctl = ir_lirc_ioctl, | ||
284 | #endif | ||
234 | .read = lirc_dev_fop_read, | 285 | .read = lirc_dev_fop_read, |
235 | .poll = lirc_dev_fop_poll, | 286 | .poll = lirc_dev_fop_poll, |
236 | .open = lirc_dev_fop_open, | 287 | .open = lirc_dev_fop_open, |
@@ -278,6 +329,10 @@ static int ir_lirc_register(struct input_dev *input_dev) | |||
278 | if (ir_dev->props->s_learning_mode) | 329 | if (ir_dev->props->s_learning_mode) |
279 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; | 330 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; |
280 | 331 | ||
332 | if (ir_dev->props->s_carrier_report) | ||
333 | features |= LIRC_CAN_MEASURE_CARRIER; | ||
334 | |||
335 | |||
281 | if (ir_dev->props->max_timeout) | 336 | if (ir_dev->props->max_timeout) |
282 | features |= LIRC_CAN_SET_REC_TIMEOUT; | 337 | features |= LIRC_CAN_SET_REC_TIMEOUT; |
283 | 338 | ||
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index d597421d654..70993f79c8a 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -54,8 +54,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
54 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) | 54 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) |
55 | return 0; | 55 | return 0; |
56 | 56 | ||
57 | if (IS_RESET(ev)) { | 57 | if (!is_timing_event(ev)) { |
58 | data->state = STATE_INACTIVE; | 58 | if (ev.reset) |
59 | data->state = STATE_INACTIVE; | ||
59 | return 0; | 60 | return 0; |
60 | } | 61 | } |
61 | 62 | ||
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 8e0e1b1f8c8..a06a07e4e0b 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -39,22 +39,34 @@ static int ir_raw_event_thread(void *data) | |||
39 | struct ir_raw_event ev; | 39 | struct ir_raw_event ev; |
40 | struct ir_raw_handler *handler; | 40 | struct ir_raw_handler *handler; |
41 | struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; | 41 | struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; |
42 | int retval; | ||
42 | 43 | ||
43 | while (!kthread_should_stop()) { | 44 | while (!kthread_should_stop()) { |
44 | try_to_freeze(); | ||
45 | 45 | ||
46 | mutex_lock(&ir_raw_handler_lock); | 46 | spin_lock_irq(&raw->lock); |
47 | retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); | ||
48 | |||
49 | if (!retval) { | ||
50 | set_current_state(TASK_INTERRUPTIBLE); | ||
51 | |||
52 | if (kthread_should_stop()) | ||
53 | set_current_state(TASK_RUNNING); | ||
47 | 54 | ||
48 | while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) { | 55 | spin_unlock_irq(&raw->lock); |
49 | list_for_each_entry(handler, &ir_raw_handler_list, list) | 56 | schedule(); |
50 | handler->decode(raw->input_dev, ev); | 57 | continue; |
51 | raw->prev_ev = ev; | ||
52 | } | 58 | } |
53 | 59 | ||
54 | mutex_unlock(&ir_raw_handler_lock); | 60 | spin_unlock_irq(&raw->lock); |
61 | |||
55 | 62 | ||
56 | set_current_state(TASK_INTERRUPTIBLE); | 63 | BUG_ON(retval != sizeof(ev)); |
57 | schedule(); | 64 | |
65 | mutex_lock(&ir_raw_handler_lock); | ||
66 | list_for_each_entry(handler, &ir_raw_handler_list, list) | ||
67 | handler->decode(raw->input_dev, ev); | ||
68 | raw->prev_ev = ev; | ||
69 | mutex_unlock(&ir_raw_handler_lock); | ||
58 | } | 70 | } |
59 | 71 | ||
60 | return 0; | 72 | return 0; |
@@ -77,7 +89,7 @@ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) | |||
77 | if (!ir->raw) | 89 | if (!ir->raw) |
78 | return -EINVAL; | 90 | return -EINVAL; |
79 | 91 | ||
80 | IR_dprintk(2, "sample: (05%dus %s)\n", | 92 | IR_dprintk(2, "sample: (%05dus %s)\n", |
81 | TO_US(ev->duration), TO_STR(ev->pulse)); | 93 | TO_US(ev->duration), TO_STR(ev->pulse)); |
82 | 94 | ||
83 | if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) | 95 | if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) |
@@ -162,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev, | |||
162 | if (ir->idle && !ev->pulse) | 174 | if (ir->idle && !ev->pulse) |
163 | return 0; | 175 | return 0; |
164 | else if (ir->idle) | 176 | else if (ir->idle) |
165 | ir_raw_event_set_idle(input_dev, 0); | 177 | ir_raw_event_set_idle(input_dev, false); |
166 | 178 | ||
167 | if (!raw->this_ev.duration) { | 179 | if (!raw->this_ev.duration) { |
168 | raw->this_ev = *ev; | 180 | raw->this_ev = *ev; |
@@ -175,48 +187,35 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev, | |||
175 | 187 | ||
176 | /* Enter idle mode if nessesary */ | 188 | /* Enter idle mode if nessesary */ |
177 | if (!ev->pulse && ir->props->timeout && | 189 | if (!ev->pulse && ir->props->timeout && |
178 | raw->this_ev.duration >= ir->props->timeout) | 190 | raw->this_ev.duration >= ir->props->timeout) { |
179 | ir_raw_event_set_idle(input_dev, 1); | 191 | ir_raw_event_set_idle(input_dev, true); |
192 | } | ||
180 | return 0; | 193 | return 0; |
181 | } | 194 | } |
182 | EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); | 195 | EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); |
183 | 196 | ||
184 | void ir_raw_event_set_idle(struct input_dev *input_dev, int idle) | 197 | /** |
198 | * ir_raw_event_set_idle() - hint the ir core if device is receiving | ||
199 | * IR data or not | ||
200 | * @input_dev: the struct input_dev device descriptor | ||
201 | * @idle: the hint value | ||
202 | */ | ||
203 | void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) | ||
185 | { | 204 | { |
186 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | 205 | struct ir_input_dev *ir = input_get_drvdata(input_dev); |
187 | struct ir_raw_event_ctrl *raw = ir->raw; | 206 | struct ir_raw_event_ctrl *raw = ir->raw; |
188 | ktime_t now; | ||
189 | u64 delta; | ||
190 | 207 | ||
191 | if (!ir->props) | 208 | if (!ir->props || !ir->raw) |
192 | return; | 209 | return; |
193 | 210 | ||
194 | if (!ir->raw) | 211 | IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); |
195 | goto out; | ||
196 | 212 | ||
197 | if (idle) { | 213 | if (idle) { |
198 | IR_dprintk(2, "enter idle mode\n"); | 214 | raw->this_ev.timeout = true; |
199 | raw->last_event = ktime_get(); | ||
200 | } else { | ||
201 | IR_dprintk(2, "exit idle mode\n"); | ||
202 | |||
203 | now = ktime_get(); | ||
204 | delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); | ||
205 | |||
206 | WARN_ON(raw->this_ev.pulse); | ||
207 | |||
208 | raw->this_ev.duration = | ||
209 | min(raw->this_ev.duration + delta, | ||
210 | (u64)IR_MAX_DURATION); | ||
211 | |||
212 | ir_raw_event_store(input_dev, &raw->this_ev); | 215 | ir_raw_event_store(input_dev, &raw->this_ev); |
213 | 216 | init_ir_raw_event(&raw->this_ev); | |
214 | if (raw->this_ev.duration == IR_MAX_DURATION) | ||
215 | ir_raw_event_reset(input_dev); | ||
216 | |||
217 | raw->this_ev.duration = 0; | ||
218 | } | 217 | } |
219 | out: | 218 | |
220 | if (ir->props->s_idle) | 219 | if (ir->props->s_idle) |
221 | ir->props->s_idle(ir->props->priv, idle); | 220 | ir->props->s_idle(ir->props->priv, idle); |
222 | ir->idle = idle; | 221 | ir->idle = idle; |
@@ -232,11 +231,14 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); | |||
232 | void ir_raw_event_handle(struct input_dev *input_dev) | 231 | void ir_raw_event_handle(struct input_dev *input_dev) |
233 | { | 232 | { |
234 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | 233 | struct ir_input_dev *ir = input_get_drvdata(input_dev); |
234 | unsigned long flags; | ||
235 | 235 | ||
236 | if (!ir->raw) | 236 | if (!ir->raw) |
237 | return; | 237 | return; |
238 | 238 | ||
239 | spin_lock_irqsave(&ir->raw->lock, flags); | ||
239 | wake_up_process(ir->raw->thread); | 240 | wake_up_process(ir->raw->thread); |
241 | spin_unlock_irqrestore(&ir->raw->lock, flags); | ||
240 | } | 242 | } |
241 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); | 243 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); |
242 | 244 | ||
@@ -275,6 +277,7 @@ int ir_raw_event_register(struct input_dev *input_dev) | |||
275 | return rc; | 277 | return rc; |
276 | } | 278 | } |
277 | 279 | ||
280 | spin_lock_init(&ir->raw->lock); | ||
278 | ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, | 281 | ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, |
279 | "rc%u", (unsigned int)ir->devno); | 282 | "rc%u", (unsigned int)ir->devno); |
280 | 283 | ||
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c index df4770d978a..572ed4ca8c6 100644 --- a/drivers/media/IR/ir-rc5-decoder.c +++ b/drivers/media/IR/ir-rc5-decoder.c | |||
@@ -55,8 +55,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
55 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) | 55 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | if (IS_RESET(ev)) { | 58 | if (!is_timing_event(ev)) { |
59 | data->state = STATE_INACTIVE; | 59 | if (ev.reset) |
60 | data->state = STATE_INACTIVE; | ||
60 | return 0; | 61 | return 0; |
61 | } | 62 | } |
62 | 63 | ||
diff --git a/drivers/media/IR/ir-rc5-sz-decoder.c b/drivers/media/IR/ir-rc5-sz-decoder.c new file mode 100644 index 00000000000..7c413501a3f --- /dev/null +++ b/drivers/media/IR/ir-rc5-sz-decoder.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol | ||
2 | * | ||
3 | * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | ||
4 | * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * This code handles the 15 bit RC5-ish protocol used by the Streamzap | ||
18 | * PC Remote. | ||
19 | * It considers a carrier of 36 kHz, with a total of 15 bits, where | ||
20 | * the first two bits are start bits, and a third one is a filing bit | ||
21 | */ | ||
22 | |||
23 | #include "ir-core-priv.h" | ||
24 | |||
25 | #define RC5_SZ_NBITS 15 | ||
26 | #define RC5_UNIT 888888 /* ns */ | ||
27 | #define RC5_BIT_START (1 * RC5_UNIT) | ||
28 | #define RC5_BIT_END (1 * RC5_UNIT) | ||
29 | |||
30 | enum rc5_sz_state { | ||
31 | STATE_INACTIVE, | ||
32 | STATE_BIT_START, | ||
33 | STATE_BIT_END, | ||
34 | STATE_FINISHED, | ||
35 | }; | ||
36 | |||
37 | /** | ||
38 | * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space | ||
39 | * @input_dev: the struct input_dev descriptor of the device | ||
40 | * @ev: the struct ir_raw_event descriptor of the pulse/space | ||
41 | * | ||
42 | * This function returns -EINVAL if the pulse violates the state machine | ||
43 | */ | ||
44 | static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev) | ||
45 | { | ||
46 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
47 | struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz; | ||
48 | u8 toggle, command, system; | ||
49 | u32 scancode; | ||
50 | |||
51 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) | ||
52 | return 0; | ||
53 | |||
54 | if (!is_timing_event(ev)) { | ||
55 | if (ev.reset) | ||
56 | data->state = STATE_INACTIVE; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) | ||
61 | goto out; | ||
62 | |||
63 | again: | ||
64 | IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n", | ||
65 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | ||
66 | |||
67 | if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) | ||
68 | return 0; | ||
69 | |||
70 | switch (data->state) { | ||
71 | |||
72 | case STATE_INACTIVE: | ||
73 | if (!ev.pulse) | ||
74 | break; | ||
75 | |||
76 | data->state = STATE_BIT_START; | ||
77 | data->count = 1; | ||
78 | data->wanted_bits = RC5_SZ_NBITS; | ||
79 | decrease_duration(&ev, RC5_BIT_START); | ||
80 | goto again; | ||
81 | |||
82 | case STATE_BIT_START: | ||
83 | if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) | ||
84 | break; | ||
85 | |||
86 | data->bits <<= 1; | ||
87 | if (!ev.pulse) | ||
88 | data->bits |= 1; | ||
89 | data->count++; | ||
90 | data->state = STATE_BIT_END; | ||
91 | return 0; | ||
92 | |||
93 | case STATE_BIT_END: | ||
94 | if (!is_transition(&ev, &ir_dev->raw->prev_ev)) | ||
95 | break; | ||
96 | |||
97 | if (data->count == data->wanted_bits) | ||
98 | data->state = STATE_FINISHED; | ||
99 | else | ||
100 | data->state = STATE_BIT_START; | ||
101 | |||
102 | decrease_duration(&ev, RC5_BIT_END); | ||
103 | goto again; | ||
104 | |||
105 | case STATE_FINISHED: | ||
106 | if (ev.pulse) | ||
107 | break; | ||
108 | |||
109 | /* RC5-sz */ | ||
110 | command = (data->bits & 0x0003F) >> 0; | ||
111 | system = (data->bits & 0x02FC0) >> 6; | ||
112 | toggle = (data->bits & 0x01000) ? 1 : 0; | ||
113 | scancode = system << 6 | command; | ||
114 | |||
115 | IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", | ||
116 | scancode, toggle); | ||
117 | |||
118 | ir_keydown(input_dev, scancode, toggle); | ||
119 | data->state = STATE_INACTIVE; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | out: | ||
124 | IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n", | ||
125 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | ||
126 | data->state = STATE_INACTIVE; | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | static struct ir_raw_handler rc5_sz_handler = { | ||
131 | .protocols = IR_TYPE_RC5_SZ, | ||
132 | .decode = ir_rc5_sz_decode, | ||
133 | }; | ||
134 | |||
135 | static int __init ir_rc5_sz_decode_init(void) | ||
136 | { | ||
137 | ir_raw_handler_register(&rc5_sz_handler); | ||
138 | |||
139 | printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n"); | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static void __exit ir_rc5_sz_decode_exit(void) | ||
144 | { | ||
145 | ir_raw_handler_unregister(&rc5_sz_handler); | ||
146 | } | ||
147 | |||
148 | module_init(ir_rc5_sz_decode_init); | ||
149 | module_exit(ir_rc5_sz_decode_exit); | ||
150 | |||
151 | MODULE_LICENSE("GPL"); | ||
152 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
153 | MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | ||
154 | MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder"); | ||
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c index f1624b8279b..d25da91f44f 100644 --- a/drivers/media/IR/ir-rc6-decoder.c +++ b/drivers/media/IR/ir-rc6-decoder.c | |||
@@ -85,8 +85,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
85 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) | 85 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) |
86 | return 0; | 86 | return 0; |
87 | 87 | ||
88 | if (IS_RESET(ev)) { | 88 | if (!is_timing_event(ev)) { |
89 | data->state = STATE_INACTIVE; | 89 | if (ev.reset) |
90 | data->state = STATE_INACTIVE; | ||
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | 93 | ||
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c index b9074f07c7a..2d15730822b 100644 --- a/drivers/media/IR/ir-sony-decoder.c +++ b/drivers/media/IR/ir-sony-decoder.c | |||
@@ -48,8 +48,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
48 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) | 48 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) |
49 | return 0; | 49 | return 0; |
50 | 50 | ||
51 | if (IS_RESET(ev)) { | 51 | if (!is_timing_event(ev)) { |
52 | data->state = STATE_INACTIVE; | 52 | if (ev.reset) |
53 | data->state = STATE_INACTIVE; | ||
53 | return 0; | 54 | return 0; |
54 | } | 55 | } |
55 | 56 | ||
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 46d42467f9b..38423a8da87 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -43,6 +43,7 @@ static struct { | |||
43 | { IR_TYPE_RC6, "rc-6" }, | 43 | { IR_TYPE_RC6, "rc-6" }, |
44 | { IR_TYPE_JVC, "jvc" }, | 44 | { IR_TYPE_JVC, "jvc" }, |
45 | { IR_TYPE_SONY, "sony" }, | 45 | { IR_TYPE_SONY, "sony" }, |
46 | { IR_TYPE_RC5_SZ, "rc-5-sz" }, | ||
46 | { IR_TYPE_LIRC, "lirc" }, | 47 | { IR_TYPE_LIRC, "lirc" }, |
47 | }; | 48 | }; |
48 | 49 | ||
@@ -67,6 +68,10 @@ static ssize_t show_protocols(struct device *d, | |||
67 | char *tmp = buf; | 68 | char *tmp = buf; |
68 | int i; | 69 | int i; |
69 | 70 | ||
71 | /* Device is being removed */ | ||
72 | if (!ir_dev) | ||
73 | return -EINVAL; | ||
74 | |||
70 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { | 75 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { |
71 | enabled = ir_dev->rc_tab.ir_type; | 76 | enabled = ir_dev->rc_tab.ir_type; |
72 | allowed = ir_dev->props->allowed_protos; | 77 | allowed = ir_dev->props->allowed_protos; |
@@ -122,6 +127,10 @@ static ssize_t store_protocols(struct device *d, | |||
122 | int rc, i, count = 0; | 127 | int rc, i, count = 0; |
123 | unsigned long flags; | 128 | unsigned long flags; |
124 | 129 | ||
130 | /* Device is being removed */ | ||
131 | if (!ir_dev) | ||
132 | return -EINVAL; | ||
133 | |||
125 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) | 134 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) |
126 | type = ir_dev->rc_tab.ir_type; | 135 | type = ir_dev->rc_tab.ir_type; |
127 | else if (ir_dev->raw) | 136 | else if (ir_dev->raw) |
@@ -256,8 +265,6 @@ static struct device_type rc_dev_type = { | |||
256 | */ | 265 | */ |
257 | int ir_register_class(struct input_dev *input_dev) | 266 | int ir_register_class(struct input_dev *input_dev) |
258 | { | 267 | { |
259 | int rc; | ||
260 | const char *path; | ||
261 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 268 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
262 | int devno = find_first_zero_bit(&ir_core_dev_number, | 269 | int devno = find_first_zero_bit(&ir_core_dev_number, |
263 | IRRCV_NUM_DEVICES); | 270 | IRRCV_NUM_DEVICES); |
@@ -266,17 +273,28 @@ int ir_register_class(struct input_dev *input_dev) | |||
266 | return devno; | 273 | return devno; |
267 | 274 | ||
268 | ir_dev->dev.type = &rc_dev_type; | 275 | ir_dev->dev.type = &rc_dev_type; |
276 | ir_dev->devno = devno; | ||
269 | 277 | ||
270 | ir_dev->dev.class = &ir_input_class; | 278 | ir_dev->dev.class = &ir_input_class; |
271 | ir_dev->dev.parent = input_dev->dev.parent; | 279 | ir_dev->dev.parent = input_dev->dev.parent; |
280 | input_dev->dev.parent = &ir_dev->dev; | ||
272 | dev_set_name(&ir_dev->dev, "rc%d", devno); | 281 | dev_set_name(&ir_dev->dev, "rc%d", devno); |
273 | dev_set_drvdata(&ir_dev->dev, ir_dev); | 282 | dev_set_drvdata(&ir_dev->dev, ir_dev); |
274 | rc = device_register(&ir_dev->dev); | 283 | return device_register(&ir_dev->dev); |
275 | if (rc) | 284 | }; |
276 | return rc; | 285 | |
286 | /** | ||
287 | * ir_register_input - registers ir input device with input subsystem | ||
288 | * @input_dev: the struct input_dev descriptor of the device | ||
289 | */ | ||
290 | |||
291 | int ir_register_input(struct input_dev *input_dev) | ||
292 | { | ||
293 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
294 | int rc; | ||
295 | const char *path; | ||
277 | 296 | ||
278 | 297 | ||
279 | input_dev->dev.parent = &ir_dev->dev; | ||
280 | rc = input_register_device(input_dev); | 298 | rc = input_register_device(input_dev); |
281 | if (rc < 0) { | 299 | if (rc < 0) { |
282 | device_del(&ir_dev->dev); | 300 | device_del(&ir_dev->dev); |
@@ -292,11 +310,9 @@ int ir_register_class(struct input_dev *input_dev) | |||
292 | path ? path : "N/A"); | 310 | path ? path : "N/A"); |
293 | kfree(path); | 311 | kfree(path); |
294 | 312 | ||
295 | ir_dev->devno = devno; | 313 | set_bit(ir_dev->devno, &ir_core_dev_number); |
296 | set_bit(devno, &ir_core_dev_number); | ||
297 | |||
298 | return 0; | 314 | return 0; |
299 | }; | 315 | } |
300 | 316 | ||
301 | /** | 317 | /** |
302 | * ir_unregister_class() - removes the sysfs for sysfs for | 318 | * ir_unregister_class() - removes the sysfs for sysfs for |
@@ -309,6 +325,7 @@ void ir_unregister_class(struct input_dev *input_dev) | |||
309 | { | 325 | { |
310 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 326 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
311 | 327 | ||
328 | input_set_drvdata(input_dev, NULL); | ||
312 | clear_bit(ir_dev->devno, &ir_core_dev_number); | 329 | clear_bit(ir_dev->devno, &ir_core_dev_number); |
313 | input_unregister_device(input_dev); | 330 | input_unregister_device(input_dev); |
314 | device_del(&ir_dev->dev); | 331 | device_del(&ir_dev->dev); |
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile index 950e5d953c6..3194d391bbd 100644 --- a/drivers/media/IR/keymaps/Makefile +++ b/drivers/media/IR/keymaps/Makefile | |||
@@ -1,4 +1,6 @@ | |||
1 | obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | 1 | obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ |
2 | rc-alink-dtu-m.o \ | ||
3 | rc-anysee.o \ | ||
2 | rc-apac-viewcomp.o \ | 4 | rc-apac-viewcomp.o \ |
3 | rc-asus-pc39.o \ | 5 | rc-asus-pc39.o \ |
4 | rc-ati-tv-wonder-hd-600.o \ | 6 | rc-ati-tv-wonder-hd-600.o \ |
@@ -8,7 +10,9 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | |||
8 | rc-avermedia-dvbt.o \ | 10 | rc-avermedia-dvbt.o \ |
9 | rc-avermedia-m135a.o \ | 11 | rc-avermedia-m135a.o \ |
10 | rc-avermedia-m733a-rm-k6.o \ | 12 | rc-avermedia-m733a-rm-k6.o \ |
13 | rc-avermedia-rm-ks.o \ | ||
11 | rc-avertv-303.o \ | 14 | rc-avertv-303.o \ |
15 | rc-azurewave-ad-tu700.o \ | ||
12 | rc-behold.o \ | 16 | rc-behold.o \ |
13 | rc-behold-columbus.o \ | 17 | rc-behold-columbus.o \ |
14 | rc-budget-ci-old.o \ | 18 | rc-budget-ci-old.o \ |
@@ -16,6 +20,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | |||
16 | rc-cinergy.o \ | 20 | rc-cinergy.o \ |
17 | rc-dib0700-nec.o \ | 21 | rc-dib0700-nec.o \ |
18 | rc-dib0700-rc5.o \ | 22 | rc-dib0700-rc5.o \ |
23 | rc-digitalnow-tinytwin.o \ | ||
24 | rc-digittrade.o \ | ||
19 | rc-dm1105-nec.o \ | 25 | rc-dm1105-nec.o \ |
20 | rc-dntv-live-dvb-t.o \ | 26 | rc-dntv-live-dvb-t.o \ |
21 | rc-dntv-live-dvbt-pro.o \ | 27 | rc-dntv-live-dvbt-pro.o \ |
@@ -38,8 +44,12 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | |||
38 | rc-kaiomy.o \ | 44 | rc-kaiomy.o \ |
39 | rc-kworld-315u.o \ | 45 | rc-kworld-315u.o \ |
40 | rc-kworld-plus-tv-analog.o \ | 46 | rc-kworld-plus-tv-analog.o \ |
47 | rc-leadtek-y04g0051.o \ | ||
41 | rc-lirc.o \ | 48 | rc-lirc.o \ |
49 | rc-lme2510.o \ | ||
42 | rc-manli.o \ | 50 | rc-manli.o \ |
51 | rc-msi-digivox-ii.o \ | ||
52 | rc-msi-digivox-iii.o \ | ||
43 | rc-msi-tvanywhere.o \ | 53 | rc-msi-tvanywhere.o \ |
44 | rc-msi-tvanywhere-plus.o \ | 54 | rc-msi-tvanywhere-plus.o \ |
45 | rc-nebula.o \ | 55 | rc-nebula.o \ |
@@ -58,14 +68,18 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | |||
58 | rc-purpletv.o \ | 68 | rc-purpletv.o \ |
59 | rc-pv951.o \ | 69 | rc-pv951.o \ |
60 | rc-rc5-hauppauge-new.o \ | 70 | rc-rc5-hauppauge-new.o \ |
61 | rc-rc5-streamzap.o \ | ||
62 | rc-rc5-tv.o \ | 71 | rc-rc5-tv.o \ |
63 | rc-rc6-mce.o \ | 72 | rc-rc6-mce.o \ |
64 | rc-real-audio-220-32-keys.o \ | 73 | rc-real-audio-220-32-keys.o \ |
74 | rc-streamzap.o \ | ||
65 | rc-tbs-nec.o \ | 75 | rc-tbs-nec.o \ |
66 | rc-terratec-cinergy-xs.o \ | 76 | rc-terratec-cinergy-xs.o \ |
77 | rc-terratec-slim.o \ | ||
67 | rc-tevii-nec.o \ | 78 | rc-tevii-nec.o \ |
79 | rc-total-media-in-hand.o \ | ||
80 | rc-trekstor.o \ | ||
68 | rc-tt-1500.o \ | 81 | rc-tt-1500.o \ |
82 | rc-twinhan1027.o \ | ||
69 | rc-videomate-s350.o \ | 83 | rc-videomate-s350.o \ |
70 | rc-videomate-tv-pvr.o \ | 84 | rc-videomate-tv-pvr.o \ |
71 | rc-winfast.o \ | 85 | rc-winfast.o \ |
diff --git a/drivers/media/IR/keymaps/rc-alink-dtu-m.c b/drivers/media/IR/keymaps/rc-alink-dtu-m.c new file mode 100644 index 00000000000..ddfee7f8093 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-alink-dtu-m.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * A-Link DTU(m) remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* A-Link DTU(m) slim remote, 6 rows, 3 columns. */ | ||
24 | static struct ir_scancode alink_dtu_m[] = { | ||
25 | { 0x0800, KEY_VOLUMEUP }, | ||
26 | { 0x0801, KEY_1 }, | ||
27 | { 0x0802, KEY_3 }, | ||
28 | { 0x0803, KEY_7 }, | ||
29 | { 0x0804, KEY_9 }, | ||
30 | { 0x0805, KEY_NEW }, /* symbol: PIP */ | ||
31 | { 0x0806, KEY_0 }, | ||
32 | { 0x0807, KEY_CHANNEL }, /* JUMP */ | ||
33 | { 0x080d, KEY_5 }, | ||
34 | { 0x080f, KEY_2 }, | ||
35 | { 0x0812, KEY_POWER2 }, | ||
36 | { 0x0814, KEY_CHANNELUP }, | ||
37 | { 0x0816, KEY_VOLUMEDOWN }, | ||
38 | { 0x0818, KEY_6 }, | ||
39 | { 0x081a, KEY_MUTE }, | ||
40 | { 0x081b, KEY_8 }, | ||
41 | { 0x081c, KEY_4 }, | ||
42 | { 0x081d, KEY_CHANNELDOWN }, | ||
43 | }; | ||
44 | |||
45 | static struct rc_keymap alink_dtu_m_map = { | ||
46 | .map = { | ||
47 | .scan = alink_dtu_m, | ||
48 | .size = ARRAY_SIZE(alink_dtu_m), | ||
49 | .ir_type = IR_TYPE_NEC, | ||
50 | .name = RC_MAP_ALINK_DTU_M, | ||
51 | } | ||
52 | }; | ||
53 | |||
54 | static int __init init_rc_map_alink_dtu_m(void) | ||
55 | { | ||
56 | return ir_register_map(&alink_dtu_m_map); | ||
57 | } | ||
58 | |||
59 | static void __exit exit_rc_map_alink_dtu_m(void) | ||
60 | { | ||
61 | ir_unregister_map(&alink_dtu_m_map); | ||
62 | } | ||
63 | |||
64 | module_init(init_rc_map_alink_dtu_m) | ||
65 | module_exit(exit_rc_map_alink_dtu_m) | ||
66 | |||
67 | MODULE_LICENSE("GPL"); | ||
68 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-anysee.c b/drivers/media/IR/keymaps/rc-anysee.c new file mode 100644 index 00000000000..30d70498cfe --- /dev/null +++ b/drivers/media/IR/keymaps/rc-anysee.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Anysee remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | static struct ir_scancode anysee[] = { | ||
24 | { 0x0800, KEY_0 }, | ||
25 | { 0x0801, KEY_1 }, | ||
26 | { 0x0802, KEY_2 }, | ||
27 | { 0x0803, KEY_3 }, | ||
28 | { 0x0804, KEY_4 }, | ||
29 | { 0x0805, KEY_5 }, | ||
30 | { 0x0806, KEY_6 }, | ||
31 | { 0x0807, KEY_7 }, | ||
32 | { 0x0808, KEY_8 }, | ||
33 | { 0x0809, KEY_9 }, | ||
34 | { 0x080a, KEY_POWER2 }, /* [red power button] */ | ||
35 | { 0x080b, KEY_VIDEO }, /* [*] MODE */ | ||
36 | { 0x080c, KEY_CHANNEL }, /* [symbol counterclockwise arrow] */ | ||
37 | { 0x080d, KEY_NEXT }, /* [>>|] */ | ||
38 | { 0x080e, KEY_MENU }, /* MENU */ | ||
39 | { 0x080f, KEY_EPG }, /* [EPG] */ | ||
40 | { 0x0810, KEY_CLEAR }, /* EXIT */ | ||
41 | { 0x0811, KEY_CHANNELUP }, | ||
42 | { 0x0812, KEY_VOLUMEDOWN }, | ||
43 | { 0x0813, KEY_VOLUMEUP }, | ||
44 | { 0x0814, KEY_CHANNELDOWN }, | ||
45 | { 0x0815, KEY_OK }, | ||
46 | { 0x0816, KEY_RADIO }, /* [symbol TV/radio] */ | ||
47 | { 0x0817, KEY_INFO }, /* [i] */ | ||
48 | { 0x0818, KEY_PREVIOUS }, /* [|<<] */ | ||
49 | { 0x0819, KEY_FAVORITES }, /* FAV. */ | ||
50 | { 0x081a, KEY_SUBTITLE }, /* Subtitle */ | ||
51 | { 0x081b, KEY_CAMERA }, /* [symbol camera] */ | ||
52 | { 0x081c, KEY_YELLOW }, | ||
53 | { 0x081d, KEY_RED }, | ||
54 | { 0x081e, KEY_LANGUAGE }, /* [symbol Second Audio Program] */ | ||
55 | { 0x081f, KEY_GREEN }, | ||
56 | { 0x0820, KEY_SLEEP }, /* Sleep */ | ||
57 | { 0x0821, KEY_SCREEN }, /* 16:9 / 4:3 */ | ||
58 | { 0x0822, KEY_ZOOM }, /* SIZE */ | ||
59 | { 0x0824, KEY_FN }, /* [F1] */ | ||
60 | { 0x0825, KEY_FN }, /* [F2] */ | ||
61 | { 0x0842, KEY_MUTE }, /* symbol mute */ | ||
62 | { 0x0844, KEY_BLUE }, | ||
63 | { 0x0847, KEY_TEXT }, /* TEXT */ | ||
64 | { 0x0848, KEY_STOP }, | ||
65 | { 0x0849, KEY_RECORD }, | ||
66 | { 0x0850, KEY_PLAY }, | ||
67 | { 0x0851, KEY_PAUSE }, | ||
68 | }; | ||
69 | |||
70 | static struct rc_keymap anysee_map = { | ||
71 | .map = { | ||
72 | .scan = anysee, | ||
73 | .size = ARRAY_SIZE(anysee), | ||
74 | .ir_type = IR_TYPE_NEC, | ||
75 | .name = RC_MAP_ANYSEE, | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | static int __init init_rc_map_anysee(void) | ||
80 | { | ||
81 | return ir_register_map(&anysee_map); | ||
82 | } | ||
83 | |||
84 | static void __exit exit_rc_map_anysee(void) | ||
85 | { | ||
86 | ir_unregister_map(&anysee_map); | ||
87 | } | ||
88 | |||
89 | module_init(init_rc_map_anysee) | ||
90 | module_exit(exit_rc_map_anysee) | ||
91 | |||
92 | MODULE_LICENSE("GPL"); | ||
93 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-asus-pc39.c b/drivers/media/IR/keymaps/rc-asus-pc39.c index 2aa068cd6c7..2996e0a3b8d 100644 --- a/drivers/media/IR/keymaps/rc-asus-pc39.c +++ b/drivers/media/IR/keymaps/rc-asus-pc39.c | |||
@@ -20,56 +20,56 @@ | |||
20 | 20 | ||
21 | static struct ir_scancode asus_pc39[] = { | 21 | static struct ir_scancode asus_pc39[] = { |
22 | /* Keys 0 to 9 */ | 22 | /* Keys 0 to 9 */ |
23 | { 0x15, KEY_0 }, | 23 | { 0x082a, KEY_0 }, |
24 | { 0x29, KEY_1 }, | 24 | { 0x0816, KEY_1 }, |
25 | { 0x2d, KEY_2 }, | 25 | { 0x0812, KEY_2 }, |
26 | { 0x2b, KEY_3 }, | 26 | { 0x0814, KEY_3 }, |
27 | { 0x09, KEY_4 }, | 27 | { 0x0836, KEY_4 }, |
28 | { 0x0d, KEY_5 }, | 28 | { 0x0832, KEY_5 }, |
29 | { 0x0b, KEY_6 }, | 29 | { 0x0834, KEY_6 }, |
30 | { 0x31, KEY_7 }, | 30 | { 0x080e, KEY_7 }, |
31 | { 0x35, KEY_8 }, | 31 | { 0x080a, KEY_8 }, |
32 | { 0x33, KEY_9 }, | 32 | { 0x080c, KEY_9 }, |
33 | 33 | ||
34 | { 0x3e, KEY_RADIO }, /* radio */ | 34 | { 0x0801, KEY_RADIO }, /* radio */ |
35 | { 0x03, KEY_MENU }, /* dvd/menu */ | 35 | { 0x083c, KEY_MENU }, /* dvd/menu */ |
36 | { 0x2a, KEY_VOLUMEUP }, | 36 | { 0x0815, KEY_VOLUMEUP }, |
37 | { 0x19, KEY_VOLUMEDOWN }, | 37 | { 0x0826, KEY_VOLUMEDOWN }, |
38 | { 0x37, KEY_UP }, | 38 | { 0x0808, KEY_UP }, |
39 | { 0x3b, KEY_DOWN }, | 39 | { 0x0804, KEY_DOWN }, |
40 | { 0x27, KEY_LEFT }, | 40 | { 0x0818, KEY_LEFT }, |
41 | { 0x2f, KEY_RIGHT }, | 41 | { 0x0810, KEY_RIGHT }, |
42 | { 0x25, KEY_VIDEO }, /* video */ | 42 | { 0x081a, KEY_VIDEO }, /* video */ |
43 | { 0x39, KEY_AUDIO }, /* music */ | 43 | { 0x0806, KEY_AUDIO }, /* music */ |
44 | 44 | ||
45 | { 0x21, KEY_TV }, /* tv */ | 45 | { 0x081e, KEY_TV }, /* tv */ |
46 | { 0x1d, KEY_EXIT }, /* back */ | 46 | { 0x0822, KEY_EXIT }, /* back */ |
47 | { 0x0a, KEY_CHANNELUP }, /* channel / program + */ | 47 | { 0x0835, KEY_CHANNELUP }, /* channel / program + */ |
48 | { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */ | 48 | { 0x0824, KEY_CHANNELDOWN }, /* channel / program - */ |
49 | { 0x1a, KEY_ENTER }, /* enter */ | 49 | { 0x0825, KEY_ENTER }, /* enter */ |
50 | 50 | ||
51 | { 0x06, KEY_PAUSE }, /* play/pause */ | 51 | { 0x0839, KEY_PAUSE }, /* play/pause */ |
52 | { 0x1e, KEY_PREVIOUS }, /* rew */ | 52 | { 0x0821, KEY_PREVIOUS }, /* rew */ |
53 | { 0x26, KEY_NEXT }, /* forward */ | 53 | { 0x0819, KEY_NEXT }, /* forward */ |
54 | { 0x0e, KEY_REWIND }, /* backward << */ | 54 | { 0x0831, KEY_REWIND }, /* backward << */ |
55 | { 0x3a, KEY_FASTFORWARD }, /* forward >> */ | 55 | { 0x0805, KEY_FASTFORWARD }, /* forward >> */ |
56 | { 0x36, KEY_STOP }, | 56 | { 0x0809, KEY_STOP }, |
57 | { 0x2e, KEY_RECORD }, /* recording */ | 57 | { 0x0811, KEY_RECORD }, /* recording */ |
58 | { 0x16, KEY_POWER }, /* the button that reads "close" */ | 58 | { 0x0829, KEY_POWER }, /* the button that reads "close" */ |
59 | 59 | ||
60 | { 0x11, KEY_ZOOM }, /* full screen */ | 60 | { 0x082e, KEY_ZOOM }, /* full screen */ |
61 | { 0x13, KEY_MACRO }, /* recall */ | 61 | { 0x082c, KEY_MACRO }, /* recall */ |
62 | { 0x23, KEY_HOME }, /* home */ | 62 | { 0x081c, KEY_HOME }, /* home */ |
63 | { 0x05, KEY_PVR }, /* picture */ | 63 | { 0x083a, KEY_PVR }, /* picture */ |
64 | { 0x3d, KEY_MUTE }, /* mute */ | 64 | { 0x0802, KEY_MUTE }, /* mute */ |
65 | { 0x01, KEY_DVD }, /* dvd */ | 65 | { 0x083e, KEY_DVD }, /* dvd */ |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static struct rc_keymap asus_pc39_map = { | 68 | static struct rc_keymap asus_pc39_map = { |
69 | .map = { | 69 | .map = { |
70 | .scan = asus_pc39, | 70 | .scan = asus_pc39, |
71 | .size = ARRAY_SIZE(asus_pc39), | 71 | .size = ARRAY_SIZE(asus_pc39), |
72 | .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ | 72 | .ir_type = IR_TYPE_RC5, |
73 | .name = RC_MAP_ASUS_PC39, | 73 | .name = RC_MAP_ASUS_PC39, |
74 | } | 74 | } |
75 | }; | 75 | }; |
diff --git a/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c b/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c new file mode 100644 index 00000000000..9ee60906c86 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * AverMedia RM-KS remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* Initial keytable is from Jose Alberto Reguero <jareguero@telefonica.net> | ||
24 | and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */ | ||
25 | /* FIXME: mappings are not 100% correct? */ | ||
26 | static struct ir_scancode avermedia_rm_ks[] = { | ||
27 | { 0x0501, KEY_POWER2 }, | ||
28 | { 0x0502, KEY_CHANNELUP }, | ||
29 | { 0x0503, KEY_CHANNELDOWN }, | ||
30 | { 0x0504, KEY_VOLUMEUP }, | ||
31 | { 0x0505, KEY_VOLUMEDOWN }, | ||
32 | { 0x0506, KEY_MUTE }, | ||
33 | { 0x0507, KEY_RIGHT }, | ||
34 | { 0x0508, KEY_PROG1 }, | ||
35 | { 0x0509, KEY_1 }, | ||
36 | { 0x050a, KEY_2 }, | ||
37 | { 0x050b, KEY_3 }, | ||
38 | { 0x050c, KEY_4 }, | ||
39 | { 0x050d, KEY_5 }, | ||
40 | { 0x050e, KEY_6 }, | ||
41 | { 0x050f, KEY_7 }, | ||
42 | { 0x0510, KEY_8 }, | ||
43 | { 0x0511, KEY_9 }, | ||
44 | { 0x0512, KEY_0 }, | ||
45 | { 0x0513, KEY_AUDIO }, | ||
46 | { 0x0515, KEY_EPG }, | ||
47 | { 0x0516, KEY_PLAY }, | ||
48 | { 0x0517, KEY_RECORD }, | ||
49 | { 0x0518, KEY_STOP }, | ||
50 | { 0x051c, KEY_BACK }, | ||
51 | { 0x051d, KEY_FORWARD }, | ||
52 | { 0x054d, KEY_LEFT }, | ||
53 | { 0x0556, KEY_ZOOM }, | ||
54 | }; | ||
55 | |||
56 | static struct rc_keymap avermedia_rm_ks_map = { | ||
57 | .map = { | ||
58 | .scan = avermedia_rm_ks, | ||
59 | .size = ARRAY_SIZE(avermedia_rm_ks), | ||
60 | .ir_type = IR_TYPE_NEC, | ||
61 | .name = RC_MAP_AVERMEDIA_RM_KS, | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | static int __init init_rc_map_avermedia_rm_ks(void) | ||
66 | { | ||
67 | return ir_register_map(&avermedia_rm_ks_map); | ||
68 | } | ||
69 | |||
70 | static void __exit exit_rc_map_avermedia_rm_ks(void) | ||
71 | { | ||
72 | ir_unregister_map(&avermedia_rm_ks_map); | ||
73 | } | ||
74 | |||
75 | module_init(init_rc_map_avermedia_rm_ks) | ||
76 | module_exit(exit_rc_map_avermedia_rm_ks) | ||
77 | |||
78 | MODULE_LICENSE("GPL"); | ||
79 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c new file mode 100644 index 00000000000..e0876147d47 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * TwinHan AzureWave AD-TU700(704J) remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | static struct ir_scancode azurewave_ad_tu700[] = { | ||
24 | { 0x0000, KEY_TAB }, /* Tab */ | ||
25 | { 0x0001, KEY_2 }, | ||
26 | { 0x0002, KEY_CHANNELDOWN }, | ||
27 | { 0x0003, KEY_1 }, | ||
28 | { 0x0004, KEY_MENU }, /* Record List */ | ||
29 | { 0x0005, KEY_CHANNELUP }, | ||
30 | { 0x0006, KEY_3 }, | ||
31 | { 0x0007, KEY_SLEEP }, /* Hibernate */ | ||
32 | { 0x0008, KEY_VIDEO }, /* A/V */ | ||
33 | { 0x0009, KEY_4 }, | ||
34 | { 0x000a, KEY_VOLUMEDOWN }, | ||
35 | { 0x000c, KEY_CANCEL }, /* Cancel */ | ||
36 | { 0x000d, KEY_7 }, | ||
37 | { 0x000e, KEY_AGAIN }, /* Recall */ | ||
38 | { 0x000f, KEY_TEXT }, /* Teletext */ | ||
39 | { 0x0010, KEY_MUTE }, | ||
40 | { 0x0011, KEY_RECORD }, | ||
41 | { 0x0012, KEY_FASTFORWARD }, /* FF >> */ | ||
42 | { 0x0013, KEY_BACK }, /* Back */ | ||
43 | { 0x0014, KEY_PLAY }, | ||
44 | { 0x0015, KEY_0 }, | ||
45 | { 0x0016, KEY_POWER2 }, /* [red power button] */ | ||
46 | { 0x0017, KEY_FAVORITES }, /* Favorite List */ | ||
47 | { 0x0018, KEY_RED }, | ||
48 | { 0x0019, KEY_8 }, | ||
49 | { 0x001a, KEY_STOP }, | ||
50 | { 0x001b, KEY_9 }, | ||
51 | { 0x001c, KEY_EPG }, /* Info/EPG */ | ||
52 | { 0x001d, KEY_5 }, | ||
53 | { 0x001e, KEY_VOLUMEUP }, | ||
54 | { 0x001f, KEY_6 }, | ||
55 | { 0x0040, KEY_REWIND }, /* FR << */ | ||
56 | { 0x0041, KEY_PREVIOUS }, /* Replay */ | ||
57 | { 0x0042, KEY_NEXT }, /* Skip */ | ||
58 | { 0x0043, KEY_SUBTITLE }, /* Subtitle / CC */ | ||
59 | { 0x0045, KEY_KPPLUS }, /* Zoom+ */ | ||
60 | { 0x0046, KEY_KPMINUS }, /* Zoom- */ | ||
61 | { 0x0047, KEY_NEW }, /* PIP */ | ||
62 | { 0x0048, KEY_INFO }, /* Preview */ | ||
63 | { 0x0049, KEY_MODE }, /* L/R */ | ||
64 | { 0x004a, KEY_CLEAR }, /* Clear */ | ||
65 | { 0x004b, KEY_UP }, /* up arrow */ | ||
66 | { 0x004c, KEY_PAUSE }, | ||
67 | { 0x004d, KEY_ZOOM }, /* Full Screen */ | ||
68 | { 0x004e, KEY_LEFT }, /* left arrow */ | ||
69 | { 0x004f, KEY_OK }, /* Enter / ok */ | ||
70 | { 0x0050, KEY_LANGUAGE }, /* SAP */ | ||
71 | { 0x0051, KEY_DOWN }, /* down arrow */ | ||
72 | { 0x0052, KEY_RIGHT }, /* right arrow */ | ||
73 | { 0x0053, KEY_GREEN }, | ||
74 | { 0x0054, KEY_CAMERA }, /* Capture */ | ||
75 | { 0x005e, KEY_YELLOW }, | ||
76 | { 0x005f, KEY_BLUE }, | ||
77 | }; | ||
78 | |||
79 | static struct rc_keymap azurewave_ad_tu700_map = { | ||
80 | .map = { | ||
81 | .scan = azurewave_ad_tu700, | ||
82 | .size = ARRAY_SIZE(azurewave_ad_tu700), | ||
83 | .ir_type = IR_TYPE_NEC, | ||
84 | .name = RC_MAP_AZUREWAVE_AD_TU700, | ||
85 | } | ||
86 | }; | ||
87 | |||
88 | static int __init init_rc_map_azurewave_ad_tu700(void) | ||
89 | { | ||
90 | return ir_register_map(&azurewave_ad_tu700_map); | ||
91 | } | ||
92 | |||
93 | static void __exit exit_rc_map_azurewave_ad_tu700(void) | ||
94 | { | ||
95 | ir_unregister_map(&azurewave_ad_tu700_map); | ||
96 | } | ||
97 | |||
98 | module_init(init_rc_map_azurewave_ad_tu700) | ||
99 | module_exit(exit_rc_map_azurewave_ad_tu700) | ||
100 | |||
101 | MODULE_LICENSE("GPL"); | ||
102 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c new file mode 100644 index 00000000000..63e469e2dd2 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * DigitalNow TinyTwin remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | static struct ir_scancode digitalnow_tinytwin[] = { | ||
24 | { 0x0000, KEY_MUTE }, /* [symbol speaker] */ | ||
25 | { 0x0001, KEY_VOLUMEUP }, | ||
26 | { 0x0002, KEY_POWER2 }, /* TV [power button] */ | ||
27 | { 0x0003, KEY_2 }, | ||
28 | { 0x0004, KEY_3 }, | ||
29 | { 0x0005, KEY_4 }, | ||
30 | { 0x0006, KEY_6 }, | ||
31 | { 0x0007, KEY_7 }, | ||
32 | { 0x0008, KEY_8 }, | ||
33 | { 0x0009, KEY_NUMERIC_STAR }, /* [*] */ | ||
34 | { 0x000a, KEY_0 }, | ||
35 | { 0x000b, KEY_NUMERIC_POUND }, /* [#] */ | ||
36 | { 0x000c, KEY_RIGHT }, /* [right arrow] */ | ||
37 | { 0x000d, KEY_HOMEPAGE }, /* [symbol home] Start */ | ||
38 | { 0x000e, KEY_RED }, /* [red] Videos */ | ||
39 | { 0x0010, KEY_POWER }, /* PC [power button] */ | ||
40 | { 0x0011, KEY_YELLOW }, /* [yellow] Pictures */ | ||
41 | { 0x0012, KEY_DOWN }, /* [down arrow] */ | ||
42 | { 0x0013, KEY_GREEN }, /* [green] Music */ | ||
43 | { 0x0014, KEY_CYCLEWINDOWS }, /* BACK */ | ||
44 | { 0x0015, KEY_FAVORITES }, /* MORE */ | ||
45 | { 0x0016, KEY_UP }, /* [up arrow] */ | ||
46 | { 0x0017, KEY_LEFT }, /* [left arrow] */ | ||
47 | { 0x0018, KEY_OK }, /* OK */ | ||
48 | { 0x0019, KEY_BLUE }, /* [blue] MyTV */ | ||
49 | { 0x001a, KEY_REWIND }, /* REW [<<] */ | ||
50 | { 0x001b, KEY_PLAY }, /* PLAY */ | ||
51 | { 0x001c, KEY_5 }, | ||
52 | { 0x001d, KEY_9 }, | ||
53 | { 0x001e, KEY_VOLUMEDOWN }, | ||
54 | { 0x001f, KEY_1 }, | ||
55 | { 0x0040, KEY_STOP }, /* STOP */ | ||
56 | { 0x0042, KEY_PAUSE }, /* PAUSE */ | ||
57 | { 0x0043, KEY_SCREEN }, /* Aspect */ | ||
58 | { 0x0044, KEY_FORWARD }, /* FWD [>>] */ | ||
59 | { 0x0045, KEY_NEXT }, /* SKIP */ | ||
60 | { 0x0048, KEY_RECORD }, /* RECORD */ | ||
61 | { 0x0049, KEY_VIDEO }, /* RTV */ | ||
62 | { 0x004a, KEY_EPG }, /* Guide */ | ||
63 | { 0x004b, KEY_CHANNELUP }, | ||
64 | { 0x004c, KEY_HELP }, /* Help */ | ||
65 | { 0x004d, KEY_RADIO }, /* Radio */ | ||
66 | { 0x004f, KEY_CHANNELDOWN }, | ||
67 | { 0x0050, KEY_DVD }, /* DVD */ | ||
68 | { 0x0051, KEY_AUDIO }, /* Audio */ | ||
69 | { 0x0052, KEY_TITLE }, /* Title */ | ||
70 | { 0x0053, KEY_NEW }, /* [symbol PIP?] */ | ||
71 | { 0x0057, KEY_MENU }, /* Mouse */ | ||
72 | { 0x005a, KEY_PREVIOUS }, /* REPLAY */ | ||
73 | }; | ||
74 | |||
75 | static struct rc_keymap digitalnow_tinytwin_map = { | ||
76 | .map = { | ||
77 | .scan = digitalnow_tinytwin, | ||
78 | .size = ARRAY_SIZE(digitalnow_tinytwin), | ||
79 | .ir_type = IR_TYPE_NEC, | ||
80 | .name = RC_MAP_DIGITALNOW_TINYTWIN, | ||
81 | } | ||
82 | }; | ||
83 | |||
84 | static int __init init_rc_map_digitalnow_tinytwin(void) | ||
85 | { | ||
86 | return ir_register_map(&digitalnow_tinytwin_map); | ||
87 | } | ||
88 | |||
89 | static void __exit exit_rc_map_digitalnow_tinytwin(void) | ||
90 | { | ||
91 | ir_unregister_map(&digitalnow_tinytwin_map); | ||
92 | } | ||
93 | |||
94 | module_init(init_rc_map_digitalnow_tinytwin) | ||
95 | module_exit(exit_rc_map_digitalnow_tinytwin) | ||
96 | |||
97 | MODULE_LICENSE("GPL"); | ||
98 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-digittrade.c b/drivers/media/IR/keymaps/rc-digittrade.c new file mode 100644 index 00000000000..5dece78e19c --- /dev/null +++ b/drivers/media/IR/keymaps/rc-digittrade.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Digittrade DVB-T USB Stick remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* Digittrade DVB-T USB Stick remote controller. */ | ||
24 | /* Imported from af9015.h. | ||
25 | Initial keytable was from Alain Kalker <miki@dds.nl> */ | ||
26 | |||
27 | /* Digittrade DVB-T USB Stick */ | ||
28 | static struct ir_scancode digittrade[] = { | ||
29 | { 0x0000, KEY_9 }, | ||
30 | { 0x0001, KEY_EPG }, /* EPG */ | ||
31 | { 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */ | ||
32 | { 0x0003, KEY_TEXT }, /* TELETEXT */ | ||
33 | { 0x0004, KEY_8 }, | ||
34 | { 0x0005, KEY_MUTE }, /* MUTE */ | ||
35 | { 0x0006, KEY_POWER2 }, /* POWER */ | ||
36 | { 0x0009, KEY_ZOOM }, /* FULLSCREEN */ | ||
37 | { 0x000a, KEY_RECORD }, /* RECORD */ | ||
38 | { 0x000d, KEY_SUBTITLE }, /* SUBTITLE */ | ||
39 | { 0x000e, KEY_STOP }, /* STOP */ | ||
40 | { 0x0010, KEY_OK }, /* RETURN */ | ||
41 | { 0x0011, KEY_2 }, | ||
42 | { 0x0012, KEY_4 }, | ||
43 | { 0x0015, KEY_3 }, | ||
44 | { 0x0016, KEY_5 }, | ||
45 | { 0x0017, KEY_CHANNELDOWN }, /* Ch Dn */ | ||
46 | { 0x0019, KEY_CHANNELUP }, /* CH Up */ | ||
47 | { 0x001a, KEY_PAUSE }, /* PAUSE */ | ||
48 | { 0x001b, KEY_1 }, | ||
49 | { 0x001d, KEY_AUDIO }, /* DUAL SOUND */ | ||
50 | { 0x001e, KEY_PLAY }, /* PLAY */ | ||
51 | { 0x001f, KEY_CAMERA }, /* SNAPSHOT */ | ||
52 | { 0x0040, KEY_VOLUMEUP }, /* Vol Up */ | ||
53 | { 0x0048, KEY_7 }, | ||
54 | { 0x004c, KEY_6 }, | ||
55 | { 0x004d, KEY_PLAYPAUSE }, /* TIMESHIFT */ | ||
56 | { 0x0054, KEY_0 }, | ||
57 | }; | ||
58 | |||
59 | static struct rc_keymap digittrade_map = { | ||
60 | .map = { | ||
61 | .scan = digittrade, | ||
62 | .size = ARRAY_SIZE(digittrade), | ||
63 | .ir_type = IR_TYPE_NEC, | ||
64 | .name = RC_MAP_DIGITTRADE, | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | static int __init init_rc_map_digittrade(void) | ||
69 | { | ||
70 | return ir_register_map(&digittrade_map); | ||
71 | } | ||
72 | |||
73 | static void __exit exit_rc_map_digittrade(void) | ||
74 | { | ||
75 | ir_unregister_map(&digittrade_map); | ||
76 | } | ||
77 | |||
78 | module_init(init_rc_map_digittrade) | ||
79 | module_exit(exit_rc_map_digittrade) | ||
80 | |||
81 | MODULE_LICENSE("GPL"); | ||
82 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c b/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c new file mode 100644 index 00000000000..7521315fd87 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * LeadTek Y04G0051 remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | static struct ir_scancode leadtek_y04g0051[] = { | ||
24 | { 0x0300, KEY_POWER2 }, | ||
25 | { 0x0303, KEY_SCREEN }, | ||
26 | { 0x0304, KEY_RIGHT }, | ||
27 | { 0x0305, KEY_1 }, | ||
28 | { 0x0306, KEY_2 }, | ||
29 | { 0x0307, KEY_3 }, | ||
30 | { 0x0308, KEY_LEFT }, | ||
31 | { 0x0309, KEY_4 }, | ||
32 | { 0x030a, KEY_5 }, | ||
33 | { 0x030b, KEY_6 }, | ||
34 | { 0x030c, KEY_UP }, | ||
35 | { 0x030d, KEY_7 }, | ||
36 | { 0x030e, KEY_8 }, | ||
37 | { 0x030f, KEY_9 }, | ||
38 | { 0x0310, KEY_DOWN }, | ||
39 | { 0x0311, KEY_AGAIN }, | ||
40 | { 0x0312, KEY_0 }, | ||
41 | { 0x0313, KEY_OK }, /* 1st ok */ | ||
42 | { 0x0314, KEY_MUTE }, | ||
43 | { 0x0316, KEY_OK }, /* 2nd ok */ | ||
44 | { 0x031e, KEY_VIDEO }, /* 2nd video */ | ||
45 | { 0x031b, KEY_AUDIO }, | ||
46 | { 0x031f, KEY_TEXT }, | ||
47 | { 0x0340, KEY_SLEEP }, | ||
48 | { 0x0341, KEY_DOT }, | ||
49 | { 0x0342, KEY_REWIND }, | ||
50 | { 0x0343, KEY_PLAY }, | ||
51 | { 0x0344, KEY_FASTFORWARD }, | ||
52 | { 0x0345, KEY_TIME }, | ||
53 | { 0x0346, KEY_STOP }, /* 2nd stop */ | ||
54 | { 0x0347, KEY_RECORD }, | ||
55 | { 0x0348, KEY_CAMERA }, | ||
56 | { 0x0349, KEY_ESC }, | ||
57 | { 0x034a, KEY_NEW }, | ||
58 | { 0x034b, KEY_RED }, | ||
59 | { 0x034c, KEY_GREEN }, | ||
60 | { 0x034d, KEY_YELLOW }, | ||
61 | { 0x034e, KEY_BLUE }, | ||
62 | { 0x034f, KEY_MENU }, | ||
63 | { 0x0350, KEY_STOP }, /* 1st stop */ | ||
64 | { 0x0351, KEY_CHANNEL }, | ||
65 | { 0x0352, KEY_VIDEO }, /* 1st video */ | ||
66 | { 0x0353, KEY_EPG }, | ||
67 | { 0x0354, KEY_PREVIOUS }, | ||
68 | { 0x0355, KEY_NEXT }, | ||
69 | { 0x0356, KEY_TV }, | ||
70 | { 0x035a, KEY_VOLUMEDOWN }, | ||
71 | { 0x035b, KEY_CHANNELUP }, | ||
72 | { 0x035e, KEY_VOLUMEUP }, | ||
73 | { 0x035f, KEY_CHANNELDOWN }, | ||
74 | }; | ||
75 | |||
76 | static struct rc_keymap leadtek_y04g0051_map = { | ||
77 | .map = { | ||
78 | .scan = leadtek_y04g0051, | ||
79 | .size = ARRAY_SIZE(leadtek_y04g0051), | ||
80 | .ir_type = IR_TYPE_NEC, | ||
81 | .name = RC_MAP_LEADTEK_Y04G0051, | ||
82 | } | ||
83 | }; | ||
84 | |||
85 | static int __init init_rc_map_leadtek_y04g0051(void) | ||
86 | { | ||
87 | return ir_register_map(&leadtek_y04g0051_map); | ||
88 | } | ||
89 | |||
90 | static void __exit exit_rc_map_leadtek_y04g0051(void) | ||
91 | { | ||
92 | ir_unregister_map(&leadtek_y04g0051_map); | ||
93 | } | ||
94 | |||
95 | module_init(init_rc_map_leadtek_y04g0051) | ||
96 | module_exit(exit_rc_map_leadtek_y04g0051) | ||
97 | |||
98 | MODULE_LICENSE("GPL"); | ||
99 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-lme2510.c b/drivers/media/IR/keymaps/rc-lme2510.c new file mode 100644 index 00000000000..40dcf0b4e21 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-lme2510.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* LME2510 remote control | ||
2 | * | ||
3 | * | ||
4 | * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <media/rc-map.h> | ||
13 | |||
14 | |||
15 | static struct ir_scancode lme2510_rc[] = { | ||
16 | { 0xba45, KEY_0 }, | ||
17 | { 0xa05f, KEY_1 }, | ||
18 | { 0xaf50, KEY_2 }, | ||
19 | { 0xa25d, KEY_3 }, | ||
20 | { 0xbe41, KEY_4 }, | ||
21 | { 0xf50a, KEY_5 }, | ||
22 | { 0xbd42, KEY_6 }, | ||
23 | { 0xb847, KEY_7 }, | ||
24 | { 0xb649, KEY_8 }, | ||
25 | { 0xfa05, KEY_9 }, | ||
26 | { 0xbc43, KEY_POWER }, | ||
27 | { 0xb946, KEY_SUBTITLE }, | ||
28 | { 0xf906, KEY_PAUSE }, | ||
29 | { 0xfc03, KEY_MEDIA_REPEAT}, | ||
30 | { 0xfd02, KEY_PAUSE }, | ||
31 | { 0xa15e, KEY_VOLUMEUP }, | ||
32 | { 0xa35c, KEY_VOLUMEDOWN }, | ||
33 | { 0xf609, KEY_CHANNELUP }, | ||
34 | { 0xe51a, KEY_CHANNELDOWN }, | ||
35 | { 0xe11e, KEY_PLAY }, | ||
36 | { 0xe41b, KEY_ZOOM }, | ||
37 | { 0xa659, KEY_MUTE }, | ||
38 | { 0xa55a, KEY_TV }, | ||
39 | { 0xe718, KEY_RECORD }, | ||
40 | { 0xf807, KEY_EPG }, | ||
41 | { 0xfe01, KEY_STOP }, | ||
42 | |||
43 | }; | ||
44 | |||
45 | static struct rc_keymap lme2510_map = { | ||
46 | .map = { | ||
47 | .scan = lme2510_rc, | ||
48 | .size = ARRAY_SIZE(lme2510_rc), | ||
49 | .ir_type = IR_TYPE_UNKNOWN, | ||
50 | .name = RC_MAP_LME2510, | ||
51 | } | ||
52 | }; | ||
53 | |||
54 | static int __init init_rc_lme2510_map(void) | ||
55 | { | ||
56 | return ir_register_map(&lme2510_map); | ||
57 | } | ||
58 | |||
59 | static void __exit exit_rc_lme2510_map(void) | ||
60 | { | ||
61 | ir_unregister_map(&lme2510_map); | ||
62 | } | ||
63 | |||
64 | module_init(init_rc_lme2510_map) | ||
65 | module_exit(exit_rc_lme2510_map) | ||
66 | |||
67 | MODULE_LICENSE("GPL"); | ||
68 | MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); | ||
diff --git a/drivers/media/IR/keymaps/rc-msi-digivox-ii.c b/drivers/media/IR/keymaps/rc-msi-digivox-ii.c new file mode 100644 index 00000000000..67237fbf9e4 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-msi-digivox-ii.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * MSI DIGIVOX mini II remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | static struct ir_scancode msi_digivox_ii[] = { | ||
24 | { 0x0002, KEY_2 }, | ||
25 | { 0x0003, KEY_UP }, /* up */ | ||
26 | { 0x0004, KEY_3 }, | ||
27 | { 0x0005, KEY_CHANNELDOWN }, | ||
28 | { 0x0008, KEY_5 }, | ||
29 | { 0x0009, KEY_0 }, | ||
30 | { 0x000b, KEY_8 }, | ||
31 | { 0x000d, KEY_DOWN }, /* down */ | ||
32 | { 0x0010, KEY_9 }, | ||
33 | { 0x0011, KEY_7 }, | ||
34 | { 0x0014, KEY_VOLUMEUP }, | ||
35 | { 0x0015, KEY_CHANNELUP }, | ||
36 | { 0x0016, KEY_OK }, | ||
37 | { 0x0017, KEY_POWER2 }, | ||
38 | { 0x001a, KEY_1 }, | ||
39 | { 0x001c, KEY_4 }, | ||
40 | { 0x001d, KEY_6 }, | ||
41 | { 0x001f, KEY_VOLUMEDOWN }, | ||
42 | }; | ||
43 | |||
44 | static struct rc_keymap msi_digivox_ii_map = { | ||
45 | .map = { | ||
46 | .scan = msi_digivox_ii, | ||
47 | .size = ARRAY_SIZE(msi_digivox_ii), | ||
48 | .ir_type = IR_TYPE_NEC, | ||
49 | .name = RC_MAP_MSI_DIGIVOX_II, | ||
50 | } | ||
51 | }; | ||
52 | |||
53 | static int __init init_rc_map_msi_digivox_ii(void) | ||
54 | { | ||
55 | return ir_register_map(&msi_digivox_ii_map); | ||
56 | } | ||
57 | |||
58 | static void __exit exit_rc_map_msi_digivox_ii(void) | ||
59 | { | ||
60 | ir_unregister_map(&msi_digivox_ii_map); | ||
61 | } | ||
62 | |||
63 | module_init(init_rc_map_msi_digivox_ii) | ||
64 | module_exit(exit_rc_map_msi_digivox_ii) | ||
65 | |||
66 | MODULE_LICENSE("GPL"); | ||
67 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-msi-digivox-iii.c b/drivers/media/IR/keymaps/rc-msi-digivox-iii.c new file mode 100644 index 00000000000..882056e52ef --- /dev/null +++ b/drivers/media/IR/keymaps/rc-msi-digivox-iii.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * MSI DIGIVOX mini III remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* MSI DIGIVOX mini III */ | ||
24 | /* Uses NEC extended 0x61d6. */ | ||
25 | /* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote | ||
26 | since rc-kworld-315u.c lacks NEC extended address byte. */ | ||
27 | static struct ir_scancode msi_digivox_iii[] = { | ||
28 | { 0x61d601, KEY_VIDEO }, /* Source */ | ||
29 | { 0x61d602, KEY_3 }, | ||
30 | { 0x61d603, KEY_POWER }, /* ShutDown */ | ||
31 | { 0x61d604, KEY_1 }, | ||
32 | { 0x61d605, KEY_5 }, | ||
33 | { 0x61d606, KEY_6 }, | ||
34 | { 0x61d607, KEY_CHANNELDOWN }, /* CH- */ | ||
35 | { 0x61d608, KEY_2 }, | ||
36 | { 0x61d609, KEY_CHANNELUP }, /* CH+ */ | ||
37 | { 0x61d60a, KEY_9 }, | ||
38 | { 0x61d60b, KEY_ZOOM }, /* Zoom */ | ||
39 | { 0x61d60c, KEY_7 }, | ||
40 | { 0x61d60d, KEY_8 }, | ||
41 | { 0x61d60e, KEY_VOLUMEUP }, /* Vol+ */ | ||
42 | { 0x61d60f, KEY_4 }, | ||
43 | { 0x61d610, KEY_ESC }, /* [back up arrow] */ | ||
44 | { 0x61d611, KEY_0 }, | ||
45 | { 0x61d612, KEY_OK }, /* [enter arrow] */ | ||
46 | { 0x61d613, KEY_VOLUMEDOWN }, /* Vol- */ | ||
47 | { 0x61d614, KEY_RECORD }, /* Rec */ | ||
48 | { 0x61d615, KEY_STOP }, /* Stop */ | ||
49 | { 0x61d616, KEY_PLAY }, /* Play */ | ||
50 | { 0x61d617, KEY_MUTE }, /* Mute */ | ||
51 | { 0x61d618, KEY_UP }, | ||
52 | { 0x61d619, KEY_DOWN }, | ||
53 | { 0x61d61a, KEY_LEFT }, | ||
54 | { 0x61d61b, KEY_RIGHT }, | ||
55 | { 0x61d61c, KEY_RED }, | ||
56 | { 0x61d61d, KEY_GREEN }, | ||
57 | { 0x61d61e, KEY_YELLOW }, | ||
58 | { 0x61d61f, KEY_BLUE }, | ||
59 | { 0x61d643, KEY_POWER2 }, /* [red power button] */ | ||
60 | }; | ||
61 | |||
62 | static struct rc_keymap msi_digivox_iii_map = { | ||
63 | .map = { | ||
64 | .scan = msi_digivox_iii, | ||
65 | .size = ARRAY_SIZE(msi_digivox_iii), | ||
66 | .ir_type = IR_TYPE_NEC, | ||
67 | .name = RC_MAP_MSI_DIGIVOX_III, | ||
68 | } | ||
69 | }; | ||
70 | |||
71 | static int __init init_rc_map_msi_digivox_iii(void) | ||
72 | { | ||
73 | return ir_register_map(&msi_digivox_iii_map); | ||
74 | } | ||
75 | |||
76 | static void __exit exit_rc_map_msi_digivox_iii(void) | ||
77 | { | ||
78 | ir_unregister_map(&msi_digivox_iii_map); | ||
79 | } | ||
80 | |||
81 | module_init(init_rc_map_msi_digivox_iii) | ||
82 | module_exit(exit_rc_map_msi_digivox_iii) | ||
83 | |||
84 | MODULE_LICENSE("GPL"); | ||
85 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-rc5-streamzap.c b/drivers/media/IR/keymaps/rc-rc5-streamzap.c deleted file mode 100644 index 4c19c58b46d..00000000000 --- a/drivers/media/IR/keymaps/rc-rc5-streamzap.c +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | /* rc-rc5-streamzap.c - Keytable for Streamzap PC Remote, for use | ||
2 | * with the Streamzap PC Remote IR Receiver. | ||
3 | * | ||
4 | * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <media/rc-map.h> | ||
13 | |||
14 | static struct ir_scancode rc5_streamzap[] = { | ||
15 | /* | ||
16 | * FIXME: The Streamzap remote isn't actually true RC-5, it has an extra | ||
17 | * bit in it, which presently throws the in-kernel RC-5 decoder for a loop. | ||
18 | * We either have to enhance the decoder to support it, add a new decoder, | ||
19 | * or just rely on lirc userspace decoding. | ||
20 | */ | ||
21 | { 0x00, KEY_NUMERIC_0 }, | ||
22 | { 0x01, KEY_NUMERIC_1 }, | ||
23 | { 0x02, KEY_NUMERIC_2 }, | ||
24 | { 0x03, KEY_NUMERIC_3 }, | ||
25 | { 0x04, KEY_NUMERIC_4 }, | ||
26 | { 0x05, KEY_NUMERIC_5 }, | ||
27 | { 0x06, KEY_NUMERIC_6 }, | ||
28 | { 0x07, KEY_NUMERIC_7 }, | ||
29 | { 0x08, KEY_NUMERIC_8 }, | ||
30 | { 0x0a, KEY_POWER }, | ||
31 | { 0x0b, KEY_MUTE }, | ||
32 | { 0x0c, KEY_CHANNELUP }, | ||
33 | { 0x0d, KEY_VOLUMEUP }, | ||
34 | { 0x0e, KEY_CHANNELDOWN }, | ||
35 | { 0x0f, KEY_VOLUMEDOWN }, | ||
36 | { 0x10, KEY_UP }, | ||
37 | { 0x11, KEY_LEFT }, | ||
38 | { 0x12, KEY_OK }, | ||
39 | { 0x13, KEY_RIGHT }, | ||
40 | { 0x14, KEY_DOWN }, | ||
41 | { 0x15, KEY_MENU }, | ||
42 | { 0x16, KEY_EXIT }, | ||
43 | { 0x17, KEY_PLAY }, | ||
44 | { 0x18, KEY_PAUSE }, | ||
45 | { 0x19, KEY_STOP }, | ||
46 | { 0x1a, KEY_BACK }, | ||
47 | { 0x1b, KEY_FORWARD }, | ||
48 | { 0x1c, KEY_RECORD }, | ||
49 | { 0x1d, KEY_REWIND }, | ||
50 | { 0x1e, KEY_FASTFORWARD }, | ||
51 | { 0x20, KEY_RED }, | ||
52 | { 0x21, KEY_GREEN }, | ||
53 | { 0x22, KEY_YELLOW }, | ||
54 | { 0x23, KEY_BLUE }, | ||
55 | |||
56 | }; | ||
57 | |||
58 | static struct rc_keymap rc5_streamzap_map = { | ||
59 | .map = { | ||
60 | .scan = rc5_streamzap, | ||
61 | .size = ARRAY_SIZE(rc5_streamzap), | ||
62 | .ir_type = IR_TYPE_RC5, | ||
63 | .name = RC_MAP_RC5_STREAMZAP, | ||
64 | } | ||
65 | }; | ||
66 | |||
67 | static int __init init_rc_map_rc5_streamzap(void) | ||
68 | { | ||
69 | return ir_register_map(&rc5_streamzap_map); | ||
70 | } | ||
71 | |||
72 | static void __exit exit_rc_map_rc5_streamzap(void) | ||
73 | { | ||
74 | ir_unregister_map(&rc5_streamzap_map); | ||
75 | } | ||
76 | |||
77 | module_init(init_rc_map_rc5_streamzap) | ||
78 | module_exit(exit_rc_map_rc5_streamzap) | ||
79 | |||
80 | MODULE_LICENSE("GPL"); | ||
81 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c index 39557ad401b..1b7adabbcee 100644 --- a/drivers/media/IR/keymaps/rc-rc6-mce.c +++ b/drivers/media/IR/keymaps/rc-rc6-mce.c | |||
@@ -12,76 +12,78 @@ | |||
12 | #include <media/rc-map.h> | 12 | #include <media/rc-map.h> |
13 | 13 | ||
14 | static struct ir_scancode rc6_mce[] = { | 14 | static struct ir_scancode rc6_mce[] = { |
15 | { 0x800f0415, KEY_REWIND }, | ||
16 | { 0x800f0414, KEY_FASTFORWARD }, | ||
17 | { 0x800f041b, KEY_PREVIOUS }, | ||
18 | { 0x800f041a, KEY_NEXT }, | ||
19 | 15 | ||
16 | { 0x800f0400, KEY_NUMERIC_0 }, | ||
17 | { 0x800f0401, KEY_NUMERIC_1 }, | ||
18 | { 0x800f0402, KEY_NUMERIC_2 }, | ||
19 | { 0x800f0403, KEY_NUMERIC_3 }, | ||
20 | { 0x800f0404, KEY_NUMERIC_4 }, | ||
21 | { 0x800f0405, KEY_NUMERIC_5 }, | ||
22 | { 0x800f0406, KEY_NUMERIC_6 }, | ||
23 | { 0x800f0407, KEY_NUMERIC_7 }, | ||
24 | { 0x800f0408, KEY_NUMERIC_8 }, | ||
25 | { 0x800f0409, KEY_NUMERIC_9 }, | ||
26 | |||
27 | { 0x800f040a, KEY_DELETE }, | ||
28 | { 0x800f040b, KEY_ENTER }, | ||
29 | { 0x800f040c, KEY_POWER }, | ||
30 | { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ | ||
31 | { 0x800f040e, KEY_MUTE }, | ||
32 | { 0x800f040f, KEY_INFO }, | ||
33 | |||
34 | { 0x800f0410, KEY_VOLUMEUP }, | ||
35 | { 0x800f0411, KEY_VOLUMEDOWN }, | ||
36 | { 0x800f0412, KEY_CHANNELUP }, | ||
37 | { 0x800f0413, KEY_CHANNELDOWN }, | ||
38 | |||
39 | { 0x800f0414, KEY_FASTFORWARD }, | ||
40 | { 0x800f0415, KEY_REWIND }, | ||
20 | { 0x800f0416, KEY_PLAY }, | 41 | { 0x800f0416, KEY_PLAY }, |
42 | { 0x800f0417, KEY_RECORD }, | ||
21 | { 0x800f0418, KEY_PAUSE }, | 43 | { 0x800f0418, KEY_PAUSE }, |
22 | { 0x800f046e, KEY_PLAYPAUSE }, | 44 | { 0x800f046e, KEY_PLAYPAUSE }, |
23 | { 0x800f0419, KEY_STOP }, | 45 | { 0x800f0419, KEY_STOP }, |
24 | { 0x800f0417, KEY_RECORD }, | 46 | { 0x800f041a, KEY_NEXT }, |
47 | { 0x800f041b, KEY_PREVIOUS }, | ||
48 | { 0x800f041c, KEY_NUMERIC_POUND }, | ||
49 | { 0x800f041d, KEY_NUMERIC_STAR }, | ||
25 | 50 | ||
26 | { 0x800f041e, KEY_UP }, | 51 | { 0x800f041e, KEY_UP }, |
27 | { 0x800f041f, KEY_DOWN }, | 52 | { 0x800f041f, KEY_DOWN }, |
28 | { 0x800f0420, KEY_LEFT }, | 53 | { 0x800f0420, KEY_LEFT }, |
29 | { 0x800f0421, KEY_RIGHT }, | 54 | { 0x800f0421, KEY_RIGHT }, |
30 | 55 | ||
31 | { 0x800f040b, KEY_ENTER }, | ||
32 | { 0x800f0422, KEY_OK }, | 56 | { 0x800f0422, KEY_OK }, |
33 | { 0x800f0423, KEY_EXIT }, | 57 | { 0x800f0423, KEY_EXIT }, |
34 | { 0x800f040a, KEY_DELETE }, | 58 | { 0x800f0424, KEY_DVD }, |
59 | { 0x800f0425, KEY_TUNER }, /* LiveTV */ | ||
60 | { 0x800f0426, KEY_EPG }, /* Guide */ | ||
61 | { 0x800f0427, KEY_ZOOM }, /* Aspect */ | ||
35 | 62 | ||
36 | { 0x800f040e, KEY_MUTE }, | ||
37 | { 0x800f0410, KEY_VOLUMEUP }, | ||
38 | { 0x800f0411, KEY_VOLUMEDOWN }, | ||
39 | { 0x800f0412, KEY_CHANNELUP }, | ||
40 | { 0x800f0413, KEY_CHANNELDOWN }, | ||
41 | { 0x800f043a, KEY_BRIGHTNESSUP }, | 63 | { 0x800f043a, KEY_BRIGHTNESSUP }, |
42 | { 0x800f0480, KEY_BRIGHTNESSDOWN }, | ||
43 | |||
44 | { 0x800f0401, KEY_NUMERIC_1 }, | ||
45 | { 0x800f0402, KEY_NUMERIC_2 }, | ||
46 | { 0x800f0403, KEY_NUMERIC_3 }, | ||
47 | { 0x800f0404, KEY_NUMERIC_4 }, | ||
48 | { 0x800f0405, KEY_NUMERIC_5 }, | ||
49 | { 0x800f0406, KEY_NUMERIC_6 }, | ||
50 | { 0x800f0407, KEY_NUMERIC_7 }, | ||
51 | { 0x800f0408, KEY_NUMERIC_8 }, | ||
52 | { 0x800f0409, KEY_NUMERIC_9 }, | ||
53 | { 0x800f0400, KEY_NUMERIC_0 }, | ||
54 | |||
55 | { 0x800f041d, KEY_NUMERIC_STAR }, | ||
56 | { 0x800f041c, KEY_NUMERIC_POUND }, | ||
57 | 64 | ||
58 | { 0x800f0446, KEY_TV }, | 65 | { 0x800f0446, KEY_TV }, |
59 | { 0x800f0447, KEY_AUDIO }, /* My Music */ | 66 | { 0x800f0447, KEY_AUDIO }, /* My Music */ |
60 | { 0x800f0448, KEY_PVR }, /* RecordedTV */ | 67 | { 0x800f0448, KEY_PVR }, /* RecordedTV */ |
61 | { 0x800f0449, KEY_CAMERA }, | 68 | { 0x800f0449, KEY_CAMERA }, |
62 | { 0x800f044a, KEY_VIDEO }, | 69 | { 0x800f044a, KEY_VIDEO }, |
63 | { 0x800f0424, KEY_DVD }, | ||
64 | { 0x800f0425, KEY_TUNER }, /* LiveTV */ | ||
65 | { 0x800f0450, KEY_RADIO }, | ||
66 | |||
67 | { 0x800f044c, KEY_LANGUAGE }, | 70 | { 0x800f044c, KEY_LANGUAGE }, |
68 | { 0x800f0427, KEY_ZOOM }, /* Aspect */ | 71 | { 0x800f044d, KEY_TITLE }, |
72 | { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ | ||
69 | 73 | ||
74 | { 0x800f0450, KEY_RADIO }, | ||
75 | |||
76 | { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ | ||
70 | { 0x800f045b, KEY_RED }, | 77 | { 0x800f045b, KEY_RED }, |
71 | { 0x800f045c, KEY_GREEN }, | 78 | { 0x800f045c, KEY_GREEN }, |
72 | { 0x800f045d, KEY_YELLOW }, | 79 | { 0x800f045d, KEY_YELLOW }, |
73 | { 0x800f045e, KEY_BLUE }, | 80 | { 0x800f045e, KEY_BLUE }, |
74 | 81 | ||
75 | { 0x800f040f, KEY_INFO }, | 82 | { 0x800f046e, KEY_PLAYPAUSE }, |
76 | { 0x800f0426, KEY_EPG }, /* Guide */ | 83 | { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ |
77 | { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ | ||
78 | { 0x800f044d, KEY_TITLE }, | ||
79 | |||
80 | { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ | ||
81 | |||
82 | { 0x800f040c, KEY_POWER }, | ||
83 | { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ | ||
84 | 84 | ||
85 | { 0x800f0480, KEY_BRIGHTNESSDOWN }, | ||
86 | { 0x800f0481, KEY_PLAYPAUSE }, | ||
85 | }; | 87 | }; |
86 | 88 | ||
87 | static struct rc_keymap rc6_mce_map = { | 89 | static struct rc_keymap rc6_mce_map = { |
diff --git a/drivers/media/IR/keymaps/rc-streamzap.c b/drivers/media/IR/keymaps/rc-streamzap.c new file mode 100644 index 00000000000..df32013a321 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-streamzap.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* rc-streamzap.c - Keytable for Streamzap PC Remote, for use | ||
2 | * with the Streamzap PC Remote IR Receiver. | ||
3 | * | ||
4 | * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <media/rc-map.h> | ||
13 | |||
14 | static struct ir_scancode streamzap[] = { | ||
15 | /* | ||
16 | * The Streamzap remote is almost, but not quite, RC-5, as it has an extra | ||
17 | * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently, | ||
18 | * an additional RC-5-sz decoder is being deployed to support it, but it | ||
19 | * may be possible to merge it back with the standard RC-5 decoder. | ||
20 | */ | ||
21 | { 0x28c0, KEY_NUMERIC_0 }, | ||
22 | { 0x28c1, KEY_NUMERIC_1 }, | ||
23 | { 0x28c2, KEY_NUMERIC_2 }, | ||
24 | { 0x28c3, KEY_NUMERIC_3 }, | ||
25 | { 0x28c4, KEY_NUMERIC_4 }, | ||
26 | { 0x28c5, KEY_NUMERIC_5 }, | ||
27 | { 0x28c6, KEY_NUMERIC_6 }, | ||
28 | { 0x28c7, KEY_NUMERIC_7 }, | ||
29 | { 0x28c8, KEY_NUMERIC_8 }, | ||
30 | { 0x28c9, KEY_NUMERIC_9 }, | ||
31 | { 0x28ca, KEY_POWER }, | ||
32 | { 0x28cb, KEY_MUTE }, | ||
33 | { 0x28cc, KEY_CHANNELUP }, | ||
34 | { 0x28cd, KEY_VOLUMEUP }, | ||
35 | { 0x28ce, KEY_CHANNELDOWN }, | ||
36 | { 0x28cf, KEY_VOLUMEDOWN }, | ||
37 | { 0x28d0, KEY_UP }, | ||
38 | { 0x28d1, KEY_LEFT }, | ||
39 | { 0x28d2, KEY_OK }, | ||
40 | { 0x28d3, KEY_RIGHT }, | ||
41 | { 0x28d4, KEY_DOWN }, | ||
42 | { 0x28d5, KEY_MENU }, | ||
43 | { 0x28d6, KEY_EXIT }, | ||
44 | { 0x28d7, KEY_PLAY }, | ||
45 | { 0x28d8, KEY_PAUSE }, | ||
46 | { 0x28d9, KEY_STOP }, | ||
47 | { 0x28da, KEY_BACK }, | ||
48 | { 0x28db, KEY_FORWARD }, | ||
49 | { 0x28dc, KEY_RECORD }, | ||
50 | { 0x28dd, KEY_REWIND }, | ||
51 | { 0x28de, KEY_FASTFORWARD }, | ||
52 | { 0x28e0, KEY_RED }, | ||
53 | { 0x28e1, KEY_GREEN }, | ||
54 | { 0x28e2, KEY_YELLOW }, | ||
55 | { 0x28e3, KEY_BLUE }, | ||
56 | |||
57 | }; | ||
58 | |||
59 | static struct rc_keymap streamzap_map = { | ||
60 | .map = { | ||
61 | .scan = streamzap, | ||
62 | .size = ARRAY_SIZE(streamzap), | ||
63 | .ir_type = IR_TYPE_RC5_SZ, | ||
64 | .name = RC_MAP_STREAMZAP, | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | static int __init init_rc_map_streamzap(void) | ||
69 | { | ||
70 | return ir_register_map(&streamzap_map); | ||
71 | } | ||
72 | |||
73 | static void __exit exit_rc_map_streamzap(void) | ||
74 | { | ||
75 | ir_unregister_map(&streamzap_map); | ||
76 | } | ||
77 | |||
78 | module_init(init_rc_map_streamzap) | ||
79 | module_exit(exit_rc_map_streamzap) | ||
80 | |||
81 | MODULE_LICENSE("GPL"); | ||
82 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-terratec-slim.c b/drivers/media/IR/keymaps/rc-terratec-slim.c new file mode 100644 index 00000000000..10dee4c1def --- /dev/null +++ b/drivers/media/IR/keymaps/rc-terratec-slim.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * TerraTec remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* TerraTec slim remote, 7 rows, 4 columns. */ | ||
24 | /* Uses NEC extended 0x02bd. */ | ||
25 | static struct ir_scancode terratec_slim[] = { | ||
26 | { 0x02bd00, KEY_1 }, | ||
27 | { 0x02bd01, KEY_2 }, | ||
28 | { 0x02bd02, KEY_3 }, | ||
29 | { 0x02bd03, KEY_4 }, | ||
30 | { 0x02bd04, KEY_5 }, | ||
31 | { 0x02bd05, KEY_6 }, | ||
32 | { 0x02bd06, KEY_7 }, | ||
33 | { 0x02bd07, KEY_8 }, | ||
34 | { 0x02bd08, KEY_9 }, | ||
35 | { 0x02bd09, KEY_0 }, | ||
36 | { 0x02bd0a, KEY_MUTE }, | ||
37 | { 0x02bd0b, KEY_NEW }, /* symbol: PIP */ | ||
38 | { 0x02bd0e, KEY_VOLUMEDOWN }, | ||
39 | { 0x02bd0f, KEY_PLAYPAUSE }, | ||
40 | { 0x02bd10, KEY_RIGHT }, | ||
41 | { 0x02bd11, KEY_LEFT }, | ||
42 | { 0x02bd12, KEY_UP }, | ||
43 | { 0x02bd13, KEY_DOWN }, | ||
44 | { 0x02bd15, KEY_OK }, | ||
45 | { 0x02bd16, KEY_STOP }, | ||
46 | { 0x02bd17, KEY_CAMERA }, /* snapshot */ | ||
47 | { 0x02bd18, KEY_CHANNELUP }, | ||
48 | { 0x02bd19, KEY_RECORD }, | ||
49 | { 0x02bd1a, KEY_CHANNELDOWN }, | ||
50 | { 0x02bd1c, KEY_ESC }, | ||
51 | { 0x02bd1f, KEY_VOLUMEUP }, | ||
52 | { 0x02bd44, KEY_EPG }, | ||
53 | { 0x02bd45, KEY_POWER2 }, /* [red power button] */ | ||
54 | }; | ||
55 | |||
56 | static struct rc_keymap terratec_slim_map = { | ||
57 | .map = { | ||
58 | .scan = terratec_slim, | ||
59 | .size = ARRAY_SIZE(terratec_slim), | ||
60 | .ir_type = IR_TYPE_NEC, | ||
61 | .name = RC_MAP_TERRATEC_SLIM, | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | static int __init init_rc_map_terratec_slim(void) | ||
66 | { | ||
67 | return ir_register_map(&terratec_slim_map); | ||
68 | } | ||
69 | |||
70 | static void __exit exit_rc_map_terratec_slim(void) | ||
71 | { | ||
72 | ir_unregister_map(&terratec_slim_map); | ||
73 | } | ||
74 | |||
75 | module_init(init_rc_map_terratec_slim) | ||
76 | module_exit(exit_rc_map_terratec_slim) | ||
77 | |||
78 | MODULE_LICENSE("GPL"); | ||
79 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-total-media-in-hand.c b/drivers/media/IR/keymaps/rc-total-media-in-hand.c new file mode 100644 index 00000000000..fd198576378 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-total-media-in-hand.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Total Media In Hand remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* Uses NEC extended 0x02bd */ | ||
24 | static struct ir_scancode total_media_in_hand[] = { | ||
25 | { 0x02bd00, KEY_1 }, | ||
26 | { 0x02bd01, KEY_2 }, | ||
27 | { 0x02bd02, KEY_3 }, | ||
28 | { 0x02bd03, KEY_4 }, | ||
29 | { 0x02bd04, KEY_5 }, | ||
30 | { 0x02bd05, KEY_6 }, | ||
31 | { 0x02bd06, KEY_7 }, | ||
32 | { 0x02bd07, KEY_8 }, | ||
33 | { 0x02bd08, KEY_9 }, | ||
34 | { 0x02bd09, KEY_0 }, | ||
35 | { 0x02bd0a, KEY_MUTE }, | ||
36 | { 0x02bd0b, KEY_CYCLEWINDOWS }, /* yellow, [min / max] */ | ||
37 | { 0x02bd0c, KEY_VIDEO }, /* TV / AV */ | ||
38 | { 0x02bd0e, KEY_VOLUMEDOWN }, | ||
39 | { 0x02bd0f, KEY_TIME }, /* TimeShift */ | ||
40 | { 0x02bd10, KEY_RIGHT }, /* right arrow */ | ||
41 | { 0x02bd11, KEY_LEFT }, /* left arrow */ | ||
42 | { 0x02bd12, KEY_UP }, /* up arrow */ | ||
43 | { 0x02bd13, KEY_DOWN }, /* down arrow */ | ||
44 | { 0x02bd14, KEY_POWER2 }, /* [red] */ | ||
45 | { 0x02bd15, KEY_OK }, /* OK */ | ||
46 | { 0x02bd16, KEY_STOP }, | ||
47 | { 0x02bd17, KEY_CAMERA }, /* Snapshot */ | ||
48 | { 0x02bd18, KEY_CHANNELUP }, | ||
49 | { 0x02bd19, KEY_RECORD }, | ||
50 | { 0x02bd1a, KEY_CHANNELDOWN }, | ||
51 | { 0x02bd1c, KEY_ESC }, /* Esc */ | ||
52 | { 0x02bd1e, KEY_PLAY }, | ||
53 | { 0x02bd1f, KEY_VOLUMEUP }, | ||
54 | { 0x02bd40, KEY_PAUSE }, | ||
55 | { 0x02bd41, KEY_FASTFORWARD }, /* FF >> */ | ||
56 | { 0x02bd42, KEY_REWIND }, /* FR << */ | ||
57 | { 0x02bd43, KEY_ZOOM }, /* [window + mouse pointer] */ | ||
58 | { 0x02bd44, KEY_SHUFFLE }, /* Shuffle */ | ||
59 | { 0x02bd45, KEY_INFO }, /* [red (I)] */ | ||
60 | }; | ||
61 | |||
62 | static struct rc_keymap total_media_in_hand_map = { | ||
63 | .map = { | ||
64 | .scan = total_media_in_hand, | ||
65 | .size = ARRAY_SIZE(total_media_in_hand), | ||
66 | .ir_type = IR_TYPE_NEC, | ||
67 | .name = RC_MAP_TOTAL_MEDIA_IN_HAND, | ||
68 | } | ||
69 | }; | ||
70 | |||
71 | static int __init init_rc_map_total_media_in_hand(void) | ||
72 | { | ||
73 | return ir_register_map(&total_media_in_hand_map); | ||
74 | } | ||
75 | |||
76 | static void __exit exit_rc_map_total_media_in_hand(void) | ||
77 | { | ||
78 | ir_unregister_map(&total_media_in_hand_map); | ||
79 | } | ||
80 | |||
81 | module_init(init_rc_map_total_media_in_hand) | ||
82 | module_exit(exit_rc_map_total_media_in_hand) | ||
83 | |||
84 | MODULE_LICENSE("GPL"); | ||
85 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-trekstor.c b/drivers/media/IR/keymaps/rc-trekstor.c new file mode 100644 index 00000000000..91092caca45 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-trekstor.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * TrekStor remote controller keytable | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-map.h> | ||
22 | |||
23 | /* TrekStor DVB-T USB Stick remote controller. */ | ||
24 | /* Imported from af9015.h. | ||
25 | Initial keytable was from Marc Schneider <macke@macke.org> */ | ||
26 | static struct ir_scancode trekstor[] = { | ||
27 | { 0x0084, KEY_0 }, | ||
28 | { 0x0085, KEY_MUTE }, /* Mute */ | ||
29 | { 0x0086, KEY_HOMEPAGE }, /* Home */ | ||
30 | { 0x0087, KEY_UP }, /* Up */ | ||
31 | { 0x0088, KEY_OK }, /* OK */ | ||
32 | { 0x0089, KEY_RIGHT }, /* Right */ | ||
33 | { 0x008a, KEY_FASTFORWARD }, /* Fast forward */ | ||
34 | { 0x008b, KEY_VOLUMEUP }, /* Volume + */ | ||
35 | { 0x008c, KEY_DOWN }, /* Down */ | ||
36 | { 0x008d, KEY_PLAY }, /* Play/Pause */ | ||
37 | { 0x008e, KEY_STOP }, /* Stop */ | ||
38 | { 0x008f, KEY_EPG }, /* Info/EPG */ | ||
39 | { 0x0090, KEY_7 }, | ||
40 | { 0x0091, KEY_4 }, | ||
41 | { 0x0092, KEY_1 }, | ||
42 | { 0x0093, KEY_CHANNELDOWN }, /* Channel - */ | ||
43 | { 0x0094, KEY_8 }, | ||
44 | { 0x0095, KEY_5 }, | ||
45 | { 0x0096, KEY_2 }, | ||
46 | { 0x0097, KEY_CHANNELUP }, /* Channel + */ | ||
47 | { 0x0098, KEY_9 }, | ||
48 | { 0x0099, KEY_6 }, | ||
49 | { 0x009a, KEY_3 }, | ||
50 | { 0x009b, KEY_VOLUMEDOWN }, /* Volume - */ | ||
51 | { 0x009c, KEY_TV }, /* TV */ | ||
52 | { 0x009d, KEY_RECORD }, /* Record */ | ||
53 | { 0x009e, KEY_REWIND }, /* Rewind */ | ||
54 | { 0x009f, KEY_LEFT }, /* Left */ | ||
55 | }; | ||
56 | |||
57 | static struct rc_keymap trekstor_map = { | ||
58 | .map = { | ||
59 | .scan = trekstor, | ||
60 | .size = ARRAY_SIZE(trekstor), | ||
61 | .ir_type = IR_TYPE_NEC, | ||
62 | .name = RC_MAP_TREKSTOR, | ||
63 | } | ||
64 | }; | ||
65 | |||
66 | static int __init init_rc_map_trekstor(void) | ||
67 | { | ||
68 | return ir_register_map(&trekstor_map); | ||
69 | } | ||
70 | |||
71 | static void __exit exit_rc_map_trekstor(void) | ||
72 | { | ||
73 | ir_unregister_map(&trekstor_map); | ||
74 | } | ||
75 | |||
76 | module_init(init_rc_map_trekstor) | ||
77 | module_exit(exit_rc_map_trekstor) | ||
78 | |||
79 | MODULE_LICENSE("GPL"); | ||
80 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-twinhan1027.c b/drivers/media/IR/keymaps/rc-twinhan1027.c new file mode 100644 index 00000000000..0b5d356c2d8 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-twinhan1027.c | |||
@@ -0,0 +1,87 @@ | |||
1 | #include <media/rc-map.h> | ||
2 | |||
3 | static struct ir_scancode twinhan_vp1027[] = { | ||
4 | { 0x16, KEY_POWER2 }, | ||
5 | { 0x17, KEY_FAVORITES }, | ||
6 | { 0x0f, KEY_TEXT }, | ||
7 | { 0x48, KEY_INFO}, | ||
8 | { 0x1c, KEY_EPG }, | ||
9 | { 0x04, KEY_LIST }, | ||
10 | |||
11 | { 0x03, KEY_1 }, | ||
12 | { 0x01, KEY_2 }, | ||
13 | { 0x06, KEY_3 }, | ||
14 | { 0x09, KEY_4 }, | ||
15 | { 0x1d, KEY_5 }, | ||
16 | { 0x1f, KEY_6 }, | ||
17 | { 0x0d, KEY_7 }, | ||
18 | { 0x19, KEY_8 }, | ||
19 | { 0x1b, KEY_9 }, | ||
20 | { 0x15, KEY_0 }, | ||
21 | |||
22 | { 0x0c, KEY_CANCEL }, | ||
23 | { 0x4a, KEY_CLEAR }, | ||
24 | { 0x13, KEY_BACKSPACE }, | ||
25 | { 0x00, KEY_TAB }, | ||
26 | |||
27 | { 0x4b, KEY_UP }, | ||
28 | { 0x51, KEY_DOWN }, | ||
29 | { 0x4e, KEY_LEFT }, | ||
30 | { 0x52, KEY_RIGHT }, | ||
31 | { 0x4f, KEY_ENTER }, | ||
32 | |||
33 | { 0x1e, KEY_VOLUMEUP }, | ||
34 | { 0x0a, KEY_VOLUMEDOWN }, | ||
35 | { 0x02, KEY_CHANNELDOWN }, | ||
36 | { 0x05, KEY_CHANNELUP }, | ||
37 | { 0x11, KEY_RECORD }, | ||
38 | |||
39 | { 0x14, KEY_PLAY }, | ||
40 | { 0x4c, KEY_PAUSE }, | ||
41 | { 0x1a, KEY_STOP }, | ||
42 | { 0x40, KEY_REWIND }, | ||
43 | { 0x12, KEY_FASTFORWARD }, | ||
44 | { 0x41, KEY_PREVIOUSSONG }, | ||
45 | { 0x42, KEY_NEXTSONG }, | ||
46 | { 0x54, KEY_SAVE }, | ||
47 | { 0x50, KEY_LANGUAGE }, | ||
48 | { 0x47, KEY_MEDIA }, | ||
49 | { 0x4d, KEY_SCREEN }, | ||
50 | { 0x43, KEY_SUBTITLE }, | ||
51 | { 0x10, KEY_MUTE }, | ||
52 | { 0x49, KEY_AUDIO }, | ||
53 | { 0x07, KEY_SLEEP }, | ||
54 | { 0x08, KEY_VIDEO }, | ||
55 | { 0x0e, KEY_AGAIN }, | ||
56 | { 0x45, KEY_EQUAL }, | ||
57 | { 0x46, KEY_MINUS }, | ||
58 | { 0x18, KEY_RED }, | ||
59 | { 0x53, KEY_GREEN }, | ||
60 | { 0x5e, KEY_YELLOW }, | ||
61 | { 0x5f, KEY_BLUE }, | ||
62 | }; | ||
63 | |||
64 | static struct rc_keymap twinhan_vp1027_map = { | ||
65 | .map = { | ||
66 | .scan = twinhan_vp1027, | ||
67 | .size = ARRAY_SIZE(twinhan_vp1027), | ||
68 | .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ | ||
69 | .name = RC_MAP_TWINHAN_VP1027_DVBS, | ||
70 | } | ||
71 | }; | ||
72 | |||
73 | static int __init init_rc_map_twinhan_vp1027(void) | ||
74 | { | ||
75 | return ir_register_map(&twinhan_vp1027_map); | ||
76 | } | ||
77 | |||
78 | static void __exit exit_rc_map_twinhan_vp1027(void) | ||
79 | { | ||
80 | ir_unregister_map(&twinhan_vp1027_map); | ||
81 | } | ||
82 | |||
83 | module_init(init_rc_map_twinhan_vp1027) | ||
84 | module_exit(exit_rc_map_twinhan_vp1027) | ||
85 | |||
86 | MODULE_LICENSE("GPL"); | ||
87 | MODULE_AUTHOR("Sergey Ivanov <123kash@gmail.com>"); | ||
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c index 202581808bd..8418b14ee4d 100644 --- a/drivers/media/IR/lirc_dev.c +++ b/drivers/media/IR/lirc_dev.c | |||
@@ -57,13 +57,12 @@ struct irctl { | |||
57 | 57 | ||
58 | struct task_struct *task; | 58 | struct task_struct *task; |
59 | long jiffies_to_wait; | 59 | long jiffies_to_wait; |
60 | |||
61 | struct cdev cdev; | ||
62 | }; | 60 | }; |
63 | 61 | ||
64 | static DEFINE_MUTEX(lirc_dev_lock); | 62 | static DEFINE_MUTEX(lirc_dev_lock); |
65 | 63 | ||
66 | static struct irctl *irctls[MAX_IRCTL_DEVICES]; | 64 | static struct irctl *irctls[MAX_IRCTL_DEVICES]; |
65 | static struct cdev cdevs[MAX_IRCTL_DEVICES]; | ||
67 | 66 | ||
68 | /* Only used for sysfs but defined to void otherwise */ | 67 | /* Only used for sysfs but defined to void otherwise */ |
69 | static struct class *lirc_class; | 68 | static struct class *lirc_class; |
@@ -71,15 +70,13 @@ static struct class *lirc_class; | |||
71 | /* helper function | 70 | /* helper function |
72 | * initializes the irctl structure | 71 | * initializes the irctl structure |
73 | */ | 72 | */ |
74 | static void init_irctl(struct irctl *ir) | 73 | static void lirc_irctl_init(struct irctl *ir) |
75 | { | 74 | { |
76 | dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n", | ||
77 | ir->d.name, ir->d.minor); | ||
78 | mutex_init(&ir->irctl_lock); | 75 | mutex_init(&ir->irctl_lock); |
79 | ir->d.minor = NOPLUG; | 76 | ir->d.minor = NOPLUG; |
80 | } | 77 | } |
81 | 78 | ||
82 | static void cleanup(struct irctl *ir) | 79 | static void lirc_irctl_cleanup(struct irctl *ir) |
83 | { | 80 | { |
84 | dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); | 81 | dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); |
85 | 82 | ||
@@ -96,7 +93,7 @@ static void cleanup(struct irctl *ir) | |||
96 | * reads key codes from driver and puts them into buffer | 93 | * reads key codes from driver and puts them into buffer |
97 | * returns 0 on success | 94 | * returns 0 on success |
98 | */ | 95 | */ |
99 | static int add_to_buf(struct irctl *ir) | 96 | static int lirc_add_to_buf(struct irctl *ir) |
100 | { | 97 | { |
101 | if (ir->d.add_to_buf) { | 98 | if (ir->d.add_to_buf) { |
102 | int res = -ENODATA; | 99 | int res = -ENODATA; |
@@ -139,7 +136,7 @@ static int lirc_thread(void *irctl) | |||
139 | } | 136 | } |
140 | if (kthread_should_stop()) | 137 | if (kthread_should_stop()) |
141 | break; | 138 | break; |
142 | if (!add_to_buf(ir)) | 139 | if (!lirc_add_to_buf(ir)) |
143 | wake_up_interruptible(&ir->buf->wait_poll); | 140 | wake_up_interruptible(&ir->buf->wait_poll); |
144 | } else { | 141 | } else { |
145 | set_current_state(TASK_INTERRUPTIBLE); | 142 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -154,12 +151,15 @@ static int lirc_thread(void *irctl) | |||
154 | } | 151 | } |
155 | 152 | ||
156 | 153 | ||
157 | static struct file_operations fops = { | 154 | static struct file_operations lirc_dev_fops = { |
158 | .owner = THIS_MODULE, | 155 | .owner = THIS_MODULE, |
159 | .read = lirc_dev_fop_read, | 156 | .read = lirc_dev_fop_read, |
160 | .write = lirc_dev_fop_write, | 157 | .write = lirc_dev_fop_write, |
161 | .poll = lirc_dev_fop_poll, | 158 | .poll = lirc_dev_fop_poll, |
162 | .unlocked_ioctl = lirc_dev_fop_ioctl, | 159 | .unlocked_ioctl = lirc_dev_fop_ioctl, |
160 | #ifdef CONFIG_COMPAT | ||
161 | .compat_ioctl = lirc_dev_fop_ioctl, | ||
162 | #endif | ||
163 | .open = lirc_dev_fop_open, | 163 | .open = lirc_dev_fop_open, |
164 | .release = lirc_dev_fop_close, | 164 | .release = lirc_dev_fop_close, |
165 | .llseek = noop_llseek, | 165 | .llseek = noop_llseek, |
@@ -169,19 +169,20 @@ static int lirc_cdev_add(struct irctl *ir) | |||
169 | { | 169 | { |
170 | int retval; | 170 | int retval; |
171 | struct lirc_driver *d = &ir->d; | 171 | struct lirc_driver *d = &ir->d; |
172 | struct cdev *cdev = &cdevs[d->minor]; | ||
172 | 173 | ||
173 | if (d->fops) { | 174 | if (d->fops) { |
174 | cdev_init(&ir->cdev, d->fops); | 175 | cdev_init(cdev, d->fops); |
175 | ir->cdev.owner = d->owner; | 176 | cdev->owner = d->owner; |
176 | } else { | 177 | } else { |
177 | cdev_init(&ir->cdev, &fops); | 178 | cdev_init(cdev, &lirc_dev_fops); |
178 | ir->cdev.owner = THIS_MODULE; | 179 | cdev->owner = THIS_MODULE; |
179 | } | 180 | } |
180 | kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor); | 181 | kobject_set_name(&cdev->kobj, "lirc%d", d->minor); |
181 | 182 | ||
182 | retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); | 183 | retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); |
183 | if (retval) | 184 | if (retval) |
184 | kobject_put(&ir->cdev.kobj); | 185 | kobject_put(&cdev->kobj); |
185 | 186 | ||
186 | return retval; | 187 | return retval; |
187 | } | 188 | } |
@@ -202,6 +203,12 @@ int lirc_register_driver(struct lirc_driver *d) | |||
202 | goto out; | 203 | goto out; |
203 | } | 204 | } |
204 | 205 | ||
206 | if (!d->dev) { | ||
207 | printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__); | ||
208 | err = -EINVAL; | ||
209 | goto out; | ||
210 | } | ||
211 | |||
205 | if (MAX_IRCTL_DEVICES <= d->minor) { | 212 | if (MAX_IRCTL_DEVICES <= d->minor) { |
206 | dev_err(d->dev, "lirc_dev: lirc_register_driver: " | 213 | dev_err(d->dev, "lirc_dev: lirc_register_driver: " |
207 | "\"minor\" must be between 0 and %d (%d)!\n", | 214 | "\"minor\" must be between 0 and %d (%d)!\n", |
@@ -277,7 +284,7 @@ int lirc_register_driver(struct lirc_driver *d) | |||
277 | err = -ENOMEM; | 284 | err = -ENOMEM; |
278 | goto out_lock; | 285 | goto out_lock; |
279 | } | 286 | } |
280 | init_irctl(ir); | 287 | lirc_irctl_init(ir); |
281 | irctls[minor] = ir; | 288 | irctls[minor] = ir; |
282 | d->minor = minor; | 289 | d->minor = minor; |
283 | 290 | ||
@@ -316,7 +323,6 @@ int lirc_register_driver(struct lirc_driver *d) | |||
316 | d->features = LIRC_CAN_REC_LIRCCODE; | 323 | d->features = LIRC_CAN_REC_LIRCCODE; |
317 | 324 | ||
318 | ir->d = *d; | 325 | ir->d = *d; |
319 | ir->d.minor = minor; | ||
320 | 326 | ||
321 | device_create(lirc_class, ir->d.dev, | 327 | device_create(lirc_class, ir->d.dev, |
322 | MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, | 328 | MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, |
@@ -357,21 +363,28 @@ EXPORT_SYMBOL(lirc_register_driver); | |||
357 | int lirc_unregister_driver(int minor) | 363 | int lirc_unregister_driver(int minor) |
358 | { | 364 | { |
359 | struct irctl *ir; | 365 | struct irctl *ir; |
366 | struct cdev *cdev; | ||
360 | 367 | ||
361 | if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { | 368 | if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { |
362 | printk(KERN_ERR "lirc_dev: lirc_unregister_driver: " | 369 | printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " |
363 | "\"minor (%d)\" must be between 0 and %d!\n", | 370 | "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1); |
364 | minor, MAX_IRCTL_DEVICES-1); | ||
365 | return -EBADRQC; | 371 | return -EBADRQC; |
366 | } | 372 | } |
367 | 373 | ||
368 | ir = irctls[minor]; | 374 | ir = irctls[minor]; |
375 | if (!ir) { | ||
376 | printk(KERN_ERR "lirc_dev: %s: failed to get irctl struct " | ||
377 | "for minor %d!\n", __func__, minor); | ||
378 | return -ENOENT; | ||
379 | } | ||
380 | |||
381 | cdev = &cdevs[minor]; | ||
369 | 382 | ||
370 | mutex_lock(&lirc_dev_lock); | 383 | mutex_lock(&lirc_dev_lock); |
371 | 384 | ||
372 | if (ir->d.minor != minor) { | 385 | if (ir->d.minor != minor) { |
373 | printk(KERN_ERR "lirc_dev: lirc_unregister_driver: " | 386 | printk(KERN_ERR "lirc_dev: %s: minor (%d) device not " |
374 | "minor (%d) device not registered!", minor); | 387 | "registered!\n", __func__, minor); |
375 | mutex_unlock(&lirc_dev_lock); | 388 | mutex_unlock(&lirc_dev_lock); |
376 | return -ENOENT; | 389 | return -ENOENT; |
377 | } | 390 | } |
@@ -390,12 +403,11 @@ int lirc_unregister_driver(int minor) | |||
390 | wake_up_interruptible(&ir->buf->wait_poll); | 403 | wake_up_interruptible(&ir->buf->wait_poll); |
391 | mutex_lock(&ir->irctl_lock); | 404 | mutex_lock(&ir->irctl_lock); |
392 | ir->d.set_use_dec(ir->d.data); | 405 | ir->d.set_use_dec(ir->d.data); |
393 | module_put(ir->d.owner); | 406 | module_put(cdev->owner); |
394 | mutex_unlock(&ir->irctl_lock); | 407 | mutex_unlock(&ir->irctl_lock); |
395 | cdev_del(&ir->cdev); | ||
396 | } else { | 408 | } else { |
397 | cleanup(ir); | 409 | lirc_irctl_cleanup(ir); |
398 | cdev_del(&ir->cdev); | 410 | cdev_del(cdev); |
399 | kfree(ir); | 411 | kfree(ir); |
400 | irctls[minor] = NULL; | 412 | irctls[minor] = NULL; |
401 | } | 413 | } |
@@ -409,6 +421,7 @@ EXPORT_SYMBOL(lirc_unregister_driver); | |||
409 | int lirc_dev_fop_open(struct inode *inode, struct file *file) | 421 | int lirc_dev_fop_open(struct inode *inode, struct file *file) |
410 | { | 422 | { |
411 | struct irctl *ir; | 423 | struct irctl *ir; |
424 | struct cdev *cdev; | ||
412 | int retval = 0; | 425 | int retval = 0; |
413 | 426 | ||
414 | if (iminor(inode) >= MAX_IRCTL_DEVICES) { | 427 | if (iminor(inode) >= MAX_IRCTL_DEVICES) { |
@@ -425,7 +438,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) | |||
425 | retval = -ENODEV; | 438 | retval = -ENODEV; |
426 | goto error; | 439 | goto error; |
427 | } | 440 | } |
428 | file->private_data = ir; | ||
429 | 441 | ||
430 | dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); | 442 | dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); |
431 | 443 | ||
@@ -439,13 +451,14 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) | |||
439 | goto error; | 451 | goto error; |
440 | } | 452 | } |
441 | 453 | ||
442 | if (try_module_get(ir->d.owner)) { | 454 | cdev = &cdevs[iminor(inode)]; |
443 | ++ir->open; | 455 | if (try_module_get(cdev->owner)) { |
456 | ir->open++; | ||
444 | retval = ir->d.set_use_inc(ir->d.data); | 457 | retval = ir->d.set_use_inc(ir->d.data); |
445 | 458 | ||
446 | if (retval) { | 459 | if (retval) { |
447 | module_put(ir->d.owner); | 460 | module_put(cdev->owner); |
448 | --ir->open; | 461 | ir->open--; |
449 | } else { | 462 | } else { |
450 | lirc_buffer_clear(ir->buf); | 463 | lirc_buffer_clear(ir->buf); |
451 | } | 464 | } |
@@ -469,17 +482,24 @@ EXPORT_SYMBOL(lirc_dev_fop_open); | |||
469 | int lirc_dev_fop_close(struct inode *inode, struct file *file) | 482 | int lirc_dev_fop_close(struct inode *inode, struct file *file) |
470 | { | 483 | { |
471 | struct irctl *ir = irctls[iminor(inode)]; | 484 | struct irctl *ir = irctls[iminor(inode)]; |
485 | struct cdev *cdev = &cdevs[iminor(inode)]; | ||
486 | |||
487 | if (!ir) { | ||
488 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); | ||
489 | return -EINVAL; | ||
490 | } | ||
472 | 491 | ||
473 | dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); | 492 | dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); |
474 | 493 | ||
475 | WARN_ON(mutex_lock_killable(&lirc_dev_lock)); | 494 | WARN_ON(mutex_lock_killable(&lirc_dev_lock)); |
476 | 495 | ||
477 | --ir->open; | 496 | ir->open--; |
478 | if (ir->attached) { | 497 | if (ir->attached) { |
479 | ir->d.set_use_dec(ir->d.data); | 498 | ir->d.set_use_dec(ir->d.data); |
480 | module_put(ir->d.owner); | 499 | module_put(cdev->owner); |
481 | } else { | 500 | } else { |
482 | cleanup(ir); | 501 | lirc_irctl_cleanup(ir); |
502 | cdev_del(cdev); | ||
483 | irctls[ir->d.minor] = NULL; | 503 | irctls[ir->d.minor] = NULL; |
484 | kfree(ir); | 504 | kfree(ir); |
485 | } | 505 | } |
@@ -495,6 +515,11 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) | |||
495 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; | 515 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; |
496 | unsigned int ret; | 516 | unsigned int ret; |
497 | 517 | ||
518 | if (!ir) { | ||
519 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); | ||
520 | return POLLERR; | ||
521 | } | ||
522 | |||
498 | dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); | 523 | dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); |
499 | 524 | ||
500 | if (!ir->attached) { | 525 | if (!ir->attached) { |
@@ -521,9 +546,14 @@ EXPORT_SYMBOL(lirc_dev_fop_poll); | |||
521 | 546 | ||
522 | long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 547 | long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
523 | { | 548 | { |
524 | unsigned long mode; | 549 | __u32 mode; |
525 | int result = 0; | 550 | int result = 0; |
526 | struct irctl *ir = file->private_data; | 551 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; |
552 | |||
553 | if (!ir) { | ||
554 | printk(KERN_ERR "lirc_dev: %s: no irctl found!\n", __func__); | ||
555 | return -ENODEV; | ||
556 | } | ||
527 | 557 | ||
528 | dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", | 558 | dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", |
529 | ir->d.name, ir->d.minor, cmd); | 559 | ir->d.name, ir->d.minor, cmd); |
@@ -538,7 +568,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
538 | 568 | ||
539 | switch (cmd) { | 569 | switch (cmd) { |
540 | case LIRC_GET_FEATURES: | 570 | case LIRC_GET_FEATURES: |
541 | result = put_user(ir->d.features, (unsigned long *)arg); | 571 | result = put_user(ir->d.features, (__u32 *)arg); |
542 | break; | 572 | break; |
543 | case LIRC_GET_REC_MODE: | 573 | case LIRC_GET_REC_MODE: |
544 | if (!(ir->d.features & LIRC_CAN_REC_MASK)) { | 574 | if (!(ir->d.features & LIRC_CAN_REC_MASK)) { |
@@ -548,7 +578,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
548 | 578 | ||
549 | result = put_user(LIRC_REC2MODE | 579 | result = put_user(LIRC_REC2MODE |
550 | (ir->d.features & LIRC_CAN_REC_MASK), | 580 | (ir->d.features & LIRC_CAN_REC_MASK), |
551 | (unsigned long *)arg); | 581 | (__u32 *)arg); |
552 | break; | 582 | break; |
553 | case LIRC_SET_REC_MODE: | 583 | case LIRC_SET_REC_MODE: |
554 | if (!(ir->d.features & LIRC_CAN_REC_MASK)) { | 584 | if (!(ir->d.features & LIRC_CAN_REC_MASK)) { |
@@ -556,7 +586,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
556 | break; | 586 | break; |
557 | } | 587 | } |
558 | 588 | ||
559 | result = get_user(mode, (unsigned long *)arg); | 589 | result = get_user(mode, (__u32 *)arg); |
560 | if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) | 590 | if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) |
561 | result = -EINVAL; | 591 | result = -EINVAL; |
562 | /* | 592 | /* |
@@ -565,7 +595,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
565 | */ | 595 | */ |
566 | break; | 596 | break; |
567 | case LIRC_GET_LENGTH: | 597 | case LIRC_GET_LENGTH: |
568 | result = put_user(ir->d.code_length, (unsigned long *)arg); | 598 | result = put_user(ir->d.code_length, (__u32 *)arg); |
569 | break; | 599 | break; |
570 | case LIRC_GET_MIN_TIMEOUT: | 600 | case LIRC_GET_MIN_TIMEOUT: |
571 | if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || | 601 | if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || |
@@ -574,7 +604,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
574 | break; | 604 | break; |
575 | } | 605 | } |
576 | 606 | ||
577 | result = put_user(ir->d.min_timeout, (unsigned long *)arg); | 607 | result = put_user(ir->d.min_timeout, (__u32 *)arg); |
578 | break; | 608 | break; |
579 | case LIRC_GET_MAX_TIMEOUT: | 609 | case LIRC_GET_MAX_TIMEOUT: |
580 | if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || | 610 | if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || |
@@ -583,7 +613,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
583 | break; | 613 | break; |
584 | } | 614 | } |
585 | 615 | ||
586 | result = put_user(ir->d.max_timeout, (unsigned long *)arg); | 616 | result = put_user(ir->d.max_timeout, (__u32 *)arg); |
587 | break; | 617 | break; |
588 | default: | 618 | default: |
589 | result = -EINVAL; | 619 | result = -EINVAL; |
@@ -604,12 +634,21 @@ ssize_t lirc_dev_fop_read(struct file *file, | |||
604 | loff_t *ppos) | 634 | loff_t *ppos) |
605 | { | 635 | { |
606 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; | 636 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; |
607 | unsigned char buf[ir->chunk_size]; | 637 | unsigned char *buf; |
608 | int ret = 0, written = 0; | 638 | int ret = 0, written = 0; |
609 | DECLARE_WAITQUEUE(wait, current); | 639 | DECLARE_WAITQUEUE(wait, current); |
610 | 640 | ||
641 | if (!ir) { | ||
642 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); | ||
643 | return -ENODEV; | ||
644 | } | ||
645 | |||
611 | dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); | 646 | dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); |
612 | 647 | ||
648 | buf = kzalloc(ir->chunk_size, GFP_KERNEL); | ||
649 | if (!buf) | ||
650 | return -ENOMEM; | ||
651 | |||
613 | if (mutex_lock_interruptible(&ir->irctl_lock)) | 652 | if (mutex_lock_interruptible(&ir->irctl_lock)) |
614 | return -ERESTARTSYS; | 653 | return -ERESTARTSYS; |
615 | if (!ir->attached) { | 654 | if (!ir->attached) { |
@@ -681,6 +720,7 @@ ssize_t lirc_dev_fop_read(struct file *file, | |||
681 | mutex_unlock(&ir->irctl_lock); | 720 | mutex_unlock(&ir->irctl_lock); |
682 | 721 | ||
683 | out_unlocked: | 722 | out_unlocked: |
723 | kfree(buf); | ||
684 | dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", | 724 | dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", |
685 | ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret); | 725 | ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret); |
686 | 726 | ||
@@ -709,6 +749,11 @@ ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, | |||
709 | { | 749 | { |
710 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; | 750 | struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; |
711 | 751 | ||
752 | if (!ir) { | ||
753 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); | ||
754 | return -ENODEV; | ||
755 | } | ||
756 | |||
712 | dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); | 757 | dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); |
713 | 758 | ||
714 | if (!ir->attached) | 759 | if (!ir->attached) |
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index bc620e10ef7..9dce684fd23 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c | |||
@@ -46,24 +46,58 @@ | |||
46 | "device driver" | 46 | "device driver" |
47 | #define DRIVER_NAME "mceusb" | 47 | #define DRIVER_NAME "mceusb" |
48 | 48 | ||
49 | #define USB_BUFLEN 32 /* USB reception buffer length */ | 49 | #define USB_BUFLEN 32 /* USB reception buffer length */ |
50 | #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ | 50 | #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ |
51 | #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ | 51 | #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ |
52 | 52 | ||
53 | /* MCE constants */ | 53 | /* MCE constants */ |
54 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ | 54 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ |
55 | #define MCE_TIME_UNIT 50 /* Approx 50us resolution */ | 55 | #define MCE_TIME_UNIT 50 /* Approx 50us resolution */ |
56 | #define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ | 56 | #define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ |
57 | #define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ | 57 | #define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ |
58 | #define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ | 58 | #define MCE_IRDATA_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ |
59 | #define MCE_CONTROL_HEADER 0x9F /* MCE status header */ | 59 | #define MCE_IRDATA_TRAILER 0x80 /* End of IR data */ |
60 | #define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ | 60 | #define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ |
61 | #define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ | 61 | #define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ |
62 | #define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */ | 62 | #define MCE_DEFAULT_TX_MASK 0x03 /* Vals: TX1=0x01, TX2=0x02, ALL=0x03 */ |
63 | #define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ | 63 | #define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ |
64 | #define MCE_PULSE_MASK 0x7F /* Pulse mask */ | 64 | #define MCE_PULSE_MASK 0x7f /* Pulse mask */ |
65 | #define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ | 65 | #define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */ |
66 | #define MCE_PACKET_LENGTH_MASK 0x1F /* Packet length mask */ | 66 | |
67 | #define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */ | ||
68 | #define MCE_COMMAND_HEADER 0x9f /* MCE command header */ | ||
69 | #define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */ | ||
70 | #define MCE_COMMAND_NULL 0x00 /* These show up various places... */ | ||
71 | /* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER, | ||
72 | * then we're looking at a raw IR data sample */ | ||
73 | #define MCE_COMMAND_IRDATA 0x80 | ||
74 | #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ | ||
75 | |||
76 | /* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */ | ||
77 | #define MCE_CMD_PING 0x03 /* Ping device */ | ||
78 | #define MCE_CMD_UNKNOWN 0x04 /* Unknown */ | ||
79 | #define MCE_CMD_UNKNOWN2 0x05 /* Unknown */ | ||
80 | #define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */ | ||
81 | #define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */ | ||
82 | #define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */ | ||
83 | #define MCE_CMD_UNKNOWN3 0x09 /* Unknown */ | ||
84 | #define MCE_CMD_UNKNOWN4 0x0a /* Unknown */ | ||
85 | #define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */ | ||
86 | #define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */ | ||
87 | #define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */ | ||
88 | #define MCE_CMD_UNKNOWN5 0x0e /* Unknown */ | ||
89 | #define MCE_CMD_UNKNOWN6 0x0f /* Unknown */ | ||
90 | #define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */ | ||
91 | #define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */ | ||
92 | #define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */ | ||
93 | #define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */ | ||
94 | #define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */ | ||
95 | #define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */ | ||
96 | #define MCE_CMD_UNKNOWN7 0x18 /* Unknown */ | ||
97 | #define MCE_CMD_UNKNOWN8 0x19 /* Unknown */ | ||
98 | #define MCE_CMD_UNKNOWN9 0x1b /* Unknown */ | ||
99 | #define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */ | ||
100 | #define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */ | ||
67 | 101 | ||
68 | 102 | ||
69 | /* module parameters */ | 103 | /* module parameters */ |
@@ -104,14 +138,64 @@ static int debug; | |||
104 | #define VENDOR_NORTHSTAR 0x04eb | 138 | #define VENDOR_NORTHSTAR 0x04eb |
105 | #define VENDOR_REALTEK 0x0bda | 139 | #define VENDOR_REALTEK 0x0bda |
106 | #define VENDOR_TIVO 0x105a | 140 | #define VENDOR_TIVO 0x105a |
141 | #define VENDOR_CONEXANT 0x0572 | ||
142 | |||
143 | enum mceusb_model_type { | ||
144 | MCE_GEN2 = 0, /* Most boards */ | ||
145 | MCE_GEN1, | ||
146 | MCE_GEN3, | ||
147 | MCE_GEN2_TX_INV, | ||
148 | POLARIS_EVK, | ||
149 | }; | ||
150 | |||
151 | struct mceusb_model { | ||
152 | u32 mce_gen1:1; | ||
153 | u32 mce_gen2:1; | ||
154 | u32 mce_gen3:1; | ||
155 | u32 tx_mask_inverted:1; | ||
156 | u32 is_polaris:1; | ||
157 | |||
158 | const char *rc_map; /* Allow specify a per-board map */ | ||
159 | const char *name; /* per-board name */ | ||
160 | }; | ||
161 | |||
162 | static const struct mceusb_model mceusb_model[] = { | ||
163 | [MCE_GEN1] = { | ||
164 | .mce_gen1 = 1, | ||
165 | .tx_mask_inverted = 1, | ||
166 | }, | ||
167 | [MCE_GEN2] = { | ||
168 | .mce_gen2 = 1, | ||
169 | }, | ||
170 | [MCE_GEN2_TX_INV] = { | ||
171 | .mce_gen2 = 1, | ||
172 | .tx_mask_inverted = 1, | ||
173 | }, | ||
174 | [MCE_GEN3] = { | ||
175 | .mce_gen3 = 1, | ||
176 | .tx_mask_inverted = 1, | ||
177 | }, | ||
178 | [POLARIS_EVK] = { | ||
179 | .is_polaris = 1, | ||
180 | /* | ||
181 | * In fact, the EVK is shipped without | ||
182 | * remotes, but we should have something handy, | ||
183 | * to allow testing it | ||
184 | */ | ||
185 | .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, | ||
186 | .name = "cx231xx MCE IR", | ||
187 | }, | ||
188 | }; | ||
107 | 189 | ||
108 | static struct usb_device_id mceusb_dev_table[] = { | 190 | static struct usb_device_id mceusb_dev_table[] = { |
109 | /* Original Microsoft MCE IR Transceiver (often HP-branded) */ | 191 | /* Original Microsoft MCE IR Transceiver (often HP-branded) */ |
110 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | 192 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d), |
193 | .driver_info = MCE_GEN1 }, | ||
111 | /* Philips Infrared Transceiver - Sahara branded */ | 194 | /* Philips Infrared Transceiver - Sahara branded */ |
112 | { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, | 195 | { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, |
113 | /* Philips Infrared Transceiver - HP branded */ | 196 | /* Philips Infrared Transceiver - HP branded */ |
114 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, | 197 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c), |
198 | .driver_info = MCE_GEN2_TX_INV }, | ||
115 | /* Philips SRM5100 */ | 199 | /* Philips SRM5100 */ |
116 | { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, | 200 | { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, |
117 | /* Philips Infrared Transceiver - Omaura */ | 201 | /* Philips Infrared Transceiver - Omaura */ |
@@ -127,11 +211,14 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
127 | /* Realtek MCE IR Receiver */ | 211 | /* Realtek MCE IR Receiver */ |
128 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, | 212 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, |
129 | /* SMK/Toshiba G83C0004D410 */ | 213 | /* SMK/Toshiba G83C0004D410 */ |
130 | { USB_DEVICE(VENDOR_SMK, 0x031d) }, | 214 | { USB_DEVICE(VENDOR_SMK, 0x031d), |
215 | .driver_info = MCE_GEN2_TX_INV }, | ||
131 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ | 216 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ |
132 | { USB_DEVICE(VENDOR_SMK, 0x0322) }, | 217 | { USB_DEVICE(VENDOR_SMK, 0x0322), |
218 | .driver_info = MCE_GEN2_TX_INV }, | ||
133 | /* bundled with Hauppauge PVR-150 */ | 219 | /* bundled with Hauppauge PVR-150 */ |
134 | { USB_DEVICE(VENDOR_SMK, 0x0334) }, | 220 | { USB_DEVICE(VENDOR_SMK, 0x0334), |
221 | .driver_info = MCE_GEN2_TX_INV }, | ||
135 | /* SMK eHome Infrared Transceiver */ | 222 | /* SMK eHome Infrared Transceiver */ |
136 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, | 223 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, |
137 | /* Tatung eHome Infrared Transceiver */ | 224 | /* Tatung eHome Infrared Transceiver */ |
@@ -145,17 +232,23 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
145 | /* Mitsumi */ | 232 | /* Mitsumi */ |
146 | { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, | 233 | { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, |
147 | /* Topseed eHome Infrared Transceiver */ | 234 | /* Topseed eHome Infrared Transceiver */ |
148 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, | 235 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001), |
236 | .driver_info = MCE_GEN2_TX_INV }, | ||
149 | /* Topseed HP eHome Infrared Transceiver */ | 237 | /* Topseed HP eHome Infrared Transceiver */ |
150 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, | 238 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006), |
239 | .driver_info = MCE_GEN2_TX_INV }, | ||
151 | /* Topseed eHome Infrared Transceiver */ | 240 | /* Topseed eHome Infrared Transceiver */ |
152 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, | 241 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007), |
242 | .driver_info = MCE_GEN2_TX_INV }, | ||
153 | /* Topseed eHome Infrared Transceiver */ | 243 | /* Topseed eHome Infrared Transceiver */ |
154 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | 244 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008), |
245 | .driver_info = MCE_GEN3 }, | ||
155 | /* Topseed eHome Infrared Transceiver */ | 246 | /* Topseed eHome Infrared Transceiver */ |
156 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, | 247 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a), |
248 | .driver_info = MCE_GEN2_TX_INV }, | ||
157 | /* Topseed eHome Infrared Transceiver */ | 249 | /* Topseed eHome Infrared Transceiver */ |
158 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, | 250 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011), |
251 | .driver_info = MCE_GEN2_TX_INV }, | ||
159 | /* Ricavision internal Infrared Transceiver */ | 252 | /* Ricavision internal Infrared Transceiver */ |
160 | { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, | 253 | { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, |
161 | /* Itron ione Libra Q-11 */ | 254 | /* Itron ione Libra Q-11 */ |
@@ -185,7 +278,8 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
185 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ | 278 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ |
186 | { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, | 279 | { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, |
187 | /* Pinnacle Remote Kit */ | 280 | /* Pinnacle Remote Kit */ |
188 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | 281 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225), |
282 | .driver_info = MCE_GEN3 }, | ||
189 | /* Elitegroup Computer Systems IR */ | 283 | /* Elitegroup Computer Systems IR */ |
190 | { USB_DEVICE(VENDOR_ECS, 0x0f38) }, | 284 | { USB_DEVICE(VENDOR_ECS, 0x0f38) }, |
191 | /* Wistron Corp. eHome Infrared Receiver */ | 285 | /* Wistron Corp. eHome Infrared Receiver */ |
@@ -198,37 +292,13 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
198 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, | 292 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, |
199 | /* TiVo PC IR Receiver */ | 293 | /* TiVo PC IR Receiver */ |
200 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, | 294 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, |
295 | /* Conexant SDK */ | ||
296 | { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), | ||
297 | .driver_info = POLARIS_EVK }, | ||
201 | /* Terminating entry */ | 298 | /* Terminating entry */ |
202 | { } | 299 | { } |
203 | }; | 300 | }; |
204 | 301 | ||
205 | static struct usb_device_id gen3_list[] = { | ||
206 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
207 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | ||
208 | {} | ||
209 | }; | ||
210 | |||
211 | static struct usb_device_id microsoft_gen1_list[] = { | ||
212 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | ||
213 | {} | ||
214 | }; | ||
215 | |||
216 | static struct usb_device_id std_tx_mask_list[] = { | ||
217 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | ||
218 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, | ||
219 | { USB_DEVICE(VENDOR_SMK, 0x031d) }, | ||
220 | { USB_DEVICE(VENDOR_SMK, 0x0322) }, | ||
221 | { USB_DEVICE(VENDOR_SMK, 0x0334) }, | ||
222 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, | ||
223 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, | ||
224 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, | ||
225 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | ||
226 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, | ||
227 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, | ||
228 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
229 | {} | ||
230 | }; | ||
231 | |||
232 | /* data structure for each usb transceiver */ | 302 | /* data structure for each usb transceiver */ |
233 | struct mceusb_dev { | 303 | struct mceusb_dev { |
234 | /* ir-core bits */ | 304 | /* ir-core bits */ |
@@ -248,8 +318,15 @@ struct mceusb_dev { | |||
248 | /* buffers and dma */ | 318 | /* buffers and dma */ |
249 | unsigned char *buf_in; | 319 | unsigned char *buf_in; |
250 | unsigned int len_in; | 320 | unsigned int len_in; |
251 | u8 cmd; /* MCE command type */ | 321 | |
252 | u8 rem; /* Remaining IR data bytes in packet */ | 322 | enum { |
323 | CMD_HEADER = 0, | ||
324 | SUBCMD, | ||
325 | CMD_DATA, | ||
326 | PARSE_IRDATA, | ||
327 | } parser_state; | ||
328 | u8 cmd, rem; /* Remaining IR data bytes in packet */ | ||
329 | |||
253 | dma_addr_t dma_in; | 330 | dma_addr_t dma_in; |
254 | dma_addr_t dma_out; | 331 | dma_addr_t dma_out; |
255 | 332 | ||
@@ -257,7 +334,6 @@ struct mceusb_dev { | |||
257 | u32 connected:1; | 334 | u32 connected:1; |
258 | u32 tx_mask_inverted:1; | 335 | u32 tx_mask_inverted:1; |
259 | u32 microsoft_gen1:1; | 336 | u32 microsoft_gen1:1; |
260 | u32 reserved:29; | ||
261 | } flags; | 337 | } flags; |
262 | 338 | ||
263 | /* transmit support */ | 339 | /* transmit support */ |
@@ -267,6 +343,7 @@ struct mceusb_dev { | |||
267 | 343 | ||
268 | char name[128]; | 344 | char name[128]; |
269 | char phys[64]; | 345 | char phys[64]; |
346 | enum mceusb_model_type model; | ||
270 | }; | 347 | }; |
271 | 348 | ||
272 | /* | 349 | /* |
@@ -291,43 +368,81 @@ struct mceusb_dev { | |||
291 | * - SET_RX_TIMEOUT sets the receiver timeout | 368 | * - SET_RX_TIMEOUT sets the receiver timeout |
292 | * - SET_RX_SENSOR sets which receiver sensor to use | 369 | * - SET_RX_SENSOR sets which receiver sensor to use |
293 | */ | 370 | */ |
294 | static char DEVICE_RESET[] = {0x00, 0xff, 0xaa}; | 371 | static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER, |
295 | static char GET_REVISION[] = {0xff, 0x0b}; | 372 | MCE_CMD_DEVICE_RESET}; |
296 | static char GET_UNKNOWN[] = {0xff, 0x18}; | 373 | static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION}; |
297 | static char GET_UNKNOWN2[] = {0x9f, 0x05}; | 374 | static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7}; |
298 | static char GET_CARRIER_FREQ[] = {0x9f, 0x07}; | 375 | static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2}; |
299 | static char GET_RX_TIMEOUT[] = {0x9f, 0x0d}; | 376 | static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER}; |
300 | static char GET_TX_BITMASK[] = {0x9f, 0x13}; | 377 | static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT}; |
301 | static char GET_RX_SENSOR[] = {0x9f, 0x15}; | 378 | static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK}; |
379 | static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR}; | ||
302 | /* sub in desired values in lower byte or bytes for full command */ | 380 | /* sub in desired values in lower byte or bytes for full command */ |
303 | /* FIXME: make use of these for transmit. | 381 | /* FIXME: make use of these for transmit. |
304 | static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00}; | 382 | static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, |
305 | static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00}; | 383 | MCE_CMD_S_CARRIER, 0x00, 0x00}; |
306 | static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00}; | 384 | static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00}; |
307 | static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00}; | 385 | static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, |
386 | MCE_CMD_S_TIMEOUT, 0x00, 0x00}; | ||
387 | static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER, | ||
388 | MCE_CMD_S_RXSENSOR, 0x00}; | ||
308 | */ | 389 | */ |
309 | 390 | ||
391 | static int mceusb_cmdsize(u8 cmd, u8 subcmd) | ||
392 | { | ||
393 | int datasize = 0; | ||
394 | |||
395 | switch (cmd) { | ||
396 | case MCE_COMMAND_NULL: | ||
397 | if (subcmd == MCE_HW_CMD_HEADER) | ||
398 | datasize = 1; | ||
399 | break; | ||
400 | case MCE_HW_CMD_HEADER: | ||
401 | switch (subcmd) { | ||
402 | case MCE_CMD_G_REVISION: | ||
403 | datasize = 2; | ||
404 | break; | ||
405 | } | ||
406 | case MCE_COMMAND_HEADER: | ||
407 | switch (subcmd) { | ||
408 | case MCE_CMD_UNKNOWN: | ||
409 | case MCE_CMD_S_CARRIER: | ||
410 | case MCE_CMD_S_TIMEOUT: | ||
411 | case MCE_CMD_G_RXSENSOR: | ||
412 | datasize = 2; | ||
413 | break; | ||
414 | case MCE_CMD_S_TXMASK: | ||
415 | case MCE_CMD_S_RXSENSOR: | ||
416 | datasize = 1; | ||
417 | break; | ||
418 | } | ||
419 | } | ||
420 | return datasize; | ||
421 | } | ||
422 | |||
310 | static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | 423 | static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, |
311 | int len, bool out) | 424 | int offset, int len, bool out) |
312 | { | 425 | { |
313 | char codes[USB_BUFLEN * 3 + 1]; | 426 | char codes[USB_BUFLEN * 3 + 1]; |
314 | char inout[9]; | 427 | char inout[9]; |
315 | int i; | ||
316 | u8 cmd, subcmd, data1, data2; | 428 | u8 cmd, subcmd, data1, data2; |
317 | struct device *dev = ir->dev; | 429 | struct device *dev = ir->dev; |
318 | int idx = 0; | 430 | int i, start, skip = 0; |
431 | |||
432 | if (!debug) | ||
433 | return; | ||
319 | 434 | ||
320 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ | 435 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ |
321 | if (ir->flags.microsoft_gen1 && !out) | 436 | if (ir->flags.microsoft_gen1 && !out) |
322 | idx = 2; | 437 | skip = 2; |
323 | 438 | ||
324 | if (len <= idx) | 439 | if (len <= skip) |
325 | return; | 440 | return; |
326 | 441 | ||
327 | for (i = 0; i < len && i < USB_BUFLEN; i++) | 442 | for (i = 0; i < len && i < USB_BUFLEN; i++) |
328 | snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF); | 443 | snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff); |
329 | 444 | ||
330 | dev_info(dev, "%sx data: %s (length=%d)\n", | 445 | dev_info(dev, "%sx data: %s(length=%d)\n", |
331 | (out ? "t" : "r"), codes, len); | 446 | (out ? "t" : "r"), codes, len); |
332 | 447 | ||
333 | if (out) | 448 | if (out) |
@@ -335,91 +450,93 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
335 | else | 450 | else |
336 | strcpy(inout, "Got\0"); | 451 | strcpy(inout, "Got\0"); |
337 | 452 | ||
338 | cmd = buf[idx] & 0xff; | 453 | start = offset + skip; |
339 | subcmd = buf[idx + 1] & 0xff; | 454 | cmd = buf[start] & 0xff; |
340 | data1 = buf[idx + 2] & 0xff; | 455 | subcmd = buf[start + 1] & 0xff; |
341 | data2 = buf[idx + 3] & 0xff; | 456 | data1 = buf[start + 2] & 0xff; |
457 | data2 = buf[start + 3] & 0xff; | ||
342 | 458 | ||
343 | switch (cmd) { | 459 | switch (cmd) { |
344 | case 0x00: | 460 | case MCE_COMMAND_NULL: |
345 | if (subcmd == 0xff && data1 == 0xaa) | 461 | if ((subcmd == MCE_HW_CMD_HEADER) && |
462 | (data1 == MCE_CMD_DEVICE_RESET)) | ||
346 | dev_info(dev, "Device reset requested\n"); | 463 | dev_info(dev, "Device reset requested\n"); |
347 | else | 464 | else |
348 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | 465 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", |
349 | cmd, subcmd); | 466 | cmd, subcmd); |
350 | break; | 467 | break; |
351 | case 0xff: | 468 | case MCE_HW_CMD_HEADER: |
352 | switch (subcmd) { | 469 | switch (subcmd) { |
353 | case 0x0b: | 470 | case MCE_CMD_G_REVISION: |
354 | if (len == 2) | 471 | if (len == 2) |
355 | dev_info(dev, "Get hw/sw rev?\n"); | 472 | dev_info(dev, "Get hw/sw rev?\n"); |
356 | else | 473 | else |
357 | dev_info(dev, "hw/sw rev 0x%02x 0x%02x " | 474 | dev_info(dev, "hw/sw rev 0x%02x 0x%02x " |
358 | "0x%02x 0x%02x\n", data1, data2, | 475 | "0x%02x 0x%02x\n", data1, data2, |
359 | buf[idx + 4], buf[idx + 5]); | 476 | buf[start + 4], buf[start + 5]); |
360 | break; | 477 | break; |
361 | case 0xaa: | 478 | case MCE_CMD_DEVICE_RESET: |
362 | dev_info(dev, "Device reset requested\n"); | 479 | dev_info(dev, "Device reset requested\n"); |
363 | break; | 480 | break; |
364 | case 0xfe: | 481 | case MCE_RSP_CMD_INVALID: |
365 | dev_info(dev, "Previous command not supported\n"); | 482 | dev_info(dev, "Previous command not supported\n"); |
366 | break; | 483 | break; |
367 | case 0x18: | 484 | case MCE_CMD_UNKNOWN7: |
368 | case 0x1b: | 485 | case MCE_CMD_UNKNOWN9: |
369 | default: | 486 | default: |
370 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | 487 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", |
371 | cmd, subcmd); | 488 | cmd, subcmd); |
372 | break; | 489 | break; |
373 | } | 490 | } |
374 | break; | 491 | break; |
375 | case 0x9f: | 492 | case MCE_COMMAND_HEADER: |
376 | switch (subcmd) { | 493 | switch (subcmd) { |
377 | case 0x03: | 494 | case MCE_CMD_PING: |
378 | dev_info(dev, "Ping\n"); | 495 | dev_info(dev, "Ping\n"); |
379 | break; | 496 | break; |
380 | case 0x04: | 497 | case MCE_CMD_UNKNOWN: |
381 | dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", | 498 | dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", |
382 | data1, data2); | 499 | data1, data2); |
383 | break; | 500 | break; |
384 | case 0x06: | 501 | case MCE_CMD_S_CARRIER: |
385 | dev_info(dev, "%s carrier mode and freq of " | 502 | dev_info(dev, "%s carrier mode and freq of " |
386 | "0x%02x 0x%02x\n", inout, data1, data2); | 503 | "0x%02x 0x%02x\n", inout, data1, data2); |
387 | break; | 504 | break; |
388 | case 0x07: | 505 | case MCE_CMD_G_CARRIER: |
389 | dev_info(dev, "Get carrier mode and freq\n"); | 506 | dev_info(dev, "Get carrier mode and freq\n"); |
390 | break; | 507 | break; |
391 | case 0x08: | 508 | case MCE_CMD_S_TXMASK: |
392 | dev_info(dev, "%s transmit blaster mask of 0x%02x\n", | 509 | dev_info(dev, "%s transmit blaster mask of 0x%02x\n", |
393 | inout, data1); | 510 | inout, data1); |
394 | break; | 511 | break; |
395 | case 0x0c: | 512 | case MCE_CMD_S_TIMEOUT: |
396 | /* value is in units of 50us, so x*50/100 or x/2 ms */ | 513 | /* value is in units of 50us, so x*50/100 or x/2 ms */ |
397 | dev_info(dev, "%s receive timeout of %d ms\n", | 514 | dev_info(dev, "%s receive timeout of %d ms\n", |
398 | inout, ((data1 << 8) | data2) / 2); | 515 | inout, ((data1 << 8) | data2) / 2); |
399 | break; | 516 | break; |
400 | case 0x0d: | 517 | case MCE_CMD_G_TIMEOUT: |
401 | dev_info(dev, "Get receive timeout\n"); | 518 | dev_info(dev, "Get receive timeout\n"); |
402 | break; | 519 | break; |
403 | case 0x13: | 520 | case MCE_CMD_G_TXMASK: |
404 | dev_info(dev, "Get transmit blaster mask\n"); | 521 | dev_info(dev, "Get transmit blaster mask\n"); |
405 | break; | 522 | break; |
406 | case 0x14: | 523 | case MCE_CMD_S_RXSENSOR: |
407 | dev_info(dev, "%s %s-range receive sensor in use\n", | 524 | dev_info(dev, "%s %s-range receive sensor in use\n", |
408 | inout, data1 == 0x02 ? "short" : "long"); | 525 | inout, data1 == 0x02 ? "short" : "long"); |
409 | break; | 526 | break; |
410 | case 0x15: | 527 | case MCE_CMD_G_RXSENSOR: |
411 | if (len == 2) | 528 | if (len == 2) |
412 | dev_info(dev, "Get receive sensor\n"); | 529 | dev_info(dev, "Get receive sensor\n"); |
413 | else | 530 | else |
414 | dev_info(dev, "Received pulse count is %d\n", | 531 | dev_info(dev, "Received pulse count is %d\n", |
415 | ((data1 << 8) | data2)); | 532 | ((data1 << 8) | data2)); |
416 | break; | 533 | break; |
417 | case 0xfe: | 534 | case MCE_RSP_CMD_INVALID: |
418 | dev_info(dev, "Error! Hardware is likely wedged...\n"); | 535 | dev_info(dev, "Error! Hardware is likely wedged...\n"); |
419 | break; | 536 | break; |
420 | case 0x05: | 537 | case MCE_CMD_UNKNOWN2: |
421 | case 0x09: | 538 | case MCE_CMD_UNKNOWN3: |
422 | case 0x0f: | 539 | case MCE_CMD_UNKNOWN5: |
423 | default: | 540 | default: |
424 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | 541 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", |
425 | cmd, subcmd); | 542 | cmd, subcmd); |
@@ -429,6 +546,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
429 | default: | 546 | default: |
430 | break; | 547 | break; |
431 | } | 548 | } |
549 | |||
550 | if (cmd == MCE_IRDATA_TRAILER) | ||
551 | dev_info(dev, "End of raw IR data\n"); | ||
552 | else if ((cmd != MCE_COMMAND_HEADER) && | ||
553 | ((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA)) | ||
554 | dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem); | ||
432 | } | 555 | } |
433 | 556 | ||
434 | static void mce_async_callback(struct urb *urb, struct pt_regs *regs) | 557 | static void mce_async_callback(struct urb *urb, struct pt_regs *regs) |
@@ -446,9 +569,7 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs) | |||
446 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", | 569 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", |
447 | urb->status, len); | 570 | urb->status, len); |
448 | 571 | ||
449 | if (debug) | 572 | mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); |
450 | mceusb_dev_printdata(ir, urb->transfer_buffer, | ||
451 | len, true); | ||
452 | } | 573 | } |
453 | 574 | ||
454 | } | 575 | } |
@@ -536,8 +657,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
536 | return -ENOMEM; | 657 | return -ENOMEM; |
537 | 658 | ||
538 | /* MCE tx init header */ | 659 | /* MCE tx init header */ |
539 | cmdbuf[cmdcount++] = MCE_CONTROL_HEADER; | 660 | cmdbuf[cmdcount++] = MCE_COMMAND_HEADER; |
540 | cmdbuf[cmdcount++] = 0x08; | 661 | cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK; |
541 | cmdbuf[cmdcount++] = ir->tx_mask; | 662 | cmdbuf[cmdcount++] = ir->tx_mask; |
542 | 663 | ||
543 | /* Generate mce packet data */ | 664 | /* Generate mce packet data */ |
@@ -551,7 +672,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
551 | if ((cmdcount < MCE_CMDBUF_SIZE) && | 672 | if ((cmdcount < MCE_CMDBUF_SIZE) && |
552 | (cmdcount - MCE_TX_HEADER_LENGTH) % | 673 | (cmdcount - MCE_TX_HEADER_LENGTH) % |
553 | MCE_CODE_LENGTH == 0) | 674 | MCE_CODE_LENGTH == 0) |
554 | cmdbuf[cmdcount++] = MCE_PACKET_HEADER; | 675 | cmdbuf[cmdcount++] = MCE_IRDATA_HEADER; |
555 | 676 | ||
556 | /* Insert mce packet data */ | 677 | /* Insert mce packet data */ |
557 | if (cmdcount < MCE_CMDBUF_SIZE) | 678 | if (cmdcount < MCE_CMDBUF_SIZE) |
@@ -570,7 +691,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
570 | 691 | ||
571 | /* Fix packet length in last header */ | 692 | /* Fix packet length in last header */ |
572 | cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = | 693 | cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = |
573 | 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1; | 694 | MCE_COMMAND_IRDATA + (cmdcount - MCE_TX_HEADER_LENGTH) % |
695 | MCE_CODE_LENGTH - 1; | ||
574 | 696 | ||
575 | /* Check if we have room for the empty packet at the end */ | 697 | /* Check if we have room for the empty packet at the end */ |
576 | if (cmdcount >= MCE_CMDBUF_SIZE) { | 698 | if (cmdcount >= MCE_CMDBUF_SIZE) { |
@@ -579,7 +701,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
579 | } | 701 | } |
580 | 702 | ||
581 | /* All mce commands end with an empty packet (0x80) */ | 703 | /* All mce commands end with an empty packet (0x80) */ |
582 | cmdbuf[cmdcount++] = 0x80; | 704 | cmdbuf[cmdcount++] = MCE_IRDATA_TRAILER; |
583 | 705 | ||
584 | /* Transmit the command to the mce device */ | 706 | /* Transmit the command to the mce device */ |
585 | mce_async_out(ir, cmdbuf, cmdcount); | 707 | mce_async_out(ir, cmdbuf, cmdcount); |
@@ -608,7 +730,8 @@ static int mceusb_set_tx_mask(void *priv, u32 mask) | |||
608 | struct mceusb_dev *ir = priv; | 730 | struct mceusb_dev *ir = priv; |
609 | 731 | ||
610 | if (ir->flags.tx_mask_inverted) | 732 | if (ir->flags.tx_mask_inverted) |
611 | ir->tx_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1; | 733 | ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ? |
734 | mask ^ MCE_DEFAULT_TX_MASK : mask) << 1; | ||
612 | else | 735 | else |
613 | ir->tx_mask = mask; | 736 | ir->tx_mask = mask; |
614 | 737 | ||
@@ -621,7 +744,8 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
621 | struct mceusb_dev *ir = priv; | 744 | struct mceusb_dev *ir = priv; |
622 | int clk = 10000000; | 745 | int clk = 10000000; |
623 | int prescaler = 0, divisor = 0; | 746 | int prescaler = 0, divisor = 0; |
624 | unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 }; | 747 | unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER, |
748 | MCE_CMD_S_CARRIER, 0x00, 0x00 }; | ||
625 | 749 | ||
626 | /* Carrier has changed */ | 750 | /* Carrier has changed */ |
627 | if (ir->carrier != carrier) { | 751 | if (ir->carrier != carrier) { |
@@ -629,7 +753,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
629 | if (carrier == 0) { | 753 | if (carrier == 0) { |
630 | ir->carrier = carrier; | 754 | ir->carrier = carrier; |
631 | cmdbuf[2] = 0x01; | 755 | cmdbuf[2] = 0x01; |
632 | cmdbuf[3] = 0x80; | 756 | cmdbuf[3] = MCE_IRDATA_TRAILER; |
633 | dev_dbg(ir->dev, "%s: disabling carrier " | 757 | dev_dbg(ir->dev, "%s: disabling carrier " |
634 | "modulation\n", __func__); | 758 | "modulation\n", __func__); |
635 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | 759 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); |
@@ -638,7 +762,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
638 | 762 | ||
639 | for (prescaler = 0; prescaler < 4; ++prescaler) { | 763 | for (prescaler = 0; prescaler < 4; ++prescaler) { |
640 | divisor = (clk >> (2 * prescaler)) / carrier; | 764 | divisor = (clk >> (2 * prescaler)) / carrier; |
641 | if (divisor <= 0xFF) { | 765 | if (divisor <= 0xff) { |
642 | ir->carrier = carrier; | 766 | ir->carrier = carrier; |
643 | cmdbuf[2] = prescaler; | 767 | cmdbuf[2] = prescaler; |
644 | cmdbuf[3] = divisor; | 768 | cmdbuf[3] = divisor; |
@@ -660,47 +784,36 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
660 | 784 | ||
661 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | 785 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) |
662 | { | 786 | { |
663 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | 787 | DEFINE_IR_RAW_EVENT(rawir); |
664 | int i, start_index = 0; | 788 | int i = 0; |
665 | u8 hdr = MCE_CONTROL_HEADER; | ||
666 | 789 | ||
667 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ | 790 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ |
668 | if (ir->flags.microsoft_gen1) | 791 | if (ir->flags.microsoft_gen1) |
669 | start_index = 2; | 792 | i = 2; |
670 | 793 | ||
671 | for (i = start_index; i < buf_len;) { | 794 | for (; i < buf_len; i++) { |
672 | if (ir->rem == 0) { | 795 | switch (ir->parser_state) { |
673 | /* decode mce packets of the form (84),AA,BB,CC,DD */ | 796 | case SUBCMD: |
674 | /* IR data packets can span USB messages - rem */ | 797 | ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]); |
675 | hdr = ir->buf_in[i]; | 798 | mceusb_dev_printdata(ir, ir->buf_in, i - 1, |
676 | ir->rem = (hdr & MCE_PACKET_LENGTH_MASK); | 799 | ir->rem + 2, false); |
677 | ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK); | 800 | ir->parser_state = CMD_DATA; |
678 | dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n", | 801 | break; |
679 | ir->rem, ir->cmd); | 802 | case PARSE_IRDATA: |
680 | i++; | ||
681 | } | ||
682 | |||
683 | /* don't process MCE commands */ | ||
684 | if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) { | ||
685 | ir->rem = 0; | ||
686 | return; | ||
687 | } | ||
688 | |||
689 | for (; (ir->rem > 0) && (i < buf_len); i++) { | ||
690 | ir->rem--; | 803 | ir->rem--; |
691 | |||
692 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); | 804 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); |
693 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | 805 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) |
694 | * MCE_TIME_UNIT * 1000; | 806 | * MCE_TIME_UNIT * 1000; |
695 | 807 | ||
696 | if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { | 808 | if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { |
697 | if (ir->rawir.pulse == rawir.pulse) | 809 | if (ir->rawir.pulse == rawir.pulse) { |
698 | ir->rawir.duration += rawir.duration; | 810 | ir->rawir.duration += rawir.duration; |
699 | else { | 811 | } else { |
700 | ir->rawir.duration = rawir.duration; | 812 | ir->rawir.duration = rawir.duration; |
701 | ir->rawir.pulse = rawir.pulse; | 813 | ir->rawir.pulse = rawir.pulse; |
702 | } | 814 | } |
703 | continue; | 815 | if (ir->rem) |
816 | break; | ||
704 | } | 817 | } |
705 | rawir.duration += ir->rawir.duration; | 818 | rawir.duration += ir->rawir.duration; |
706 | ir->rawir.duration = 0; | 819 | ir->rawir.duration = 0; |
@@ -711,14 +824,40 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
711 | rawir.duration); | 824 | rawir.duration); |
712 | 825 | ||
713 | ir_raw_event_store(ir->idev, &rawir); | 826 | ir_raw_event_store(ir->idev, &rawir); |
827 | break; | ||
828 | case CMD_DATA: | ||
829 | ir->rem--; | ||
830 | break; | ||
831 | case CMD_HEADER: | ||
832 | /* decode mce packets of the form (84),AA,BB,CC,DD */ | ||
833 | /* IR data packets can span USB messages - rem */ | ||
834 | ir->cmd = ir->buf_in[i]; | ||
835 | if ((ir->cmd == MCE_COMMAND_HEADER) || | ||
836 | ((ir->cmd & MCE_COMMAND_MASK) != | ||
837 | MCE_COMMAND_IRDATA)) { | ||
838 | ir->parser_state = SUBCMD; | ||
839 | continue; | ||
840 | } | ||
841 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); | ||
842 | mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false); | ||
843 | if (ir->rem) { | ||
844 | ir->parser_state = PARSE_IRDATA; | ||
845 | break; | ||
846 | } | ||
847 | /* | ||
848 | * a package with len=0 (e. g. 0x80) means end of | ||
849 | * data. We could use it to do the call to | ||
850 | * ir_raw_event_handle(). For now, we don't need to | ||
851 | * use it. | ||
852 | */ | ||
853 | break; | ||
714 | } | 854 | } |
715 | 855 | ||
716 | if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f) | 856 | if (ir->parser_state != CMD_HEADER && !ir->rem) |
717 | ir->rem = 0; | 857 | ir->parser_state = CMD_HEADER; |
718 | |||
719 | dev_dbg(ir->dev, "calling ir_raw_event_handle\n"); | ||
720 | ir_raw_event_handle(ir->idev); | ||
721 | } | 858 | } |
859 | dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); | ||
860 | ir_raw_event_handle(ir->idev); | ||
722 | } | 861 | } |
723 | 862 | ||
724 | static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | 863 | static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) |
@@ -737,9 +876,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
737 | 876 | ||
738 | buf_len = urb->actual_length; | 877 | buf_len = urb->actual_length; |
739 | 878 | ||
740 | if (debug) | ||
741 | mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false); | ||
742 | |||
743 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { | 879 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { |
744 | ir->send_flags = SEND_FLAG_COMPLETE; | 880 | ir->send_flags = SEND_FLAG_COMPLETE; |
745 | dev_dbg(ir->dev, "setup answer received %d bytes\n", | 881 | dev_dbg(ir->dev, "setup answer received %d bytes\n", |
@@ -760,6 +896,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
760 | 896 | ||
761 | case -EPIPE: | 897 | case -EPIPE: |
762 | default: | 898 | default: |
899 | dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status); | ||
763 | break; | 900 | break; |
764 | } | 901 | } |
765 | 902 | ||
@@ -865,6 +1002,8 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
865 | struct input_dev *idev; | 1002 | struct input_dev *idev; |
866 | struct ir_dev_props *props; | 1003 | struct ir_dev_props *props; |
867 | struct device *dev = ir->dev; | 1004 | struct device *dev = ir->dev; |
1005 | const char *rc_map = RC_MAP_RC6_MCE; | ||
1006 | const char *name = "Media Center Ed. eHome Infrared Remote Transceiver"; | ||
868 | int ret = -ENODEV; | 1007 | int ret = -ENODEV; |
869 | 1008 | ||
870 | idev = input_allocate_device(); | 1009 | idev = input_allocate_device(); |
@@ -880,8 +1019,11 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
880 | goto props_alloc_failed; | 1019 | goto props_alloc_failed; |
881 | } | 1020 | } |
882 | 1021 | ||
883 | snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome " | 1022 | if (mceusb_model[ir->model].name) |
884 | "Infrared Remote Transceiver (%04x:%04x)", | 1023 | name = mceusb_model[ir->model].name; |
1024 | |||
1025 | snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", | ||
1026 | name, | ||
885 | le16_to_cpu(ir->usbdev->descriptor.idVendor), | 1027 | le16_to_cpu(ir->usbdev->descriptor.idVendor), |
886 | le16_to_cpu(ir->usbdev->descriptor.idProduct)); | 1028 | le16_to_cpu(ir->usbdev->descriptor.idProduct)); |
887 | 1029 | ||
@@ -899,7 +1041,10 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
899 | 1041 | ||
900 | ir->props = props; | 1042 | ir->props = props; |
901 | 1043 | ||
902 | ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME); | 1044 | if (mceusb_model[ir->model].rc_map) |
1045 | rc_map = mceusb_model[ir->model].rc_map; | ||
1046 | |||
1047 | ret = ir_input_register(idev, rc_map, props, DRIVER_NAME); | ||
903 | if (ret < 0) { | 1048 | if (ret < 0) { |
904 | dev_err(dev, "remote input device register failed\n"); | 1049 | dev_err(dev, "remote input device register failed\n"); |
905 | goto irdev_failed; | 1050 | goto irdev_failed; |
@@ -926,17 +1071,26 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
926 | struct mceusb_dev *ir = NULL; | 1071 | struct mceusb_dev *ir = NULL; |
927 | int pipe, maxp, i; | 1072 | int pipe, maxp, i; |
928 | char buf[63], name[128] = ""; | 1073 | char buf[63], name[128] = ""; |
1074 | enum mceusb_model_type model = id->driver_info; | ||
929 | bool is_gen3; | 1075 | bool is_gen3; |
930 | bool is_microsoft_gen1; | 1076 | bool is_microsoft_gen1; |
931 | bool tx_mask_inverted; | 1077 | bool tx_mask_inverted; |
1078 | bool is_polaris; | ||
932 | 1079 | ||
933 | dev_dbg(&intf->dev, ": %s called\n", __func__); | 1080 | dev_dbg(&intf->dev, ": %s called\n", __func__); |
934 | 1081 | ||
935 | idesc = intf->cur_altsetting; | 1082 | idesc = intf->cur_altsetting; |
936 | 1083 | ||
937 | is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0; | 1084 | is_gen3 = mceusb_model[model].mce_gen3; |
938 | is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0; | 1085 | is_microsoft_gen1 = mceusb_model[model].mce_gen1; |
939 | tx_mask_inverted = usb_match_id(intf, std_tx_mask_list) ? 0 : 1; | 1086 | tx_mask_inverted = mceusb_model[model].tx_mask_inverted; |
1087 | is_polaris = mceusb_model[model].is_polaris; | ||
1088 | |||
1089 | if (is_polaris) { | ||
1090 | /* Interface 0 is IR */ | ||
1091 | if (idesc->desc.bInterfaceNumber) | ||
1092 | return -ENODEV; | ||
1093 | } | ||
940 | 1094 | ||
941 | /* step through the endpoints to find first bulk in and out endpoint */ | 1095 | /* step through the endpoints to find first bulk in and out endpoint */ |
942 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { | 1096 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { |
@@ -997,6 +1151,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
997 | ir->len_in = maxp; | 1151 | ir->len_in = maxp; |
998 | ir->flags.microsoft_gen1 = is_microsoft_gen1; | 1152 | ir->flags.microsoft_gen1 = is_microsoft_gen1; |
999 | ir->flags.tx_mask_inverted = tx_mask_inverted; | 1153 | ir->flags.tx_mask_inverted = tx_mask_inverted; |
1154 | ir->model = model; | ||
1155 | |||
1156 | init_ir_raw_event(&ir->rawir); | ||
1000 | 1157 | ||
1001 | /* Saving usb interface data for use by the transmitter routine */ | 1158 | /* Saving usb interface data for use by the transmitter routine */ |
1002 | ir->usb_ep_in = ep_in; | 1159 | ir->usb_ep_in = ep_in; |
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/IR/nuvoton-cir.c new file mode 100644 index 00000000000..301be53aee8 --- /dev/null +++ b/drivers/media/IR/nuvoton-cir.c | |||
@@ -0,0 +1,1246 @@ | |||
1 | /* | ||
2 | * Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR | ||
3 | * | ||
4 | * Copyright (C) 2010 Jarod Wilson <jarod@redhat.com> | ||
5 | * Copyright (C) 2009 Nuvoton PS Team | ||
6 | * | ||
7 | * Special thanks to Nuvoton for providing hardware, spec sheets and | ||
8 | * sample code upon which portions of this driver are based. Indirect | ||
9 | * thanks also to Maxim Levitsky, whose ene_ir driver this driver is | ||
10 | * modeled after. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License as | ||
14 | * published by the Free Software Foundation; either version 2 of the | ||
15 | * License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, but | ||
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
25 | * USA | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/pnp.h> | ||
31 | #include <linux/io.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/sched.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/input.h> | ||
36 | #include <media/ir-core.h> | ||
37 | #include <linux/pci_ids.h> | ||
38 | |||
39 | #include "nuvoton-cir.h" | ||
40 | |||
41 | static char *chip_id = "w836x7hg"; | ||
42 | |||
43 | /* write val to config reg */ | ||
44 | static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg) | ||
45 | { | ||
46 | outb(reg, nvt->cr_efir); | ||
47 | outb(val, nvt->cr_efdr); | ||
48 | } | ||
49 | |||
50 | /* read val from config reg */ | ||
51 | static inline u8 nvt_cr_read(struct nvt_dev *nvt, u8 reg) | ||
52 | { | ||
53 | outb(reg, nvt->cr_efir); | ||
54 | return inb(nvt->cr_efdr); | ||
55 | } | ||
56 | |||
57 | /* update config register bit without changing other bits */ | ||
58 | static inline void nvt_set_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg) | ||
59 | { | ||
60 | u8 tmp = nvt_cr_read(nvt, reg) | val; | ||
61 | nvt_cr_write(nvt, tmp, reg); | ||
62 | } | ||
63 | |||
64 | /* clear config register bit without changing other bits */ | ||
65 | static inline void nvt_clear_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg) | ||
66 | { | ||
67 | u8 tmp = nvt_cr_read(nvt, reg) & ~val; | ||
68 | nvt_cr_write(nvt, tmp, reg); | ||
69 | } | ||
70 | |||
71 | /* enter extended function mode */ | ||
72 | static inline void nvt_efm_enable(struct nvt_dev *nvt) | ||
73 | { | ||
74 | /* Enabling Extended Function Mode explicitly requires writing 2x */ | ||
75 | outb(EFER_EFM_ENABLE, nvt->cr_efir); | ||
76 | outb(EFER_EFM_ENABLE, nvt->cr_efir); | ||
77 | } | ||
78 | |||
79 | /* exit extended function mode */ | ||
80 | static inline void nvt_efm_disable(struct nvt_dev *nvt) | ||
81 | { | ||
82 | outb(EFER_EFM_DISABLE, nvt->cr_efir); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * When you want to address a specific logical device, write its logical | ||
87 | * device number to CR_LOGICAL_DEV_SEL, then enable/disable by writing | ||
88 | * 0x1/0x0 respectively to CR_LOGICAL_DEV_EN. | ||
89 | */ | ||
90 | static inline void nvt_select_logical_dev(struct nvt_dev *nvt, u8 ldev) | ||
91 | { | ||
92 | outb(CR_LOGICAL_DEV_SEL, nvt->cr_efir); | ||
93 | outb(ldev, nvt->cr_efdr); | ||
94 | } | ||
95 | |||
96 | /* write val to cir config register */ | ||
97 | static inline void nvt_cir_reg_write(struct nvt_dev *nvt, u8 val, u8 offset) | ||
98 | { | ||
99 | outb(val, nvt->cir_addr + offset); | ||
100 | } | ||
101 | |||
102 | /* read val from cir config register */ | ||
103 | static u8 nvt_cir_reg_read(struct nvt_dev *nvt, u8 offset) | ||
104 | { | ||
105 | u8 val; | ||
106 | |||
107 | val = inb(nvt->cir_addr + offset); | ||
108 | |||
109 | return val; | ||
110 | } | ||
111 | |||
112 | /* write val to cir wake register */ | ||
113 | static inline void nvt_cir_wake_reg_write(struct nvt_dev *nvt, | ||
114 | u8 val, u8 offset) | ||
115 | { | ||
116 | outb(val, nvt->cir_wake_addr + offset); | ||
117 | } | ||
118 | |||
119 | /* read val from cir wake config register */ | ||
120 | static u8 nvt_cir_wake_reg_read(struct nvt_dev *nvt, u8 offset) | ||
121 | { | ||
122 | u8 val; | ||
123 | |||
124 | val = inb(nvt->cir_wake_addr + offset); | ||
125 | |||
126 | return val; | ||
127 | } | ||
128 | |||
129 | #define pr_reg(text, ...) \ | ||
130 | printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__) | ||
131 | |||
132 | /* dump current cir register contents */ | ||
133 | static void cir_dump_regs(struct nvt_dev *nvt) | ||
134 | { | ||
135 | nvt_efm_enable(nvt); | ||
136 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
137 | |||
138 | pr_reg("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME); | ||
139 | pr_reg(" * CR CIR ACTIVE : 0x%x\n", | ||
140 | nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); | ||
141 | pr_reg(" * CR CIR BASE ADDR: 0x%x\n", | ||
142 | (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | | ||
143 | nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); | ||
144 | pr_reg(" * CR CIR IRQ NUM: 0x%x\n", | ||
145 | nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); | ||
146 | |||
147 | nvt_efm_disable(nvt); | ||
148 | |||
149 | pr_reg("%s: Dump CIR registers:\n", NVT_DRIVER_NAME); | ||
150 | pr_reg(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON)); | ||
151 | pr_reg(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS)); | ||
152 | pr_reg(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN)); | ||
153 | pr_reg(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT)); | ||
154 | pr_reg(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP)); | ||
155 | pr_reg(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC)); | ||
156 | pr_reg(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH)); | ||
157 | pr_reg(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL)); | ||
158 | pr_reg(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON)); | ||
159 | pr_reg(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS)); | ||
160 | pr_reg(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO)); | ||
161 | pr_reg(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT)); | ||
162 | pr_reg(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO)); | ||
163 | pr_reg(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH)); | ||
164 | pr_reg(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL)); | ||
165 | pr_reg(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM)); | ||
166 | } | ||
167 | |||
168 | /* dump current cir wake register contents */ | ||
169 | static void cir_wake_dump_regs(struct nvt_dev *nvt) | ||
170 | { | ||
171 | u8 i, fifo_len; | ||
172 | |||
173 | nvt_efm_enable(nvt); | ||
174 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); | ||
175 | |||
176 | pr_reg("%s: Dump CIR WAKE logical device registers:\n", | ||
177 | NVT_DRIVER_NAME); | ||
178 | pr_reg(" * CR CIR WAKE ACTIVE : 0x%x\n", | ||
179 | nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); | ||
180 | pr_reg(" * CR CIR WAKE BASE ADDR: 0x%x\n", | ||
181 | (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | | ||
182 | nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); | ||
183 | pr_reg(" * CR CIR WAKE IRQ NUM: 0x%x\n", | ||
184 | nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); | ||
185 | |||
186 | nvt_efm_disable(nvt); | ||
187 | |||
188 | pr_reg("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME); | ||
189 | pr_reg(" * IRCON: 0x%x\n", | ||
190 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON)); | ||
191 | pr_reg(" * IRSTS: 0x%x\n", | ||
192 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS)); | ||
193 | pr_reg(" * IREN: 0x%x\n", | ||
194 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN)); | ||
195 | pr_reg(" * FIFO CMP DEEP: 0x%x\n", | ||
196 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP)); | ||
197 | pr_reg(" * FIFO CMP TOL: 0x%x\n", | ||
198 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL)); | ||
199 | pr_reg(" * FIFO COUNT: 0x%x\n", | ||
200 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT)); | ||
201 | pr_reg(" * SLCH: 0x%x\n", | ||
202 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH)); | ||
203 | pr_reg(" * SLCL: 0x%x\n", | ||
204 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL)); | ||
205 | pr_reg(" * FIFOCON: 0x%x\n", | ||
206 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON)); | ||
207 | pr_reg(" * SRXFSTS: 0x%x\n", | ||
208 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS)); | ||
209 | pr_reg(" * SAMPLE RX FIFO: 0x%x\n", | ||
210 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO)); | ||
211 | pr_reg(" * WR FIFO DATA: 0x%x\n", | ||
212 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA)); | ||
213 | pr_reg(" * RD FIFO ONLY: 0x%x\n", | ||
214 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); | ||
215 | pr_reg(" * RD FIFO ONLY IDX: 0x%x\n", | ||
216 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)); | ||
217 | pr_reg(" * FIFO IGNORE: 0x%x\n", | ||
218 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE)); | ||
219 | pr_reg(" * IRFSM: 0x%x\n", | ||
220 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM)); | ||
221 | |||
222 | fifo_len = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT); | ||
223 | pr_reg("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len); | ||
224 | pr_reg("* Contents = "); | ||
225 | for (i = 0; i < fifo_len; i++) | ||
226 | printk(KERN_CONT "%02x ", | ||
227 | nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); | ||
228 | printk(KERN_CONT "\n"); | ||
229 | } | ||
230 | |||
231 | /* detect hardware features */ | ||
232 | static int nvt_hw_detect(struct nvt_dev *nvt) | ||
233 | { | ||
234 | unsigned long flags; | ||
235 | u8 chip_major, chip_minor; | ||
236 | int ret = 0; | ||
237 | |||
238 | nvt_efm_enable(nvt); | ||
239 | |||
240 | /* Check if we're wired for the alternate EFER setup */ | ||
241 | chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); | ||
242 | if (chip_major == 0xff) { | ||
243 | nvt->cr_efir = CR_EFIR2; | ||
244 | nvt->cr_efdr = CR_EFDR2; | ||
245 | nvt_efm_enable(nvt); | ||
246 | chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); | ||
247 | } | ||
248 | |||
249 | chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); | ||
250 | nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor); | ||
251 | |||
252 | if (chip_major != CHIP_ID_HIGH && | ||
253 | (chip_minor != CHIP_ID_LOW || chip_minor != CHIP_ID_LOW2)) | ||
254 | ret = -ENODEV; | ||
255 | |||
256 | nvt_efm_disable(nvt); | ||
257 | |||
258 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
259 | nvt->chip_major = chip_major; | ||
260 | nvt->chip_minor = chip_minor; | ||
261 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
262 | |||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static void nvt_cir_ldev_init(struct nvt_dev *nvt) | ||
267 | { | ||
268 | u8 val; | ||
269 | |||
270 | /* output pin selection (Pin95=CIRRX, Pin96=CIRTX1, WB enabled */ | ||
271 | val = nvt_cr_read(nvt, CR_OUTPUT_PIN_SEL); | ||
272 | val &= OUTPUT_PIN_SEL_MASK; | ||
273 | val |= (OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB); | ||
274 | nvt_cr_write(nvt, val, CR_OUTPUT_PIN_SEL); | ||
275 | |||
276 | /* Select CIR logical device and enable */ | ||
277 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
278 | nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); | ||
279 | |||
280 | nvt_cr_write(nvt, nvt->cir_addr >> 8, CR_CIR_BASE_ADDR_HI); | ||
281 | nvt_cr_write(nvt, nvt->cir_addr & 0xff, CR_CIR_BASE_ADDR_LO); | ||
282 | |||
283 | nvt_cr_write(nvt, nvt->cir_irq, CR_CIR_IRQ_RSRC); | ||
284 | |||
285 | nvt_dbg("CIR initialized, base io port address: 0x%lx, irq: %d", | ||
286 | nvt->cir_addr, nvt->cir_irq); | ||
287 | } | ||
288 | |||
289 | static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt) | ||
290 | { | ||
291 | /* Select ACPI logical device, enable it and CIR Wake */ | ||
292 | nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI); | ||
293 | nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); | ||
294 | |||
295 | /* Enable CIR Wake via PSOUT# (Pin60) */ | ||
296 | nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); | ||
297 | |||
298 | /* enable cir interrupt of mouse/keyboard IRQ event */ | ||
299 | nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); | ||
300 | |||
301 | /* enable pme interrupt of cir wakeup event */ | ||
302 | nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); | ||
303 | |||
304 | /* Select CIR Wake logical device and enable */ | ||
305 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); | ||
306 | nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); | ||
307 | |||
308 | nvt_cr_write(nvt, nvt->cir_wake_addr >> 8, CR_CIR_BASE_ADDR_HI); | ||
309 | nvt_cr_write(nvt, nvt->cir_wake_addr & 0xff, CR_CIR_BASE_ADDR_LO); | ||
310 | |||
311 | nvt_cr_write(nvt, nvt->cir_wake_irq, CR_CIR_IRQ_RSRC); | ||
312 | |||
313 | nvt_dbg("CIR Wake initialized, base io port address: 0x%lx, irq: %d", | ||
314 | nvt->cir_wake_addr, nvt->cir_wake_irq); | ||
315 | } | ||
316 | |||
317 | /* clear out the hardware's cir rx fifo */ | ||
318 | static void nvt_clear_cir_fifo(struct nvt_dev *nvt) | ||
319 | { | ||
320 | u8 val; | ||
321 | |||
322 | val = nvt_cir_reg_read(nvt, CIR_FIFOCON); | ||
323 | nvt_cir_reg_write(nvt, val | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); | ||
324 | } | ||
325 | |||
326 | /* clear out the hardware's cir wake rx fifo */ | ||
327 | static void nvt_clear_cir_wake_fifo(struct nvt_dev *nvt) | ||
328 | { | ||
329 | u8 val; | ||
330 | |||
331 | val = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON); | ||
332 | nvt_cir_wake_reg_write(nvt, val | CIR_WAKE_FIFOCON_RXFIFOCLR, | ||
333 | CIR_WAKE_FIFOCON); | ||
334 | } | ||
335 | |||
336 | /* clear out the hardware's cir tx fifo */ | ||
337 | static void nvt_clear_tx_fifo(struct nvt_dev *nvt) | ||
338 | { | ||
339 | u8 val; | ||
340 | |||
341 | val = nvt_cir_reg_read(nvt, CIR_FIFOCON); | ||
342 | nvt_cir_reg_write(nvt, val | CIR_FIFOCON_TXFIFOCLR, CIR_FIFOCON); | ||
343 | } | ||
344 | |||
345 | /* enable RX Trigger Level Reach and Packet End interrupts */ | ||
346 | static void nvt_set_cir_iren(struct nvt_dev *nvt) | ||
347 | { | ||
348 | u8 iren; | ||
349 | |||
350 | iren = CIR_IREN_RTR | CIR_IREN_PE; | ||
351 | nvt_cir_reg_write(nvt, iren, CIR_IREN); | ||
352 | } | ||
353 | |||
354 | static void nvt_cir_regs_init(struct nvt_dev *nvt) | ||
355 | { | ||
356 | /* set sample limit count (PE interrupt raised when reached) */ | ||
357 | nvt_cir_reg_write(nvt, CIR_RX_LIMIT_COUNT >> 8, CIR_SLCH); | ||
358 | nvt_cir_reg_write(nvt, CIR_RX_LIMIT_COUNT & 0xff, CIR_SLCL); | ||
359 | |||
360 | /* set fifo irq trigger levels */ | ||
361 | nvt_cir_reg_write(nvt, CIR_FIFOCON_TX_TRIGGER_LEV | | ||
362 | CIR_FIFOCON_RX_TRIGGER_LEV, CIR_FIFOCON); | ||
363 | |||
364 | /* | ||
365 | * Enable TX and RX, specify carrier on = low, off = high, and set | ||
366 | * sample period (currently 50us) | ||
367 | */ | ||
368 | nvt_cir_reg_write(nvt, | ||
369 | CIR_IRCON_TXEN | CIR_IRCON_RXEN | | ||
370 | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, | ||
371 | CIR_IRCON); | ||
372 | |||
373 | /* clear hardware rx and tx fifos */ | ||
374 | nvt_clear_cir_fifo(nvt); | ||
375 | nvt_clear_tx_fifo(nvt); | ||
376 | |||
377 | /* clear any and all stray interrupts */ | ||
378 | nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); | ||
379 | |||
380 | /* and finally, enable interrupts */ | ||
381 | nvt_set_cir_iren(nvt); | ||
382 | } | ||
383 | |||
384 | static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) | ||
385 | { | ||
386 | /* set number of bytes needed for wake key comparison (default 67) */ | ||
387 | nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFO_LEN, CIR_WAKE_FIFO_CMP_DEEP); | ||
388 | |||
389 | /* set tolerance/variance allowed per byte during wake compare */ | ||
390 | nvt_cir_wake_reg_write(nvt, CIR_WAKE_CMP_TOLERANCE, | ||
391 | CIR_WAKE_FIFO_CMP_TOL); | ||
392 | |||
393 | /* set sample limit count (PE interrupt raised when reached) */ | ||
394 | nvt_cir_wake_reg_write(nvt, CIR_RX_LIMIT_COUNT >> 8, CIR_WAKE_SLCH); | ||
395 | nvt_cir_wake_reg_write(nvt, CIR_RX_LIMIT_COUNT & 0xff, CIR_WAKE_SLCL); | ||
396 | |||
397 | /* set cir wake fifo rx trigger level (currently 67) */ | ||
398 | nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFOCON_RX_TRIGGER_LEV, | ||
399 | CIR_WAKE_FIFOCON); | ||
400 | |||
401 | /* | ||
402 | * Enable TX and RX, specific carrier on = low, off = high, and set | ||
403 | * sample period (currently 50us) | ||
404 | */ | ||
405 | nvt_cir_wake_reg_write(nvt, CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | | ||
406 | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | | ||
407 | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, | ||
408 | CIR_WAKE_IRCON); | ||
409 | |||
410 | /* clear cir wake rx fifo */ | ||
411 | nvt_clear_cir_wake_fifo(nvt); | ||
412 | |||
413 | /* clear any and all stray interrupts */ | ||
414 | nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS); | ||
415 | } | ||
416 | |||
417 | static void nvt_enable_wake(struct nvt_dev *nvt) | ||
418 | { | ||
419 | nvt_efm_enable(nvt); | ||
420 | |||
421 | nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI); | ||
422 | nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); | ||
423 | nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); | ||
424 | nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); | ||
425 | |||
426 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); | ||
427 | nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); | ||
428 | |||
429 | nvt_efm_disable(nvt); | ||
430 | |||
431 | nvt_cir_wake_reg_write(nvt, CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | | ||
432 | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | | ||
433 | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, | ||
434 | CIR_WAKE_IRCON); | ||
435 | nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS); | ||
436 | nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN); | ||
437 | } | ||
438 | |||
439 | /* rx carrier detect only works in learning mode, must be called w/nvt_lock */ | ||
440 | static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) | ||
441 | { | ||
442 | u32 count, carrier, duration = 0; | ||
443 | int i; | ||
444 | |||
445 | count = nvt_cir_reg_read(nvt, CIR_FCCL) | | ||
446 | nvt_cir_reg_read(nvt, CIR_FCCH) << 8; | ||
447 | |||
448 | for (i = 0; i < nvt->pkts; i++) { | ||
449 | if (nvt->buf[i] & BUF_PULSE_BIT) | ||
450 | duration += nvt->buf[i] & BUF_LEN_MASK; | ||
451 | } | ||
452 | |||
453 | duration *= SAMPLE_PERIOD; | ||
454 | |||
455 | if (!count || !duration) { | ||
456 | nvt_pr(KERN_NOTICE, "Unable to determine carrier! (c:%u, d:%u)", | ||
457 | count, duration); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | carrier = (count * 1000000) / duration; | ||
462 | |||
463 | if ((carrier > MAX_CARRIER) || (carrier < MIN_CARRIER)) | ||
464 | nvt_dbg("WTF? Carrier frequency out of range!"); | ||
465 | |||
466 | nvt_dbg("Carrier frequency: %u (count %u, duration %u)", | ||
467 | carrier, count, duration); | ||
468 | |||
469 | return carrier; | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * set carrier frequency | ||
474 | * | ||
475 | * set carrier on 2 registers: CP & CC | ||
476 | * always set CP as 0x81 | ||
477 | * set CC by SPEC, CC = 3MHz/carrier - 1 | ||
478 | */ | ||
479 | static int nvt_set_tx_carrier(void *data, u32 carrier) | ||
480 | { | ||
481 | struct nvt_dev *nvt = data; | ||
482 | u16 val; | ||
483 | |||
484 | nvt_cir_reg_write(nvt, 1, CIR_CP); | ||
485 | val = 3000000 / (carrier) - 1; | ||
486 | nvt_cir_reg_write(nvt, val & 0xff, CIR_CC); | ||
487 | |||
488 | nvt_dbg("cp: 0x%x cc: 0x%x\n", | ||
489 | nvt_cir_reg_read(nvt, CIR_CP), nvt_cir_reg_read(nvt, CIR_CC)); | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | /* | ||
495 | * nvt_tx_ir | ||
496 | * | ||
497 | * 1) clean TX fifo first (handled by AP) | ||
498 | * 2) copy data from user space | ||
499 | * 3) disable RX interrupts, enable TX interrupts: TTR & TFU | ||
500 | * 4) send 9 packets to TX FIFO to open TTR | ||
501 | * in interrupt_handler: | ||
502 | * 5) send all data out | ||
503 | * go back to write(): | ||
504 | * 6) disable TX interrupts, re-enable RX interupts | ||
505 | * | ||
506 | * The key problem of this function is user space data may larger than | ||
507 | * driver's data buf length. So nvt_tx_ir() will only copy TX_BUF_LEN data to | ||
508 | * buf, and keep current copied data buf num in cur_buf_num. But driver's buf | ||
509 | * number may larger than TXFCONT (0xff). So in interrupt_handler, it has to | ||
510 | * set TXFCONT as 0xff, until buf_count less than 0xff. | ||
511 | */ | ||
512 | static int nvt_tx_ir(void *priv, int *txbuf, u32 n) | ||
513 | { | ||
514 | struct nvt_dev *nvt = priv; | ||
515 | unsigned long flags; | ||
516 | size_t cur_count; | ||
517 | unsigned int i; | ||
518 | u8 iren; | ||
519 | int ret; | ||
520 | |||
521 | spin_lock_irqsave(&nvt->tx.lock, flags); | ||
522 | |||
523 | if (n >= TX_BUF_LEN) { | ||
524 | nvt->tx.buf_count = cur_count = TX_BUF_LEN; | ||
525 | ret = TX_BUF_LEN; | ||
526 | } else { | ||
527 | nvt->tx.buf_count = cur_count = n; | ||
528 | ret = n; | ||
529 | } | ||
530 | |||
531 | memcpy(nvt->tx.buf, txbuf, nvt->tx.buf_count); | ||
532 | |||
533 | nvt->tx.cur_buf_num = 0; | ||
534 | |||
535 | /* save currently enabled interrupts */ | ||
536 | iren = nvt_cir_reg_read(nvt, CIR_IREN); | ||
537 | |||
538 | /* now disable all interrupts, save TFU & TTR */ | ||
539 | nvt_cir_reg_write(nvt, CIR_IREN_TFU | CIR_IREN_TTR, CIR_IREN); | ||
540 | |||
541 | nvt->tx.tx_state = ST_TX_REPLY; | ||
542 | |||
543 | nvt_cir_reg_write(nvt, CIR_FIFOCON_TX_TRIGGER_LEV_8 | | ||
544 | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); | ||
545 | |||
546 | /* trigger TTR interrupt by writing out ones, (yes, it's ugly) */ | ||
547 | for (i = 0; i < 9; i++) | ||
548 | nvt_cir_reg_write(nvt, 0x01, CIR_STXFIFO); | ||
549 | |||
550 | spin_unlock_irqrestore(&nvt->tx.lock, flags); | ||
551 | |||
552 | wait_event(nvt->tx.queue, nvt->tx.tx_state == ST_TX_REQUEST); | ||
553 | |||
554 | spin_lock_irqsave(&nvt->tx.lock, flags); | ||
555 | nvt->tx.tx_state = ST_TX_NONE; | ||
556 | spin_unlock_irqrestore(&nvt->tx.lock, flags); | ||
557 | |||
558 | /* restore enabled interrupts to prior state */ | ||
559 | nvt_cir_reg_write(nvt, iren, CIR_IREN); | ||
560 | |||
561 | return ret; | ||
562 | } | ||
563 | |||
564 | /* dump contents of the last rx buffer we got from the hw rx fifo */ | ||
565 | static void nvt_dump_rx_buf(struct nvt_dev *nvt) | ||
566 | { | ||
567 | int i; | ||
568 | |||
569 | printk(KERN_DEBUG "%s (len %d): ", __func__, nvt->pkts); | ||
570 | for (i = 0; (i < nvt->pkts) && (i < RX_BUF_LEN); i++) | ||
571 | printk(KERN_CONT "0x%02x ", nvt->buf[i]); | ||
572 | printk(KERN_CONT "\n"); | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * Process raw data in rx driver buffer, store it in raw IR event kfifo, | ||
577 | * trigger decode when appropriate. | ||
578 | * | ||
579 | * We get IR data samples one byte at a time. If the msb is set, its a pulse, | ||
580 | * otherwise its a space. The lower 7 bits are the count of SAMPLE_PERIOD | ||
581 | * (default 50us) intervals for that pulse/space. A discrete signal is | ||
582 | * followed by a series of 0x7f packets, then either 0x7<something> or 0x80 | ||
583 | * to signal more IR coming (repeats) or end of IR, respectively. We store | ||
584 | * sample data in the raw event kfifo until we see 0x7<something> (except f) | ||
585 | * or 0x80, at which time, we trigger a decode operation. | ||
586 | */ | ||
587 | static void nvt_process_rx_ir_data(struct nvt_dev *nvt) | ||
588 | { | ||
589 | DEFINE_IR_RAW_EVENT(rawir); | ||
590 | unsigned int count; | ||
591 | u32 carrier; | ||
592 | u8 sample; | ||
593 | int i; | ||
594 | |||
595 | nvt_dbg_verbose("%s firing", __func__); | ||
596 | |||
597 | if (debug) | ||
598 | nvt_dump_rx_buf(nvt); | ||
599 | |||
600 | if (nvt->carrier_detect_enabled) | ||
601 | carrier = nvt_rx_carrier_detect(nvt); | ||
602 | |||
603 | count = nvt->pkts; | ||
604 | nvt_dbg_verbose("Processing buffer of len %d", count); | ||
605 | |||
606 | for (i = 0; i < count; i++) { | ||
607 | nvt->pkts--; | ||
608 | sample = nvt->buf[i]; | ||
609 | |||
610 | rawir.pulse = ((sample & BUF_PULSE_BIT) != 0); | ||
611 | rawir.duration = (sample & BUF_LEN_MASK) | ||
612 | * SAMPLE_PERIOD * 1000; | ||
613 | |||
614 | if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) { | ||
615 | if (nvt->rawir.pulse == rawir.pulse) | ||
616 | nvt->rawir.duration += rawir.duration; | ||
617 | else { | ||
618 | nvt->rawir.duration = rawir.duration; | ||
619 | nvt->rawir.pulse = rawir.pulse; | ||
620 | } | ||
621 | continue; | ||
622 | } | ||
623 | |||
624 | rawir.duration += nvt->rawir.duration; | ||
625 | |||
626 | init_ir_raw_event(&nvt->rawir); | ||
627 | nvt->rawir.duration = 0; | ||
628 | nvt->rawir.pulse = rawir.pulse; | ||
629 | |||
630 | if (sample == BUF_PULSE_BIT) | ||
631 | rawir.pulse = false; | ||
632 | |||
633 | if (rawir.duration) { | ||
634 | nvt_dbg("Storing %s with duration %d", | ||
635 | rawir.pulse ? "pulse" : "space", | ||
636 | rawir.duration); | ||
637 | |||
638 | ir_raw_event_store(nvt->rdev, &rawir); | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | * BUF_PULSE_BIT indicates end of IR data, BUF_REPEAT_BYTE | ||
643 | * indicates end of IR signal, but new data incoming. In both | ||
644 | * cases, it means we're ready to call ir_raw_event_handle | ||
645 | */ | ||
646 | if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) && | ||
647 | (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE)) | ||
648 | ir_raw_event_handle(nvt->rdev); | ||
649 | } | ||
650 | |||
651 | if (nvt->pkts) { | ||
652 | nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); | ||
653 | nvt->pkts = 0; | ||
654 | } | ||
655 | |||
656 | nvt_dbg_verbose("%s done", __func__); | ||
657 | } | ||
658 | |||
659 | static void nvt_handle_rx_fifo_overrun(struct nvt_dev *nvt) | ||
660 | { | ||
661 | nvt_pr(KERN_WARNING, "RX FIFO overrun detected, flushing data!"); | ||
662 | |||
663 | nvt->pkts = 0; | ||
664 | nvt_clear_cir_fifo(nvt); | ||
665 | ir_raw_event_reset(nvt->rdev); | ||
666 | } | ||
667 | |||
668 | /* copy data from hardware rx fifo into driver buffer */ | ||
669 | static void nvt_get_rx_ir_data(struct nvt_dev *nvt) | ||
670 | { | ||
671 | unsigned long flags; | ||
672 | u8 fifocount, val; | ||
673 | unsigned int b_idx; | ||
674 | bool overrun = false; | ||
675 | int i; | ||
676 | |||
677 | /* Get count of how many bytes to read from RX FIFO */ | ||
678 | fifocount = nvt_cir_reg_read(nvt, CIR_RXFCONT); | ||
679 | /* if we get 0xff, probably means the logical dev is disabled */ | ||
680 | if (fifocount == 0xff) | ||
681 | return; | ||
682 | /* watch out for a fifo overrun condition */ | ||
683 | else if (fifocount > RX_BUF_LEN) { | ||
684 | overrun = true; | ||
685 | fifocount = RX_BUF_LEN; | ||
686 | } | ||
687 | |||
688 | nvt_dbg("attempting to fetch %u bytes from hw rx fifo", fifocount); | ||
689 | |||
690 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
691 | |||
692 | b_idx = nvt->pkts; | ||
693 | |||
694 | /* This should never happen, but lets check anyway... */ | ||
695 | if (b_idx + fifocount > RX_BUF_LEN) { | ||
696 | nvt_process_rx_ir_data(nvt); | ||
697 | b_idx = 0; | ||
698 | } | ||
699 | |||
700 | /* Read fifocount bytes from CIR Sample RX FIFO register */ | ||
701 | for (i = 0; i < fifocount; i++) { | ||
702 | val = nvt_cir_reg_read(nvt, CIR_SRXFIFO); | ||
703 | nvt->buf[b_idx + i] = val; | ||
704 | } | ||
705 | |||
706 | nvt->pkts += fifocount; | ||
707 | nvt_dbg("%s: pkts now %d", __func__, nvt->pkts); | ||
708 | |||
709 | nvt_process_rx_ir_data(nvt); | ||
710 | |||
711 | if (overrun) | ||
712 | nvt_handle_rx_fifo_overrun(nvt); | ||
713 | |||
714 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
715 | } | ||
716 | |||
717 | static void nvt_cir_log_irqs(u8 status, u8 iren) | ||
718 | { | ||
719 | nvt_pr(KERN_INFO, "IRQ 0x%02x (IREN 0x%02x) :%s%s%s%s%s%s%s%s%s", | ||
720 | status, iren, | ||
721 | status & CIR_IRSTS_RDR ? " RDR" : "", | ||
722 | status & CIR_IRSTS_RTR ? " RTR" : "", | ||
723 | status & CIR_IRSTS_PE ? " PE" : "", | ||
724 | status & CIR_IRSTS_RFO ? " RFO" : "", | ||
725 | status & CIR_IRSTS_TE ? " TE" : "", | ||
726 | status & CIR_IRSTS_TTR ? " TTR" : "", | ||
727 | status & CIR_IRSTS_TFU ? " TFU" : "", | ||
728 | status & CIR_IRSTS_GH ? " GH" : "", | ||
729 | status & ~(CIR_IRSTS_RDR | CIR_IRSTS_RTR | CIR_IRSTS_PE | | ||
730 | CIR_IRSTS_RFO | CIR_IRSTS_TE | CIR_IRSTS_TTR | | ||
731 | CIR_IRSTS_TFU | CIR_IRSTS_GH) ? " ?" : ""); | ||
732 | } | ||
733 | |||
734 | static bool nvt_cir_tx_inactive(struct nvt_dev *nvt) | ||
735 | { | ||
736 | unsigned long flags; | ||
737 | bool tx_inactive; | ||
738 | u8 tx_state; | ||
739 | |||
740 | spin_lock_irqsave(&nvt->tx.lock, flags); | ||
741 | tx_state = nvt->tx.tx_state; | ||
742 | spin_unlock_irqrestore(&nvt->tx.lock, flags); | ||
743 | |||
744 | tx_inactive = (tx_state == ST_TX_NONE); | ||
745 | |||
746 | return tx_inactive; | ||
747 | } | ||
748 | |||
749 | /* interrupt service routine for incoming and outgoing CIR data */ | ||
750 | static irqreturn_t nvt_cir_isr(int irq, void *data) | ||
751 | { | ||
752 | struct nvt_dev *nvt = data; | ||
753 | u8 status, iren, cur_state; | ||
754 | unsigned long flags; | ||
755 | |||
756 | nvt_dbg_verbose("%s firing", __func__); | ||
757 | |||
758 | nvt_efm_enable(nvt); | ||
759 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
760 | nvt_efm_disable(nvt); | ||
761 | |||
762 | /* | ||
763 | * Get IR Status register contents. Write 1 to ack/clear | ||
764 | * | ||
765 | * bit: reg name - description | ||
766 | * 7: CIR_IRSTS_RDR - RX Data Ready | ||
767 | * 6: CIR_IRSTS_RTR - RX FIFO Trigger Level Reach | ||
768 | * 5: CIR_IRSTS_PE - Packet End | ||
769 | * 4: CIR_IRSTS_RFO - RX FIFO Overrun (RDR will also be set) | ||
770 | * 3: CIR_IRSTS_TE - TX FIFO Empty | ||
771 | * 2: CIR_IRSTS_TTR - TX FIFO Trigger Level Reach | ||
772 | * 1: CIR_IRSTS_TFU - TX FIFO Underrun | ||
773 | * 0: CIR_IRSTS_GH - Min Length Detected | ||
774 | */ | ||
775 | status = nvt_cir_reg_read(nvt, CIR_IRSTS); | ||
776 | if (!status) { | ||
777 | nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__); | ||
778 | nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); | ||
779 | return IRQ_RETVAL(IRQ_NONE); | ||
780 | } | ||
781 | |||
782 | /* ack/clear all irq flags we've got */ | ||
783 | nvt_cir_reg_write(nvt, status, CIR_IRSTS); | ||
784 | nvt_cir_reg_write(nvt, 0, CIR_IRSTS); | ||
785 | |||
786 | /* Interrupt may be shared with CIR Wake, bail if CIR not enabled */ | ||
787 | iren = nvt_cir_reg_read(nvt, CIR_IREN); | ||
788 | if (!iren) { | ||
789 | nvt_dbg_verbose("%s exiting, CIR not enabled", __func__); | ||
790 | return IRQ_RETVAL(IRQ_NONE); | ||
791 | } | ||
792 | |||
793 | if (debug) | ||
794 | nvt_cir_log_irqs(status, iren); | ||
795 | |||
796 | if (status & CIR_IRSTS_RTR) { | ||
797 | /* FIXME: add code for study/learn mode */ | ||
798 | /* We only do rx if not tx'ing */ | ||
799 | if (nvt_cir_tx_inactive(nvt)) | ||
800 | nvt_get_rx_ir_data(nvt); | ||
801 | } | ||
802 | |||
803 | if (status & CIR_IRSTS_PE) { | ||
804 | if (nvt_cir_tx_inactive(nvt)) | ||
805 | nvt_get_rx_ir_data(nvt); | ||
806 | |||
807 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
808 | |||
809 | cur_state = nvt->study_state; | ||
810 | |||
811 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
812 | |||
813 | if (cur_state == ST_STUDY_NONE) | ||
814 | nvt_clear_cir_fifo(nvt); | ||
815 | } | ||
816 | |||
817 | if (status & CIR_IRSTS_TE) | ||
818 | nvt_clear_tx_fifo(nvt); | ||
819 | |||
820 | if (status & CIR_IRSTS_TTR) { | ||
821 | unsigned int pos, count; | ||
822 | u8 tmp; | ||
823 | |||
824 | spin_lock_irqsave(&nvt->tx.lock, flags); | ||
825 | |||
826 | pos = nvt->tx.cur_buf_num; | ||
827 | count = nvt->tx.buf_count; | ||
828 | |||
829 | /* Write data into the hardware tx fifo while pos < count */ | ||
830 | if (pos < count) { | ||
831 | nvt_cir_reg_write(nvt, nvt->tx.buf[pos], CIR_STXFIFO); | ||
832 | nvt->tx.cur_buf_num++; | ||
833 | /* Disable TX FIFO Trigger Level Reach (TTR) interrupt */ | ||
834 | } else { | ||
835 | tmp = nvt_cir_reg_read(nvt, CIR_IREN); | ||
836 | nvt_cir_reg_write(nvt, tmp & ~CIR_IREN_TTR, CIR_IREN); | ||
837 | } | ||
838 | |||
839 | spin_unlock_irqrestore(&nvt->tx.lock, flags); | ||
840 | |||
841 | } | ||
842 | |||
843 | if (status & CIR_IRSTS_TFU) { | ||
844 | spin_lock_irqsave(&nvt->tx.lock, flags); | ||
845 | if (nvt->tx.tx_state == ST_TX_REPLY) { | ||
846 | nvt->tx.tx_state = ST_TX_REQUEST; | ||
847 | wake_up(&nvt->tx.queue); | ||
848 | } | ||
849 | spin_unlock_irqrestore(&nvt->tx.lock, flags); | ||
850 | } | ||
851 | |||
852 | nvt_dbg_verbose("%s done", __func__); | ||
853 | return IRQ_RETVAL(IRQ_HANDLED); | ||
854 | } | ||
855 | |||
856 | /* Interrupt service routine for CIR Wake */ | ||
857 | static irqreturn_t nvt_cir_wake_isr(int irq, void *data) | ||
858 | { | ||
859 | u8 status, iren, val; | ||
860 | struct nvt_dev *nvt = data; | ||
861 | unsigned long flags; | ||
862 | |||
863 | nvt_dbg_wake("%s firing", __func__); | ||
864 | |||
865 | status = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS); | ||
866 | if (!status) | ||
867 | return IRQ_RETVAL(IRQ_NONE); | ||
868 | |||
869 | if (status & CIR_WAKE_IRSTS_IR_PENDING) | ||
870 | nvt_clear_cir_wake_fifo(nvt); | ||
871 | |||
872 | nvt_cir_wake_reg_write(nvt, status, CIR_WAKE_IRSTS); | ||
873 | nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IRSTS); | ||
874 | |||
875 | /* Interrupt may be shared with CIR, bail if Wake not enabled */ | ||
876 | iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN); | ||
877 | if (!iren) { | ||
878 | nvt_dbg_wake("%s exiting, wake not enabled", __func__); | ||
879 | return IRQ_RETVAL(IRQ_HANDLED); | ||
880 | } | ||
881 | |||
882 | if ((status & CIR_WAKE_IRSTS_PE) && | ||
883 | (nvt->wake_state == ST_WAKE_START)) { | ||
884 | while (nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)) { | ||
885 | val = nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY); | ||
886 | nvt_dbg("setting wake up key: 0x%x", val); | ||
887 | } | ||
888 | |||
889 | nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN); | ||
890 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
891 | nvt->wake_state = ST_WAKE_FINISH; | ||
892 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
893 | } | ||
894 | |||
895 | nvt_dbg_wake("%s done", __func__); | ||
896 | return IRQ_RETVAL(IRQ_HANDLED); | ||
897 | } | ||
898 | |||
899 | static void nvt_enable_cir(struct nvt_dev *nvt) | ||
900 | { | ||
901 | /* set function enable flags */ | ||
902 | nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN | | ||
903 | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, | ||
904 | CIR_IRCON); | ||
905 | |||
906 | nvt_efm_enable(nvt); | ||
907 | |||
908 | /* enable the CIR logical device */ | ||
909 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
910 | nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); | ||
911 | |||
912 | nvt_efm_disable(nvt); | ||
913 | |||
914 | /* clear all pending interrupts */ | ||
915 | nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); | ||
916 | |||
917 | /* enable interrupts */ | ||
918 | nvt_set_cir_iren(nvt); | ||
919 | } | ||
920 | |||
921 | static void nvt_disable_cir(struct nvt_dev *nvt) | ||
922 | { | ||
923 | /* disable CIR interrupts */ | ||
924 | nvt_cir_reg_write(nvt, 0, CIR_IREN); | ||
925 | |||
926 | /* clear any and all pending interrupts */ | ||
927 | nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); | ||
928 | |||
929 | /* clear all function enable flags */ | ||
930 | nvt_cir_reg_write(nvt, 0, CIR_IRCON); | ||
931 | |||
932 | /* clear hardware rx and tx fifos */ | ||
933 | nvt_clear_cir_fifo(nvt); | ||
934 | nvt_clear_tx_fifo(nvt); | ||
935 | |||
936 | nvt_efm_enable(nvt); | ||
937 | |||
938 | /* disable the CIR logical device */ | ||
939 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
940 | nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN); | ||
941 | |||
942 | nvt_efm_disable(nvt); | ||
943 | } | ||
944 | |||
945 | static int nvt_open(void *data) | ||
946 | { | ||
947 | struct nvt_dev *nvt = (struct nvt_dev *)data; | ||
948 | unsigned long flags; | ||
949 | |||
950 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
951 | nvt->in_use = true; | ||
952 | nvt_enable_cir(nvt); | ||
953 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static void nvt_close(void *data) | ||
959 | { | ||
960 | struct nvt_dev *nvt = (struct nvt_dev *)data; | ||
961 | unsigned long flags; | ||
962 | |||
963 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
964 | nvt->in_use = false; | ||
965 | nvt_disable_cir(nvt); | ||
966 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
967 | } | ||
968 | |||
969 | /* Allocate memory, probe hardware, and initialize everything */ | ||
970 | static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) | ||
971 | { | ||
972 | struct nvt_dev *nvt = NULL; | ||
973 | struct input_dev *rdev = NULL; | ||
974 | struct ir_dev_props *props = NULL; | ||
975 | int ret = -ENOMEM; | ||
976 | |||
977 | nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL); | ||
978 | if (!nvt) | ||
979 | return ret; | ||
980 | |||
981 | props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); | ||
982 | if (!props) | ||
983 | goto failure; | ||
984 | |||
985 | /* input device for IR remote (and tx) */ | ||
986 | rdev = input_allocate_device(); | ||
987 | if (!rdev) | ||
988 | goto failure; | ||
989 | |||
990 | ret = -ENODEV; | ||
991 | /* validate pnp resources */ | ||
992 | if (!pnp_port_valid(pdev, 0) || | ||
993 | pnp_port_len(pdev, 0) < CIR_IOREG_LENGTH) { | ||
994 | dev_err(&pdev->dev, "IR PNP Port not valid!\n"); | ||
995 | goto failure; | ||
996 | } | ||
997 | |||
998 | if (!pnp_irq_valid(pdev, 0)) { | ||
999 | dev_err(&pdev->dev, "PNP IRQ not valid!\n"); | ||
1000 | goto failure; | ||
1001 | } | ||
1002 | |||
1003 | if (!pnp_port_valid(pdev, 1) || | ||
1004 | pnp_port_len(pdev, 1) < CIR_IOREG_LENGTH) { | ||
1005 | dev_err(&pdev->dev, "Wake PNP Port not valid!\n"); | ||
1006 | goto failure; | ||
1007 | } | ||
1008 | |||
1009 | nvt->cir_addr = pnp_port_start(pdev, 0); | ||
1010 | nvt->cir_irq = pnp_irq(pdev, 0); | ||
1011 | |||
1012 | nvt->cir_wake_addr = pnp_port_start(pdev, 1); | ||
1013 | /* irq is always shared between cir and cir wake */ | ||
1014 | nvt->cir_wake_irq = nvt->cir_irq; | ||
1015 | |||
1016 | nvt->cr_efir = CR_EFIR; | ||
1017 | nvt->cr_efdr = CR_EFDR; | ||
1018 | |||
1019 | spin_lock_init(&nvt->nvt_lock); | ||
1020 | spin_lock_init(&nvt->tx.lock); | ||
1021 | init_ir_raw_event(&nvt->rawir); | ||
1022 | |||
1023 | ret = -EBUSY; | ||
1024 | /* now claim resources */ | ||
1025 | if (!request_region(nvt->cir_addr, | ||
1026 | CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) | ||
1027 | goto failure; | ||
1028 | |||
1029 | if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, | ||
1030 | NVT_DRIVER_NAME, (void *)nvt)) | ||
1031 | goto failure; | ||
1032 | |||
1033 | if (!request_region(nvt->cir_wake_addr, | ||
1034 | CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) | ||
1035 | goto failure; | ||
1036 | |||
1037 | if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, | ||
1038 | NVT_DRIVER_NAME, (void *)nvt)) | ||
1039 | goto failure; | ||
1040 | |||
1041 | pnp_set_drvdata(pdev, nvt); | ||
1042 | nvt->pdev = pdev; | ||
1043 | |||
1044 | init_waitqueue_head(&nvt->tx.queue); | ||
1045 | |||
1046 | ret = nvt_hw_detect(nvt); | ||
1047 | if (ret) | ||
1048 | goto failure; | ||
1049 | |||
1050 | /* Initialize CIR & CIR Wake Logical Devices */ | ||
1051 | nvt_efm_enable(nvt); | ||
1052 | nvt_cir_ldev_init(nvt); | ||
1053 | nvt_cir_wake_ldev_init(nvt); | ||
1054 | nvt_efm_disable(nvt); | ||
1055 | |||
1056 | /* Initialize CIR & CIR Wake Config Registers */ | ||
1057 | nvt_cir_regs_init(nvt); | ||
1058 | nvt_cir_wake_regs_init(nvt); | ||
1059 | |||
1060 | /* Set up ir-core props */ | ||
1061 | props->priv = nvt; | ||
1062 | props->driver_type = RC_DRIVER_IR_RAW; | ||
1063 | props->allowed_protos = IR_TYPE_ALL; | ||
1064 | props->open = nvt_open; | ||
1065 | props->close = nvt_close; | ||
1066 | #if 0 | ||
1067 | props->min_timeout = XYZ; | ||
1068 | props->max_timeout = XYZ; | ||
1069 | props->timeout = XYZ; | ||
1070 | /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ | ||
1071 | props->rx_resolution = XYZ; | ||
1072 | |||
1073 | /* tx bits */ | ||
1074 | props->tx_resolution = XYZ; | ||
1075 | #endif | ||
1076 | props->tx_ir = nvt_tx_ir; | ||
1077 | props->s_tx_carrier = nvt_set_tx_carrier; | ||
1078 | |||
1079 | rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver"; | ||
1080 | rdev->id.bustype = BUS_HOST; | ||
1081 | rdev->id.vendor = PCI_VENDOR_ID_WINBOND2; | ||
1082 | rdev->id.product = nvt->chip_major; | ||
1083 | rdev->id.version = nvt->chip_minor; | ||
1084 | |||
1085 | nvt->props = props; | ||
1086 | nvt->rdev = rdev; | ||
1087 | |||
1088 | device_set_wakeup_capable(&pdev->dev, 1); | ||
1089 | device_set_wakeup_enable(&pdev->dev, 1); | ||
1090 | |||
1091 | ret = ir_input_register(rdev, RC_MAP_RC6_MCE, props, NVT_DRIVER_NAME); | ||
1092 | if (ret) | ||
1093 | goto failure; | ||
1094 | |||
1095 | nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n"); | ||
1096 | if (debug) { | ||
1097 | cir_dump_regs(nvt); | ||
1098 | cir_wake_dump_regs(nvt); | ||
1099 | } | ||
1100 | |||
1101 | return 0; | ||
1102 | |||
1103 | failure: | ||
1104 | if (nvt->cir_irq) | ||
1105 | free_irq(nvt->cir_irq, nvt); | ||
1106 | if (nvt->cir_addr) | ||
1107 | release_region(nvt->cir_addr, CIR_IOREG_LENGTH); | ||
1108 | |||
1109 | if (nvt->cir_wake_irq) | ||
1110 | free_irq(nvt->cir_wake_irq, nvt); | ||
1111 | if (nvt->cir_wake_addr) | ||
1112 | release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); | ||
1113 | |||
1114 | input_free_device(rdev); | ||
1115 | kfree(props); | ||
1116 | kfree(nvt); | ||
1117 | |||
1118 | return ret; | ||
1119 | } | ||
1120 | |||
1121 | static void __devexit nvt_remove(struct pnp_dev *pdev) | ||
1122 | { | ||
1123 | struct nvt_dev *nvt = pnp_get_drvdata(pdev); | ||
1124 | unsigned long flags; | ||
1125 | |||
1126 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
1127 | /* disable CIR */ | ||
1128 | nvt_cir_reg_write(nvt, 0, CIR_IREN); | ||
1129 | nvt_disable_cir(nvt); | ||
1130 | /* enable CIR Wake (for IR power-on) */ | ||
1131 | nvt_enable_wake(nvt); | ||
1132 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
1133 | |||
1134 | /* free resources */ | ||
1135 | free_irq(nvt->cir_irq, nvt); | ||
1136 | free_irq(nvt->cir_wake_irq, nvt); | ||
1137 | release_region(nvt->cir_addr, CIR_IOREG_LENGTH); | ||
1138 | release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); | ||
1139 | |||
1140 | ir_input_unregister(nvt->rdev); | ||
1141 | |||
1142 | kfree(nvt->props); | ||
1143 | kfree(nvt); | ||
1144 | } | ||
1145 | |||
1146 | static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) | ||
1147 | { | ||
1148 | struct nvt_dev *nvt = pnp_get_drvdata(pdev); | ||
1149 | unsigned long flags; | ||
1150 | |||
1151 | nvt_dbg("%s called", __func__); | ||
1152 | |||
1153 | /* zero out misc state tracking */ | ||
1154 | spin_lock_irqsave(&nvt->nvt_lock, flags); | ||
1155 | nvt->study_state = ST_STUDY_NONE; | ||
1156 | nvt->wake_state = ST_WAKE_NONE; | ||
1157 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | ||
1158 | |||
1159 | spin_lock_irqsave(&nvt->tx.lock, flags); | ||
1160 | nvt->tx.tx_state = ST_TX_NONE; | ||
1161 | spin_unlock_irqrestore(&nvt->tx.lock, flags); | ||
1162 | |||
1163 | /* disable all CIR interrupts */ | ||
1164 | nvt_cir_reg_write(nvt, 0, CIR_IREN); | ||
1165 | |||
1166 | nvt_efm_enable(nvt); | ||
1167 | |||
1168 | /* disable cir logical dev */ | ||
1169 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
1170 | nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN); | ||
1171 | |||
1172 | nvt_efm_disable(nvt); | ||
1173 | |||
1174 | /* make sure wake is enabled */ | ||
1175 | nvt_enable_wake(nvt); | ||
1176 | |||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | static int nvt_resume(struct pnp_dev *pdev) | ||
1181 | { | ||
1182 | int ret = 0; | ||
1183 | struct nvt_dev *nvt = pnp_get_drvdata(pdev); | ||
1184 | |||
1185 | nvt_dbg("%s called", __func__); | ||
1186 | |||
1187 | /* open interrupt */ | ||
1188 | nvt_set_cir_iren(nvt); | ||
1189 | |||
1190 | /* Enable CIR logical device */ | ||
1191 | nvt_efm_enable(nvt); | ||
1192 | nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); | ||
1193 | nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); | ||
1194 | |||
1195 | nvt_efm_disable(nvt); | ||
1196 | |||
1197 | nvt_cir_regs_init(nvt); | ||
1198 | nvt_cir_wake_regs_init(nvt); | ||
1199 | |||
1200 | return ret; | ||
1201 | } | ||
1202 | |||
1203 | static void nvt_shutdown(struct pnp_dev *pdev) | ||
1204 | { | ||
1205 | struct nvt_dev *nvt = pnp_get_drvdata(pdev); | ||
1206 | nvt_enable_wake(nvt); | ||
1207 | } | ||
1208 | |||
1209 | static const struct pnp_device_id nvt_ids[] = { | ||
1210 | { "WEC0530", 0 }, /* CIR */ | ||
1211 | { "NTN0530", 0 }, /* CIR for new chip's pnp id*/ | ||
1212 | { "", 0 }, | ||
1213 | }; | ||
1214 | |||
1215 | static struct pnp_driver nvt_driver = { | ||
1216 | .name = NVT_DRIVER_NAME, | ||
1217 | .id_table = nvt_ids, | ||
1218 | .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, | ||
1219 | .probe = nvt_probe, | ||
1220 | .remove = __devexit_p(nvt_remove), | ||
1221 | .suspend = nvt_suspend, | ||
1222 | .resume = nvt_resume, | ||
1223 | .shutdown = nvt_shutdown, | ||
1224 | }; | ||
1225 | |||
1226 | int nvt_init(void) | ||
1227 | { | ||
1228 | return pnp_register_driver(&nvt_driver); | ||
1229 | } | ||
1230 | |||
1231 | void nvt_exit(void) | ||
1232 | { | ||
1233 | pnp_unregister_driver(&nvt_driver); | ||
1234 | } | ||
1235 | |||
1236 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
1237 | MODULE_PARM_DESC(debug, "Enable debugging output"); | ||
1238 | |||
1239 | MODULE_DEVICE_TABLE(pnp, nvt_ids); | ||
1240 | MODULE_DESCRIPTION("Nuvoton W83667HG-A & W83677HG-I CIR driver"); | ||
1241 | |||
1242 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
1243 | MODULE_LICENSE("GPL"); | ||
1244 | |||
1245 | module_init(nvt_init); | ||
1246 | module_exit(nvt_exit); | ||
diff --git a/drivers/media/IR/nuvoton-cir.h b/drivers/media/IR/nuvoton-cir.h new file mode 100644 index 00000000000..62dc53017c8 --- /dev/null +++ b/drivers/media/IR/nuvoton-cir.h | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR | ||
3 | * | ||
4 | * Copyright (C) 2010 Jarod Wilson <jarod@redhat.com> | ||
5 | * Copyright (C) 2009 Nuvoton PS Team | ||
6 | * | ||
7 | * Special thanks to Nuvoton for providing hardware, spec sheets and | ||
8 | * sample code upon which portions of this driver are based. Indirect | ||
9 | * thanks also to Maxim Levitsky, whose ene_ir driver this driver is | ||
10 | * modeled after. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License as | ||
14 | * published by the Free Software Foundation; either version 2 of the | ||
15 | * License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, but | ||
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
25 | * USA | ||
26 | */ | ||
27 | |||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/ioctl.h> | ||
30 | |||
31 | /* platform driver name to register */ | ||
32 | #define NVT_DRIVER_NAME "nuvoton-cir" | ||
33 | |||
34 | /* debugging module parameter */ | ||
35 | static int debug; | ||
36 | |||
37 | |||
38 | #define nvt_pr(level, text, ...) \ | ||
39 | printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__) | ||
40 | |||
41 | #define nvt_dbg(text, ...) \ | ||
42 | if (debug) \ | ||
43 | printk(KERN_DEBUG \ | ||
44 | KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) | ||
45 | |||
46 | #define nvt_dbg_verbose(text, ...) \ | ||
47 | if (debug > 1) \ | ||
48 | printk(KERN_DEBUG \ | ||
49 | KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) | ||
50 | |||
51 | #define nvt_dbg_wake(text, ...) \ | ||
52 | if (debug > 2) \ | ||
53 | printk(KERN_DEBUG \ | ||
54 | KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) | ||
55 | |||
56 | |||
57 | /* | ||
58 | * Original lirc driver said min value of 76, and recommended value of 256 | ||
59 | * for the buffer length, but then used 2048. Never mind that the size of the | ||
60 | * RX FIFO is 32 bytes... So I'm using 32 for RX and 256 for TX atm, but I'm | ||
61 | * not sure if maybe that TX value is off by a factor of 8 (bits vs. bytes), | ||
62 | * and I don't have TX-capable hardware to test/debug on... | ||
63 | */ | ||
64 | #define TX_BUF_LEN 256 | ||
65 | #define RX_BUF_LEN 32 | ||
66 | |||
67 | struct nvt_dev { | ||
68 | struct pnp_dev *pdev; | ||
69 | struct input_dev *rdev; | ||
70 | struct ir_dev_props *props; | ||
71 | struct ir_raw_event rawir; | ||
72 | |||
73 | spinlock_t nvt_lock; | ||
74 | bool in_use; | ||
75 | |||
76 | /* for rx */ | ||
77 | u8 buf[RX_BUF_LEN]; | ||
78 | unsigned int pkts; | ||
79 | |||
80 | struct { | ||
81 | spinlock_t lock; | ||
82 | u8 buf[TX_BUF_LEN]; | ||
83 | unsigned int buf_count; | ||
84 | unsigned int cur_buf_num; | ||
85 | wait_queue_head_t queue; | ||
86 | u8 tx_state; | ||
87 | } tx; | ||
88 | |||
89 | /* EFER Config register index/data pair */ | ||
90 | u8 cr_efir; | ||
91 | u8 cr_efdr; | ||
92 | |||
93 | /* hardware I/O settings */ | ||
94 | unsigned long cir_addr; | ||
95 | unsigned long cir_wake_addr; | ||
96 | int cir_irq; | ||
97 | int cir_wake_irq; | ||
98 | |||
99 | /* hardware id */ | ||
100 | u8 chip_major; | ||
101 | u8 chip_minor; | ||
102 | |||
103 | /* hardware features */ | ||
104 | bool hw_learning_capable; | ||
105 | bool hw_tx_capable; | ||
106 | |||
107 | /* rx settings */ | ||
108 | bool learning_enabled; | ||
109 | bool carrier_detect_enabled; | ||
110 | |||
111 | /* track cir wake state */ | ||
112 | u8 wake_state; | ||
113 | /* for study */ | ||
114 | u8 study_state; | ||
115 | /* carrier period = 1 / frequency */ | ||
116 | u32 carrier; | ||
117 | }; | ||
118 | |||
119 | /* study states */ | ||
120 | #define ST_STUDY_NONE 0x0 | ||
121 | #define ST_STUDY_START 0x1 | ||
122 | #define ST_STUDY_CARRIER 0x2 | ||
123 | #define ST_STUDY_ALL_RECV 0x4 | ||
124 | |||
125 | /* wake states */ | ||
126 | #define ST_WAKE_NONE 0x0 | ||
127 | #define ST_WAKE_START 0x1 | ||
128 | #define ST_WAKE_FINISH 0x2 | ||
129 | |||
130 | /* receive states */ | ||
131 | #define ST_RX_WAIT_7F 0x1 | ||
132 | #define ST_RX_WAIT_HEAD 0x2 | ||
133 | #define ST_RX_WAIT_SILENT_END 0x4 | ||
134 | |||
135 | /* send states */ | ||
136 | #define ST_TX_NONE 0x0 | ||
137 | #define ST_TX_REQUEST 0x2 | ||
138 | #define ST_TX_REPLY 0x4 | ||
139 | |||
140 | /* buffer packet constants */ | ||
141 | #define BUF_PULSE_BIT 0x80 | ||
142 | #define BUF_LEN_MASK 0x7f | ||
143 | #define BUF_REPEAT_BYTE 0x70 | ||
144 | #define BUF_REPEAT_MASK 0xf0 | ||
145 | |||
146 | /* CIR settings */ | ||
147 | |||
148 | /* total length of CIR and CIR WAKE */ | ||
149 | #define CIR_IOREG_LENGTH 0x0f | ||
150 | |||
151 | /* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL (0x7d0 = 2000) */ | ||
152 | #define CIR_RX_LIMIT_COUNT 0x7d0 | ||
153 | |||
154 | /* CIR Regs */ | ||
155 | #define CIR_IRCON 0x00 | ||
156 | #define CIR_IRSTS 0x01 | ||
157 | #define CIR_IREN 0x02 | ||
158 | #define CIR_RXFCONT 0x03 | ||
159 | #define CIR_CP 0x04 | ||
160 | #define CIR_CC 0x05 | ||
161 | #define CIR_SLCH 0x06 | ||
162 | #define CIR_SLCL 0x07 | ||
163 | #define CIR_FIFOCON 0x08 | ||
164 | #define CIR_IRFIFOSTS 0x09 | ||
165 | #define CIR_SRXFIFO 0x0a | ||
166 | #define CIR_TXFCONT 0x0b | ||
167 | #define CIR_STXFIFO 0x0c | ||
168 | #define CIR_FCCH 0x0d | ||
169 | #define CIR_FCCL 0x0e | ||
170 | #define CIR_IRFSM 0x0f | ||
171 | |||
172 | /* CIR IRCON settings */ | ||
173 | #define CIR_IRCON_RECV 0x80 | ||
174 | #define CIR_IRCON_WIREN 0x40 | ||
175 | #define CIR_IRCON_TXEN 0x20 | ||
176 | #define CIR_IRCON_RXEN 0x10 | ||
177 | #define CIR_IRCON_WRXINV 0x08 | ||
178 | #define CIR_IRCON_RXINV 0x04 | ||
179 | |||
180 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00 | ||
181 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01 | ||
182 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02 | ||
183 | #define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03 | ||
184 | |||
185 | /* FIXME: make this a runtime option */ | ||
186 | /* select sample period as 50us */ | ||
187 | #define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 | ||
188 | |||
189 | /* CIR IRSTS settings */ | ||
190 | #define CIR_IRSTS_RDR 0x80 | ||
191 | #define CIR_IRSTS_RTR 0x40 | ||
192 | #define CIR_IRSTS_PE 0x20 | ||
193 | #define CIR_IRSTS_RFO 0x10 | ||
194 | #define CIR_IRSTS_TE 0x08 | ||
195 | #define CIR_IRSTS_TTR 0x04 | ||
196 | #define CIR_IRSTS_TFU 0x02 | ||
197 | #define CIR_IRSTS_GH 0x01 | ||
198 | |||
199 | /* CIR IREN settings */ | ||
200 | #define CIR_IREN_RDR 0x80 | ||
201 | #define CIR_IREN_RTR 0x40 | ||
202 | #define CIR_IREN_PE 0x20 | ||
203 | #define CIR_IREN_RFO 0x10 | ||
204 | #define CIR_IREN_TE 0x08 | ||
205 | #define CIR_IREN_TTR 0x04 | ||
206 | #define CIR_IREN_TFU 0x02 | ||
207 | #define CIR_IREN_GH 0x01 | ||
208 | |||
209 | /* CIR FIFOCON settings */ | ||
210 | #define CIR_FIFOCON_TXFIFOCLR 0x80 | ||
211 | |||
212 | #define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00 | ||
213 | #define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10 | ||
214 | #define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20 | ||
215 | #define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30 | ||
216 | |||
217 | /* FIXME: make this a runtime option */ | ||
218 | /* select TX trigger level as 16 */ | ||
219 | #define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16 | ||
220 | |||
221 | #define CIR_FIFOCON_RXFIFOCLR 0x08 | ||
222 | |||
223 | #define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00 | ||
224 | #define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01 | ||
225 | #define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02 | ||
226 | #define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03 | ||
227 | |||
228 | /* FIXME: make this a runtime option */ | ||
229 | /* select RX trigger level as 24 */ | ||
230 | #define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_24 | ||
231 | |||
232 | /* CIR IRFIFOSTS settings */ | ||
233 | #define CIR_IRFIFOSTS_IR_PENDING 0x80 | ||
234 | #define CIR_IRFIFOSTS_RX_GS 0x40 | ||
235 | #define CIR_IRFIFOSTS_RX_FTA 0x20 | ||
236 | #define CIR_IRFIFOSTS_RX_EMPTY 0x10 | ||
237 | #define CIR_IRFIFOSTS_RX_FULL 0x08 | ||
238 | #define CIR_IRFIFOSTS_TX_FTA 0x04 | ||
239 | #define CIR_IRFIFOSTS_TX_EMPTY 0x02 | ||
240 | #define CIR_IRFIFOSTS_TX_FULL 0x01 | ||
241 | |||
242 | |||
243 | /* CIR WAKE UP Regs */ | ||
244 | #define CIR_WAKE_IRCON 0x00 | ||
245 | #define CIR_WAKE_IRSTS 0x01 | ||
246 | #define CIR_WAKE_IREN 0x02 | ||
247 | #define CIR_WAKE_FIFO_CMP_DEEP 0x03 | ||
248 | #define CIR_WAKE_FIFO_CMP_TOL 0x04 | ||
249 | #define CIR_WAKE_FIFO_COUNT 0x05 | ||
250 | #define CIR_WAKE_SLCH 0x06 | ||
251 | #define CIR_WAKE_SLCL 0x07 | ||
252 | #define CIR_WAKE_FIFOCON 0x08 | ||
253 | #define CIR_WAKE_SRXFSTS 0x09 | ||
254 | #define CIR_WAKE_SAMPLE_RX_FIFO 0x0a | ||
255 | #define CIR_WAKE_WR_FIFO_DATA 0x0b | ||
256 | #define CIR_WAKE_RD_FIFO_ONLY 0x0c | ||
257 | #define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0d | ||
258 | #define CIR_WAKE_FIFO_IGNORE 0x0e | ||
259 | #define CIR_WAKE_IRFSM 0x0f | ||
260 | |||
261 | /* CIR WAKE UP IRCON settings */ | ||
262 | #define CIR_WAKE_IRCON_DEC_RST 0x80 | ||
263 | #define CIR_WAKE_IRCON_MODE1 0x40 | ||
264 | #define CIR_WAKE_IRCON_MODE0 0x20 | ||
265 | #define CIR_WAKE_IRCON_RXEN 0x10 | ||
266 | #define CIR_WAKE_IRCON_R 0x08 | ||
267 | #define CIR_WAKE_IRCON_RXINV 0x04 | ||
268 | |||
269 | /* FIXME/jarod: make this a runtime option */ | ||
270 | /* select a same sample period like cir register */ | ||
271 | #define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 | ||
272 | |||
273 | /* CIR WAKE IRSTS Bits */ | ||
274 | #define CIR_WAKE_IRSTS_RDR 0x80 | ||
275 | #define CIR_WAKE_IRSTS_RTR 0x40 | ||
276 | #define CIR_WAKE_IRSTS_PE 0x20 | ||
277 | #define CIR_WAKE_IRSTS_RFO 0x10 | ||
278 | #define CIR_WAKE_IRSTS_GH 0x08 | ||
279 | #define CIR_WAKE_IRSTS_IR_PENDING 0x01 | ||
280 | |||
281 | /* CIR WAKE UP IREN Bits */ | ||
282 | #define CIR_WAKE_IREN_RDR 0x80 | ||
283 | #define CIR_WAKE_IREN_RTR 0x40 | ||
284 | #define CIR_WAKE_IREN_PE 0x20 | ||
285 | #define CIR_WAKE_IREN_RFO 0x10 | ||
286 | #define CIR_WAKE_IREN_TE 0x08 | ||
287 | #define CIR_WAKE_IREN_TTR 0x04 | ||
288 | #define CIR_WAKE_IREN_TFU 0x02 | ||
289 | #define CIR_WAKE_IREN_GH 0x01 | ||
290 | |||
291 | /* CIR WAKE FIFOCON settings */ | ||
292 | #define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08 | ||
293 | |||
294 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00 | ||
295 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01 | ||
296 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02 | ||
297 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03 | ||
298 | |||
299 | /* FIXME: make this a runtime option */ | ||
300 | /* select WAKE UP RX trigger level as 67 */ | ||
301 | #define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 | ||
302 | |||
303 | /* CIR WAKE SRXFSTS settings */ | ||
304 | #define CIR_WAKE_IRFIFOSTS_RX_GS 0x80 | ||
305 | #define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40 | ||
306 | #define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 | ||
307 | #define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 | ||
308 | |||
309 | /* CIR Wake FIFO buffer is 67 bytes long */ | ||
310 | #define CIR_WAKE_FIFO_LEN 67 | ||
311 | /* CIR Wake byte comparison tolerance */ | ||
312 | #define CIR_WAKE_CMP_TOLERANCE 5 | ||
313 | |||
314 | /* | ||
315 | * Extended Function Enable Registers: | ||
316 | * Extended Function Index Register | ||
317 | * Extended Function Data Register | ||
318 | */ | ||
319 | #define CR_EFIR 0x2e | ||
320 | #define CR_EFDR 0x2f | ||
321 | |||
322 | /* Possible alternate EFER values, depends on how the chip is wired */ | ||
323 | #define CR_EFIR2 0x4e | ||
324 | #define CR_EFDR2 0x4f | ||
325 | |||
326 | /* Extended Function Mode enable/disable magic values */ | ||
327 | #define EFER_EFM_ENABLE 0x87 | ||
328 | #define EFER_EFM_DISABLE 0xaa | ||
329 | |||
330 | /* Chip IDs found in CR_CHIP_ID_{HI,LO} */ | ||
331 | #define CHIP_ID_HIGH 0xb4 | ||
332 | #define CHIP_ID_LOW 0x72 | ||
333 | #define CHIP_ID_LOW2 0x73 | ||
334 | |||
335 | /* Config regs we need to care about */ | ||
336 | #define CR_SOFTWARE_RESET 0x02 | ||
337 | #define CR_LOGICAL_DEV_SEL 0x07 | ||
338 | #define CR_CHIP_ID_HI 0x20 | ||
339 | #define CR_CHIP_ID_LO 0x21 | ||
340 | #define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */ | ||
341 | #define CR_OUTPUT_PIN_SEL 0x27 | ||
342 | #define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */ | ||
343 | /* next three regs valid for both the CIR and CIR_WAKE logical devices */ | ||
344 | #define CR_CIR_BASE_ADDR_HI 0x60 | ||
345 | #define CR_CIR_BASE_ADDR_LO 0x61 | ||
346 | #define CR_CIR_IRQ_RSRC 0x70 | ||
347 | /* next three regs valid only for ACPI logical dev */ | ||
348 | #define CR_ACPI_CIR_WAKE 0xe0 | ||
349 | #define CR_ACPI_IRQ_EVENTS 0xf6 | ||
350 | #define CR_ACPI_IRQ_EVENTS2 0xf7 | ||
351 | |||
352 | /* Logical devices that we need to care about */ | ||
353 | #define LOGICAL_DEV_LPT 0x01 | ||
354 | #define LOGICAL_DEV_CIR 0x06 | ||
355 | #define LOGICAL_DEV_ACPI 0x0a | ||
356 | #define LOGICAL_DEV_CIR_WAKE 0x0e | ||
357 | |||
358 | #define LOGICAL_DEV_DISABLE 0x00 | ||
359 | #define LOGICAL_DEV_ENABLE 0x01 | ||
360 | |||
361 | #define CIR_WAKE_ENABLE_BIT 0x08 | ||
362 | #define CIR_INTR_MOUSE_IRQ_BIT 0x80 | ||
363 | #define PME_INTR_CIR_PASS_BIT 0x08 | ||
364 | |||
365 | #define OUTPUT_PIN_SEL_MASK 0xbc | ||
366 | #define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */ | ||
367 | #define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */ | ||
368 | |||
369 | /* MCE CIR signal length, related on sample period */ | ||
370 | |||
371 | /* MCE CIR controller signal length: about 43ms | ||
372 | * 43ms / 50us (sample period) * 0.85 (inaccuracy) | ||
373 | */ | ||
374 | #define CONTROLLER_BUF_LEN_MIN 830 | ||
375 | |||
376 | /* MCE CIR keyboard signal length: about 26ms | ||
377 | * 26ms / 50us (sample period) * 0.85 (inaccuracy) | ||
378 | */ | ||
379 | #define KEYBOARD_BUF_LEN_MAX 650 | ||
380 | #define KEYBOARD_BUF_LEN_MIN 610 | ||
381 | |||
382 | /* MCE CIR mouse signal length: about 24ms | ||
383 | * 24ms / 50us (sample period) * 0.85 (inaccuracy) | ||
384 | */ | ||
385 | #define MOUSE_BUF_LEN_MIN 565 | ||
386 | |||
387 | #define CIR_SAMPLE_PERIOD 50 | ||
388 | #define CIR_SAMPLE_LOW_INACCURACY 0.85 | ||
389 | |||
390 | /* MAX silence time that driver will sent to lirc */ | ||
391 | #define MAX_SILENCE_TIME 60000 | ||
392 | |||
393 | #if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100 | ||
394 | #define SAMPLE_PERIOD 100 | ||
395 | |||
396 | #elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50 | ||
397 | #define SAMPLE_PERIOD 50 | ||
398 | |||
399 | #elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25 | ||
400 | #define SAMPLE_PERIOD 25 | ||
401 | |||
402 | #else | ||
403 | #define SAMPLE_PERIOD 1 | ||
404 | #endif | ||
405 | |||
406 | /* as VISTA MCE definition, valid carrier value */ | ||
407 | #define MAX_CARRIER 60000 | ||
408 | #define MIN_CARRIER 30000 | ||
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c index 058e29fd478..548381c35bf 100644 --- a/drivers/media/IR/streamzap.c +++ b/drivers/media/IR/streamzap.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/input.h> | 38 | #include <linux/input.h> |
39 | #include <media/ir-core.h> | 39 | #include <media/ir-core.h> |
40 | 40 | ||
41 | #define DRIVER_VERSION "1.60" | 41 | #define DRIVER_VERSION "1.61" |
42 | #define DRIVER_NAME "streamzap" | 42 | #define DRIVER_NAME "streamzap" |
43 | #define DRIVER_DESC "Streamzap Remote Control driver" | 43 | #define DRIVER_DESC "Streamzap Remote Control driver" |
44 | 44 | ||
@@ -61,14 +61,21 @@ static struct usb_device_id streamzap_table[] = { | |||
61 | 61 | ||
62 | MODULE_DEVICE_TABLE(usb, streamzap_table); | 62 | MODULE_DEVICE_TABLE(usb, streamzap_table); |
63 | 63 | ||
64 | #define STREAMZAP_PULSE_MASK 0xf0 | 64 | #define SZ_PULSE_MASK 0xf0 |
65 | #define STREAMZAP_SPACE_MASK 0x0f | 65 | #define SZ_SPACE_MASK 0x0f |
66 | #define STREAMZAP_TIMEOUT 0xff | 66 | #define SZ_TIMEOUT 0xff |
67 | #define STREAMZAP_RESOLUTION 256 | 67 | #define SZ_RESOLUTION 256 |
68 | 68 | ||
69 | /* number of samples buffered */ | 69 | /* number of samples buffered */ |
70 | #define SZ_BUF_LEN 128 | 70 | #define SZ_BUF_LEN 128 |
71 | 71 | ||
72 | /* from ir-rc5-sz-decoder.c */ | ||
73 | #ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE | ||
74 | #define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder") | ||
75 | #else | ||
76 | #define load_rc5_sz_decode() 0 | ||
77 | #endif | ||
78 | |||
72 | enum StreamzapDecoderState { | 79 | enum StreamzapDecoderState { |
73 | PulseSpace, | 80 | PulseSpace, |
74 | FullPulse, | 81 | FullPulse, |
@@ -81,7 +88,6 @@ struct streamzap_ir { | |||
81 | 88 | ||
82 | /* ir-core */ | 89 | /* ir-core */ |
83 | struct ir_dev_props *props; | 90 | struct ir_dev_props *props; |
84 | struct ir_raw_event rawir; | ||
85 | 91 | ||
86 | /* core device info */ | 92 | /* core device info */ |
87 | struct device *dev; | 93 | struct device *dev; |
@@ -98,17 +104,6 @@ struct streamzap_ir { | |||
98 | dma_addr_t dma_in; | 104 | dma_addr_t dma_in; |
99 | unsigned int buf_in_len; | 105 | unsigned int buf_in_len; |
100 | 106 | ||
101 | /* timer used to support delay buffering */ | ||
102 | struct timer_list delay_timer; | ||
103 | bool timer_running; | ||
104 | spinlock_t timer_lock; | ||
105 | struct timer_list flush_timer; | ||
106 | bool flush; | ||
107 | |||
108 | /* delay buffer */ | ||
109 | struct kfifo fifo; | ||
110 | bool fifo_initialized; | ||
111 | |||
112 | /* track what state we're in */ | 107 | /* track what state we're in */ |
113 | enum StreamzapDecoderState decoder_state; | 108 | enum StreamzapDecoderState decoder_state; |
114 | /* tracks whether we are currently receiving some signal */ | 109 | /* tracks whether we are currently receiving some signal */ |
@@ -118,7 +113,7 @@ struct streamzap_ir { | |||
118 | /* start time of signal; necessary for gap tracking */ | 113 | /* start time of signal; necessary for gap tracking */ |
119 | struct timeval signal_last; | 114 | struct timeval signal_last; |
120 | struct timeval signal_start; | 115 | struct timeval signal_start; |
121 | /* bool timeout_enabled; */ | 116 | bool timeout_enabled; |
122 | 117 | ||
123 | char name[128]; | 118 | char name[128]; |
124 | char phys[64]; | 119 | char phys[64]; |
@@ -143,122 +138,16 @@ static struct usb_driver streamzap_driver = { | |||
143 | .id_table = streamzap_table, | 138 | .id_table = streamzap_table, |
144 | }; | 139 | }; |
145 | 140 | ||
146 | static void streamzap_stop_timer(struct streamzap_ir *sz) | 141 | static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) |
147 | { | ||
148 | unsigned long flags; | ||
149 | |||
150 | spin_lock_irqsave(&sz->timer_lock, flags); | ||
151 | if (sz->timer_running) { | ||
152 | sz->timer_running = false; | ||
153 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
154 | del_timer_sync(&sz->delay_timer); | ||
155 | } else { | ||
156 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static void streamzap_flush_timeout(unsigned long arg) | ||
161 | { | ||
162 | struct streamzap_ir *sz = (struct streamzap_ir *)arg; | ||
163 | |||
164 | dev_info(sz->dev, "%s: callback firing\n", __func__); | ||
165 | |||
166 | /* finally start accepting data */ | ||
167 | sz->flush = false; | ||
168 | } | ||
169 | |||
170 | static void streamzap_delay_timeout(unsigned long arg) | ||
171 | { | ||
172 | struct streamzap_ir *sz = (struct streamzap_ir *)arg; | ||
173 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | ||
174 | unsigned long flags; | ||
175 | int len, ret; | ||
176 | static unsigned long delay; | ||
177 | bool wake = false; | ||
178 | |||
179 | /* deliver data every 10 ms */ | ||
180 | delay = msecs_to_jiffies(10); | ||
181 | |||
182 | spin_lock_irqsave(&sz->timer_lock, flags); | ||
183 | |||
184 | if (kfifo_len(&sz->fifo) > 0) { | ||
185 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
186 | if (ret != sizeof(rawir)) | ||
187 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
188 | ir_raw_event_store(sz->idev, &rawir); | ||
189 | wake = true; | ||
190 | } | ||
191 | |||
192 | len = kfifo_len(&sz->fifo); | ||
193 | if (len > 0) { | ||
194 | while ((len < SZ_BUF_LEN / 2) && | ||
195 | (len < SZ_BUF_LEN * sizeof(int))) { | ||
196 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
197 | if (ret != sizeof(rawir)) | ||
198 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
199 | ir_raw_event_store(sz->idev, &rawir); | ||
200 | wake = true; | ||
201 | len = kfifo_len(&sz->fifo); | ||
202 | } | ||
203 | if (sz->timer_running) | ||
204 | mod_timer(&sz->delay_timer, jiffies + delay); | ||
205 | |||
206 | } else { | ||
207 | sz->timer_running = false; | ||
208 | } | ||
209 | |||
210 | if (wake) | ||
211 | ir_raw_event_handle(sz->idev); | ||
212 | |||
213 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
214 | } | ||
215 | |||
216 | static void streamzap_flush_delay_buffer(struct streamzap_ir *sz) | ||
217 | { | 142 | { |
218 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | 143 | ir_raw_event_store(sz->idev, &rawir); |
219 | bool wake = false; | ||
220 | int ret; | ||
221 | |||
222 | while (kfifo_len(&sz->fifo) > 0) { | ||
223 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
224 | if (ret != sizeof(rawir)) | ||
225 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
226 | ir_raw_event_store(sz->idev, &rawir); | ||
227 | wake = true; | ||
228 | } | ||
229 | |||
230 | if (wake) | ||
231 | ir_raw_event_handle(sz->idev); | ||
232 | } | ||
233 | |||
234 | static void sz_push(struct streamzap_ir *sz) | ||
235 | { | ||
236 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | ||
237 | unsigned long flags; | ||
238 | int ret; | ||
239 | |||
240 | spin_lock_irqsave(&sz->timer_lock, flags); | ||
241 | if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) { | ||
242 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
243 | if (ret != sizeof(rawir)) | ||
244 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
245 | ir_raw_event_store(sz->idev, &rawir); | ||
246 | } | ||
247 | |||
248 | kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir)); | ||
249 | |||
250 | if (!sz->timer_running) { | ||
251 | sz->delay_timer.expires = jiffies + (HZ / 10); | ||
252 | add_timer(&sz->delay_timer); | ||
253 | sz->timer_running = true; | ||
254 | } | ||
255 | |||
256 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
257 | } | 144 | } |
258 | 145 | ||
259 | static void sz_push_full_pulse(struct streamzap_ir *sz, | 146 | static void sz_push_full_pulse(struct streamzap_ir *sz, |
260 | unsigned char value) | 147 | unsigned char value) |
261 | { | 148 | { |
149 | DEFINE_IR_RAW_EVENT(rawir); | ||
150 | |||
262 | if (sz->idle) { | 151 | if (sz->idle) { |
263 | long deltv; | 152 | long deltv; |
264 | 153 | ||
@@ -266,57 +155,59 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, | |||
266 | do_gettimeofday(&sz->signal_start); | 155 | do_gettimeofday(&sz->signal_start); |
267 | 156 | ||
268 | deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; | 157 | deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; |
269 | sz->rawir.pulse = false; | 158 | rawir.pulse = false; |
270 | if (deltv > 15) { | 159 | if (deltv > 15) { |
271 | /* really long time */ | 160 | /* really long time */ |
272 | sz->rawir.duration = IR_MAX_DURATION; | 161 | rawir.duration = IR_MAX_DURATION; |
273 | } else { | 162 | } else { |
274 | sz->rawir.duration = (int)(deltv * 1000000 + | 163 | rawir.duration = (int)(deltv * 1000000 + |
275 | sz->signal_start.tv_usec - | 164 | sz->signal_start.tv_usec - |
276 | sz->signal_last.tv_usec); | 165 | sz->signal_last.tv_usec); |
277 | sz->rawir.duration -= sz->sum; | 166 | rawir.duration -= sz->sum; |
278 | sz->rawir.duration *= 1000; | 167 | rawir.duration *= 1000; |
279 | sz->rawir.duration &= IR_MAX_DURATION; | 168 | rawir.duration &= IR_MAX_DURATION; |
280 | } | 169 | } |
281 | dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration); | 170 | dev_dbg(sz->dev, "ls %u\n", rawir.duration); |
282 | sz_push(sz); | 171 | sz_push(sz, rawir); |
283 | 172 | ||
284 | sz->idle = 0; | 173 | sz->idle = false; |
285 | sz->sum = 0; | 174 | sz->sum = 0; |
286 | } | 175 | } |
287 | 176 | ||
288 | sz->rawir.pulse = true; | 177 | rawir.pulse = true; |
289 | sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION; | 178 | rawir.duration = ((int) value) * SZ_RESOLUTION; |
290 | sz->rawir.duration += STREAMZAP_RESOLUTION / 2; | 179 | rawir.duration += SZ_RESOLUTION / 2; |
291 | sz->sum += sz->rawir.duration; | 180 | sz->sum += rawir.duration; |
292 | sz->rawir.duration *= 1000; | 181 | rawir.duration *= 1000; |
293 | sz->rawir.duration &= IR_MAX_DURATION; | 182 | rawir.duration &= IR_MAX_DURATION; |
294 | dev_dbg(sz->dev, "p %u\n", sz->rawir.duration); | 183 | dev_dbg(sz->dev, "p %u\n", rawir.duration); |
295 | sz_push(sz); | 184 | sz_push(sz, rawir); |
296 | } | 185 | } |
297 | 186 | ||
298 | static void sz_push_half_pulse(struct streamzap_ir *sz, | 187 | static void sz_push_half_pulse(struct streamzap_ir *sz, |
299 | unsigned char value) | 188 | unsigned char value) |
300 | { | 189 | { |
301 | sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4); | 190 | sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4); |
302 | } | 191 | } |
303 | 192 | ||
304 | static void sz_push_full_space(struct streamzap_ir *sz, | 193 | static void sz_push_full_space(struct streamzap_ir *sz, |
305 | unsigned char value) | 194 | unsigned char value) |
306 | { | 195 | { |
307 | sz->rawir.pulse = false; | 196 | DEFINE_IR_RAW_EVENT(rawir); |
308 | sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION; | 197 | |
309 | sz->rawir.duration += STREAMZAP_RESOLUTION / 2; | 198 | rawir.pulse = false; |
310 | sz->sum += sz->rawir.duration; | 199 | rawir.duration = ((int) value) * SZ_RESOLUTION; |
311 | sz->rawir.duration *= 1000; | 200 | rawir.duration += SZ_RESOLUTION / 2; |
312 | dev_dbg(sz->dev, "s %u\n", sz->rawir.duration); | 201 | sz->sum += rawir.duration; |
313 | sz_push(sz); | 202 | rawir.duration *= 1000; |
203 | dev_dbg(sz->dev, "s %u\n", rawir.duration); | ||
204 | sz_push(sz, rawir); | ||
314 | } | 205 | } |
315 | 206 | ||
316 | static void sz_push_half_space(struct streamzap_ir *sz, | 207 | static void sz_push_half_space(struct streamzap_ir *sz, |
317 | unsigned long value) | 208 | unsigned long value) |
318 | { | 209 | { |
319 | sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK); | 210 | sz_push_full_space(sz, value & SZ_SPACE_MASK); |
320 | } | 211 | } |
321 | 212 | ||
322 | /** | 213 | /** |
@@ -330,10 +221,8 @@ static void streamzap_callback(struct urb *urb) | |||
330 | struct streamzap_ir *sz; | 221 | struct streamzap_ir *sz; |
331 | unsigned int i; | 222 | unsigned int i; |
332 | int len; | 223 | int len; |
333 | #if 0 | 224 | static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & |
334 | static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) & | ||
335 | IR_MAX_DURATION) | 0x03000000); | 225 | IR_MAX_DURATION) | 0x03000000); |
336 | #endif | ||
337 | 226 | ||
338 | if (!urb) | 227 | if (!urb) |
339 | return; | 228 | return; |
@@ -356,57 +245,53 @@ static void streamzap_callback(struct urb *urb) | |||
356 | } | 245 | } |
357 | 246 | ||
358 | dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); | 247 | dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); |
359 | if (!sz->flush) { | 248 | for (i = 0; i < len; i++) { |
360 | for (i = 0; i < urb->actual_length; i++) { | 249 | dev_dbg(sz->dev, "sz idx %d: %x\n", |
361 | dev_dbg(sz->dev, "%d: %x\n", i, | 250 | i, (unsigned char)sz->buf_in[i]); |
362 | (unsigned char)sz->buf_in[i]); | 251 | switch (sz->decoder_state) { |
363 | switch (sz->decoder_state) { | 252 | case PulseSpace: |
364 | case PulseSpace: | 253 | if ((sz->buf_in[i] & SZ_PULSE_MASK) == |
365 | if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) == | 254 | SZ_PULSE_MASK) { |
366 | STREAMZAP_PULSE_MASK) { | 255 | sz->decoder_state = FullPulse; |
367 | sz->decoder_state = FullPulse; | 256 | continue; |
368 | continue; | 257 | } else if ((sz->buf_in[i] & SZ_SPACE_MASK) |
369 | } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) | 258 | == SZ_SPACE_MASK) { |
370 | == STREAMZAP_SPACE_MASK) { | 259 | sz_push_half_pulse(sz, sz->buf_in[i]); |
371 | sz_push_half_pulse(sz, sz->buf_in[i]); | 260 | sz->decoder_state = FullSpace; |
372 | sz->decoder_state = FullSpace; | 261 | continue; |
373 | continue; | 262 | } else { |
374 | } else { | 263 | sz_push_half_pulse(sz, sz->buf_in[i]); |
375 | sz_push_half_pulse(sz, sz->buf_in[i]); | ||
376 | sz_push_half_space(sz, sz->buf_in[i]); | ||
377 | } | ||
378 | break; | ||
379 | case FullPulse: | ||
380 | sz_push_full_pulse(sz, sz->buf_in[i]); | ||
381 | sz->decoder_state = IgnorePulse; | ||
382 | break; | ||
383 | case FullSpace: | ||
384 | if (sz->buf_in[i] == STREAMZAP_TIMEOUT) { | ||
385 | sz->idle = 1; | ||
386 | streamzap_stop_timer(sz); | ||
387 | #if 0 | ||
388 | if (sz->timeout_enabled) { | ||
389 | sz->rawir.pulse = false; | ||
390 | sz->rawir.duration = timeout; | ||
391 | sz->rawir.duration *= 1000; | ||
392 | sz_push(sz); | ||
393 | } | ||
394 | #endif | ||
395 | streamzap_flush_delay_buffer(sz); | ||
396 | } else | ||
397 | sz_push_full_space(sz, sz->buf_in[i]); | ||
398 | sz->decoder_state = PulseSpace; | ||
399 | break; | ||
400 | case IgnorePulse: | ||
401 | if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) == | ||
402 | STREAMZAP_SPACE_MASK) { | ||
403 | sz->decoder_state = FullSpace; | ||
404 | continue; | ||
405 | } | ||
406 | sz_push_half_space(sz, sz->buf_in[i]); | 264 | sz_push_half_space(sz, sz->buf_in[i]); |
407 | sz->decoder_state = PulseSpace; | ||
408 | break; | ||
409 | } | 265 | } |
266 | break; | ||
267 | case FullPulse: | ||
268 | sz_push_full_pulse(sz, sz->buf_in[i]); | ||
269 | sz->decoder_state = IgnorePulse; | ||
270 | break; | ||
271 | case FullSpace: | ||
272 | if (sz->buf_in[i] == SZ_TIMEOUT) { | ||
273 | DEFINE_IR_RAW_EVENT(rawir); | ||
274 | |||
275 | rawir.pulse = false; | ||
276 | rawir.duration = timeout; | ||
277 | sz->idle = true; | ||
278 | if (sz->timeout_enabled) | ||
279 | sz_push(sz, rawir); | ||
280 | ir_raw_event_handle(sz->idev); | ||
281 | } else { | ||
282 | sz_push_full_space(sz, sz->buf_in[i]); | ||
283 | } | ||
284 | sz->decoder_state = PulseSpace; | ||
285 | break; | ||
286 | case IgnorePulse: | ||
287 | if ((sz->buf_in[i] & SZ_SPACE_MASK) == | ||
288 | SZ_SPACE_MASK) { | ||
289 | sz->decoder_state = FullSpace; | ||
290 | continue; | ||
291 | } | ||
292 | sz_push_half_space(sz, sz->buf_in[i]); | ||
293 | sz->decoder_state = PulseSpace; | ||
294 | break; | ||
410 | } | 295 | } |
411 | } | 296 | } |
412 | 297 | ||
@@ -446,12 +331,11 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) | |||
446 | 331 | ||
447 | props->priv = sz; | 332 | props->priv = sz; |
448 | props->driver_type = RC_DRIVER_IR_RAW; | 333 | props->driver_type = RC_DRIVER_IR_RAW; |
449 | /* FIXME: not sure about supported protocols, check on this */ | 334 | props->allowed_protos = IR_TYPE_ALL; |
450 | props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6; | ||
451 | 335 | ||
452 | sz->props = props; | 336 | sz->props = props; |
453 | 337 | ||
454 | ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME); | 338 | ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); |
455 | if (ret < 0) { | 339 | if (ret < 0) { |
456 | dev_err(dev, "remote input device register failed\n"); | 340 | dev_err(dev, "remote input device register failed\n"); |
457 | goto irdev_failed; | 341 | goto irdev_failed; |
@@ -467,29 +351,6 @@ idev_alloc_failed: | |||
467 | return NULL; | 351 | return NULL; |
468 | } | 352 | } |
469 | 353 | ||
470 | static int streamzap_delay_buf_init(struct streamzap_ir *sz) | ||
471 | { | ||
472 | int ret; | ||
473 | |||
474 | ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN, | ||
475 | GFP_KERNEL); | ||
476 | if (ret == 0) | ||
477 | sz->fifo_initialized = 1; | ||
478 | |||
479 | return ret; | ||
480 | } | ||
481 | |||
482 | static void streamzap_start_flush_timer(struct streamzap_ir *sz) | ||
483 | { | ||
484 | sz->flush_timer.expires = jiffies + HZ; | ||
485 | sz->flush = true; | ||
486 | add_timer(&sz->flush_timer); | ||
487 | |||
488 | sz->urb_in->dev = sz->usbdev; | ||
489 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) | ||
490 | dev_err(sz->dev, "urb submit failed\n"); | ||
491 | } | ||
492 | |||
493 | /** | 354 | /** |
494 | * streamzap_probe | 355 | * streamzap_probe |
495 | * | 356 | * |
@@ -575,35 +436,21 @@ static int __devinit streamzap_probe(struct usb_interface *intf, | |||
575 | snprintf(name + strlen(name), sizeof(name) - strlen(name), | 436 | snprintf(name + strlen(name), sizeof(name) - strlen(name), |
576 | " %s", buf); | 437 | " %s", buf); |
577 | 438 | ||
578 | retval = streamzap_delay_buf_init(sz); | ||
579 | if (retval) { | ||
580 | dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__); | ||
581 | goto free_urb_in; | ||
582 | } | ||
583 | |||
584 | sz->idev = streamzap_init_input_dev(sz); | 439 | sz->idev = streamzap_init_input_dev(sz); |
585 | if (!sz->idev) | 440 | if (!sz->idev) |
586 | goto input_dev_fail; | 441 | goto input_dev_fail; |
587 | 442 | ||
588 | sz->idle = true; | 443 | sz->idle = true; |
589 | sz->decoder_state = PulseSpace; | 444 | sz->decoder_state = PulseSpace; |
445 | /* FIXME: don't yet have a way to set this */ | ||
446 | sz->timeout_enabled = true; | ||
590 | #if 0 | 447 | #if 0 |
591 | /* not yet supported, depends on patches from maxim */ | 448 | /* not yet supported, depends on patches from maxim */ |
592 | /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ | 449 | /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ |
593 | sz->timeout_enabled = false; | 450 | sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000; |
594 | sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000; | 451 | sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000; |
595 | sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000; | ||
596 | #endif | 452 | #endif |
597 | 453 | ||
598 | init_timer(&sz->delay_timer); | ||
599 | sz->delay_timer.function = streamzap_delay_timeout; | ||
600 | sz->delay_timer.data = (unsigned long)sz; | ||
601 | spin_lock_init(&sz->timer_lock); | ||
602 | |||
603 | init_timer(&sz->flush_timer); | ||
604 | sz->flush_timer.function = streamzap_flush_timeout; | ||
605 | sz->flush_timer.data = (unsigned long)sz; | ||
606 | |||
607 | do_gettimeofday(&sz->signal_start); | 454 | do_gettimeofday(&sz->signal_start); |
608 | 455 | ||
609 | /* Complete final initialisations */ | 456 | /* Complete final initialisations */ |
@@ -615,16 +462,18 @@ static int __devinit streamzap_probe(struct usb_interface *intf, | |||
615 | 462 | ||
616 | usb_set_intfdata(intf, sz); | 463 | usb_set_intfdata(intf, sz); |
617 | 464 | ||
618 | streamzap_start_flush_timer(sz); | 465 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) |
466 | dev_err(sz->dev, "urb submit failed\n"); | ||
619 | 467 | ||
620 | dev_info(sz->dev, "Registered %s on usb%d:%d\n", name, | 468 | dev_info(sz->dev, "Registered %s on usb%d:%d\n", name, |
621 | usbdev->bus->busnum, usbdev->devnum); | 469 | usbdev->bus->busnum, usbdev->devnum); |
622 | 470 | ||
471 | /* Load the streamzap not-quite-rc5 decoder too */ | ||
472 | load_rc5_sz_decode(); | ||
473 | |||
623 | return 0; | 474 | return 0; |
624 | 475 | ||
625 | input_dev_fail: | 476 | input_dev_fail: |
626 | kfifo_free(&sz->fifo); | ||
627 | free_urb_in: | ||
628 | usb_free_urb(sz->urb_in); | 477 | usb_free_urb(sz->urb_in); |
629 | free_buf_in: | 478 | free_buf_in: |
630 | usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); | 479 | usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); |
@@ -654,13 +503,6 @@ static void streamzap_disconnect(struct usb_interface *interface) | |||
654 | if (!sz) | 503 | if (!sz) |
655 | return; | 504 | return; |
656 | 505 | ||
657 | if (sz->flush) { | ||
658 | sz->flush = false; | ||
659 | del_timer_sync(&sz->flush_timer); | ||
660 | } | ||
661 | |||
662 | streamzap_stop_timer(sz); | ||
663 | |||
664 | sz->usbdev = NULL; | 506 | sz->usbdev = NULL; |
665 | ir_input_unregister(sz->idev); | 507 | ir_input_unregister(sz->idev); |
666 | usb_kill_urb(sz->urb_in); | 508 | usb_kill_urb(sz->urb_in); |
@@ -674,13 +516,6 @@ static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) | |||
674 | { | 516 | { |
675 | struct streamzap_ir *sz = usb_get_intfdata(intf); | 517 | struct streamzap_ir *sz = usb_get_intfdata(intf); |
676 | 518 | ||
677 | if (sz->flush) { | ||
678 | sz->flush = false; | ||
679 | del_timer_sync(&sz->flush_timer); | ||
680 | } | ||
681 | |||
682 | streamzap_stop_timer(sz); | ||
683 | |||
684 | usb_kill_urb(sz->urb_in); | 519 | usb_kill_urb(sz->urb_in); |
685 | 520 | ||
686 | return 0; | 521 | return 0; |
@@ -690,13 +525,6 @@ static int streamzap_resume(struct usb_interface *intf) | |||
690 | { | 525 | { |
691 | struct streamzap_ir *sz = usb_get_intfdata(intf); | 526 | struct streamzap_ir *sz = usb_get_intfdata(intf); |
692 | 527 | ||
693 | if (sz->fifo_initialized) | ||
694 | kfifo_reset(&sz->fifo); | ||
695 | |||
696 | sz->flush_timer.expires = jiffies + HZ; | ||
697 | sz->flush = true; | ||
698 | add_timer(&sz->flush_timer); | ||
699 | |||
700 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { | 528 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { |
701 | dev_err(sz->dev, "Error sumbiting urb\n"); | 529 | dev_err(sz->dev, "Error sumbiting urb\n"); |
702 | return -EIO; | 530 | return -EIO; |
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 4da2a54cb8b..e3fedc60fe7 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -56,7 +56,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q, | |||
56 | 56 | ||
57 | BUG_ON(in_interrupt()); | 57 | BUG_ON(in_interrupt()); |
58 | 58 | ||
59 | videobuf_waiton(&buf->vb,0,0); | 59 | videobuf_waiton(q, &buf->vb, 0, 0); |
60 | videobuf_dma_unmap(q->dev, dma); | 60 | videobuf_dma_unmap(q->dev, dma); |
61 | videobuf_dma_free(dma); | 61 | videobuf_dma_free(dma); |
62 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 62 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 48cb154c7a4..3d88542612e 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c | |||
@@ -414,7 +414,6 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c | |||
414 | i2c_adapter->dev.parent = &dev->pci->dev; | 414 | i2c_adapter->dev.parent = &dev->pci->dev; |
415 | i2c_adapter->algo = &saa7146_algo; | 415 | i2c_adapter->algo = &saa7146_algo; |
416 | i2c_adapter->algo_data = NULL; | 416 | i2c_adapter->algo_data = NULL; |
417 | i2c_adapter->id = I2C_HW_SAA7146; | ||
418 | i2c_adapter->timeout = SAA7146_I2C_TIMEOUT; | 417 | i2c_adapter->timeout = SAA7146_I2C_TIMEOUT; |
419 | i2c_adapter->retries = SAA7146_I2C_RETRIES; | 418 | i2c_adapter->retries = SAA7146_I2C_RETRIES; |
420 | } | 419 | } |
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index 8224c301d05..2d4533ab22b 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c | |||
@@ -412,7 +412,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) | |||
412 | V4L2_BUF_TYPE_VBI_CAPTURE, | 412 | V4L2_BUF_TYPE_VBI_CAPTURE, |
413 | V4L2_FIELD_SEQ_TB, // FIXME: does this really work? | 413 | V4L2_FIELD_SEQ_TB, // FIXME: does this really work? |
414 | sizeof(struct saa7146_buf), | 414 | sizeof(struct saa7146_buf), |
415 | file); | 415 | file, NULL); |
416 | 416 | ||
417 | init_timer(&fh->vbi_read_timeout); | 417 | init_timer(&fh->vbi_read_timeout); |
418 | fh->vbi_read_timeout.function = vbi_read_timeout; | 418 | fh->vbi_read_timeout.function = vbi_read_timeout; |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index a212a91a30f..741c5732b43 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -1386,7 +1386,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file) | |||
1386 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1386 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1387 | V4L2_FIELD_INTERLACED, | 1387 | V4L2_FIELD_INTERLACED, |
1388 | sizeof(struct saa7146_buf), | 1388 | sizeof(struct saa7146_buf), |
1389 | file); | 1389 | file, NULL); |
1390 | 1390 | ||
1391 | return 0; | 1391 | return 0; |
1392 | } | 1392 | } |
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index b3ed5daaacf..2385e6cca63 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig | |||
@@ -179,4 +179,11 @@ config MEDIA_TUNER_MAX2165 | |||
179 | help | 179 | help |
180 | A driver for the silicon tuner MAX2165 from Maxim. | 180 | A driver for the silicon tuner MAX2165 from Maxim. |
181 | 181 | ||
182 | config MEDIA_TUNER_TDA18218 | ||
183 | tristate "NXP TDA18218 silicon tuner" | ||
184 | depends on VIDEO_MEDIA && I2C | ||
185 | default m if MEDIA_TUNER_CUSTOMISE | ||
186 | help | ||
187 | NXP TDA18218 silicon tuner driver. | ||
188 | |||
182 | endif # MEDIA_TUNER_CUSTOMISE | 189 | endif # MEDIA_TUNER_CUSTOMISE |
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile index a5438523f30..96da03d349c 100644 --- a/drivers/media/common/tuners/Makefile +++ b/drivers/media/common/tuners/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o | |||
24 | obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o | 24 | obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o |
25 | obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o | 25 | obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o |
26 | obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o | 26 | obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o |
27 | obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o | ||
27 | 28 | ||
28 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 29 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
29 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 30 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c new file mode 100644 index 00000000000..8da1fdeddaa --- /dev/null +++ b/drivers/media/common/tuners/tda18218.c | |||
@@ -0,0 +1,334 @@ | |||
1 | /* | ||
2 | * NXP TDA18218HN silicon tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include "tda18218.h" | ||
22 | #include "tda18218_priv.h" | ||
23 | |||
24 | static int debug; | ||
25 | module_param(debug, int, 0644); | ||
26 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | ||
27 | |||
28 | /* write multiple registers */ | ||
29 | static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) | ||
30 | { | ||
31 | int ret; | ||
32 | u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max; | ||
33 | struct i2c_msg msg[1] = { | ||
34 | { | ||
35 | .addr = priv->cfg->i2c_address, | ||
36 | .flags = 0, | ||
37 | .buf = buf, | ||
38 | } | ||
39 | }; | ||
40 | |||
41 | msg_len_max = priv->cfg->i2c_wr_max - 1; | ||
42 | quotient = len / msg_len_max; | ||
43 | remainder = len % msg_len_max; | ||
44 | msg_len = msg_len_max; | ||
45 | for (i = 0; (i <= quotient && remainder); i++) { | ||
46 | if (i == quotient) /* set len of the last msg */ | ||
47 | msg_len = remainder; | ||
48 | |||
49 | msg[0].len = msg_len + 1; | ||
50 | buf[0] = reg + i * msg_len_max; | ||
51 | memcpy(&buf[1], &val[i * msg_len_max], msg_len); | ||
52 | |||
53 | ret = i2c_transfer(priv->i2c, msg, 1); | ||
54 | if (ret != 1) | ||
55 | break; | ||
56 | } | ||
57 | |||
58 | if (ret == 1) { | ||
59 | ret = 0; | ||
60 | } else { | ||
61 | warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len); | ||
62 | ret = -EREMOTEIO; | ||
63 | } | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | /* read multiple registers */ | ||
69 | static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len) | ||
70 | { | ||
71 | int ret; | ||
72 | u8 buf[reg+len]; /* we must start read always from reg 0x00 */ | ||
73 | struct i2c_msg msg[2] = { | ||
74 | { | ||
75 | .addr = priv->cfg->i2c_address, | ||
76 | .flags = 0, | ||
77 | .len = 1, | ||
78 | .buf = "\x00", | ||
79 | }, { | ||
80 | .addr = priv->cfg->i2c_address, | ||
81 | .flags = I2C_M_RD, | ||
82 | .len = sizeof(buf), | ||
83 | .buf = buf, | ||
84 | } | ||
85 | }; | ||
86 | |||
87 | ret = i2c_transfer(priv->i2c, msg, 2); | ||
88 | if (ret == 2) { | ||
89 | memcpy(val, &buf[reg], len); | ||
90 | ret = 0; | ||
91 | } else { | ||
92 | warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len); | ||
93 | ret = -EREMOTEIO; | ||
94 | } | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | /* write single register */ | ||
100 | static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val) | ||
101 | { | ||
102 | return tda18218_wr_regs(priv, reg, &val, 1); | ||
103 | } | ||
104 | |||
105 | /* read single register */ | ||
106 | |||
107 | static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val) | ||
108 | { | ||
109 | return tda18218_rd_regs(priv, reg, val, 1); | ||
110 | } | ||
111 | |||
112 | static int tda18218_set_params(struct dvb_frontend *fe, | ||
113 | struct dvb_frontend_parameters *params) | ||
114 | { | ||
115 | struct tda18218_priv *priv = fe->tuner_priv; | ||
116 | int ret; | ||
117 | u8 buf[3], i, BP_Filter, LP_Fc; | ||
118 | u32 LO_Frac; | ||
119 | /* TODO: find out correct AGC algorithm */ | ||
120 | u8 agc[][2] = { | ||
121 | { R20_AGC11, 0x60 }, | ||
122 | { R23_AGC21, 0x02 }, | ||
123 | { R20_AGC11, 0xa0 }, | ||
124 | { R23_AGC21, 0x09 }, | ||
125 | { R20_AGC11, 0xe0 }, | ||
126 | { R23_AGC21, 0x0c }, | ||
127 | { R20_AGC11, 0x40 }, | ||
128 | { R23_AGC21, 0x01 }, | ||
129 | { R20_AGC11, 0x80 }, | ||
130 | { R23_AGC21, 0x08 }, | ||
131 | { R20_AGC11, 0xc0 }, | ||
132 | { R23_AGC21, 0x0b }, | ||
133 | { R24_AGC22, 0x1c }, | ||
134 | { R24_AGC22, 0x0c }, | ||
135 | }; | ||
136 | |||
137 | if (fe->ops.i2c_gate_ctrl) | ||
138 | fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ | ||
139 | |||
140 | /* low-pass filter cut-off frequency */ | ||
141 | switch (params->u.ofdm.bandwidth) { | ||
142 | case BANDWIDTH_6_MHZ: | ||
143 | LP_Fc = 0; | ||
144 | LO_Frac = params->frequency + 4000000; | ||
145 | break; | ||
146 | case BANDWIDTH_7_MHZ: | ||
147 | LP_Fc = 1; | ||
148 | LO_Frac = params->frequency + 3500000; | ||
149 | break; | ||
150 | case BANDWIDTH_8_MHZ: | ||
151 | default: | ||
152 | LP_Fc = 2; | ||
153 | LO_Frac = params->frequency + 4000000; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | /* band-pass filter */ | ||
158 | if (LO_Frac < 188000000) | ||
159 | BP_Filter = 3; | ||
160 | else if (LO_Frac < 253000000) | ||
161 | BP_Filter = 4; | ||
162 | else if (LO_Frac < 343000000) | ||
163 | BP_Filter = 5; | ||
164 | else | ||
165 | BP_Filter = 6; | ||
166 | |||
167 | buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */ | ||
168 | buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */ | ||
169 | buf[2] = priv->regs[R1C_AGC2B]; | ||
170 | ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3); | ||
171 | if (ret) | ||
172 | goto error; | ||
173 | |||
174 | buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */ | ||
175 | buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */ | ||
176 | buf[2] = (LO_Frac / 1000) << 4 | | ||
177 | (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */ | ||
178 | ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3); | ||
179 | if (ret) | ||
180 | goto error; | ||
181 | |||
182 | buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */ | ||
183 | ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1); | ||
184 | if (ret) | ||
185 | goto error; | ||
186 | |||
187 | buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */ | ||
188 | ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1); | ||
189 | if (ret) | ||
190 | goto error; | ||
191 | |||
192 | /* trigger AGC */ | ||
193 | for (i = 0; i < ARRAY_SIZE(agc); i++) { | ||
194 | ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]); | ||
195 | if (ret) | ||
196 | goto error; | ||
197 | } | ||
198 | |||
199 | error: | ||
200 | if (fe->ops.i2c_gate_ctrl) | ||
201 | fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ | ||
202 | |||
203 | if (ret) | ||
204 | dbg("%s: failed ret:%d", __func__, ret); | ||
205 | |||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static int tda18218_sleep(struct dvb_frontend *fe) | ||
210 | { | ||
211 | struct tda18218_priv *priv = fe->tuner_priv; | ||
212 | int ret; | ||
213 | |||
214 | if (fe->ops.i2c_gate_ctrl) | ||
215 | fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ | ||
216 | |||
217 | /* standby */ | ||
218 | ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0)); | ||
219 | |||
220 | if (fe->ops.i2c_gate_ctrl) | ||
221 | fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ | ||
222 | |||
223 | if (ret) | ||
224 | dbg("%s: failed ret:%d", __func__, ret); | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static int tda18218_init(struct dvb_frontend *fe) | ||
230 | { | ||
231 | struct tda18218_priv *priv = fe->tuner_priv; | ||
232 | int ret; | ||
233 | |||
234 | /* TODO: calibrations */ | ||
235 | |||
236 | if (fe->ops.i2c_gate_ctrl) | ||
237 | fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ | ||
238 | |||
239 | ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS); | ||
240 | |||
241 | if (fe->ops.i2c_gate_ctrl) | ||
242 | fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ | ||
243 | |||
244 | if (ret) | ||
245 | dbg("%s: failed ret:%d", __func__, ret); | ||
246 | |||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | static int tda18218_release(struct dvb_frontend *fe) | ||
251 | { | ||
252 | kfree(fe->tuner_priv); | ||
253 | fe->tuner_priv = NULL; | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static const struct dvb_tuner_ops tda18218_tuner_ops = { | ||
258 | .info = { | ||
259 | .name = "NXP TDA18218", | ||
260 | |||
261 | .frequency_min = 174000000, | ||
262 | .frequency_max = 864000000, | ||
263 | .frequency_step = 1000, | ||
264 | }, | ||
265 | |||
266 | .release = tda18218_release, | ||
267 | .init = tda18218_init, | ||
268 | .sleep = tda18218_sleep, | ||
269 | |||
270 | .set_params = tda18218_set_params, | ||
271 | }; | ||
272 | |||
273 | struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, | ||
274 | struct i2c_adapter *i2c, struct tda18218_config *cfg) | ||
275 | { | ||
276 | struct tda18218_priv *priv = NULL; | ||
277 | u8 val; | ||
278 | int ret; | ||
279 | /* chip default registers values */ | ||
280 | static u8 def_regs[] = { | ||
281 | 0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40, | ||
282 | 0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00, | ||
283 | 0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01, | ||
284 | 0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9, | ||
285 | 0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00, | ||
286 | 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6 | ||
287 | }; | ||
288 | |||
289 | priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL); | ||
290 | if (priv == NULL) | ||
291 | return NULL; | ||
292 | |||
293 | priv->cfg = cfg; | ||
294 | priv->i2c = i2c; | ||
295 | fe->tuner_priv = priv; | ||
296 | |||
297 | if (fe->ops.i2c_gate_ctrl) | ||
298 | fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ | ||
299 | |||
300 | /* check if the tuner is there */ | ||
301 | ret = tda18218_rd_reg(priv, R00_ID, &val); | ||
302 | dbg("%s: ret:%d chip ID:%02x", __func__, ret, val); | ||
303 | if (ret || val != def_regs[R00_ID]) { | ||
304 | kfree(priv); | ||
305 | return NULL; | ||
306 | } | ||
307 | |||
308 | info("NXP TDA18218HN successfully identified."); | ||
309 | |||
310 | memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops, | ||
311 | sizeof(struct dvb_tuner_ops)); | ||
312 | memcpy(priv->regs, def_regs, sizeof(def_regs)); | ||
313 | |||
314 | /* loop-through enabled chip default register values */ | ||
315 | if (priv->cfg->loop_through) { | ||
316 | priv->regs[R17_PD1] = 0xb0; | ||
317 | priv->regs[R18_PD2] = 0x59; | ||
318 | } | ||
319 | |||
320 | /* standby */ | ||
321 | ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0)); | ||
322 | if (ret) | ||
323 | dbg("%s: failed ret:%d", __func__, ret); | ||
324 | |||
325 | if (fe->ops.i2c_gate_ctrl) | ||
326 | fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ | ||
327 | |||
328 | return fe; | ||
329 | } | ||
330 | EXPORT_SYMBOL(tda18218_attach); | ||
331 | |||
332 | MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver"); | ||
333 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
334 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/common/tuners/tda18218.h b/drivers/media/common/tuners/tda18218.h new file mode 100644 index 00000000000..b4180d18002 --- /dev/null +++ b/drivers/media/common/tuners/tda18218.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * NXP TDA18218HN silicon tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef TDA18218_H | ||
22 | #define TDA18218_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | |||
26 | struct tda18218_config { | ||
27 | u8 i2c_address; | ||
28 | u8 i2c_wr_max; | ||
29 | u8 loop_through:1; | ||
30 | }; | ||
31 | |||
32 | #if defined(CONFIG_MEDIA_TUNER_TDA18218) || \ | ||
33 | (defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE)) | ||
34 | extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, | ||
35 | struct i2c_adapter *i2c, struct tda18218_config *cfg); | ||
36 | #else | ||
37 | static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, | ||
38 | struct i2c_adapter *i2c, struct tda18218_config *cfg) | ||
39 | { | ||
40 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
41 | return NULL; | ||
42 | } | ||
43 | #endif | ||
44 | |||
45 | #endif | ||
diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/common/tuners/tda18218_priv.h new file mode 100644 index 00000000000..904e5365c78 --- /dev/null +++ b/drivers/media/common/tuners/tda18218_priv.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * NXP TDA18218HN silicon tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef TDA18218_PRIV_H | ||
22 | #define TDA18218_PRIV_H | ||
23 | |||
24 | #define LOG_PREFIX "tda18218" | ||
25 | |||
26 | #undef dbg | ||
27 | #define dbg(f, arg...) \ | ||
28 | if (debug) \ | ||
29 | printk(KERN_DEBUG LOG_PREFIX": " f "\n" , ## arg) | ||
30 | #undef err | ||
31 | #define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) | ||
32 | #undef info | ||
33 | #define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) | ||
34 | #undef warn | ||
35 | #define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) | ||
36 | |||
37 | #define R00_ID 0x00 /* ID byte */ | ||
38 | #define R01_R1 0x01 /* Read byte 1 */ | ||
39 | #define R02_R2 0x02 /* Read byte 2 */ | ||
40 | #define R03_R3 0x03 /* Read byte 3 */ | ||
41 | #define R04_R4 0x04 /* Read byte 4 */ | ||
42 | #define R05_R5 0x05 /* Read byte 5 */ | ||
43 | #define R06_R6 0x06 /* Read byte 6 */ | ||
44 | #define R07_MD1 0x07 /* Main divider byte 1 */ | ||
45 | #define R08_PSM1 0x08 /* PSM byte 1 */ | ||
46 | #define R09_MD2 0x09 /* Main divider byte 2 */ | ||
47 | #define R0A_MD3 0x0a /* Main divider byte 1 */ | ||
48 | #define R0B_MD4 0x0b /* Main divider byte 4 */ | ||
49 | #define R0C_MD5 0x0c /* Main divider byte 5 */ | ||
50 | #define R0D_MD6 0x0d /* Main divider byte 6 */ | ||
51 | #define R0E_MD7 0x0e /* Main divider byte 7 */ | ||
52 | #define R0F_MD8 0x0f /* Main divider byte 8 */ | ||
53 | #define R10_CD1 0x10 /* Call divider byte 1 */ | ||
54 | #define R11_CD2 0x11 /* Call divider byte 2 */ | ||
55 | #define R12_CD3 0x12 /* Call divider byte 3 */ | ||
56 | #define R13_CD4 0x13 /* Call divider byte 4 */ | ||
57 | #define R14_CD5 0x14 /* Call divider byte 5 */ | ||
58 | #define R15_CD6 0x15 /* Call divider byte 6 */ | ||
59 | #define R16_CD7 0x16 /* Call divider byte 7 */ | ||
60 | #define R17_PD1 0x17 /* Power-down byte 1 */ | ||
61 | #define R18_PD2 0x18 /* Power-down byte 2 */ | ||
62 | #define R19_XTOUT 0x19 /* XTOUT byte */ | ||
63 | #define R1A_IF1 0x1a /* IF byte 1 */ | ||
64 | #define R1B_IF2 0x1b /* IF byte 2 */ | ||
65 | #define R1C_AGC2B 0x1c /* AGC2b byte */ | ||
66 | #define R1D_PSM2 0x1d /* PSM byte 2 */ | ||
67 | #define R1E_PSM3 0x1e /* PSM byte 3 */ | ||
68 | #define R1F_PSM4 0x1f /* PSM byte 4 */ | ||
69 | #define R20_AGC11 0x20 /* AGC1 byte 1 */ | ||
70 | #define R21_AGC12 0x21 /* AGC1 byte 2 */ | ||
71 | #define R22_AGC13 0x22 /* AGC1 byte 3 */ | ||
72 | #define R23_AGC21 0x23 /* AGC2 byte 1 */ | ||
73 | #define R24_AGC22 0x24 /* AGC2 byte 2 */ | ||
74 | #define R25_AAGC 0x25 /* Analog AGC byte */ | ||
75 | #define R26_RC 0x26 /* RC byte */ | ||
76 | #define R27_RSSI 0x27 /* RSSI byte */ | ||
77 | #define R28_IRCAL1 0x28 /* IR CAL byte 1 */ | ||
78 | #define R29_IRCAL2 0x29 /* IR CAL byte 2 */ | ||
79 | #define R2A_IRCAL3 0x2a /* IR CAL byte 3 */ | ||
80 | #define R2B_IRCAL4 0x2b /* IR CAL byte 4 */ | ||
81 | #define R2C_RFCAL1 0x2c /* RF CAL byte 1 */ | ||
82 | #define R2D_RFCAL2 0x2d /* RF CAL byte 2 */ | ||
83 | #define R2E_RFCAL3 0x2e /* RF CAL byte 3 */ | ||
84 | #define R2F_RFCAL4 0x2f /* RF CAL byte 4 */ | ||
85 | #define R30_RFCAL5 0x30 /* RF CAL byte 5 */ | ||
86 | #define R31_RFCAL6 0x31 /* RF CAL byte 6 */ | ||
87 | #define R32_RFCAL7 0x32 /* RF CAL byte 7 */ | ||
88 | #define R33_RFCAL8 0x33 /* RF CAL byte 8 */ | ||
89 | #define R34_RFCAL9 0x34 /* RF CAL byte 9 */ | ||
90 | #define R35_RFCAL10 0x35 /* RF CAL byte 10 */ | ||
91 | #define R36_RFCALRAM1 0x36 /* RF CAL RAM byte 1 */ | ||
92 | #define R37_RFCALRAM2 0x37 /* RF CAL RAM byte 2 */ | ||
93 | #define R38_MARGIN 0x38 /* Margin byte */ | ||
94 | #define R39_FMAX1 0x39 /* Fmax byte 1 */ | ||
95 | #define R3A_FMAX2 0x3a /* Fmax byte 2 */ | ||
96 | |||
97 | #define TDA18218_NUM_REGS 59 | ||
98 | |||
99 | struct tda18218_priv { | ||
100 | struct tda18218_config *cfg; | ||
101 | struct i2c_adapter *i2c; | ||
102 | |||
103 | u8 regs[TDA18218_NUM_REGS]; | ||
104 | }; | ||
105 | |||
106 | #endif | ||
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index e1f678281a5..5466d47db89 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c | |||
@@ -193,25 +193,51 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) | |||
193 | unsigned char *regs = priv->tda18271_regs; | 193 | unsigned char *regs = priv->tda18271_regs; |
194 | unsigned char buf[TDA18271_NUM_REGS + 1]; | 194 | unsigned char buf[TDA18271_NUM_REGS + 1]; |
195 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, | 195 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, |
196 | .buf = buf, .len = len + 1 }; | 196 | .buf = buf }; |
197 | int i, ret; | 197 | int i, ret = 1, max; |
198 | 198 | ||
199 | BUG_ON((len == 0) || (idx + len > sizeof(buf))); | 199 | BUG_ON((len == 0) || (idx + len > sizeof(buf))); |
200 | 200 | ||
201 | buf[0] = idx; | 201 | |
202 | for (i = 1; i <= len; i++) | 202 | switch (priv->small_i2c) { |
203 | buf[i] = regs[idx - 1 + i]; | 203 | case TDA18271_03_BYTE_CHUNK_INIT: |
204 | max = 3; | ||
205 | break; | ||
206 | case TDA18271_08_BYTE_CHUNK_INIT: | ||
207 | max = 8; | ||
208 | break; | ||
209 | case TDA18271_16_BYTE_CHUNK_INIT: | ||
210 | max = 16; | ||
211 | break; | ||
212 | case TDA18271_39_BYTE_CHUNK_INIT: | ||
213 | default: | ||
214 | max = 39; | ||
215 | } | ||
204 | 216 | ||
205 | tda18271_i2c_gate_ctrl(fe, 1); | 217 | tda18271_i2c_gate_ctrl(fe, 1); |
218 | while (len) { | ||
219 | if (max > len) | ||
220 | max = len; | ||
221 | |||
222 | buf[0] = idx; | ||
223 | for (i = 1; i <= max; i++) | ||
224 | buf[i] = regs[idx - 1 + i]; | ||
206 | 225 | ||
207 | /* write registers */ | 226 | msg.len = max + 1; |
208 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
209 | 227 | ||
228 | /* write registers */ | ||
229 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
230 | if (ret != 1) | ||
231 | break; | ||
232 | |||
233 | idx += max; | ||
234 | len -= max; | ||
235 | } | ||
210 | tda18271_i2c_gate_ctrl(fe, 0); | 236 | tda18271_i2c_gate_ctrl(fe, 0); |
211 | 237 | ||
212 | if (ret != 1) | 238 | if (ret != 1) |
213 | tda_err("ERROR: idx = 0x%x, len = %d, " | 239 | tda_err("ERROR: idx = 0x%x, len = %d, " |
214 | "i2c_transfer returned: %d\n", idx, len, ret); | 240 | "i2c_transfer returned: %d\n", idx, max, ret); |
215 | 241 | ||
216 | return (ret == 1 ? 0 : ret); | 242 | return (ret == 1 ? 0 : ret); |
217 | } | 243 | } |
@@ -326,24 +352,7 @@ int tda18271_init_regs(struct dvb_frontend *fe) | |||
326 | regs[R_EB22] = 0x48; | 352 | regs[R_EB22] = 0x48; |
327 | regs[R_EB23] = 0xb0; | 353 | regs[R_EB23] = 0xb0; |
328 | 354 | ||
329 | switch (priv->small_i2c) { | 355 | tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); |
330 | case TDA18271_08_BYTE_CHUNK_INIT: | ||
331 | tda18271_write_regs(fe, 0x00, 0x08); | ||
332 | tda18271_write_regs(fe, 0x08, 0x08); | ||
333 | tda18271_write_regs(fe, 0x10, 0x08); | ||
334 | tda18271_write_regs(fe, 0x18, 0x08); | ||
335 | tda18271_write_regs(fe, 0x20, 0x07); | ||
336 | break; | ||
337 | case TDA18271_16_BYTE_CHUNK_INIT: | ||
338 | tda18271_write_regs(fe, 0x00, 0x10); | ||
339 | tda18271_write_regs(fe, 0x10, 0x10); | ||
340 | tda18271_write_regs(fe, 0x20, 0x07); | ||
341 | break; | ||
342 | case TDA18271_39_BYTE_CHUNK_INIT: | ||
343 | default: | ||
344 | tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); | ||
345 | break; | ||
346 | } | ||
347 | 356 | ||
348 | /* setup agc1 gain */ | 357 | /* setup agc1 gain */ |
349 | regs[R_EB17] = 0x00; | 358 | regs[R_EB17] = 0x00; |
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 7955e49a344..9ad4454a148 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c | |||
@@ -1156,7 +1156,6 @@ static int tda18271_get_id(struct dvb_frontend *fe) | |||
1156 | struct tda18271_priv *priv = fe->tuner_priv; | 1156 | struct tda18271_priv *priv = fe->tuner_priv; |
1157 | unsigned char *regs = priv->tda18271_regs; | 1157 | unsigned char *regs = priv->tda18271_regs; |
1158 | char *name; | 1158 | char *name; |
1159 | int ret = 0; | ||
1160 | 1159 | ||
1161 | mutex_lock(&priv->lock); | 1160 | mutex_lock(&priv->lock); |
1162 | tda18271_read_regs(fe); | 1161 | tda18271_read_regs(fe); |
@@ -1172,17 +1171,16 @@ static int tda18271_get_id(struct dvb_frontend *fe) | |||
1172 | priv->id = TDA18271HDC2; | 1171 | priv->id = TDA18271HDC2; |
1173 | break; | 1172 | break; |
1174 | default: | 1173 | default: |
1175 | name = "Unknown device"; | 1174 | tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n", |
1176 | ret = -EINVAL; | 1175 | regs[R_ID], i2c_adapter_id(priv->i2c_props.adap), |
1177 | break; | 1176 | priv->i2c_props.addr); |
1177 | return -EINVAL; | ||
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | tda_info("%s detected @ %d-%04x%s\n", name, | 1180 | tda_info("%s detected @ %d-%04x\n", name, |
1181 | i2c_adapter_id(priv->i2c_props.adap), | 1181 | i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr); |
1182 | priv->i2c_props.addr, | ||
1183 | (0 == ret) ? "" : ", device not supported."); | ||
1184 | 1182 | ||
1185 | return ret; | 1183 | return 0; |
1186 | } | 1184 | } |
1187 | 1185 | ||
1188 | static int tda18271_setup_configuration(struct dvb_frontend *fe, | 1186 | static int tda18271_setup_configuration(struct dvb_frontend *fe, |
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h index d7fcc36dc6e..3abb221f3d0 100644 --- a/drivers/media/common/tuners/tda18271.h +++ b/drivers/media/common/tuners/tda18271.h | |||
@@ -80,8 +80,9 @@ enum tda18271_output_options { | |||
80 | 80 | ||
81 | enum tda18271_small_i2c { | 81 | enum tda18271_small_i2c { |
82 | TDA18271_39_BYTE_CHUNK_INIT = 0, | 82 | TDA18271_39_BYTE_CHUNK_INIT = 0, |
83 | TDA18271_16_BYTE_CHUNK_INIT = 1, | 83 | TDA18271_16_BYTE_CHUNK_INIT = 16, |
84 | TDA18271_08_BYTE_CHUNK_INIT = 2, | 84 | TDA18271_08_BYTE_CHUNK_INIT = 8, |
85 | TDA18271_03_BYTE_CHUNK_INIT = 3, | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | struct tda18271_config { | 88 | struct tda18271_config { |
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index d2b2c12a556..76ac5cd84af 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -1042,7 +1042,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { | |||
1042 | 1042 | ||
1043 | struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | 1043 | struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, |
1044 | struct i2c_adapter *i2c, | 1044 | struct i2c_adapter *i2c, |
1045 | struct xc5000_config *cfg) | 1045 | const struct xc5000_config *cfg) |
1046 | { | 1046 | { |
1047 | struct xc5000_priv *priv = NULL; | 1047 | struct xc5000_priv *priv = NULL; |
1048 | int instance; | 1048 | int instance; |
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index e6d7236c9ea..3756e73649b 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h | |||
@@ -53,11 +53,11 @@ struct xc5000_config { | |||
53 | (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) | 53 | (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) |
54 | extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | 54 | extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, |
55 | struct i2c_adapter *i2c, | 55 | struct i2c_adapter *i2c, |
56 | struct xc5000_config *cfg); | 56 | const struct xc5000_config *cfg); |
57 | #else | 57 | #else |
58 | static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | 58 | static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, |
59 | struct i2c_adapter *i2c, | 59 | struct i2c_adapter *i2c, |
60 | struct xc5000_config *cfg) | 60 | const struct xc5000_config *cfg) |
61 | { | 61 | { |
62 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 62 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
63 | return NULL; | 63 | return NULL; |
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index fd1df235276..965d5eb3375 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c | |||
@@ -245,9 +245,6 @@ int flexcop_i2c_init(struct flexcop_device *fc) | |||
245 | i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); | 245 | i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); |
246 | i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]); | 246 | i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]); |
247 | 247 | ||
248 | fc->fc_i2c_adap[0].i2c_adap.class = | ||
249 | fc->fc_i2c_adap[1].i2c_adap.class = | ||
250 | fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
251 | fc->fc_i2c_adap[0].i2c_adap.algo = | 248 | fc->fc_i2c_adap[0].i2c_adap.algo = |
252 | fc->fc_i2c_adap[1].i2c_adap.algo = | 249 | fc->fc_i2c_adap[1].i2c_adap.algo = |
253 | fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo; | 250 | fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo; |
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index bca07c0bcd0..5d404f1bf03 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -862,7 +862,6 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, | |||
862 | i2c_set_adapdata(&dev->i2c_adap, dev); | 862 | i2c_set_adapdata(&dev->i2c_adap, dev); |
863 | strcpy(dev->i2c_adap.name, DRIVER_NAME); | 863 | strcpy(dev->i2c_adap.name, DRIVER_NAME); |
864 | dev->i2c_adap.owner = THIS_MODULE; | 864 | dev->i2c_adap.owner = THIS_MODULE; |
865 | dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
866 | dev->i2c_adap.dev.parent = &pdev->dev; | 865 | dev->i2c_adap.dev.parent = &pdev->dev; |
867 | dev->i2c_adap.algo = &dm1105_algo; | 866 | dev->i2c_adap.algo = &dm1105_algo; |
868 | dev->i2c_adap.algo_data = dev; | 867 | dev->i2c_adap.algo_data = dev; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 970c9b8882d..1589d5a5cb4 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -702,7 +702,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) | |||
702 | 702 | ||
703 | kthread_stop(fepriv->thread); | 703 | kthread_stop(fepriv->thread); |
704 | 704 | ||
705 | init_MUTEX (&fepriv->sem); | 705 | sema_init(&fepriv->sem, 1); |
706 | fepriv->state = FESTATE_IDLE; | 706 | fepriv->state = FESTATE_IDLE; |
707 | 707 | ||
708 | /* paranoia check in case a signal arrived */ | 708 | /* paranoia check in case a signal arrived */ |
@@ -2062,7 +2062,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
2062 | } | 2062 | } |
2063 | fepriv = fe->frontend_priv; | 2063 | fepriv = fe->frontend_priv; |
2064 | 2064 | ||
2065 | init_MUTEX (&fepriv->sem); | 2065 | sema_init(&fepriv->sem, 1); |
2066 | init_waitqueue_head (&fepriv->wait_queue); | 2066 | init_waitqueue_head (&fepriv->wait_queue); |
2067 | init_waitqueue_head (&fepriv->events.wait_queue); | 2067 | init_waitqueue_head (&fepriv->events.wait_queue); |
2068 | mutex_init(&fepriv->events.mtx); | 2068 | mutex_init(&fepriv->events.mtx); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index bf0e6bed28d..f9f19be7718 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -260,7 +260,7 @@ struct dvb_frontend_ops { | |||
260 | int (*init)(struct dvb_frontend* fe); | 260 | int (*init)(struct dvb_frontend* fe); |
261 | int (*sleep)(struct dvb_frontend* fe); | 261 | int (*sleep)(struct dvb_frontend* fe); |
262 | 262 | ||
263 | int (*write)(struct dvb_frontend* fe, u8* buf, int len); | 263 | int (*write)(struct dvb_frontend* fe, const u8 buf[], int len); |
264 | 264 | ||
265 | /* if this is set, it overrides the default swzigzag */ | 265 | /* if this is set, it overrides the default swzigzag */ |
266 | int (*tune)(struct dvb_frontend* fe, | 266 | int (*tune)(struct dvb_frontend* fe, |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index fdc19bba212..2525d3b3c88 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -314,6 +314,8 @@ config DVB_USB_AF9015 | |||
314 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE | 314 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE |
315 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 315 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
316 | select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE | 316 | select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE |
317 | select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE | ||
318 | select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE | ||
317 | help | 319 | help |
318 | Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver | 320 | Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver |
319 | 321 | ||
@@ -346,3 +348,13 @@ config DVB_USB_AZ6027 | |||
346 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | 348 | select DVB_STB6100 if !DVB_FE_CUSTOMISE |
347 | help | 349 | help |
348 | Say Y here to support the AZ6027 device | 350 | Say Y here to support the AZ6027 device |
351 | |||
352 | config DVB_USB_LME2510 | ||
353 | tristate "LME DM04/QQBOX DVB-S USB2.0 support" | ||
354 | depends on DVB_USB | ||
355 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE | ||
356 | select DVB_TDA826X if !DVB_FE_CUSTOMISE | ||
357 | select DVB_STV0288 if !DVB_FE_CUSTOMISE | ||
358 | select DVB_IX2505V if !DVB_FE_CUSTOMISE | ||
359 | help | ||
360 | Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . | ||
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 1a192453b0e..5b1d12f2d59 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -88,6 +88,9 @@ obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o | |||
88 | dvb-usb-az6027-objs = az6027.o | 88 | dvb-usb-az6027-objs = az6027.o |
89 | obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o | 89 | obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o |
90 | 90 | ||
91 | dvb-usb-lmedm04-objs = lmedm04.o | ||
92 | obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o | ||
93 | |||
91 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 94 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
92 | # due to tuner-xc3028 | 95 | # due to tuner-xc3028 |
93 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | 96 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index ea1ed3b4592..31c0a0ed39f 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "tda18271.h" | 31 | #include "tda18271.h" |
32 | #include "mxl5005s.h" | 32 | #include "mxl5005s.h" |
33 | #include "mc44s803.h" | 33 | #include "mc44s803.h" |
34 | #include "tda18218.h" | ||
35 | #include "mxl5007t.h" | ||
34 | 36 | ||
35 | static int dvb_usb_af9015_debug; | 37 | static int dvb_usb_af9015_debug; |
36 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); | 38 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); |
@@ -205,12 +207,18 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) | |||
205 | return af9015_write_regs(d, addr, &val, 1); | 207 | return af9015_write_regs(d, addr, &val, 1); |
206 | } | 208 | } |
207 | 209 | ||
208 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | 210 | static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) |
209 | { | 211 | { |
210 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val}; | 212 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, |
213 | val}; | ||
211 | return af9015_ctrl_msg(d, &req); | 214 | return af9015_ctrl_msg(d, &req); |
212 | } | 215 | } |
213 | 216 | ||
217 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | ||
218 | { | ||
219 | return af9015_read_regs(d, addr, val, 1); | ||
220 | } | ||
221 | |||
214 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, | 222 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, |
215 | u8 val) | 223 | u8 val) |
216 | { | 224 | { |
@@ -241,7 +249,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
241 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 249 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
242 | int ret = 0, i = 0; | 250 | int ret = 0, i = 0; |
243 | u16 addr; | 251 | u16 addr; |
244 | u8 mbox, addr_len; | 252 | u8 uninitialized_var(mbox), addr_len; |
245 | struct req_t req; | 253 | struct req_t req; |
246 | 254 | ||
247 | /* TODO: implement bus lock | 255 | /* TODO: implement bus lock |
@@ -280,7 +288,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
280 | } else { | 288 | } else { |
281 | addr = msg[i].buf[0]; | 289 | addr = msg[i].buf[0]; |
282 | addr_len = 1; | 290 | addr_len = 1; |
283 | mbox = 0; | 291 | /* mbox is don't care in that case */ |
284 | } | 292 | } |
285 | 293 | ||
286 | if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { | 294 | if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { |
@@ -494,7 +502,8 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) | |||
494 | /* wait 2nd demodulator ready */ | 502 | /* wait 2nd demodulator ready */ |
495 | msleep(100); | 503 | msleep(100); |
496 | 504 | ||
497 | ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val); | 505 | ret = af9015_read_reg_i2c(d, |
506 | af9015_af9013_config[1].demod_address, 0x98be, &val); | ||
498 | if (ret) | 507 | if (ret) |
499 | goto error; | 508 | goto error; |
500 | else | 509 | else |
@@ -597,37 +606,6 @@ free: | |||
597 | return ret; | 606 | return ret; |
598 | } | 607 | } |
599 | 608 | ||
600 | static int af9015_download_ir_table(struct dvb_usb_device *d) | ||
601 | { | ||
602 | int i, packets = 0, ret; | ||
603 | u16 addr = 0x9a56; /* ir-table start address */ | ||
604 | struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL}; | ||
605 | u8 *data = NULL; | ||
606 | deb_info("%s:\n", __func__); | ||
607 | |||
608 | data = af9015_config.ir_table; | ||
609 | packets = af9015_config.ir_table_size; | ||
610 | |||
611 | /* no remote */ | ||
612 | if (!packets) | ||
613 | goto exit; | ||
614 | |||
615 | /* load remote ir-table */ | ||
616 | for (i = 0; i < packets; i++) { | ||
617 | req.addr = addr + i; | ||
618 | req.data = &data[i]; | ||
619 | ret = af9015_ctrl_msg(d, &req); | ||
620 | if (ret) { | ||
621 | err("ir-table download failed at packet %d with " \ | ||
622 | "code %d", i, ret); | ||
623 | return ret; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | exit: | ||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static int af9015_init(struct dvb_usb_device *d) | 609 | static int af9015_init(struct dvb_usb_device *d) |
632 | { | 610 | { |
633 | int ret; | 611 | int ret; |
@@ -637,10 +615,6 @@ static int af9015_init(struct dvb_usb_device *d) | |||
637 | if (ret) | 615 | if (ret) |
638 | goto error; | 616 | goto error; |
639 | 617 | ||
640 | ret = af9015_download_ir_table(d); | ||
641 | if (ret) | ||
642 | goto error; | ||
643 | |||
644 | error: | 618 | error: |
645 | return ret; | 619 | return ret; |
646 | } | 620 | } |
@@ -733,125 +707,102 @@ error: | |||
733 | return ret; | 707 | return ret; |
734 | } | 708 | } |
735 | 709 | ||
736 | struct af9015_setup { | 710 | struct af9015_rc_setup { |
737 | unsigned int id; | 711 | unsigned int id; |
738 | struct ir_scancode *rc_key_map; | 712 | char *rc_codes; |
739 | unsigned int rc_key_map_size; | ||
740 | u8 *ir_table; | ||
741 | unsigned int ir_table_size; | ||
742 | }; | 713 | }; |
743 | 714 | ||
744 | static const struct af9015_setup *af9015_setup_match(unsigned int id, | 715 | static char *af9015_rc_setup_match(unsigned int id, |
745 | const struct af9015_setup *table) | 716 | const struct af9015_rc_setup *table) |
746 | { | 717 | { |
747 | for (; table->rc_key_map; table++) | 718 | for (; table->rc_codes; table++) |
748 | if (table->id == id) | 719 | if (table->id == id) |
749 | return table; | 720 | return table->rc_codes; |
750 | return NULL; | 721 | return NULL; |
751 | } | 722 | } |
752 | 723 | ||
753 | static const struct af9015_setup af9015_setup_modparam[] = { | 724 | static const struct af9015_rc_setup af9015_rc_setup_modparam[] = { |
754 | { AF9015_REMOTE_A_LINK_DTU_M, | 725 | { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M }, |
755 | ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link), | 726 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II }, |
756 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | 727 | { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND }, |
757 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 728 | { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE }, |
758 | ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi), | 729 | { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS }, |
759 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | ||
760 | { AF9015_REMOTE_MYGICTV_U718, | ||
761 | ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv), | ||
762 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | ||
763 | { AF9015_REMOTE_DIGITTRADE_DVB_T, | ||
764 | ir_codes_af9015_table_digittrade, ARRAY_SIZE(ir_codes_af9015_table_digittrade), | ||
765 | af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) }, | ||
766 | { AF9015_REMOTE_AVERMEDIA_KS, | ||
767 | ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia), | ||
768 | af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) }, | ||
769 | { } | 730 | { } |
770 | }; | 731 | }; |
771 | 732 | ||
772 | /* don't add new entries here anymore, use hashes instead */ | 733 | static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { |
773 | static const struct af9015_setup af9015_setup_usbids[] = { | 734 | { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II }, |
774 | { USB_VID_LEADTEK, | 735 | { 0xa3703d00, RC_MAP_ALINK_DTU_M }, |
775 | ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek), | 736 | { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */ |
776 | af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) }, | ||
777 | { USB_VID_VISIONPLUS, | ||
778 | ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan), | ||
779 | af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) }, | ||
780 | { USB_VID_KWORLD_2, /* TODO: use correct rc keys */ | ||
781 | ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan), | ||
782 | af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) }, | ||
783 | { USB_VID_AVERMEDIA, | ||
784 | ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia), | ||
785 | af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) }, | ||
786 | { USB_VID_MSI_2, | ||
787 | ir_codes_af9015_table_msi_digivox_iii, ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii), | ||
788 | af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) }, | ||
789 | { } | 737 | { } |
790 | }; | 738 | }; |
791 | 739 | ||
792 | static const struct af9015_setup af9015_setup_hashes[] = { | 740 | static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { |
793 | { 0xb8feb708, | 741 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, |
794 | ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi), | 742 | RC_MAP_TERRATEC_SLIM }, |
795 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | 743 | { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, |
796 | { 0xa3703d00, | 744 | RC_MAP_AZUREWAVE_AD_TU700 }, |
797 | ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link), | 745 | { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN, |
798 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | 746 | RC_MAP_AZUREWAVE_AD_TU700 }, |
799 | { 0x9b7dc64e, | 747 | { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III, |
800 | ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv), | 748 | RC_MAP_MSI_DIGIVOX_III }, |
801 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | 749 | { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD, |
750 | RC_MAP_LEADTEK_Y04G0051 }, | ||
751 | { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X, | ||
752 | RC_MAP_AVERMEDIA_M135A }, | ||
753 | { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT, | ||
754 | RC_MAP_TREKSTOR }, | ||
755 | { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2, | ||
756 | RC_MAP_DIGITALNOW_TINYTWIN }, | ||
757 | { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3, | ||
758 | RC_MAP_DIGITALNOW_TINYTWIN }, | ||
802 | { } | 759 | { } |
803 | }; | 760 | }; |
804 | 761 | ||
805 | static void af9015_set_remote_config(struct usb_device *udev, | 762 | static void af9015_set_remote_config(struct usb_device *udev, |
806 | struct dvb_usb_device_properties *props) | 763 | struct dvb_usb_device_properties *props) |
807 | { | 764 | { |
808 | const struct af9015_setup *table = NULL; | 765 | u16 vid = le16_to_cpu(udev->descriptor.idVendor); |
809 | 766 | u16 pid = le16_to_cpu(udev->descriptor.idProduct); | |
810 | if (dvb_usb_af9015_remote) { | 767 | |
811 | /* load remote defined as module param */ | 768 | /* try to load remote based module param */ |
812 | table = af9015_setup_match(dvb_usb_af9015_remote, | 769 | props->rc.core.rc_codes = af9015_rc_setup_match( |
813 | af9015_setup_modparam); | 770 | dvb_usb_af9015_remote, af9015_rc_setup_modparam); |
814 | } else { | 771 | |
815 | u16 vendor = le16_to_cpu(udev->descriptor.idVendor); | 772 | /* try to load remote based eeprom hash */ |
816 | 773 | if (!props->rc.core.rc_codes) | |
817 | table = af9015_setup_match(af9015_config.eeprom_sum, | 774 | props->rc.core.rc_codes = af9015_rc_setup_match( |
818 | af9015_setup_hashes); | 775 | af9015_config.eeprom_sum, af9015_rc_setup_hashes); |
819 | 776 | ||
820 | if (!table && vendor == USB_VID_AFATECH) { | 777 | /* try to load remote based USB ID */ |
821 | /* Check USB manufacturer and product strings and try | 778 | if (!props->rc.core.rc_codes) |
822 | to determine correct remote in case of chip vendor | 779 | props->rc.core.rc_codes = af9015_rc_setup_match( |
823 | reference IDs are used. | 780 | (vid << 16) + pid, af9015_rc_setup_usbids); |
824 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. | 781 | |
825 | */ | 782 | /* try to load remote based USB iManufacturer string */ |
826 | char manufacturer[10]; | 783 | if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) { |
827 | memset(manufacturer, 0, sizeof(manufacturer)); | 784 | /* Check USB manufacturer and product strings and try |
828 | usb_string(udev, udev->descriptor.iManufacturer, | 785 | to determine correct remote in case of chip vendor |
829 | manufacturer, sizeof(manufacturer)); | 786 | reference IDs are used. |
830 | if (!strcmp("MSI", manufacturer)) { | 787 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */ |
831 | /* iManufacturer 1 MSI | 788 | char manufacturer[10]; |
832 | iProduct 2 MSI K-VOX */ | 789 | memset(manufacturer, 0, sizeof(manufacturer)); |
833 | table = af9015_setup_match( | 790 | usb_string(udev, udev->descriptor.iManufacturer, |
834 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 791 | manufacturer, sizeof(manufacturer)); |
835 | af9015_setup_modparam); | 792 | if (!strcmp("MSI", manufacturer)) { |
836 | } else if (udev->descriptor.idProduct == | 793 | /* iManufacturer 1 MSI |
837 | cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { | 794 | iProduct 2 MSI K-VOX */ |
838 | table = &(const struct af9015_setup){ 0, | 795 | props->rc.core.rc_codes = af9015_rc_setup_match( |
839 | ir_codes_af9015_table_trekstor, | 796 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, |
840 | ARRAY_SIZE(ir_codes_af9015_table_trekstor), | 797 | af9015_rc_setup_modparam); |
841 | af9015_ir_table_trekstor, | 798 | } |
842 | ARRAY_SIZE(af9015_ir_table_trekstor) | ||
843 | }; | ||
844 | } | ||
845 | } else if (!table) | ||
846 | table = af9015_setup_match(vendor, af9015_setup_usbids); | ||
847 | } | 799 | } |
848 | 800 | ||
849 | if (table) { | 801 | /* finally load "empty" just for leaving IR receiver enabled */ |
850 | props->rc.legacy.rc_key_map = table->rc_key_map; | 802 | if (!props->rc.core.rc_codes) |
851 | props->rc.legacy.rc_key_map_size = table->rc_key_map_size; | 803 | props->rc.core.rc_codes = RC_MAP_EMPTY; |
852 | af9015_config.ir_table = table->ir_table; | 804 | |
853 | af9015_config.ir_table_size = table->ir_table_size; | 805 | return; |
854 | } | ||
855 | } | 806 | } |
856 | 807 | ||
857 | static int af9015_read_config(struct usb_device *udev) | 808 | static int af9015_read_config(struct usb_device *udev) |
@@ -877,10 +828,9 @@ static int af9015_read_config(struct usb_device *udev) | |||
877 | 828 | ||
878 | deb_info("%s: IR mode:%d\n", __func__, val); | 829 | deb_info("%s: IR mode:%d\n", __func__, val); |
879 | for (i = 0; i < af9015_properties_count; i++) { | 830 | for (i = 0; i < af9015_properties_count; i++) { |
880 | if (val == AF9015_IR_MODE_DISABLED) { | 831 | if (val == AF9015_IR_MODE_DISABLED) |
881 | af9015_properties[i].rc.legacy.rc_key_map = NULL; | 832 | af9015_properties[i].rc.core.rc_codes = NULL; |
882 | af9015_properties[i].rc.legacy.rc_key_map_size = 0; | 833 | else |
883 | } else | ||
884 | af9015_set_remote_config(udev, &af9015_properties[i]); | 834 | af9015_set_remote_config(udev, &af9015_properties[i]); |
885 | } | 835 | } |
886 | 836 | ||
@@ -992,20 +942,19 @@ static int af9015_read_config(struct usb_device *udev) | |||
992 | case AF9013_TUNER_MT2060_2: | 942 | case AF9013_TUNER_MT2060_2: |
993 | case AF9013_TUNER_TDA18271: | 943 | case AF9013_TUNER_TDA18271: |
994 | case AF9013_TUNER_QT1010A: | 944 | case AF9013_TUNER_QT1010A: |
945 | case AF9013_TUNER_TDA18218: | ||
995 | af9015_af9013_config[i].rf_spec_inv = 1; | 946 | af9015_af9013_config[i].rf_spec_inv = 1; |
996 | break; | 947 | break; |
997 | case AF9013_TUNER_MXL5003D: | 948 | case AF9013_TUNER_MXL5003D: |
998 | case AF9013_TUNER_MXL5005D: | 949 | case AF9013_TUNER_MXL5005D: |
999 | case AF9013_TUNER_MXL5005R: | 950 | case AF9013_TUNER_MXL5005R: |
951 | case AF9013_TUNER_MXL5007T: | ||
1000 | af9015_af9013_config[i].rf_spec_inv = 0; | 952 | af9015_af9013_config[i].rf_spec_inv = 0; |
1001 | break; | 953 | break; |
1002 | case AF9013_TUNER_MC44S803: | 954 | case AF9013_TUNER_MC44S803: |
1003 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; | 955 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; |
1004 | af9015_af9013_config[i].rf_spec_inv = 1; | 956 | af9015_af9013_config[i].rf_spec_inv = 1; |
1005 | break; | 957 | break; |
1006 | case AF9013_TUNER_TDA18218: | ||
1007 | warn("tuner NXP TDA18218 not supported yet"); | ||
1008 | return -ENODEV; | ||
1009 | default: | 958 | default: |
1010 | warn("tuner id:%d not supported, please report!", val); | 959 | warn("tuner id:%d not supported, please report!", val); |
1011 | return -ENODEV; | 960 | return -ENODEV; |
@@ -1020,9 +969,13 @@ error: | |||
1020 | err("eeprom read failed:%d", ret); | 969 | err("eeprom read failed:%d", ret); |
1021 | 970 | ||
1022 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM | 971 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM |
1023 | content :-( Override some wrong values here. */ | 972 | content :-( Override some wrong values here. Ditto for the |
973 | AVerTV Red HD+ (A850T) device. */ | ||
1024 | if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && | 974 | if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && |
1025 | le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) { | 975 | ((le16_to_cpu(udev->descriptor.idProduct) == |
976 | USB_PID_AVERMEDIA_A850) || | ||
977 | (le16_to_cpu(udev->descriptor.idProduct) == | ||
978 | USB_PID_AVERMEDIA_A850T))) { | ||
1026 | deb_info("%s: AverMedia A850: overriding config\n", __func__); | 979 | deb_info("%s: AverMedia A850: overriding config\n", __func__); |
1027 | /* disable dual mode */ | 980 | /* disable dual mode */ |
1028 | af9015_config.dual_mode = 0; | 981 | af9015_config.dual_mode = 0; |
@@ -1059,36 +1012,53 @@ static int af9015_identify_state(struct usb_device *udev, | |||
1059 | return ret; | 1012 | return ret; |
1060 | } | 1013 | } |
1061 | 1014 | ||
1062 | static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 1015 | static int af9015_rc_query(struct dvb_usb_device *d) |
1063 | { | 1016 | { |
1064 | u8 buf[8]; | 1017 | struct af9015_state *priv = d->priv; |
1065 | struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; | 1018 | int ret; |
1066 | struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; | 1019 | u8 buf[16]; |
1067 | int i, ret; | ||
1068 | |||
1069 | memset(buf, 0, sizeof(buf)); | ||
1070 | 1020 | ||
1071 | ret = af9015_ctrl_msg(d, &req); | 1021 | /* read registers needed to detect remote controller code */ |
1022 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | ||
1072 | if (ret) | 1023 | if (ret) |
1073 | return ret; | 1024 | goto error; |
1074 | 1025 | ||
1075 | *event = 0; | 1026 | if (buf[14] || buf[15]) { |
1076 | *state = REMOTE_NO_KEY_PRESSED; | 1027 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, |
1028 | buf[12], buf[13], buf[14], buf[15]); | ||
1077 | 1029 | ||
1078 | for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { | 1030 | /* clean IR code from mem */ |
1079 | if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] && | 1031 | ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); |
1080 | rc5_data(&keymap[i]) == buf[2]) { | 1032 | if (ret) |
1081 | *event = keymap[i].keycode; | 1033 | goto error; |
1082 | *state = REMOTE_KEY_PRESSED; | 1034 | |
1083 | break; | 1035 | if (buf[14] == (u8) ~buf[15]) { |
1036 | if (buf[12] == (u8) ~buf[13]) { | ||
1037 | /* NEC */ | ||
1038 | priv->rc_keycode = buf[12] << 8 | buf[14]; | ||
1039 | } else { | ||
1040 | /* NEC extended*/ | ||
1041 | priv->rc_keycode = buf[12] << 16 | | ||
1042 | buf[13] << 8 | buf[14]; | ||
1043 | } | ||
1044 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); | ||
1045 | } else { | ||
1046 | priv->rc_keycode = 0; /* clear just for sure */ | ||
1084 | } | 1047 | } |
1048 | } else if (priv->rc_repeat != buf[6] || buf[0]) { | ||
1049 | deb_rc("%s: key repeated\n", __func__); | ||
1050 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); | ||
1051 | } else { | ||
1052 | deb_rc("%s: no key press\n", __func__); | ||
1085 | } | 1053 | } |
1086 | if (!buf[1]) | ||
1087 | deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
1088 | __func__, buf[0], buf[1], buf[2], buf[3], buf[4], | ||
1089 | buf[5], buf[6], buf[7]); | ||
1090 | 1054 | ||
1091 | return 0; | 1055 | priv->rc_repeat = buf[6]; |
1056 | |||
1057 | error: | ||
1058 | if (ret) | ||
1059 | err("%s: failed:%d", __func__, ret); | ||
1060 | |||
1061 | return ret; | ||
1092 | } | 1062 | } |
1093 | 1063 | ||
1094 | /* init 2nd I2C adapter */ | 1064 | /* init 2nd I2C adapter */ |
@@ -1100,11 +1070,6 @@ static int af9015_i2c_init(struct dvb_usb_device *d) | |||
1100 | 1070 | ||
1101 | strncpy(state->i2c_adap.name, d->desc->name, | 1071 | strncpy(state->i2c_adap.name, d->desc->name, |
1102 | sizeof(state->i2c_adap.name)); | 1072 | sizeof(state->i2c_adap.name)); |
1103 | #ifdef I2C_ADAP_CLASS_TV_DIGITAL | ||
1104 | state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, | ||
1105 | #else | ||
1106 | state->i2c_adap.class = I2C_CLASS_TV_DIGITAL, | ||
1107 | #endif | ||
1108 | state->i2c_adap.algo = d->props.i2c_algo; | 1073 | state->i2c_adap.algo = d->props.i2c_algo; |
1109 | state->i2c_adap.algo_data = NULL; | 1074 | state->i2c_adap.algo_data = NULL; |
1110 | state->i2c_adap.dev.parent = &d->udev->dev; | 1075 | state->i2c_adap.dev.parent = &d->udev->dev; |
@@ -1166,7 +1131,7 @@ static struct qt1010_config af9015_qt1010_config = { | |||
1166 | 1131 | ||
1167 | static struct tda18271_config af9015_tda18271_config = { | 1132 | static struct tda18271_config af9015_tda18271_config = { |
1168 | .gate = TDA18271_GATE_DIGITAL, | 1133 | .gate = TDA18271_GATE_DIGITAL, |
1169 | .small_i2c = 1, | 1134 | .small_i2c = TDA18271_16_BYTE_CHUNK_INIT, |
1170 | }; | 1135 | }; |
1171 | 1136 | ||
1172 | static struct mxl5005s_config af9015_mxl5003_config = { | 1137 | static struct mxl5005s_config af9015_mxl5003_config = { |
@@ -1208,12 +1173,22 @@ static struct mc44s803_config af9015_mc44s803_config = { | |||
1208 | .dig_out = 1, | 1173 | .dig_out = 1, |
1209 | }; | 1174 | }; |
1210 | 1175 | ||
1176 | static struct tda18218_config af9015_tda18218_config = { | ||
1177 | .i2c_address = 0xc0, | ||
1178 | .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */ | ||
1179 | }; | ||
1180 | |||
1181 | static struct mxl5007t_config af9015_mxl5007t_config = { | ||
1182 | .xtal_freq_hz = MxL_XTAL_24_MHZ, | ||
1183 | .if_freq_hz = MxL_IF_4_57_MHZ, | ||
1184 | }; | ||
1185 | |||
1211 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | 1186 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) |
1212 | { | 1187 | { |
1213 | struct af9015_state *state = adap->dev->priv; | 1188 | struct af9015_state *state = adap->dev->priv; |
1214 | struct i2c_adapter *i2c_adap; | 1189 | struct i2c_adapter *i2c_adap; |
1215 | int ret; | 1190 | int ret; |
1216 | deb_info("%s: \n", __func__); | 1191 | deb_info("%s:\n", __func__); |
1217 | 1192 | ||
1218 | /* select I2C adapter */ | 1193 | /* select I2C adapter */ |
1219 | if (adap->id == 0) | 1194 | if (adap->id == 0) |
@@ -1238,6 +1213,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1238 | ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, | 1213 | ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, |
1239 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; | 1214 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; |
1240 | break; | 1215 | break; |
1216 | case AF9013_TUNER_TDA18218: | ||
1217 | ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap, | ||
1218 | &af9015_tda18218_config) == NULL ? -ENODEV : 0; | ||
1219 | break; | ||
1241 | case AF9013_TUNER_MXL5003D: | 1220 | case AF9013_TUNER_MXL5003D: |
1242 | ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, | 1221 | ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, |
1243 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; | 1222 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; |
@@ -1255,6 +1234,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1255 | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, | 1234 | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, |
1256 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; | 1235 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; |
1257 | break; | 1236 | break; |
1237 | case AF9013_TUNER_MXL5007T: | ||
1238 | ret = dvb_attach(mxl5007t_attach, adap->fe, i2c_adap, | ||
1239 | 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; | ||
1240 | break; | ||
1258 | case AF9013_TUNER_UNKNOWN: | 1241 | case AF9013_TUNER_UNKNOWN: |
1259 | default: | 1242 | default: |
1260 | ret = -ENODEV; | 1243 | ret = -ENODEV; |
@@ -1300,10 +1283,16 @@ static struct usb_device_id af9015_usb_table[] = { | |||
1300 | /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, | 1283 | /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, |
1301 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, | 1284 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, |
1302 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, | 1285 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, |
1286 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, | ||
1287 | {USB_DEVICE(USB_VID_TERRATEC, | ||
1288 | USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, | ||
1289 | /* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, | ||
1290 | {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, | ||
1303 | {0}, | 1291 | {0}, |
1304 | }; | 1292 | }; |
1305 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); | 1293 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); |
1306 | 1294 | ||
1295 | #define AF9015_RC_INTERVAL 500 | ||
1307 | static struct dvb_usb_device_properties af9015_properties[] = { | 1296 | static struct dvb_usb_device_properties af9015_properties[] = { |
1308 | { | 1297 | { |
1309 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1298 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -1354,14 +1343,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1354 | 1343 | ||
1355 | .identify_state = af9015_identify_state, | 1344 | .identify_state = af9015_identify_state, |
1356 | 1345 | ||
1357 | .rc.legacy = { | 1346 | .rc.core = { |
1347 | .protocol = IR_TYPE_NEC, | ||
1348 | .module_name = "af9015", | ||
1358 | .rc_query = af9015_rc_query, | 1349 | .rc_query = af9015_rc_query, |
1359 | .rc_interval = 150, | 1350 | .rc_interval = AF9015_RC_INTERVAL, |
1351 | .rc_props = { | ||
1352 | .allowed_protos = IR_TYPE_NEC, | ||
1353 | }, | ||
1360 | }, | 1354 | }, |
1361 | 1355 | ||
1362 | .i2c_algo = &af9015_i2c_algo, | 1356 | .i2c_algo = &af9015_i2c_algo, |
1363 | 1357 | ||
1364 | .num_device_descs = 9, /* max 9 */ | 1358 | .num_device_descs = 12, /* check max from dvb-usb.h */ |
1365 | .devices = { | 1359 | .devices = { |
1366 | { | 1360 | { |
1367 | .name = "Afatech AF9015 DVB-T USB2.0 stick", | 1361 | .name = "Afatech AF9015 DVB-T USB2.0 stick", |
@@ -1389,7 +1383,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1389 | { | 1383 | { |
1390 | .name = "DigitalNow TinyTwin DVB-T Receiver", | 1384 | .name = "DigitalNow TinyTwin DVB-T Receiver", |
1391 | .cold_ids = {&af9015_usb_table[5], | 1385 | .cold_ids = {&af9015_usb_table[5], |
1392 | &af9015_usb_table[28], NULL}, | 1386 | &af9015_usb_table[28], |
1387 | &af9015_usb_table[36], NULL}, | ||
1393 | .warm_ids = {NULL}, | 1388 | .warm_ids = {NULL}, |
1394 | }, | 1389 | }, |
1395 | { | 1390 | { |
@@ -1413,6 +1408,21 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1413 | .cold_ids = {&af9015_usb_table[9], NULL}, | 1408 | .cold_ids = {&af9015_usb_table[9], NULL}, |
1414 | .warm_ids = {NULL}, | 1409 | .warm_ids = {NULL}, |
1415 | }, | 1410 | }, |
1411 | { | ||
1412 | .name = "TerraTec Cinergy T Stick RC", | ||
1413 | .cold_ids = {&af9015_usb_table[33], NULL}, | ||
1414 | .warm_ids = {NULL}, | ||
1415 | }, | ||
1416 | { | ||
1417 | .name = "TerraTec Cinergy T Stick Dual RC", | ||
1418 | .cold_ids = {&af9015_usb_table[34], NULL}, | ||
1419 | .warm_ids = {NULL}, | ||
1420 | }, | ||
1421 | { | ||
1422 | .name = "AverMedia AVerTV Red HD+ (A850T)", | ||
1423 | .cold_ids = {&af9015_usb_table[35], NULL}, | ||
1424 | .warm_ids = {NULL}, | ||
1425 | }, | ||
1416 | } | 1426 | } |
1417 | }, { | 1427 | }, { |
1418 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1428 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -1463,14 +1473,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1463 | 1473 | ||
1464 | .identify_state = af9015_identify_state, | 1474 | .identify_state = af9015_identify_state, |
1465 | 1475 | ||
1466 | .rc.legacy = { | 1476 | .rc.core = { |
1477 | .protocol = IR_TYPE_NEC, | ||
1478 | .module_name = "af9015", | ||
1467 | .rc_query = af9015_rc_query, | 1479 | .rc_query = af9015_rc_query, |
1468 | .rc_interval = 150, | 1480 | .rc_interval = AF9015_RC_INTERVAL, |
1481 | .rc_props = { | ||
1482 | .allowed_protos = IR_TYPE_NEC, | ||
1483 | }, | ||
1469 | }, | 1484 | }, |
1470 | 1485 | ||
1471 | .i2c_algo = &af9015_i2c_algo, | 1486 | .i2c_algo = &af9015_i2c_algo, |
1472 | 1487 | ||
1473 | .num_device_descs = 9, /* max 9 */ | 1488 | .num_device_descs = 9, /* check max from dvb-usb.h */ |
1474 | .devices = { | 1489 | .devices = { |
1475 | { | 1490 | { |
1476 | .name = "Xtensions XD-380", | 1491 | .name = "Xtensions XD-380", |
@@ -1572,14 +1587,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1572 | 1587 | ||
1573 | .identify_state = af9015_identify_state, | 1588 | .identify_state = af9015_identify_state, |
1574 | 1589 | ||
1575 | .rc.legacy = { | 1590 | .rc.core = { |
1591 | .protocol = IR_TYPE_NEC, | ||
1592 | .module_name = "af9015", | ||
1576 | .rc_query = af9015_rc_query, | 1593 | .rc_query = af9015_rc_query, |
1577 | .rc_interval = 150, | 1594 | .rc_interval = AF9015_RC_INTERVAL, |
1595 | .rc_props = { | ||
1596 | .allowed_protos = IR_TYPE_NEC, | ||
1597 | }, | ||
1578 | }, | 1598 | }, |
1579 | 1599 | ||
1580 | .i2c_algo = &af9015_i2c_algo, | 1600 | .i2c_algo = &af9015_i2c_algo, |
1581 | 1601 | ||
1582 | .num_device_descs = 9, /* max 9 */ | 1602 | .num_device_descs = 9, /* check max from dvb-usb.h */ |
1583 | .devices = { | 1603 | .devices = { |
1584 | { | 1604 | { |
1585 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", | 1605 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", |
@@ -1672,7 +1692,7 @@ static int af9015_usb_probe(struct usb_interface *intf, | |||
1672 | static void af9015_i2c_exit(struct dvb_usb_device *d) | 1692 | static void af9015_i2c_exit(struct dvb_usb_device *d) |
1673 | { | 1693 | { |
1674 | struct af9015_state *state = d->priv; | 1694 | struct af9015_state *state = d->priv; |
1675 | deb_info("%s: \n", __func__); | 1695 | deb_info("%s:\n", __func__); |
1676 | 1696 | ||
1677 | /* remove 2nd I2C adapter */ | 1697 | /* remove 2nd I2C adapter */ |
1678 | if (d->state & DVB_USB_STATE_I2C) | 1698 | if (d->state & DVB_USB_STATE_I2C) |
@@ -1682,7 +1702,7 @@ static void af9015_i2c_exit(struct dvb_usb_device *d) | |||
1682 | static void af9015_usb_device_exit(struct usb_interface *intf) | 1702 | static void af9015_usb_device_exit(struct usb_interface *intf) |
1683 | { | 1703 | { |
1684 | struct dvb_usb_device *d = usb_get_intfdata(intf); | 1704 | struct dvb_usb_device *d = usb_get_intfdata(intf); |
1685 | deb_info("%s: \n", __func__); | 1705 | deb_info("%s:\n", __func__); |
1686 | 1706 | ||
1687 | /* remove 2nd I2C adapter */ | 1707 | /* remove 2nd I2C adapter */ |
1688 | if (d != NULL && d->desc != NULL) | 1708 | if (d != NULL && d->desc != NULL) |
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index c8e9349742e..f20cfa6ed69 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h | |||
@@ -100,6 +100,8 @@ enum af9015_ir_mode { | |||
100 | 100 | ||
101 | struct af9015_state { | 101 | struct af9015_state { |
102 | struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ | 102 | struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ |
103 | u8 rc_repeat; | ||
104 | u32 rc_keycode; | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | struct af9015_config { | 107 | struct af9015_config { |
@@ -108,8 +110,6 @@ struct af9015_config { | |||
108 | u16 firmware_size; | 110 | u16 firmware_size; |
109 | u16 firmware_checksum; | 111 | u16 firmware_checksum; |
110 | u32 eeprom_sum; | 112 | u32 eeprom_sum; |
111 | u8 *ir_table; | ||
112 | u16 ir_table_size; | ||
113 | }; | 113 | }; |
114 | 114 | ||
115 | enum af9015_remote { | 115 | enum af9015_remote { |
@@ -121,735 +121,4 @@ enum af9015_remote { | |||
121 | /* 5 */ AF9015_REMOTE_AVERMEDIA_KS, | 121 | /* 5 */ AF9015_REMOTE_AVERMEDIA_KS, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* LeadTek - Y04G0051 */ | ||
125 | /* Leadtek WinFast DTV Dongle Gold */ | ||
126 | static struct ir_scancode ir_codes_af9015_table_leadtek[] = { | ||
127 | { 0x001e, KEY_1 }, | ||
128 | { 0x001f, KEY_2 }, | ||
129 | { 0x0020, KEY_3 }, | ||
130 | { 0x0021, KEY_4 }, | ||
131 | { 0x0022, KEY_5 }, | ||
132 | { 0x0023, KEY_6 }, | ||
133 | { 0x0024, KEY_7 }, | ||
134 | { 0x0025, KEY_8 }, | ||
135 | { 0x0026, KEY_9 }, | ||
136 | { 0x0027, KEY_0 }, | ||
137 | { 0x0028, KEY_OK }, | ||
138 | { 0x004f, KEY_RIGHT }, | ||
139 | { 0x0050, KEY_LEFT }, | ||
140 | { 0x0051, KEY_DOWN }, | ||
141 | { 0x0052, KEY_UP }, | ||
142 | { 0x011a, KEY_POWER2 }, | ||
143 | { 0x04b4, KEY_TV }, | ||
144 | { 0x04b3, KEY_RED }, | ||
145 | { 0x04b2, KEY_GREEN }, | ||
146 | { 0x04b1, KEY_YELLOW }, | ||
147 | { 0x04b0, KEY_BLUE }, | ||
148 | { 0x003d, KEY_TEXT }, | ||
149 | { 0x0113, KEY_SLEEP }, | ||
150 | { 0x0010, KEY_MUTE }, | ||
151 | { 0x0105, KEY_ESC }, | ||
152 | { 0x0009, KEY_SCREEN }, | ||
153 | { 0x010f, KEY_MENU }, | ||
154 | { 0x003f, KEY_CHANNEL }, | ||
155 | { 0x0013, KEY_REWIND }, | ||
156 | { 0x0012, KEY_PLAY }, | ||
157 | { 0x0011, KEY_FASTFORWARD }, | ||
158 | { 0x0005, KEY_PREVIOUS }, | ||
159 | { 0x0029, KEY_STOP }, | ||
160 | { 0x002b, KEY_NEXT }, | ||
161 | { 0x0041, KEY_EPG }, | ||
162 | { 0x0019, KEY_VIDEO }, | ||
163 | { 0x0016, KEY_AUDIO }, | ||
164 | { 0x0037, KEY_DOT }, | ||
165 | { 0x002a, KEY_AGAIN }, | ||
166 | { 0x002c, KEY_CAMERA }, | ||
167 | { 0x003c, KEY_NEW }, | ||
168 | { 0x0115, KEY_RECORD }, | ||
169 | { 0x010b, KEY_TIME }, | ||
170 | { 0x0043, KEY_VOLUMEUP }, | ||
171 | { 0x0042, KEY_VOLUMEDOWN }, | ||
172 | { 0x004b, KEY_CHANNELUP }, | ||
173 | { 0x004e, KEY_CHANNELDOWN }, | ||
174 | }; | ||
175 | |||
176 | static u8 af9015_ir_table_leadtek[] = { | ||
177 | 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */ | ||
178 | 0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */ | ||
179 | 0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */ | ||
180 | 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */ | ||
181 | 0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */ | ||
182 | 0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */ | ||
183 | 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */ | ||
184 | 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */ | ||
185 | 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */ | ||
186 | 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */ | ||
187 | 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/ | ||
188 | 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */ | ||
189 | 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */ | ||
190 | 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */ | ||
191 | 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */ | ||
192 | 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */ | ||
193 | 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */ | ||
194 | 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */ | ||
195 | 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */ | ||
196 | 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */ | ||
197 | 0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */ | ||
198 | 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */ | ||
199 | 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */ | ||
200 | 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */ | ||
201 | 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */ | ||
202 | 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */ | ||
203 | 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */ | ||
204 | 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */ | ||
205 | 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */ | ||
206 | 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */ | ||
207 | 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */ | ||
208 | 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */ | ||
209 | 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */ | ||
210 | 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */ | ||
211 | 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */ | ||
212 | 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */ | ||
213 | 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */ | ||
214 | 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */ | ||
215 | 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */ | ||
216 | 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */ | ||
217 | 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */ | ||
218 | 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */ | ||
219 | 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */ | ||
220 | 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */ | ||
221 | 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */ | ||
222 | 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */ | ||
223 | 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */ | ||
224 | 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */ | ||
225 | 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */ | ||
226 | 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */ | ||
227 | }; | ||
228 | |||
229 | /* TwinHan AzureWave AD-TU700(704J) */ | ||
230 | static struct ir_scancode ir_codes_af9015_table_twinhan[] = { | ||
231 | { 0x053f, KEY_POWER }, | ||
232 | { 0x0019, KEY_FAVORITES }, /* Favorite List */ | ||
233 | { 0x0004, KEY_TEXT }, /* Teletext */ | ||
234 | { 0x000e, KEY_POWER }, | ||
235 | { 0x000e, KEY_INFO }, /* Preview */ | ||
236 | { 0x0008, KEY_EPG }, /* Info/EPG */ | ||
237 | { 0x000f, KEY_LIST }, /* Record List */ | ||
238 | { 0x001e, KEY_1 }, | ||
239 | { 0x001f, KEY_2 }, | ||
240 | { 0x0020, KEY_3 }, | ||
241 | { 0x0021, KEY_4 }, | ||
242 | { 0x0022, KEY_5 }, | ||
243 | { 0x0023, KEY_6 }, | ||
244 | { 0x0024, KEY_7 }, | ||
245 | { 0x0025, KEY_8 }, | ||
246 | { 0x0026, KEY_9 }, | ||
247 | { 0x0027, KEY_0 }, | ||
248 | { 0x0029, KEY_CANCEL }, /* Cancel */ | ||
249 | { 0x004c, KEY_CLEAR }, /* Clear */ | ||
250 | { 0x002a, KEY_BACK }, /* Back */ | ||
251 | { 0x002b, KEY_TAB }, /* Tab */ | ||
252 | { 0x0052, KEY_UP }, /* up arrow */ | ||
253 | { 0x0051, KEY_DOWN }, /* down arrow */ | ||
254 | { 0x004f, KEY_RIGHT }, /* right arrow */ | ||
255 | { 0x0050, KEY_LEFT }, /* left arrow */ | ||
256 | { 0x0028, KEY_ENTER }, /* Enter / ok */ | ||
257 | { 0x0252, KEY_VOLUMEUP }, | ||
258 | { 0x0251, KEY_VOLUMEDOWN }, | ||
259 | { 0x004e, KEY_CHANNELDOWN }, | ||
260 | { 0x004b, KEY_CHANNELUP }, | ||
261 | { 0x004a, KEY_RECORD }, | ||
262 | { 0x0111, KEY_PLAY }, | ||
263 | { 0x0017, KEY_PAUSE }, | ||
264 | { 0x000c, KEY_REWIND }, /* FR << */ | ||
265 | { 0x0011, KEY_FASTFORWARD }, /* FF >> */ | ||
266 | { 0x0115, KEY_PREVIOUS }, /* Replay */ | ||
267 | { 0x010e, KEY_NEXT }, /* Skip */ | ||
268 | { 0x0013, KEY_CAMERA }, /* Capture */ | ||
269 | { 0x010f, KEY_LANGUAGE }, /* SAP */ | ||
270 | { 0x0113, KEY_TV2 }, /* PIP */ | ||
271 | { 0x001d, KEY_ZOOM }, /* Full Screen */ | ||
272 | { 0x0117, KEY_SUBTITLE }, /* Subtitle / CC */ | ||
273 | { 0x0010, KEY_MUTE }, | ||
274 | { 0x0119, KEY_AUDIO }, /* L/R */ /* TODO better event */ | ||
275 | { 0x0116, KEY_SLEEP }, /* Hibernate */ | ||
276 | { 0x0116, KEY_SWITCHVIDEOMODE }, | ||
277 | /* A/V */ /* TODO does not work */ | ||
278 | { 0x0006, KEY_AGAIN }, /* Recall */ | ||
279 | { 0x0116, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */ | ||
280 | { 0x0116, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */ | ||
281 | { 0x0215, KEY_RED }, | ||
282 | { 0x020a, KEY_GREEN }, | ||
283 | { 0x021c, KEY_YELLOW }, | ||
284 | { 0x0205, KEY_BLUE }, | ||
285 | }; | ||
286 | |||
287 | static u8 af9015_ir_table_twinhan[] = { | ||
288 | 0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00, | ||
289 | 0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00, | ||
290 | 0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00, | ||
291 | 0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00, | ||
292 | 0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00, | ||
293 | 0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00, | ||
294 | 0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00, | ||
295 | 0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00, | ||
296 | 0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00, | ||
297 | 0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00, | ||
298 | 0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00, | ||
299 | 0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00, | ||
300 | 0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00, | ||
301 | 0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00, | ||
302 | 0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00, | ||
303 | 0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00, | ||
304 | 0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00, | ||
305 | 0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00, | ||
306 | 0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00, | ||
307 | 0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00, | ||
308 | 0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00, | ||
309 | 0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00, | ||
310 | 0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00, | ||
311 | 0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00, | ||
312 | 0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00, | ||
313 | 0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00, | ||
314 | 0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00, | ||
315 | 0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00, | ||
316 | 0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00, | ||
317 | 0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00, | ||
318 | 0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00, | ||
319 | 0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00, | ||
320 | 0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00, | ||
321 | 0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00, | ||
322 | 0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00, | ||
323 | 0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00, | ||
324 | 0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00, | ||
325 | 0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00, | ||
326 | 0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00, | ||
327 | 0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00, | ||
328 | 0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00, | ||
329 | 0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00, | ||
330 | 0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00, | ||
331 | 0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00, | ||
332 | 0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00, | ||
333 | 0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00, | ||
334 | 0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00, | ||
335 | 0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00, | ||
336 | 0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00, | ||
337 | 0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00, | ||
338 | }; | ||
339 | |||
340 | /* A-Link DTU(m) */ | ||
341 | static struct ir_scancode ir_codes_af9015_table_a_link[] = { | ||
342 | { 0x001e, KEY_1 }, | ||
343 | { 0x001f, KEY_2 }, | ||
344 | { 0x0020, KEY_3 }, | ||
345 | { 0x0021, KEY_4 }, | ||
346 | { 0x0022, KEY_5 }, | ||
347 | { 0x0023, KEY_6 }, | ||
348 | { 0x0024, KEY_7 }, | ||
349 | { 0x0025, KEY_8 }, | ||
350 | { 0x0026, KEY_9 }, | ||
351 | { 0x0027, KEY_0 }, | ||
352 | { 0x002e, KEY_CHANNELUP }, | ||
353 | { 0x002d, KEY_CHANNELDOWN }, | ||
354 | { 0x0428, KEY_ZOOM }, | ||
355 | { 0x0041, KEY_MUTE }, | ||
356 | { 0x0042, KEY_VOLUMEDOWN }, | ||
357 | { 0x0043, KEY_VOLUMEUP }, | ||
358 | { 0x0044, KEY_GOTO }, /* jump */ | ||
359 | { 0x0545, KEY_POWER }, | ||
360 | }; | ||
361 | |||
362 | static u8 af9015_ir_table_a_link[] = { | ||
363 | 0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */ | ||
364 | 0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */ | ||
365 | 0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */ | ||
366 | 0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */ | ||
367 | 0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */ | ||
368 | 0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */ | ||
369 | 0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */ | ||
370 | 0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */ | ||
371 | 0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */ | ||
372 | 0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */ | ||
373 | 0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */ | ||
374 | 0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */ | ||
375 | 0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */ | ||
376 | 0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */ | ||
377 | 0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */ | ||
378 | 0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */ | ||
379 | 0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */ | ||
380 | 0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */ | ||
381 | }; | ||
382 | |||
383 | /* MSI DIGIVOX mini II V3.0 */ | ||
384 | static struct ir_scancode ir_codes_af9015_table_msi[] = { | ||
385 | { 0x001e, KEY_1 }, | ||
386 | { 0x001f, KEY_2 }, | ||
387 | { 0x0020, KEY_3 }, | ||
388 | { 0x0021, KEY_4 }, | ||
389 | { 0x0022, KEY_5 }, | ||
390 | { 0x0023, KEY_6 }, | ||
391 | { 0x0024, KEY_7 }, | ||
392 | { 0x0025, KEY_8 }, | ||
393 | { 0x0026, KEY_9 }, | ||
394 | { 0x0027, KEY_0 }, | ||
395 | { 0x030f, KEY_CHANNELUP }, | ||
396 | { 0x030e, KEY_CHANNELDOWN }, | ||
397 | { 0x0042, KEY_VOLUMEDOWN }, | ||
398 | { 0x0043, KEY_VOLUMEUP }, | ||
399 | { 0x0545, KEY_POWER }, | ||
400 | { 0x0052, KEY_UP }, /* up */ | ||
401 | { 0x0051, KEY_DOWN }, /* down */ | ||
402 | { 0x0028, KEY_ENTER }, | ||
403 | }; | ||
404 | |||
405 | static u8 af9015_ir_table_msi[] = { | ||
406 | 0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */ | ||
407 | 0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */ | ||
408 | 0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */ | ||
409 | 0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */ | ||
410 | 0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */ | ||
411 | 0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */ | ||
412 | 0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */ | ||
413 | 0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */ | ||
414 | 0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */ | ||
415 | 0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */ | ||
416 | 0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */ | ||
417 | 0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */ | ||
418 | 0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */ | ||
419 | 0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */ | ||
420 | 0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */ | ||
421 | 0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */ | ||
422 | 0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */ | ||
423 | 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */ | ||
424 | }; | ||
425 | |||
426 | /* MYGICTV U718 */ | ||
427 | static struct ir_scancode ir_codes_af9015_table_mygictv[] = { | ||
428 | { 0x003d, KEY_SWITCHVIDEOMODE }, | ||
429 | /* TV / AV */ | ||
430 | { 0x0545, KEY_POWER }, | ||
431 | { 0x001e, KEY_1 }, | ||
432 | { 0x001f, KEY_2 }, | ||
433 | { 0x0020, KEY_3 }, | ||
434 | { 0x0021, KEY_4 }, | ||
435 | { 0x0022, KEY_5 }, | ||
436 | { 0x0023, KEY_6 }, | ||
437 | { 0x0024, KEY_7 }, | ||
438 | { 0x0025, KEY_8 }, | ||
439 | { 0x0026, KEY_9 }, | ||
440 | { 0x0027, KEY_0 }, | ||
441 | { 0x0041, KEY_MUTE }, | ||
442 | { 0x002a, KEY_ESC }, /* Esc */ | ||
443 | { 0x002e, KEY_CHANNELUP }, | ||
444 | { 0x002d, KEY_CHANNELDOWN }, | ||
445 | { 0x0042, KEY_VOLUMEDOWN }, | ||
446 | { 0x0043, KEY_VOLUMEUP }, | ||
447 | { 0x0052, KEY_UP }, /* up arrow */ | ||
448 | { 0x0051, KEY_DOWN }, /* down arrow */ | ||
449 | { 0x004f, KEY_RIGHT }, /* right arrow */ | ||
450 | { 0x0050, KEY_LEFT }, /* left arrow */ | ||
451 | { 0x0028, KEY_ENTER }, /* ok */ | ||
452 | { 0x0115, KEY_RECORD }, | ||
453 | { 0x0313, KEY_PLAY }, | ||
454 | { 0x0113, KEY_PAUSE }, | ||
455 | { 0x0116, KEY_STOP }, | ||
456 | { 0x0307, KEY_REWIND }, /* FR << */ | ||
457 | { 0x0309, KEY_FASTFORWARD }, /* FF >> */ | ||
458 | { 0x003b, KEY_TIME }, /* TimeShift */ | ||
459 | { 0x003e, KEY_CAMERA }, /* Snapshot */ | ||
460 | { 0x0316, KEY_CYCLEWINDOWS }, /* yellow, min / max */ | ||
461 | { 0x0000, KEY_ZOOM }, /* 'select' (?) */ | ||
462 | { 0x0316, KEY_SHUFFLE }, /* Shuffle */ | ||
463 | { 0x0345, KEY_POWER }, | ||
464 | }; | ||
465 | |||
466 | static u8 af9015_ir_table_mygictv[] = { | ||
467 | 0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */ | ||
468 | 0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */ | ||
469 | 0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */ | ||
470 | 0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */ | ||
471 | 0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */ | ||
472 | 0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */ | ||
473 | 0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */ | ||
474 | 0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */ | ||
475 | 0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */ | ||
476 | 0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */ | ||
477 | 0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */ | ||
478 | 0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */ | ||
479 | 0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */ | ||
480 | 0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */ | ||
481 | 0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */ | ||
482 | 0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */ | ||
483 | 0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */ | ||
484 | 0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */ | ||
485 | 0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */ | ||
486 | 0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */ | ||
487 | 0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */ | ||
488 | 0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */ | ||
489 | 0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */ | ||
490 | 0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */ | ||
491 | 0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */ | ||
492 | 0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */ | ||
493 | 0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */ | ||
494 | 0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */ | ||
495 | 0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */ | ||
496 | 0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */ | ||
497 | 0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */ | ||
498 | 0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */ | ||
499 | 0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */ | ||
500 | 0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */ | ||
501 | 0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */ | ||
502 | }; | ||
503 | |||
504 | /* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */ | ||
505 | static u8 af9015_ir_table_kworld[] = { | ||
506 | 0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00, | ||
507 | 0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00, | ||
508 | 0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00, | ||
509 | 0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00, | ||
510 | 0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00, | ||
511 | 0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00, | ||
512 | 0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00, | ||
513 | 0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00, | ||
514 | 0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00, | ||
515 | 0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00, | ||
516 | 0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00, | ||
517 | 0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00, | ||
518 | 0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00, | ||
519 | 0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00, | ||
520 | 0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00, | ||
521 | 0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00, | ||
522 | 0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00, | ||
523 | 0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00, | ||
524 | 0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00, | ||
525 | 0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00, | ||
526 | 0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00, | ||
527 | 0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00, | ||
528 | 0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00, | ||
529 | 0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00, | ||
530 | 0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00, | ||
531 | 0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00, | ||
532 | 0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00, | ||
533 | 0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00, | ||
534 | 0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00, | ||
535 | 0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00, | ||
536 | 0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00, | ||
537 | 0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00, | ||
538 | 0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00, | ||
539 | 0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00, | ||
540 | 0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00, | ||
541 | 0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00, | ||
542 | 0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00, | ||
543 | 0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00, | ||
544 | 0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00, | ||
545 | 0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00, | ||
546 | 0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00, | ||
547 | 0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00, | ||
548 | 0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00, | ||
549 | 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00, | ||
550 | }; | ||
551 | |||
552 | /* AverMedia Volar X */ | ||
553 | static struct ir_scancode ir_codes_af9015_table_avermedia[] = { | ||
554 | { 0x053d, KEY_PROG1 }, /* SOURCE */ | ||
555 | { 0x0512, KEY_POWER }, /* POWER */ | ||
556 | { 0x051e, KEY_1 }, /* 1 */ | ||
557 | { 0x051f, KEY_2 }, /* 2 */ | ||
558 | { 0x0520, KEY_3 }, /* 3 */ | ||
559 | { 0x0521, KEY_4 }, /* 4 */ | ||
560 | { 0x0522, KEY_5 }, /* 5 */ | ||
561 | { 0x0523, KEY_6 }, /* 6 */ | ||
562 | { 0x0524, KEY_7 }, /* 7 */ | ||
563 | { 0x0525, KEY_8 }, /* 8 */ | ||
564 | { 0x0526, KEY_9 }, /* 9 */ | ||
565 | { 0x053f, KEY_LEFT }, /* L / DISPLAY */ | ||
566 | { 0x0527, KEY_0 }, /* 0 */ | ||
567 | { 0x050f, KEY_RIGHT }, /* R / CH RTN */ | ||
568 | { 0x0518, KEY_PROG2 }, /* SNAP SHOT */ | ||
569 | { 0x051c, KEY_PROG3 }, /* 16-CH PREV */ | ||
570 | { 0x052d, KEY_VOLUMEDOWN }, /* VOL DOWN */ | ||
571 | { 0x053e, KEY_ZOOM }, /* FULL SCREEN */ | ||
572 | { 0x052e, KEY_VOLUMEUP }, /* VOL UP */ | ||
573 | { 0x0510, KEY_MUTE }, /* MUTE */ | ||
574 | { 0x0504, KEY_AUDIO }, /* AUDIO */ | ||
575 | { 0x0515, KEY_RECORD }, /* RECORD */ | ||
576 | { 0x0511, KEY_PLAY }, /* PLAY */ | ||
577 | { 0x0516, KEY_STOP }, /* STOP */ | ||
578 | { 0x050c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ | ||
579 | { 0x0505, KEY_BACK }, /* << / RED */ | ||
580 | { 0x0509, KEY_FORWARD }, /* >> / YELLOW */ | ||
581 | { 0x0517, KEY_TEXT }, /* TELETEXT */ | ||
582 | { 0x050a, KEY_EPG }, /* EPG */ | ||
583 | { 0x0513, KEY_MENU }, /* MENU */ | ||
584 | |||
585 | { 0x050e, KEY_CHANNELUP }, /* CH UP */ | ||
586 | { 0x050d, KEY_CHANNELDOWN }, /* CH DOWN */ | ||
587 | { 0x0519, KEY_FIRST }, /* |<< / GREEN */ | ||
588 | { 0x0508, KEY_LAST }, /* >>| / BLUE */ | ||
589 | }; | ||
590 | |||
591 | static u8 af9015_ir_table_avermedia[] = { | ||
592 | 0x02, 0xfd, 0x00, 0xff, 0x12, 0x05, 0x00, | ||
593 | 0x02, 0xfd, 0x01, 0xfe, 0x3d, 0x05, 0x00, | ||
594 | 0x02, 0xfd, 0x03, 0xfc, 0x17, 0x05, 0x00, | ||
595 | 0x02, 0xfd, 0x04, 0xfb, 0x0a, 0x05, 0x00, | ||
596 | 0x02, 0xfd, 0x05, 0xfa, 0x1e, 0x05, 0x00, | ||
597 | 0x02, 0xfd, 0x06, 0xf9, 0x1f, 0x05, 0x00, | ||
598 | 0x02, 0xfd, 0x07, 0xf8, 0x20, 0x05, 0x00, | ||
599 | 0x02, 0xfd, 0x09, 0xf6, 0x21, 0x05, 0x00, | ||
600 | 0x02, 0xfd, 0x0a, 0xf5, 0x22, 0x05, 0x00, | ||
601 | 0x02, 0xfd, 0x0b, 0xf4, 0x23, 0x05, 0x00, | ||
602 | 0x02, 0xfd, 0x0d, 0xf2, 0x24, 0x05, 0x00, | ||
603 | 0x02, 0xfd, 0x0e, 0xf1, 0x25, 0x05, 0x00, | ||
604 | 0x02, 0xfd, 0x0f, 0xf0, 0x26, 0x05, 0x00, | ||
605 | 0x02, 0xfd, 0x11, 0xee, 0x27, 0x05, 0x00, | ||
606 | 0x02, 0xfd, 0x08, 0xf7, 0x04, 0x05, 0x00, | ||
607 | 0x02, 0xfd, 0x0c, 0xf3, 0x3e, 0x05, 0x00, | ||
608 | 0x02, 0xfd, 0x10, 0xef, 0x1c, 0x05, 0x00, | ||
609 | 0x02, 0xfd, 0x12, 0xed, 0x3f, 0x05, 0x00, | ||
610 | 0x02, 0xfd, 0x13, 0xec, 0x0f, 0x05, 0x00, | ||
611 | 0x02, 0xfd, 0x14, 0xeb, 0x10, 0x05, 0x00, | ||
612 | 0x02, 0xfd, 0x15, 0xea, 0x13, 0x05, 0x00, | ||
613 | 0x02, 0xfd, 0x17, 0xe8, 0x18, 0x05, 0x00, | ||
614 | 0x02, 0xfd, 0x18, 0xe7, 0x11, 0x05, 0x00, | ||
615 | 0x02, 0xfd, 0x19, 0xe6, 0x15, 0x05, 0x00, | ||
616 | 0x02, 0xfd, 0x1a, 0xe5, 0x0c, 0x05, 0x00, | ||
617 | 0x02, 0xfd, 0x1b, 0xe4, 0x16, 0x05, 0x00, | ||
618 | 0x02, 0xfd, 0x1c, 0xe3, 0x09, 0x05, 0x00, | ||
619 | 0x02, 0xfd, 0x1d, 0xe2, 0x05, 0x05, 0x00, | ||
620 | 0x02, 0xfd, 0x1e, 0xe1, 0x2d, 0x05, 0x00, | ||
621 | 0x02, 0xfd, 0x1f, 0xe0, 0x2e, 0x05, 0x00, | ||
622 | 0x03, 0xfc, 0x00, 0xff, 0x08, 0x05, 0x00, | ||
623 | 0x03, 0xfc, 0x01, 0xfe, 0x19, 0x05, 0x00, | ||
624 | 0x03, 0xfc, 0x02, 0xfd, 0x0d, 0x05, 0x00, | ||
625 | 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00, | ||
626 | }; | ||
627 | |||
628 | static u8 af9015_ir_table_avermedia_ks[] = { | ||
629 | 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00, | ||
630 | 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00, | ||
631 | 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00, | ||
632 | 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00, | ||
633 | 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00, | ||
634 | 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00, | ||
635 | 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00, | ||
636 | 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00, | ||
637 | 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00, | ||
638 | 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00, | ||
639 | 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00, | ||
640 | 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00, | ||
641 | 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00, | ||
642 | 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00, | ||
643 | 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00, | ||
644 | 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00, | ||
645 | 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00, | ||
646 | 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00, | ||
647 | 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00, | ||
648 | 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00, | ||
649 | 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00, | ||
650 | 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00, | ||
651 | 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00, | ||
652 | 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00, | ||
653 | 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00, | ||
654 | 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00, | ||
655 | 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00 | ||
656 | }; | ||
657 | |||
658 | /* Digittrade DVB-T USB Stick */ | ||
659 | static struct ir_scancode ir_codes_af9015_table_digittrade[] = { | ||
660 | { 0x010f, KEY_LAST }, /* RETURN */ | ||
661 | { 0x0517, KEY_TEXT }, /* TELETEXT */ | ||
662 | { 0x0108, KEY_EPG }, /* EPG */ | ||
663 | { 0x0513, KEY_POWER }, /* POWER */ | ||
664 | { 0x0109, KEY_ZOOM }, /* FULLSCREEN */ | ||
665 | { 0x0040, KEY_AUDIO }, /* DUAL SOUND */ | ||
666 | { 0x002c, KEY_PRINT }, /* SNAPSHOT */ | ||
667 | { 0x0516, KEY_SUBTITLE }, /* SUBTITLE */ | ||
668 | { 0x0052, KEY_CHANNELUP }, /* CH Up */ | ||
669 | { 0x0051, KEY_CHANNELDOWN },/* Ch Dn */ | ||
670 | { 0x0057, KEY_VOLUMEUP }, /* Vol Up */ | ||
671 | { 0x0056, KEY_VOLUMEDOWN }, /* Vol Dn */ | ||
672 | { 0x0110, KEY_MUTE }, /* MUTE */ | ||
673 | { 0x0027, KEY_0 }, | ||
674 | { 0x001e, KEY_1 }, | ||
675 | { 0x001f, KEY_2 }, | ||
676 | { 0x0020, KEY_3 }, | ||
677 | { 0x0021, KEY_4 }, | ||
678 | { 0x0022, KEY_5 }, | ||
679 | { 0x0023, KEY_6 }, | ||
680 | { 0x0024, KEY_7 }, | ||
681 | { 0x0025, KEY_8 }, | ||
682 | { 0x0026, KEY_9 }, | ||
683 | { 0x0117, KEY_PLAYPAUSE }, /* TIMESHIFT */ | ||
684 | { 0x0115, KEY_RECORD }, /* RECORD */ | ||
685 | { 0x0313, KEY_PLAY }, /* PLAY */ | ||
686 | { 0x0116, KEY_STOP }, /* STOP */ | ||
687 | { 0x0113, KEY_PAUSE }, /* PAUSE */ | ||
688 | }; | ||
689 | |||
690 | static u8 af9015_ir_table_digittrade[] = { | ||
691 | 0x00, 0xff, 0x06, 0xf9, 0x13, 0x05, 0x00, | ||
692 | 0x00, 0xff, 0x4d, 0xb2, 0x17, 0x01, 0x00, | ||
693 | 0x00, 0xff, 0x1f, 0xe0, 0x2c, 0x00, 0x00, | ||
694 | 0x00, 0xff, 0x0a, 0xf5, 0x15, 0x01, 0x00, | ||
695 | 0x00, 0xff, 0x0e, 0xf1, 0x16, 0x01, 0x00, | ||
696 | 0x00, 0xff, 0x09, 0xf6, 0x09, 0x01, 0x00, | ||
697 | 0x00, 0xff, 0x01, 0xfe, 0x08, 0x01, 0x00, | ||
698 | 0x00, 0xff, 0x05, 0xfa, 0x10, 0x01, 0x00, | ||
699 | 0x00, 0xff, 0x02, 0xfd, 0x56, 0x00, 0x00, | ||
700 | 0x00, 0xff, 0x40, 0xbf, 0x57, 0x00, 0x00, | ||
701 | 0x00, 0xff, 0x19, 0xe6, 0x52, 0x00, 0x00, | ||
702 | 0x00, 0xff, 0x17, 0xe8, 0x51, 0x00, 0x00, | ||
703 | 0x00, 0xff, 0x10, 0xef, 0x0f, 0x01, 0x00, | ||
704 | 0x00, 0xff, 0x54, 0xab, 0x27, 0x00, 0x00, | ||
705 | 0x00, 0xff, 0x1b, 0xe4, 0x1e, 0x00, 0x00, | ||
706 | 0x00, 0xff, 0x11, 0xee, 0x1f, 0x00, 0x00, | ||
707 | 0x00, 0xff, 0x15, 0xea, 0x20, 0x00, 0x00, | ||
708 | 0x00, 0xff, 0x12, 0xed, 0x21, 0x00, 0x00, | ||
709 | 0x00, 0xff, 0x16, 0xe9, 0x22, 0x00, 0x00, | ||
710 | 0x00, 0xff, 0x4c, 0xb3, 0x23, 0x00, 0x00, | ||
711 | 0x00, 0xff, 0x48, 0xb7, 0x24, 0x00, 0x00, | ||
712 | 0x00, 0xff, 0x04, 0xfb, 0x25, 0x00, 0x00, | ||
713 | 0x00, 0xff, 0x00, 0xff, 0x26, 0x00, 0x00, | ||
714 | 0x00, 0xff, 0x1e, 0xe1, 0x13, 0x03, 0x00, | ||
715 | 0x00, 0xff, 0x1a, 0xe5, 0x13, 0x01, 0x00, | ||
716 | 0x00, 0xff, 0x03, 0xfc, 0x17, 0x05, 0x00, | ||
717 | 0x00, 0xff, 0x0d, 0xf2, 0x16, 0x05, 0x00, | ||
718 | 0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00, | ||
719 | }; | ||
720 | |||
721 | /* TREKSTOR DVB-T USB Stick */ | ||
722 | static struct ir_scancode ir_codes_af9015_table_trekstor[] = { | ||
723 | { 0x0704, KEY_AGAIN }, /* Home */ | ||
724 | { 0x0705, KEY_MUTE }, /* Mute */ | ||
725 | { 0x0706, KEY_UP }, /* Up */ | ||
726 | { 0x0707, KEY_DOWN }, /* Down */ | ||
727 | { 0x0709, KEY_RIGHT }, /* Right */ | ||
728 | { 0x070a, KEY_ENTER }, /* OK */ | ||
729 | { 0x070b, KEY_FASTFORWARD }, /* Fast forward */ | ||
730 | { 0x070c, KEY_REWIND }, /* Rewind */ | ||
731 | { 0x070d, KEY_PLAY }, /* Play/Pause */ | ||
732 | { 0x070e, KEY_VOLUMEUP }, /* Volume + */ | ||
733 | { 0x070f, KEY_VOLUMEDOWN }, /* Volume - */ | ||
734 | { 0x0710, KEY_RECORD }, /* Record */ | ||
735 | { 0x0711, KEY_STOP }, /* Stop */ | ||
736 | { 0x0712, KEY_ZOOM }, /* TV */ | ||
737 | { 0x0713, KEY_EPG }, /* Info/EPG */ | ||
738 | { 0x0714, KEY_CHANNELDOWN }, /* Channel - */ | ||
739 | { 0x0715, KEY_CHANNELUP }, /* Channel + */ | ||
740 | { 0x071e, KEY_1 }, | ||
741 | { 0x071f, KEY_2 }, | ||
742 | { 0x0720, KEY_3 }, | ||
743 | { 0x0721, KEY_4 }, | ||
744 | { 0x0722, KEY_5 }, | ||
745 | { 0x0723, KEY_6 }, | ||
746 | { 0x0724, KEY_7 }, | ||
747 | { 0x0725, KEY_8 }, | ||
748 | { 0x0726, KEY_9 }, | ||
749 | { 0x0708, KEY_LEFT }, /* LEFT */ | ||
750 | { 0x0727, KEY_0 }, | ||
751 | }; | ||
752 | |||
753 | static u8 af9015_ir_table_trekstor[] = { | ||
754 | 0x00, 0xff, 0x86, 0x79, 0x04, 0x07, 0x00, | ||
755 | 0x00, 0xff, 0x85, 0x7a, 0x05, 0x07, 0x00, | ||
756 | 0x00, 0xff, 0x87, 0x78, 0x06, 0x07, 0x00, | ||
757 | 0x00, 0xff, 0x8c, 0x73, 0x07, 0x07, 0x00, | ||
758 | 0x00, 0xff, 0x89, 0x76, 0x09, 0x07, 0x00, | ||
759 | 0x00, 0xff, 0x88, 0x77, 0x0a, 0x07, 0x00, | ||
760 | 0x00, 0xff, 0x8a, 0x75, 0x0b, 0x07, 0x00, | ||
761 | 0x00, 0xff, 0x9e, 0x61, 0x0c, 0x07, 0x00, | ||
762 | 0x00, 0xff, 0x8d, 0x72, 0x0d, 0x07, 0x00, | ||
763 | 0x00, 0xff, 0x8b, 0x74, 0x0e, 0x07, 0x00, | ||
764 | 0x00, 0xff, 0x9b, 0x64, 0x0f, 0x07, 0x00, | ||
765 | 0x00, 0xff, 0x9d, 0x62, 0x10, 0x07, 0x00, | ||
766 | 0x00, 0xff, 0x8e, 0x71, 0x11, 0x07, 0x00, | ||
767 | 0x00, 0xff, 0x9c, 0x63, 0x12, 0x07, 0x00, | ||
768 | 0x00, 0xff, 0x8f, 0x70, 0x13, 0x07, 0x00, | ||
769 | 0x00, 0xff, 0x93, 0x6c, 0x14, 0x07, 0x00, | ||
770 | 0x00, 0xff, 0x97, 0x68, 0x15, 0x07, 0x00, | ||
771 | 0x00, 0xff, 0x92, 0x6d, 0x1e, 0x07, 0x00, | ||
772 | 0x00, 0xff, 0x96, 0x69, 0x1f, 0x07, 0x00, | ||
773 | 0x00, 0xff, 0x9a, 0x65, 0x20, 0x07, 0x00, | ||
774 | 0x00, 0xff, 0x91, 0x6e, 0x21, 0x07, 0x00, | ||
775 | 0x00, 0xff, 0x95, 0x6a, 0x22, 0x07, 0x00, | ||
776 | 0x00, 0xff, 0x99, 0x66, 0x23, 0x07, 0x00, | ||
777 | 0x00, 0xff, 0x90, 0x6f, 0x24, 0x07, 0x00, | ||
778 | 0x00, 0xff, 0x94, 0x6b, 0x25, 0x07, 0x00, | ||
779 | 0x00, 0xff, 0x98, 0x67, 0x26, 0x07, 0x00, | ||
780 | 0x00, 0xff, 0x9f, 0x60, 0x08, 0x07, 0x00, | ||
781 | 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00, | ||
782 | }; | ||
783 | |||
784 | /* MSI DIGIVOX mini III */ | ||
785 | static struct ir_scancode ir_codes_af9015_table_msi_digivox_iii[] = { | ||
786 | { 0x0713, KEY_POWER }, /* [red power button] */ | ||
787 | { 0x073b, KEY_VIDEO }, /* Source */ | ||
788 | { 0x073e, KEY_ZOOM }, /* Zoom */ | ||
789 | { 0x070b, KEY_POWER2 }, /* ShutDown */ | ||
790 | { 0x071e, KEY_1 }, | ||
791 | { 0x071f, KEY_2 }, | ||
792 | { 0x0720, KEY_3 }, | ||
793 | { 0x0721, KEY_4 }, | ||
794 | { 0x0722, KEY_5 }, | ||
795 | { 0x0723, KEY_6 }, | ||
796 | { 0x0724, KEY_7 }, | ||
797 | { 0x0725, KEY_8 }, | ||
798 | { 0x0726, KEY_9 }, | ||
799 | { 0x0727, KEY_0 }, | ||
800 | { 0x0752, KEY_CHANNELUP }, /* CH+ */ | ||
801 | { 0x0751, KEY_CHANNELDOWN }, /* CH- */ | ||
802 | { 0x0750, KEY_VOLUMEUP }, /* Vol+ */ | ||
803 | { 0x074f, KEY_VOLUMEDOWN }, /* Vol- */ | ||
804 | { 0x0705, KEY_ESC }, /* [back up arrow] */ | ||
805 | { 0x0708, KEY_OK }, /* [enter arrow] */ | ||
806 | { 0x073f, KEY_RECORD }, /* Rec */ | ||
807 | { 0x0716, KEY_STOP }, /* Stop */ | ||
808 | { 0x072a, KEY_PLAY }, /* Play */ | ||
809 | { 0x073c, KEY_MUTE }, /* Mute */ | ||
810 | { 0x0718, KEY_UP }, | ||
811 | { 0x0707, KEY_DOWN }, | ||
812 | { 0x070f, KEY_LEFT }, | ||
813 | { 0x0715, KEY_RIGHT }, | ||
814 | { 0x0736, KEY_RED }, | ||
815 | { 0x0737, KEY_GREEN }, | ||
816 | { 0x072d, KEY_YELLOW }, | ||
817 | { 0x072e, KEY_BLUE }, | ||
818 | }; | ||
819 | |||
820 | static u8 af9015_ir_table_msi_digivox_iii[] = { | ||
821 | 0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */ | ||
822 | 0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */ | ||
823 | 0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */ | ||
824 | 0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */ | ||
825 | 0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */ | ||
826 | 0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */ | ||
827 | 0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */ | ||
828 | 0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */ | ||
829 | 0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */ | ||
830 | 0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */ | ||
831 | 0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */ | ||
832 | 0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */ | ||
833 | 0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */ | ||
834 | 0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */ | ||
835 | 0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */ | ||
836 | 0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */ | ||
837 | 0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */ | ||
838 | 0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */ | ||
839 | 0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */ | ||
840 | 0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */ | ||
841 | 0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */ | ||
842 | 0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */ | ||
843 | 0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */ | ||
844 | 0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */ | ||
845 | 0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */ | ||
846 | 0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */ | ||
847 | 0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */ | ||
848 | 0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */ | ||
849 | 0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */ | ||
850 | 0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */ | ||
851 | 0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */ | ||
852 | 0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */ | ||
853 | }; | ||
854 | |||
855 | #endif | 124 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 4685259e161..1759d26bca4 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
@@ -354,7 +354,7 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
354 | static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | 354 | static int anysee_tuner_attach(struct dvb_usb_adapter *adap) |
355 | { | 355 | { |
356 | struct anysee_state *state = adap->dev->priv; | 356 | struct anysee_state *state = adap->dev->priv; |
357 | deb_info("%s: \n", __func__); | 357 | deb_info("%s:\n", __func__); |
358 | 358 | ||
359 | switch (state->tuner) { | 359 | switch (state->tuner) { |
360 | case DVB_PLL_THOMSON_DTT7579: | 360 | case DVB_PLL_THOMSON_DTT7579: |
@@ -374,78 +374,32 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | |||
374 | return 0; | 374 | return 0; |
375 | } | 375 | } |
376 | 376 | ||
377 | static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 377 | static int anysee_rc_query(struct dvb_usb_device *d) |
378 | { | 378 | { |
379 | u8 buf[] = {CMD_GET_IR_CODE}; | 379 | u8 buf[] = {CMD_GET_IR_CODE}; |
380 | struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; | ||
381 | u8 ircode[2]; | 380 | u8 ircode[2]; |
382 | int i, ret; | 381 | int ret; |
382 | |||
383 | /* Remote controller is basic NEC using address byte 0x08. | ||
384 | Anysee device RC query returns only two bytes, status and code, | ||
385 | address byte is dropped. Also it does not return any value for | ||
386 | NEC RCs having address byte other than 0x08. Due to that, we | ||
387 | cannot use that device as standard NEC receiver. | ||
388 | It could be possible make hack which reads whole code directly | ||
389 | from device memory... */ | ||
383 | 390 | ||
384 | ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2); | 391 | ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode)); |
385 | if (ret) | 392 | if (ret) |
386 | return ret; | 393 | return ret; |
387 | 394 | ||
388 | *event = 0; | 395 | if (ircode[0]) { |
389 | *state = REMOTE_NO_KEY_PRESSED; | 396 | deb_rc("%s: key pressed %02x\n", __func__, ircode[1]); |
390 | 397 | ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0); | |
391 | for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { | ||
392 | if (rc5_custom(&keymap[i]) == ircode[0] && | ||
393 | rc5_data(&keymap[i]) == ircode[1]) { | ||
394 | *event = keymap[i].keycode; | ||
395 | *state = REMOTE_KEY_PRESSED; | ||
396 | return 0; | ||
397 | } | ||
398 | } | 398 | } |
399 | |||
399 | return 0; | 400 | return 0; |
400 | } | 401 | } |
401 | 402 | ||
402 | static struct ir_scancode ir_codes_anysee_table[] = { | ||
403 | { 0x0100, KEY_0 }, | ||
404 | { 0x0101, KEY_1 }, | ||
405 | { 0x0102, KEY_2 }, | ||
406 | { 0x0103, KEY_3 }, | ||
407 | { 0x0104, KEY_4 }, | ||
408 | { 0x0105, KEY_5 }, | ||
409 | { 0x0106, KEY_6 }, | ||
410 | { 0x0107, KEY_7 }, | ||
411 | { 0x0108, KEY_8 }, | ||
412 | { 0x0109, KEY_9 }, | ||
413 | { 0x010a, KEY_POWER }, | ||
414 | { 0x010b, KEY_DOCUMENTS }, /* * */ | ||
415 | { 0x0119, KEY_FAVORITES }, | ||
416 | { 0x0120, KEY_SLEEP }, | ||
417 | { 0x0121, KEY_MODE }, /* 4:3 / 16:9 select */ | ||
418 | { 0x0122, KEY_ZOOM }, | ||
419 | { 0x0147, KEY_TEXT }, | ||
420 | { 0x0116, KEY_TV }, /* TV / radio select */ | ||
421 | { 0x011e, KEY_LANGUAGE }, /* Second Audio Program */ | ||
422 | { 0x011a, KEY_SUBTITLE }, | ||
423 | { 0x011b, KEY_CAMERA }, /* screenshot */ | ||
424 | { 0x0142, KEY_MUTE }, | ||
425 | { 0x010e, KEY_MENU }, | ||
426 | { 0x010f, KEY_EPG }, | ||
427 | { 0x0117, KEY_INFO }, | ||
428 | { 0x0110, KEY_EXIT }, | ||
429 | { 0x0113, KEY_VOLUMEUP }, | ||
430 | { 0x0112, KEY_VOLUMEDOWN }, | ||
431 | { 0x0111, KEY_CHANNELUP }, | ||
432 | { 0x0114, KEY_CHANNELDOWN }, | ||
433 | { 0x0115, KEY_OK }, | ||
434 | { 0x011d, KEY_RED }, | ||
435 | { 0x011f, KEY_GREEN }, | ||
436 | { 0x011c, KEY_YELLOW }, | ||
437 | { 0x0144, KEY_BLUE }, | ||
438 | { 0x010c, KEY_SHUFFLE }, /* snapshot */ | ||
439 | { 0x0148, KEY_STOP }, | ||
440 | { 0x0150, KEY_PLAY }, | ||
441 | { 0x0151, KEY_PAUSE }, | ||
442 | { 0x0149, KEY_RECORD }, | ||
443 | { 0x0118, KEY_PREVIOUS }, /* |<< */ | ||
444 | { 0x010d, KEY_NEXT }, /* >>| */ | ||
445 | { 0x0124, KEY_PROG1 }, /* F1 */ | ||
446 | { 0x0125, KEY_PROG2 }, /* F2 */ | ||
447 | }; | ||
448 | |||
449 | /* DVB USB Driver stuff */ | 403 | /* DVB USB Driver stuff */ |
450 | static struct dvb_usb_device_properties anysee_properties; | 404 | static struct dvb_usb_device_properties anysee_properties; |
451 | 405 | ||
@@ -520,11 +474,12 @@ static struct dvb_usb_device_properties anysee_properties = { | |||
520 | } | 474 | } |
521 | }, | 475 | }, |
522 | 476 | ||
523 | .rc.legacy = { | 477 | .rc.core = { |
524 | .rc_key_map = ir_codes_anysee_table, | 478 | .rc_codes = RC_MAP_ANYSEE, |
525 | .rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table), | 479 | .protocol = IR_TYPE_OTHER, |
480 | .module_name = "anysee", | ||
526 | .rc_query = anysee_rc_query, | 481 | .rc_query = anysee_rc_query, |
527 | .rc_interval = 200, /* windows driver uses 500ms */ | 482 | .rc_interval = 250, /* windows driver uses 500ms */ |
528 | }, | 483 | }, |
529 | 484 | ||
530 | .i2c_algo = &anysee_i2c_algo, | 485 | .i2c_algo = &anysee_i2c_algo, |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index cead089bbb4..88e4a62abc4 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | |||
@@ -20,7 +20,6 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) | |||
20 | } | 20 | } |
21 | 21 | ||
22 | strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); | 22 | strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); |
23 | d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, | ||
24 | d->i2c_adap.algo = d->props.i2c_algo; | 23 | d->i2c_adap.algo = d->props.i2c_algo; |
25 | d->i2c_adap.algo_data = NULL; | 24 | d->i2c_adap.algo_data = NULL; |
26 | d->i2c_adap.dev.parent = &d->udev->dev; | 25 | d->i2c_adap.dev.parent = &d->udev->dev; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 1a774d58d66..192a40ce583 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #define USB_VID_EMPIA 0xeb1a | 32 | #define USB_VID_EMPIA 0xeb1a |
33 | #define USB_VID_GENPIX 0x09c0 | 33 | #define USB_VID_GENPIX 0x09c0 |
34 | #define USB_VID_GRANDTEC 0x5032 | 34 | #define USB_VID_GRANDTEC 0x5032 |
35 | #define USB_VID_GTEK 0x1f4d | ||
35 | #define USB_VID_HANFTEK 0x15f4 | 36 | #define USB_VID_HANFTEK 0x15f4 |
36 | #define USB_VID_HAUPPAUGE 0x2040 | 37 | #define USB_VID_HAUPPAUGE 0x2040 |
37 | #define USB_VID_HYPER_PALTEK 0x1025 | 38 | #define USB_VID_HYPER_PALTEK 0x1025 |
@@ -133,6 +134,8 @@ | |||
133 | #define USB_PID_KWORLD_VSTREAM_WARM 0x17df | 134 | #define USB_PID_KWORLD_VSTREAM_WARM 0x17df |
134 | #define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 | 135 | #define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 |
135 | #define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069 | 136 | #define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069 |
137 | #define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097 | ||
138 | #define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099 | ||
136 | #define USB_PID_TWINHAN_VP7041_COLD 0x3201 | 139 | #define USB_PID_TWINHAN_VP7041_COLD 0x3201 |
137 | #define USB_PID_TWINHAN_VP7041_WARM 0x3202 | 140 | #define USB_PID_TWINHAN_VP7041_WARM 0x3202 |
138 | #define USB_PID_TWINHAN_VP7020_COLD 0x3203 | 141 | #define USB_PID_TWINHAN_VP7020_COLD 0x3203 |
@@ -143,6 +146,7 @@ | |||
143 | #define USB_PID_TWINHAN_VP7021_WARM 0x3208 | 146 | #define USB_PID_TWINHAN_VP7021_WARM 0x3208 |
144 | #define USB_PID_TINYTWIN 0x3226 | 147 | #define USB_PID_TINYTWIN 0x3226 |
145 | #define USB_PID_TINYTWIN_2 0xe402 | 148 | #define USB_PID_TINYTWIN_2 0xe402 |
149 | #define USB_PID_TINYTWIN_3 0x9016 | ||
146 | #define USB_PID_DNTV_TINYUSB2_COLD 0x3223 | 150 | #define USB_PID_DNTV_TINYUSB2_COLD 0x3223 |
147 | #define USB_PID_DNTV_TINYUSB2_WARM 0x3224 | 151 | #define USB_PID_DNTV_TINYUSB2_WARM 0x3224 |
148 | #define USB_PID_ULTIMA_TVBOX_COLD 0x8105 | 152 | #define USB_PID_ULTIMA_TVBOX_COLD 0x8105 |
@@ -196,6 +200,7 @@ | |||
196 | #define USB_PID_AVERMEDIA_A309 0xa309 | 200 | #define USB_PID_AVERMEDIA_A309 0xa309 |
197 | #define USB_PID_AVERMEDIA_A310 0xa310 | 201 | #define USB_PID_AVERMEDIA_A310 0xa310 |
198 | #define USB_PID_AVERMEDIA_A850 0x850a | 202 | #define USB_PID_AVERMEDIA_A850 0x850a |
203 | #define USB_PID_AVERMEDIA_A850T 0x850b | ||
199 | #define USB_PID_AVERMEDIA_A805 0xa805 | 204 | #define USB_PID_AVERMEDIA_A805 0xa805 |
200 | #define USB_PID_AVERMEDIA_A815M 0x815a | 205 | #define USB_PID_AVERMEDIA_A815M 0x815a |
201 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 | 206 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 |
@@ -268,6 +273,7 @@ | |||
268 | #define USB_PID_GENPIX_8PSK_REV_2 0x0202 | 273 | #define USB_PID_GENPIX_8PSK_REV_2 0x0202 |
269 | #define USB_PID_GENPIX_SKYWALKER_1 0x0203 | 274 | #define USB_PID_GENPIX_SKYWALKER_1 0x0203 |
270 | #define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204 | 275 | #define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204 |
276 | #define USB_PID_GENPIX_SKYWALKER_2 0x0206 | ||
271 | #define USB_PID_SIGMATEK_DVB_110 0x6610 | 277 | #define USB_PID_SIGMATEK_DVB_110 0x6610 |
272 | #define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 | 278 | #define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 |
273 | #define USB_PID_MSI_DIGIVOX_DUO 0x8801 | 279 | #define USB_PID_MSI_DIGIVOX_DUO 0x8801 |
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index 93c21ddd0b7..015b4e8af1a 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c | |||
@@ -75,7 +75,7 @@ static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state, | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len) | 78 | static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len) |
79 | { | 79 | { |
80 | struct jdvbt90502_state *state = fe->demodulator_priv; | 80 | struct jdvbt90502_state *state = fe->demodulator_priv; |
81 | int err, i; | 81 | int err, i; |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index dbdb5347b2a..60d11e57e7d 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c | |||
@@ -109,7 +109,7 @@ static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength | |||
109 | 109 | ||
110 | static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) | 110 | static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) |
111 | { | 111 | { |
112 | tune->min_delay_ms = 200; | 112 | tune->min_delay_ms = 800; |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
@@ -334,7 +334,7 @@ success: | |||
334 | 334 | ||
335 | static struct dvb_frontend_ops gp8psk_fe_ops = { | 335 | static struct dvb_frontend_ops gp8psk_fe_ops = { |
336 | .info = { | 336 | .info = { |
337 | .name = "Genpix 8psk-to-USB2 DVB-S", | 337 | .name = "Genpix DVB-S", |
338 | .type = FE_QPSK, | 338 | .type = FE_QPSK, |
339 | .frequency_min = 800000, | 339 | .frequency_min = 800000, |
340 | .frequency_max = 2250000, | 340 | .frequency_max = 2250000, |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 45106ac4967..c821293dbc2 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c | |||
@@ -227,6 +227,7 @@ static struct usb_device_id gp8psk_usb_table [] = { | |||
227 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, | 227 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, |
228 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, | 228 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, |
229 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, | 229 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, |
230 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) }, | ||
230 | /* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */ | 231 | /* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */ |
231 | { 0 }, | 232 | { 0 }, |
232 | }; | 233 | }; |
@@ -258,7 +259,7 @@ static struct dvb_usb_device_properties gp8psk_properties = { | |||
258 | 259 | ||
259 | .generic_bulk_ctrl_endpoint = 0x01, | 260 | .generic_bulk_ctrl_endpoint = 0x01, |
260 | 261 | ||
261 | .num_device_descs = 3, | 262 | .num_device_descs = 4, |
262 | .devices = { | 263 | .devices = { |
263 | { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", | 264 | { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", |
264 | .cold_ids = { &gp8psk_usb_table[0], NULL }, | 265 | .cold_ids = { &gp8psk_usb_table[0], NULL }, |
@@ -272,6 +273,10 @@ static struct dvb_usb_device_properties gp8psk_properties = { | |||
272 | .cold_ids = { NULL }, | 273 | .cold_ids = { NULL }, |
273 | .warm_ids = { &gp8psk_usb_table[3], NULL }, | 274 | .warm_ids = { &gp8psk_usb_table[3], NULL }, |
274 | }, | 275 | }, |
276 | { .name = "Genpix SkyWalker-2 DVB-S receiver", | ||
277 | .cold_ids = { NULL }, | ||
278 | .warm_ids = { &gp8psk_usb_table[4], NULL }, | ||
279 | }, | ||
275 | { NULL }, | 280 | { NULL }, |
276 | } | 281 | } |
277 | }; | 282 | }; |
@@ -306,6 +311,6 @@ module_init(gp8psk_usb_module_init); | |||
306 | module_exit(gp8psk_usb_module_exit); | 311 | module_exit(gp8psk_usb_module_exit); |
307 | 312 | ||
308 | MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); | 313 | MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); |
309 | MODULE_DESCRIPTION("Driver for Genpix 8psk-to-USB2 DVB-S"); | 314 | MODULE_DESCRIPTION("Driver for Genpix DVB-S"); |
310 | MODULE_VERSION("1.1"); | 315 | MODULE_VERSION("1.1"); |
311 | MODULE_LICENSE("GPL"); | 316 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c new file mode 100644 index 00000000000..d939fbbf9fe --- /dev/null +++ b/drivers/media/dvb/dvb-usb/lmedm04.c | |||
@@ -0,0 +1,1088 @@ | |||
1 | /* DVB USB compliant linux driver for | ||
2 | * | ||
3 | * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 | ||
4 | * LME2510C + LG TDQY-P001F | ||
5 | * LME2510 + LG TDQY-P001F | ||
6 | * | ||
7 | * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) | ||
8 | * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) | ||
9 | * | ||
10 | * MV001F (LME2510+LGTDQY-P001F) | ||
11 | * LG TDQY - P001F =(TDA8263 + TDA10086H) | ||
12 | * | ||
13 | * MVB0001F (LME2510C+LGTDQT-P001F) | ||
14 | * | ||
15 | * For firmware see Documentation/dvb/lmedm04.txt | ||
16 | * | ||
17 | * I2C addresses: | ||
18 | * 0xd0 - STV0288 - Demodulator | ||
19 | * 0xc0 - Sharp IX2505V - Tuner | ||
20 | * --or-- | ||
21 | * 0x1c - TDA10086 - Demodulator | ||
22 | * 0xc0 - TDA8263 - Tuner | ||
23 | * | ||
24 | * ***Please Note*** | ||
25 | * There are other variants of the DM04 | ||
26 | * ***NOT SUPPORTED*** | ||
27 | * MV0194 (LME2510+SHARP0194) | ||
28 | * MVB0194 (LME2510C+SHARP0194) | ||
29 | * | ||
30 | * | ||
31 | * VID = 3344 PID LME2510=1122 LME2510C=1120 | ||
32 | * | ||
33 | * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com) | ||
34 | * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd. | ||
35 | * | ||
36 | * This program is free software; you can redistribute it and/or modify | ||
37 | * it under the terms of the GNU General Public License Version 2, as | ||
38 | * published by the Free Software Foundation. | ||
39 | * | ||
40 | * This program is distributed in the hope that it will be useful, | ||
41 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
42 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
43 | * GNU General Public License for more details. | ||
44 | * | ||
45 | * You should have received a copy of the GNU General Public License | ||
46 | * along with this program; if not, write to the Free Software | ||
47 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
48 | * | ||
49 | * | ||
50 | * see Documentation/dvb/README.dvb-usb for more information | ||
51 | * | ||
52 | * Known Issues : | ||
53 | * LME2510: Non Intel USB chipsets fail to maintain High Speed on | ||
54 | * Boot or Hot Plug. | ||
55 | * | ||
56 | * QQbox suffers from noise on LNB voltage. | ||
57 | * | ||
58 | * PID functions have been removed from this driver version due to | ||
59 | * problems with different firmware and application versions. | ||
60 | */ | ||
61 | #define DVB_USB_LOG_PREFIX "LME2510(C)" | ||
62 | #include <linux/usb.h> | ||
63 | #include <linux/usb/input.h> | ||
64 | #include <media/ir-core.h> | ||
65 | |||
66 | #include "dvb-usb.h" | ||
67 | #include "lmedm04.h" | ||
68 | #include "tda826x.h" | ||
69 | #include "tda10086.h" | ||
70 | #include "stv0288.h" | ||
71 | #include "ix2505v.h" | ||
72 | |||
73 | |||
74 | |||
75 | /* debug */ | ||
76 | static int dvb_usb_lme2510_debug; | ||
77 | #define l_dprintk(var, level, args...) do { \ | ||
78 | if ((var >= level)) \ | ||
79 | printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \ | ||
80 | } while (0) | ||
81 | |||
82 | #define deb_info(level, args...) l_dprintk(dvb_usb_lme2510_debug, level, args) | ||
83 | #define debug_data_snipet(level, name, p) \ | ||
84 | deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \ | ||
85 | *p, *(p+1), *(p+2), *(p+3), *(p+4), \ | ||
86 | *(p+5), *(p+6), *(p+7)); | ||
87 | |||
88 | |||
89 | module_param_named(debug, dvb_usb_lme2510_debug, int, 0644); | ||
90 | MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." | ||
91 | DVB_USB_DEBUG_STATUS); | ||
92 | |||
93 | static int dvb_usb_lme2510_firmware; | ||
94 | module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644); | ||
95 | MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG"); | ||
96 | |||
97 | |||
98 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
99 | #define TUNER_LG 0x1 | ||
100 | #define TUNER_S7395 0x2 | ||
101 | |||
102 | struct lme2510_state { | ||
103 | u8 id; | ||
104 | u8 tuner_config; | ||
105 | u8 signal_lock; | ||
106 | u8 signal_level; | ||
107 | u8 signal_sn; | ||
108 | u8 time_key; | ||
109 | u8 i2c_talk_onoff; | ||
110 | u8 i2c_gate; | ||
111 | u8 i2c_tuner_gate_w; | ||
112 | u8 i2c_tuner_gate_r; | ||
113 | u8 i2c_tuner_addr; | ||
114 | u8 stream_on; | ||
115 | u8 one_tune; | ||
116 | void *buffer; | ||
117 | struct urb *lme_urb; | ||
118 | void *usb_buffer; | ||
119 | |||
120 | }; | ||
121 | |||
122 | static int lme2510_bulk_write(struct usb_device *dev, | ||
123 | u8 *snd, int len, u8 pipe) | ||
124 | { | ||
125 | int ret, actual_l; | ||
126 | |||
127 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), | ||
128 | snd, len , &actual_l, 500); | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | static int lme2510_bulk_read(struct usb_device *dev, | ||
133 | u8 *rev, int len, u8 pipe) | ||
134 | { | ||
135 | int ret, actual_l; | ||
136 | |||
137 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), | ||
138 | rev, len , &actual_l, 500); | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | static int lme2510_usb_talk(struct dvb_usb_device *d, | ||
143 | u8 *wbuf, int wlen, u8 *rbuf, int rlen) | ||
144 | { | ||
145 | struct lme2510_state *st = d->priv; | ||
146 | u8 *buff; | ||
147 | int ret = 0; | ||
148 | |||
149 | if (st->usb_buffer == NULL) { | ||
150 | st->usb_buffer = kmalloc(512, GFP_KERNEL); | ||
151 | if (st->usb_buffer == NULL) { | ||
152 | info("MEM Error no memory"); | ||
153 | return -ENOMEM; | ||
154 | } | ||
155 | } | ||
156 | buff = st->usb_buffer; | ||
157 | |||
158 | /* the read/write capped at 512 */ | ||
159 | memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen); | ||
160 | |||
161 | ret = mutex_lock_interruptible(&d->usb_mutex); | ||
162 | |||
163 | if (ret < 0) | ||
164 | return -EAGAIN; | ||
165 | |||
166 | ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01)); | ||
167 | |||
168 | ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01); | ||
169 | |||
170 | msleep(12); | ||
171 | |||
172 | ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01)); | ||
173 | |||
174 | ret |= lme2510_bulk_read(d->udev, buff, (rlen > 512) ? | ||
175 | 512 : rlen , 0x01); | ||
176 | |||
177 | if (rlen > 0) | ||
178 | memcpy(rbuf, buff, rlen); | ||
179 | |||
180 | mutex_unlock(&d->usb_mutex); | ||
181 | |||
182 | return (ret < 0) ? -ENODEV : 0; | ||
183 | } | ||
184 | |||
185 | static int lme2510_usb_talk_restart(struct dvb_usb_device *d, | ||
186 | u8 *wbuf, int wlen, u8 *rbuf, int rlen) { | ||
187 | static u8 stream_on[] = LME_ST_ON_W; | ||
188 | int ret; | ||
189 | u8 rbuff[10]; | ||
190 | /*Send Normal Command*/ | ||
191 | ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); | ||
192 | /*Restart Stream Command*/ | ||
193 | ret |= lme2510_usb_talk(d, stream_on, sizeof(stream_on), | ||
194 | rbuff, sizeof(rbuff)); | ||
195 | return ret; | ||
196 | } | ||
197 | static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) | ||
198 | { | ||
199 | struct dvb_usb_device *d = adap->dev; | ||
200 | |||
201 | deb_info(1, "INT Key Keypress =%04x", keypress); | ||
202 | |||
203 | if (keypress > 0) | ||
204 | ir_keydown(d->rc_input_dev, keypress, 0); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static void lme2510_int_response(struct urb *lme_urb) | ||
210 | { | ||
211 | struct dvb_usb_adapter *adap = lme_urb->context; | ||
212 | struct lme2510_state *st = adap->dev->priv; | ||
213 | static u8 *ibuf, *rbuf; | ||
214 | int i = 0, offset; | ||
215 | |||
216 | switch (lme_urb->status) { | ||
217 | case 0: | ||
218 | case -ETIMEDOUT: | ||
219 | break; | ||
220 | case -ECONNRESET: | ||
221 | case -ENOENT: | ||
222 | case -ESHUTDOWN: | ||
223 | return; | ||
224 | default: | ||
225 | info("Error %x", lme_urb->status); | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | rbuf = (u8 *) lme_urb->transfer_buffer; | ||
230 | |||
231 | offset = ((lme_urb->actual_length/8) > 4) | ||
232 | ? 4 : (lme_urb->actual_length/8) ; | ||
233 | |||
234 | for (i = 0; i < offset; ++i) { | ||
235 | ibuf = (u8 *)&rbuf[i*8]; | ||
236 | deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x", | ||
237 | offset, i, ibuf[0], ibuf[1]); | ||
238 | |||
239 | switch (ibuf[0]) { | ||
240 | case 0xaa: | ||
241 | debug_data_snipet(1, "INT Remote data snipet in", ibuf); | ||
242 | lme2510_remote_keypress(adap, | ||
243 | (u16)(ibuf[4]<<8)+ibuf[5]); | ||
244 | break; | ||
245 | case 0xbb: | ||
246 | switch (st->tuner_config) { | ||
247 | case TUNER_LG: | ||
248 | if (ibuf[2] > 0) | ||
249 | st->signal_lock = ibuf[2]; | ||
250 | st->signal_level = ibuf[4]; | ||
251 | st->signal_sn = ibuf[3]; | ||
252 | st->time_key = ibuf[7]; | ||
253 | break; | ||
254 | case TUNER_S7395: | ||
255 | /* Tweak for earlier firmware*/ | ||
256 | if (ibuf[1] == 0x03) { | ||
257 | st->signal_level = ibuf[3]; | ||
258 | st->signal_sn = ibuf[4]; | ||
259 | } else { | ||
260 | st->signal_level = ibuf[4]; | ||
261 | st->signal_sn = ibuf[5]; | ||
262 | } | ||
263 | break; | ||
264 | default: | ||
265 | break; | ||
266 | } | ||
267 | debug_data_snipet(5, "INT Remote data snipet in", ibuf); | ||
268 | break; | ||
269 | case 0xcc: | ||
270 | debug_data_snipet(1, "INT Control data snipet", ibuf); | ||
271 | break; | ||
272 | default: | ||
273 | debug_data_snipet(1, "INT Unknown data snipet", ibuf); | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | usb_submit_urb(lme_urb, GFP_ATOMIC); | ||
278 | } | ||
279 | |||
280 | static int lme2510_int_read(struct dvb_usb_adapter *adap) | ||
281 | { | ||
282 | struct lme2510_state *lme_int = adap->dev->priv; | ||
283 | |||
284 | lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
285 | |||
286 | if (lme_int->lme_urb == NULL) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 5000, GFP_ATOMIC, | ||
290 | &lme_int->lme_urb->transfer_dma); | ||
291 | |||
292 | if (lme_int->buffer == NULL) | ||
293 | return -ENOMEM; | ||
294 | |||
295 | usb_fill_int_urb(lme_int->lme_urb, | ||
296 | adap->dev->udev, | ||
297 | usb_rcvintpipe(adap->dev->udev, 0xa), | ||
298 | lme_int->buffer, | ||
299 | 4096, | ||
300 | lme2510_int_response, | ||
301 | adap, | ||
302 | 11); | ||
303 | |||
304 | lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
305 | |||
306 | usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC); | ||
307 | info("INT Interupt Service Started"); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int lme2510_return_status(struct usb_device *dev) | ||
313 | { | ||
314 | int ret = 0; | ||
315 | u8 data[10] = {0}; | ||
316 | |||
317 | ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
318 | 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200); | ||
319 | info("Firmware Status: %x (%x)", ret , data[2]); | ||
320 | |||
321 | return (ret < 0) ? -ENODEV : data[2]; | ||
322 | } | ||
323 | |||
324 | static int lme2510_msg(struct dvb_usb_device *d, | ||
325 | u8 *wbuf, int wlen, u8 *rbuf, int rlen) | ||
326 | { | ||
327 | int ret = 0; | ||
328 | struct lme2510_state *st = d->priv; | ||
329 | |||
330 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
331 | return -EAGAIN; | ||
332 | |||
333 | if (st->i2c_talk_onoff == 1) { | ||
334 | |||
335 | ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); | ||
336 | |||
337 | switch (st->tuner_config) { | ||
338 | case TUNER_LG: | ||
339 | if (wbuf[2] == 0x1c) { | ||
340 | if (wbuf[3] == 0x0e) { | ||
341 | st->signal_lock = rbuf[1]; | ||
342 | if ((st->stream_on & 1) && | ||
343 | (st->signal_lock & 0x10)) { | ||
344 | lme2510_usb_talk_restart(d, | ||
345 | wbuf, wlen, rbuf, rlen); | ||
346 | st->i2c_talk_onoff = 0; | ||
347 | } | ||
348 | msleep(80); | ||
349 | } | ||
350 | } | ||
351 | break; | ||
352 | case TUNER_S7395: | ||
353 | if (wbuf[2] == 0xd0) { | ||
354 | if (wbuf[3] == 0x24) { | ||
355 | st->signal_lock = rbuf[1]; | ||
356 | if ((st->stream_on & 1) && | ||
357 | (st->signal_lock & 0x8)) { | ||
358 | lme2510_usb_talk_restart(d, | ||
359 | wbuf, wlen, rbuf, rlen); | ||
360 | st->i2c_talk_onoff = 0; | ||
361 | } | ||
362 | } | ||
363 | if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5)) | ||
364 | msleep(5); | ||
365 | |||
366 | |||
367 | } | ||
368 | break; | ||
369 | default: | ||
370 | break; | ||
371 | } | ||
372 | } else { | ||
373 | switch (st->tuner_config) { | ||
374 | case TUNER_LG: | ||
375 | switch (wbuf[3]) { | ||
376 | case 0x0e: | ||
377 | rbuf[0] = 0x55; | ||
378 | rbuf[1] = st->signal_lock; | ||
379 | break; | ||
380 | case 0x43: | ||
381 | rbuf[0] = 0x55; | ||
382 | rbuf[1] = st->signal_level; | ||
383 | break; | ||
384 | case 0x1c: | ||
385 | rbuf[0] = 0x55; | ||
386 | rbuf[1] = st->signal_sn; | ||
387 | break; | ||
388 | /*DiSEqC functions as per TDA10086*/ | ||
389 | case 0x36: | ||
390 | case 0x48: | ||
391 | case 0x49: | ||
392 | case 0x4a: | ||
393 | case 0x4b: | ||
394 | case 0x4c: | ||
395 | case 0x4d: | ||
396 | if (wbuf[2] == 0x1c) | ||
397 | lme2510_usb_talk_restart(d, | ||
398 | wbuf, wlen, rbuf, rlen); | ||
399 | default: | ||
400 | break; | ||
401 | } | ||
402 | break; | ||
403 | case TUNER_S7395: | ||
404 | switch (wbuf[3]) { | ||
405 | case 0x10: | ||
406 | rbuf[0] = 0x55; | ||
407 | rbuf[1] = (st->signal_level & 0x80) | ||
408 | ? 0 : (st->signal_level * 2); | ||
409 | break; | ||
410 | case 0x2d: | ||
411 | rbuf[0] = 0x55; | ||
412 | rbuf[1] = st->signal_sn; | ||
413 | break; | ||
414 | case 0x24: | ||
415 | rbuf[0] = 0x55; | ||
416 | rbuf[1] = (st->signal_level & 0x80) | ||
417 | ? 0 : st->signal_lock; | ||
418 | break; | ||
419 | case 0x6: | ||
420 | if (wbuf[2] == 0xd0) | ||
421 | lme2510_usb_talk(d, | ||
422 | wbuf, wlen, rbuf, rlen); | ||
423 | break; | ||
424 | case 0x1: | ||
425 | if (st->one_tune > 0) | ||
426 | break; | ||
427 | st->one_tune++; | ||
428 | st->i2c_talk_onoff = 1; | ||
429 | /*DiSEqC functions as per STV0288*/ | ||
430 | case 0x5: | ||
431 | case 0x7: | ||
432 | case 0x8: | ||
433 | case 0x9: | ||
434 | case 0xa: | ||
435 | case 0xb: | ||
436 | if (wbuf[2] == 0xd0) | ||
437 | lme2510_usb_talk_restart(d, | ||
438 | wbuf, wlen, rbuf, rlen); | ||
439 | break; | ||
440 | default: | ||
441 | rbuf[0] = 0x55; | ||
442 | rbuf[1] = 0x00; | ||
443 | break; | ||
444 | } | ||
445 | break; | ||
446 | default: | ||
447 | break; | ||
448 | |||
449 | } | ||
450 | |||
451 | deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)", | ||
452 | wbuf[3], rbuf[1]); | ||
453 | |||
454 | } | ||
455 | |||
456 | mutex_unlock(&d->i2c_mutex); | ||
457 | |||
458 | return ret; | ||
459 | } | ||
460 | |||
461 | |||
462 | static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||
463 | int num) | ||
464 | { | ||
465 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
466 | struct lme2510_state *st = d->priv; | ||
467 | static u8 obuf[64], ibuf[512]; | ||
468 | int i, read, read_o; | ||
469 | u16 len; | ||
470 | u8 gate = st->i2c_gate; | ||
471 | |||
472 | if (gate == 0) | ||
473 | gate = 5; | ||
474 | |||
475 | if (num > 2) | ||
476 | warn("more than 2 i2c messages" | ||
477 | "at a time is not handled yet. TODO."); | ||
478 | |||
479 | for (i = 0; i < num; i++) { | ||
480 | read_o = 1 & (msg[i].flags & I2C_M_RD); | ||
481 | read = i+1 < num && (msg[i+1].flags & I2C_M_RD); | ||
482 | read |= read_o; | ||
483 | gate = (msg[i].addr == st->i2c_tuner_addr) | ||
484 | ? (read) ? st->i2c_tuner_gate_r | ||
485 | : st->i2c_tuner_gate_w | ||
486 | : st->i2c_gate; | ||
487 | obuf[0] = gate | (read << 7); | ||
488 | |||
489 | if (gate == 5) | ||
490 | obuf[1] = (read) ? 2 : msg[i].len + 1; | ||
491 | else | ||
492 | obuf[1] = msg[i].len + read + 1; | ||
493 | |||
494 | obuf[2] = msg[i].addr; | ||
495 | if (read) { | ||
496 | if (read_o) | ||
497 | len = 3; | ||
498 | else { | ||
499 | memcpy(&obuf[3], msg[i].buf, msg[i].len); | ||
500 | obuf[msg[i].len+3] = msg[i+1].len; | ||
501 | len = msg[i].len+4; | ||
502 | } | ||
503 | } else { | ||
504 | memcpy(&obuf[3], msg[i].buf, msg[i].len); | ||
505 | len = msg[i].len+3; | ||
506 | } | ||
507 | |||
508 | if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) { | ||
509 | deb_info(1, "i2c transfer failed."); | ||
510 | return -EAGAIN; | ||
511 | } | ||
512 | |||
513 | if (read) { | ||
514 | if (read_o) | ||
515 | memcpy(msg[i].buf, &ibuf[1], msg[i].len); | ||
516 | else { | ||
517 | memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len); | ||
518 | i++; | ||
519 | } | ||
520 | } | ||
521 | } | ||
522 | return i; | ||
523 | } | ||
524 | |||
525 | static u32 lme2510_i2c_func(struct i2c_adapter *adapter) | ||
526 | { | ||
527 | return I2C_FUNC_I2C; | ||
528 | } | ||
529 | |||
530 | static struct i2c_algorithm lme2510_i2c_algo = { | ||
531 | .master_xfer = lme2510_i2c_xfer, | ||
532 | .functionality = lme2510_i2c_func, | ||
533 | }; | ||
534 | |||
535 | /* Callbacks for DVB USB */ | ||
536 | static int lme2510_identify_state(struct usb_device *udev, | ||
537 | struct dvb_usb_device_properties *props, | ||
538 | struct dvb_usb_device_description **desc, | ||
539 | int *cold) | ||
540 | { | ||
541 | if (lme2510_return_status(udev) == 0x44) | ||
542 | *cold = 1; | ||
543 | else | ||
544 | *cold = 0; | ||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
549 | { | ||
550 | struct lme2510_state *st = adap->dev->priv; | ||
551 | static u8 stream_on[] = LME_ST_ON_W; | ||
552 | static u8 clear_reg_3[] = LME_CLEAR_PID; | ||
553 | static u8 rbuf[1]; | ||
554 | static u8 timeout; | ||
555 | int ret = 0, len = 2, rlen = sizeof(rbuf); | ||
556 | |||
557 | deb_info(1, "STM (%02x)", onoff); | ||
558 | |||
559 | if (onoff == 1) { | ||
560 | st->i2c_talk_onoff = 0; | ||
561 | timeout = 0; | ||
562 | /* wait for i2C to be free */ | ||
563 | while (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) { | ||
564 | timeout++; | ||
565 | if (timeout > 5) | ||
566 | return -ENODEV; | ||
567 | } | ||
568 | msleep(100); | ||
569 | ret |= lme2510_usb_talk(adap->dev, | ||
570 | stream_on, len, rbuf, rlen); | ||
571 | st->stream_on = 1; | ||
572 | st->one_tune = 0; | ||
573 | mutex_unlock(&adap->dev->i2c_mutex); | ||
574 | } else { | ||
575 | deb_info(1, "STM Steam Off"); | ||
576 | ret |= lme2510_usb_talk(adap->dev, clear_reg_3, | ||
577 | sizeof(clear_reg_3), rbuf, rlen); | ||
578 | st->stream_on = 0; | ||
579 | st->i2c_talk_onoff = 1; | ||
580 | } | ||
581 | |||
582 | return (ret < 0) ? -ENODEV : 0; | ||
583 | } | ||
584 | |||
585 | static int lme2510_int_service(struct dvb_usb_adapter *adap) | ||
586 | { | ||
587 | struct dvb_usb_device *d = adap->dev; | ||
588 | struct input_dev *input_dev; | ||
589 | char *ir_codes = RC_MAP_LME2510; | ||
590 | int ret = 0; | ||
591 | |||
592 | info("STA Configuring Remote"); | ||
593 | |||
594 | usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); | ||
595 | |||
596 | strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); | ||
597 | |||
598 | input_dev = input_allocate_device(); | ||
599 | if (!input_dev) | ||
600 | return -ENOMEM; | ||
601 | |||
602 | input_dev->name = "LME2510 Remote Control"; | ||
603 | input_dev->phys = d->rc_phys; | ||
604 | |||
605 | usb_to_input_id(d->udev, &input_dev->id); | ||
606 | |||
607 | ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510"); | ||
608 | |||
609 | if (ret) { | ||
610 | input_free_device(input_dev); | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | d->rc_input_dev = input_dev; | ||
615 | /* Start the Interupt */ | ||
616 | ret = lme2510_int_read(adap); | ||
617 | |||
618 | if (ret < 0) { | ||
619 | ir_input_unregister(input_dev); | ||
620 | input_free_device(input_dev); | ||
621 | } | ||
622 | return (ret < 0) ? -ENODEV : 0; | ||
623 | } | ||
624 | |||
625 | static u8 check_sum(u8 *p, u8 len) | ||
626 | { | ||
627 | u8 sum = 0; | ||
628 | while (len--) | ||
629 | sum += *p++; | ||
630 | return sum; | ||
631 | } | ||
632 | |||
633 | static int lme2510_download_firmware(struct usb_device *dev, | ||
634 | const struct firmware *fw) | ||
635 | { | ||
636 | int ret = 0; | ||
637 | u8 data[512] = {0}; | ||
638 | u16 j, wlen, len_in, start, end; | ||
639 | u8 packet_size, dlen, i; | ||
640 | u8 *fw_data; | ||
641 | |||
642 | packet_size = 0x31; | ||
643 | len_in = 1; | ||
644 | |||
645 | |||
646 | info("FRM Starting Firmware Download"); | ||
647 | |||
648 | for (i = 1; i < 3; i++) { | ||
649 | start = (i == 1) ? 0 : 512; | ||
650 | end = (i == 1) ? 512 : fw->size; | ||
651 | for (j = start; j < end; j += (packet_size+1)) { | ||
652 | fw_data = (u8 *)(fw->data + j); | ||
653 | if ((end - j) > packet_size) { | ||
654 | data[0] = i; | ||
655 | dlen = packet_size; | ||
656 | } else { | ||
657 | data[0] = i | 0x80; | ||
658 | dlen = (u8)(end - j)-1; | ||
659 | } | ||
660 | data[1] = dlen; | ||
661 | memcpy(&data[2], fw_data, dlen+1); | ||
662 | wlen = (u8) dlen + 4; | ||
663 | data[wlen-1] = check_sum(fw_data, dlen+1); | ||
664 | deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3], | ||
665 | data[dlen+2], data[dlen+3]); | ||
666 | ret |= lme2510_bulk_write(dev, data, wlen, 1); | ||
667 | ret |= lme2510_bulk_read(dev, data, len_in , 1); | ||
668 | ret |= (data[0] == 0x88) ? 0 : -1; | ||
669 | } | ||
670 | } | ||
671 | usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
672 | 0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000); | ||
673 | |||
674 | |||
675 | data[0] = 0x8a; | ||
676 | len_in = 1; | ||
677 | msleep(2000); | ||
678 | ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Resetting*/ | ||
679 | ret |= lme2510_bulk_read(dev, data, len_in, 1); | ||
680 | msleep(400); | ||
681 | |||
682 | if (ret < 0) | ||
683 | info("FRM Firmware Download Failed (%04x)" , ret); | ||
684 | else | ||
685 | info("FRM Firmware Download Completed - Resetting Device"); | ||
686 | |||
687 | |||
688 | return (ret < 0) ? -ENODEV : 0; | ||
689 | } | ||
690 | |||
691 | /* Default firmware for LME2510C */ | ||
692 | const char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; | ||
693 | |||
694 | static void lme_coldreset(struct usb_device *dev) | ||
695 | { | ||
696 | int ret = 0, len_in; | ||
697 | u8 data[512] = {0}; | ||
698 | |||
699 | data[0] = 0x0a; | ||
700 | len_in = 1; | ||
701 | info("FRM Firmware Cold Reset"); | ||
702 | ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/ | ||
703 | ret |= lme2510_bulk_read(dev, data, len_in, 1); | ||
704 | return; | ||
705 | } | ||
706 | |||
707 | static void lme_firmware_switch(struct usb_device *udev, int cold) | ||
708 | { | ||
709 | const struct firmware *fw = NULL; | ||
710 | char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; | ||
711 | char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw"; | ||
712 | char *firm_msg[] = {"Loading", "Switching to"}; | ||
713 | int ret; | ||
714 | |||
715 | if (udev->descriptor.idProduct == 0x1122) | ||
716 | return; | ||
717 | |||
718 | switch (dvb_usb_lme2510_firmware) { | ||
719 | case 0: | ||
720 | default: | ||
721 | memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395)); | ||
722 | ret = request_firmware(&fw, lme_firmware, &udev->dev); | ||
723 | if (ret == 0) { | ||
724 | info("FRM %s S7395 Firmware", firm_msg[cold]); | ||
725 | break; | ||
726 | } | ||
727 | if (cold == 0) | ||
728 | dvb_usb_lme2510_firmware = 1; | ||
729 | else | ||
730 | cold = 0; | ||
731 | case 1: | ||
732 | memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg)); | ||
733 | ret = request_firmware(&fw, lme_firmware, &udev->dev); | ||
734 | if (ret == 0) { | ||
735 | info("FRM %s LG Firmware", firm_msg[cold]); | ||
736 | break; | ||
737 | } | ||
738 | info("FRM No Firmware Found - please install"); | ||
739 | dvb_usb_lme2510_firmware = 0; | ||
740 | cold = 0; | ||
741 | break; | ||
742 | } | ||
743 | release_firmware(fw); | ||
744 | if (cold) | ||
745 | lme_coldreset(udev); | ||
746 | return; | ||
747 | } | ||
748 | |||
749 | static int lme2510_kill_urb(struct usb_data_stream *stream) | ||
750 | { | ||
751 | int i; | ||
752 | for (i = 0; i < stream->urbs_submitted; i++) { | ||
753 | deb_info(3, "killing URB no. %d.", i); | ||
754 | |||
755 | /* stop the URB */ | ||
756 | usb_kill_urb(stream->urb_list[i]); | ||
757 | } | ||
758 | stream->urbs_submitted = 0; | ||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | static struct tda10086_config tda10086_config = { | ||
763 | .demod_address = 0x1c, | ||
764 | .invert = 0, | ||
765 | .diseqc_tone = 1, | ||
766 | .xtal_freq = TDA10086_XTAL_16M, | ||
767 | }; | ||
768 | |||
769 | static struct stv0288_config lme_config = { | ||
770 | .demod_address = 0xd0, | ||
771 | .min_delay_ms = 15, | ||
772 | .inittab = s7395_inittab, | ||
773 | }; | ||
774 | |||
775 | static struct ix2505v_config lme_tuner = { | ||
776 | .tuner_address = 0xc0, | ||
777 | .min_delay_ms = 100, | ||
778 | .tuner_gain = 0x0, | ||
779 | .tuner_chargepump = 0x3, | ||
780 | }; | ||
781 | |||
782 | static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, | ||
783 | fe_sec_voltage_t voltage) | ||
784 | { | ||
785 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
786 | struct lme2510_state *st = adap->dev->priv; | ||
787 | static u8 voltage_low[] = LME_VOLTAGE_L; | ||
788 | static u8 voltage_high[] = LME_VOLTAGE_H; | ||
789 | static u8 lnb_on[] = LNB_ON; | ||
790 | static u8 lnb_off[] = LNB_OFF; | ||
791 | static u8 rbuf[1]; | ||
792 | int ret = 0, len = 3, rlen = 1; | ||
793 | |||
794 | if (st->stream_on == 1) | ||
795 | return 0; | ||
796 | |||
797 | ret |= lme2510_usb_talk(adap->dev, lnb_on, len, rbuf, rlen); | ||
798 | |||
799 | switch (voltage) { | ||
800 | case SEC_VOLTAGE_18: | ||
801 | ret |= lme2510_usb_talk(adap->dev, | ||
802 | voltage_high, len, rbuf, rlen); | ||
803 | break; | ||
804 | |||
805 | case SEC_VOLTAGE_OFF: | ||
806 | ret |= lme2510_usb_talk(adap->dev, | ||
807 | lnb_off, len, rbuf, rlen); | ||
808 | case SEC_VOLTAGE_13: | ||
809 | default: | ||
810 | ret |= lme2510_usb_talk(adap->dev, | ||
811 | voltage_low, len, rbuf, rlen); | ||
812 | break; | ||
813 | |||
814 | |||
815 | }; | ||
816 | st->i2c_talk_onoff = 1; | ||
817 | return (ret < 0) ? -ENODEV : 0; | ||
818 | } | ||
819 | |||
820 | static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) | ||
821 | { | ||
822 | int ret = 0; | ||
823 | struct lme2510_state *st = adap->dev->priv; | ||
824 | |||
825 | /* Interupt Start */ | ||
826 | ret = lme2510_int_service(adap); | ||
827 | if (ret < 0) { | ||
828 | info("INT Unable to start Interupt Service"); | ||
829 | return -ENODEV; | ||
830 | } | ||
831 | |||
832 | st->i2c_talk_onoff = 1; | ||
833 | st->i2c_gate = 4; | ||
834 | |||
835 | adap->fe = dvb_attach(tda10086_attach, &tda10086_config, | ||
836 | &adap->dev->i2c_adap); | ||
837 | |||
838 | if (adap->fe) { | ||
839 | info("TUN Found Frontend TDA10086"); | ||
840 | memcpy(&adap->fe->ops.info.name, | ||
841 | &"DM04_LG_TDQY-P001F DVB-S", 24); | ||
842 | adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; | ||
843 | st->i2c_tuner_gate_w = 4; | ||
844 | st->i2c_tuner_gate_r = 4; | ||
845 | st->i2c_tuner_addr = 0xc0; | ||
846 | if (dvb_attach(tda826x_attach, adap->fe, 0xc0, | ||
847 | &adap->dev->i2c_adap, 1)) { | ||
848 | info("TUN TDA8263 Found"); | ||
849 | st->tuner_config = TUNER_LG; | ||
850 | if (dvb_usb_lme2510_firmware != 1) { | ||
851 | dvb_usb_lme2510_firmware = 1; | ||
852 | lme_firmware_switch(adap->dev->udev, 1); | ||
853 | } | ||
854 | return 0; | ||
855 | } | ||
856 | kfree(adap->fe); | ||
857 | adap->fe = NULL; | ||
858 | } | ||
859 | st->i2c_gate = 5; | ||
860 | adap->fe = dvb_attach(stv0288_attach, &lme_config, | ||
861 | &adap->dev->i2c_adap); | ||
862 | |||
863 | if (adap->fe) { | ||
864 | info("FE Found Stv0288"); | ||
865 | memcpy(&adap->fe->ops.info.name, | ||
866 | &"DM04_SHARP:BS2F7HZ7395", 22); | ||
867 | adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; | ||
868 | st->i2c_tuner_gate_w = 4; | ||
869 | st->i2c_tuner_gate_r = 5; | ||
870 | st->i2c_tuner_addr = 0xc0; | ||
871 | if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner, | ||
872 | &adap->dev->i2c_adap)) { | ||
873 | st->tuner_config = TUNER_S7395; | ||
874 | info("TUN Sharp IX2505V silicon tuner"); | ||
875 | if (dvb_usb_lme2510_firmware != 0) { | ||
876 | dvb_usb_lme2510_firmware = 0; | ||
877 | lme_firmware_switch(adap->dev->udev, 1); | ||
878 | } | ||
879 | return 0; | ||
880 | } | ||
881 | kfree(adap->fe); | ||
882 | adap->fe = NULL; | ||
883 | } | ||
884 | |||
885 | info("DM04 Not Supported"); | ||
886 | return -ENODEV; | ||
887 | } | ||
888 | |||
889 | static int lme2510_powerup(struct dvb_usb_device *d, int onoff) | ||
890 | { | ||
891 | struct lme2510_state *st = d->priv; | ||
892 | st->i2c_talk_onoff = 1; | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | /* DVB USB Driver stuff */ | ||
897 | static struct dvb_usb_device_properties lme2510_properties; | ||
898 | static struct dvb_usb_device_properties lme2510c_properties; | ||
899 | |||
900 | static int lme2510_probe(struct usb_interface *intf, | ||
901 | const struct usb_device_id *id) | ||
902 | { | ||
903 | struct usb_device *udev = interface_to_usbdev(intf); | ||
904 | int ret = 0; | ||
905 | |||
906 | usb_reset_configuration(udev); | ||
907 | |||
908 | usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1); | ||
909 | |||
910 | if (udev->speed != USB_SPEED_HIGH) { | ||
911 | ret = usb_reset_device(udev); | ||
912 | info("DEV Failed to connect in HIGH SPEED mode"); | ||
913 | return -ENODEV; | ||
914 | } | ||
915 | |||
916 | lme_firmware_switch(udev, 0); | ||
917 | |||
918 | if (0 == dvb_usb_device_init(intf, &lme2510_properties, | ||
919 | THIS_MODULE, NULL, adapter_nr)) { | ||
920 | info("DEV registering device driver"); | ||
921 | return 0; | ||
922 | } | ||
923 | if (0 == dvb_usb_device_init(intf, &lme2510c_properties, | ||
924 | THIS_MODULE, NULL, adapter_nr)) { | ||
925 | info("DEV registering device driver"); | ||
926 | return 0; | ||
927 | } | ||
928 | |||
929 | info("DEV lme2510 Error"); | ||
930 | return -ENODEV; | ||
931 | |||
932 | } | ||
933 | |||
934 | static struct usb_device_id lme2510_table[] = { | ||
935 | { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */ | ||
936 | { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */ | ||
937 | {} /* Terminating entry */ | ||
938 | }; | ||
939 | |||
940 | MODULE_DEVICE_TABLE(usb, lme2510_table); | ||
941 | |||
942 | static struct dvb_usb_device_properties lme2510_properties = { | ||
943 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
944 | .usb_ctrl = DEVICE_SPECIFIC, | ||
945 | .download_firmware = lme2510_download_firmware, | ||
946 | .firmware = "dvb-usb-lme2510-lg.fw", | ||
947 | |||
948 | .size_of_priv = sizeof(struct lme2510_state), | ||
949 | .num_adapters = 1, | ||
950 | .adapter = { | ||
951 | { | ||
952 | .streaming_ctrl = lme2510_streaming_ctrl, | ||
953 | .frontend_attach = dm04_lme2510_frontend_attach, | ||
954 | /* parameter for the MPEG2-data transfer */ | ||
955 | .stream = { | ||
956 | .type = USB_BULK, | ||
957 | .count = 10, | ||
958 | .endpoint = 0x06, | ||
959 | .u = { | ||
960 | .bulk = { | ||
961 | .buffersize = 4096, | ||
962 | |||
963 | } | ||
964 | } | ||
965 | } | ||
966 | } | ||
967 | }, | ||
968 | .power_ctrl = lme2510_powerup, | ||
969 | .identify_state = lme2510_identify_state, | ||
970 | .i2c_algo = &lme2510_i2c_algo, | ||
971 | .generic_bulk_ctrl_endpoint = 0, | ||
972 | .num_device_descs = 1, | ||
973 | .devices = { | ||
974 | { "DM04 LME2510 DVB-S USB 2.0", | ||
975 | { &lme2510_table[0], NULL }, | ||
976 | }, | ||
977 | |||
978 | } | ||
979 | }; | ||
980 | |||
981 | static struct dvb_usb_device_properties lme2510c_properties = { | ||
982 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
983 | .usb_ctrl = DEVICE_SPECIFIC, | ||
984 | .download_firmware = lme2510_download_firmware, | ||
985 | .firmware = lme_firmware, | ||
986 | .size_of_priv = sizeof(struct lme2510_state), | ||
987 | .num_adapters = 1, | ||
988 | .adapter = { | ||
989 | { | ||
990 | .streaming_ctrl = lme2510_streaming_ctrl, | ||
991 | .frontend_attach = dm04_lme2510_frontend_attach, | ||
992 | /* parameter for the MPEG2-data transfer */ | ||
993 | .stream = { | ||
994 | .type = USB_BULK, | ||
995 | .count = 10, | ||
996 | .endpoint = 0x8, | ||
997 | .u = { | ||
998 | .bulk = { | ||
999 | .buffersize = 4096, | ||
1000 | |||
1001 | } | ||
1002 | } | ||
1003 | } | ||
1004 | } | ||
1005 | }, | ||
1006 | .power_ctrl = lme2510_powerup, | ||
1007 | .identify_state = lme2510_identify_state, | ||
1008 | .i2c_algo = &lme2510_i2c_algo, | ||
1009 | .generic_bulk_ctrl_endpoint = 0, | ||
1010 | .num_device_descs = 1, | ||
1011 | .devices = { | ||
1012 | { "DM04 LME2510C USB2.0", | ||
1013 | { &lme2510_table[1], NULL }, | ||
1014 | }, | ||
1015 | } | ||
1016 | }; | ||
1017 | |||
1018 | void *lme2510_exit_int(struct dvb_usb_device *d) | ||
1019 | { | ||
1020 | struct lme2510_state *st = d->priv; | ||
1021 | struct dvb_usb_adapter *adap = &d->adapter[0]; | ||
1022 | void *buffer = NULL; | ||
1023 | |||
1024 | if (adap != NULL) { | ||
1025 | lme2510_kill_urb(&adap->stream); | ||
1026 | adap->feedcount = 0; | ||
1027 | } | ||
1028 | |||
1029 | if (st->lme_urb != NULL) { | ||
1030 | st->i2c_talk_onoff = 1; | ||
1031 | st->signal_lock = 0; | ||
1032 | st->signal_level = 0; | ||
1033 | st->signal_sn = 0; | ||
1034 | buffer = st->usb_buffer; | ||
1035 | usb_kill_urb(st->lme_urb); | ||
1036 | usb_free_coherent(d->udev, 5000, st->buffer, | ||
1037 | st->lme_urb->transfer_dma); | ||
1038 | info("Interupt Service Stopped"); | ||
1039 | ir_input_unregister(d->rc_input_dev); | ||
1040 | info("Remote Stopped"); | ||
1041 | } | ||
1042 | return buffer; | ||
1043 | } | ||
1044 | |||
1045 | void lme2510_exit(struct usb_interface *intf) | ||
1046 | { | ||
1047 | struct dvb_usb_device *d = usb_get_intfdata(intf); | ||
1048 | void *usb_buffer; | ||
1049 | |||
1050 | if (d != NULL) { | ||
1051 | usb_buffer = lme2510_exit_int(d); | ||
1052 | dvb_usb_device_exit(intf); | ||
1053 | kfree(usb_buffer); | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | static struct usb_driver lme2510_driver = { | ||
1058 | .name = "LME2510C_DVBS", | ||
1059 | .probe = lme2510_probe, | ||
1060 | .disconnect = lme2510_exit, | ||
1061 | .id_table = lme2510_table, | ||
1062 | }; | ||
1063 | |||
1064 | /* module stuff */ | ||
1065 | static int __init lme2510_module_init(void) | ||
1066 | { | ||
1067 | int result = usb_register(&lme2510_driver); | ||
1068 | if (result) { | ||
1069 | err("usb_register failed. Error number %d", result); | ||
1070 | return result; | ||
1071 | } | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1076 | static void __exit lme2510_module_exit(void) | ||
1077 | { | ||
1078 | /* deregister this driver from the USB subsystem */ | ||
1079 | usb_deregister(&lme2510_driver); | ||
1080 | } | ||
1081 | |||
1082 | module_init(lme2510_module_init); | ||
1083 | module_exit(lme2510_module_exit); | ||
1084 | |||
1085 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); | ||
1086 | MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0"); | ||
1087 | MODULE_VERSION("1.60"); | ||
1088 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h new file mode 100644 index 00000000000..e6af16c1e3e --- /dev/null +++ b/drivers/media/dvb/dvb-usb/lmedm04.h | |||
@@ -0,0 +1,173 @@ | |||
1 | /* DVB USB compliant linux driver for | ||
2 | * | ||
3 | * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 | ||
4 | * LME2510C + LG TDQY-P001F | ||
5 | * LME2510 + LG TDQY-P001F | ||
6 | * | ||
7 | * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) | ||
8 | * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) | ||
9 | * | ||
10 | * MVB001F (LME2510+LGTDQT-P001F) | ||
11 | * LG TDQY - P001F =(TDA8263 + TDA10086H) | ||
12 | * | ||
13 | * MVB0001F (LME2510C+LGTDQT-P001F) | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License as published by the Free | ||
17 | * Software Foundation, version 2. | ||
18 | * * | ||
19 | * see Documentation/dvb/README.dvb-usb for more information | ||
20 | */ | ||
21 | #ifndef _DVB_USB_LME2510_H_ | ||
22 | #define _DVB_USB_LME2510_H_ | ||
23 | |||
24 | /* Streamer & PID | ||
25 | * | ||
26 | * Note: These commands do not actually stop the streaming | ||
27 | * but form some kind of packet filtering/stream count | ||
28 | * or tuning related functions. | ||
29 | * 06 XX | ||
30 | * offset 1 = 00 Enable Streaming | ||
31 | * | ||
32 | * | ||
33 | * PID | ||
34 | * 03 XX XX ----> reg number ---> setting....20 XX | ||
35 | * offset 1 = length | ||
36 | * offset 2 = start of data | ||
37 | * end byte -1 = 20 | ||
38 | * end byte = clear pid always a0, other wise 9c, 9a ?? | ||
39 | * | ||
40 | */ | ||
41 | #define LME_ST_ON_W {0x06, 0x00} | ||
42 | #define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0} | ||
43 | |||
44 | /* LNB Voltage | ||
45 | * 07 XX XX | ||
46 | * offset 1 = 01 | ||
47 | * offset 2 = 00=Voltage low 01=Voltage high | ||
48 | * | ||
49 | * LNB Power | ||
50 | * 03 01 XX | ||
51 | * offset 2 = 00=ON 01=OFF | ||
52 | */ | ||
53 | |||
54 | #define LME_VOLTAGE_L {0x07, 0x01, 0x00} | ||
55 | #define LME_VOLTAGE_H {0x07, 0x01, 0x01} | ||
56 | #define LNB_ON {0x3a, 0x01, 0x00} | ||
57 | #define LNB_OFF {0x3a, 0x01, 0x01} | ||
58 | |||
59 | /* Initial stv0288 settings for 7395 Frontend */ | ||
60 | static u8 s7395_inittab[] = { | ||
61 | 0x01, 0x15, | ||
62 | 0x02, 0x20, | ||
63 | 0x03, 0xa0, | ||
64 | 0x04, 0xa0, | ||
65 | 0x05, 0x12, | ||
66 | 0x06, 0x00, | ||
67 | 0x09, 0x00, | ||
68 | 0x0a, 0x04, | ||
69 | 0x0b, 0x00, | ||
70 | 0x0c, 0x00, | ||
71 | 0x0d, 0x00, | ||
72 | 0x0e, 0xc1, | ||
73 | 0x0f, 0x54, | ||
74 | 0x11, 0x7a, | ||
75 | 0x12, 0x03, | ||
76 | 0x13, 0x48, | ||
77 | 0x14, 0x84, | ||
78 | 0x15, 0xc5, | ||
79 | 0x16, 0xb8, | ||
80 | 0x17, 0x9c, | ||
81 | 0x18, 0x00, | ||
82 | 0x19, 0xa6, | ||
83 | 0x1a, 0x88, | ||
84 | 0x1b, 0x8f, | ||
85 | 0x1c, 0xf0, | ||
86 | 0x20, 0x0b, | ||
87 | 0x21, 0x54, | ||
88 | 0x22, 0xff, | ||
89 | 0x23, 0x01, | ||
90 | 0x28, 0x46, | ||
91 | 0x29, 0x66, | ||
92 | 0x2a, 0x90, | ||
93 | 0x2b, 0xfa, | ||
94 | 0x2c, 0xd9, | ||
95 | 0x30, 0x0, | ||
96 | 0x31, 0x1e, | ||
97 | 0x32, 0x14, | ||
98 | 0x33, 0x0f, | ||
99 | 0x34, 0x09, | ||
100 | 0x35, 0x0c, | ||
101 | 0x36, 0x05, | ||
102 | 0x37, 0x2f, | ||
103 | 0x38, 0x16, | ||
104 | 0x39, 0xbd, | ||
105 | 0x3a, 0x0, | ||
106 | 0x3b, 0x13, | ||
107 | 0x3c, 0x11, | ||
108 | 0x3d, 0x30, | ||
109 | 0x40, 0x63, | ||
110 | 0x41, 0x04, | ||
111 | 0x42, 0x60, | ||
112 | 0x43, 0x00, | ||
113 | 0x44, 0x00, | ||
114 | 0x45, 0x00, | ||
115 | 0x46, 0x00, | ||
116 | 0x47, 0x00, | ||
117 | 0x4a, 0x00, | ||
118 | 0x50, 0x12, | ||
119 | 0x51, 0x36, | ||
120 | 0x52, 0x21, | ||
121 | 0x53, 0x94, | ||
122 | 0x54, 0xb2, | ||
123 | 0x55, 0x29, | ||
124 | 0x56, 0x64, | ||
125 | 0x57, 0x2b, | ||
126 | 0x58, 0x54, | ||
127 | 0x59, 0x86, | ||
128 | 0x5a, 0x00, | ||
129 | 0x5b, 0x9b, | ||
130 | 0x5c, 0x08, | ||
131 | 0x5d, 0x7f, | ||
132 | 0x5e, 0xff, | ||
133 | 0x5f, 0x8d, | ||
134 | 0x70, 0x0, | ||
135 | 0x71, 0x0, | ||
136 | 0x72, 0x0, | ||
137 | 0x74, 0x0, | ||
138 | 0x75, 0x0, | ||
139 | 0x76, 0x0, | ||
140 | 0x81, 0x0, | ||
141 | 0x82, 0x3f, | ||
142 | 0x83, 0x3f, | ||
143 | 0x84, 0x0, | ||
144 | 0x85, 0x0, | ||
145 | 0x88, 0x0, | ||
146 | 0x89, 0x0, | ||
147 | 0x8a, 0x0, | ||
148 | 0x8b, 0x0, | ||
149 | 0x8c, 0x0, | ||
150 | 0x90, 0x0, | ||
151 | 0x91, 0x0, | ||
152 | 0x92, 0x0, | ||
153 | 0x93, 0x0, | ||
154 | 0x94, 0x1c, | ||
155 | 0x97, 0x0, | ||
156 | 0xa0, 0x48, | ||
157 | 0xa1, 0x0, | ||
158 | 0xb0, 0xb8, | ||
159 | 0xb1, 0x3a, | ||
160 | 0xb2, 0x10, | ||
161 | 0xb3, 0x82, | ||
162 | 0xb4, 0x80, | ||
163 | 0xb5, 0x82, | ||
164 | 0xb6, 0x82, | ||
165 | 0xb7, 0x82, | ||
166 | 0xb8, 0x20, | ||
167 | 0xb9, 0x0, | ||
168 | 0xf0, 0x0, | ||
169 | 0xf1, 0x0, | ||
170 | 0xf2, 0xc0, | ||
171 | 0xff, 0xff, | ||
172 | }; | ||
173 | #endif | ||
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 28294af752d..f0f1842fab6 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | 26 | ||
27 | #include <dvb_frontend.h> | ||
28 | |||
27 | #include "firedtv.h" | 29 | #include "firedtv.h" |
28 | 30 | ||
29 | #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL | 31 | #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL |
@@ -130,6 +132,20 @@ MODULE_PARM_DESC(debug, "Verbose logging (none = 0" | |||
130 | ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) | 132 | ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) |
131 | ", or a combination, or all = -1)"); | 133 | ", or a combination, or all = -1)"); |
132 | 134 | ||
135 | /* | ||
136 | * This is a workaround since there is no vendor specific command to retrieve | ||
137 | * ca_info using AVC. If this parameter is not used, ca_system_id will be | ||
138 | * filled with application_manufacturer from ca_app_info. | ||
139 | * Digital Everywhere have said that adding ca_info is on their TODO list. | ||
140 | */ | ||
141 | static unsigned int num_fake_ca_system_ids; | ||
142 | static int fake_ca_system_ids[4] = { -1, -1, -1, -1 }; | ||
143 | module_param_array(fake_ca_system_ids, int, &num_fake_ca_system_ids, 0644); | ||
144 | MODULE_PARM_DESC(fake_ca_system_ids, "If your CAM application manufacturer " | ||
145 | "does not have the same ca_system_id as your CAS, you can " | ||
146 | "override what ca_system_ids are presented to the " | ||
147 | "application by setting this field to an array of ids."); | ||
148 | |||
133 | static const char *debug_fcp_ctype(unsigned int ctype) | 149 | static const char *debug_fcp_ctype(unsigned int ctype) |
134 | { | 150 | { |
135 | static const char *ctypes[] = { | 151 | static const char *ctypes[] = { |
@@ -368,10 +384,30 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, | |||
368 | c->operand[12] = 0; | 384 | c->operand[12] = 0; |
369 | 385 | ||
370 | if (fdtv->type == FIREDTV_DVB_S2) { | 386 | if (fdtv->type == FIREDTV_DVB_S2) { |
371 | c->operand[13] = 0x1; | 387 | if (fdtv->fe.dtv_property_cache.delivery_system == SYS_DVBS2) { |
372 | c->operand[14] = 0xff; | 388 | switch (fdtv->fe.dtv_property_cache.modulation) { |
373 | c->operand[15] = 0xff; | 389 | case QAM_16: c->operand[13] = 0x1; break; |
374 | 390 | case QPSK: c->operand[13] = 0x2; break; | |
391 | case PSK_8: c->operand[13] = 0x3; break; | ||
392 | default: c->operand[13] = 0x2; break; | ||
393 | } | ||
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; | ||
397 | case ROLLOFF_20: c->operand[14] = 0x0; break; | ||
398 | case ROLLOFF_25: c->operand[14] = 0x1; break; | ||
399 | /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */ | ||
400 | } | ||
401 | switch (fdtv->fe.dtv_property_cache.pilot) { | ||
402 | case PILOT_AUTO: c->operand[15] = 0x0; break; | ||
403 | case PILOT_OFF: c->operand[15] = 0x0; break; | ||
404 | case PILOT_ON: c->operand[15] = 0x1; break; | ||
405 | } | ||
406 | } else { | ||
407 | c->operand[13] = 0x1; /* auto modulation */ | ||
408 | c->operand[14] = 0xff; /* disable rolloff */ | ||
409 | c->operand[15] = 0xff; /* disable pilot */ | ||
410 | } | ||
375 | return 16; | 411 | return 16; |
376 | } else { | 412 | } else { |
377 | return 13; | 413 | return 13; |
@@ -977,7 +1013,7 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
977 | { | 1013 | { |
978 | struct avc_command_frame *c = (void *)fdtv->avc_data; | 1014 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
979 | struct avc_response_frame *r = (void *)fdtv->avc_data; | 1015 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
980 | int pos, ret; | 1016 | int i, pos, ret; |
981 | 1017 | ||
982 | mutex_lock(&fdtv->avc_mutex); | 1018 | mutex_lock(&fdtv->avc_mutex); |
983 | 1019 | ||
@@ -1004,9 +1040,18 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
1004 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; | 1040 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; |
1005 | app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; | 1041 | app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; |
1006 | app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; | 1042 | app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; |
1007 | app_info[3] = 2; | 1043 | if (num_fake_ca_system_ids == 0) { |
1008 | app_info[4] = r->operand[pos + 0]; | 1044 | app_info[3] = 2; |
1009 | app_info[5] = r->operand[pos + 1]; | 1045 | app_info[4] = r->operand[pos + 0]; |
1046 | app_info[5] = r->operand[pos + 1]; | ||
1047 | } else { | ||
1048 | app_info[3] = num_fake_ca_system_ids * 2; | ||
1049 | for (i = 0; i < num_fake_ca_system_ids; i++) { | ||
1050 | app_info[4 + i * 2] = | ||
1051 | (fake_ca_system_ids[i] >> 8) & 0xff; | ||
1052 | app_info[5 + i * 2] = fake_ca_system_ids[i] & 0xff; | ||
1053 | } | ||
1054 | } | ||
1010 | *len = app_info[3] + 4; | 1055 | *len = app_info[3] + 4; |
1011 | out: | 1056 | out: |
1012 | mutex_unlock(&fdtv->avc_mutex); | 1057 | mutex_unlock(&fdtv->avc_mutex); |
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c index e49cdc88b0c..d10920e2f3a 100644 --- a/drivers/media/dvb/firewire/firedtv-fe.c +++ b/drivers/media/dvb/firewire/firedtv-fe.c | |||
@@ -155,6 +155,16 @@ static int fdtv_get_frontend(struct dvb_frontend *fe, | |||
155 | return -EOPNOTSUPP; | 155 | return -EOPNOTSUPP; |
156 | } | 156 | } |
157 | 157 | ||
158 | static int fdtv_get_property(struct dvb_frontend *fe, struct dtv_property *tvp) | ||
159 | { | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp) | ||
164 | { | ||
165 | return 0; | ||
166 | } | ||
167 | |||
158 | void fdtv_frontend_init(struct firedtv *fdtv) | 168 | void fdtv_frontend_init(struct firedtv *fdtv) |
159 | { | 169 | { |
160 | struct dvb_frontend_ops *ops = &fdtv->fe.ops; | 170 | struct dvb_frontend_ops *ops = &fdtv->fe.ops; |
@@ -166,6 +176,9 @@ void fdtv_frontend_init(struct firedtv *fdtv) | |||
166 | ops->set_frontend = fdtv_set_frontend; | 176 | ops->set_frontend = fdtv_set_frontend; |
167 | ops->get_frontend = fdtv_get_frontend; | 177 | ops->get_frontend = fdtv_get_frontend; |
168 | 178 | ||
179 | ops->get_property = fdtv_get_property; | ||
180 | ops->set_property = fdtv_set_property; | ||
181 | |||
169 | ops->read_status = fdtv_read_status; | 182 | ops->read_status = fdtv_read_status; |
170 | ops->read_ber = fdtv_read_ber; | 183 | ops->read_ber = fdtv_read_ber; |
171 | ops->read_signal_strength = fdtv_read_signal_strength; | 184 | ops->read_signal_strength = fdtv_read_signal_strength; |
@@ -179,7 +192,6 @@ void fdtv_frontend_init(struct firedtv *fdtv) | |||
179 | 192 | ||
180 | switch (fdtv->type) { | 193 | switch (fdtv->type) { |
181 | case FIREDTV_DVB_S: | 194 | case FIREDTV_DVB_S: |
182 | case FIREDTV_DVB_S2: | ||
183 | fi->type = FE_QPSK; | 195 | fi->type = FE_QPSK; |
184 | 196 | ||
185 | fi->frequency_min = 950000; | 197 | fi->frequency_min = 950000; |
@@ -188,7 +200,7 @@ void fdtv_frontend_init(struct firedtv *fdtv) | |||
188 | fi->symbol_rate_min = 1000000; | 200 | fi->symbol_rate_min = 1000000; |
189 | fi->symbol_rate_max = 40000000; | 201 | fi->symbol_rate_max = 40000000; |
190 | 202 | ||
191 | fi->caps = FE_CAN_INVERSION_AUTO | | 203 | fi->caps = FE_CAN_INVERSION_AUTO | |
192 | FE_CAN_FEC_1_2 | | 204 | FE_CAN_FEC_1_2 | |
193 | FE_CAN_FEC_2_3 | | 205 | FE_CAN_FEC_2_3 | |
194 | FE_CAN_FEC_3_4 | | 206 | FE_CAN_FEC_3_4 | |
@@ -198,6 +210,26 @@ void fdtv_frontend_init(struct firedtv *fdtv) | |||
198 | FE_CAN_QPSK; | 210 | FE_CAN_QPSK; |
199 | break; | 211 | break; |
200 | 212 | ||
213 | case FIREDTV_DVB_S2: | ||
214 | fi->type = FE_QPSK; | ||
215 | |||
216 | fi->frequency_min = 950000; | ||
217 | fi->frequency_max = 2150000; | ||
218 | fi->frequency_stepsize = 125; | ||
219 | fi->symbol_rate_min = 1000000; | ||
220 | fi->symbol_rate_max = 40000000; | ||
221 | |||
222 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
223 | FE_CAN_FEC_1_2 | | ||
224 | FE_CAN_FEC_2_3 | | ||
225 | FE_CAN_FEC_3_4 | | ||
226 | FE_CAN_FEC_5_6 | | ||
227 | FE_CAN_FEC_7_8 | | ||
228 | FE_CAN_FEC_AUTO | | ||
229 | FE_CAN_QPSK | | ||
230 | FE_CAN_2G_MODULATION; | ||
231 | break; | ||
232 | |||
201 | case FIREDTV_DVB_C: | 233 | case FIREDTV_DVB_C: |
202 | fi->type = FE_QAM; | 234 | fi->type = FE_QAM; |
203 | 235 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index b5f6a04f9c1..e9062b08a48 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -257,6 +257,13 @@ config DVB_CX22702 | |||
257 | help | 257 | help |
258 | A DVB-T tuner module. Say Y when you want to support this frontend. | 258 | A DVB-T tuner module. Say Y when you want to support this frontend. |
259 | 259 | ||
260 | config DVB_S5H1432 | ||
261 | tristate "Samsung s5h1432 demodulator (OFDM)" | ||
262 | depends on DVB_CORE && I2C | ||
263 | default m if DVB_FE_CUSTOMISE | ||
264 | help | ||
265 | A DVB-T tuner module. Say Y when you want to support this frontend. | ||
266 | |||
260 | config DVB_DRX397XD | 267 | config DVB_DRX397XD |
261 | tristate "Micronas DRX3975D/DRX3977D based" | 268 | tristate "Micronas DRX3975D/DRX3977D based" |
262 | depends on DVB_CORE && I2C | 269 | depends on DVB_CORE && I2C |
@@ -455,16 +462,8 @@ config DVB_LGDT330X | |||
455 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 462 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
456 | to support this frontend. | 463 | to support this frontend. |
457 | 464 | ||
458 | config DVB_LGDT3304 | ||
459 | tristate "LG Electronics LGDT3304" | ||
460 | depends on DVB_CORE && I2C | ||
461 | default m if DVB_FE_CUSTOMISE | ||
462 | help | ||
463 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | ||
464 | to support this frontend. | ||
465 | |||
466 | config DVB_LGDT3305 | 465 | config DVB_LGDT3305 |
467 | tristate "LG Electronics LGDT3305 based" | 466 | tristate "LG Electronics LGDT3304 and LGDT3305 based" |
468 | depends on DVB_CORE && I2C | 467 | depends on DVB_CORE && I2C |
469 | default m if DVB_FE_CUSTOMISE | 468 | default m if DVB_FE_CUSTOMISE |
470 | help | 469 | help |
@@ -607,6 +606,13 @@ config DVB_TDA665x | |||
607 | Currently supported tuners: | 606 | Currently supported tuners: |
608 | * Panasonic ENV57H12D5 (ET-50DT) | 607 | * Panasonic ENV57H12D5 (ET-50DT) |
609 | 608 | ||
609 | config DVB_IX2505V | ||
610 | tristate "Sharp IX2505V silicon tuner" | ||
611 | depends on DVB_CORE && I2C | ||
612 | default m if DVB_FE_CUSTOMISE | ||
613 | help | ||
614 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
615 | |||
610 | comment "Tools to develop new frontends" | 616 | comment "Tools to develop new frontends" |
611 | 617 | ||
612 | config DVB_DUMMY_FE | 618 | config DVB_DUMMY_FE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 874e8ada4d1..9a31985c0df 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -16,6 +16,7 @@ obj-$(CONFIG_DVB_STB0899) += stb0899.o | |||
16 | obj-$(CONFIG_DVB_STB6100) += stb6100.o | 16 | obj-$(CONFIG_DVB_STB6100) += stb6100.o |
17 | obj-$(CONFIG_DVB_SP8870) += sp8870.o | 17 | obj-$(CONFIG_DVB_SP8870) += sp8870.o |
18 | obj-$(CONFIG_DVB_CX22700) += cx22700.o | 18 | obj-$(CONFIG_DVB_CX22700) += cx22700.o |
19 | obj-$(CONFIG_DVB_S5H1432) += s5h1432.o | ||
19 | obj-$(CONFIG_DVB_CX24110) += cx24110.o | 20 | obj-$(CONFIG_DVB_CX24110) += cx24110.o |
20 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o | 21 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o |
21 | obj-$(CONFIG_DVB_L64781) += l64781.o | 22 | obj-$(CONFIG_DVB_L64781) += l64781.o |
@@ -45,7 +46,6 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o | |||
45 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | 46 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o |
46 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 47 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
47 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 48 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
48 | obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o | ||
49 | obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o | 49 | obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o |
50 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | 50 | obj-$(CONFIG_DVB_CX24123) += cx24123.o |
51 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | 51 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o |
@@ -82,3 +82,4 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o | |||
82 | obj-$(CONFIG_DVB_EC100) += ec100.o | 82 | obj-$(CONFIG_DVB_EC100) += ec100.o |
83 | obj-$(CONFIG_DVB_DS3000) += ds3000.o | 83 | obj-$(CONFIG_DVB_DS3000) += ds3000.o |
84 | obj-$(CONFIG_DVB_MB86A16) += mb86a16.o | 84 | obj-$(CONFIG_DVB_MB86A16) += mb86a16.o |
85 | obj-$(CONFIG_DVB_IX2505V) += ix2505v.o | ||
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index dac917f7bb7..e2a95c07bab 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -42,6 +42,8 @@ struct af9013_state { | |||
42 | 42 | ||
43 | struct af9013_config config; | 43 | struct af9013_config config; |
44 | 44 | ||
45 | /* tuner/demod RF and IF AGC limits used for signal strength calc */ | ||
46 | u8 signal_strength_en, rf_50, rf_80, if_50, if_80; | ||
45 | u16 signal_strength; | 47 | u16 signal_strength; |
46 | u32 ber; | 48 | u32 ber; |
47 | u32 ucblocks; | 49 | u32 ucblocks; |
@@ -220,184 +222,37 @@ static u32 af913_div(u32 a, u32 b, u32 x) | |||
220 | 222 | ||
221 | static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) | 223 | static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) |
222 | { | 224 | { |
223 | int ret = 0; | 225 | int ret, i, j, found; |
224 | u8 i = 0; | ||
225 | u8 buf[24]; | ||
226 | u32 uninitialized_var(ns_coeff1_2048nu); | ||
227 | u32 uninitialized_var(ns_coeff1_8191nu); | ||
228 | u32 uninitialized_var(ns_coeff1_8192nu); | ||
229 | u32 uninitialized_var(ns_coeff1_8193nu); | ||
230 | u32 uninitialized_var(ns_coeff2_2k); | ||
231 | u32 uninitialized_var(ns_coeff2_8k); | ||
232 | |||
233 | deb_info("%s: adc_clock:%d bw:%d\n", __func__, | 226 | deb_info("%s: adc_clock:%d bw:%d\n", __func__, |
234 | state->config.adc_clock, bw); | 227 | state->config.adc_clock, bw); |
235 | 228 | ||
236 | switch (state->config.adc_clock) { | 229 | /* lookup coeff from table */ |
237 | case 28800: /* 28.800 MHz */ | 230 | for (i = 0, found = 0; i < ARRAY_SIZE(coeff_table); i++) { |
238 | switch (bw) { | 231 | if (coeff_table[i].adc_clock == state->config.adc_clock && |
239 | case BANDWIDTH_6_MHZ: | 232 | coeff_table[i].bw == bw) { |
240 | ns_coeff1_2048nu = 0x01e79e7a; | 233 | found = 1; |
241 | ns_coeff1_8191nu = 0x0079eb6e; | ||
242 | ns_coeff1_8192nu = 0x0079e79e; | ||
243 | ns_coeff1_8193nu = 0x0079e3cf; | ||
244 | ns_coeff2_2k = 0x00f3cf3d; | ||
245 | ns_coeff2_8k = 0x003cf3cf; | ||
246 | break; | ||
247 | case BANDWIDTH_7_MHZ: | ||
248 | ns_coeff1_2048nu = 0x0238e38e; | ||
249 | ns_coeff1_8191nu = 0x008e3d55; | ||
250 | ns_coeff1_8192nu = 0x008e38e4; | ||
251 | ns_coeff1_8193nu = 0x008e3472; | ||
252 | ns_coeff2_2k = 0x011c71c7; | ||
253 | ns_coeff2_8k = 0x00471c72; | ||
254 | break; | 234 | break; |
255 | case BANDWIDTH_8_MHZ: | ||
256 | ns_coeff1_2048nu = 0x028a28a3; | ||
257 | ns_coeff1_8191nu = 0x00a28f3d; | ||
258 | ns_coeff1_8192nu = 0x00a28a29; | ||
259 | ns_coeff1_8193nu = 0x00a28514; | ||
260 | ns_coeff2_2k = 0x01451451; | ||
261 | ns_coeff2_8k = 0x00514514; | ||
262 | break; | ||
263 | default: | ||
264 | ret = -EINVAL; | ||
265 | } | 235 | } |
266 | break; | ||
267 | case 20480: /* 20.480 MHz */ | ||
268 | switch (bw) { | ||
269 | case BANDWIDTH_6_MHZ: | ||
270 | ns_coeff1_2048nu = 0x02adb6dc; | ||
271 | ns_coeff1_8191nu = 0x00ab7313; | ||
272 | ns_coeff1_8192nu = 0x00ab6db7; | ||
273 | ns_coeff1_8193nu = 0x00ab685c; | ||
274 | ns_coeff2_2k = 0x0156db6e; | ||
275 | ns_coeff2_8k = 0x0055b6dc; | ||
276 | break; | ||
277 | case BANDWIDTH_7_MHZ: | ||
278 | ns_coeff1_2048nu = 0x03200001; | ||
279 | ns_coeff1_8191nu = 0x00c80640; | ||
280 | ns_coeff1_8192nu = 0x00c80000; | ||
281 | ns_coeff1_8193nu = 0x00c7f9c0; | ||
282 | ns_coeff2_2k = 0x01900000; | ||
283 | ns_coeff2_8k = 0x00640000; | ||
284 | break; | ||
285 | case BANDWIDTH_8_MHZ: | ||
286 | ns_coeff1_2048nu = 0x03924926; | ||
287 | ns_coeff1_8191nu = 0x00e4996e; | ||
288 | ns_coeff1_8192nu = 0x00e49249; | ||
289 | ns_coeff1_8193nu = 0x00e48b25; | ||
290 | ns_coeff2_2k = 0x01c92493; | ||
291 | ns_coeff2_8k = 0x00724925; | ||
292 | break; | ||
293 | default: | ||
294 | ret = -EINVAL; | ||
295 | } | ||
296 | break; | ||
297 | case 28000: /* 28.000 MHz */ | ||
298 | switch (bw) { | ||
299 | case BANDWIDTH_6_MHZ: | ||
300 | ns_coeff1_2048nu = 0x01f58d10; | ||
301 | ns_coeff1_8191nu = 0x007d672f; | ||
302 | ns_coeff1_8192nu = 0x007d6344; | ||
303 | ns_coeff1_8193nu = 0x007d5f59; | ||
304 | ns_coeff2_2k = 0x00fac688; | ||
305 | ns_coeff2_8k = 0x003eb1a2; | ||
306 | break; | ||
307 | case BANDWIDTH_7_MHZ: | ||
308 | ns_coeff1_2048nu = 0x02492492; | ||
309 | ns_coeff1_8191nu = 0x00924db7; | ||
310 | ns_coeff1_8192nu = 0x00924925; | ||
311 | ns_coeff1_8193nu = 0x00924492; | ||
312 | ns_coeff2_2k = 0x01249249; | ||
313 | ns_coeff2_8k = 0x00492492; | ||
314 | break; | ||
315 | case BANDWIDTH_8_MHZ: | ||
316 | ns_coeff1_2048nu = 0x029cbc15; | ||
317 | ns_coeff1_8191nu = 0x00a7343f; | ||
318 | ns_coeff1_8192nu = 0x00a72f05; | ||
319 | ns_coeff1_8193nu = 0x00a729cc; | ||
320 | ns_coeff2_2k = 0x014e5e0a; | ||
321 | ns_coeff2_8k = 0x00539783; | ||
322 | break; | ||
323 | default: | ||
324 | ret = -EINVAL; | ||
325 | } | ||
326 | break; | ||
327 | case 25000: /* 25.000 MHz */ | ||
328 | switch (bw) { | ||
329 | case BANDWIDTH_6_MHZ: | ||
330 | ns_coeff1_2048nu = 0x0231bcb5; | ||
331 | ns_coeff1_8191nu = 0x008c7391; | ||
332 | ns_coeff1_8192nu = 0x008c6f2d; | ||
333 | ns_coeff1_8193nu = 0x008c6aca; | ||
334 | ns_coeff2_2k = 0x0118de5b; | ||
335 | ns_coeff2_8k = 0x00463797; | ||
336 | break; | ||
337 | case BANDWIDTH_7_MHZ: | ||
338 | ns_coeff1_2048nu = 0x028f5c29; | ||
339 | ns_coeff1_8191nu = 0x00a3dc29; | ||
340 | ns_coeff1_8192nu = 0x00a3d70a; | ||
341 | ns_coeff1_8193nu = 0x00a3d1ec; | ||
342 | ns_coeff2_2k = 0x0147ae14; | ||
343 | ns_coeff2_8k = 0x0051eb85; | ||
344 | break; | ||
345 | case BANDWIDTH_8_MHZ: | ||
346 | ns_coeff1_2048nu = 0x02ecfb9d; | ||
347 | ns_coeff1_8191nu = 0x00bb44c1; | ||
348 | ns_coeff1_8192nu = 0x00bb3ee7; | ||
349 | ns_coeff1_8193nu = 0x00bb390d; | ||
350 | ns_coeff2_2k = 0x01767dce; | ||
351 | ns_coeff2_8k = 0x005d9f74; | ||
352 | break; | ||
353 | default: | ||
354 | ret = -EINVAL; | ||
355 | } | ||
356 | break; | ||
357 | default: | ||
358 | err("invalid xtal"); | ||
359 | return -EINVAL; | ||
360 | } | 236 | } |
361 | if (ret) { | 237 | |
362 | err("invalid bandwidth"); | 238 | if (!found) { |
363 | return ret; | 239 | err("invalid bw or clock"); |
240 | ret = -EINVAL; | ||
241 | goto error; | ||
364 | } | 242 | } |
365 | 243 | ||
366 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); | 244 | deb_info("%s: coeff: ", __func__); |
367 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); | 245 | debug_dump(coeff_table[i].val, sizeof(coeff_table[i].val), deb_info); |
368 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); | ||
369 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); | ||
370 | buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); | ||
371 | buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); | ||
372 | buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); | ||
373 | buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); | ||
374 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); | ||
375 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); | ||
376 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); | ||
377 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); | ||
378 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); | ||
379 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); | ||
380 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); | ||
381 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); | ||
382 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); | ||
383 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); | ||
384 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); | ||
385 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); | ||
386 | buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); | ||
387 | buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); | ||
388 | buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); | ||
389 | buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); | ||
390 | |||
391 | deb_info("%s: coeff:", __func__); | ||
392 | debug_dump(buf, sizeof(buf), deb_info); | ||
393 | 246 | ||
394 | /* program */ | 247 | /* program */ |
395 | for (i = 0; i < sizeof(buf); i++) { | 248 | for (j = 0; j < sizeof(coeff_table[i].val); j++) { |
396 | ret = af9013_write_reg(state, 0xae00 + i, buf[i]); | 249 | ret = af9013_write_reg(state, 0xae00 + j, |
250 | coeff_table[i].val[j]); | ||
397 | if (ret) | 251 | if (ret) |
398 | break; | 252 | break; |
399 | } | 253 | } |
400 | 254 | ||
255 | error: | ||
401 | return ret; | 256 | return ret; |
402 | } | 257 | } |
403 | 258 | ||
@@ -486,6 +341,19 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) | |||
486 | if_sample_freq = 4300000; /* 4.3 MHz */ | 341 | if_sample_freq = 4300000; /* 4.3 MHz */ |
487 | break; | 342 | break; |
488 | } | 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 | } | ||
489 | } | 357 | } |
490 | 358 | ||
491 | while (if_sample_freq > (adc_freq / 2)) | 359 | while (if_sample_freq > (adc_freq / 2)) |
@@ -1097,45 +965,31 @@ static int af9013_update_signal_strength(struct dvb_frontend *fe) | |||
1097 | { | 965 | { |
1098 | struct af9013_state *state = fe->demodulator_priv; | 966 | struct af9013_state *state = fe->demodulator_priv; |
1099 | int ret; | 967 | int ret; |
1100 | u8 tmp0; | 968 | u8 rf_gain, if_gain; |
1101 | u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; | ||
1102 | int signal_strength; | 969 | int signal_strength; |
1103 | 970 | ||
1104 | deb_info("%s\n", __func__); | 971 | deb_info("%s\n", __func__); |
1105 | 972 | ||
1106 | state->signal_strength = 0; | 973 | if (state->signal_strength_en) { |
1107 | |||
1108 | ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); | ||
1109 | if (ret) | ||
1110 | goto error; | ||
1111 | if (tmp0) { | ||
1112 | ret = af9013_read_reg(state, 0x9bbd, &rf_50); | ||
1113 | if (ret) | ||
1114 | goto error; | ||
1115 | ret = af9013_read_reg(state, 0x9bd0, &rf_80); | ||
1116 | if (ret) | ||
1117 | goto error; | ||
1118 | ret = af9013_read_reg(state, 0x9be2, &if_50); | ||
1119 | if (ret) | ||
1120 | goto error; | ||
1121 | ret = af9013_read_reg(state, 0x9be4, &if_80); | ||
1122 | if (ret) | ||
1123 | goto error; | ||
1124 | ret = af9013_read_reg(state, 0xd07c, &rf_gain); | 974 | ret = af9013_read_reg(state, 0xd07c, &rf_gain); |
1125 | if (ret) | 975 | if (ret) |
1126 | goto error; | 976 | goto error; |
1127 | ret = af9013_read_reg(state, 0xd07d, &if_gain); | 977 | ret = af9013_read_reg(state, 0xd07d, &if_gain); |
1128 | if (ret) | 978 | if (ret) |
1129 | goto error; | 979 | goto error; |
1130 | signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ | 980 | signal_strength = (0xffff / \ |
1131 | 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ | 981 | (9 * (state->rf_50 + state->if_50) - \ |
1132 | 11 * (rf_80 + if_80)); | 982 | 11 * (state->rf_80 + state->if_80))) * \ |
983 | (10 * (rf_gain + if_gain) - \ | ||
984 | 11 * (state->rf_80 + state->if_80)); | ||
1133 | if (signal_strength < 0) | 985 | if (signal_strength < 0) |
1134 | signal_strength = 0; | 986 | signal_strength = 0; |
1135 | else if (signal_strength > 0xffff) | 987 | else if (signal_strength > 0xffff) |
1136 | signal_strength = 0xffff; | 988 | signal_strength = 0xffff; |
1137 | 989 | ||
1138 | state->signal_strength = signal_strength; | 990 | state->signal_strength = signal_strength; |
991 | } else { | ||
992 | state->signal_strength = 0; | ||
1139 | } | 993 | } |
1140 | 994 | ||
1141 | error: | 995 | error: |
@@ -1368,6 +1222,7 @@ static int af9013_init(struct dvb_frontend *fe) | |||
1368 | break; | 1222 | break; |
1369 | case AF9013_TUNER_MXL5005D: | 1223 | case AF9013_TUNER_MXL5005D: |
1370 | case AF9013_TUNER_MXL5005R: | 1224 | case AF9013_TUNER_MXL5005R: |
1225 | case AF9013_TUNER_MXL5007T: | ||
1371 | len = ARRAY_SIZE(tuner_init_mxl5005); | 1226 | len = ARRAY_SIZE(tuner_init_mxl5005); |
1372 | init = tuner_init_mxl5005; | 1227 | init = tuner_init_mxl5005; |
1373 | break; | 1228 | break; |
@@ -1393,6 +1248,7 @@ static int af9013_init(struct dvb_frontend *fe) | |||
1393 | init = tuner_init_mt2060_2; | 1248 | init = tuner_init_mt2060_2; |
1394 | break; | 1249 | break; |
1395 | case AF9013_TUNER_TDA18271: | 1250 | case AF9013_TUNER_TDA18271: |
1251 | case AF9013_TUNER_TDA18218: | ||
1396 | len = ARRAY_SIZE(tuner_init_tda18271); | 1252 | len = ARRAY_SIZE(tuner_init_tda18271); |
1397 | init = tuner_init_tda18271; | 1253 | init = tuner_init_tda18271; |
1398 | break; | 1254 | break; |
@@ -1438,6 +1294,27 @@ static int af9013_init(struct dvb_frontend *fe) | |||
1438 | if (ret) | 1294 | if (ret) |
1439 | goto error; | 1295 | goto error; |
1440 | 1296 | ||
1297 | /* read values needed for signal strength calculation */ | ||
1298 | ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, | ||
1299 | &state->signal_strength_en); | ||
1300 | if (ret) | ||
1301 | goto error; | ||
1302 | |||
1303 | if (state->signal_strength_en) { | ||
1304 | ret = af9013_read_reg(state, 0x9bbd, &state->rf_50); | ||
1305 | if (ret) | ||
1306 | goto error; | ||
1307 | ret = af9013_read_reg(state, 0x9bd0, &state->rf_80); | ||
1308 | if (ret) | ||
1309 | goto error; | ||
1310 | ret = af9013_read_reg(state, 0x9be2, &state->if_50); | ||
1311 | if (ret) | ||
1312 | goto error; | ||
1313 | ret = af9013_read_reg(state, 0x9be4, &state->if_80); | ||
1314 | if (ret) | ||
1315 | goto error; | ||
1316 | } | ||
1317 | |||
1441 | error: | 1318 | error: |
1442 | return ret; | 1319 | return ret; |
1443 | } | 1320 | } |
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h index 72c71bb5d11..e53d873f755 100644 --- a/drivers/media/dvb/frontends/af9013.h +++ b/drivers/media/dvb/frontends/af9013.h | |||
@@ -44,6 +44,7 @@ enum af9013_tuner { | |||
44 | AF9013_TUNER_MT2060_2 = 147, /* Microtune */ | 44 | AF9013_TUNER_MT2060_2 = 147, /* Microtune */ |
45 | AF9013_TUNER_TDA18271 = 156, /* NXP */ | 45 | AF9013_TUNER_TDA18271 = 156, /* NXP */ |
46 | AF9013_TUNER_QT1010A = 162, /* Quantek */ | 46 | AF9013_TUNER_QT1010A = 162, /* Quantek */ |
47 | AF9013_TUNER_MXL5007T = 177, /* MaxLinear */ | ||
47 | AF9013_TUNER_TDA18218 = 179, /* NXP */ | 48 | AF9013_TUNER_TDA18218 = 179, /* NXP */ |
48 | }; | 49 | }; |
49 | 50 | ||
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h index 0fd42b7e248..e00b2a4a2db 100644 --- a/drivers/media/dvb/frontends/af9013_priv.h +++ b/drivers/media/dvb/frontends/af9013_priv.h | |||
@@ -60,6 +60,56 @@ struct snr_table { | |||
60 | u8 snr; | 60 | u8 snr; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | struct coeff { | ||
64 | u32 adc_clock; | ||
65 | fe_bandwidth_t bw; | ||
66 | u8 val[24]; | ||
67 | }; | ||
68 | |||
69 | /* pre-calculated coeff lookup table */ | ||
70 | static struct coeff coeff_table[] = { | ||
71 | /* 28.800 MHz */ | ||
72 | { 28800, BANDWIDTH_8_MHZ, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14, | ||
73 | 0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a, | ||
74 | 0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } }, | ||
75 | { 28800, BANDWIDTH_7_MHZ, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71, | ||
76 | 0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38, | ||
77 | 0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } }, | ||
78 | { 28800, BANDWIDTH_6_MHZ, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf, | ||
79 | 0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7, | ||
80 | 0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } }, | ||
81 | /* 20.480 MHz */ | ||
82 | { 20480, BANDWIDTH_8_MHZ, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24, | ||
83 | 0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92, | ||
84 | 0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } }, | ||
85 | { 20480, BANDWIDTH_7_MHZ, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40, | ||
86 | 0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00, | ||
87 | 0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } }, | ||
88 | { 20480, BANDWIDTH_6_MHZ, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b, | ||
89 | 0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d, | ||
90 | 0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } }, | ||
91 | /* 28.000 MHz */ | ||
92 | { 28000, BANDWIDTH_8_MHZ, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39, | ||
93 | 0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f, | ||
94 | 0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } }, | ||
95 | { 28000, BANDWIDTH_7_MHZ, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92, | ||
96 | 0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49, | ||
97 | 0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } }, | ||
98 | { 28000, BANDWIDTH_6_MHZ, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb, | ||
99 | 0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63, | ||
100 | 0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } }, | ||
101 | /* 25.000 MHz */ | ||
102 | { 25000, BANDWIDTH_8_MHZ, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9, | ||
103 | 0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e, | ||
104 | 0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } }, | ||
105 | { 25000, BANDWIDTH_7_MHZ, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e, | ||
106 | 0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7, | ||
107 | 0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } }, | ||
108 | { 25000, BANDWIDTH_6_MHZ, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63, | ||
109 | 0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f, | ||
110 | 0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } }, | ||
111 | }; | ||
112 | |||
63 | /* QPSK SNR lookup table */ | 113 | /* QPSK SNR lookup table */ |
64 | static struct snr_table qpsk_snr_table[] = { | 114 | static struct snr_table qpsk_snr_table[] = { |
65 | { 0x0b4771, 0 }, | 115 | { 0x0b4771, 0 }, |
@@ -480,9 +530,10 @@ static struct regdesc tuner_init_mxl5003d[] = { | |||
480 | { 0x9bd9, 0, 8, 0x08 }, | 530 | { 0x9bd9, 0, 8, 0x08 }, |
481 | }; | 531 | }; |
482 | 532 | ||
483 | /* MaxLinear MXL5005 tuner init | 533 | /* MaxLinear MXL5005S & MXL5007T tuner init |
484 | AF9013_TUNER_MXL5005D = 13 | 534 | AF9013_TUNER_MXL5005D = 13 |
485 | AF9013_TUNER_MXL5005R = 30 */ | 535 | AF9013_TUNER_MXL5005R = 30 |
536 | AF9013_TUNER_MXL5007T = 177 */ | ||
486 | static struct regdesc tuner_init_mxl5005[] = { | 537 | static struct regdesc tuner_init_mxl5005[] = { |
487 | { 0x9bd5, 0, 8, 0x01 }, | 538 | { 0x9bd5, 0, 8, 0x01 }, |
488 | { 0x9bd6, 0, 8, 0x07 }, | 539 | { 0x9bd6, 0, 8, 0x07 }, |
@@ -791,8 +842,9 @@ static struct regdesc tuner_init_unknown[] = { | |||
791 | { 0x9bd9, 0, 8, 0x08 }, | 842 | { 0x9bd9, 0, 8, 0x08 }, |
792 | }; | 843 | }; |
793 | 844 | ||
794 | /* NXP TDA18271 tuner init | 845 | /* NXP TDA18271 & TDA18218 tuner init |
795 | AF9013_TUNER_TDA18271 = 156 */ | 846 | AF9013_TUNER_TDA18271 = 156 |
847 | AF9013_TUNER_TDA18218 = 179 */ | ||
796 | static struct regdesc tuner_init_tda18271[] = { | 848 | static struct regdesc tuner_init_tda18271[] = { |
797 | { 0x9bd5, 0, 8, 0x01 }, | 849 | { 0x9bd5, 0, 8, 0x01 }, |
798 | { 0x9bd6, 0, 8, 0x04 }, | 850 | { 0x9bd6, 0, 8, 0x04 }, |
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 29cdbfe3685..6d9c5943eb3 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <media/v4l2-chip-ident.h> | 38 | #include <media/v4l2-chip-ident.h> |
39 | #include <media/v4l2-i2c-drv.h> | ||
40 | #include <media/v4l2-device.h> | 39 | #include <media/v4l2-device.h> |
41 | #include "au8522.h" | 40 | #include "au8522.h" |
42 | #include "au8522_priv.h" | 41 | #include "au8522_priv.h" |
@@ -831,9 +830,25 @@ static const struct i2c_device_id au8522_id[] = { | |||
831 | 830 | ||
832 | MODULE_DEVICE_TABLE(i2c, au8522_id); | 831 | MODULE_DEVICE_TABLE(i2c, au8522_id); |
833 | 832 | ||
834 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 833 | static struct i2c_driver au8522_driver = { |
835 | .name = "au8522", | 834 | .driver = { |
836 | .probe = au8522_probe, | 835 | .owner = THIS_MODULE, |
837 | .remove = au8522_remove, | 836 | .name = "au8522", |
838 | .id_table = au8522_id, | 837 | }, |
838 | .probe = au8522_probe, | ||
839 | .remove = au8522_remove, | ||
840 | .id_table = au8522_id, | ||
839 | }; | 841 | }; |
842 | |||
843 | static __init int init_au8522(void) | ||
844 | { | ||
845 | return i2c_add_driver(&au8522_driver); | ||
846 | } | ||
847 | |||
848 | static __exit void exit_au8522(void) | ||
849 | { | ||
850 | i2c_del_driver(&au8522_driver); | ||
851 | } | ||
852 | |||
853 | module_init(init_au8522); | ||
854 | module_exit(exit_au8522); | ||
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 00b5c7e91d5..ff6c4983051 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | |||
54 | #define dprintk if (debug) printk | 54 | #define dprintk if (debug) printk |
55 | 55 | ||
56 | /* Register values to initialise the demod */ | 56 | /* Register values to initialise the demod */ |
57 | static u8 init_tab[] = { | 57 | static const u8 init_tab[] = { |
58 | 0x00, 0x00, /* Stop aquisition */ | 58 | 0x00, 0x00, /* Stop aquisition */ |
59 | 0x0B, 0x06, | 59 | 0x0B, 0x06, |
60 | 0x09, 0x01, | 60 | 0x09, 0x01, |
@@ -92,52 +92,56 @@ static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) | |||
92 | 92 | ||
93 | ret = i2c_transfer(state->i2c, &msg, 1); | 93 | ret = i2c_transfer(state->i2c, &msg, 1); |
94 | 94 | ||
95 | if (ret != 1) | 95 | if (unlikely(ret != 1)) { |
96 | printk(KERN_ERR | 96 | printk(KERN_ERR |
97 | "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", | 97 | "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", |
98 | __func__, reg, data, ret); | 98 | __func__, reg, data, ret); |
99 | return -1; | ||
100 | } | ||
99 | 101 | ||
100 | return (ret != 1) ? -1 : 0; | 102 | return 0; |
101 | } | 103 | } |
102 | 104 | ||
103 | static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) | 105 | static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) |
104 | { | 106 | { |
105 | int ret; | 107 | int ret; |
106 | u8 b0[] = { reg }; | 108 | u8 data; |
107 | u8 b1[] = { 0 }; | ||
108 | 109 | ||
109 | struct i2c_msg msg[] = { | 110 | struct i2c_msg msg[] = { |
110 | { .addr = state->config->demod_address, .flags = 0, | 111 | { .addr = state->config->demod_address, .flags = 0, |
111 | .buf = b0, .len = 1 }, | 112 | .buf = ®, .len = 1 }, |
112 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | 113 | { .addr = state->config->demod_address, .flags = I2C_M_RD, |
113 | .buf = b1, .len = 1 } }; | 114 | .buf = &data, .len = 1 } }; |
114 | 115 | ||
115 | ret = i2c_transfer(state->i2c, msg, 2); | 116 | ret = i2c_transfer(state->i2c, msg, 2); |
116 | 117 | ||
117 | if (ret != 2) | 118 | if (unlikely(ret != 2)) { |
118 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", | 119 | printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n", |
119 | __func__, ret); | 120 | __func__, reg, ret); |
121 | return 0; | ||
122 | } | ||
120 | 123 | ||
121 | return b1[0]; | 124 | return data; |
122 | } | 125 | } |
123 | 126 | ||
124 | static int cx22702_set_inversion(struct cx22702_state *state, int inversion) | 127 | static int cx22702_set_inversion(struct cx22702_state *state, int inversion) |
125 | { | 128 | { |
126 | u8 val; | 129 | u8 val; |
127 | 130 | ||
131 | val = cx22702_readreg(state, 0x0C); | ||
128 | switch (inversion) { | 132 | switch (inversion) { |
129 | case INVERSION_AUTO: | 133 | case INVERSION_AUTO: |
130 | return -EOPNOTSUPP; | 134 | return -EOPNOTSUPP; |
131 | case INVERSION_ON: | 135 | case INVERSION_ON: |
132 | val = cx22702_readreg(state, 0x0C); | 136 | val |= 0x01; |
133 | return cx22702_writereg(state, 0x0C, val | 0x01); | 137 | break; |
134 | case INVERSION_OFF: | 138 | case INVERSION_OFF: |
135 | val = cx22702_readreg(state, 0x0C); | 139 | val &= 0xfe; |
136 | return cx22702_writereg(state, 0x0C, val & 0xfe); | 140 | break; |
137 | default: | 141 | default: |
138 | return -EINVAL; | 142 | return -EINVAL; |
139 | } | 143 | } |
140 | 144 | return cx22702_writereg(state, 0x0C, val); | |
141 | } | 145 | } |
142 | 146 | ||
143 | /* Retrieve the demod settings */ | 147 | /* Retrieve the demod settings */ |
@@ -244,13 +248,15 @@ static int cx22702_get_tps(struct cx22702_state *state, | |||
244 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | 248 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
245 | { | 249 | { |
246 | struct cx22702_state *state = fe->demodulator_priv; | 250 | struct cx22702_state *state = fe->demodulator_priv; |
251 | u8 val; | ||
252 | |||
247 | dprintk("%s(%d)\n", __func__, enable); | 253 | dprintk("%s(%d)\n", __func__, enable); |
254 | val = cx22702_readreg(state, 0x0D); | ||
248 | if (enable) | 255 | if (enable) |
249 | return cx22702_writereg(state, 0x0D, | 256 | val &= 0xfe; |
250 | cx22702_readreg(state, 0x0D) & 0xfe); | ||
251 | else | 257 | else |
252 | return cx22702_writereg(state, 0x0D, | 258 | val |= 0x01; |
253 | cx22702_readreg(state, 0x0D) | 1); | 259 | return cx22702_writereg(state, 0x0D, val); |
254 | } | 260 | } |
255 | 261 | ||
256 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 262 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
@@ -270,23 +276,21 @@ static int cx22702_set_tps(struct dvb_frontend *fe, | |||
270 | cx22702_set_inversion(state, p->inversion); | 276 | cx22702_set_inversion(state, p->inversion); |
271 | 277 | ||
272 | /* set bandwidth */ | 278 | /* set bandwidth */ |
279 | val = cx22702_readreg(state, 0x0C) & 0xcf; | ||
273 | switch (p->u.ofdm.bandwidth) { | 280 | switch (p->u.ofdm.bandwidth) { |
274 | case BANDWIDTH_6_MHZ: | 281 | case BANDWIDTH_6_MHZ: |
275 | cx22702_writereg(state, 0x0C, | 282 | val |= 0x20; |
276 | (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); | ||
277 | break; | 283 | break; |
278 | case BANDWIDTH_7_MHZ: | 284 | case BANDWIDTH_7_MHZ: |
279 | cx22702_writereg(state, 0x0C, | 285 | val |= 0x10; |
280 | (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); | ||
281 | break; | 286 | break; |
282 | case BANDWIDTH_8_MHZ: | 287 | case BANDWIDTH_8_MHZ: |
283 | cx22702_writereg(state, 0x0C, | ||
284 | cx22702_readreg(state, 0x0C) & 0xcf); | ||
285 | break; | 288 | break; |
286 | default: | 289 | default: |
287 | dprintk("%s: invalid bandwidth\n", __func__); | 290 | dprintk("%s: invalid bandwidth\n", __func__); |
288 | return -EINVAL; | 291 | return -EINVAL; |
289 | } | 292 | } |
293 | cx22702_writereg(state, 0x0C, val); | ||
290 | 294 | ||
291 | p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ | 295 | p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ |
292 | 296 | ||
@@ -312,33 +316,31 @@ static int cx22702_set_tps(struct dvb_frontend *fe, | |||
312 | } | 316 | } |
313 | 317 | ||
314 | /* manually programmed values */ | 318 | /* manually programmed values */ |
315 | val = 0; | 319 | switch (p->u.ofdm.constellation) { /* mask 0x18 */ |
316 | switch (p->u.ofdm.constellation) { | ||
317 | case QPSK: | 320 | case QPSK: |
318 | val = (val & 0xe7); | 321 | val = 0x00; |
319 | break; | 322 | break; |
320 | case QAM_16: | 323 | case QAM_16: |
321 | val = (val & 0xe7) | 0x08; | 324 | val = 0x08; |
322 | break; | 325 | break; |
323 | case QAM_64: | 326 | case QAM_64: |
324 | val = (val & 0xe7) | 0x10; | 327 | val = 0x10; |
325 | break; | 328 | break; |
326 | default: | 329 | default: |
327 | dprintk("%s: invalid constellation\n", __func__); | 330 | dprintk("%s: invalid constellation\n", __func__); |
328 | return -EINVAL; | 331 | return -EINVAL; |
329 | } | 332 | } |
330 | switch (p->u.ofdm.hierarchy_information) { | 333 | switch (p->u.ofdm.hierarchy_information) { /* mask 0x07 */ |
331 | case HIERARCHY_NONE: | 334 | case HIERARCHY_NONE: |
332 | val = (val & 0xf8); | ||
333 | break; | 335 | break; |
334 | case HIERARCHY_1: | 336 | case HIERARCHY_1: |
335 | val = (val & 0xf8) | 1; | 337 | val |= 0x01; |
336 | break; | 338 | break; |
337 | case HIERARCHY_2: | 339 | case HIERARCHY_2: |
338 | val = (val & 0xf8) | 2; | 340 | val |= 0x02; |
339 | break; | 341 | break; |
340 | case HIERARCHY_4: | 342 | case HIERARCHY_4: |
341 | val = (val & 0xf8) | 3; | 343 | val |= 0x03; |
342 | break; | 344 | break; |
343 | default: | 345 | default: |
344 | dprintk("%s: invalid hierarchy\n", __func__); | 346 | dprintk("%s: invalid hierarchy\n", __func__); |
@@ -346,44 +348,42 @@ static int cx22702_set_tps(struct dvb_frontend *fe, | |||
346 | } | 348 | } |
347 | cx22702_writereg(state, 0x06, val); | 349 | cx22702_writereg(state, 0x06, val); |
348 | 350 | ||
349 | val = 0; | 351 | switch (p->u.ofdm.code_rate_HP) { /* mask 0x38 */ |
350 | switch (p->u.ofdm.code_rate_HP) { | ||
351 | case FEC_NONE: | 352 | case FEC_NONE: |
352 | case FEC_1_2: | 353 | case FEC_1_2: |
353 | val = (val & 0xc7); | 354 | val = 0x00; |
354 | break; | 355 | break; |
355 | case FEC_2_3: | 356 | case FEC_2_3: |
356 | val = (val & 0xc7) | 0x08; | 357 | val = 0x08; |
357 | break; | 358 | break; |
358 | case FEC_3_4: | 359 | case FEC_3_4: |
359 | val = (val & 0xc7) | 0x10; | 360 | val = 0x10; |
360 | break; | 361 | break; |
361 | case FEC_5_6: | 362 | case FEC_5_6: |
362 | val = (val & 0xc7) | 0x18; | 363 | val = 0x18; |
363 | break; | 364 | break; |
364 | case FEC_7_8: | 365 | case FEC_7_8: |
365 | val = (val & 0xc7) | 0x20; | 366 | val = 0x20; |
366 | break; | 367 | break; |
367 | default: | 368 | default: |
368 | dprintk("%s: invalid code_rate_HP\n", __func__); | 369 | dprintk("%s: invalid code_rate_HP\n", __func__); |
369 | return -EINVAL; | 370 | return -EINVAL; |
370 | } | 371 | } |
371 | switch (p->u.ofdm.code_rate_LP) { | 372 | switch (p->u.ofdm.code_rate_LP) { /* mask 0x07 */ |
372 | case FEC_NONE: | 373 | case FEC_NONE: |
373 | case FEC_1_2: | 374 | case FEC_1_2: |
374 | val = (val & 0xf8); | ||
375 | break; | 375 | break; |
376 | case FEC_2_3: | 376 | case FEC_2_3: |
377 | val = (val & 0xf8) | 1; | 377 | val |= 0x01; |
378 | break; | 378 | break; |
379 | case FEC_3_4: | 379 | case FEC_3_4: |
380 | val = (val & 0xf8) | 2; | 380 | val |= 0x02; |
381 | break; | 381 | break; |
382 | case FEC_5_6: | 382 | case FEC_5_6: |
383 | val = (val & 0xf8) | 3; | 383 | val |= 0x03; |
384 | break; | 384 | break; |
385 | case FEC_7_8: | 385 | case FEC_7_8: |
386 | val = (val & 0xf8) | 4; | 386 | val |= 0x04; |
387 | break; | 387 | break; |
388 | default: | 388 | default: |
389 | dprintk("%s: invalid code_rate_LP\n", __func__); | 389 | dprintk("%s: invalid code_rate_LP\n", __func__); |
@@ -391,30 +391,28 @@ static int cx22702_set_tps(struct dvb_frontend *fe, | |||
391 | } | 391 | } |
392 | cx22702_writereg(state, 0x07, val); | 392 | cx22702_writereg(state, 0x07, val); |
393 | 393 | ||
394 | val = 0; | 394 | switch (p->u.ofdm.guard_interval) { /* mask 0x0c */ |
395 | switch (p->u.ofdm.guard_interval) { | ||
396 | case GUARD_INTERVAL_1_32: | 395 | case GUARD_INTERVAL_1_32: |
397 | val = (val & 0xf3); | 396 | val = 0x00; |
398 | break; | 397 | break; |
399 | case GUARD_INTERVAL_1_16: | 398 | case GUARD_INTERVAL_1_16: |
400 | val = (val & 0xf3) | 0x04; | 399 | val = 0x04; |
401 | break; | 400 | break; |
402 | case GUARD_INTERVAL_1_8: | 401 | case GUARD_INTERVAL_1_8: |
403 | val = (val & 0xf3) | 0x08; | 402 | val = 0x08; |
404 | break; | 403 | break; |
405 | case GUARD_INTERVAL_1_4: | 404 | case GUARD_INTERVAL_1_4: |
406 | val = (val & 0xf3) | 0x0c; | 405 | val = 0x0c; |
407 | break; | 406 | break; |
408 | default: | 407 | default: |
409 | dprintk("%s: invalid guard_interval\n", __func__); | 408 | dprintk("%s: invalid guard_interval\n", __func__); |
410 | return -EINVAL; | 409 | return -EINVAL; |
411 | } | 410 | } |
412 | switch (p->u.ofdm.transmission_mode) { | 411 | switch (p->u.ofdm.transmission_mode) { /* mask 0x03 */ |
413 | case TRANSMISSION_MODE_2K: | 412 | case TRANSMISSION_MODE_2K: |
414 | val = (val & 0xfc); | ||
415 | break; | 413 | break; |
416 | case TRANSMISSION_MODE_8K: | 414 | case TRANSMISSION_MODE_8K: |
417 | val = (val & 0xfc) | 1; | 415 | val |= 0x1; |
418 | break; | 416 | break; |
419 | default: | 417 | default: |
420 | dprintk("%s: invalid transmission_mode\n", __func__); | 418 | dprintk("%s: invalid transmission_mode\n", __func__); |
@@ -505,7 +503,7 @@ static int cx22702_read_signal_strength(struct dvb_frontend *fe, | |||
505 | { | 503 | { |
506 | struct cx22702_state *state = fe->demodulator_priv; | 504 | struct cx22702_state *state = fe->demodulator_priv; |
507 | 505 | ||
508 | u16 rs_ber = 0; | 506 | u16 rs_ber; |
509 | rs_ber = cx22702_readreg(state, 0x23); | 507 | rs_ber = cx22702_readreg(state, 0x23); |
510 | *signal_strength = (rs_ber << 8) | rs_ber; | 508 | *signal_strength = (rs_ber << 8) | rs_ber; |
511 | 509 | ||
@@ -516,7 +514,7 @@ static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
516 | { | 514 | { |
517 | struct cx22702_state *state = fe->demodulator_priv; | 515 | struct cx22702_state *state = fe->demodulator_priv; |
518 | 516 | ||
519 | u16 rs_ber = 0; | 517 | u16 rs_ber; |
520 | if (cx22702_readreg(state, 0xE4) & 0x02) { | 518 | if (cx22702_readreg(state, 0xE4) & 0x02) { |
521 | /* Realtime statistics */ | 519 | /* Realtime statistics */ |
522 | rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 | 520 | rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
@@ -572,7 +570,7 @@ static void cx22702_release(struct dvb_frontend *fe) | |||
572 | kfree(state); | 570 | kfree(state); |
573 | } | 571 | } |
574 | 572 | ||
575 | static struct dvb_frontend_ops cx22702_ops; | 573 | static const struct dvb_frontend_ops cx22702_ops; |
576 | 574 | ||
577 | struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, | 575 | struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, |
578 | struct i2c_adapter *i2c) | 576 | struct i2c_adapter *i2c) |
@@ -587,7 +585,6 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, | |||
587 | /* setup the state */ | 585 | /* setup the state */ |
588 | state->config = config; | 586 | state->config = config; |
589 | state->i2c = i2c; | 587 | state->i2c = i2c; |
590 | state->prevUCBlocks = 0; | ||
591 | 588 | ||
592 | /* check if the demod is there */ | 589 | /* check if the demod is there */ |
593 | if (cx22702_readreg(state, 0x1f) != 0x3) | 590 | if (cx22702_readreg(state, 0x1f) != 0x3) |
@@ -605,7 +602,7 @@ error: | |||
605 | } | 602 | } |
606 | EXPORT_SYMBOL(cx22702_attach); | 603 | EXPORT_SYMBOL(cx22702_attach); |
607 | 604 | ||
608 | static struct dvb_frontend_ops cx22702_ops = { | 605 | static const struct dvb_frontend_ops cx22702_ops = { |
609 | 606 | ||
610 | .info = { | 607 | .info = { |
611 | .name = "Conexant CX22702 DVB-T", | 608 | .name = "Conexant CX22702 DVB-T", |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 00a4e8f0330..7a1a5bc337d 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -310,7 +310,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) | |||
310 | 310 | ||
311 | } | 311 | } |
312 | 312 | ||
313 | static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len) | 313 | static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len) |
314 | { | 314 | { |
315 | struct cx24110_state *state = fe->demodulator_priv; | 315 | struct cx24110_state *state = fe->demodulator_priv; |
316 | 316 | ||
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index d8f921b6faf..fad6a990a39 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -1108,7 +1108,6 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, | |||
1108 | 1108 | ||
1109 | strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", | 1109 | strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", |
1110 | sizeof(state->tuner_i2c_adapter.name)); | 1110 | sizeof(state->tuner_i2c_adapter.name)); |
1111 | state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, | ||
1112 | state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; | 1111 | state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; |
1113 | state->tuner_i2c_adapter.algo_data = NULL; | 1112 | state->tuner_i2c_adapter.algo_data = NULL; |
1114 | i2c_set_adapdata(&state->tuner_i2c_adapter, state); | 1113 | i2c_set_adapdata(&state->tuner_i2c_adapter, state); |
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 980e02f1575..a4991026254 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c | |||
@@ -130,7 +130,6 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, | |||
130 | struct dibx000_i2c_master *mst) | 130 | struct dibx000_i2c_master *mst) |
131 | { | 131 | { |
132 | strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); | 132 | strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); |
133 | i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo; | ||
134 | i2c_adap->algo_data = NULL; | 133 | i2c_adap->algo_data = NULL; |
135 | i2c_set_adapdata(i2c_adap, mst); | 134 | i2c_set_adapdata(i2c_adap, mst); |
136 | if (i2c_add_adapter(i2c_adap) < 0) | 135 | if (i2c_add_adapter(i2c_adap) < 0) |
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index f74cca6dc26..a05007c8098 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c | |||
@@ -232,7 +232,7 @@ static int write_fw(struct drx397xD_state *s, enum blob_ix ix) | |||
232 | exit_rc: | 232 | exit_rc: |
233 | read_unlock(&fw[s->chip_rev].lock); | 233 | read_unlock(&fw[s->chip_rev].lock); |
234 | 234 | ||
235 | return 0; | 235 | return rc; |
236 | } | 236 | } |
237 | 237 | ||
238 | /* Function is not endian safe, use the RD16 wrapper below */ | 238 | /* Function is not endian safe, use the RD16 wrapper below */ |
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c new file mode 100644 index 00000000000..55f2eba7bc9 --- /dev/null +++ b/drivers/media/dvb/frontends/ix2505v.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /** | ||
2 | * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner | ||
3 | * | ||
4 | * Copyright (C) 2010 Malcolm Priestley | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License Version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/dvb/frontend.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/types.h> | ||
25 | |||
26 | #include "ix2505v.h" | ||
27 | |||
28 | static int ix2505v_debug; | ||
29 | #define dprintk(level, args...) do { \ | ||
30 | if (ix2505v_debug & level) \ | ||
31 | printk(KERN_DEBUG "ix2505v: " args); \ | ||
32 | } while (0) | ||
33 | |||
34 | #define deb_info(args...) dprintk(0x01, args) | ||
35 | #define deb_i2c(args...) dprintk(0x02, args) | ||
36 | |||
37 | struct ix2505v_state { | ||
38 | struct i2c_adapter *i2c; | ||
39 | const struct ix2505v_config *config; | ||
40 | u32 frequency; | ||
41 | }; | ||
42 | |||
43 | /** | ||
44 | * Data read format of the Sharp IX2505V B0017 | ||
45 | * | ||
46 | * byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1 | ||
47 | * byte2: POR | FL | RD2 | RD1 | RD0 | X | X | X | ||
48 | * | ||
49 | * byte1 = address | ||
50 | * byte2; | ||
51 | * POR = Power on Reset (VCC H=<2.2v L=>2.2v) | ||
52 | * FL = Phase Lock (H=lock L=unlock) | ||
53 | * RD0-2 = Reserved internal operations | ||
54 | * | ||
55 | * Only POR can be used to check the tuner is present | ||
56 | * | ||
57 | * Caution: after byte2 the I2C reverts to write mode continuing to read | ||
58 | * may corrupt tuning data. | ||
59 | * | ||
60 | */ | ||
61 | |||
62 | static int ix2505v_read_status_reg(struct ix2505v_state *state) | ||
63 | { | ||
64 | u8 addr = state->config->tuner_address; | ||
65 | u8 b2[] = {0}; | ||
66 | int ret; | ||
67 | |||
68 | struct i2c_msg msg[1] = { | ||
69 | { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } | ||
70 | }; | ||
71 | |||
72 | ret = i2c_transfer(state->i2c, msg, 1); | ||
73 | deb_i2c("Read %s ", __func__); | ||
74 | |||
75 | return (ret = 1) ? (int) b2[0] : -1; | ||
76 | } | ||
77 | |||
78 | static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count) | ||
79 | { | ||
80 | struct i2c_msg msg[1] = { | ||
81 | { .addr = state->config->tuner_address, .flags = 0, | ||
82 | .buf = buf, .len = count }, | ||
83 | }; | ||
84 | |||
85 | int ret; | ||
86 | |||
87 | ret = i2c_transfer(state->i2c, msg, 1); | ||
88 | |||
89 | if (ret != 1) { | ||
90 | deb_i2c("%s: i2c error, ret=%d\n", __func__, ret); | ||
91 | return -EIO; | ||
92 | } | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int ix2505v_release(struct dvb_frontend *fe) | ||
98 | { | ||
99 | struct ix2505v_state *state = fe->tuner_priv; | ||
100 | |||
101 | fe->tuner_priv = NULL; | ||
102 | kfree(state); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | /** | ||
108 | * Data write format of the Sharp IX2505V B0017 | ||
109 | * | ||
110 | * byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0 | ||
111 | * byte2: 0 | BG1 | BG2 | N8 | N7 | N6 | N5 | N4 | ||
112 | * byte3: N3 | N2 | N1 | A5 | A4 | A3 | A2 | A1 | ||
113 | * byte4: 1 | 1(C1) | 1(C0) | PD5 | PD4 | TM | 0(RTS)| 1(REF) | ||
114 | * byte5: BA2 | BA1 | BA0 | PSC | PD3 |PD2/TS2|DIV/TS1|PD0/TS0 | ||
115 | * | ||
116 | * byte1 = address | ||
117 | * | ||
118 | * Write order | ||
119 | * 1) byte1 -> byte2 -> byte3 -> byte4 -> byte5 | ||
120 | * 2) byte1 -> byte4 -> byte5 -> byte2 -> byte3 | ||
121 | * 3) byte1 -> byte2 -> byte3 -> byte4 | ||
122 | * 4) byte1 -> byte4 -> byte5 -> byte2 | ||
123 | * 5) byte1 -> byte2 -> byte3 | ||
124 | * 6) byte1 -> byte4 -> byte5 | ||
125 | * 7) byte1 -> byte2 | ||
126 | * 8) byte1 -> byte4 | ||
127 | * | ||
128 | * Recommended Setup | ||
129 | * 1 -> 8 -> 6 | ||
130 | */ | ||
131 | |||
132 | static int ix2505v_set_params(struct dvb_frontend *fe, | ||
133 | struct dvb_frontend_parameters *params) | ||
134 | { | ||
135 | struct ix2505v_state *state = fe->tuner_priv; | ||
136 | u32 frequency = params->frequency; | ||
137 | u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000; | ||
138 | u32 div_factor, N , A, x; | ||
139 | int ret = 0, len; | ||
140 | u8 gain, cc, ref, psc, local_osc, lpf; | ||
141 | u8 data[4] = {0}; | ||
142 | |||
143 | if ((frequency < fe->ops.info.frequency_min) | ||
144 | || (frequency > fe->ops.info.frequency_max)) | ||
145 | return -EINVAL; | ||
146 | |||
147 | if (state->config->tuner_gain) | ||
148 | gain = (state->config->tuner_gain < 4) | ||
149 | ? state->config->tuner_gain : 0; | ||
150 | else | ||
151 | gain = 0x0; | ||
152 | |||
153 | if (state->config->tuner_chargepump) | ||
154 | cc = state->config->tuner_chargepump; | ||
155 | else | ||
156 | cc = 0x3; | ||
157 | |||
158 | ref = 8; /* REF =1 */ | ||
159 | psc = 32; /* PSC = 0 */ | ||
160 | |||
161 | div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */ | ||
162 | x = div_factor / psc; | ||
163 | N = x/100; | ||
164 | A = ((x - (N * 100)) * psc) / 100; | ||
165 | |||
166 | data[0] = ((gain & 0x3) << 5) | (N >> 3); | ||
167 | data[1] = (N << 5) | (A & 0x1f); | ||
168 | data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/ | ||
169 | |||
170 | deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A); | ||
171 | |||
172 | if (frequency <= 1065000) | ||
173 | local_osc = (6 << 5) | 2; | ||
174 | else if (frequency <= 1170000) | ||
175 | local_osc = (7 << 5) | 2; | ||
176 | else if (frequency <= 1300000) | ||
177 | local_osc = (1 << 5); | ||
178 | else if (frequency <= 1445000) | ||
179 | local_osc = (2 << 5); | ||
180 | else if (frequency <= 1607000) | ||
181 | local_osc = (3 << 5); | ||
182 | else if (frequency <= 1778000) | ||
183 | local_osc = (4 << 5); | ||
184 | else if (frequency <= 1942000) | ||
185 | local_osc = (5 << 5); | ||
186 | else /*frequency up to 2150000*/ | ||
187 | local_osc = (6 << 5); | ||
188 | |||
189 | data[3] = local_osc; /* all other bits set 0 */ | ||
190 | |||
191 | if (b_w <= 10000) | ||
192 | lpf = 0xc; | ||
193 | else if (b_w <= 12000) | ||
194 | lpf = 0x2; | ||
195 | else if (b_w <= 14000) | ||
196 | lpf = 0xa; | ||
197 | else if (b_w <= 16000) | ||
198 | lpf = 0x6; | ||
199 | else if (b_w <= 18000) | ||
200 | lpf = 0xe; | ||
201 | else if (b_w <= 20000) | ||
202 | lpf = 0x1; | ||
203 | else if (b_w <= 22000) | ||
204 | lpf = 0x9; | ||
205 | else if (b_w <= 24000) | ||
206 | lpf = 0x5; | ||
207 | else if (b_w <= 26000) | ||
208 | lpf = 0xd; | ||
209 | else if (b_w <= 28000) | ||
210 | lpf = 0x3; | ||
211 | else | ||
212 | lpf = 0xb; | ||
213 | |||
214 | deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf); | ||
215 | deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]); | ||
216 | |||
217 | if (fe->ops.i2c_gate_ctrl) | ||
218 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
219 | |||
220 | len = sizeof(data); | ||
221 | |||
222 | ret |= ix2505v_write(state, data, len); | ||
223 | |||
224 | data[2] |= 0x4; /* set TM = 1 other bits same */ | ||
225 | |||
226 | len = 1; | ||
227 | ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */ | ||
228 | |||
229 | msleep(10); | ||
230 | |||
231 | data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */ | ||
232 | data[3] |= (lpf & 0x3) << 2; | ||
233 | |||
234 | deb_info("Data 2=[%x%x]\n", data[2], data[3]); | ||
235 | |||
236 | len = 2; | ||
237 | ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */ | ||
238 | |||
239 | if (fe->ops.i2c_gate_ctrl) | ||
240 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
241 | |||
242 | if (state->config->min_delay_ms) | ||
243 | msleep(state->config->min_delay_ms); | ||
244 | |||
245 | state->frequency = frequency; | ||
246 | |||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
251 | { | ||
252 | struct ix2505v_state *state = fe->tuner_priv; | ||
253 | |||
254 | *frequency = state->frequency; | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static struct dvb_tuner_ops ix2505v_tuner_ops = { | ||
260 | .info = { | ||
261 | .name = "Sharp IX2505V (B0017)", | ||
262 | .frequency_min = 950000, | ||
263 | .frequency_max = 2175000 | ||
264 | }, | ||
265 | .release = ix2505v_release, | ||
266 | .set_params = ix2505v_set_params, | ||
267 | .get_frequency = ix2505v_get_frequency, | ||
268 | }; | ||
269 | |||
270 | struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, | ||
271 | const struct ix2505v_config *config, | ||
272 | struct i2c_adapter *i2c) | ||
273 | { | ||
274 | struct ix2505v_state *state = NULL; | ||
275 | int ret; | ||
276 | |||
277 | if (NULL == config) { | ||
278 | deb_i2c("%s: no config ", __func__); | ||
279 | goto error; | ||
280 | } | ||
281 | |||
282 | state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL); | ||
283 | if (NULL == state) | ||
284 | return NULL; | ||
285 | |||
286 | state->config = config; | ||
287 | state->i2c = i2c; | ||
288 | |||
289 | if (state->config->tuner_write_only) { | ||
290 | if (fe->ops.i2c_gate_ctrl) | ||
291 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
292 | |||
293 | ret = ix2505v_read_status_reg(state); | ||
294 | |||
295 | if (ret & 0x80) { | ||
296 | deb_i2c("%s: No IX2505V found\n", __func__); | ||
297 | goto error; | ||
298 | } | ||
299 | |||
300 | if (fe->ops.i2c_gate_ctrl) | ||
301 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
302 | } | ||
303 | |||
304 | fe->tuner_priv = state; | ||
305 | |||
306 | memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops, | ||
307 | sizeof(struct dvb_tuner_ops)); | ||
308 | deb_i2c("%s: initialization (%s addr=0x%02x) ok\n", | ||
309 | __func__, fe->ops.tuner_ops.info.name, config->tuner_address); | ||
310 | |||
311 | return fe; | ||
312 | |||
313 | error: | ||
314 | ix2505v_release(fe); | ||
315 | return NULL; | ||
316 | } | ||
317 | EXPORT_SYMBOL(ix2505v_attach); | ||
318 | |||
319 | module_param_named(debug, ix2505v_debug, int, 0644); | ||
320 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
321 | MODULE_DESCRIPTION("DVB IX2505V tuner driver"); | ||
322 | MODULE_AUTHOR("Malcolm Priestley"); | ||
323 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/ix2505v.h b/drivers/media/dvb/frontends/ix2505v.h new file mode 100644 index 00000000000..67e89d616d5 --- /dev/null +++ b/drivers/media/dvb/frontends/ix2505v.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /** | ||
2 | * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner | ||
3 | * | ||
4 | * Copyright (C) 2010 Malcolm Priestley | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License Version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef DVB_IX2505V_H | ||
21 | #define DVB_IX2505V_H | ||
22 | |||
23 | #include <linux/i2c.h> | ||
24 | #include "dvb_frontend.h" | ||
25 | |||
26 | /** | ||
27 | * Attach a ix2505v tuner to the supplied frontend structure. | ||
28 | * | ||
29 | * @param fe Frontend to attach to. | ||
30 | * @param config ix2505v_config structure | ||
31 | * @return FE pointer on success, NULL on failure. | ||
32 | */ | ||
33 | |||
34 | struct ix2505v_config { | ||
35 | u8 tuner_address; | ||
36 | |||
37 | /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */ | ||
38 | u8 tuner_gain; | ||
39 | |||
40 | /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */ | ||
41 | u8 tuner_chargepump; | ||
42 | |||
43 | /* delay after tune */ | ||
44 | int min_delay_ms; | ||
45 | |||
46 | /* disables reads*/ | ||
47 | u8 tuner_write_only; | ||
48 | |||
49 | }; | ||
50 | |||
51 | #if defined(CONFIG_DVB_IX2505V) || \ | ||
52 | (defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE)) | ||
53 | extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, | ||
54 | const struct ix2505v_config *config, struct i2c_adapter *i2c); | ||
55 | #else | ||
56 | static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, | ||
57 | const struct ix2505v_config *config, struct i2c_adapter *i2c) | ||
58 | { | ||
59 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
60 | return NULL; | ||
61 | } | ||
62 | #endif | ||
63 | |||
64 | #endif /* DVB_IX2505V_H */ | ||
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c deleted file mode 100644 index 45a529b06b9..00000000000 --- a/drivers/media/dvb/frontends/lgdt3304.c +++ /dev/null | |||
@@ -1,380 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for LG ATSC lgdt3304 driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include "dvb_frontend.h" | ||
13 | #include "lgdt3304.h" | ||
14 | |||
15 | static unsigned int debug = 0; | ||
16 | module_param(debug, int, 0644); | ||
17 | MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); | ||
18 | |||
19 | #define dprintk(fmt, args...) if (debug) do {\ | ||
20 | printk("lgdt3304 debug: " fmt, ##args); } while (0) | ||
21 | |||
22 | struct lgdt3304_state | ||
23 | { | ||
24 | struct dvb_frontend frontend; | ||
25 | fe_modulation_t current_modulation; | ||
26 | __u32 snr; | ||
27 | __u32 current_frequency; | ||
28 | __u8 addr; | ||
29 | struct i2c_adapter *i2c; | ||
30 | }; | ||
31 | |||
32 | static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) | ||
33 | { | ||
34 | struct lgdt3304_state *state = fe->demodulator_priv; | ||
35 | struct i2c_msg i2cmsgs = { | ||
36 | .addr = state->addr, | ||
37 | .flags = 0, | ||
38 | .len = 3, | ||
39 | .buf = buf | ||
40 | }; | ||
41 | int i; | ||
42 | int err; | ||
43 | |||
44 | for (i=0; i<len-1; i+=3){ | ||
45 | if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { | ||
46 | printk("%s i2c_transfer error %d\n", __func__, err); | ||
47 | if (err < 0) | ||
48 | return err; | ||
49 | else | ||
50 | return -EREMOTEIO; | ||
51 | } | ||
52 | i2cmsgs.buf += 3; | ||
53 | } | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) | ||
58 | { | ||
59 | struct lgdt3304_state *state = fe->demodulator_priv; | ||
60 | struct i2c_msg i2cmsgs[2]; | ||
61 | int ret; | ||
62 | __u8 buf; | ||
63 | |||
64 | __u8 regbuf[2] = { reg>>8, reg&0xff }; | ||
65 | |||
66 | i2cmsgs[0].addr = state->addr; | ||
67 | i2cmsgs[0].flags = 0; | ||
68 | i2cmsgs[0].len = 2; | ||
69 | i2cmsgs[0].buf = regbuf; | ||
70 | |||
71 | i2cmsgs[1].addr = state->addr; | ||
72 | i2cmsgs[1].flags = I2C_M_RD; | ||
73 | i2cmsgs[1].len = 1; | ||
74 | i2cmsgs[1].buf = &buf; | ||
75 | |||
76 | if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { | ||
77 | printk("%s i2c_transfer error %d\n", __func__, ret); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | return buf; | ||
82 | } | ||
83 | |||
84 | static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) | ||
85 | { | ||
86 | struct lgdt3304_state *state = fe->demodulator_priv; | ||
87 | char buffer[3] = { reg>>8, reg&0xff, val }; | ||
88 | int ret; | ||
89 | |||
90 | struct i2c_msg i2cmsgs = { | ||
91 | .addr = state->addr, | ||
92 | .flags = 0, | ||
93 | .len = 3, | ||
94 | .buf=buffer | ||
95 | }; | ||
96 | ret = i2c_transfer(state->i2c, &i2cmsgs, 1); | ||
97 | if (ret != 1) { | ||
98 | printk("%s i2c_transfer error %d\n", __func__, ret); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | |||
106 | static int lgdt3304_soft_Reset(struct dvb_frontend *fe) | ||
107 | { | ||
108 | lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); | ||
109 | lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); | ||
110 | mdelay(200); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { | ||
115 | int err = 0; | ||
116 | |||
117 | static __u8 lgdt3304_vsb8_data[] = { | ||
118 | /* 16bit , 8bit */ | ||
119 | /* regs , val */ | ||
120 | 0x00, 0x00, 0x02, | ||
121 | 0x00, 0x00, 0x13, | ||
122 | 0x00, 0x0d, 0x02, | ||
123 | 0x00, 0x0e, 0x02, | ||
124 | 0x00, 0x12, 0x32, | ||
125 | 0x00, 0x13, 0xc4, | ||
126 | 0x01, 0x12, 0x17, | ||
127 | 0x01, 0x13, 0x15, | ||
128 | 0x01, 0x14, 0x18, | ||
129 | 0x01, 0x15, 0xff, | ||
130 | 0x01, 0x16, 0x2c, | ||
131 | 0x02, 0x14, 0x67, | ||
132 | 0x02, 0x24, 0x8d, | ||
133 | 0x04, 0x27, 0x12, | ||
134 | 0x04, 0x28, 0x4f, | ||
135 | 0x03, 0x08, 0x80, | ||
136 | 0x03, 0x09, 0x00, | ||
137 | 0x03, 0x0d, 0x00, | ||
138 | 0x03, 0x0e, 0x1c, | ||
139 | 0x03, 0x14, 0xe1, | ||
140 | 0x05, 0x0e, 0x5b, | ||
141 | }; | ||
142 | |||
143 | /* not yet tested .. */ | ||
144 | static __u8 lgdt3304_qam64_data[] = { | ||
145 | /* 16bit , 8bit */ | ||
146 | /* regs , val */ | ||
147 | 0x00, 0x00, 0x18, | ||
148 | 0x00, 0x0d, 0x02, | ||
149 | //0x00, 0x0e, 0x02, | ||
150 | 0x00, 0x12, 0x2a, | ||
151 | 0x00, 0x13, 0x00, | ||
152 | 0x03, 0x14, 0xe3, | ||
153 | 0x03, 0x0e, 0x1c, | ||
154 | 0x03, 0x08, 0x66, | ||
155 | 0x03, 0x09, 0x66, | ||
156 | 0x03, 0x0a, 0x08, | ||
157 | 0x03, 0x0b, 0x9b, | ||
158 | 0x05, 0x0e, 0x5b, | ||
159 | }; | ||
160 | |||
161 | |||
162 | /* tested with KWorld a340 */ | ||
163 | static __u8 lgdt3304_qam256_data[] = { | ||
164 | /* 16bit , 8bit */ | ||
165 | /* regs , val */ | ||
166 | 0x00, 0x00, 0x01, //0x19, | ||
167 | 0x00, 0x12, 0x2a, | ||
168 | 0x00, 0x13, 0x80, | ||
169 | 0x00, 0x0d, 0x02, | ||
170 | 0x03, 0x14, 0xe3, | ||
171 | |||
172 | 0x03, 0x0e, 0x1c, | ||
173 | 0x03, 0x08, 0x66, | ||
174 | 0x03, 0x09, 0x66, | ||
175 | 0x03, 0x0a, 0x08, | ||
176 | 0x03, 0x0b, 0x9b, | ||
177 | |||
178 | 0x03, 0x0d, 0x14, | ||
179 | //0x05, 0x0e, 0x5b, | ||
180 | 0x01, 0x06, 0x4a, | ||
181 | 0x01, 0x07, 0x3d, | ||
182 | 0x01, 0x08, 0x70, | ||
183 | 0x01, 0x09, 0xa3, | ||
184 | |||
185 | 0x05, 0x04, 0xfd, | ||
186 | |||
187 | 0x00, 0x0d, 0x82, | ||
188 | |||
189 | 0x05, 0x0e, 0x5b, | ||
190 | |||
191 | 0x05, 0x0e, 0x5b, | ||
192 | |||
193 | 0x00, 0x02, 0x9a, | ||
194 | |||
195 | 0x00, 0x02, 0x9b, | ||
196 | |||
197 | 0x00, 0x00, 0x01, | ||
198 | 0x00, 0x12, 0x2a, | ||
199 | 0x00, 0x13, 0x80, | ||
200 | 0x00, 0x0d, 0x02, | ||
201 | 0x03, 0x14, 0xe3, | ||
202 | |||
203 | 0x03, 0x0e, 0x1c, | ||
204 | 0x03, 0x08, 0x66, | ||
205 | 0x03, 0x09, 0x66, | ||
206 | 0x03, 0x0a, 0x08, | ||
207 | 0x03, 0x0b, 0x9b, | ||
208 | |||
209 | 0x03, 0x0d, 0x14, | ||
210 | 0x01, 0x06, 0x4a, | ||
211 | 0x01, 0x07, 0x3d, | ||
212 | 0x01, 0x08, 0x70, | ||
213 | 0x01, 0x09, 0xa3, | ||
214 | |||
215 | 0x05, 0x04, 0xfd, | ||
216 | |||
217 | 0x00, 0x0d, 0x82, | ||
218 | |||
219 | 0x05, 0x0e, 0x5b, | ||
220 | }; | ||
221 | |||
222 | struct lgdt3304_state *state = fe->demodulator_priv; | ||
223 | if (state->current_modulation != param->u.vsb.modulation) { | ||
224 | switch(param->u.vsb.modulation) { | ||
225 | case VSB_8: | ||
226 | err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, | ||
227 | sizeof(lgdt3304_vsb8_data)); | ||
228 | break; | ||
229 | case QAM_64: | ||
230 | err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, | ||
231 | sizeof(lgdt3304_qam64_data)); | ||
232 | break; | ||
233 | case QAM_256: | ||
234 | err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, | ||
235 | sizeof(lgdt3304_qam256_data)); | ||
236 | break; | ||
237 | default: | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | if (err) { | ||
242 | printk("%s error setting modulation\n", __func__); | ||
243 | } else { | ||
244 | state->current_modulation = param->u.vsb.modulation; | ||
245 | } | ||
246 | } | ||
247 | state->current_frequency = param->frequency; | ||
248 | |||
249 | lgdt3304_soft_Reset(fe); | ||
250 | |||
251 | |||
252 | if (fe->ops.tuner_ops.set_params) | ||
253 | fe->ops.tuner_ops.set_params(fe, param); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int lgdt3304_init(struct dvb_frontend *fe) { | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int lgdt3304_sleep(struct dvb_frontend *fe) { | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | |||
267 | static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
268 | { | ||
269 | struct lgdt3304_state *state = fe->demodulator_priv; | ||
270 | int r011d; | ||
271 | int qam_lck; | ||
272 | |||
273 | *status = 0; | ||
274 | dprintk("lgdt read status\n"); | ||
275 | |||
276 | r011d = lgdt3304_i2c_read_reg(fe, 0x011d); | ||
277 | |||
278 | dprintk("%02x\n", r011d); | ||
279 | |||
280 | switch(state->current_modulation) { | ||
281 | case VSB_8: | ||
282 | if (r011d & 0x80) { | ||
283 | dprintk("VSB Locked\n"); | ||
284 | *status |= FE_HAS_CARRIER; | ||
285 | *status |= FE_HAS_LOCK; | ||
286 | *status |= FE_HAS_SYNC; | ||
287 | *status |= FE_HAS_SIGNAL; | ||
288 | } | ||
289 | break; | ||
290 | case QAM_64: | ||
291 | case QAM_256: | ||
292 | qam_lck = r011d & 0x7; | ||
293 | switch(qam_lck) { | ||
294 | case 0x0: dprintk("Unlock\n"); | ||
295 | break; | ||
296 | case 0x4: dprintk("1st Lock in acquisition state\n"); | ||
297 | break; | ||
298 | case 0x6: dprintk("2nd Lock in acquisition state\n"); | ||
299 | break; | ||
300 | case 0x7: dprintk("Final Lock in good reception state\n"); | ||
301 | *status |= FE_HAS_CARRIER; | ||
302 | *status |= FE_HAS_LOCK; | ||
303 | *status |= FE_HAS_SYNC; | ||
304 | *status |= FE_HAS_SIGNAL; | ||
305 | break; | ||
306 | } | ||
307 | break; | ||
308 | default: | ||
309 | printk("%s unhandled modulation\n", __func__); | ||
310 | } | ||
311 | |||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) | ||
317 | { | ||
318 | dprintk("read ber\n"); | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) | ||
323 | { | ||
324 | dprintk("read snr\n"); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) | ||
329 | { | ||
330 | dprintk("read ucblocks\n"); | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static void lgdt3304_release(struct dvb_frontend *fe) | ||
335 | { | ||
336 | struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; | ||
337 | kfree(state); | ||
338 | } | ||
339 | |||
340 | static struct dvb_frontend_ops demod_lgdt3304={ | ||
341 | .info = { | ||
342 | .name = "LG 3304", | ||
343 | .type = FE_ATSC, | ||
344 | .frequency_min = 54000000, | ||
345 | .frequency_max = 858000000, | ||
346 | .frequency_stepsize = 62500, | ||
347 | .symbol_rate_min = 5056941, | ||
348 | .symbol_rate_max = 10762000, | ||
349 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
350 | }, | ||
351 | .init = lgdt3304_init, | ||
352 | .sleep = lgdt3304_sleep, | ||
353 | .set_frontend = lgdt3304_set_parameters, | ||
354 | .read_snr = lgdt3304_read_snr, | ||
355 | .read_ber = lgdt3304_read_ber, | ||
356 | .read_status = lgdt3304_read_status, | ||
357 | .read_ucblocks = lgdt3304_read_ucblocks, | ||
358 | .release = lgdt3304_release, | ||
359 | }; | ||
360 | |||
361 | struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, | ||
362 | struct i2c_adapter *i2c) | ||
363 | { | ||
364 | |||
365 | struct lgdt3304_state *state; | ||
366 | state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); | ||
367 | if (state == NULL) | ||
368 | return NULL; | ||
369 | state->addr = config->i2c_address; | ||
370 | state->i2c = i2c; | ||
371 | |||
372 | memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); | ||
373 | state->frontend.demodulator_priv = state; | ||
374 | return &state->frontend; | ||
375 | } | ||
376 | |||
377 | EXPORT_SYMBOL_GPL(lgdt3304_attach); | ||
378 | MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); | ||
379 | MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); | ||
380 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/lgdt3304.h b/drivers/media/dvb/frontends/lgdt3304.h deleted file mode 100644 index fc409fe59ac..00000000000 --- a/drivers/media/dvb/frontends/lgdt3304.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for DVB-T lgdt3304 demodulator | ||
3 | * | ||
4 | * Copyright (C) 2008 Markus Rechberger <mrechberger@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
20 | */ | ||
21 | |||
22 | #ifndef LGDT3304_H | ||
23 | #define LGDT3304_H | ||
24 | |||
25 | #include <linux/dvb/frontend.h> | ||
26 | |||
27 | struct lgdt3304_config | ||
28 | { | ||
29 | /* demodulator's I2C address */ | ||
30 | u8 i2c_address; | ||
31 | }; | ||
32 | |||
33 | #if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) | ||
34 | extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, | ||
35 | struct i2c_adapter *i2c); | ||
36 | #else | ||
37 | static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, | ||
38 | struct i2c_adapter *i2c) | ||
39 | { | ||
40 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
41 | return NULL; | ||
42 | } | ||
43 | #endif /* CONFIG_DVB_LGDT */ | ||
44 | |||
45 | #endif /* LGDT3304_H */ | ||
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index 5ea28ae2ba8..0fcddc4569d 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c | |||
@@ -662,7 +662,7 @@ static void lgs8gxx_release(struct dvb_frontend *fe) | |||
662 | } | 662 | } |
663 | 663 | ||
664 | 664 | ||
665 | static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len) | 665 | static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len) |
666 | { | 666 | { |
667 | struct lgs8gxx_state *priv = fe->demodulator_priv; | 667 | struct lgs8gxx_state *priv = fe->demodulator_priv; |
668 | 668 | ||
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c index beba5aa0db5..319672f8e1a 100644 --- a/drivers/media/dvb/frontends/mt352.c +++ b/drivers/media/dvb/frontends/mt352.c | |||
@@ -69,7 +69,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val) | |||
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) | 72 | static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen) |
73 | { | 73 | { |
74 | int err,i; | 74 | int err,i; |
75 | for (i=0; i < ilen-1; i++) | 75 | for (i=0; i < ilen-1; i++) |
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index 595092f9f0c..ca2562d6f28 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h | |||
@@ -63,7 +63,7 @@ static inline struct dvb_frontend* mt352_attach(const struct mt352_config* confi | |||
63 | } | 63 | } |
64 | #endif // CONFIG_DVB_MT352 | 64 | #endif // CONFIG_DVB_MT352 |
65 | 65 | ||
66 | static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) { | 66 | static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) { |
67 | int r = 0; | 67 | int r = 0; |
68 | if (fe->ops.write) | 68 | if (fe->ops.write) |
69 | r = fe->ops.write(fe, buf, len); | 69 | r = fe->ops.write(fe, buf, len); |
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 2e9fd2893ed..e87b747ea99 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c | |||
@@ -920,7 +920,6 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, | |||
920 | /* create tuner i2c adapter */ | 920 | /* create tuner i2c adapter */ |
921 | strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", | 921 | strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", |
922 | sizeof(state->tuner_i2c_adapter.name)); | 922 | sizeof(state->tuner_i2c_adapter.name)); |
923 | state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, | ||
924 | state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; | 923 | state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; |
925 | state->tuner_i2c_adapter.algo_data = NULL; | 924 | state->tuner_i2c_adapter.algo_data = NULL; |
926 | i2c_set_adapdata(&state->tuner_i2c_adapter, state); | 925 | i2c_set_adapdata(&state->tuner_i2c_adapter, state); |
diff --git a/drivers/media/dvb/frontends/s5h1432.c b/drivers/media/dvb/frontends/s5h1432.c new file mode 100644 index 00000000000..0c6dcb90d16 --- /dev/null +++ b/drivers/media/dvb/frontends/s5h1432.c | |||
@@ -0,0 +1,415 @@ | |||
1 | /* | ||
2 | * Samsung s5h1432 DVB-T demodulator driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include "dvb_frontend.h" | ||
28 | #include "s5h1432.h" | ||
29 | |||
30 | struct s5h1432_state { | ||
31 | |||
32 | struct i2c_adapter *i2c; | ||
33 | |||
34 | /* configuration settings */ | ||
35 | const struct s5h1432_config *config; | ||
36 | |||
37 | struct dvb_frontend frontend; | ||
38 | |||
39 | fe_modulation_t current_modulation; | ||
40 | unsigned int first_tune:1; | ||
41 | |||
42 | u32 current_frequency; | ||
43 | int if_freq; | ||
44 | |||
45 | u8 inversion; | ||
46 | }; | ||
47 | |||
48 | static int debug; | ||
49 | |||
50 | #define dprintk(arg...) do { \ | ||
51 | if (debug) \ | ||
52 | printk(arg); \ | ||
53 | } while (0) | ||
54 | |||
55 | static int s5h1432_writereg(struct s5h1432_state *state, | ||
56 | u8 addr, u8 reg, u8 data) | ||
57 | { | ||
58 | int ret; | ||
59 | u8 buf[] = { reg, data }; | ||
60 | |||
61 | struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 }; | ||
62 | |||
63 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
64 | |||
65 | if (ret != 1) | ||
66 | printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " | ||
67 | "ret == %i)\n", __func__, addr, reg, data, ret); | ||
68 | |||
69 | return (ret != 1) ? -1 : 0; | ||
70 | } | ||
71 | |||
72 | static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg) | ||
73 | { | ||
74 | int ret; | ||
75 | u8 b0[] = { reg }; | ||
76 | u8 b1[] = { 0 }; | ||
77 | |||
78 | struct i2c_msg msg[] = { | ||
79 | {.addr = addr, .flags = 0, .buf = b0, .len = 1}, | ||
80 | {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1} | ||
81 | }; | ||
82 | |||
83 | ret = i2c_transfer(state->i2c, msg, 2); | ||
84 | |||
85 | if (ret != 2) | ||
86 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", | ||
87 | __func__, ret); | ||
88 | return b1[0]; | ||
89 | } | ||
90 | |||
91 | static int s5h1432_sleep(struct dvb_frontend *fe) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe, | ||
97 | u32 bandwidth) | ||
98 | { | ||
99 | struct s5h1432_state *state = fe->demodulator_priv; | ||
100 | |||
101 | u8 reg = 0; | ||
102 | |||
103 | /* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */ | ||
104 | reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E); | ||
105 | reg &= ~(0x0C); | ||
106 | switch (bandwidth) { | ||
107 | case 6: | ||
108 | reg |= 0x08; | ||
109 | break; | ||
110 | case 7: | ||
111 | reg |= 0x04; | ||
112 | break; | ||
113 | case 8: | ||
114 | reg |= 0x00; | ||
115 | break; | ||
116 | default: | ||
117 | return 0; | ||
118 | } | ||
119 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg); | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz) | ||
124 | { | ||
125 | struct s5h1432_state *state = fe->demodulator_priv; | ||
126 | |||
127 | switch (ifFreqHz) { | ||
128 | case TAIWAN_HI_IF_FREQ_44_MHZ: | ||
129 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55); | ||
130 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55); | ||
131 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15); | ||
132 | break; | ||
133 | case EUROPE_HI_IF_FREQ_36_MHZ: | ||
134 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00); | ||
135 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00); | ||
136 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40); | ||
137 | break; | ||
138 | case IF_FREQ_6_MHZ: | ||
139 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00); | ||
140 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00); | ||
141 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0); | ||
142 | break; | ||
143 | case IF_FREQ_3point3_MHZ: | ||
144 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66); | ||
145 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66); | ||
146 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE); | ||
147 | break; | ||
148 | case IF_FREQ_3point5_MHZ: | ||
149 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55); | ||
150 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55); | ||
151 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED); | ||
152 | break; | ||
153 | case IF_FREQ_4_MHZ: | ||
154 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA); | ||
155 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA); | ||
156 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA); | ||
157 | break; | ||
158 | default: | ||
159 | { | ||
160 | u32 value = 0; | ||
161 | value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 * | ||
162 | (u32) 32768) / (48 * 1000)); | ||
163 | printk(KERN_INFO | ||
164 | "Default IFFreq %d :reg value = 0x%x\n", | ||
165 | ifFreqHz, value); | ||
166 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, | ||
167 | (u8) value & 0xFF); | ||
168 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, | ||
169 | (u8) (value >> 8) & 0xFF); | ||
170 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, | ||
171 | (u8) (value >> 16) & 0xFF); | ||
172 | break; | ||
173 | } | ||
174 | |||
175 | } | ||
176 | |||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | ||
181 | static int s5h1432_set_frontend(struct dvb_frontend *fe, | ||
182 | struct dvb_frontend_parameters *p) | ||
183 | { | ||
184 | u32 dvb_bandwidth = 8; | ||
185 | struct s5h1432_state *state = fe->demodulator_priv; | ||
186 | |||
187 | if (p->frequency == state->current_frequency) { | ||
188 | /*current_frequency = p->frequency; */ | ||
189 | /*state->current_frequency = p->frequency; */ | ||
190 | } else { | ||
191 | fe->ops.tuner_ops.set_params(fe, p); | ||
192 | msleep(300); | ||
193 | s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); | ||
194 | switch (p->u.ofdm.bandwidth) { | ||
195 | case BANDWIDTH_6_MHZ: | ||
196 | dvb_bandwidth = 6; | ||
197 | s5h1432_set_IF(fe, IF_FREQ_4_MHZ); | ||
198 | break; | ||
199 | case BANDWIDTH_7_MHZ: | ||
200 | dvb_bandwidth = 7; | ||
201 | s5h1432_set_IF(fe, IF_FREQ_4_MHZ); | ||
202 | break; | ||
203 | case BANDWIDTH_8_MHZ: | ||
204 | dvb_bandwidth = 8; | ||
205 | s5h1432_set_IF(fe, IF_FREQ_4_MHZ); | ||
206 | break; | ||
207 | default: | ||
208 | return 0; | ||
209 | } | ||
210 | /*fe->ops.tuner_ops.set_params(fe, p); */ | ||
211 | /*Soft Reset chip*/ | ||
212 | msleep(30); | ||
213 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); | ||
214 | msleep(30); | ||
215 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); | ||
216 | |||
217 | s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); | ||
218 | switch (p->u.ofdm.bandwidth) { | ||
219 | case BANDWIDTH_6_MHZ: | ||
220 | dvb_bandwidth = 6; | ||
221 | s5h1432_set_IF(fe, IF_FREQ_4_MHZ); | ||
222 | break; | ||
223 | case BANDWIDTH_7_MHZ: | ||
224 | dvb_bandwidth = 7; | ||
225 | s5h1432_set_IF(fe, IF_FREQ_4_MHZ); | ||
226 | break; | ||
227 | case BANDWIDTH_8_MHZ: | ||
228 | dvb_bandwidth = 8; | ||
229 | s5h1432_set_IF(fe, IF_FREQ_4_MHZ); | ||
230 | break; | ||
231 | default: | ||
232 | return 0; | ||
233 | } | ||
234 | /*fe->ops.tuner_ops.set_params(fe,p); */ | ||
235 | /*Soft Reset chip*/ | ||
236 | msleep(30); | ||
237 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); | ||
238 | msleep(30); | ||
239 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); | ||
240 | |||
241 | } | ||
242 | |||
243 | state->current_frequency = p->frequency; | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int s5h1432_init(struct dvb_frontend *fe) | ||
249 | { | ||
250 | struct s5h1432_state *state = fe->demodulator_priv; | ||
251 | |||
252 | u8 reg = 0; | ||
253 | state->current_frequency = 0; | ||
254 | printk(KERN_INFO " s5h1432_init().\n"); | ||
255 | |||
256 | /*Set VSB mode as default, this also does a soft reset */ | ||
257 | /*Initialize registers */ | ||
258 | |||
259 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8); | ||
260 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01); | ||
261 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70); | ||
262 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80); | ||
263 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D); | ||
264 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30); | ||
265 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20); | ||
266 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B); | ||
267 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40); | ||
268 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84); | ||
269 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a); | ||
270 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3); | ||
271 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50); | ||
272 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c); | ||
273 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10); | ||
274 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c); | ||
275 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00); | ||
276 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94); | ||
277 | /* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */ | ||
278 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00); | ||
279 | |||
280 | /*For NXP tuner*/ | ||
281 | |||
282 | /*Set 3.3MHz as default IF frequency */ | ||
283 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66); | ||
284 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66); | ||
285 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE); | ||
286 | /* Set reg 0x1E to get the full dynamic range */ | ||
287 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31); | ||
288 | |||
289 | /* Mode setting in demod */ | ||
290 | reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42); | ||
291 | reg |= 0x80; | ||
292 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg); | ||
293 | /* Serial mode */ | ||
294 | |||
295 | /* Soft Reset chip */ | ||
296 | |||
297 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); | ||
298 | msleep(30); | ||
299 | s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); | ||
300 | |||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
306 | { | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int s5h1432_read_signal_strength(struct dvb_frontend *fe, | ||
311 | u16 *signal_strength) | ||
312 | { | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
317 | { | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
322 | { | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
328 | { | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int s5h1432_get_frontend(struct dvb_frontend *fe, | ||
333 | struct dvb_frontend_parameters *p) | ||
334 | { | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static int s5h1432_get_tune_settings(struct dvb_frontend *fe, | ||
339 | struct dvb_frontend_tune_settings *tune) | ||
340 | { | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static void s5h1432_release(struct dvb_frontend *fe) | ||
345 | { | ||
346 | struct s5h1432_state *state = fe->demodulator_priv; | ||
347 | kfree(state); | ||
348 | } | ||
349 | |||
350 | static struct dvb_frontend_ops s5h1432_ops; | ||
351 | |||
352 | struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, | ||
353 | struct i2c_adapter *i2c) | ||
354 | { | ||
355 | struct s5h1432_state *state = NULL; | ||
356 | |||
357 | printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n"); | ||
358 | /* allocate memory for the internal state */ | ||
359 | state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL); | ||
360 | if (state == NULL) | ||
361 | goto error; | ||
362 | |||
363 | /* setup the state */ | ||
364 | state->config = config; | ||
365 | state->i2c = i2c; | ||
366 | state->current_modulation = QAM_16; | ||
367 | state->inversion = state->config->inversion; | ||
368 | |||
369 | /* create dvb_frontend */ | ||
370 | memcpy(&state->frontend.ops, &s5h1432_ops, | ||
371 | sizeof(struct dvb_frontend_ops)); | ||
372 | |||
373 | state->frontend.demodulator_priv = state; | ||
374 | |||
375 | return &state->frontend; | ||
376 | |||
377 | error: | ||
378 | kfree(state); | ||
379 | return NULL; | ||
380 | } | ||
381 | EXPORT_SYMBOL(s5h1432_attach); | ||
382 | |||
383 | static struct dvb_frontend_ops s5h1432_ops = { | ||
384 | |||
385 | .info = { | ||
386 | .name = "Samsung s5h1432 DVB-T Frontend", | ||
387 | .type = FE_OFDM, | ||
388 | .frequency_min = 177000000, | ||
389 | .frequency_max = 858000000, | ||
390 | .frequency_stepsize = 166666, | ||
391 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
392 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
393 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | ||
394 | FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | ||
395 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER}, | ||
396 | |||
397 | .init = s5h1432_init, | ||
398 | .sleep = s5h1432_sleep, | ||
399 | .set_frontend = s5h1432_set_frontend, | ||
400 | .get_frontend = s5h1432_get_frontend, | ||
401 | .get_tune_settings = s5h1432_get_tune_settings, | ||
402 | .read_status = s5h1432_read_status, | ||
403 | .read_ber = s5h1432_read_ber, | ||
404 | .read_signal_strength = s5h1432_read_signal_strength, | ||
405 | .read_snr = s5h1432_read_snr, | ||
406 | .read_ucblocks = s5h1432_read_ucblocks, | ||
407 | .release = s5h1432_release, | ||
408 | }; | ||
409 | |||
410 | module_param(debug, int, 0644); | ||
411 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
412 | |||
413 | MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver"); | ||
414 | MODULE_AUTHOR("Bill Liu"); | ||
415 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/s5h1432.h b/drivers/media/dvb/frontends/s5h1432.h new file mode 100644 index 00000000000..b57438c3254 --- /dev/null +++ b/drivers/media/dvb/frontends/s5h1432.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Samsung s5h1432 VSB/QAM demodulator driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __S5H1432_H__ | ||
23 | #define __S5H1432_H__ | ||
24 | |||
25 | #include <linux/dvb/frontend.h> | ||
26 | |||
27 | #define S5H1432_I2C_TOP_ADDR (0x02 >> 1) | ||
28 | |||
29 | #define TAIWAN_HI_IF_FREQ_44_MHZ 44000000 | ||
30 | #define EUROPE_HI_IF_FREQ_36_MHZ 36000000 | ||
31 | #define IF_FREQ_6_MHZ 6000000 | ||
32 | #define IF_FREQ_3point3_MHZ 3300000 | ||
33 | #define IF_FREQ_3point5_MHZ 3500000 | ||
34 | #define IF_FREQ_4_MHZ 4000000 | ||
35 | |||
36 | struct s5h1432_config { | ||
37 | |||
38 | /* serial/parallel output */ | ||
39 | #define S5H1432_PARALLEL_OUTPUT 0 | ||
40 | #define S5H1432_SERIAL_OUTPUT 1 | ||
41 | u8 output_mode; | ||
42 | |||
43 | /* GPIO Setting */ | ||
44 | #define S5H1432_GPIO_OFF 0 | ||
45 | #define S5H1432_GPIO_ON 1 | ||
46 | u8 gpio; | ||
47 | |||
48 | /* MPEG signal timing */ | ||
49 | #define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 | ||
50 | #define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 | ||
51 | #define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 | ||
52 | #define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 | ||
53 | u16 mpeg_timing; | ||
54 | |||
55 | /* IF Freq for QAM and VSB in KHz */ | ||
56 | #define S5H1432_IF_3250 3250 | ||
57 | #define S5H1432_IF_3500 3500 | ||
58 | #define S5H1432_IF_4000 4000 | ||
59 | #define S5H1432_IF_5380 5380 | ||
60 | #define S5H1432_IF_44000 44000 | ||
61 | #define S5H1432_VSB_IF_DEFAULT s5h1432_IF_44000 | ||
62 | #define S5H1432_QAM_IF_DEFAULT s5h1432_IF_44000 | ||
63 | u16 qam_if; | ||
64 | u16 vsb_if; | ||
65 | |||
66 | /* Spectral Inversion */ | ||
67 | #define S5H1432_INVERSION_OFF 0 | ||
68 | #define S5H1432_INVERSION_ON 1 | ||
69 | u8 inversion; | ||
70 | |||
71 | /* Return lock status based on tuner lock, or demod lock */ | ||
72 | #define S5H1432_TUNERLOCKING 0 | ||
73 | #define S5H1432_DEMODLOCKING 1 | ||
74 | u8 status_mode; | ||
75 | }; | ||
76 | |||
77 | #if defined(CONFIG_DVB_S5H1432) || \ | ||
78 | (defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE)) | ||
79 | extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, | ||
80 | struct i2c_adapter *i2c); | ||
81 | #else | ||
82 | static inline struct dvb_frontend *s5h1432_attach(const struct s5h1432_config | ||
83 | *config, | ||
84 | struct i2c_adapter *i2c) | ||
85 | { | ||
86 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
87 | return NULL; | ||
88 | } | ||
89 | #endif /* CONFIG_DVB_s5h1432 */ | ||
90 | |||
91 | #endif /* __s5h1432_H__ */ | ||
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c index d21a327db62..4b0c99a08a8 100644 --- a/drivers/media/dvb/frontends/si21xx.c +++ b/drivers/media/dvb/frontends/si21xx.c | |||
@@ -268,7 +268,7 @@ static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data) | |||
268 | return (ret != 1) ? -EREMOTEIO : 0; | 268 | return (ret != 1) ? -EREMOTEIO : 0; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int si21_write(struct dvb_frontend *fe, u8 *buf, int len) | 271 | static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len) |
272 | { | 272 | { |
273 | struct si21xx_state *state = fe->demodulator_priv; | 273 | struct si21xx_state *state = fe->demodulator_priv; |
274 | 274 | ||
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c index f73c13323e9..80a9e4cba63 100644 --- a/drivers/media/dvb/frontends/stb6100.c +++ b/drivers/media/dvb/frontends/stb6100.c | |||
@@ -506,7 +506,7 @@ static struct dvb_tuner_ops stb6100_ops = { | |||
506 | }; | 506 | }; |
507 | 507 | ||
508 | struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, | 508 | struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, |
509 | struct stb6100_config *config, | 509 | const struct stb6100_config *config, |
510 | struct i2c_adapter *i2c) | 510 | struct i2c_adapter *i2c) |
511 | { | 511 | { |
512 | struct stb6100_state *state = NULL; | 512 | struct stb6100_state *state = NULL; |
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h index 395d056599a..2ab096614b3 100644 --- a/drivers/media/dvb/frontends/stb6100.h +++ b/drivers/media/dvb/frontends/stb6100.h | |||
@@ -97,13 +97,13 @@ struct stb6100_state { | |||
97 | #if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE)) | 97 | #if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE)) |
98 | 98 | ||
99 | extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, | 99 | extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, |
100 | struct stb6100_config *config, | 100 | const struct stb6100_config *config, |
101 | struct i2c_adapter *i2c); | 101 | struct i2c_adapter *i2c); |
102 | 102 | ||
103 | #else | 103 | #else |
104 | 104 | ||
105 | static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, | 105 | static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, |
106 | struct stb6100_config *config, | 106 | const struct stb6100_config *config, |
107 | struct i2c_adapter *i2c) | 107 | struct i2c_adapter *i2c) |
108 | { | 108 | { |
109 | printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); | 109 | printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); |
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c index 2930a5d6768..63db8fd2754 100644 --- a/drivers/media/dvb/frontends/stv0288.c +++ b/drivers/media/dvb/frontends/stv0288.c | |||
@@ -6,6 +6,8 @@ | |||
6 | Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> | 6 | Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> |
7 | Removed stb6000 specific tuner code and revised some | 7 | Removed stb6000 specific tuner code and revised some |
8 | procedures. | 8 | procedures. |
9 | 2010-09-01 Josef Pavlik <josef@pavlik.it> | ||
10 | Fixed diseqc_msg, diseqc_burst and set_tone problems | ||
9 | 11 | ||
10 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License as published by | 13 | it under the terms of the GNU General Public License as published by |
@@ -78,7 +80,7 @@ static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data) | |||
78 | return (ret != 1) ? -EREMOTEIO : 0; | 80 | return (ret != 1) ? -EREMOTEIO : 0; |
79 | } | 81 | } |
80 | 82 | ||
81 | static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len) | 83 | static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len) |
82 | { | 84 | { |
83 | struct stv0288_state *state = fe->demodulator_priv; | 85 | struct stv0288_state *state = fe->demodulator_priv; |
84 | 86 | ||
@@ -156,14 +158,13 @@ static int stv0288_send_diseqc_msg(struct dvb_frontend *fe, | |||
156 | 158 | ||
157 | stv0288_writeregI(state, 0x09, 0); | 159 | stv0288_writeregI(state, 0x09, 0); |
158 | msleep(30); | 160 | msleep(30); |
159 | stv0288_writeregI(state, 0x05, 0x16); | 161 | stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */ |
160 | 162 | ||
161 | for (i = 0; i < m->msg_len; i++) { | 163 | for (i = 0; i < m->msg_len; i++) { |
162 | if (stv0288_writeregI(state, 0x06, m->msg[i])) | 164 | if (stv0288_writeregI(state, 0x06, m->msg[i])) |
163 | return -EREMOTEIO; | 165 | return -EREMOTEIO; |
164 | msleep(12); | ||
165 | } | 166 | } |
166 | 167 | msleep(m->msg_len*12); | |
167 | return 0; | 168 | return 0; |
168 | } | 169 | } |
169 | 170 | ||
@@ -174,13 +175,14 @@ static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, | |||
174 | 175 | ||
175 | dprintk("%s\n", __func__); | 176 | dprintk("%s\n", __func__); |
176 | 177 | ||
177 | if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */ | 178 | if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */ |
178 | return -EREMOTEIO; | 179 | return -EREMOTEIO; |
179 | 180 | ||
180 | if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff)) | 181 | if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff)) |
181 | return -EREMOTEIO; | 182 | return -EREMOTEIO; |
182 | 183 | ||
183 | if (stv0288_writeregI(state, 0x06, 0x12)) | 184 | msleep(15); |
185 | if (stv0288_writeregI(state, 0x05, 0x12)) | ||
184 | return -EREMOTEIO; | 186 | return -EREMOTEIO; |
185 | 187 | ||
186 | return 0; | 188 | return 0; |
@@ -192,18 +194,19 @@ static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | |||
192 | 194 | ||
193 | switch (tone) { | 195 | switch (tone) { |
194 | case SEC_TONE_ON: | 196 | case SEC_TONE_ON: |
195 | if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */ | 197 | if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */ |
196 | return -EREMOTEIO; | 198 | return -EREMOTEIO; |
197 | return stv0288_writeregI(state, 0x06, 0xff); | 199 | break; |
198 | 200 | ||
199 | case SEC_TONE_OFF: | 201 | case SEC_TONE_OFF: |
200 | if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */ | 202 | if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/ |
201 | return -EREMOTEIO; | 203 | return -EREMOTEIO; |
202 | return stv0288_writeregI(state, 0x06, 0x00); | 204 | break; |
203 | 205 | ||
204 | default: | 206 | default: |
205 | return -EINVAL; | 207 | return -EINVAL; |
206 | } | 208 | } |
209 | return 0; | ||
207 | } | 210 | } |
208 | 211 | ||
209 | static u8 stv0288_inittab[] = { | 212 | static u8 stv0288_inittab[] = { |
@@ -486,7 +489,7 @@ static int stv0288_set_frontend(struct dvb_frontend *fe, | |||
486 | tda[2] = 0x0; /* CFRL */ | 489 | tda[2] = 0x0; /* CFRL */ |
487 | for (tm = -6; tm < 7;) { | 490 | for (tm = -6; tm < 7;) { |
488 | /* Viterbi status */ | 491 | /* Viterbi status */ |
489 | if (stv0288_readreg(state, 0x24) & 0x80) | 492 | if (stv0288_readreg(state, 0x24) & 0x8) |
490 | break; | 493 | break; |
491 | 494 | ||
492 | tda[2] += 40; | 495 | tda[2] += 40; |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 96887446972..4e3db3a42e0 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) | |||
92 | return (ret != 1) ? -EREMOTEIO : 0; | 92 | return (ret != 1) ? -EREMOTEIO : 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) | 95 | static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len) |
96 | { | 96 | { |
97 | struct stv0299_state* state = fe->demodulator_priv; | 97 | struct stv0299_state* state = fe->demodulator_priv; |
98 | 98 | ||
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 0fd96e22b65..ba219b767a6 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -65,7 +65,7 @@ struct stv0299_config | |||
65 | * First of each pair is the register, second is the value. | 65 | * First of each pair is the register, second is the value. |
66 | * List should be terminated with an 0xff, 0xff pair. | 66 | * List should be terminated with an 0xff, 0xff pair. |
67 | */ | 67 | */ |
68 | u8* inittab; | 68 | const u8* inittab; |
69 | 69 | ||
70 | /* master clock to use */ | 70 | /* master clock to use */ |
71 | u32 mclk; | 71 | u32 mclk; |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index f2a8abe0a24..ea485d92355 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -598,7 +598,7 @@ static int tda1004x_decode_fec(int tdafec) | |||
598 | return -1; | 598 | return -1; |
599 | } | 599 | } |
600 | 600 | ||
601 | static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) | 601 | static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len) |
602 | { | 602 | { |
603 | struct tda1004x_state* state = fe->demodulator_priv; | 603 | struct tda1004x_state* state = fe->demodulator_priv; |
604 | 604 | ||
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 8c612719adf..adbbf6d3d04 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c | |||
@@ -64,7 +64,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) | |||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) | 67 | static int zl10353_write(struct dvb_frontend *fe, const u8 ibuf[], int ilen) |
68 | { | 68 | { |
69 | int err, i; | 69 | int err, i; |
70 | for (i = 0; i < ilen - 1; i++) | 70 | for (i = 0; i < ilen - 1; i++) |
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c index 8113b23ce44..22524a8e6f6 100644 --- a/drivers/media/dvb/mantis/mantis_core.c +++ b/drivers/media/dvb/mantis/mantis_core.c | |||
@@ -91,10 +91,7 @@ static int get_mac_address(struct mantis_pci *mantis) | |||
91 | return err; | 91 | return err; |
92 | } | 92 | } |
93 | dprintk(verbose, MANTIS_ERROR, 0, | 93 | dprintk(verbose, MANTIS_ERROR, 0, |
94 | " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", | 94 | " MAC Address=[%pM]\n", mantis->mac_address); |
95 | mantis->mac_address[0], mantis->mac_address[1], | ||
96 | mantis->mac_address[2], mantis->mac_address[3], | ||
97 | mantis->mac_address[4], mantis->mac_address[5]); | ||
98 | 95 | ||
99 | return 0; | 96 | return 0; |
100 | } | 97 | } |
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c index 7870bcf9689..e7794517fe2 100644 --- a/drivers/media/dvb/mantis/mantis_i2c.c +++ b/drivers/media/dvb/mantis/mantis_i2c.c | |||
@@ -229,7 +229,6 @@ int __devinit mantis_i2c_init(struct mantis_pci *mantis) | |||
229 | i2c_set_adapdata(i2c_adapter, mantis); | 229 | i2c_set_adapdata(i2c_adapter, mantis); |
230 | 230 | ||
231 | i2c_adapter->owner = THIS_MODULE; | 231 | i2c_adapter->owner = THIS_MODULE; |
232 | i2c_adapter->class = I2C_CLASS_TV_DIGITAL; | ||
233 | i2c_adapter->algo = &mantis_algo; | 232 | i2c_adapter->algo = &mantis_algo; |
234 | i2c_adapter->algo_data = NULL; | 233 | i2c_adapter->algo_data = NULL; |
235 | i2c_adapter->timeout = 500; | 234 | i2c_adapter->timeout = 500; |
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c index de148ded52d..fe31cfb0b15 100644 --- a/drivers/media/dvb/mantis/mantis_ioc.c +++ b/drivers/media/dvb/mantis/mantis_ioc.c | |||
@@ -68,14 +68,7 @@ int mantis_get_mac(struct mantis_pci *mantis) | |||
68 | return err; | 68 | return err; |
69 | } | 69 | } |
70 | 70 | ||
71 | dprintk(MANTIS_ERROR, 0, | 71 | dprintk(MANTIS_ERROR, 0, " MAC Address=[%pM]\n", mac_addr); |
72 | " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", | ||
73 | mac_addr[0], | ||
74 | mac_addr[1], | ||
75 | mac_addr[2], | ||
76 | mac_addr[3], | ||
77 | mac_addr[4], | ||
78 | mac_addr[5]); | ||
79 | 72 | ||
80 | return 0; | 73 | return 0; |
81 | } | 74 | } |
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c index 477fe0aade8..c3ae956714e 100644 --- a/drivers/media/dvb/ngene/ngene-i2c.c +++ b/drivers/media/dvb/ngene/ngene-i2c.c | |||
@@ -165,7 +165,6 @@ int ngene_i2c_init(struct ngene *dev, int dev_nr) | |||
165 | struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); | 165 | struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); |
166 | 166 | ||
167 | i2c_set_adapdata(adap, &(dev->channel[dev_nr])); | 167 | i2c_set_adapdata(adap, &(dev->channel[dev_nr])); |
168 | adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG; | ||
169 | 168 | ||
170 | strcpy(adap->name, "nGene"); | 169 | strcpy(adap->name, "nGene"); |
171 | 170 | ||
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1c798219dc7..6ca6713d527 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c | |||
@@ -647,7 +647,6 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, | |||
647 | i2c_set_adapdata(&pluto->i2c_adap, pluto); | 647 | i2c_set_adapdata(&pluto->i2c_adap, pluto); |
648 | strcpy(pluto->i2c_adap.name, DRIVER_NAME); | 648 | strcpy(pluto->i2c_adap.name, DRIVER_NAME); |
649 | pluto->i2c_adap.owner = THIS_MODULE; | 649 | pluto->i2c_adap.owner = THIS_MODULE; |
650 | pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
651 | pluto->i2c_adap.dev.parent = &pdev->dev; | 650 | pluto->i2c_adap.dev.parent = &pdev->dev; |
652 | pluto->i2c_adap.algo_data = &pluto->i2c_bit; | 651 | pluto->i2c_adap.algo_data = &pluto->i2c_bit; |
653 | pluto->i2c_bit.data = pluto; | 652 | pluto->i2c_bit.data = pluto; |
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c index 69ad94934ec..0486919c1d0 100644 --- a/drivers/media/dvb/pt1/pt1.c +++ b/drivers/media/dvb/pt1/pt1.c | |||
@@ -1087,7 +1087,6 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1087 | pt1_update_power(pt1); | 1087 | pt1_update_power(pt1); |
1088 | 1088 | ||
1089 | i2c_adap = &pt1->i2c_adap; | 1089 | i2c_adap = &pt1->i2c_adap; |
1090 | i2c_adap->class = I2C_CLASS_TV_DIGITAL; | ||
1091 | i2c_adap->algo = &pt1_i2c_algo; | 1090 | i2c_adap->algo = &pt1_i2c_algo; |
1092 | i2c_adap->algo_data = NULL; | 1091 | i2c_adap->algo_data = NULL; |
1093 | i2c_adap->dev.parent = &pdev->dev; | 1092 | i2c_adap->dev.parent = &pdev->dev; |
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index ff3b0fa901b..135e45bd00c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c | |||
@@ -1504,8 +1504,7 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, | |||
1504 | u32 msgData[3]; /* keep it 3 ! */ | 1504 | u32 msgData[3]; /* keep it 3 ! */ |
1505 | } *pMsg; | 1505 | } *pMsg; |
1506 | 1506 | ||
1507 | if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || | 1507 | if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER)) |
1508 | (PinNum > MAX_GPIO_PIN_NUMBER)) | ||
1509 | return -EINVAL; | 1508 | return -EINVAL; |
1510 | 1509 | ||
1511 | totalLen = sizeof(struct SmsMsgHdr_ST) + | 1510 | totalLen = sizeof(struct SmsMsgHdr_ST) + |
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c index d0e4639ee9d..a27c44a8af5 100644 --- a/drivers/media/dvb/siano/smsir.c +++ b/drivers/media/dvb/siano/smsir.c | |||
@@ -40,7 +40,7 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) | |||
40 | const s32 *samples = (const void *)buf; | 40 | const s32 *samples = (const void *)buf; |
41 | 41 | ||
42 | for (i = 0; i < len >> 2; i++) { | 42 | for (i = 0; i < len >> 2; i++) { |
43 | struct ir_raw_event ev; | 43 | DEFINE_IR_RAW_EVENT(ev); |
44 | 44 | ||
45 | ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ | 45 | ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ |
46 | ev.pulse = (samples[i] > 0) ? false : true; | 46 | ev.pulse = (samples[i] > 0) ? false : true; |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index a12b88f53ed..fc0a60f8a1e 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -2472,7 +2472,6 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
2472 | get recognized before the main driver is fully loaded */ | 2472 | get recognized before the main driver is fully loaded */ |
2473 | saa7146_write(dev, GPIO_CTRL, 0x500000); | 2473 | saa7146_write(dev, GPIO_CTRL, 0x500000); |
2474 | 2474 | ||
2475 | av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
2476 | strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); | 2475 | strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); |
2477 | 2476 | ||
2478 | saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ | 2477 | saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ |
@@ -2886,7 +2885,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl); | |||
2886 | 2885 | ||
2887 | 2886 | ||
2888 | static struct saa7146_extension av7110_extension_driver = { | 2887 | static struct saa7146_extension av7110_extension_driver = { |
2889 | .name = "dvb", | 2888 | .name = "av7110", |
2890 | .flags = SAA7146_USE_I2C_IRQ, | 2889 | .flags = SAA7146_USE_I2C_IRQ, |
2891 | 2890 | ||
2892 | .module = THIS_MODULE, | 2891 | .module = THIS_MODULE, |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 244d5d51f5f..952b33dbac4 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -245,8 +245,11 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) | |||
245 | return -1; | 245 | return -1; |
246 | } | 246 | } |
247 | while (1) { | 247 | while (1) { |
248 | if ((len = dvb_ringbuffer_avail(buf)) < 6) | 248 | len = dvb_ringbuffer_avail(buf); |
249 | if (len < 6) { | ||
250 | wake_up(&buf->queue); | ||
249 | return -1; | 251 | return -1; |
252 | } | ||
250 | sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; | 253 | sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; |
251 | sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; | 254 | sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; |
252 | sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; | 255 | sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 05466131531..37666d4edab 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -495,8 +495,6 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
495 | if (bi->type != BUDGET_FS_ACTIVY) | 495 | if (bi->type != BUDGET_FS_ACTIVY) |
496 | saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ | 496 | saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ |
497 | 497 | ||
498 | budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
499 | |||
500 | strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); | 498 | strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); |
501 | 499 | ||
502 | saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); | 500 | saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 4a3f2b8ea37..40625b26ac1 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -1694,7 +1694,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1694 | 1694 | ||
1695 | i2c_set_adapdata(&ttusb->i2c_adap, ttusb); | 1695 | i2c_set_adapdata(&ttusb->i2c_adap, ttusb); |
1696 | 1696 | ||
1697 | ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
1698 | ttusb->i2c_adap.algo = &ttusb_dec_algo; | 1697 | ttusb->i2c_adap.algo = &ttusb_dec_algo; |
1699 | ttusb->i2c_adap.algo_data = NULL; | 1698 | ttusb->i2c_adap.algo_data = NULL; |
1700 | ttusb->i2c_adap.dev.parent = &udev->dev; | 1699 | ttusb->i2c_adap.dev.parent = &udev->dev; |
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 482d0f3be5f..b701ea6e7c7 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
@@ -374,7 +374,8 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
374 | switch (v->index) { | 374 | switch (v->index) { |
375 | case 0: | 375 | case 0: |
376 | strlcpy(v->name, "FM", sizeof(v->name)); | 376 | strlcpy(v->name, "FM", sizeof(v->name)); |
377 | v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS; | 377 | v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | |
378 | V4L2_TUNER_CAP_RDS_BLOCK_IO; | ||
378 | v->rangelow = 1400; /* 87.5 MHz */ | 379 | v->rangelow = 1400; /* 87.5 MHz */ |
379 | v->rangehigh = 1728; /* 108.0 MHz */ | 380 | v->rangehigh = 1728; /* 108.0 MHz */ |
380 | v->rxsubchans = cadet_getstereo(dev); | 381 | v->rxsubchans = cadet_getstereo(dev); |
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 353b8285594..b540e8072e9 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -176,8 +176,6 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) | |||
176 | int retval; | 176 | int retval; |
177 | int size; | 177 | int size; |
178 | 178 | ||
179 | BUG_ON(!mutex_is_locked(&radio->lock)); | ||
180 | |||
181 | radio->buffer[0] = 0x00; | 179 | radio->buffer[0] = 0x00; |
182 | radio->buffer[1] = 0x55; | 180 | radio->buffer[1] = 0x55; |
183 | radio->buffer[2] = 0xaa; | 181 | radio->buffer[2] = 0xaa; |
@@ -207,8 +205,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) | |||
207 | int size; | 205 | int size; |
208 | unsigned short freq_send = 0x10 + (freq >> 3) / 25; | 206 | unsigned short freq_send = 0x10 + (freq >> 3) / 25; |
209 | 207 | ||
210 | BUG_ON(!mutex_is_locked(&radio->lock)); | ||
211 | |||
212 | radio->buffer[0] = 0x00; | 208 | radio->buffer[0] = 0x00; |
213 | radio->buffer[1] = 0x55; | 209 | radio->buffer[1] = 0x55; |
214 | radio->buffer[2] = 0xaa; | 210 | radio->buffer[2] = 0xaa; |
@@ -253,8 +249,6 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) | |||
253 | int retval; | 249 | int retval; |
254 | int size; | 250 | int size; |
255 | 251 | ||
256 | BUG_ON(!mutex_is_locked(&radio->lock)); | ||
257 | |||
258 | radio->buffer[0] = 0x00; | 252 | radio->buffer[0] = 0x00; |
259 | radio->buffer[1] = 0x55; | 253 | radio->buffer[1] = 0x55; |
260 | radio->buffer[2] = 0xaa; | 254 | radio->buffer[2] = 0xaa; |
@@ -290,11 +284,13 @@ static void usb_amradio_disconnect(struct usb_interface *intf) | |||
290 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); | 284 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); |
291 | 285 | ||
292 | mutex_lock(&radio->lock); | 286 | mutex_lock(&radio->lock); |
293 | radio->usbdev = NULL; | 287 | /* increase the device node's refcount */ |
294 | mutex_unlock(&radio->lock); | 288 | get_device(&radio->videodev.dev); |
295 | |||
296 | v4l2_device_disconnect(&radio->v4l2_dev); | 289 | v4l2_device_disconnect(&radio->v4l2_dev); |
297 | video_unregister_device(&radio->videodev); | 290 | video_unregister_device(&radio->videodev); |
291 | mutex_unlock(&radio->lock); | ||
292 | /* decrease the device node's refcount, allowing it to be released */ | ||
293 | put_device(&radio->videodev.dev); | ||
298 | } | 294 | } |
299 | 295 | ||
300 | /* vidioc_querycap - query device capabilities */ | 296 | /* vidioc_querycap - query device capabilities */ |
@@ -503,28 +499,18 @@ out: | |||
503 | static int usb_amradio_open(struct file *file) | 499 | static int usb_amradio_open(struct file *file) |
504 | { | 500 | { |
505 | struct amradio_device *radio = video_drvdata(file); | 501 | struct amradio_device *radio = video_drvdata(file); |
506 | int retval = 0; | 502 | int retval; |
507 | |||
508 | mutex_lock(&radio->lock); | ||
509 | |||
510 | if (!radio->usbdev) { | ||
511 | retval = -EIO; | ||
512 | goto unlock; | ||
513 | } | ||
514 | 503 | ||
515 | file->private_data = radio; | 504 | file->private_data = radio; |
516 | retval = usb_autopm_get_interface(radio->intf); | 505 | retval = usb_autopm_get_interface(radio->intf); |
517 | if (retval) | 506 | if (retval) |
518 | goto unlock; | 507 | return retval; |
519 | 508 | ||
520 | if (unlikely(!radio->initialized)) { | 509 | if (unlikely(!radio->initialized)) { |
521 | retval = usb_amradio_init(radio); | 510 | retval = usb_amradio_init(radio); |
522 | if (retval) | 511 | if (retval) |
523 | usb_autopm_put_interface(radio->intf); | 512 | usb_autopm_put_interface(radio->intf); |
524 | } | 513 | } |
525 | |||
526 | unlock: | ||
527 | mutex_unlock(&radio->lock); | ||
528 | return retval; | 514 | return retval; |
529 | } | 515 | } |
530 | 516 | ||
@@ -532,37 +518,10 @@ unlock: | |||
532 | static int usb_amradio_close(struct file *file) | 518 | static int usb_amradio_close(struct file *file) |
533 | { | 519 | { |
534 | struct amradio_device *radio = file->private_data; | 520 | struct amradio_device *radio = file->private_data; |
535 | int retval = 0; | ||
536 | |||
537 | mutex_lock(&radio->lock); | ||
538 | 521 | ||
539 | if (!radio->usbdev) | 522 | if (video_is_registered(&radio->videodev)) |
540 | retval = -EIO; | ||
541 | else | ||
542 | usb_autopm_put_interface(radio->intf); | 523 | usb_autopm_put_interface(radio->intf); |
543 | 524 | return 0; | |
544 | mutex_unlock(&radio->lock); | ||
545 | return retval; | ||
546 | } | ||
547 | |||
548 | static long usb_amradio_ioctl(struct file *file, unsigned int cmd, | ||
549 | unsigned long arg) | ||
550 | { | ||
551 | struct amradio_device *radio = file->private_data; | ||
552 | long retval = 0; | ||
553 | |||
554 | mutex_lock(&radio->lock); | ||
555 | |||
556 | if (!radio->usbdev) { | ||
557 | retval = -EIO; | ||
558 | goto unlock; | ||
559 | } | ||
560 | |||
561 | retval = video_ioctl2(file, cmd, arg); | ||
562 | |||
563 | unlock: | ||
564 | mutex_unlock(&radio->lock); | ||
565 | return retval; | ||
566 | } | 525 | } |
567 | 526 | ||
568 | /* Suspend device - stop device. Need to be checked and fixed */ | 527 | /* Suspend device - stop device. Need to be checked and fixed */ |
@@ -571,15 +530,13 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) | |||
571 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); | 530 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); |
572 | 531 | ||
573 | mutex_lock(&radio->lock); | 532 | mutex_lock(&radio->lock); |
574 | |||
575 | if (!radio->muted && radio->initialized) { | 533 | if (!radio->muted && radio->initialized) { |
576 | amradio_set_mute(radio, AMRADIO_STOP); | 534 | amradio_set_mute(radio, AMRADIO_STOP); |
577 | radio->muted = 0; | 535 | radio->muted = 0; |
578 | } | 536 | } |
537 | mutex_unlock(&radio->lock); | ||
579 | 538 | ||
580 | dev_info(&intf->dev, "going into suspend..\n"); | 539 | dev_info(&intf->dev, "going into suspend..\n"); |
581 | |||
582 | mutex_unlock(&radio->lock); | ||
583 | return 0; | 540 | return 0; |
584 | } | 541 | } |
585 | 542 | ||
@@ -589,7 +546,6 @@ static int usb_amradio_resume(struct usb_interface *intf) | |||
589 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); | 546 | struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); |
590 | 547 | ||
591 | mutex_lock(&radio->lock); | 548 | mutex_lock(&radio->lock); |
592 | |||
593 | if (unlikely(!radio->initialized)) | 549 | if (unlikely(!radio->initialized)) |
594 | goto unlock; | 550 | goto unlock; |
595 | 551 | ||
@@ -604,9 +560,9 @@ static int usb_amradio_resume(struct usb_interface *intf) | |||
604 | amradio_set_mute(radio, AMRADIO_START); | 560 | amradio_set_mute(radio, AMRADIO_START); |
605 | 561 | ||
606 | unlock: | 562 | unlock: |
607 | dev_info(&intf->dev, "coming out of suspend..\n"); | ||
608 | |||
609 | mutex_unlock(&radio->lock); | 563 | mutex_unlock(&radio->lock); |
564 | |||
565 | dev_info(&intf->dev, "coming out of suspend..\n"); | ||
610 | return 0; | 566 | return 0; |
611 | } | 567 | } |
612 | 568 | ||
@@ -615,7 +571,7 @@ static const struct v4l2_file_operations usb_amradio_fops = { | |||
615 | .owner = THIS_MODULE, | 571 | .owner = THIS_MODULE, |
616 | .open = usb_amradio_open, | 572 | .open = usb_amradio_open, |
617 | .release = usb_amradio_close, | 573 | .release = usb_amradio_close, |
618 | .ioctl = usb_amradio_ioctl, | 574 | .unlocked_ioctl = video_ioctl2, |
619 | }; | 575 | }; |
620 | 576 | ||
621 | static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { | 577 | static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { |
@@ -671,19 +627,20 @@ static int usb_amradio_probe(struct usb_interface *intf, | |||
671 | goto err_v4l2; | 627 | goto err_v4l2; |
672 | } | 628 | } |
673 | 629 | ||
630 | mutex_init(&radio->lock); | ||
631 | |||
674 | strlcpy(radio->videodev.name, radio->v4l2_dev.name, | 632 | strlcpy(radio->videodev.name, radio->v4l2_dev.name, |
675 | sizeof(radio->videodev.name)); | 633 | sizeof(radio->videodev.name)); |
676 | radio->videodev.v4l2_dev = &radio->v4l2_dev; | 634 | radio->videodev.v4l2_dev = &radio->v4l2_dev; |
677 | radio->videodev.fops = &usb_amradio_fops; | 635 | radio->videodev.fops = &usb_amradio_fops; |
678 | radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; | 636 | radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; |
679 | radio->videodev.release = usb_amradio_video_device_release; | 637 | radio->videodev.release = usb_amradio_video_device_release; |
638 | radio->videodev.lock = &radio->lock; | ||
680 | 639 | ||
681 | radio->usbdev = interface_to_usbdev(intf); | 640 | radio->usbdev = interface_to_usbdev(intf); |
682 | radio->intf = intf; | 641 | radio->intf = intf; |
683 | radio->curfreq = 95.16 * FREQ_MUL; | 642 | radio->curfreq = 95.16 * FREQ_MUL; |
684 | 643 | ||
685 | mutex_init(&radio->lock); | ||
686 | |||
687 | video_set_drvdata(&radio->videodev, radio); | 644 | video_set_drvdata(&radio->videodev, radio); |
688 | 645 | ||
689 | retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, | 646 | retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, |
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 13554ab13f7..6a435786b63 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c | |||
@@ -291,19 +291,19 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) | |||
291 | goto unregister_v4l2_dev; | 291 | goto unregister_v4l2_dev; |
292 | } | 292 | } |
293 | 293 | ||
294 | sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, "si4713_i2c", | 294 | sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL, |
295 | pdata->subdev_board_info, NULL); | 295 | pdata->subdev_board_info, NULL); |
296 | if (!sd) { | 296 | if (!sd) { |
297 | dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); | 297 | dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); |
298 | rval = -ENODEV; | 298 | rval = -ENODEV; |
299 | goto unregister_v4l2_dev; | 299 | goto put_adapter; |
300 | } | 300 | } |
301 | 301 | ||
302 | rsdev->radio_dev = video_device_alloc(); | 302 | rsdev->radio_dev = video_device_alloc(); |
303 | if (!rsdev->radio_dev) { | 303 | if (!rsdev->radio_dev) { |
304 | dev_err(&pdev->dev, "Failed to alloc video device.\n"); | 304 | dev_err(&pdev->dev, "Failed to alloc video device.\n"); |
305 | rval = -ENOMEM; | 305 | rval = -ENOMEM; |
306 | goto unregister_v4l2_dev; | 306 | goto put_adapter; |
307 | } | 307 | } |
308 | 308 | ||
309 | memcpy(rsdev->radio_dev, &radio_si4713_vdev_template, | 309 | memcpy(rsdev->radio_dev, &radio_si4713_vdev_template, |
@@ -320,6 +320,8 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) | |||
320 | 320 | ||
321 | free_vdev: | 321 | free_vdev: |
322 | video_device_release(rsdev->radio_dev); | 322 | video_device_release(rsdev->radio_dev); |
323 | put_adapter: | ||
324 | i2c_put_adapter(adapter); | ||
323 | unregister_v4l2_dev: | 325 | unregister_v4l2_dev: |
324 | v4l2_device_unregister(&rsdev->v4l2_dev); | 326 | v4l2_device_unregister(&rsdev->v4l2_dev); |
325 | free_rsdev: | 327 | free_rsdev: |
@@ -335,8 +337,12 @@ static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev) | |||
335 | struct radio_si4713_device *rsdev = container_of(v4l2_dev, | 337 | struct radio_si4713_device *rsdev = container_of(v4l2_dev, |
336 | struct radio_si4713_device, | 338 | struct radio_si4713_device, |
337 | v4l2_dev); | 339 | v4l2_dev); |
340 | struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next, | ||
341 | struct v4l2_subdev, list); | ||
342 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
338 | 343 | ||
339 | video_unregister_device(rsdev->radio_dev); | 344 | video_unregister_device(rsdev->radio_dev); |
345 | i2c_put_adapter(client->adapter); | ||
340 | v4l2_device_unregister(&rsdev->v4l2_dev); | 346 | v4l2_device_unregister(&rsdev->v4l2_dev); |
341 | kfree(rsdev); | 347 | kfree(rsdev); |
342 | 348 | ||
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 9927a595b42..ac76dfe5b3f 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -408,17 +408,15 @@ done: | |||
408 | /* | 408 | /* |
409 | * si470x_rds_on - switch on rds reception | 409 | * si470x_rds_on - switch on rds reception |
410 | */ | 410 | */ |
411 | int si470x_rds_on(struct si470x_device *radio) | 411 | static int si470x_rds_on(struct si470x_device *radio) |
412 | { | 412 | { |
413 | int retval; | 413 | int retval; |
414 | 414 | ||
415 | /* sysconfig 1 */ | 415 | /* sysconfig 1 */ |
416 | mutex_lock(&radio->lock); | ||
417 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; | 416 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; |
418 | retval = si470x_set_register(radio, SYSCONFIG1); | 417 | retval = si470x_set_register(radio, SYSCONFIG1); |
419 | if (retval < 0) | 418 | if (retval < 0) |
420 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; | 419 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; |
421 | mutex_unlock(&radio->lock); | ||
422 | 420 | ||
423 | return retval; | 421 | return retval; |
424 | } | 422 | } |
@@ -440,6 +438,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, | |||
440 | unsigned int block_count = 0; | 438 | unsigned int block_count = 0; |
441 | 439 | ||
442 | /* switch on rds reception */ | 440 | /* switch on rds reception */ |
441 | mutex_lock(&radio->lock); | ||
443 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | 442 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) |
444 | si470x_rds_on(radio); | 443 | si470x_rds_on(radio); |
445 | 444 | ||
@@ -480,9 +479,9 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, | |||
480 | buf += 3; | 479 | buf += 3; |
481 | retval += 3; | 480 | retval += 3; |
482 | } | 481 | } |
483 | mutex_unlock(&radio->lock); | ||
484 | 482 | ||
485 | done: | 483 | done: |
484 | mutex_unlock(&radio->lock); | ||
486 | return retval; | 485 | return retval; |
487 | } | 486 | } |
488 | 487 | ||
@@ -497,8 +496,11 @@ static unsigned int si470x_fops_poll(struct file *file, | |||
497 | int retval = 0; | 496 | int retval = 0; |
498 | 497 | ||
499 | /* switch on rds reception */ | 498 | /* switch on rds reception */ |
499 | |||
500 | mutex_lock(&radio->lock); | ||
500 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | 501 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) |
501 | si470x_rds_on(radio); | 502 | si470x_rds_on(radio); |
503 | mutex_unlock(&radio->lock); | ||
502 | 504 | ||
503 | poll_wait(file, &radio->read_queue, pts); | 505 | poll_wait(file, &radio->read_queue, pts); |
504 | 506 | ||
@@ -516,7 +518,7 @@ static const struct v4l2_file_operations si470x_fops = { | |||
516 | .owner = THIS_MODULE, | 518 | .owner = THIS_MODULE, |
517 | .read = si470x_fops_read, | 519 | .read = si470x_fops_read, |
518 | .poll = si470x_fops_poll, | 520 | .poll = si470x_fops_poll, |
519 | .ioctl = video_ioctl2, | 521 | .unlocked_ioctl = video_ioctl2, |
520 | .open = si470x_fops_open, | 522 | .open = si470x_fops_open, |
521 | .release = si470x_fops_release, | 523 | .release = si470x_fops_release, |
522 | }; | 524 | }; |
@@ -572,6 +574,7 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, | |||
572 | struct si470x_device *radio = video_drvdata(file); | 574 | struct si470x_device *radio = video_drvdata(file); |
573 | int retval = 0; | 575 | int retval = 0; |
574 | 576 | ||
577 | mutex_lock(&radio->lock); | ||
575 | /* safety checks */ | 578 | /* safety checks */ |
576 | retval = si470x_disconnect_check(radio); | 579 | retval = si470x_disconnect_check(radio); |
577 | if (retval) | 580 | if (retval) |
@@ -594,6 +597,8 @@ done: | |||
594 | if (retval < 0) | 597 | if (retval < 0) |
595 | dev_warn(&radio->videodev->dev, | 598 | dev_warn(&radio->videodev->dev, |
596 | "get control failed with %d\n", retval); | 599 | "get control failed with %d\n", retval); |
600 | |||
601 | mutex_unlock(&radio->lock); | ||
597 | return retval; | 602 | return retval; |
598 | } | 603 | } |
599 | 604 | ||
@@ -607,6 +612,7 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, | |||
607 | struct si470x_device *radio = video_drvdata(file); | 612 | struct si470x_device *radio = video_drvdata(file); |
608 | int retval = 0; | 613 | int retval = 0; |
609 | 614 | ||
615 | mutex_lock(&radio->lock); | ||
610 | /* safety checks */ | 616 | /* safety checks */ |
611 | retval = si470x_disconnect_check(radio); | 617 | retval = si470x_disconnect_check(radio); |
612 | if (retval) | 618 | if (retval) |
@@ -633,6 +639,7 @@ done: | |||
633 | if (retval < 0) | 639 | if (retval < 0) |
634 | dev_warn(&radio->videodev->dev, | 640 | dev_warn(&radio->videodev->dev, |
635 | "set control failed with %d\n", retval); | 641 | "set control failed with %d\n", retval); |
642 | mutex_unlock(&radio->lock); | ||
636 | return retval; | 643 | return retval; |
637 | } | 644 | } |
638 | 645 | ||
@@ -662,6 +669,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
662 | struct si470x_device *radio = video_drvdata(file); | 669 | struct si470x_device *radio = video_drvdata(file); |
663 | int retval = 0; | 670 | int retval = 0; |
664 | 671 | ||
672 | mutex_lock(&radio->lock); | ||
665 | /* safety checks */ | 673 | /* safety checks */ |
666 | retval = si470x_disconnect_check(radio); | 674 | retval = si470x_disconnect_check(radio); |
667 | if (retval) | 675 | if (retval) |
@@ -681,7 +689,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
681 | tuner->type = V4L2_TUNER_RADIO; | 689 | tuner->type = V4L2_TUNER_RADIO; |
682 | #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) | 690 | #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) |
683 | tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 691 | tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
684 | V4L2_TUNER_CAP_RDS; | 692 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; |
685 | #else | 693 | #else |
686 | tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | 694 | tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; |
687 | #endif | 695 | #endif |
@@ -737,6 +745,7 @@ done: | |||
737 | if (retval < 0) | 745 | if (retval < 0) |
738 | dev_warn(&radio->videodev->dev, | 746 | dev_warn(&radio->videodev->dev, |
739 | "get tuner failed with %d\n", retval); | 747 | "get tuner failed with %d\n", retval); |
748 | mutex_unlock(&radio->lock); | ||
740 | return retval; | 749 | return retval; |
741 | } | 750 | } |
742 | 751 | ||
@@ -750,6 +759,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, | |||
750 | struct si470x_device *radio = video_drvdata(file); | 759 | struct si470x_device *radio = video_drvdata(file); |
751 | int retval = 0; | 760 | int retval = 0; |
752 | 761 | ||
762 | mutex_lock(&radio->lock); | ||
753 | /* safety checks */ | 763 | /* safety checks */ |
754 | retval = si470x_disconnect_check(radio); | 764 | retval = si470x_disconnect_check(radio); |
755 | if (retval) | 765 | if (retval) |
@@ -776,6 +786,7 @@ done: | |||
776 | if (retval < 0) | 786 | if (retval < 0) |
777 | dev_warn(&radio->videodev->dev, | 787 | dev_warn(&radio->videodev->dev, |
778 | "set tuner failed with %d\n", retval); | 788 | "set tuner failed with %d\n", retval); |
789 | mutex_unlock(&radio->lock); | ||
779 | return retval; | 790 | return retval; |
780 | } | 791 | } |
781 | 792 | ||
@@ -790,6 +801,7 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, | |||
790 | int retval = 0; | 801 | int retval = 0; |
791 | 802 | ||
792 | /* safety checks */ | 803 | /* safety checks */ |
804 | mutex_lock(&radio->lock); | ||
793 | retval = si470x_disconnect_check(radio); | 805 | retval = si470x_disconnect_check(radio); |
794 | if (retval) | 806 | if (retval) |
795 | goto done; | 807 | goto done; |
@@ -806,6 +818,7 @@ done: | |||
806 | if (retval < 0) | 818 | if (retval < 0) |
807 | dev_warn(&radio->videodev->dev, | 819 | dev_warn(&radio->videodev->dev, |
808 | "get frequency failed with %d\n", retval); | 820 | "get frequency failed with %d\n", retval); |
821 | mutex_unlock(&radio->lock); | ||
809 | return retval; | 822 | return retval; |
810 | } | 823 | } |
811 | 824 | ||
@@ -819,6 +832,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, | |||
819 | struct si470x_device *radio = video_drvdata(file); | 832 | struct si470x_device *radio = video_drvdata(file); |
820 | int retval = 0; | 833 | int retval = 0; |
821 | 834 | ||
835 | mutex_lock(&radio->lock); | ||
822 | /* safety checks */ | 836 | /* safety checks */ |
823 | retval = si470x_disconnect_check(radio); | 837 | retval = si470x_disconnect_check(radio); |
824 | if (retval) | 838 | if (retval) |
@@ -835,6 +849,7 @@ done: | |||
835 | if (retval < 0) | 849 | if (retval < 0) |
836 | dev_warn(&radio->videodev->dev, | 850 | dev_warn(&radio->videodev->dev, |
837 | "set frequency failed with %d\n", retval); | 851 | "set frequency failed with %d\n", retval); |
852 | mutex_unlock(&radio->lock); | ||
838 | return retval; | 853 | return retval; |
839 | } | 854 | } |
840 | 855 | ||
@@ -848,6 +863,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, | |||
848 | struct si470x_device *radio = video_drvdata(file); | 863 | struct si470x_device *radio = video_drvdata(file); |
849 | int retval = 0; | 864 | int retval = 0; |
850 | 865 | ||
866 | mutex_lock(&radio->lock); | ||
851 | /* safety checks */ | 867 | /* safety checks */ |
852 | retval = si470x_disconnect_check(radio); | 868 | retval = si470x_disconnect_check(radio); |
853 | if (retval) | 869 | if (retval) |
@@ -864,6 +880,7 @@ done: | |||
864 | if (retval < 0) | 880 | if (retval < 0) |
865 | dev_warn(&radio->videodev->dev, | 881 | dev_warn(&radio->videodev->dev, |
866 | "set hardware frequency seek failed with %d\n", retval); | 882 | "set hardware frequency seek failed with %d\n", retval); |
883 | mutex_unlock(&radio->lock); | ||
867 | return retval; | 884 | return retval; |
868 | } | 885 | } |
869 | 886 | ||
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 5ec13e50a9f..392e84fe90e 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -517,7 +517,7 @@ int si470x_fops_open(struct file *file) | |||
517 | struct si470x_device *radio = video_drvdata(file); | 517 | struct si470x_device *radio = video_drvdata(file); |
518 | int retval; | 518 | int retval; |
519 | 519 | ||
520 | lock_kernel(); | 520 | mutex_lock(&radio->lock); |
521 | radio->users++; | 521 | radio->users++; |
522 | 522 | ||
523 | retval = usb_autopm_get_interface(radio->intf); | 523 | retval = usb_autopm_get_interface(radio->intf); |
@@ -558,7 +558,7 @@ int si470x_fops_open(struct file *file) | |||
558 | } | 558 | } |
559 | 559 | ||
560 | done: | 560 | done: |
561 | unlock_kernel(); | 561 | mutex_unlock(&radio->lock); |
562 | return retval; | 562 | return retval; |
563 | } | 563 | } |
564 | 564 | ||
@@ -577,7 +577,7 @@ int si470x_fops_release(struct file *file) | |||
577 | goto done; | 577 | goto done; |
578 | } | 578 | } |
579 | 579 | ||
580 | mutex_lock(&radio->disconnect_lock); | 580 | mutex_lock(&radio->lock); |
581 | radio->users--; | 581 | radio->users--; |
582 | if (radio->users == 0) { | 582 | if (radio->users == 0) { |
583 | /* shutdown interrupt handler */ | 583 | /* shutdown interrupt handler */ |
@@ -591,7 +591,7 @@ int si470x_fops_release(struct file *file) | |||
591 | video_unregister_device(radio->videodev); | 591 | video_unregister_device(radio->videodev); |
592 | kfree(radio->int_in_buffer); | 592 | kfree(radio->int_in_buffer); |
593 | kfree(radio->buffer); | 593 | kfree(radio->buffer); |
594 | mutex_unlock(&radio->disconnect_lock); | 594 | mutex_unlock(&radio->lock); |
595 | kfree(radio); | 595 | kfree(radio); |
596 | goto done; | 596 | goto done; |
597 | } | 597 | } |
@@ -603,7 +603,7 @@ int si470x_fops_release(struct file *file) | |||
603 | retval = si470x_stop(radio); | 603 | retval = si470x_stop(radio); |
604 | usb_autopm_put_interface(radio->intf); | 604 | usb_autopm_put_interface(radio->intf); |
605 | } | 605 | } |
606 | mutex_unlock(&radio->disconnect_lock); | 606 | mutex_unlock(&radio->lock); |
607 | done: | 607 | done: |
608 | return retval; | 608 | return retval; |
609 | } | 609 | } |
@@ -661,7 +661,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
661 | radio->disconnected = 0; | 661 | radio->disconnected = 0; |
662 | radio->usbdev = interface_to_usbdev(intf); | 662 | radio->usbdev = interface_to_usbdev(intf); |
663 | radio->intf = intf; | 663 | radio->intf = intf; |
664 | mutex_init(&radio->disconnect_lock); | ||
665 | mutex_init(&radio->lock); | 664 | mutex_init(&radio->lock); |
666 | 665 | ||
667 | iface_desc = intf->cur_altsetting; | 666 | iface_desc = intf->cur_altsetting; |
@@ -830,7 +829,7 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) | |||
830 | { | 829 | { |
831 | struct si470x_device *radio = usb_get_intfdata(intf); | 830 | struct si470x_device *radio = usb_get_intfdata(intf); |
832 | 831 | ||
833 | mutex_lock(&radio->disconnect_lock); | 832 | mutex_lock(&radio->lock); |
834 | radio->disconnected = 1; | 833 | radio->disconnected = 1; |
835 | usb_set_intfdata(intf, NULL); | 834 | usb_set_intfdata(intf, NULL); |
836 | if (radio->users == 0) { | 835 | if (radio->users == 0) { |
@@ -843,10 +842,10 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) | |||
843 | kfree(radio->int_in_buffer); | 842 | kfree(radio->int_in_buffer); |
844 | video_unregister_device(radio->videodev); | 843 | video_unregister_device(radio->videodev); |
845 | kfree(radio->buffer); | 844 | kfree(radio->buffer); |
846 | mutex_unlock(&radio->disconnect_lock); | 845 | mutex_unlock(&radio->lock); |
847 | kfree(radio); | 846 | kfree(radio); |
848 | } else { | 847 | } else { |
849 | mutex_unlock(&radio->disconnect_lock); | 848 | mutex_unlock(&radio->lock); |
850 | } | 849 | } |
851 | } | 850 | } |
852 | 851 | ||
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 3cd0a29cd6e..ea12782359a 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h | |||
@@ -177,7 +177,6 @@ struct si470x_device { | |||
177 | 177 | ||
178 | /* driver management */ | 178 | /* driver management */ |
179 | unsigned char disconnected; | 179 | unsigned char disconnected; |
180 | struct mutex disconnect_lock; | ||
181 | #endif | 180 | #endif |
182 | 181 | ||
183 | #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) | 182 | #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) |
@@ -221,7 +220,6 @@ int si470x_disconnect_check(struct si470x_device *radio); | |||
221 | int si470x_set_freq(struct si470x_device *radio, unsigned int freq); | 220 | int si470x_set_freq(struct si470x_device *radio, unsigned int freq); |
222 | int si470x_start(struct si470x_device *radio); | 221 | int si470x_start(struct si470x_device *radio); |
223 | int si470x_stop(struct si470x_device *radio); | 222 | int si470x_stop(struct si470x_device *radio); |
224 | int si470x_rds_on(struct si470x_device *radio); | ||
225 | int si470x_fops_open(struct file *file); | 223 | int si470x_fops_open(struct file *file); |
226 | int si470x_fops_release(struct file *file); | 224 | int si470x_fops_release(struct file *file); |
227 | int si470x_vidioc_querycap(struct file *file, void *priv, | 225 | int si470x_vidioc_querycap(struct file *file, void *priv, |
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index fc7f4b79464..a6e6f1987a3 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c | |||
@@ -1804,7 +1804,7 @@ static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm) | |||
1804 | 1804 | ||
1805 | strncpy(vm->name, "FM Modulator", 32); | 1805 | strncpy(vm->name, "FM Modulator", 32); |
1806 | vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW | | 1806 | vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW | |
1807 | V4L2_TUNER_CAP_RDS; | 1807 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS; |
1808 | 1808 | ||
1809 | /* Report current frequency range limits */ | 1809 | /* Report current frequency range limits */ |
1810 | vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW); | 1810 | vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW); |
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index 90cae90277e..7c0d77751f6 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/i2c-id.h> | ||
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <media/v4l2-ioctl.h> | 26 | #include <media/v4l2-ioctl.h> |
28 | #include <media/v4l2-device.h> | 27 | #include <media/v4l2-device.h> |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d000522cb0f..ac16e815e27 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -539,7 +539,7 @@ config VIDEO_VIU | |||
539 | config VIDEO_VIVI | 539 | config VIDEO_VIVI |
540 | tristate "Virtual Video Driver" | 540 | tristate "Virtual Video Driver" |
541 | depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 | 541 | depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 |
542 | depends on (FRAMEBUFFER_CONSOLE || STI_CONSOLE) && FONTS | 542 | depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE |
543 | select FONT_8x16 | 543 | select FONT_8x16 |
544 | select VIDEOBUF_VMALLOC | 544 | select VIDEOBUF_VMALLOC |
545 | default n | 545 | default n |
@@ -599,68 +599,8 @@ config VIDEO_W9966 | |||
599 | Check out <file:Documentation/video4linux/w9966.txt> for more | 599 | Check out <file:Documentation/video4linux/w9966.txt> for more |
600 | information. | 600 | information. |
601 | 601 | ||
602 | config VIDEO_CPIA | ||
603 | tristate "CPiA Video For Linux (DEPRECATED)" | ||
604 | depends on VIDEO_V4L1 | ||
605 | default n | ||
606 | ---help--- | ||
607 | This driver is DEPRECATED please use the gspca cpia1 module | ||
608 | instead. Note that you need atleast version 0.6.4 of libv4l for | ||
609 | the cpia1 gspca module. | ||
610 | |||
611 | This is the video4linux driver for cameras based on Vision's CPiA | ||
612 | (Colour Processor Interface ASIC), such as the Creative Labs Video | ||
613 | Blaster Webcam II. If you have one of these cameras, say Y here | ||
614 | and select parallel port and/or USB lowlevel support below, | ||
615 | otherwise say N. This will not work with the Creative Webcam III. | ||
616 | |||
617 | Please read <file:Documentation/video4linux/README.cpia> for more | ||
618 | information. | ||
619 | |||
620 | This driver is also available as a module (cpia). | ||
621 | |||
622 | config VIDEO_CPIA_PP | ||
623 | tristate "CPiA Parallel Port Lowlevel Support" | ||
624 | depends on PARPORT_1284 && VIDEO_CPIA && PARPORT | ||
625 | help | ||
626 | This is the lowlevel parallel port support for cameras based on | ||
627 | Vision's CPiA (Colour Processor Interface ASIC), such as the | ||
628 | Creative Webcam II. If you have the parallel port version of one | ||
629 | of these cameras, say Y here, otherwise say N. It is also available | ||
630 | as a module (cpia_pp). | ||
631 | |||
632 | config VIDEO_CPIA_USB | ||
633 | tristate "CPiA USB Lowlevel Support" | ||
634 | depends on VIDEO_CPIA && USB | ||
635 | help | ||
636 | This is the lowlevel USB support for cameras based on Vision's CPiA | ||
637 | (Colour Processor Interface ASIC), such as the Creative Webcam II. | ||
638 | If you have the USB version of one of these cameras, say Y here, | ||
639 | otherwise say N. This will not work with the Creative Webcam III. | ||
640 | It is also available as a module (cpia_usb). | ||
641 | |||
642 | source "drivers/media/video/cpia2/Kconfig" | 602 | source "drivers/media/video/cpia2/Kconfig" |
643 | 603 | ||
644 | config VIDEO_SAA5246A | ||
645 | tristate "SAA5246A, SAA5281 Teletext processor" | ||
646 | depends on I2C && VIDEO_V4L2 | ||
647 | help | ||
648 | Support for I2C bus based teletext using the SAA5246A or SAA5281 | ||
649 | chip. Useful only if you live in Europe. | ||
650 | |||
651 | To compile this driver as a module, choose M here: the | ||
652 | module will be called saa5246a. | ||
653 | |||
654 | config VIDEO_SAA5249 | ||
655 | tristate "SAA5249 Teletext processor" | ||
656 | depends on I2C && VIDEO_V4L2 | ||
657 | help | ||
658 | Support for I2C bus based teletext using the SAA5249 chip. At the | ||
659 | moment this is only useful on some European WinTV cards. | ||
660 | |||
661 | To compile this driver as a module, choose M here: the | ||
662 | module will be called saa5249. | ||
663 | |||
664 | config VIDEO_VINO | 604 | config VIDEO_VINO |
665 | tristate "SGI Vino Video For Linux (EXPERIMENTAL)" | 605 | tristate "SGI Vino Video For Linux (EXPERIMENTAL)" |
666 | depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 | 606 | depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 |
@@ -669,14 +609,6 @@ config VIDEO_VINO | |||
669 | Say Y here to build in support for the Vino video input system found | 609 | Say Y here to build in support for the Vino video input system found |
670 | on SGI Indy machines. | 610 | on SGI Indy machines. |
671 | 611 | ||
672 | config VIDEO_STRADIS | ||
673 | tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)" | ||
674 | depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS | ||
675 | help | ||
676 | Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video | ||
677 | driver for PCI. There is a product page at | ||
678 | <http://www.stradis.com/>. | ||
679 | |||
680 | source "drivers/media/video/zoran/Kconfig" | 612 | source "drivers/media/video/zoran/Kconfig" |
681 | 613 | ||
682 | config VIDEO_MEYE | 614 | config VIDEO_MEYE |
@@ -774,6 +706,22 @@ config VIDEO_CAFE_CCIC | |||
774 | CMOS camera controller. This is the controller found on first- | 706 | CMOS camera controller. This is the controller found on first- |
775 | generation OLPC systems. | 707 | generation OLPC systems. |
776 | 708 | ||
709 | config VIDEO_SR030PC30 | ||
710 | tristate "SR030PC30 VGA camera sensor support" | ||
711 | depends on I2C && VIDEO_V4L2 | ||
712 | ---help--- | ||
713 | This driver supports SR030PC30 VGA camera from Siliconfile | ||
714 | |||
715 | config VIDEO_VIA_CAMERA | ||
716 | tristate "VIAFB camera controller support" | ||
717 | depends on FB_VIA | ||
718 | select VIDEOBUF_DMA_SG | ||
719 | select VIDEO_OV7670 | ||
720 | help | ||
721 | Driver support for the integrated camera controller in VIA | ||
722 | Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems | ||
723 | with ov7670 sensors. | ||
724 | |||
777 | config SOC_CAMERA | 725 | config SOC_CAMERA |
778 | tristate "SoC camera support" | 726 | tristate "SoC camera support" |
779 | depends on VIDEO_V4L2 && HAS_DMA && I2C | 727 | depends on VIDEO_V4L2 && HAS_DMA && I2C |
@@ -783,6 +731,12 @@ config SOC_CAMERA | |||
783 | over a bus like PCI or USB. For example some i2c camera connected | 731 | over a bus like PCI or USB. For example some i2c camera connected |
784 | directly to the data bus of an SoC. | 732 | directly to the data bus of an SoC. |
785 | 733 | ||
734 | config SOC_CAMERA_IMX074 | ||
735 | tristate "imx074 support" | ||
736 | depends on SOC_CAMERA && I2C | ||
737 | help | ||
738 | This driver supports IMX074 cameras from Sony | ||
739 | |||
786 | config SOC_CAMERA_MT9M001 | 740 | config SOC_CAMERA_MT9M001 |
787 | tristate "mt9m001 support" | 741 | tristate "mt9m001 support" |
788 | depends on SOC_CAMERA && I2C | 742 | depends on SOC_CAMERA && I2C |
@@ -835,6 +789,12 @@ config SOC_CAMERA_PLATFORM | |||
835 | help | 789 | help |
836 | This is a generic SoC camera platform driver, useful for testing | 790 | This is a generic SoC camera platform driver, useful for testing |
837 | 791 | ||
792 | config SOC_CAMERA_OV6650 | ||
793 | tristate "ov6650 sensor support" | ||
794 | depends on SOC_CAMERA && I2C | ||
795 | ---help--- | ||
796 | This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor | ||
797 | |||
838 | config SOC_CAMERA_OV772X | 798 | config SOC_CAMERA_OV772X |
839 | tristate "ov772x camera support" | 799 | tristate "ov772x camera support" |
840 | depends on SOC_CAMERA && I2C | 800 | depends on SOC_CAMERA && I2C |
@@ -890,6 +850,14 @@ config VIDEO_SH_MOBILE_CEU | |||
890 | ---help--- | 850 | ---help--- |
891 | This is a v4l2 driver for the SuperH Mobile CEU Interface | 851 | This is a v4l2 driver for the SuperH Mobile CEU Interface |
892 | 852 | ||
853 | config VIDEO_OMAP1 | ||
854 | tristate "OMAP1 Camera Interface driver" | ||
855 | depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA | ||
856 | select VIDEOBUF_DMA_CONTIG | ||
857 | select VIDEOBUF_DMA_SG | ||
858 | ---help--- | ||
859 | This is a v4l2 driver for the TI OMAP1 camera interface | ||
860 | |||
893 | config VIDEO_OMAP2 | 861 | config VIDEO_OMAP2 |
894 | tristate "OMAP2 Camera Capture Interface driver" | 862 | tristate "OMAP2 Camera Capture Interface driver" |
895 | depends on VIDEO_DEV && ARCH_OMAP2 | 863 | depends on VIDEO_DEV && ARCH_OMAP2 |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 40f98fba5f8..af79d476a4c 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -33,8 +33,6 @@ obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o | |||
33 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o | 33 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o |
34 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o | 34 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o |
35 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o | 35 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o |
36 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o | ||
37 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o | ||
38 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o | 36 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o |
39 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o | 37 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o |
40 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o | 38 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o |
@@ -73,12 +71,15 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | |||
73 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | 71 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o |
74 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | 72 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o |
75 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o | 73 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o |
74 | obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o | ||
76 | 75 | ||
76 | obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o | ||
77 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | 77 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
78 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | 78 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o |
79 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | 79 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o |
80 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o | 80 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o |
81 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | 81 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o |
82 | obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o | ||
82 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | 83 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o |
83 | obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o | 84 | obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o |
84 | obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o | 85 | obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o |
@@ -93,10 +94,6 @@ obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o | |||
93 | obj-$(CONFIG_VIDEO_W9966) += w9966.o | 94 | obj-$(CONFIG_VIDEO_W9966) += w9966.o |
94 | obj-$(CONFIG_VIDEO_PMS) += pms.o | 95 | obj-$(CONFIG_VIDEO_PMS) += pms.o |
95 | obj-$(CONFIG_VIDEO_VINO) += vino.o | 96 | obj-$(CONFIG_VIDEO_VINO) += vino.o |
96 | obj-$(CONFIG_VIDEO_STRADIS) += stradis.o | ||
97 | obj-$(CONFIG_VIDEO_CPIA) += cpia.o | ||
98 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o | ||
99 | obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o | ||
100 | obj-$(CONFIG_VIDEO_MEYE) += meye.o | 97 | obj-$(CONFIG_VIDEO_MEYE) += meye.o |
101 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ | 98 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ |
102 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 99 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
@@ -125,6 +122,8 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o | |||
125 | 122 | ||
126 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o | 123 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o |
127 | 124 | ||
125 | obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o | ||
126 | |||
128 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | 127 | obj-$(CONFIG_USB_DABUSB) += dabusb.o |
129 | obj-$(CONFIG_USB_SE401) += se401.o | 128 | obj-$(CONFIG_USB_SE401) += se401.o |
130 | obj-$(CONFIG_USB_ZR364XX) += zr364xx.o | 129 | obj-$(CONFIG_USB_ZR364XX) += zr364xx.o |
@@ -163,6 +162,7 @@ obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o | |||
163 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o | 162 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o |
164 | obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o | 163 | obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o |
165 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o | 164 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o |
165 | obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o | ||
166 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ | 166 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ |
167 | 167 | ||
168 | obj-$(CONFIG_ARCH_DAVINCI) += davinci/ | 168 | obj-$(CONFIG_ARCH_DAVINCI) += davinci/ |
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 48e89fbf391..23ba5c37c3e 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c | |||
@@ -34,11 +34,9 @@ | |||
34 | #include <linux/ioctl.h> | 34 | #include <linux/ioctl.h> |
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/i2c-id.h> | ||
38 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
39 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
40 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
41 | #include <media/v4l2-i2c-drv.h> | ||
42 | 40 | ||
43 | MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); | 41 | MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); |
44 | MODULE_AUTHOR("Maxim Yevtyushkin"); | 42 | MODULE_AUTHOR("Maxim Yevtyushkin"); |
@@ -337,9 +335,25 @@ static const struct i2c_device_id adv7170_id[] = { | |||
337 | }; | 335 | }; |
338 | MODULE_DEVICE_TABLE(i2c, adv7170_id); | 336 | MODULE_DEVICE_TABLE(i2c, adv7170_id); |
339 | 337 | ||
340 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 338 | static struct i2c_driver adv7170_driver = { |
341 | .name = "adv7170", | 339 | .driver = { |
342 | .probe = adv7170_probe, | 340 | .owner = THIS_MODULE, |
343 | .remove = adv7170_remove, | 341 | .name = "adv7170", |
344 | .id_table = adv7170_id, | 342 | }, |
343 | .probe = adv7170_probe, | ||
344 | .remove = adv7170_remove, | ||
345 | .id_table = adv7170_id, | ||
345 | }; | 346 | }; |
347 | |||
348 | static __init int init_adv7170(void) | ||
349 | { | ||
350 | return i2c_add_driver(&adv7170_driver); | ||
351 | } | ||
352 | |||
353 | static __exit void exit_adv7170(void) | ||
354 | { | ||
355 | i2c_del_driver(&adv7170_driver); | ||
356 | } | ||
357 | |||
358 | module_init(init_adv7170); | ||
359 | module_exit(exit_adv7170); | ||
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index f1ba0d742c6..f318b51448b 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c | |||
@@ -30,11 +30,9 @@ | |||
30 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/i2c-id.h> | ||
34 | #include <linux/videodev2.h> | 33 | #include <linux/videodev2.h> |
35 | #include <media/v4l2-device.h> | 34 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 35 | #include <media/v4l2-chip-ident.h> |
37 | #include <media/v4l2-i2c-drv.h> | ||
38 | 36 | ||
39 | MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); | 37 | MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); |
40 | MODULE_AUTHOR("Dave Perks"); | 38 | MODULE_AUTHOR("Dave Perks"); |
@@ -376,9 +374,25 @@ static const struct i2c_device_id adv7175_id[] = { | |||
376 | }; | 374 | }; |
377 | MODULE_DEVICE_TABLE(i2c, adv7175_id); | 375 | MODULE_DEVICE_TABLE(i2c, adv7175_id); |
378 | 376 | ||
379 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 377 | static struct i2c_driver adv7175_driver = { |
380 | .name = "adv7175", | 378 | .driver = { |
381 | .probe = adv7175_probe, | 379 | .owner = THIS_MODULE, |
382 | .remove = adv7175_remove, | 380 | .name = "adv7175", |
383 | .id_table = adv7175_id, | 381 | }, |
382 | .probe = adv7175_probe, | ||
383 | .remove = adv7175_remove, | ||
384 | .id_table = adv7175_id, | ||
384 | }; | 385 | }; |
386 | |||
387 | static __init int init_adv7175(void) | ||
388 | { | ||
389 | return i2c_add_driver(&adv7175_driver); | ||
390 | } | ||
391 | |||
392 | static __exit void exit_adv7175(void) | ||
393 | { | ||
394 | i2c_del_driver(&adv7175_driver); | ||
395 | } | ||
396 | |||
397 | module_init(init_adv7175); | ||
398 | module_exit(exit_adv7175); | ||
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index 23e610f6273..d2138d06bca 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/i2c-id.h> | ||
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <media/v4l2-ioctl.h> | 26 | #include <media/v4l2-ioctl.h> |
28 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 57dd9195daf..0453816d4ec 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c | |||
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev) | |||
212 | be abstracted out if we ever need to support a different | 212 | be abstracted out if we ever need to support a different |
213 | demod) */ | 213 | demod) */ |
214 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 214 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
215 | "au8522", "au8522", 0x8e >> 1, NULL); | 215 | NULL, "au8522", 0x8e >> 1, NULL); |
216 | if (sd == NULL) | 216 | if (sd == NULL) |
217 | printk(KERN_ERR "analog subdev registration failed\n"); | 217 | printk(KERN_ERR "analog subdev registration failed\n"); |
218 | } | 218 | } |
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev) | |||
221 | if (dev->board.tuner_type != TUNER_ABSENT) { | 221 | if (dev->board.tuner_type != TUNER_ABSENT) { |
222 | /* Load the tuner module, which does the attach */ | 222 | /* Load the tuner module, which does the attach */ |
223 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 223 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
224 | "tuner", "tuner", dev->board.tuner_addr, NULL); | 224 | NULL, "tuner", dev->board.tuner_addr, NULL); |
225 | if (sd == NULL) | 225 | if (sd == NULL) |
226 | printk(KERN_ERR "tuner subdev registration fail\n"); | 226 | printk(KERN_ERR "tuner subdev registration fail\n"); |
227 | 227 | ||
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 7989a7ba7c4..162fd5f9d44 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c | |||
@@ -965,7 +965,7 @@ static int au0828_v4l2_open(struct file *filp) | |||
965 | NULL, &dev->slock, | 965 | NULL, &dev->slock, |
966 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 966 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
967 | V4L2_FIELD_INTERLACED, | 967 | V4L2_FIELD_INTERLACED, |
968 | sizeof(struct au0828_buffer), fh); | 968 | sizeof(struct au0828_buffer), fh, NULL); |
969 | 969 | ||
970 | /* VBI Setup */ | 970 | /* VBI Setup */ |
971 | dev->vbi_width = 720; | 971 | dev->vbi_width = 720; |
@@ -974,7 +974,7 @@ static int au0828_v4l2_open(struct file *filp) | |||
974 | NULL, &dev->slock, | 974 | NULL, &dev->slock, |
975 | V4L2_BUF_TYPE_VBI_CAPTURE, | 975 | V4L2_BUF_TYPE_VBI_CAPTURE, |
976 | V4L2_FIELD_SEQ_TB, | 976 | V4L2_FIELD_SEQ_TB, |
977 | sizeof(struct au0828_buffer), fh); | 977 | sizeof(struct au0828_buffer), fh, NULL); |
978 | 978 | ||
979 | 979 | ||
980 | return ret; | 980 | return ret; |
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 770cb9accf8..c38300fc0b1 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c | |||
@@ -33,12 +33,10 @@ | |||
33 | #include <linux/ioctl.h> | 33 | #include <linux/ioctl.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
36 | #include <linux/i2c-id.h> | ||
37 | #include <linux/videodev2.h> | 36 | #include <linux/videodev2.h> |
38 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
39 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
40 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
41 | #include <media/v4l2-i2c-drv.h> | ||
42 | #include <media/bt819.h> | 40 | #include <media/bt819.h> |
43 | 41 | ||
44 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); | 42 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); |
@@ -537,9 +535,25 @@ static const struct i2c_device_id bt819_id[] = { | |||
537 | }; | 535 | }; |
538 | MODULE_DEVICE_TABLE(i2c, bt819_id); | 536 | MODULE_DEVICE_TABLE(i2c, bt819_id); |
539 | 537 | ||
540 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 538 | static struct i2c_driver bt819_driver = { |
541 | .name = "bt819", | 539 | .driver = { |
542 | .probe = bt819_probe, | 540 | .owner = THIS_MODULE, |
543 | .remove = bt819_remove, | 541 | .name = "bt819", |
544 | .id_table = bt819_id, | 542 | }, |
543 | .probe = bt819_probe, | ||
544 | .remove = bt819_remove, | ||
545 | .id_table = bt819_id, | ||
545 | }; | 546 | }; |
547 | |||
548 | static __init int init_bt819(void) | ||
549 | { | ||
550 | return i2c_add_driver(&bt819_driver); | ||
551 | } | ||
552 | |||
553 | static __exit void exit_bt819(void) | ||
554 | { | ||
555 | i2c_del_driver(&bt819_driver); | ||
556 | } | ||
557 | |||
558 | module_init(init_bt819); | ||
559 | module_exit(exit_bt819); | ||
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index ae333739250..a43059d4c79 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c | |||
@@ -34,11 +34,9 @@ | |||
34 | #include <linux/ioctl.h> | 34 | #include <linux/ioctl.h> |
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/i2c-id.h> | ||
38 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
39 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
40 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
41 | #include <media/v4l2-i2c-drv.h> | ||
42 | 40 | ||
43 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); | 41 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); |
44 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 42 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
@@ -262,9 +260,25 @@ static const struct i2c_device_id bt856_id[] = { | |||
262 | }; | 260 | }; |
263 | MODULE_DEVICE_TABLE(i2c, bt856_id); | 261 | MODULE_DEVICE_TABLE(i2c, bt856_id); |
264 | 262 | ||
265 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 263 | static struct i2c_driver bt856_driver = { |
266 | .name = "bt856", | 264 | .driver = { |
267 | .probe = bt856_probe, | 265 | .owner = THIS_MODULE, |
268 | .remove = bt856_remove, | 266 | .name = "bt856", |
269 | .id_table = bt856_id, | 267 | }, |
268 | .probe = bt856_probe, | ||
269 | .remove = bt856_remove, | ||
270 | .id_table = bt856_id, | ||
270 | }; | 271 | }; |
272 | |||
273 | static __init int init_bt856(void) | ||
274 | { | ||
275 | return i2c_add_driver(&bt856_driver); | ||
276 | } | ||
277 | |||
278 | static __exit void exit_bt856(void) | ||
279 | { | ||
280 | i2c_del_driver(&bt856_driver); | ||
281 | } | ||
282 | |||
283 | module_init(init_bt856); | ||
284 | module_exit(exit_bt856); | ||
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c index 62ac422bb15..4e5dcea0501 100644 --- a/drivers/media/video/bt866.c +++ b/drivers/media/video/bt866.c | |||
@@ -34,11 +34,9 @@ | |||
34 | #include <linux/ioctl.h> | 34 | #include <linux/ioctl.h> |
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/i2c-id.h> | ||
38 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
39 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
40 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
41 | #include <media/v4l2-i2c-drv.h> | ||
42 | 40 | ||
43 | MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); | 41 | MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); |
44 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 42 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
@@ -232,9 +230,25 @@ static const struct i2c_device_id bt866_id[] = { | |||
232 | }; | 230 | }; |
233 | MODULE_DEVICE_TABLE(i2c, bt866_id); | 231 | MODULE_DEVICE_TABLE(i2c, bt866_id); |
234 | 232 | ||
235 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 233 | static struct i2c_driver bt866_driver = { |
236 | .name = "bt866", | 234 | .driver = { |
237 | .probe = bt866_probe, | 235 | .owner = THIS_MODULE, |
238 | .remove = bt866_remove, | 236 | .name = "bt866", |
239 | .id_table = bt866_id, | 237 | }, |
238 | .probe = bt866_probe, | ||
239 | .remove = bt866_remove, | ||
240 | .id_table = bt866_id, | ||
240 | }; | 241 | }; |
242 | |||
243 | static __init int init_bt866(void) | ||
244 | { | ||
245 | return i2c_add_driver(&bt866_driver); | ||
246 | } | ||
247 | |||
248 | static __exit void exit_bt866(void) | ||
249 | { | ||
250 | i2c_del_driver(&bt866_driver); | ||
251 | } | ||
252 | |||
253 | module_init(init_bt866); | ||
254 | module_exit(exit_bt866); | ||
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 7af56cde0c7..87d8b006ef7 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -3529,7 +3529,7 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3529 | struct v4l2_subdev *sd; | 3529 | struct v4l2_subdev *sd; |
3530 | 3530 | ||
3531 | sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3531 | sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3532 | &btv->c.i2c_adap, "saa6588", "saa6588", 0, addrs); | 3532 | &btv->c.i2c_adap, NULL, "saa6588", 0, addrs); |
3533 | btv->has_saa6588 = (sd != NULL); | 3533 | btv->has_saa6588 = (sd != NULL); |
3534 | } | 3534 | } |
3535 | 3535 | ||
@@ -3554,7 +3554,7 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3554 | }; | 3554 | }; |
3555 | 3555 | ||
3556 | btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3556 | btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3557 | &btv->c.i2c_adap, "msp3400", "msp3400", 0, addrs); | 3557 | &btv->c.i2c_adap, NULL, "msp3400", 0, addrs); |
3558 | if (btv->sd_msp34xx) | 3558 | if (btv->sd_msp34xx) |
3559 | return; | 3559 | return; |
3560 | goto no_audio; | 3560 | goto no_audio; |
@@ -3568,7 +3568,7 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3568 | }; | 3568 | }; |
3569 | 3569 | ||
3570 | if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3570 | if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3571 | &btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs)) | 3571 | &btv->c.i2c_adap, NULL, "tda7432", 0, addrs)) |
3572 | return; | 3572 | return; |
3573 | goto no_audio; | 3573 | goto no_audio; |
3574 | } | 3574 | } |
@@ -3576,7 +3576,7 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3576 | case 3: { | 3576 | case 3: { |
3577 | /* The user specified that we should probe for tvaudio */ | 3577 | /* The user specified that we should probe for tvaudio */ |
3578 | btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3578 | btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3579 | &btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs()); | 3579 | &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs()); |
3580 | if (btv->sd_tvaudio) | 3580 | if (btv->sd_tvaudio) |
3581 | return; | 3581 | return; |
3582 | goto no_audio; | 3582 | goto no_audio; |
@@ -3596,11 +3596,11 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3596 | found is really something else (e.g. a tea6300). */ | 3596 | found is really something else (e.g. a tea6300). */ |
3597 | if (!bttv_tvcards[btv->c.type].no_msp34xx) { | 3597 | if (!bttv_tvcards[btv->c.type].no_msp34xx) { |
3598 | btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3598 | btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3599 | &btv->c.i2c_adap, "msp3400", "msp3400", | 3599 | &btv->c.i2c_adap, NULL, "msp3400", |
3600 | 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1)); | 3600 | 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1)); |
3601 | } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { | 3601 | } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { |
3602 | btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3602 | btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3603 | &btv->c.i2c_adap, "msp3400", "msp3400", | 3603 | &btv->c.i2c_adap, NULL, "msp3400", |
3604 | 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1)); | 3604 | 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1)); |
3605 | } | 3605 | } |
3606 | 3606 | ||
@@ -3616,13 +3616,13 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3616 | }; | 3616 | }; |
3617 | 3617 | ||
3618 | if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3618 | if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3619 | &btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs)) | 3619 | &btv->c.i2c_adap, NULL, "tda7432", 0, addrs)) |
3620 | return; | 3620 | return; |
3621 | } | 3621 | } |
3622 | 3622 | ||
3623 | /* Now see if we can find one of the tvaudio devices. */ | 3623 | /* Now see if we can find one of the tvaudio devices. */ |
3624 | btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3624 | btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3625 | &btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs()); | 3625 | &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs()); |
3626 | if (btv->sd_tvaudio) | 3626 | if (btv->sd_tvaudio) |
3627 | return; | 3627 | return; |
3628 | 3628 | ||
@@ -3646,13 +3646,13 @@ void __devinit bttv_init_tuner(struct bttv *btv) | |||
3646 | /* Load tuner module before issuing tuner config call! */ | 3646 | /* Load tuner module before issuing tuner config call! */ |
3647 | if (bttv_tvcards[btv->c.type].has_radio) | 3647 | if (bttv_tvcards[btv->c.type].has_radio) |
3648 | v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3648 | v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3649 | &btv->c.i2c_adap, "tuner", "tuner", | 3649 | &btv->c.i2c_adap, NULL, "tuner", |
3650 | 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); | 3650 | 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); |
3651 | v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3651 | v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3652 | &btv->c.i2c_adap, "tuner", "tuner", | 3652 | &btv->c.i2c_adap, NULL, "tuner", |
3653 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | 3653 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); |
3654 | v4l2_i2c_new_subdev(&btv->c.v4l2_dev, | 3654 | v4l2_i2c_new_subdev(&btv->c.v4l2_dev, |
3655 | &btv->c.i2c_adap, "tuner", "tuner", | 3655 | &btv->c.i2c_adap, NULL, "tuner", |
3656 | 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); | 3656 | 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); |
3657 | 3657 | ||
3658 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | 3658 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 38c7f78ad9c..3da6e80e104 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -842,7 +842,7 @@ static const struct v4l2_queryctrl *ctrl_by_id(int id) | |||
842 | RESOURCE_OVERLAY) | 842 | RESOURCE_OVERLAY) |
843 | 843 | ||
844 | static | 844 | static |
845 | int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit) | 845 | int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) |
846 | { | 846 | { |
847 | int xbits; /* mutual exclusive resources */ | 847 | int xbits; /* mutual exclusive resources */ |
848 | 848 | ||
@@ -935,7 +935,7 @@ disclaim_video_lines(struct bttv *btv) | |||
935 | } | 935 | } |
936 | 936 | ||
937 | static | 937 | static |
938 | void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits) | 938 | void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) |
939 | { | 939 | { |
940 | if ((fh->resources & bits) != bits) { | 940 | if ((fh->resources & bits) != bits) { |
941 | /* trying to free ressources not allocated by us ... */ | 941 | /* trying to free ressources not allocated by us ... */ |
@@ -1682,7 +1682,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, | |||
1682 | kfree(old); | 1682 | kfree(old); |
1683 | } | 1683 | } |
1684 | if (NULL == new) | 1684 | if (NULL == new) |
1685 | free_btres(btv,fh,RESOURCE_OVERLAY); | 1685 | free_btres_lock(btv,fh,RESOURCE_OVERLAY); |
1686 | dprintk("switch_overlay: done\n"); | 1686 | dprintk("switch_overlay: done\n"); |
1687 | return retval; | 1687 | return retval; |
1688 | } | 1688 | } |
@@ -1859,21 +1859,25 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) | |||
1859 | unsigned int i; | 1859 | unsigned int i; |
1860 | int err; | 1860 | int err; |
1861 | 1861 | ||
1862 | mutex_lock(&btv->lock); | ||
1862 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1863 | err = v4l2_prio_check(&btv->prio, fh->prio); |
1863 | if (0 != err) | 1864 | if (err) |
1864 | return err; | 1865 | goto err; |
1865 | 1866 | ||
1866 | for (i = 0; i < BTTV_TVNORMS; i++) | 1867 | for (i = 0; i < BTTV_TVNORMS; i++) |
1867 | if (*id & bttv_tvnorms[i].v4l2_id) | 1868 | if (*id & bttv_tvnorms[i].v4l2_id) |
1868 | break; | 1869 | break; |
1869 | if (i == BTTV_TVNORMS) | 1870 | if (i == BTTV_TVNORMS) { |
1870 | return -EINVAL; | 1871 | err = -EINVAL; |
1872 | goto err; | ||
1873 | } | ||
1871 | 1874 | ||
1872 | mutex_lock(&btv->lock); | ||
1873 | set_tvnorm(btv, i); | 1875 | set_tvnorm(btv, i); |
1876 | |||
1877 | err: | ||
1874 | mutex_unlock(&btv->lock); | 1878 | mutex_unlock(&btv->lock); |
1875 | 1879 | ||
1876 | return 0; | 1880 | return err; |
1877 | } | 1881 | } |
1878 | 1882 | ||
1879 | static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) | 1883 | static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) |
@@ -1893,10 +1897,13 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
1893 | { | 1897 | { |
1894 | struct bttv_fh *fh = priv; | 1898 | struct bttv_fh *fh = priv; |
1895 | struct bttv *btv = fh->btv; | 1899 | struct bttv *btv = fh->btv; |
1896 | int n; | 1900 | int rc = 0; |
1897 | 1901 | ||
1898 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) | 1902 | mutex_lock(&btv->lock); |
1899 | return -EINVAL; | 1903 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { |
1904 | rc = -EINVAL; | ||
1905 | goto err; | ||
1906 | } | ||
1900 | 1907 | ||
1901 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1908 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1902 | i->audioset = 1; | 1909 | i->audioset = 1; |
@@ -1919,10 +1926,12 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
1919 | i->status |= V4L2_IN_ST_NO_H_LOCK; | 1926 | i->status |= V4L2_IN_ST_NO_H_LOCK; |
1920 | } | 1927 | } |
1921 | 1928 | ||
1922 | for (n = 0; n < BTTV_TVNORMS; n++) | 1929 | i->std = BTTV_NORMS; |
1923 | i->std |= bttv_tvnorms[n].v4l2_id; | ||
1924 | 1930 | ||
1925 | return 0; | 1931 | err: |
1932 | mutex_unlock(&btv->lock); | ||
1933 | |||
1934 | return rc; | ||
1926 | } | 1935 | } |
1927 | 1936 | ||
1928 | static int bttv_g_input(struct file *file, void *priv, unsigned int *i) | 1937 | static int bttv_g_input(struct file *file, void *priv, unsigned int *i) |
@@ -1930,7 +1939,10 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i) | |||
1930 | struct bttv_fh *fh = priv; | 1939 | struct bttv_fh *fh = priv; |
1931 | struct bttv *btv = fh->btv; | 1940 | struct bttv *btv = fh->btv; |
1932 | 1941 | ||
1942 | mutex_lock(&btv->lock); | ||
1933 | *i = btv->input; | 1943 | *i = btv->input; |
1944 | mutex_unlock(&btv->lock); | ||
1945 | |||
1934 | return 0; | 1946 | return 0; |
1935 | } | 1947 | } |
1936 | 1948 | ||
@@ -1941,15 +1953,19 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) | |||
1941 | 1953 | ||
1942 | int err; | 1954 | int err; |
1943 | 1955 | ||
1956 | mutex_lock(&btv->lock); | ||
1944 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1957 | err = v4l2_prio_check(&btv->prio, fh->prio); |
1945 | if (0 != err) | 1958 | if (unlikely(err)) |
1946 | return err; | 1959 | goto err; |
1947 | 1960 | ||
1948 | if (i > bttv_tvcards[btv->c.type].video_inputs) | 1961 | if (i > bttv_tvcards[btv->c.type].video_inputs) { |
1949 | return -EINVAL; | 1962 | err = -EINVAL; |
1963 | goto err; | ||
1964 | } | ||
1950 | 1965 | ||
1951 | mutex_lock(&btv->lock); | ||
1952 | set_input(btv, i, btv->tvnorm); | 1966 | set_input(btv, i, btv->tvnorm); |
1967 | |||
1968 | err: | ||
1953 | mutex_unlock(&btv->lock); | 1969 | mutex_unlock(&btv->lock); |
1954 | return 0; | 1970 | return 0; |
1955 | } | 1971 | } |
@@ -1961,22 +1977,25 @@ static int bttv_s_tuner(struct file *file, void *priv, | |||
1961 | struct bttv *btv = fh->btv; | 1977 | struct bttv *btv = fh->btv; |
1962 | int err; | 1978 | int err; |
1963 | 1979 | ||
1964 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1980 | if (unlikely(0 != t->index)) |
1965 | if (0 != err) | ||
1966 | return err; | ||
1967 | |||
1968 | if (btv->tuner_type == TUNER_ABSENT) | ||
1969 | return -EINVAL; | ||
1970 | |||
1971 | if (0 != t->index) | ||
1972 | return -EINVAL; | 1981 | return -EINVAL; |
1973 | 1982 | ||
1974 | mutex_lock(&btv->lock); | 1983 | mutex_lock(&btv->lock); |
1984 | if (unlikely(btv->tuner_type == TUNER_ABSENT)) { | ||
1985 | err = -EINVAL; | ||
1986 | goto err; | ||
1987 | } | ||
1988 | |||
1989 | err = v4l2_prio_check(&btv->prio, fh->prio); | ||
1990 | if (unlikely(err)) | ||
1991 | goto err; | ||
1992 | |||
1975 | bttv_call_all(btv, tuner, s_tuner, t); | 1993 | bttv_call_all(btv, tuner, s_tuner, t); |
1976 | 1994 | ||
1977 | if (btv->audio_mode_gpio) | 1995 | if (btv->audio_mode_gpio) |
1978 | btv->audio_mode_gpio(btv, t, 1); | 1996 | btv->audio_mode_gpio(btv, t, 1); |
1979 | 1997 | ||
1998 | err: | ||
1980 | mutex_unlock(&btv->lock); | 1999 | mutex_unlock(&btv->lock); |
1981 | 2000 | ||
1982 | return 0; | 2001 | return 0; |
@@ -1988,8 +2007,10 @@ static int bttv_g_frequency(struct file *file, void *priv, | |||
1988 | struct bttv_fh *fh = priv; | 2007 | struct bttv_fh *fh = priv; |
1989 | struct bttv *btv = fh->btv; | 2008 | struct bttv *btv = fh->btv; |
1990 | 2009 | ||
2010 | mutex_lock(&btv->lock); | ||
1991 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 2011 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1992 | f->frequency = btv->freq; | 2012 | f->frequency = btv->freq; |
2013 | mutex_unlock(&btv->lock); | ||
1993 | 2014 | ||
1994 | return 0; | 2015 | return 0; |
1995 | } | 2016 | } |
@@ -2001,21 +2022,26 @@ static int bttv_s_frequency(struct file *file, void *priv, | |||
2001 | struct bttv *btv = fh->btv; | 2022 | struct bttv *btv = fh->btv; |
2002 | int err; | 2023 | int err; |
2003 | 2024 | ||
2004 | err = v4l2_prio_check(&btv->prio, fh->prio); | ||
2005 | if (0 != err) | ||
2006 | return err; | ||
2007 | |||
2008 | if (unlikely(f->tuner != 0)) | 2025 | if (unlikely(f->tuner != 0)) |
2009 | return -EINVAL; | 2026 | return -EINVAL; |
2010 | if (unlikely(f->type != (btv->radio_user | 2027 | |
2011 | ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) | ||
2012 | return -EINVAL; | ||
2013 | mutex_lock(&btv->lock); | 2028 | mutex_lock(&btv->lock); |
2029 | err = v4l2_prio_check(&btv->prio, fh->prio); | ||
2030 | if (unlikely(err)) | ||
2031 | goto err; | ||
2032 | |||
2033 | if (unlikely(f->type != (btv->radio_user | ||
2034 | ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) { | ||
2035 | err = -EINVAL; | ||
2036 | goto err; | ||
2037 | } | ||
2014 | btv->freq = f->frequency; | 2038 | btv->freq = f->frequency; |
2015 | bttv_call_all(btv, tuner, s_frequency, f); | 2039 | bttv_call_all(btv, tuner, s_frequency, f); |
2016 | if (btv->has_matchbox && btv->radio_user) | 2040 | if (btv->has_matchbox && btv->radio_user) |
2017 | tea5757_set_freq(btv, btv->freq); | 2041 | tea5757_set_freq(btv, btv->freq); |
2042 | err: | ||
2018 | mutex_unlock(&btv->lock); | 2043 | mutex_unlock(&btv->lock); |
2044 | |||
2019 | return 0; | 2045 | return 0; |
2020 | } | 2046 | } |
2021 | 2047 | ||
@@ -2124,7 +2150,7 @@ bttv_crop_adjust (struct bttv_crop * c, | |||
2124 | also adjust the current cropping parameters to get closer to the | 2150 | also adjust the current cropping parameters to get closer to the |
2125 | desired image size. */ | 2151 | desired image size. */ |
2126 | static int | 2152 | static int |
2127 | limit_scaled_size (struct bttv_fh * fh, | 2153 | limit_scaled_size_lock (struct bttv_fh * fh, |
2128 | __s32 * width, | 2154 | __s32 * width, |
2129 | __s32 * height, | 2155 | __s32 * height, |
2130 | enum v4l2_field field, | 2156 | enum v4l2_field field, |
@@ -2238,7 +2264,7 @@ limit_scaled_size (struct bttv_fh * fh, | |||
2238 | may also adjust the current cropping parameters to get closer | 2264 | may also adjust the current cropping parameters to get closer |
2239 | to the desired window size. */ | 2265 | to the desired window size. */ |
2240 | static int | 2266 | static int |
2241 | verify_window (struct bttv_fh * fh, | 2267 | verify_window_lock (struct bttv_fh * fh, |
2242 | struct v4l2_window * win, | 2268 | struct v4l2_window * win, |
2243 | int adjust_size, | 2269 | int adjust_size, |
2244 | int adjust_crop) | 2270 | int adjust_crop) |
@@ -2257,7 +2283,9 @@ verify_window (struct bttv_fh * fh, | |||
2257 | if (V4L2_FIELD_ANY == field) { | 2283 | if (V4L2_FIELD_ANY == field) { |
2258 | __s32 height2; | 2284 | __s32 height2; |
2259 | 2285 | ||
2286 | mutex_lock(&fh->btv->lock); | ||
2260 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; | 2287 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; |
2288 | mutex_unlock(&fh->btv->lock); | ||
2261 | field = (win->w.height > height2) | 2289 | field = (win->w.height > height2) |
2262 | ? V4L2_FIELD_INTERLACED | 2290 | ? V4L2_FIELD_INTERLACED |
2263 | : V4L2_FIELD_TOP; | 2291 | : V4L2_FIELD_TOP; |
@@ -2292,7 +2320,7 @@ verify_window (struct bttv_fh * fh, | |||
2292 | win->w.width -= win->w.left & ~width_mask; | 2320 | win->w.width -= win->w.left & ~width_mask; |
2293 | win->w.left = (win->w.left - width_mask - 1) & width_mask; | 2321 | win->w.left = (win->w.left - width_mask - 1) & width_mask; |
2294 | 2322 | ||
2295 | rc = limit_scaled_size(fh, &win->w.width, &win->w.height, | 2323 | rc = limit_scaled_size_lock(fh, &win->w.width, &win->w.height, |
2296 | field, width_mask, | 2324 | field, width_mask, |
2297 | /* width_bias: round down */ 0, | 2325 | /* width_bias: round down */ 0, |
2298 | adjust_size, adjust_crop); | 2326 | adjust_size, adjust_crop); |
@@ -2303,7 +2331,7 @@ verify_window (struct bttv_fh * fh, | |||
2303 | return 0; | 2331 | return 0; |
2304 | } | 2332 | } |
2305 | 2333 | ||
2306 | static int setup_window(struct bttv_fh *fh, struct bttv *btv, | 2334 | static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, |
2307 | struct v4l2_window *win, int fixup) | 2335 | struct v4l2_window *win, int fixup) |
2308 | { | 2336 | { |
2309 | struct v4l2_clip *clips = NULL; | 2337 | struct v4l2_clip *clips = NULL; |
@@ -2313,7 +2341,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
2313 | return -EINVAL; | 2341 | return -EINVAL; |
2314 | if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) | 2342 | if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) |
2315 | return -EINVAL; | 2343 | return -EINVAL; |
2316 | retval = verify_window(fh, win, | 2344 | retval = verify_window_lock(fh, win, |
2317 | /* adjust_size */ fixup, | 2345 | /* adjust_size */ fixup, |
2318 | /* adjust_crop */ fixup); | 2346 | /* adjust_crop */ fixup); |
2319 | if (0 != retval) | 2347 | if (0 != retval) |
@@ -2332,6 +2360,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
2332 | return -EFAULT; | 2360 | return -EFAULT; |
2333 | } | 2361 | } |
2334 | } | 2362 | } |
2363 | |||
2364 | mutex_lock(&fh->cap.vb_lock); | ||
2335 | /* clip against screen */ | 2365 | /* clip against screen */ |
2336 | if (NULL != btv->fbuf.base) | 2366 | if (NULL != btv->fbuf.base) |
2337 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, | 2367 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, |
@@ -2354,7 +2384,6 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
2354 | BUG(); | 2384 | BUG(); |
2355 | } | 2385 | } |
2356 | 2386 | ||
2357 | mutex_lock(&fh->cap.vb_lock); | ||
2358 | kfree(fh->ov.clips); | 2387 | kfree(fh->ov.clips); |
2359 | fh->ov.clips = clips; | 2388 | fh->ov.clips = clips; |
2360 | fh->ov.nclips = n; | 2389 | fh->ov.nclips = n; |
@@ -2362,6 +2391,14 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, | |||
2362 | fh->ov.w = win->w; | 2391 | fh->ov.w = win->w; |
2363 | fh->ov.field = win->field; | 2392 | fh->ov.field = win->field; |
2364 | fh->ov.setup_ok = 1; | 2393 | fh->ov.setup_ok = 1; |
2394 | |||
2395 | /* | ||
2396 | * FIXME: btv is protected by btv->lock mutex, while btv->init | ||
2397 | * is protected by fh->cap.vb_lock. This seems to open the | ||
2398 | * possibility for some race situations. Maybe the better would | ||
2399 | * be to unify those locks or to use another way to store the | ||
2400 | * init values that will be consumed by videobuf callbacks | ||
2401 | */ | ||
2365 | btv->init.ov.w.width = win->w.width; | 2402 | btv->init.ov.w.width = win->w.width; |
2366 | btv->init.ov.w.height = win->w.height; | 2403 | btv->init.ov.w.height = win->w.height; |
2367 | btv->init.ov.field = win->field; | 2404 | btv->init.ov.field = win->field; |
@@ -2490,7 +2527,9 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, | |||
2490 | if (V4L2_FIELD_ANY == field) { | 2527 | if (V4L2_FIELD_ANY == field) { |
2491 | __s32 height2; | 2528 | __s32 height2; |
2492 | 2529 | ||
2530 | mutex_lock(&btv->lock); | ||
2493 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; | 2531 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; |
2532 | mutex_unlock(&btv->lock); | ||
2494 | field = (f->fmt.pix.height > height2) | 2533 | field = (f->fmt.pix.height > height2) |
2495 | ? V4L2_FIELD_INTERLACED | 2534 | ? V4L2_FIELD_INTERLACED |
2496 | : V4L2_FIELD_BOTTOM; | 2535 | : V4L2_FIELD_BOTTOM; |
@@ -2516,7 +2555,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, | |||
2516 | width = f->fmt.pix.width; | 2555 | width = f->fmt.pix.width; |
2517 | height = f->fmt.pix.height; | 2556 | height = f->fmt.pix.height; |
2518 | 2557 | ||
2519 | rc = limit_scaled_size(fh, &width, &height, field, | 2558 | rc = limit_scaled_size_lock(fh, &width, &height, field, |
2520 | /* width_mask: 4 pixels */ ~3, | 2559 | /* width_mask: 4 pixels */ ~3, |
2521 | /* width_bias: nearest */ 2, | 2560 | /* width_bias: nearest */ 2, |
2522 | /* adjust_size */ 1, | 2561 | /* adjust_size */ 1, |
@@ -2536,7 +2575,7 @@ static int bttv_try_fmt_vid_overlay(struct file *file, void *priv, | |||
2536 | { | 2575 | { |
2537 | struct bttv_fh *fh = priv; | 2576 | struct bttv_fh *fh = priv; |
2538 | 2577 | ||
2539 | return verify_window(fh, &f->fmt.win, | 2578 | return verify_window_lock(fh, &f->fmt.win, |
2540 | /* adjust_size */ 1, | 2579 | /* adjust_size */ 1, |
2541 | /* adjust_crop */ 0); | 2580 | /* adjust_crop */ 0); |
2542 | } | 2581 | } |
@@ -2563,7 +2602,7 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv, | |||
2563 | height = f->fmt.pix.height; | 2602 | height = f->fmt.pix.height; |
2564 | field = f->fmt.pix.field; | 2603 | field = f->fmt.pix.field; |
2565 | 2604 | ||
2566 | retval = limit_scaled_size(fh, &width, &height, f->fmt.pix.field, | 2605 | retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field, |
2567 | /* width_mask: 4 pixels */ ~3, | 2606 | /* width_mask: 4 pixels */ ~3, |
2568 | /* width_bias: nearest */ 2, | 2607 | /* width_bias: nearest */ 2, |
2569 | /* adjust_size */ 1, | 2608 | /* adjust_size */ 1, |
@@ -2601,7 +2640,7 @@ static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, | |||
2601 | return -EINVAL; | 2640 | return -EINVAL; |
2602 | } | 2641 | } |
2603 | 2642 | ||
2604 | return setup_window(fh, btv, &f->fmt.win, 1); | 2643 | return setup_window_lock(fh, btv, &f->fmt.win, 1); |
2605 | } | 2644 | } |
2606 | 2645 | ||
2607 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 2646 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
@@ -2651,11 +2690,15 @@ static int bttv_querycap(struct file *file, void *priv, | |||
2651 | V4L2_CAP_VBI_CAPTURE | | 2690 | V4L2_CAP_VBI_CAPTURE | |
2652 | V4L2_CAP_READWRITE | | 2691 | V4L2_CAP_READWRITE | |
2653 | V4L2_CAP_STREAMING; | 2692 | V4L2_CAP_STREAMING; |
2654 | if (btv->has_saa6588) | ||
2655 | cap->capabilities |= V4L2_CAP_RDS_CAPTURE; | ||
2656 | if (no_overlay <= 0) | 2693 | if (no_overlay <= 0) |
2657 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | 2694 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; |
2658 | 2695 | ||
2696 | /* | ||
2697 | * No need to lock here: those vars are initialized during board | ||
2698 | * probe and remains untouched during the rest of the driver lifecycle | ||
2699 | */ | ||
2700 | if (btv->has_saa6588) | ||
2701 | cap->capabilities |= V4L2_CAP_RDS_CAPTURE; | ||
2659 | if (btv->tuner_type != TUNER_ABSENT) | 2702 | if (btv->tuner_type != TUNER_ABSENT) |
2660 | cap->capabilities |= V4L2_CAP_TUNER; | 2703 | cap->capabilities |= V4L2_CAP_TUNER; |
2661 | return 0; | 2704 | return 0; |
@@ -2730,19 +2773,25 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
2730 | struct bttv_fh *fh = f; | 2773 | struct bttv_fh *fh = f; |
2731 | struct bttv *btv = fh->btv; | 2774 | struct bttv *btv = fh->btv; |
2732 | struct bttv_buffer *new; | 2775 | struct bttv_buffer *new; |
2733 | int retval; | 2776 | int retval = 0; |
2734 | 2777 | ||
2735 | if (on) { | 2778 | if (on) { |
2779 | mutex_lock(&fh->cap.vb_lock); | ||
2736 | /* verify args */ | 2780 | /* verify args */ |
2737 | if (NULL == btv->fbuf.base) | 2781 | if (unlikely(!btv->fbuf.base)) { |
2782 | mutex_unlock(&fh->cap.vb_lock); | ||
2738 | return -EINVAL; | 2783 | return -EINVAL; |
2739 | if (!fh->ov.setup_ok) { | 2784 | } |
2785 | if (unlikely(!fh->ov.setup_ok)) { | ||
2740 | dprintk("bttv%d: overlay: !setup_ok\n", btv->c.nr); | 2786 | dprintk("bttv%d: overlay: !setup_ok\n", btv->c.nr); |
2741 | return -EINVAL; | 2787 | retval = -EINVAL; |
2742 | } | 2788 | } |
2789 | if (retval) | ||
2790 | return retval; | ||
2791 | mutex_unlock(&fh->cap.vb_lock); | ||
2743 | } | 2792 | } |
2744 | 2793 | ||
2745 | if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY)) | 2794 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) |
2746 | return -EBUSY; | 2795 | return -EBUSY; |
2747 | 2796 | ||
2748 | mutex_lock(&fh->cap.vb_lock); | 2797 | mutex_lock(&fh->cap.vb_lock); |
@@ -2785,7 +2834,7 @@ static int bttv_s_fbuf(struct file *file, void *f, | |||
2785 | __s32 width = fb->fmt.width; | 2834 | __s32 width = fb->fmt.width; |
2786 | __s32 height = fb->fmt.height; | 2835 | __s32 height = fb->fmt.height; |
2787 | 2836 | ||
2788 | retval = limit_scaled_size(fh, &width, &height, | 2837 | retval = limit_scaled_size_lock(fh, &width, &height, |
2789 | V4L2_FIELD_INTERLACED, | 2838 | V4L2_FIELD_INTERLACED, |
2790 | /* width_mask */ ~3, | 2839 | /* width_mask */ ~3, |
2791 | /* width_bias */ 2, | 2840 | /* width_bias */ 2, |
@@ -2852,7 +2901,7 @@ static int bttv_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | |||
2852 | struct bttv *btv = fh->btv; | 2901 | struct bttv *btv = fh->btv; |
2853 | int res = bttv_resource(fh); | 2902 | int res = bttv_resource(fh); |
2854 | 2903 | ||
2855 | if (!check_alloc_btres(btv, fh, res)) | 2904 | if (!check_alloc_btres_lock(btv, fh, res)) |
2856 | return -EBUSY; | 2905 | return -EBUSY; |
2857 | 2906 | ||
2858 | return videobuf_qbuf(bttv_queue(fh), b); | 2907 | return videobuf_qbuf(bttv_queue(fh), b); |
@@ -2872,7 +2921,7 @@ static int bttv_streamon(struct file *file, void *priv, | |||
2872 | struct bttv *btv = fh->btv; | 2921 | struct bttv *btv = fh->btv; |
2873 | int res = bttv_resource(fh); | 2922 | int res = bttv_resource(fh); |
2874 | 2923 | ||
2875 | if (!check_alloc_btres(btv, fh, res)) | 2924 | if (!check_alloc_btres_lock(btv, fh, res)) |
2876 | return -EBUSY; | 2925 | return -EBUSY; |
2877 | return videobuf_streamon(bttv_queue(fh)); | 2926 | return videobuf_streamon(bttv_queue(fh)); |
2878 | } | 2927 | } |
@@ -2890,7 +2939,7 @@ static int bttv_streamoff(struct file *file, void *priv, | |||
2890 | retval = videobuf_streamoff(bttv_queue(fh)); | 2939 | retval = videobuf_streamoff(bttv_queue(fh)); |
2891 | if (retval < 0) | 2940 | if (retval < 0) |
2892 | return retval; | 2941 | return retval; |
2893 | free_btres(btv, fh, res); | 2942 | free_btres_lock(btv, fh, res); |
2894 | return 0; | 2943 | return 0; |
2895 | } | 2944 | } |
2896 | 2945 | ||
@@ -2907,6 +2956,7 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
2907 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | 2956 | c->id >= V4L2_CID_PRIVATE_LASTP1)) |
2908 | return -EINVAL; | 2957 | return -EINVAL; |
2909 | 2958 | ||
2959 | mutex_lock(&btv->lock); | ||
2910 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) | 2960 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) |
2911 | *c = no_ctl; | 2961 | *c = no_ctl; |
2912 | else { | 2962 | else { |
@@ -2914,6 +2964,7 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
2914 | 2964 | ||
2915 | *c = (NULL != ctrl) ? *ctrl : no_ctl; | 2965 | *c = (NULL != ctrl) ? *ctrl : no_ctl; |
2916 | } | 2966 | } |
2967 | mutex_unlock(&btv->lock); | ||
2917 | 2968 | ||
2918 | return 0; | 2969 | return 0; |
2919 | } | 2970 | } |
@@ -2924,8 +2975,11 @@ static int bttv_g_parm(struct file *file, void *f, | |||
2924 | struct bttv_fh *fh = f; | 2975 | struct bttv_fh *fh = f; |
2925 | struct bttv *btv = fh->btv; | 2976 | struct bttv *btv = fh->btv; |
2926 | 2977 | ||
2978 | mutex_lock(&btv->lock); | ||
2927 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, | 2979 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, |
2928 | &parm->parm.capture.timeperframe); | 2980 | &parm->parm.capture.timeperframe); |
2981 | mutex_unlock(&btv->lock); | ||
2982 | |||
2929 | return 0; | 2983 | return 0; |
2930 | } | 2984 | } |
2931 | 2985 | ||
@@ -2961,7 +3015,9 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) | |||
2961 | struct bttv_fh *fh = f; | 3015 | struct bttv_fh *fh = f; |
2962 | struct bttv *btv = fh->btv; | 3016 | struct bttv *btv = fh->btv; |
2963 | 3017 | ||
3018 | mutex_lock(&btv->lock); | ||
2964 | *p = v4l2_prio_max(&btv->prio); | 3019 | *p = v4l2_prio_max(&btv->prio); |
3020 | mutex_unlock(&btv->lock); | ||
2965 | 3021 | ||
2966 | return 0; | 3022 | return 0; |
2967 | } | 3023 | } |
@@ -2971,8 +3027,13 @@ static int bttv_s_priority(struct file *file, void *f, | |||
2971 | { | 3027 | { |
2972 | struct bttv_fh *fh = f; | 3028 | struct bttv_fh *fh = f; |
2973 | struct bttv *btv = fh->btv; | 3029 | struct bttv *btv = fh->btv; |
3030 | int rc; | ||
2974 | 3031 | ||
2975 | return v4l2_prio_change(&btv->prio, &fh->prio, prio); | 3032 | mutex_lock(&btv->lock); |
3033 | rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); | ||
3034 | mutex_unlock(&btv->lock); | ||
3035 | |||
3036 | return rc; | ||
2976 | } | 3037 | } |
2977 | 3038 | ||
2978 | static int bttv_cropcap(struct file *file, void *priv, | 3039 | static int bttv_cropcap(struct file *file, void *priv, |
@@ -2985,7 +3046,9 @@ static int bttv_cropcap(struct file *file, void *priv, | |||
2985 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 3046 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
2986 | return -EINVAL; | 3047 | return -EINVAL; |
2987 | 3048 | ||
3049 | mutex_lock(&btv->lock); | ||
2988 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | 3050 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; |
3051 | mutex_unlock(&btv->lock); | ||
2989 | 3052 | ||
2990 | return 0; | 3053 | return 0; |
2991 | } | 3054 | } |
@@ -3003,7 +3066,9 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3003 | inconsistent with fh->width or fh->height and apps | 3066 | inconsistent with fh->width or fh->height and apps |
3004 | do not expect a change here. */ | 3067 | do not expect a change here. */ |
3005 | 3068 | ||
3069 | mutex_lock(&btv->lock); | ||
3006 | crop->c = btv->crop[!!fh->do_crop].rect; | 3070 | crop->c = btv->crop[!!fh->do_crop].rect; |
3071 | mutex_unlock(&btv->lock); | ||
3007 | 3072 | ||
3008 | return 0; | 3073 | return 0; |
3009 | } | 3074 | } |
@@ -3024,14 +3089,15 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3024 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 3089 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
3025 | return -EINVAL; | 3090 | return -EINVAL; |
3026 | 3091 | ||
3027 | retval = v4l2_prio_check(&btv->prio, fh->prio); | ||
3028 | if (0 != retval) | ||
3029 | return retval; | ||
3030 | |||
3031 | /* Make sure tvnorm, vbi_end and the current cropping | 3092 | /* Make sure tvnorm, vbi_end and the current cropping |
3032 | parameters remain consistent until we're done. Note | 3093 | parameters remain consistent until we're done. Note |
3033 | read() may change vbi_end in check_alloc_btres(). */ | 3094 | read() may change vbi_end in check_alloc_btres_lock(). */ |
3034 | mutex_lock(&btv->lock); | 3095 | mutex_lock(&btv->lock); |
3096 | retval = v4l2_prio_check(&btv->prio, fh->prio); | ||
3097 | if (0 != retval) { | ||
3098 | mutex_unlock(&btv->lock); | ||
3099 | return retval; | ||
3100 | } | ||
3035 | 3101 | ||
3036 | retval = -EBUSY; | 3102 | retval = -EBUSY; |
3037 | 3103 | ||
@@ -3128,17 +3194,17 @@ static ssize_t bttv_read(struct file *file, char __user *data, | |||
3128 | 3194 | ||
3129 | switch (fh->type) { | 3195 | switch (fh->type) { |
3130 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 3196 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
3131 | if (!check_alloc_btres(fh->btv, fh, RESOURCE_VIDEO_READ)) { | 3197 | if (!check_alloc_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ)) { |
3132 | /* VIDEO_READ in use by another fh, | 3198 | /* VIDEO_READ in use by another fh, |
3133 | or VIDEO_STREAM by any fh. */ | 3199 | or VIDEO_STREAM by any fh. */ |
3134 | return -EBUSY; | 3200 | return -EBUSY; |
3135 | } | 3201 | } |
3136 | retval = videobuf_read_one(&fh->cap, data, count, ppos, | 3202 | retval = videobuf_read_one(&fh->cap, data, count, ppos, |
3137 | file->f_flags & O_NONBLOCK); | 3203 | file->f_flags & O_NONBLOCK); |
3138 | free_btres(fh->btv, fh, RESOURCE_VIDEO_READ); | 3204 | free_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ); |
3139 | break; | 3205 | break; |
3140 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 3206 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
3141 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) | 3207 | if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) |
3142 | return -EBUSY; | 3208 | return -EBUSY; |
3143 | retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1, | 3209 | retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1, |
3144 | file->f_flags & O_NONBLOCK); | 3210 | file->f_flags & O_NONBLOCK); |
@@ -3157,20 +3223,19 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3157 | unsigned int rc = POLLERR; | 3223 | unsigned int rc = POLLERR; |
3158 | 3224 | ||
3159 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 3225 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
3160 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) | 3226 | if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) |
3161 | return POLLERR; | 3227 | return POLLERR; |
3162 | return videobuf_poll_stream(file, &fh->vbi, wait); | 3228 | return videobuf_poll_stream(file, &fh->vbi, wait); |
3163 | } | 3229 | } |
3164 | 3230 | ||
3231 | mutex_lock(&fh->cap.vb_lock); | ||
3165 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { | 3232 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { |
3166 | mutex_lock(&fh->cap.vb_lock); | ||
3167 | /* streaming capture */ | 3233 | /* streaming capture */ |
3168 | if (list_empty(&fh->cap.stream)) | 3234 | if (list_empty(&fh->cap.stream)) |
3169 | goto err; | 3235 | goto err; |
3170 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); | 3236 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); |
3171 | } else { | 3237 | } else { |
3172 | /* read() capture */ | 3238 | /* read() capture */ |
3173 | mutex_lock(&fh->cap.vb_lock); | ||
3174 | if (NULL == fh->cap.read_buf) { | 3239 | if (NULL == fh->cap.read_buf) { |
3175 | /* need to capture a new frame */ | 3240 | /* need to capture a new frame */ |
3176 | if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) | 3241 | if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) |
@@ -3188,7 +3253,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3188 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); | 3253 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); |
3189 | fh->cap.read_off = 0; | 3254 | fh->cap.read_off = 0; |
3190 | } | 3255 | } |
3191 | mutex_unlock(&fh->cap.vb_lock); | ||
3192 | buf = (struct bttv_buffer*)fh->cap.read_buf; | 3256 | buf = (struct bttv_buffer*)fh->cap.read_buf; |
3193 | } | 3257 | } |
3194 | 3258 | ||
@@ -3221,21 +3285,32 @@ static int bttv_open(struct file *file) | |||
3221 | return -ENODEV; | 3285 | return -ENODEV; |
3222 | } | 3286 | } |
3223 | 3287 | ||
3224 | lock_kernel(); | ||
3225 | |||
3226 | dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", | 3288 | dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", |
3227 | btv->c.nr,v4l2_type_names[type]); | 3289 | btv->c.nr,v4l2_type_names[type]); |
3228 | 3290 | ||
3229 | /* allocate per filehandle data */ | 3291 | /* allocate per filehandle data */ |
3230 | fh = kmalloc(sizeof(*fh),GFP_KERNEL); | 3292 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); |
3231 | if (NULL == fh) { | 3293 | if (unlikely(!fh)) |
3232 | unlock_kernel(); | ||
3233 | return -ENOMEM; | 3294 | return -ENOMEM; |
3234 | } | ||
3235 | file->private_data = fh; | 3295 | file->private_data = fh; |
3296 | |||
3297 | /* | ||
3298 | * btv is protected by btv->lock mutex, while btv->init and other | ||
3299 | * streaming vars are protected by fh->cap.vb_lock. We need to take | ||
3300 | * care of both locks to avoid troubles. However, vb_lock is used also | ||
3301 | * inside videobuf, without calling buf->lock. So, it is a very bad | ||
3302 | * idea to hold both locks at the same time. | ||
3303 | * Let's first copy btv->init at fh, holding cap.vb_lock, and then work | ||
3304 | * with the rest of init, holding btv->lock. | ||
3305 | */ | ||
3306 | mutex_lock(&fh->cap.vb_lock); | ||
3236 | *fh = btv->init; | 3307 | *fh = btv->init; |
3308 | mutex_unlock(&fh->cap.vb_lock); | ||
3309 | |||
3237 | fh->type = type; | 3310 | fh->type = type; |
3238 | fh->ov.setup_ok = 0; | 3311 | fh->ov.setup_ok = 0; |
3312 | |||
3313 | mutex_lock(&btv->lock); | ||
3239 | v4l2_prio_open(&btv->prio, &fh->prio); | 3314 | v4l2_prio_open(&btv->prio, &fh->prio); |
3240 | 3315 | ||
3241 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, | 3316 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, |
@@ -3243,13 +3318,13 @@ static int bttv_open(struct file *file) | |||
3243 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 3318 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
3244 | V4L2_FIELD_INTERLACED, | 3319 | V4L2_FIELD_INTERLACED, |
3245 | sizeof(struct bttv_buffer), | 3320 | sizeof(struct bttv_buffer), |
3246 | fh); | 3321 | fh, NULL); |
3247 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, | 3322 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, |
3248 | &btv->c.pci->dev, &btv->s_lock, | 3323 | &btv->c.pci->dev, &btv->s_lock, |
3249 | V4L2_BUF_TYPE_VBI_CAPTURE, | 3324 | V4L2_BUF_TYPE_VBI_CAPTURE, |
3250 | V4L2_FIELD_SEQ_TB, | 3325 | V4L2_FIELD_SEQ_TB, |
3251 | sizeof(struct bttv_buffer), | 3326 | sizeof(struct bttv_buffer), |
3252 | fh); | 3327 | fh, NULL); |
3253 | set_tvnorm(btv,btv->tvnorm); | 3328 | set_tvnorm(btv,btv->tvnorm); |
3254 | set_input(btv, btv->input, btv->tvnorm); | 3329 | set_input(btv, btv->input, btv->tvnorm); |
3255 | 3330 | ||
@@ -3272,7 +3347,7 @@ static int bttv_open(struct file *file) | |||
3272 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); | 3347 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); |
3273 | 3348 | ||
3274 | bttv_field_count(btv); | 3349 | bttv_field_count(btv); |
3275 | unlock_kernel(); | 3350 | mutex_unlock(&btv->lock); |
3276 | return 0; | 3351 | return 0; |
3277 | } | 3352 | } |
3278 | 3353 | ||
@@ -3281,6 +3356,7 @@ static int bttv_release(struct file *file) | |||
3281 | struct bttv_fh *fh = file->private_data; | 3356 | struct bttv_fh *fh = file->private_data; |
3282 | struct bttv *btv = fh->btv; | 3357 | struct bttv *btv = fh->btv; |
3283 | 3358 | ||
3359 | mutex_lock(&btv->lock); | ||
3284 | /* turn off overlay */ | 3360 | /* turn off overlay */ |
3285 | if (check_btres(fh, RESOURCE_OVERLAY)) | 3361 | if (check_btres(fh, RESOURCE_OVERLAY)) |
3286 | bttv_switch_overlay(btv,fh,NULL); | 3362 | bttv_switch_overlay(btv,fh,NULL); |
@@ -3288,25 +3364,32 @@ static int bttv_release(struct file *file) | |||
3288 | /* stop video capture */ | 3364 | /* stop video capture */ |
3289 | if (check_btres(fh, RESOURCE_VIDEO_STREAM)) { | 3365 | if (check_btres(fh, RESOURCE_VIDEO_STREAM)) { |
3290 | videobuf_streamoff(&fh->cap); | 3366 | videobuf_streamoff(&fh->cap); |
3291 | free_btres(btv,fh,RESOURCE_VIDEO_STREAM); | 3367 | free_btres_lock(btv,fh,RESOURCE_VIDEO_STREAM); |
3292 | } | 3368 | } |
3293 | if (fh->cap.read_buf) { | 3369 | if (fh->cap.read_buf) { |
3294 | buffer_release(&fh->cap,fh->cap.read_buf); | 3370 | buffer_release(&fh->cap,fh->cap.read_buf); |
3295 | kfree(fh->cap.read_buf); | 3371 | kfree(fh->cap.read_buf); |
3296 | } | 3372 | } |
3297 | if (check_btres(fh, RESOURCE_VIDEO_READ)) { | 3373 | if (check_btres(fh, RESOURCE_VIDEO_READ)) { |
3298 | free_btres(btv, fh, RESOURCE_VIDEO_READ); | 3374 | free_btres_lock(btv, fh, RESOURCE_VIDEO_READ); |
3299 | } | 3375 | } |
3300 | 3376 | ||
3301 | /* stop vbi capture */ | 3377 | /* stop vbi capture */ |
3302 | if (check_btres(fh, RESOURCE_VBI)) { | 3378 | if (check_btres(fh, RESOURCE_VBI)) { |
3303 | videobuf_stop(&fh->vbi); | 3379 | videobuf_stop(&fh->vbi); |
3304 | free_btres(btv,fh,RESOURCE_VBI); | 3380 | free_btres_lock(btv,fh,RESOURCE_VBI); |
3305 | } | 3381 | } |
3306 | 3382 | ||
3307 | /* free stuff */ | 3383 | /* free stuff */ |
3384 | |||
3385 | /* | ||
3386 | * videobuf uses cap.vb_lock - we should avoid holding btv->lock, | ||
3387 | * otherwise we may have dead lock conditions | ||
3388 | */ | ||
3389 | mutex_unlock(&btv->lock); | ||
3308 | videobuf_mmap_free(&fh->cap); | 3390 | videobuf_mmap_free(&fh->cap); |
3309 | videobuf_mmap_free(&fh->vbi); | 3391 | videobuf_mmap_free(&fh->vbi); |
3392 | mutex_lock(&btv->lock); | ||
3310 | v4l2_prio_close(&btv->prio, fh->prio); | 3393 | v4l2_prio_close(&btv->prio, fh->prio); |
3311 | file->private_data = NULL; | 3394 | file->private_data = NULL; |
3312 | kfree(fh); | 3395 | kfree(fh); |
@@ -3316,6 +3399,7 @@ static int bttv_release(struct file *file) | |||
3316 | 3399 | ||
3317 | if (!btv->users) | 3400 | if (!btv->users) |
3318 | audio_mute(btv, 1); | 3401 | audio_mute(btv, 1); |
3402 | mutex_unlock(&btv->lock); | ||
3319 | 3403 | ||
3320 | return 0; | 3404 | return 0; |
3321 | } | 3405 | } |
@@ -3333,13 +3417,13 @@ bttv_mmap(struct file *file, struct vm_area_struct *vma) | |||
3333 | 3417 | ||
3334 | static const struct v4l2_file_operations bttv_fops = | 3418 | static const struct v4l2_file_operations bttv_fops = |
3335 | { | 3419 | { |
3336 | .owner = THIS_MODULE, | 3420 | .owner = THIS_MODULE, |
3337 | .open = bttv_open, | 3421 | .open = bttv_open, |
3338 | .release = bttv_release, | 3422 | .release = bttv_release, |
3339 | .ioctl = video_ioctl2, | 3423 | .unlocked_ioctl = video_ioctl2, |
3340 | .read = bttv_read, | 3424 | .read = bttv_read, |
3341 | .mmap = bttv_mmap, | 3425 | .mmap = bttv_mmap, |
3342 | .poll = bttv_poll, | 3426 | .poll = bttv_poll, |
3343 | }; | 3427 | }; |
3344 | 3428 | ||
3345 | static const struct v4l2_ioctl_ops bttv_ioctl_ops = { | 3429 | static const struct v4l2_ioctl_ops bttv_ioctl_ops = { |
@@ -3412,21 +3496,19 @@ static int radio_open(struct file *file) | |||
3412 | 3496 | ||
3413 | dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); | 3497 | dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); |
3414 | 3498 | ||
3415 | lock_kernel(); | ||
3416 | |||
3417 | dprintk("bttv%d: open called (radio)\n",btv->c.nr); | 3499 | dprintk("bttv%d: open called (radio)\n",btv->c.nr); |
3418 | 3500 | ||
3419 | /* allocate per filehandle data */ | 3501 | /* allocate per filehandle data */ |
3420 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); | 3502 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); |
3421 | if (NULL == fh) { | 3503 | if (unlikely(!fh)) |
3422 | unlock_kernel(); | ||
3423 | return -ENOMEM; | 3504 | return -ENOMEM; |
3424 | } | ||
3425 | file->private_data = fh; | 3505 | file->private_data = fh; |
3506 | mutex_lock(&fh->cap.vb_lock); | ||
3426 | *fh = btv->init; | 3507 | *fh = btv->init; |
3427 | v4l2_prio_open(&btv->prio, &fh->prio); | 3508 | mutex_unlock(&fh->cap.vb_lock); |
3428 | 3509 | ||
3429 | mutex_lock(&btv->lock); | 3510 | mutex_lock(&btv->lock); |
3511 | v4l2_prio_open(&btv->prio, &fh->prio); | ||
3430 | 3512 | ||
3431 | btv->radio_user++; | 3513 | btv->radio_user++; |
3432 | 3514 | ||
@@ -3434,7 +3516,6 @@ static int radio_open(struct file *file) | |||
3434 | audio_input(btv,TVAUDIO_INPUT_RADIO); | 3516 | audio_input(btv,TVAUDIO_INPUT_RADIO); |
3435 | 3517 | ||
3436 | mutex_unlock(&btv->lock); | 3518 | mutex_unlock(&btv->lock); |
3437 | unlock_kernel(); | ||
3438 | return 0; | 3519 | return 0; |
3439 | } | 3520 | } |
3440 | 3521 | ||
@@ -3444,6 +3525,7 @@ static int radio_release(struct file *file) | |||
3444 | struct bttv *btv = fh->btv; | 3525 | struct bttv *btv = fh->btv; |
3445 | struct rds_command cmd; | 3526 | struct rds_command cmd; |
3446 | 3527 | ||
3528 | mutex_lock(&btv->lock); | ||
3447 | v4l2_prio_close(&btv->prio, fh->prio); | 3529 | v4l2_prio_close(&btv->prio, fh->prio); |
3448 | file->private_data = NULL; | 3530 | file->private_data = NULL; |
3449 | kfree(fh); | 3531 | kfree(fh); |
@@ -3451,6 +3533,7 @@ static int radio_release(struct file *file) | |||
3451 | btv->radio_user--; | 3533 | btv->radio_user--; |
3452 | 3534 | ||
3453 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); | 3535 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); |
3536 | mutex_unlock(&btv->lock); | ||
3454 | 3537 | ||
3455 | return 0; | 3538 | return 0; |
3456 | } | 3539 | } |
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index 685d6597ee7..d49b675045f 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -121,9 +121,8 @@ bttv_i2c_wait_done(struct bttv *btv) | |||
121 | 121 | ||
122 | /* timeout */ | 122 | /* timeout */ |
123 | if (wait_event_interruptible_timeout(btv->i2c_queue, | 123 | if (wait_event_interruptible_timeout(btv->i2c_queue, |
124 | btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS) | 124 | btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS) |
125 | 125 | rc = -EIO; | |
126 | rc = -EIO; | ||
127 | 126 | ||
128 | if (btv->i2c_done & BT848_INT_RACK) | 127 | if (btv->i2c_done & BT848_INT_RACK) |
129 | rc = 1; | 128 | rc = 1; |
@@ -390,41 +389,3 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
390 | 389 | ||
391 | return btv->i2c_rc; | 390 | return btv->i2c_rc; |
392 | } | 391 | } |
393 | |||
394 | /* Instantiate the I2C IR receiver device, if present */ | ||
395 | void __devinit init_bttv_i2c_ir(struct bttv *btv) | ||
396 | { | ||
397 | if (0 == btv->i2c_rc) { | ||
398 | struct i2c_board_info info; | ||
399 | /* The external IR receiver is at i2c address 0x34 (0x35 for | ||
400 | reads). Future Hauppauge cards will have an internal | ||
401 | receiver at 0x30 (0x31 for reads). In theory, both can be | ||
402 | fitted, and Hauppauge suggest an external overrides an | ||
403 | internal. | ||
404 | |||
405 | That's why we probe 0x1a (~0x34) first. CB | ||
406 | */ | ||
407 | const unsigned short addr_list[] = { | ||
408 | 0x1a, 0x18, 0x4b, 0x64, 0x30, 0x71, | ||
409 | I2C_CLIENT_END | ||
410 | }; | ||
411 | |||
412 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
413 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
414 | i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | int __devexit fini_bttv_i2c(struct bttv *btv) | ||
419 | { | ||
420 | if (0 != btv->i2c_rc) | ||
421 | return 0; | ||
422 | |||
423 | return i2c_del_adapter(&btv->c.i2c_adap); | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Local variables: | ||
428 | * c-basic-offset: 8 | ||
429 | * End: | ||
430 | */ | ||
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index f68717a4bde..6bf05a7dc5f 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -245,6 +245,83 @@ static void bttv_ir_stop(struct bttv *btv) | |||
245 | } | 245 | } |
246 | } | 246 | } |
247 | 247 | ||
248 | /* | ||
249 | * Get_key functions used by I2C remotes | ||
250 | */ | ||
251 | |||
252 | static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
253 | { | ||
254 | unsigned char b; | ||
255 | |||
256 | /* poll IR chip */ | ||
257 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | ||
258 | dprintk(KERN_INFO DEVNAME ": read error\n"); | ||
259 | return -EIO; | ||
260 | } | ||
261 | |||
262 | /* ignore 0xaa */ | ||
263 | if (b==0xaa) | ||
264 | return 0; | ||
265 | dprintk(KERN_INFO DEVNAME ": key %02x\n", b); | ||
266 | |||
267 | *ir_key = b; | ||
268 | *ir_raw = b; | ||
269 | return 1; | ||
270 | } | ||
271 | |||
272 | /* Instantiate the I2C IR receiver device, if present */ | ||
273 | void __devinit init_bttv_i2c_ir(struct bttv *btv) | ||
274 | { | ||
275 | const unsigned short addr_list[] = { | ||
276 | 0x1a, 0x18, 0x64, 0x30, 0x71, | ||
277 | I2C_CLIENT_END | ||
278 | }; | ||
279 | struct i2c_board_info info; | ||
280 | |||
281 | if (0 != btv->i2c_rc) | ||
282 | return; | ||
283 | |||
284 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
285 | memset(&btv->init_data, 0, sizeof(btv->init_data)); | ||
286 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
287 | |||
288 | switch (btv->c.type) { | ||
289 | case BTTV_BOARD_PV951: | ||
290 | btv->init_data.name = "PV951"; | ||
291 | btv->init_data.get_key = get_key_pv951; | ||
292 | btv->init_data.ir_codes = RC_MAP_PV951; | ||
293 | btv->init_data.type = IR_TYPE_OTHER; | ||
294 | info.addr = 0x4b; | ||
295 | break; | ||
296 | default: | ||
297 | /* | ||
298 | * The external IR receiver is at i2c address 0x34 (0x35 for | ||
299 | * reads). Future Hauppauge cards will have an internal | ||
300 | * receiver at 0x30 (0x31 for reads). In theory, both can be | ||
301 | * fitted, and Hauppauge suggest an external overrides an | ||
302 | * internal. | ||
303 | * That's why we probe 0x1a (~0x34) first. CB | ||
304 | */ | ||
305 | |||
306 | i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | if (btv->init_data.name) | ||
311 | info.platform_data = &btv->init_data; | ||
312 | i2c_new_device(&btv->c.i2c_adap, &info); | ||
313 | |||
314 | return; | ||
315 | } | ||
316 | |||
317 | int __devexit fini_bttv_i2c(struct bttv *btv) | ||
318 | { | ||
319 | if (0 != btv->i2c_rc) | ||
320 | return 0; | ||
321 | |||
322 | return i2c_del_adapter(&btv->c.i2c_adap); | ||
323 | } | ||
324 | |||
248 | int bttv_input_init(struct bttv *btv) | 325 | int bttv_input_init(struct bttv *btv) |
249 | { | 326 | { |
250 | struct card_ir *ir; | 327 | struct card_ir *ir; |
@@ -420,10 +497,3 @@ void bttv_input_fini(struct bttv *btv) | |||
420 | kfree(btv->remote); | 497 | kfree(btv->remote); |
421 | btv->remote = NULL; | 498 | btv->remote = NULL; |
422 | } | 499 | } |
423 | |||
424 | |||
425 | /* | ||
426 | * Local variables: | ||
427 | * c-basic-offset: 8 | ||
428 | * End: | ||
429 | */ | ||
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index 0fa9f39f37a..9b57d091da4 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c | |||
@@ -582,7 +582,7 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf | |||
582 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 582 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
583 | 583 | ||
584 | BUG_ON(in_interrupt()); | 584 | BUG_ON(in_interrupt()); |
585 | videobuf_waiton(&buf->vb,0,0); | 585 | videobuf_waiton(q, &buf->vb, 0, 0); |
586 | videobuf_dma_unmap(q->dev, dma); | 586 | videobuf_dma_unmap(q->dev, dma); |
587 | videobuf_dma_free(dma); | 587 | videobuf_dma_free(dma); |
588 | btcx_riscmem_free(btv->c.pci,&buf->bottom); | 588 | btcx_riscmem_free(btv->c.pci,&buf->bottom); |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index 3ec2402c6b4..6fd2a8ebda1 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <media/v4l2-device.h> | 19 | #include <media/v4l2-device.h> |
20 | #include <media/ir-common.h> | 20 | #include <media/ir-common.h> |
21 | #include <media/ir-kbd-i2c.h> | ||
22 | #include <media/i2c-addr.h> | 21 | #include <media/i2c-addr.h> |
23 | #include <media/tuner.h> | 22 | #include <media/tuner.h> |
24 | 23 | ||
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 6cccc2a17ee..d1e26a448ed 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <media/videobuf-dma-sg.h> | 42 | #include <media/videobuf-dma-sg.h> |
43 | #include <media/tveeprom.h> | 43 | #include <media/tveeprom.h> |
44 | #include <media/ir-common.h> | 44 | #include <media/ir-common.h> |
45 | 45 | #include <media/ir-kbd-i2c.h> | |
46 | 46 | ||
47 | #include "bt848.h" | 47 | #include "bt848.h" |
48 | #include "bttv.h" | 48 | #include "bttv.h" |
@@ -271,6 +271,12 @@ int bttv_sub_del_devices(struct bttv_core *core); | |||
271 | extern int no_overlay; | 271 | extern int no_overlay; |
272 | 272 | ||
273 | /* ---------------------------------------------------------- */ | 273 | /* ---------------------------------------------------------- */ |
274 | /* bttv-input.c */ | ||
275 | |||
276 | extern void init_bttv_i2c_ir(struct bttv *btv); | ||
277 | extern int fini_bttv_i2c(struct bttv *btv); | ||
278 | |||
279 | /* ---------------------------------------------------------- */ | ||
274 | /* bttv-driver.c */ | 280 | /* bttv-driver.c */ |
275 | 281 | ||
276 | /* insmod options */ | 282 | /* insmod options */ |
@@ -279,8 +285,6 @@ extern unsigned int bttv_debug; | |||
279 | extern unsigned int bttv_gpio; | 285 | extern unsigned int bttv_gpio; |
280 | extern void bttv_gpio_tracking(struct bttv *btv, char *comment); | 286 | extern void bttv_gpio_tracking(struct bttv *btv, char *comment); |
281 | extern int init_bttv_i2c(struct bttv *btv); | 287 | extern int init_bttv_i2c(struct bttv *btv); |
282 | extern void init_bttv_i2c_ir(struct bttv *btv); | ||
283 | extern int fini_bttv_i2c(struct bttv *btv); | ||
284 | 288 | ||
285 | #define bttv_printk if (bttv_verbose) printk | 289 | #define bttv_printk if (bttv_verbose) printk |
286 | #define dprintk if (bttv_debug >= 1) printk | 290 | #define dprintk if (bttv_debug >= 1) printk |
@@ -366,6 +370,9 @@ struct bttv { | |||
366 | int has_remote; | 370 | int has_remote; |
367 | struct card_ir *remote; | 371 | struct card_ir *remote; |
368 | 372 | ||
373 | /* I2C remote data */ | ||
374 | struct IR_i2c_init_data init_data; | ||
375 | |||
369 | /* locking */ | 376 | /* locking */ |
370 | spinlock_t s_lock; | 377 | spinlock_t s_lock; |
371 | struct mutex lock; | 378 | struct mutex lock; |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 9536f1a40dd..2934770dacc 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/dmi.h> | ||
28 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
29 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
30 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
@@ -46,6 +47,7 @@ | |||
46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
48 | 49 | ||
50 | #include "ov7670.h" | ||
49 | #include "cafe_ccic-regs.h" | 51 | #include "cafe_ccic-regs.h" |
50 | 52 | ||
51 | #define CAFE_VERSION 0x000002 | 53 | #define CAFE_VERSION 0x000002 |
@@ -180,6 +182,7 @@ struct cafe_camera | |||
180 | /* Current operating parameters */ | 182 | /* Current operating parameters */ |
181 | u32 sensor_type; /* Currently ov7670 only */ | 183 | u32 sensor_type; /* Currently ov7670 only */ |
182 | struct v4l2_pix_format pix_format; | 184 | struct v4l2_pix_format pix_format; |
185 | enum v4l2_mbus_pixelcode mbus_code; | ||
183 | 186 | ||
184 | /* Locks */ | 187 | /* Locks */ |
185 | struct mutex s_mutex; /* Access to this structure */ | 188 | struct mutex s_mutex; /* Access to this structure */ |
@@ -207,6 +210,49 @@ static inline struct cafe_camera *to_cam(struct v4l2_device *dev) | |||
207 | return container_of(dev, struct cafe_camera, v4l2_dev); | 210 | return container_of(dev, struct cafe_camera, v4l2_dev); |
208 | } | 211 | } |
209 | 212 | ||
213 | static struct cafe_format_struct { | ||
214 | __u8 *desc; | ||
215 | __u32 pixelformat; | ||
216 | int bpp; /* Bytes per pixel */ | ||
217 | enum v4l2_mbus_pixelcode mbus_code; | ||
218 | } cafe_formats[] = { | ||
219 | { | ||
220 | .desc = "YUYV 4:2:2", | ||
221 | .pixelformat = V4L2_PIX_FMT_YUYV, | ||
222 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, | ||
223 | .bpp = 2, | ||
224 | }, | ||
225 | { | ||
226 | .desc = "RGB 444", | ||
227 | .pixelformat = V4L2_PIX_FMT_RGB444, | ||
228 | .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, | ||
229 | .bpp = 2, | ||
230 | }, | ||
231 | { | ||
232 | .desc = "RGB 565", | ||
233 | .pixelformat = V4L2_PIX_FMT_RGB565, | ||
234 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
235 | .bpp = 2, | ||
236 | }, | ||
237 | { | ||
238 | .desc = "Raw RGB Bayer", | ||
239 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
240 | .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, | ||
241 | .bpp = 1 | ||
242 | }, | ||
243 | }; | ||
244 | #define N_CAFE_FMTS ARRAY_SIZE(cafe_formats) | ||
245 | |||
246 | static struct cafe_format_struct *cafe_find_format(u32 pixelformat) | ||
247 | { | ||
248 | unsigned i; | ||
249 | |||
250 | for (i = 0; i < N_CAFE_FMTS; i++) | ||
251 | if (cafe_formats[i].pixelformat == pixelformat) | ||
252 | return cafe_formats + i; | ||
253 | /* Not found? Then return the first format. */ | ||
254 | return cafe_formats; | ||
255 | } | ||
210 | 256 | ||
211 | /* | 257 | /* |
212 | * Start over with DMA buffers - dev_lock needed. | 258 | * Start over with DMA buffers - dev_lock needed. |
@@ -319,7 +365,6 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, | |||
319 | { | 365 | { |
320 | unsigned int rval; | 366 | unsigned int rval; |
321 | unsigned long flags; | 367 | unsigned long flags; |
322 | DEFINE_WAIT(the_wait); | ||
323 | 368 | ||
324 | spin_lock_irqsave(&cam->dev_lock, flags); | 369 | spin_lock_irqsave(&cam->dev_lock, flags); |
325 | rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); | 370 | rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); |
@@ -334,28 +379,27 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, | |||
334 | cafe_reg_write(cam, REG_TWSIC1, rval); | 379 | cafe_reg_write(cam, REG_TWSIC1, rval); |
335 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 380 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
336 | 381 | ||
382 | /* Unfortunately, reading TWSIC1 too soon after sending a command | ||
383 | * causes the device to die. | ||
384 | * Use a busy-wait because we often send a large quantity of small | ||
385 | * commands at-once; using msleep() would cause a lot of context | ||
386 | * switches which take longer than 2ms, resulting in a noticable | ||
387 | * boot-time and capture-start delays. | ||
388 | */ | ||
389 | mdelay(2); | ||
390 | |||
337 | /* | 391 | /* |
338 | * Time to wait for the write to complete. THIS IS A RACY | 392 | * Another sad fact is that sometimes, commands silently complete but |
339 | * WAY TO DO IT, but the sad fact is that reading the TWSIC1 | 393 | * cafe_smbus_write_done() never becomes aware of this. |
340 | * register too quickly after starting the operation sends | 394 | * This happens at random and appears to possible occur with any |
341 | * the device into a place that may be kinder and better, but | 395 | * command. |
342 | * which is absolutely useless for controlling the sensor. In | 396 | * We don't understand why this is. We work around this issue |
343 | * practice we have plenty of time to get into our sleep state | 397 | * with the timeout in the wait below, assuming that all commands |
344 | * before the interrupt hits, and the worst case is that we | 398 | * complete within the timeout. |
345 | * time out and then see that things completed, so this seems | ||
346 | * the best way for now. | ||
347 | */ | 399 | */ |
348 | do { | ||
349 | prepare_to_wait(&cam->smbus_wait, &the_wait, | ||
350 | TASK_UNINTERRUPTIBLE); | ||
351 | schedule_timeout(1); /* even 1 jiffy is too long */ | ||
352 | finish_wait(&cam->smbus_wait, &the_wait); | ||
353 | } while (!cafe_smbus_write_done(cam)); | ||
354 | |||
355 | #ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT | ||
356 | wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam), | 400 | wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam), |
357 | CAFE_SMBUS_TIMEOUT); | 401 | CAFE_SMBUS_TIMEOUT); |
358 | #endif | 402 | |
359 | spin_lock_irqsave(&cam->dev_lock, flags); | 403 | spin_lock_irqsave(&cam->dev_lock, flags); |
360 | rval = cafe_reg_read(cam, REG_TWSIC1); | 404 | rval = cafe_reg_read(cam, REG_TWSIC1); |
361 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 405 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
@@ -812,15 +856,15 @@ static int cafe_cam_set_flip(struct cafe_camera *cam) | |||
812 | 856 | ||
813 | static int cafe_cam_configure(struct cafe_camera *cam) | 857 | static int cafe_cam_configure(struct cafe_camera *cam) |
814 | { | 858 | { |
815 | struct v4l2_format fmt; | 859 | struct v4l2_mbus_framefmt mbus_fmt; |
816 | int ret; | 860 | int ret; |
817 | 861 | ||
818 | if (cam->state != S_IDLE) | 862 | if (cam->state != S_IDLE) |
819 | return -EINVAL; | 863 | return -EINVAL; |
820 | fmt.fmt.pix = cam->pix_format; | 864 | v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code); |
821 | ret = sensor_call(cam, core, init, 0); | 865 | ret = sensor_call(cam, core, init, 0); |
822 | if (ret == 0) | 866 | if (ret == 0) |
823 | ret = sensor_call(cam, video, s_fmt, &fmt); | 867 | ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt); |
824 | /* | 868 | /* |
825 | * OV7670 does weird things if flip is set *before* format... | 869 | * OV7670 does weird things if flip is set *before* format... |
826 | */ | 870 | */ |
@@ -1481,7 +1525,7 @@ static int cafe_vidioc_querycap(struct file *file, void *priv, | |||
1481 | /* | 1525 | /* |
1482 | * The default format we use until somebody says otherwise. | 1526 | * The default format we use until somebody says otherwise. |
1483 | */ | 1527 | */ |
1484 | static struct v4l2_pix_format cafe_def_pix_format = { | 1528 | static const struct v4l2_pix_format cafe_def_pix_format = { |
1485 | .width = VGA_WIDTH, | 1529 | .width = VGA_WIDTH, |
1486 | .height = VGA_HEIGHT, | 1530 | .height = VGA_HEIGHT, |
1487 | .pixelformat = V4L2_PIX_FMT_YUYV, | 1531 | .pixelformat = V4L2_PIX_FMT_YUYV, |
@@ -1490,28 +1534,38 @@ static struct v4l2_pix_format cafe_def_pix_format = { | |||
1490 | .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, | 1534 | .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, |
1491 | }; | 1535 | }; |
1492 | 1536 | ||
1537 | static const enum v4l2_mbus_pixelcode cafe_def_mbus_code = | ||
1538 | V4L2_MBUS_FMT_YUYV8_2X8; | ||
1539 | |||
1493 | static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp, | 1540 | static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp, |
1494 | void *priv, struct v4l2_fmtdesc *fmt) | 1541 | void *priv, struct v4l2_fmtdesc *fmt) |
1495 | { | 1542 | { |
1496 | struct cafe_camera *cam = priv; | 1543 | if (fmt->index >= N_CAFE_FMTS) |
1497 | int ret; | 1544 | return -EINVAL; |
1498 | 1545 | strlcpy(fmt->description, cafe_formats[fmt->index].desc, | |
1499 | mutex_lock(&cam->s_mutex); | 1546 | sizeof(fmt->description)); |
1500 | ret = sensor_call(cam, video, enum_fmt, fmt); | 1547 | fmt->pixelformat = cafe_formats[fmt->index].pixelformat; |
1501 | mutex_unlock(&cam->s_mutex); | 1548 | return 0; |
1502 | return ret; | ||
1503 | } | 1549 | } |
1504 | 1550 | ||
1505 | |||
1506 | static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, | 1551 | static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, |
1507 | struct v4l2_format *fmt) | 1552 | struct v4l2_format *fmt) |
1508 | { | 1553 | { |
1509 | struct cafe_camera *cam = priv; | 1554 | struct cafe_camera *cam = priv; |
1555 | struct cafe_format_struct *f; | ||
1556 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
1557 | struct v4l2_mbus_framefmt mbus_fmt; | ||
1510 | int ret; | 1558 | int ret; |
1511 | 1559 | ||
1560 | f = cafe_find_format(pix->pixelformat); | ||
1561 | pix->pixelformat = f->pixelformat; | ||
1562 | v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code); | ||
1512 | mutex_lock(&cam->s_mutex); | 1563 | mutex_lock(&cam->s_mutex); |
1513 | ret = sensor_call(cam, video, try_fmt, fmt); | 1564 | ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt); |
1514 | mutex_unlock(&cam->s_mutex); | 1565 | mutex_unlock(&cam->s_mutex); |
1566 | v4l2_fill_pix_format(pix, &mbus_fmt); | ||
1567 | pix->bytesperline = pix->width * f->bpp; | ||
1568 | pix->sizeimage = pix->height * pix->bytesperline; | ||
1515 | return ret; | 1569 | return ret; |
1516 | } | 1570 | } |
1517 | 1571 | ||
@@ -1519,6 +1573,7 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, | |||
1519 | struct v4l2_format *fmt) | 1573 | struct v4l2_format *fmt) |
1520 | { | 1574 | { |
1521 | struct cafe_camera *cam = priv; | 1575 | struct cafe_camera *cam = priv; |
1576 | struct cafe_format_struct *f; | ||
1522 | int ret; | 1577 | int ret; |
1523 | 1578 | ||
1524 | /* | 1579 | /* |
@@ -1527,6 +1582,9 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, | |||
1527 | */ | 1582 | */ |
1528 | if (cam->state != S_IDLE || cam->n_sbufs > 0) | 1583 | if (cam->state != S_IDLE || cam->n_sbufs > 0) |
1529 | return -EBUSY; | 1584 | return -EBUSY; |
1585 | |||
1586 | f = cafe_find_format(fmt->fmt.pix.pixelformat); | ||
1587 | |||
1530 | /* | 1588 | /* |
1531 | * See if the formatting works in principle. | 1589 | * See if the formatting works in principle. |
1532 | */ | 1590 | */ |
@@ -1539,6 +1597,8 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, | |||
1539 | */ | 1597 | */ |
1540 | mutex_lock(&cam->s_mutex); | 1598 | mutex_lock(&cam->s_mutex); |
1541 | cam->pix_format = fmt->fmt.pix; | 1599 | cam->pix_format = fmt->fmt.pix; |
1600 | cam->mbus_code = f->mbus_code; | ||
1601 | |||
1542 | /* | 1602 | /* |
1543 | * Make sure we have appropriate DMA buffers. | 1603 | * Make sure we have appropriate DMA buffers. |
1544 | */ | 1604 | */ |
@@ -1652,6 +1712,30 @@ static int cafe_vidioc_g_chip_ident(struct file *file, void *priv, | |||
1652 | return sensor_call(cam, core, g_chip_ident, chip); | 1712 | return sensor_call(cam, core, g_chip_ident, chip); |
1653 | } | 1713 | } |
1654 | 1714 | ||
1715 | static int cafe_vidioc_enum_framesizes(struct file *filp, void *priv, | ||
1716 | struct v4l2_frmsizeenum *sizes) | ||
1717 | { | ||
1718 | struct cafe_camera *cam = priv; | ||
1719 | int ret; | ||
1720 | |||
1721 | mutex_lock(&cam->s_mutex); | ||
1722 | ret = sensor_call(cam, video, enum_framesizes, sizes); | ||
1723 | mutex_unlock(&cam->s_mutex); | ||
1724 | return ret; | ||
1725 | } | ||
1726 | |||
1727 | static int cafe_vidioc_enum_frameintervals(struct file *filp, void *priv, | ||
1728 | struct v4l2_frmivalenum *interval) | ||
1729 | { | ||
1730 | struct cafe_camera *cam = priv; | ||
1731 | int ret; | ||
1732 | |||
1733 | mutex_lock(&cam->s_mutex); | ||
1734 | ret = sensor_call(cam, video, enum_frameintervals, interval); | ||
1735 | mutex_unlock(&cam->s_mutex); | ||
1736 | return ret; | ||
1737 | } | ||
1738 | |||
1655 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1739 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1656 | static int cafe_vidioc_g_register(struct file *file, void *priv, | 1740 | static int cafe_vidioc_g_register(struct file *file, void *priv, |
1657 | struct v4l2_dbg_register *reg) | 1741 | struct v4l2_dbg_register *reg) |
@@ -1715,6 +1799,8 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | |||
1715 | .vidioc_s_ctrl = cafe_vidioc_s_ctrl, | 1799 | .vidioc_s_ctrl = cafe_vidioc_s_ctrl, |
1716 | .vidioc_g_parm = cafe_vidioc_g_parm, | 1800 | .vidioc_g_parm = cafe_vidioc_g_parm, |
1717 | .vidioc_s_parm = cafe_vidioc_s_parm, | 1801 | .vidioc_s_parm = cafe_vidioc_s_parm, |
1802 | .vidioc_enum_framesizes = cafe_vidioc_enum_framesizes, | ||
1803 | .vidioc_enum_frameintervals = cafe_vidioc_enum_frameintervals, | ||
1718 | .vidioc_g_chip_ident = cafe_vidioc_g_chip_ident, | 1804 | .vidioc_g_chip_ident = cafe_vidioc_g_chip_ident, |
1719 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1805 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1720 | .vidioc_g_register = cafe_vidioc_g_register, | 1806 | .vidioc_g_register = cafe_vidioc_g_register, |
@@ -1890,11 +1976,33 @@ static irqreturn_t cafe_irq(int irq, void *data) | |||
1890 | * PCI interface stuff. | 1976 | * PCI interface stuff. |
1891 | */ | 1977 | */ |
1892 | 1978 | ||
1979 | static const struct dmi_system_id olpc_xo1_dmi[] = { | ||
1980 | { | ||
1981 | .matches = { | ||
1982 | DMI_MATCH(DMI_SYS_VENDOR, "OLPC"), | ||
1983 | DMI_MATCH(DMI_PRODUCT_NAME, "XO"), | ||
1984 | DMI_MATCH(DMI_PRODUCT_VERSION, "1"), | ||
1985 | }, | ||
1986 | }, | ||
1987 | { } | ||
1988 | }; | ||
1989 | |||
1893 | static int cafe_pci_probe(struct pci_dev *pdev, | 1990 | static int cafe_pci_probe(struct pci_dev *pdev, |
1894 | const struct pci_device_id *id) | 1991 | const struct pci_device_id *id) |
1895 | { | 1992 | { |
1896 | int ret; | 1993 | int ret; |
1897 | struct cafe_camera *cam; | 1994 | struct cafe_camera *cam; |
1995 | struct ov7670_config sensor_cfg = { | ||
1996 | /* This controller only does SMBUS */ | ||
1997 | .use_smbus = true, | ||
1998 | |||
1999 | /* | ||
2000 | * Exclude QCIF mode, because it only captures a tiny portion | ||
2001 | * of the sensor FOV | ||
2002 | */ | ||
2003 | .min_width = 320, | ||
2004 | .min_height = 240, | ||
2005 | }; | ||
1898 | 2006 | ||
1899 | /* | 2007 | /* |
1900 | * Start putting together one of our big camera structures. | 2008 | * Start putting together one of our big camera structures. |
@@ -1915,6 +2023,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, | |||
1915 | init_waitqueue_head(&cam->iowait); | 2023 | init_waitqueue_head(&cam->iowait); |
1916 | cam->pdev = pdev; | 2024 | cam->pdev = pdev; |
1917 | cam->pix_format = cafe_def_pix_format; | 2025 | cam->pix_format = cafe_def_pix_format; |
2026 | cam->mbus_code = cafe_def_mbus_code; | ||
1918 | INIT_LIST_HEAD(&cam->dev_list); | 2027 | INIT_LIST_HEAD(&cam->dev_list); |
1919 | INIT_LIST_HEAD(&cam->sb_avail); | 2028 | INIT_LIST_HEAD(&cam->sb_avail); |
1920 | INIT_LIST_HEAD(&cam->sb_full); | 2029 | INIT_LIST_HEAD(&cam->sb_full); |
@@ -1951,13 +2060,18 @@ static int cafe_pci_probe(struct pci_dev *pdev, | |||
1951 | if (ret) | 2060 | if (ret) |
1952 | goto out_freeirq; | 2061 | goto out_freeirq; |
1953 | 2062 | ||
2063 | /* Apply XO-1 clock speed */ | ||
2064 | if (dmi_check_system(olpc_xo1_dmi)) | ||
2065 | sensor_cfg.clock_speed = 45; | ||
2066 | |||
1954 | cam->sensor_addr = 0x42; | 2067 | cam->sensor_addr = 0x42; |
1955 | cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter, | 2068 | cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter, |
1956 | "ov7670", "ov7670", cam->sensor_addr, NULL); | 2069 | NULL, "ov7670", cam->sensor_addr, NULL); |
1957 | if (cam->sensor == NULL) { | 2070 | if (cam->sensor == NULL) { |
1958 | ret = -ENODEV; | 2071 | ret = -ENODEV; |
1959 | goto out_smbus; | 2072 | goto out_smbus; |
1960 | } | 2073 | } |
2074 | |||
1961 | ret = cafe_cam_init(cam); | 2075 | ret = cafe_cam_init(cam); |
1962 | if (ret) | 2076 | if (ret) |
1963 | goto out_smbus; | 2077 | goto out_smbus; |
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig index e39a9615200..66e9283f599 100644 --- a/drivers/media/video/cpia2/Kconfig +++ b/drivers/media/video/cpia2/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_CPIA2 | 1 | config VIDEO_CPIA2 |
2 | tristate "CPiA2 Video For Linux" | 2 | tristate "CPiA2 Video For Linux" |
3 | depends on VIDEO_DEV && USB && VIDEO_V4L1 | 3 | depends on VIDEO_DEV && USB && VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | This is the video4linux driver for cameras based on Vision's CPiA2 | 5 | This is the video4linux driver for cameras based on Vision's CPiA2 |
6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 | 6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 |
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h index 8d2dfc12882..916c13d5cf7 100644 --- a/drivers/media/video/cpia2/cpia2.h +++ b/drivers/media/video/cpia2/cpia2.h | |||
@@ -32,7 +32,7 @@ | |||
32 | #define __CPIA2_H__ | 32 | #define __CPIA2_H__ |
33 | 33 | ||
34 | #include <linux/version.h> | 34 | #include <linux/version.h> |
35 | #include <linux/videodev.h> | 35 | #include <linux/videodev2.h> |
36 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
@@ -43,7 +43,7 @@ | |||
43 | /* define for verbose debug output */ | 43 | /* define for verbose debug output */ |
44 | //#define _CPIA2_DEBUG_ | 44 | //#define _CPIA2_DEBUG_ |
45 | 45 | ||
46 | #define CPIA2_MAJ_VER 2 | 46 | #define CPIA2_MAJ_VER 3 |
47 | #define CPIA2_MIN_VER 0 | 47 | #define CPIA2_MIN_VER 0 |
48 | #define CPIA2_PATCH_VER 0 | 48 | #define CPIA2_PATCH_VER 0 |
49 | 49 | ||
@@ -396,8 +396,8 @@ struct camera_data { | |||
396 | /* v4l */ | 396 | /* v4l */ |
397 | int video_size; /* VIDEO_SIZE_ */ | 397 | int video_size; /* VIDEO_SIZE_ */ |
398 | struct video_device *vdev; /* v4l videodev */ | 398 | struct video_device *vdev; /* v4l videodev */ |
399 | struct video_picture vp; /* v4l camera settings */ | 399 | u32 width; |
400 | struct video_window vw; /* v4l capture area */ | 400 | u32 height; /* Its size */ |
401 | __u32 pixelformat; /* Format fourcc */ | 401 | __u32 pixelformat; /* Format fourcc */ |
402 | 402 | ||
403 | /* USB */ | 403 | /* USB */ |
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index 1cc0df8beff..9606bc01b80 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/drivers/media/video/cpia2/cpia2_core.c | |||
@@ -1058,44 +1058,44 @@ static int set_vw_size(struct camera_data *cam, int size) | |||
1058 | DBG("Setting size to VGA\n"); | 1058 | DBG("Setting size to VGA\n"); |
1059 | cam->params.roi.width = STV_IMAGE_VGA_COLS; | 1059 | cam->params.roi.width = STV_IMAGE_VGA_COLS; |
1060 | cam->params.roi.height = STV_IMAGE_VGA_ROWS; | 1060 | cam->params.roi.height = STV_IMAGE_VGA_ROWS; |
1061 | cam->vw.width = STV_IMAGE_VGA_COLS; | 1061 | cam->width = STV_IMAGE_VGA_COLS; |
1062 | cam->vw.height = STV_IMAGE_VGA_ROWS; | 1062 | cam->height = STV_IMAGE_VGA_ROWS; |
1063 | break; | 1063 | break; |
1064 | case VIDEOSIZE_CIF: | 1064 | case VIDEOSIZE_CIF: |
1065 | DBG("Setting size to CIF\n"); | 1065 | DBG("Setting size to CIF\n"); |
1066 | cam->params.roi.width = STV_IMAGE_CIF_COLS; | 1066 | cam->params.roi.width = STV_IMAGE_CIF_COLS; |
1067 | cam->params.roi.height = STV_IMAGE_CIF_ROWS; | 1067 | cam->params.roi.height = STV_IMAGE_CIF_ROWS; |
1068 | cam->vw.width = STV_IMAGE_CIF_COLS; | 1068 | cam->width = STV_IMAGE_CIF_COLS; |
1069 | cam->vw.height = STV_IMAGE_CIF_ROWS; | 1069 | cam->height = STV_IMAGE_CIF_ROWS; |
1070 | break; | 1070 | break; |
1071 | case VIDEOSIZE_QVGA: | 1071 | case VIDEOSIZE_QVGA: |
1072 | DBG("Setting size to QVGA\n"); | 1072 | DBG("Setting size to QVGA\n"); |
1073 | cam->params.roi.width = STV_IMAGE_QVGA_COLS; | 1073 | cam->params.roi.width = STV_IMAGE_QVGA_COLS; |
1074 | cam->params.roi.height = STV_IMAGE_QVGA_ROWS; | 1074 | cam->params.roi.height = STV_IMAGE_QVGA_ROWS; |
1075 | cam->vw.width = STV_IMAGE_QVGA_COLS; | 1075 | cam->width = STV_IMAGE_QVGA_COLS; |
1076 | cam->vw.height = STV_IMAGE_QVGA_ROWS; | 1076 | cam->height = STV_IMAGE_QVGA_ROWS; |
1077 | break; | 1077 | break; |
1078 | case VIDEOSIZE_288_216: | 1078 | case VIDEOSIZE_288_216: |
1079 | cam->params.roi.width = 288; | 1079 | cam->params.roi.width = 288; |
1080 | cam->params.roi.height = 216; | 1080 | cam->params.roi.height = 216; |
1081 | cam->vw.width = 288; | 1081 | cam->width = 288; |
1082 | cam->vw.height = 216; | 1082 | cam->height = 216; |
1083 | break; | 1083 | break; |
1084 | case VIDEOSIZE_256_192: | 1084 | case VIDEOSIZE_256_192: |
1085 | cam->vw.width = 256; | 1085 | cam->width = 256; |
1086 | cam->vw.height = 192; | 1086 | cam->height = 192; |
1087 | cam->params.roi.width = 256; | 1087 | cam->params.roi.width = 256; |
1088 | cam->params.roi.height = 192; | 1088 | cam->params.roi.height = 192; |
1089 | break; | 1089 | break; |
1090 | case VIDEOSIZE_224_168: | 1090 | case VIDEOSIZE_224_168: |
1091 | cam->vw.width = 224; | 1091 | cam->width = 224; |
1092 | cam->vw.height = 168; | 1092 | cam->height = 168; |
1093 | cam->params.roi.width = 224; | 1093 | cam->params.roi.width = 224; |
1094 | cam->params.roi.height = 168; | 1094 | cam->params.roi.height = 168; |
1095 | break; | 1095 | break; |
1096 | case VIDEOSIZE_192_144: | 1096 | case VIDEOSIZE_192_144: |
1097 | cam->vw.width = 192; | 1097 | cam->width = 192; |
1098 | cam->vw.height = 144; | 1098 | cam->height = 144; |
1099 | cam->params.roi.width = 192; | 1099 | cam->params.roi.width = 192; |
1100 | cam->params.roi.height = 144; | 1100 | cam->params.roi.height = 144; |
1101 | break; | 1101 | break; |
@@ -1103,8 +1103,8 @@ static int set_vw_size(struct camera_data *cam, int size) | |||
1103 | DBG("Setting size to QCIF\n"); | 1103 | DBG("Setting size to QCIF\n"); |
1104 | cam->params.roi.width = STV_IMAGE_QCIF_COLS; | 1104 | cam->params.roi.width = STV_IMAGE_QCIF_COLS; |
1105 | cam->params.roi.height = STV_IMAGE_QCIF_ROWS; | 1105 | cam->params.roi.height = STV_IMAGE_QCIF_ROWS; |
1106 | cam->vw.width = STV_IMAGE_QCIF_COLS; | 1106 | cam->width = STV_IMAGE_QCIF_COLS; |
1107 | cam->vw.height = STV_IMAGE_QCIF_ROWS; | 1107 | cam->height = STV_IMAGE_QCIF_ROWS; |
1108 | break; | 1108 | break; |
1109 | default: | 1109 | default: |
1110 | retval = -EINVAL; | 1110 | retval = -EINVAL; |
@@ -2224,23 +2224,8 @@ static void reset_camera_struct(struct camera_data *cam) | |||
2224 | cam->params.roi.height = STV_IMAGE_CIF_ROWS; | 2224 | cam->params.roi.height = STV_IMAGE_CIF_ROWS; |
2225 | } | 2225 | } |
2226 | 2226 | ||
2227 | /*** | 2227 | cam->width = cam->params.roi.width; |
2228 | * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP | 2228 | cam->height = cam->params.roi.height; |
2229 | * Ioctl. Here, just do the window and picture stucts. | ||
2230 | ***/ | ||
2231 | cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */ | ||
2232 | cam->vp.brightness = (u16) cam->params.color_params.brightness * 256; | ||
2233 | cam->vp.colour = (u16) cam->params.color_params.saturation * 256; | ||
2234 | cam->vp.contrast = (u16) cam->params.color_params.contrast * 256; | ||
2235 | |||
2236 | cam->vw.x = 0; | ||
2237 | cam->vw.y = 0; | ||
2238 | cam->vw.width = cam->params.roi.width; | ||
2239 | cam->vw.height = cam->params.roi.height; | ||
2240 | cam->vw.flags = 0; | ||
2241 | cam->vw.clipcount = 0; | ||
2242 | |||
2243 | return; | ||
2244 | } | 2229 | } |
2245 | 2230 | ||
2246 | /****************************************************************************** | 2231 | /****************************************************************************** |
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 5520789854d..46b433bbf2c 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/videodev.h> | 40 | #include <linux/videodev2.h> |
41 | #include <linux/stringify.h> | 41 | #include <linux/stringify.h> |
42 | #include <media/v4l2-ioctl.h> | 42 | #include <media/v4l2-ioctl.h> |
43 | 43 | ||
@@ -391,113 +391,6 @@ static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct * | |||
391 | } | 391 | } |
392 | 392 | ||
393 | 393 | ||
394 | /****************************************************************************** | ||
395 | * | ||
396 | * ioctl_cap_query | ||
397 | * | ||
398 | *****************************************************************************/ | ||
399 | static int ioctl_cap_query(void *arg, struct camera_data *cam) | ||
400 | { | ||
401 | struct video_capability *vc; | ||
402 | int retval = 0; | ||
403 | vc = arg; | ||
404 | |||
405 | if (cam->params.pnp_id.product == 0x151) | ||
406 | strcpy(vc->name, "QX5 Microscope"); | ||
407 | else | ||
408 | strcpy(vc->name, "CPiA2 Camera"); | ||
409 | |||
410 | vc->type = VID_TYPE_CAPTURE | VID_TYPE_MJPEG_ENCODER; | ||
411 | vc->channels = 1; | ||
412 | vc->audios = 0; | ||
413 | vc->minwidth = 176; /* VIDEOSIZE_QCIF */ | ||
414 | vc->minheight = 144; | ||
415 | switch (cam->params.version.sensor_flags) { | ||
416 | case CPIA2_VP_SENSOR_FLAGS_500: | ||
417 | vc->maxwidth = STV_IMAGE_VGA_COLS; | ||
418 | vc->maxheight = STV_IMAGE_VGA_ROWS; | ||
419 | break; | ||
420 | case CPIA2_VP_SENSOR_FLAGS_410: | ||
421 | vc->maxwidth = STV_IMAGE_CIF_COLS; | ||
422 | vc->maxheight = STV_IMAGE_CIF_ROWS; | ||
423 | break; | ||
424 | default: | ||
425 | return -EINVAL; | ||
426 | } | ||
427 | |||
428 | return retval; | ||
429 | } | ||
430 | |||
431 | /****************************************************************************** | ||
432 | * | ||
433 | * ioctl_get_channel | ||
434 | * | ||
435 | *****************************************************************************/ | ||
436 | static int ioctl_get_channel(void *arg) | ||
437 | { | ||
438 | int retval = 0; | ||
439 | struct video_channel *v; | ||
440 | v = arg; | ||
441 | |||
442 | if (v->channel != 0) | ||
443 | return -EINVAL; | ||
444 | |||
445 | v->channel = 0; | ||
446 | strcpy(v->name, "Camera"); | ||
447 | v->tuners = 0; | ||
448 | v->flags = 0; | ||
449 | v->type = VIDEO_TYPE_CAMERA; | ||
450 | v->norm = 0; | ||
451 | |||
452 | return retval; | ||
453 | } | ||
454 | |||
455 | /****************************************************************************** | ||
456 | * | ||
457 | * ioctl_set_channel | ||
458 | * | ||
459 | *****************************************************************************/ | ||
460 | static int ioctl_set_channel(void *arg) | ||
461 | { | ||
462 | struct video_channel *v; | ||
463 | int retval = 0; | ||
464 | v = arg; | ||
465 | |||
466 | if (retval == 0 && v->channel != 0) | ||
467 | retval = -EINVAL; | ||
468 | |||
469 | return retval; | ||
470 | } | ||
471 | |||
472 | /****************************************************************************** | ||
473 | * | ||
474 | * ioctl_set_image_prop | ||
475 | * | ||
476 | *****************************************************************************/ | ||
477 | static int ioctl_set_image_prop(void *arg, struct camera_data *cam) | ||
478 | { | ||
479 | struct video_picture *vp; | ||
480 | int retval = 0; | ||
481 | vp = arg; | ||
482 | |||
483 | /* brightness, color, contrast need no check 0-65535 */ | ||
484 | memcpy(&cam->vp, vp, sizeof(*vp)); | ||
485 | |||
486 | /* update cam->params.colorParams */ | ||
487 | cam->params.color_params.brightness = vp->brightness / 256; | ||
488 | cam->params.color_params.saturation = vp->colour / 256; | ||
489 | cam->params.color_params.contrast = vp->contrast / 256; | ||
490 | |||
491 | DBG("Requested params: bright 0x%X, sat 0x%X, contrast 0x%X\n", | ||
492 | cam->params.color_params.brightness, | ||
493 | cam->params.color_params.saturation, | ||
494 | cam->params.color_params.contrast); | ||
495 | |||
496 | cpia2_set_color_params(cam); | ||
497 | |||
498 | return retval; | ||
499 | } | ||
500 | |||
501 | static int sync(struct camera_data *cam, int frame_nr) | 394 | static int sync(struct camera_data *cam, int frame_nr) |
502 | { | 395 | { |
503 | struct framebuf *frame = &cam->buffers[frame_nr]; | 396 | struct framebuf *frame = &cam->buffers[frame_nr]; |
@@ -526,61 +419,10 @@ static int sync(struct camera_data *cam, int frame_nr) | |||
526 | 419 | ||
527 | /****************************************************************************** | 420 | /****************************************************************************** |
528 | * | 421 | * |
529 | * ioctl_set_window_size | ||
530 | * | ||
531 | *****************************************************************************/ | ||
532 | static int ioctl_set_window_size(void *arg, struct camera_data *cam, | ||
533 | struct cpia2_fh *fh) | ||
534 | { | ||
535 | /* copy_from_user, check validity, copy to internal structure */ | ||
536 | struct video_window *vw; | ||
537 | int frame, err; | ||
538 | vw = arg; | ||
539 | |||
540 | if (vw->clipcount != 0) /* clipping not supported */ | ||
541 | return -EINVAL; | ||
542 | |||
543 | if (vw->clips != NULL) /* clipping not supported */ | ||
544 | return -EINVAL; | ||
545 | |||
546 | /* Ensure that only this process can change the format. */ | ||
547 | err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); | ||
548 | if(err != 0) | ||
549 | return err; | ||
550 | |||
551 | cam->pixelformat = V4L2_PIX_FMT_JPEG; | ||
552 | |||
553 | /* Be sure to supply the Huffman tables, this isn't MJPEG */ | ||
554 | cam->params.compression.inhibit_htables = 0; | ||
555 | |||
556 | /* we set the video window to something smaller or equal to what | ||
557 | * is requested by the user??? | ||
558 | */ | ||
559 | DBG("Requested width = %d, height = %d\n", vw->width, vw->height); | ||
560 | if (vw->width != cam->vw.width || vw->height != cam->vw.height) { | ||
561 | cam->vw.width = vw->width; | ||
562 | cam->vw.height = vw->height; | ||
563 | cam->params.roi.width = vw->width; | ||
564 | cam->params.roi.height = vw->height; | ||
565 | cpia2_set_format(cam); | ||
566 | } | ||
567 | |||
568 | for (frame = 0; frame < cam->num_frames; ++frame) { | ||
569 | if (cam->buffers[frame].status == FRAME_READING) | ||
570 | if ((err = sync(cam, frame)) < 0) | ||
571 | return err; | ||
572 | |||
573 | cam->buffers[frame].status = FRAME_EMPTY; | ||
574 | } | ||
575 | |||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | /****************************************************************************** | ||
580 | * | ||
581 | * ioctl_get_mbuf | 422 | * ioctl_get_mbuf |
582 | * | 423 | * |
583 | *****************************************************************************/ | 424 | *****************************************************************************/ |
425 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
584 | static int ioctl_get_mbuf(void *arg, struct camera_data *cam) | 426 | static int ioctl_get_mbuf(void *arg, struct camera_data *cam) |
585 | { | 427 | { |
586 | struct video_mbuf *vm; | 428 | struct video_mbuf *vm; |
@@ -595,66 +437,7 @@ static int ioctl_get_mbuf(void *arg, struct camera_data *cam) | |||
595 | 437 | ||
596 | return 0; | 438 | return 0; |
597 | } | 439 | } |
598 | 440 | #endif | |
599 | /****************************************************************************** | ||
600 | * | ||
601 | * ioctl_mcapture | ||
602 | * | ||
603 | *****************************************************************************/ | ||
604 | static int ioctl_mcapture(void *arg, struct camera_data *cam, | ||
605 | struct cpia2_fh *fh) | ||
606 | { | ||
607 | struct video_mmap *vm; | ||
608 | int video_size, err; | ||
609 | vm = arg; | ||
610 | |||
611 | if (vm->frame < 0 || vm->frame >= cam->num_frames) | ||
612 | return -EINVAL; | ||
613 | |||
614 | /* set video size */ | ||
615 | video_size = cpia2_match_video_size(vm->width, vm->height); | ||
616 | if (cam->video_size < 0) { | ||
617 | return -EINVAL; | ||
618 | } | ||
619 | |||
620 | /* Ensure that only this process can change the format. */ | ||
621 | err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD); | ||
622 | if(err != 0) | ||
623 | return err; | ||
624 | |||
625 | if (video_size != cam->video_size) { | ||
626 | cam->video_size = video_size; | ||
627 | cam->params.roi.width = vm->width; | ||
628 | cam->params.roi.height = vm->height; | ||
629 | cpia2_set_format(cam); | ||
630 | } | ||
631 | |||
632 | if (cam->buffers[vm->frame].status == FRAME_READING) | ||
633 | if ((err=sync(cam, vm->frame)) < 0) | ||
634 | return err; | ||
635 | |||
636 | cam->buffers[vm->frame].status = FRAME_EMPTY; | ||
637 | |||
638 | return cpia2_usb_stream_start(cam,cam->params.camera_state.stream_mode); | ||
639 | } | ||
640 | |||
641 | /****************************************************************************** | ||
642 | * | ||
643 | * ioctl_sync | ||
644 | * | ||
645 | *****************************************************************************/ | ||
646 | static int ioctl_sync(void *arg, struct camera_data *cam) | ||
647 | { | ||
648 | int frame; | ||
649 | |||
650 | frame = *(int*)arg; | ||
651 | |||
652 | if (frame < 0 || frame >= cam->num_frames) | ||
653 | return -EINVAL; | ||
654 | |||
655 | return sync(cam, frame); | ||
656 | } | ||
657 | |||
658 | 441 | ||
659 | /****************************************************************************** | 442 | /****************************************************************************** |
660 | * | 443 | * |
@@ -897,10 +680,10 @@ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) | |||
897 | */ | 680 | */ |
898 | DBG("Requested width = %d, height = %d\n", | 681 | DBG("Requested width = %d, height = %d\n", |
899 | f->fmt.pix.width, f->fmt.pix.height); | 682 | f->fmt.pix.width, f->fmt.pix.height); |
900 | if (f->fmt.pix.width != cam->vw.width || | 683 | if (f->fmt.pix.width != cam->width || |
901 | f->fmt.pix.height != cam->vw.height) { | 684 | f->fmt.pix.height != cam->height) { |
902 | cam->vw.width = f->fmt.pix.width; | 685 | cam->width = f->fmt.pix.width; |
903 | cam->vw.height = f->fmt.pix.height; | 686 | cam->height = f->fmt.pix.height; |
904 | cam->params.roi.width = f->fmt.pix.width; | 687 | cam->params.roi.width = f->fmt.pix.width; |
905 | cam->params.roi.height = f->fmt.pix.height; | 688 | cam->params.roi.height = f->fmt.pix.height; |
906 | cpia2_set_format(cam); | 689 | cpia2_set_format(cam); |
@@ -932,8 +715,8 @@ static int ioctl_get_fmt(void *arg,struct camera_data *cam) | |||
932 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 715 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
933 | return -EINVAL; | 716 | return -EINVAL; |
934 | 717 | ||
935 | f->fmt.pix.width = cam->vw.width; | 718 | f->fmt.pix.width = cam->width; |
936 | f->fmt.pix.height = cam->vw.height; | 719 | f->fmt.pix.height = cam->height; |
937 | f->fmt.pix.pixelformat = cam->pixelformat; | 720 | f->fmt.pix.pixelformat = cam->pixelformat; |
938 | f->fmt.pix.field = V4L2_FIELD_NONE; | 721 | f->fmt.pix.field = V4L2_FIELD_NONE; |
939 | f->fmt.pix.bytesperline = 0; | 722 | f->fmt.pix.bytesperline = 0; |
@@ -962,12 +745,12 @@ static int ioctl_cropcap(void *arg,struct camera_data *cam) | |||
962 | 745 | ||
963 | c->bounds.left = 0; | 746 | c->bounds.left = 0; |
964 | c->bounds.top = 0; | 747 | c->bounds.top = 0; |
965 | c->bounds.width = cam->vw.width; | 748 | c->bounds.width = cam->width; |
966 | c->bounds.height = cam->vw.height; | 749 | c->bounds.height = cam->height; |
967 | c->defrect.left = 0; | 750 | c->defrect.left = 0; |
968 | c->defrect.top = 0; | 751 | c->defrect.top = 0; |
969 | c->defrect.width = cam->vw.width; | 752 | c->defrect.width = cam->width; |
970 | c->defrect.height = cam->vw.height; | 753 | c->defrect.height = cam->height; |
971 | c->pixelaspect.numerator = 1; | 754 | c->pixelaspect.numerator = 1; |
972 | c->pixelaspect.denominator = 1; | 755 | c->pixelaspect.denominator = 1; |
973 | 756 | ||
@@ -1587,8 +1370,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1587 | 1370 | ||
1588 | /* Priority check */ | 1371 | /* Priority check */ |
1589 | switch (cmd) { | 1372 | switch (cmd) { |
1590 | case VIDIOCSWIN: | ||
1591 | case VIDIOCMCAPTURE: | ||
1592 | case VIDIOC_S_FMT: | 1373 | case VIDIOC_S_FMT: |
1593 | { | 1374 | { |
1594 | struct cpia2_fh *fh = file->private_data; | 1375 | struct cpia2_fh *fh = file->private_data; |
@@ -1599,8 +1380,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1599 | } | 1380 | } |
1600 | break; | 1381 | break; |
1601 | } | 1382 | } |
1383 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1602 | case VIDIOCGMBUF: | 1384 | case VIDIOCGMBUF: |
1603 | case VIDIOCSYNC: | ||
1604 | { | 1385 | { |
1605 | struct cpia2_fh *fh = file->private_data; | 1386 | struct cpia2_fh *fh = file->private_data; |
1606 | if(fh->prio != V4L2_PRIORITY_RECORD) { | 1387 | if(fh->prio != V4L2_PRIORITY_RECORD) { |
@@ -1609,68 +1390,21 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1609 | } | 1390 | } |
1610 | break; | 1391 | break; |
1611 | } | 1392 | } |
1393 | #endif | ||
1612 | default: | 1394 | default: |
1613 | break; | 1395 | break; |
1614 | } | 1396 | } |
1615 | 1397 | ||
1616 | switch (cmd) { | 1398 | switch (cmd) { |
1617 | case VIDIOCGCAP: /* query capabilities */ | ||
1618 | retval = ioctl_cap_query(arg, cam); | ||
1619 | break; | ||
1620 | |||
1621 | case VIDIOCGCHAN: /* get video source - we are a camera, nothing else */ | ||
1622 | retval = ioctl_get_channel(arg); | ||
1623 | break; | ||
1624 | case VIDIOCSCHAN: /* set video source - we are a camera, nothing else */ | ||
1625 | retval = ioctl_set_channel(arg); | ||
1626 | break; | ||
1627 | case VIDIOCGPICT: /* image properties */ | ||
1628 | memcpy(arg, &cam->vp, sizeof(struct video_picture)); | ||
1629 | break; | ||
1630 | case VIDIOCSPICT: | ||
1631 | retval = ioctl_set_image_prop(arg, cam); | ||
1632 | break; | ||
1633 | case VIDIOCGWIN: /* get/set capture window */ | ||
1634 | memcpy(arg, &cam->vw, sizeof(struct video_window)); | ||
1635 | break; | ||
1636 | case VIDIOCSWIN: | ||
1637 | retval = ioctl_set_window_size(arg, cam, file->private_data); | ||
1638 | break; | ||
1639 | case VIDIOCGMBUF: /* mmap interface */ | ||
1640 | retval = ioctl_get_mbuf(arg, cam); | ||
1641 | break; | ||
1642 | case VIDIOCMCAPTURE: | ||
1643 | retval = ioctl_mcapture(arg, cam, file->private_data); | ||
1644 | break; | ||
1645 | case VIDIOCSYNC: | ||
1646 | retval = ioctl_sync(arg, cam); | ||
1647 | break; | ||
1648 | /* pointless to implement overlay with this camera */ | ||
1649 | case VIDIOCCAPTURE: | ||
1650 | case VIDIOCGFBUF: | ||
1651 | case VIDIOCSFBUF: | ||
1652 | case VIDIOCKEY: | ||
1653 | retval = -EINVAL; | ||
1654 | break; | ||
1655 | |||
1656 | /* tuner interface - we have none */ | ||
1657 | case VIDIOCGTUNER: | ||
1658 | case VIDIOCSTUNER: | ||
1659 | case VIDIOCGFREQ: | ||
1660 | case VIDIOCSFREQ: | ||
1661 | retval = -EINVAL; | ||
1662 | break; | ||
1663 | |||
1664 | /* audio interface - we have none */ | ||
1665 | case VIDIOCGAUDIO: | ||
1666 | case VIDIOCSAUDIO: | ||
1667 | retval = -EINVAL; | ||
1668 | break; | ||
1669 | |||
1670 | /* CPIA2 extension to Video4Linux API */ | 1399 | /* CPIA2 extension to Video4Linux API */ |
1671 | case CPIA2_IOC_SET_GPIO: | 1400 | case CPIA2_IOC_SET_GPIO: |
1672 | retval = ioctl_set_gpio(arg, cam); | 1401 | retval = ioctl_set_gpio(arg, cam); |
1673 | break; | 1402 | break; |
1403 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1404 | case VIDIOCGMBUF: /* mmap interface */ | ||
1405 | retval = ioctl_get_mbuf(arg, cam); | ||
1406 | break; | ||
1407 | #endif | ||
1674 | case VIDIOC_QUERYCAP: | 1408 | case VIDIOC_QUERYCAP: |
1675 | retval = ioctl_querycap(arg,cam); | 1409 | retval = ioctl_querycap(arg,cam); |
1676 | break; | 1410 | break; |
@@ -1874,21 +1608,8 @@ static int cpia2_mmap(struct file *file, struct vm_area_struct *area) | |||
1874 | *****************************************************************************/ | 1608 | *****************************************************************************/ |
1875 | static void reset_camera_struct_v4l(struct camera_data *cam) | 1609 | static void reset_camera_struct_v4l(struct camera_data *cam) |
1876 | { | 1610 | { |
1877 | /*** | 1611 | cam->width = cam->params.roi.width; |
1878 | * Fill in the v4l structures. video_cap is filled in inside the VIDIOCCAP | 1612 | cam->height = cam->params.roi.height; |
1879 | * Ioctl. Here, just do the window and picture stucts. | ||
1880 | ***/ | ||
1881 | cam->vp.palette = (u16) VIDEO_PALETTE_RGB24; /* Is this right? */ | ||
1882 | cam->vp.brightness = (u16) cam->params.color_params.brightness * 256; | ||
1883 | cam->vp.colour = (u16) cam->params.color_params.saturation * 256; | ||
1884 | cam->vp.contrast = (u16) cam->params.color_params.contrast * 256; | ||
1885 | |||
1886 | cam->vw.x = 0; | ||
1887 | cam->vw.y = 0; | ||
1888 | cam->vw.width = cam->params.roi.width; | ||
1889 | cam->vw.height = cam->params.roi.height; | ||
1890 | cam->vw.flags = 0; | ||
1891 | cam->vw.clipcount = 0; | ||
1892 | 1613 | ||
1893 | cam->frame_size = buffer_size; | 1614 | cam->frame_size = buffer_size; |
1894 | cam->num_frames = num_buffers; | 1615 | cam->num_frames = num_buffers; |
@@ -1902,13 +1623,12 @@ static void reset_camera_struct_v4l(struct camera_data *cam) | |||
1902 | 1623 | ||
1903 | cam->pixelformat = V4L2_PIX_FMT_JPEG; | 1624 | cam->pixelformat = V4L2_PIX_FMT_JPEG; |
1904 | v4l2_prio_init(&cam->prio); | 1625 | v4l2_prio_init(&cam->prio); |
1905 | return; | ||
1906 | } | 1626 | } |
1907 | 1627 | ||
1908 | /*** | 1628 | /*** |
1909 | * The v4l video device structure initialized for this device | 1629 | * The v4l video device structure initialized for this device |
1910 | ***/ | 1630 | ***/ |
1911 | static const struct v4l2_file_operations fops_template = { | 1631 | static const struct v4l2_file_operations cpia2_fops = { |
1912 | .owner = THIS_MODULE, | 1632 | .owner = THIS_MODULE, |
1913 | .open = cpia2_open, | 1633 | .open = cpia2_open, |
1914 | .release = cpia2_close, | 1634 | .release = cpia2_close, |
@@ -1920,9 +1640,9 @@ static const struct v4l2_file_operations fops_template = { | |||
1920 | 1640 | ||
1921 | static struct video_device cpia2_template = { | 1641 | static struct video_device cpia2_template = { |
1922 | /* I could not find any place for the old .initialize initializer?? */ | 1642 | /* I could not find any place for the old .initialize initializer?? */ |
1923 | .name= "CPiA2 Camera", | 1643 | .name = "CPiA2 Camera", |
1924 | .fops= &fops_template, | 1644 | .fops = &cpia2_fops, |
1925 | .release= video_device_release, | 1645 | .release = video_device_release, |
1926 | }; | 1646 | }; |
1927 | 1647 | ||
1928 | /****************************************************************************** | 1648 | /****************************************************************************** |
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h index d58097ce0d5..f66691fe5a3 100644 --- a/drivers/media/video/cpia2/cpia2dev.h +++ b/drivers/media/video/cpia2/cpia2dev.h | |||
@@ -29,14 +29,14 @@ | |||
29 | #ifndef CPIA2_DEV_HEADER | 29 | #ifndef CPIA2_DEV_HEADER |
30 | #define CPIA2_DEV_HEADER | 30 | #define CPIA2_DEV_HEADER |
31 | 31 | ||
32 | #include <linux/videodev.h> | 32 | #include <linux/videodev2.h> |
33 | 33 | ||
34 | /*** | 34 | /*** |
35 | * The following defines are ioctl numbers based on video4linux private ioctls, | 35 | * The following defines are ioctl numbers based on video4linux private ioctls, |
36 | * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int | 36 | * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int |
37 | * args | 37 | * args |
38 | */ | 38 | */ |
39 | #define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOCPRIVATE + 17, __u32) | 39 | #define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOC_PRIVATE + 17, __u32) |
40 | 40 | ||
41 | /* V4L2 driver specific controls */ | 41 | /* V4L2 driver specific controls */ |
42 | #define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0) | 42 | #define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0) |
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 8362db509e2..9358fe77e56 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <media/v4l2-device.h> | 26 | #include <media/v4l2-device.h> |
27 | #include <media/v4l2-chip-ident.h> | 27 | #include <media/v4l2-chip-ident.h> |
28 | #include <media/v4l2-i2c-drv.h> | ||
29 | 28 | ||
30 | MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC"); | 29 | MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC"); |
31 | MODULE_AUTHOR("Hans Verkuil"); | 30 | MODULE_AUTHOR("Hans Verkuil"); |
@@ -209,9 +208,25 @@ static const struct i2c_device_id cs5345_id[] = { | |||
209 | }; | 208 | }; |
210 | MODULE_DEVICE_TABLE(i2c, cs5345_id); | 209 | MODULE_DEVICE_TABLE(i2c, cs5345_id); |
211 | 210 | ||
212 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 211 | static struct i2c_driver cs5345_driver = { |
213 | .name = "cs5345", | 212 | .driver = { |
214 | .probe = cs5345_probe, | 213 | .owner = THIS_MODULE, |
215 | .remove = cs5345_remove, | 214 | .name = "cs5345", |
216 | .id_table = cs5345_id, | 215 | }, |
216 | .probe = cs5345_probe, | ||
217 | .remove = cs5345_remove, | ||
218 | .id_table = cs5345_id, | ||
217 | }; | 219 | }; |
220 | |||
221 | static __init int init_cs5345(void) | ||
222 | { | ||
223 | return i2c_add_driver(&cs5345_driver); | ||
224 | } | ||
225 | |||
226 | static __exit void exit_cs5345(void) | ||
227 | { | ||
228 | i2c_del_driver(&cs5345_driver); | ||
229 | } | ||
230 | |||
231 | module_init(init_cs5345); | ||
232 | module_exit(exit_cs5345); | ||
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index cc9e84d75ea..d93e5ab45fd 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <media/v4l2-device.h> | 30 | #include <media/v4l2-device.h> |
31 | #include <media/v4l2-chip-ident.h> | 31 | #include <media/v4l2-chip-ident.h> |
32 | #include <media/v4l2-ctrls.h> | 32 | #include <media/v4l2-ctrls.h> |
33 | #include <media/v4l2-i2c-drv.h> | ||
34 | 33 | ||
35 | MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); | 34 | MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); |
36 | MODULE_AUTHOR("Martin Vaughan"); | 35 | MODULE_AUTHOR("Martin Vaughan"); |
@@ -239,9 +238,25 @@ static const struct i2c_device_id cs53l32a_id[] = { | |||
239 | }; | 238 | }; |
240 | MODULE_DEVICE_TABLE(i2c, cs53l32a_id); | 239 | MODULE_DEVICE_TABLE(i2c, cs53l32a_id); |
241 | 240 | ||
242 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 241 | static struct i2c_driver cs53l32a_driver = { |
243 | .name = "cs53l32a", | 242 | .driver = { |
244 | .remove = cs53l32a_remove, | 243 | .owner = THIS_MODULE, |
245 | .probe = cs53l32a_probe, | 244 | .name = "cs53l32a", |
246 | .id_table = cs53l32a_id, | 245 | }, |
246 | .probe = cs53l32a_probe, | ||
247 | .remove = cs53l32a_remove, | ||
248 | .id_table = cs53l32a_id, | ||
247 | }; | 249 | }; |
250 | |||
251 | static __init int init_cs53l32a(void) | ||
252 | { | ||
253 | return i2c_add_driver(&cs53l32a_driver); | ||
254 | } | ||
255 | |||
256 | static __exit void exit_cs53l32a(void) | ||
257 | { | ||
258 | i2c_del_driver(&cs53l32a_driver); | ||
259 | } | ||
260 | |||
261 | module_init(init_cs53l32a); | ||
262 | module_exit(exit_cs53l32a); | ||
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 9bc51a99376..77be58c1096 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -674,18 +674,25 @@ static inline int cx18_raw_vbi(const struct cx18 *cx) | |||
674 | 674 | ||
675 | /* Call the specified callback for all subdevs with a grp_id bit matching the | 675 | /* Call the specified callback for all subdevs with a grp_id bit matching the |
676 | * mask in hw (if 0, then match them all). Ignore any errors. */ | 676 | * mask in hw (if 0, then match them all). Ignore any errors. */ |
677 | #define cx18_call_hw(cx, hw, o, f, args...) \ | 677 | #define cx18_call_hw(cx, hw, o, f, args...) \ |
678 | __v4l2_device_call_subdevs(&(cx)->v4l2_dev, \ | 678 | do { \ |
679 | !(hw) || (sd->grp_id & (hw)), o, f , ##args) | 679 | struct v4l2_subdev *__sd; \ |
680 | __v4l2_device_call_subdevs_p(&(cx)->v4l2_dev, __sd, \ | ||
681 | !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \ | ||
682 | } while (0) | ||
680 | 683 | ||
681 | #define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args) | 684 | #define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args) |
682 | 685 | ||
683 | /* Call the specified callback for all subdevs with a grp_id bit matching the | 686 | /* Call the specified callback for all subdevs with a grp_id bit matching the |
684 | * mask in hw (if 0, then match them all). If the callback returns an error | 687 | * mask in hw (if 0, then match them all). If the callback returns an error |
685 | * other than 0 or -ENOIOCTLCMD, then return with that error code. */ | 688 | * other than 0 or -ENOIOCTLCMD, then return with that error code. */ |
686 | #define cx18_call_hw_err(cx, hw, o, f, args...) \ | 689 | #define cx18_call_hw_err(cx, hw, o, f, args...) \ |
687 | __v4l2_device_call_subdevs_until_err( \ | 690 | ({ \ |
688 | &(cx)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) | 691 | struct v4l2_subdev *__sd; \ |
692 | __v4l2_device_call_subdevs_until_err_p(&(cx)->v4l2_dev, \ | ||
693 | __sd, !(hw) || (__sd->grp_id & (hw)), o, f, \ | ||
694 | ##args); \ | ||
695 | }) | ||
689 | 696 | ||
690 | #define cx18_call_all_err(cx, o, f, args...) \ | 697 | #define cx18_call_all_err(cx, o, f, args...) \ |
691 | cx18_call_hw_err(cx, 0, o, f , ##args) | 698 | cx18_call_hw_err(cx, 0, o, f , ##args) |
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 73ce90c2f57..a09caf88317 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
@@ -71,19 +71,6 @@ static const u8 hw_bus[] = { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* This array should match the CX18_HW_ defines */ | 73 | /* This array should match the CX18_HW_ defines */ |
74 | static const char * const hw_modules[] = { | ||
75 | "tuner", /* CX18_HW_TUNER */ | ||
76 | NULL, /* CX18_HW_TVEEPROM */ | ||
77 | "cs5345", /* CX18_HW_CS5345 */ | ||
78 | NULL, /* CX18_HW_DVB */ | ||
79 | NULL, /* CX18_HW_418_AV */ | ||
80 | NULL, /* CX18_HW_GPIO_MUX */ | ||
81 | NULL, /* CX18_HW_GPIO_RESET_CTRL */ | ||
82 | NULL, /* CX18_HW_Z8F0811_IR_TX_HAUP */ | ||
83 | NULL, /* CX18_HW_Z8F0811_IR_RX_HAUP */ | ||
84 | }; | ||
85 | |||
86 | /* This array should match the CX18_HW_ defines */ | ||
87 | static const char * const hw_devicenames[] = { | 74 | static const char * const hw_devicenames[] = { |
88 | "tuner", | 75 | "tuner", |
89 | "tveeprom", | 76 | "tveeprom", |
@@ -126,7 +113,6 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) | |||
126 | struct v4l2_subdev *sd; | 113 | struct v4l2_subdev *sd; |
127 | int bus = hw_bus[idx]; | 114 | int bus = hw_bus[idx]; |
128 | struct i2c_adapter *adap = &cx->i2c_adap[bus]; | 115 | struct i2c_adapter *adap = &cx->i2c_adap[bus]; |
129 | const char *mod = hw_modules[idx]; | ||
130 | const char *type = hw_devicenames[idx]; | 116 | const char *type = hw_devicenames[idx]; |
131 | u32 hw = 1 << idx; | 117 | u32 hw = 1 << idx; |
132 | 118 | ||
@@ -136,15 +122,15 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) | |||
136 | if (hw == CX18_HW_TUNER) { | 122 | if (hw == CX18_HW_TUNER) { |
137 | /* special tuner group handling */ | 123 | /* special tuner group handling */ |
138 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, | 124 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, |
139 | adap, mod, type, 0, cx->card_i2c->radio); | 125 | adap, NULL, type, 0, cx->card_i2c->radio); |
140 | if (sd != NULL) | 126 | if (sd != NULL) |
141 | sd->grp_id = hw; | 127 | sd->grp_id = hw; |
142 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, | 128 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, |
143 | adap, mod, type, 0, cx->card_i2c->demod); | 129 | adap, NULL, type, 0, cx->card_i2c->demod); |
144 | if (sd != NULL) | 130 | if (sd != NULL) |
145 | sd->grp_id = hw; | 131 | sd->grp_id = hw; |
146 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, | 132 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, |
147 | adap, mod, type, 0, cx->card_i2c->tv); | 133 | adap, NULL, type, 0, cx->card_i2c->tv); |
148 | if (sd != NULL) | 134 | if (sd != NULL) |
149 | sd->grp_id = hw; | 135 | sd->grp_id = hw; |
150 | return sd != NULL ? 0 : -1; | 136 | return sd != NULL ? 0 : -1; |
@@ -158,7 +144,8 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) | |||
158 | return -1; | 144 | return -1; |
159 | 145 | ||
160 | /* It's an I2C device other than an analog tuner or IR chip */ | 146 | /* It's an I2C device other than an analog tuner or IR chip */ |
161 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx], NULL); | 147 | sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, NULL, type, hw_addrs[idx], |
148 | NULL); | ||
162 | if (sd != NULL) | 149 | if (sd != NULL) |
163 | sd->grp_id = hw; | 150 | sd->grp_id = hw; |
164 | return sd != NULL ? 0 : -1; | 151 | return sd != NULL ? 0 : -1; |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index d6792405f8d..7150195740d 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "cx18-av-core.h" | 40 | #include "cx18-av-core.h" |
41 | #include <media/tveeprom.h> | 41 | #include <media/tveeprom.h> |
42 | #include <media/v4l2-chip-ident.h> | 42 | #include <media/v4l2-chip-ident.h> |
43 | #include <linux/i2c-id.h> | ||
44 | 43 | ||
45 | u16 cx18_service2vbi(int type) | 44 | u16 cx18_service2vbi(int type) |
46 | { | 45 | { |
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig index 5ac7eceecec..bb04914983f 100644 --- a/drivers/media/video/cx231xx/Kconfig +++ b/drivers/media/video/cx231xx/Kconfig | |||
@@ -6,6 +6,7 @@ config VIDEO_CX231XX | |||
6 | depends on VIDEO_IR | 6 | depends on VIDEO_IR |
7 | select VIDEOBUF_VMALLOC | 7 | select VIDEOBUF_VMALLOC |
8 | select VIDEO_CX25840 | 8 | select VIDEO_CX25840 |
9 | select VIDEO_CX2341X | ||
9 | 10 | ||
10 | ---help--- | 11 | ---help--- |
11 | This is a video4linux driver for Conexant 231xx USB based TV cards. | 12 | This is a video4linux driver for Conexant 231xx USB based TV cards. |
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile index 6f2b5738448..a6bc4cc5467 100644 --- a/drivers/media/video/cx231xx/Makefile +++ b/drivers/media/video/cx231xx/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \ | 1 | cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \ |
2 | cx231xx-avcore.o cx231xx-pcb-cfg.o cx231xx-vbi.o | 2 | cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o |
3 | 3 | ||
4 | cx231xx-alsa-objs := cx231xx-audio.o | 4 | cx231xx-alsa-objs := cx231xx-audio.o |
5 | 5 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c new file mode 100644 index 00000000000..aab21f3ce47 --- /dev/null +++ b/drivers/media/video/cx231xx/cx231xx-417.c | |||
@@ -0,0 +1,2194 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Support for a cx23417 mpeg encoder via cx231xx host port. | ||
4 | * | ||
5 | * (c) 2004 Jelle Foks <jelle@foks.us> | ||
6 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> | ||
7 | * (c) 2008 Steven Toth <stoth@linuxtv.org> | ||
8 | * - CX23885/7/8 support | ||
9 | * | ||
10 | * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/moduleparam.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/fs.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/device.h> | ||
33 | #include <linux/firmware.h> | ||
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/vmalloc.h> | ||
36 | #include <media/v4l2-common.h> | ||
37 | #include <media/v4l2-ioctl.h> | ||
38 | #include <media/cx2341x.h> | ||
39 | #include <linux/usb.h> | ||
40 | |||
41 | #include "cx231xx.h" | ||
42 | /*#include "cx23885-ioctl.h"*/ | ||
43 | |||
44 | #define CX231xx_FIRM_IMAGE_SIZE 376836 | ||
45 | #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" | ||
46 | |||
47 | /* for polaris ITVC */ | ||
48 | #define ITVC_WRITE_DIR 0x03FDFC00 | ||
49 | #define ITVC_READ_DIR 0x0001FC00 | ||
50 | |||
51 | #define MCI_MEMORY_DATA_BYTE0 0x00 | ||
52 | #define MCI_MEMORY_DATA_BYTE1 0x08 | ||
53 | #define MCI_MEMORY_DATA_BYTE2 0x10 | ||
54 | #define MCI_MEMORY_DATA_BYTE3 0x18 | ||
55 | |||
56 | #define MCI_MEMORY_ADDRESS_BYTE2 0x20 | ||
57 | #define MCI_MEMORY_ADDRESS_BYTE1 0x28 | ||
58 | #define MCI_MEMORY_ADDRESS_BYTE0 0x30 | ||
59 | |||
60 | #define MCI_REGISTER_DATA_BYTE0 0x40 | ||
61 | #define MCI_REGISTER_DATA_BYTE1 0x48 | ||
62 | #define MCI_REGISTER_DATA_BYTE2 0x50 | ||
63 | #define MCI_REGISTER_DATA_BYTE3 0x58 | ||
64 | |||
65 | #define MCI_REGISTER_ADDRESS_BYTE0 0x60 | ||
66 | #define MCI_REGISTER_ADDRESS_BYTE1 0x68 | ||
67 | |||
68 | #define MCI_REGISTER_MODE 0x70 | ||
69 | |||
70 | /* Read and write modes for polaris ITVC */ | ||
71 | #define MCI_MODE_REGISTER_READ 0x000 | ||
72 | #define MCI_MODE_REGISTER_WRITE 0x100 | ||
73 | #define MCI_MODE_MEMORY_READ 0x000 | ||
74 | #define MCI_MODE_MEMORY_WRITE 0x4000 | ||
75 | |||
76 | static unsigned int mpegbufs = 8; | ||
77 | module_param(mpegbufs, int, 0644); | ||
78 | MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32"); | ||
79 | static unsigned int mpeglines = 128; | ||
80 | module_param(mpeglines, int, 0644); | ||
81 | MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32"); | ||
82 | static unsigned int mpeglinesize = 512; | ||
83 | module_param(mpeglinesize, int, 0644); | ||
84 | MODULE_PARM_DESC(mpeglinesize, | ||
85 | "number of bytes in each line of an MPEG buffer, range 512-1024"); | ||
86 | |||
87 | static unsigned int v4l_debug = 1; | ||
88 | module_param(v4l_debug, int, 0644); | ||
89 | MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); | ||
90 | struct cx231xx_dmaqueue *dma_qq; | ||
91 | #define dprintk(level, fmt, arg...)\ | ||
92 | do { if (v4l_debug >= level) \ | ||
93 | printk(KERN_INFO "%s: " fmt, \ | ||
94 | (dev) ? dev->name : "cx231xx[?]", ## arg); \ | ||
95 | } while (0) | ||
96 | |||
97 | static struct cx231xx_tvnorm cx231xx_tvnorms[] = { | ||
98 | { | ||
99 | .name = "NTSC-M", | ||
100 | .id = V4L2_STD_NTSC_M, | ||
101 | }, { | ||
102 | .name = "NTSC-JP", | ||
103 | .id = V4L2_STD_NTSC_M_JP, | ||
104 | }, { | ||
105 | .name = "PAL-BG", | ||
106 | .id = V4L2_STD_PAL_BG, | ||
107 | }, { | ||
108 | .name = "PAL-DK", | ||
109 | .id = V4L2_STD_PAL_DK, | ||
110 | }, { | ||
111 | .name = "PAL-I", | ||
112 | .id = V4L2_STD_PAL_I, | ||
113 | }, { | ||
114 | .name = "PAL-M", | ||
115 | .id = V4L2_STD_PAL_M, | ||
116 | }, { | ||
117 | .name = "PAL-N", | ||
118 | .id = V4L2_STD_PAL_N, | ||
119 | }, { | ||
120 | .name = "PAL-Nc", | ||
121 | .id = V4L2_STD_PAL_Nc, | ||
122 | }, { | ||
123 | .name = "PAL-60", | ||
124 | .id = V4L2_STD_PAL_60, | ||
125 | }, { | ||
126 | .name = "SECAM-L", | ||
127 | .id = V4L2_STD_SECAM_L, | ||
128 | }, { | ||
129 | .name = "SECAM-DK", | ||
130 | .id = V4L2_STD_SECAM_DK, | ||
131 | } | ||
132 | }; | ||
133 | |||
134 | /* ------------------------------------------------------------------ */ | ||
135 | enum cx231xx_capture_type { | ||
136 | CX231xx_MPEG_CAPTURE, | ||
137 | CX231xx_RAW_CAPTURE, | ||
138 | CX231xx_RAW_PASSTHRU_CAPTURE | ||
139 | }; | ||
140 | enum cx231xx_capture_bits { | ||
141 | CX231xx_RAW_BITS_NONE = 0x00, | ||
142 | CX231xx_RAW_BITS_YUV_CAPTURE = 0x01, | ||
143 | CX231xx_RAW_BITS_PCM_CAPTURE = 0x02, | ||
144 | CX231xx_RAW_BITS_VBI_CAPTURE = 0x04, | ||
145 | CX231xx_RAW_BITS_PASSTHRU_CAPTURE = 0x08, | ||
146 | CX231xx_RAW_BITS_TO_HOST_CAPTURE = 0x10 | ||
147 | }; | ||
148 | enum cx231xx_capture_end { | ||
149 | CX231xx_END_AT_GOP, /* stop at the end of gop, generate irq */ | ||
150 | CX231xx_END_NOW, /* stop immediately, no irq */ | ||
151 | }; | ||
152 | enum cx231xx_framerate { | ||
153 | CX231xx_FRAMERATE_NTSC_30, /* NTSC: 30fps */ | ||
154 | CX231xx_FRAMERATE_PAL_25 /* PAL: 25fps */ | ||
155 | }; | ||
156 | enum cx231xx_stream_port { | ||
157 | CX231xx_OUTPUT_PORT_MEMORY, | ||
158 | CX231xx_OUTPUT_PORT_STREAMING, | ||
159 | CX231xx_OUTPUT_PORT_SERIAL | ||
160 | }; | ||
161 | enum cx231xx_data_xfer_status { | ||
162 | CX231xx_MORE_BUFFERS_FOLLOW, | ||
163 | CX231xx_LAST_BUFFER, | ||
164 | }; | ||
165 | enum cx231xx_picture_mask { | ||
166 | CX231xx_PICTURE_MASK_NONE, | ||
167 | CX231xx_PICTURE_MASK_I_FRAMES, | ||
168 | CX231xx_PICTURE_MASK_I_P_FRAMES = 0x3, | ||
169 | CX231xx_PICTURE_MASK_ALL_FRAMES = 0x7, | ||
170 | }; | ||
171 | enum cx231xx_vbi_mode_bits { | ||
172 | CX231xx_VBI_BITS_SLICED, | ||
173 | CX231xx_VBI_BITS_RAW, | ||
174 | }; | ||
175 | enum cx231xx_vbi_insertion_bits { | ||
176 | CX231xx_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, | ||
177 | CX231xx_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, | ||
178 | CX231xx_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, | ||
179 | CX231xx_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, | ||
180 | CX231xx_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, | ||
181 | }; | ||
182 | enum cx231xx_dma_unit { | ||
183 | CX231xx_DMA_BYTES, | ||
184 | CX231xx_DMA_FRAMES, | ||
185 | }; | ||
186 | enum cx231xx_dma_transfer_status_bits { | ||
187 | CX231xx_DMA_TRANSFER_BITS_DONE = 0x01, | ||
188 | CX231xx_DMA_TRANSFER_BITS_ERROR = 0x04, | ||
189 | CX231xx_DMA_TRANSFER_BITS_LL_ERROR = 0x10, | ||
190 | }; | ||
191 | enum cx231xx_pause { | ||
192 | CX231xx_PAUSE_ENCODING, | ||
193 | CX231xx_RESUME_ENCODING, | ||
194 | }; | ||
195 | enum cx231xx_copyright { | ||
196 | CX231xx_COPYRIGHT_OFF, | ||
197 | CX231xx_COPYRIGHT_ON, | ||
198 | }; | ||
199 | enum cx231xx_notification_type { | ||
200 | CX231xx_NOTIFICATION_REFRESH, | ||
201 | }; | ||
202 | enum cx231xx_notification_status { | ||
203 | CX231xx_NOTIFICATION_OFF, | ||
204 | CX231xx_NOTIFICATION_ON, | ||
205 | }; | ||
206 | enum cx231xx_notification_mailbox { | ||
207 | CX231xx_NOTIFICATION_NO_MAILBOX = -1, | ||
208 | }; | ||
209 | enum cx231xx_field1_lines { | ||
210 | CX231xx_FIELD1_SAA7114 = 0x00EF, /* 239 */ | ||
211 | CX231xx_FIELD1_SAA7115 = 0x00F0, /* 240 */ | ||
212 | CX231xx_FIELD1_MICRONAS = 0x0105, /* 261 */ | ||
213 | }; | ||
214 | enum cx231xx_field2_lines { | ||
215 | CX231xx_FIELD2_SAA7114 = 0x00EF, /* 239 */ | ||
216 | CX231xx_FIELD2_SAA7115 = 0x00F0, /* 240 */ | ||
217 | CX231xx_FIELD2_MICRONAS = 0x0106, /* 262 */ | ||
218 | }; | ||
219 | enum cx231xx_custom_data_type { | ||
220 | CX231xx_CUSTOM_EXTENSION_USR_DATA, | ||
221 | CX231xx_CUSTOM_PRIVATE_PACKET, | ||
222 | }; | ||
223 | enum cx231xx_mute { | ||
224 | CX231xx_UNMUTE, | ||
225 | CX231xx_MUTE, | ||
226 | }; | ||
227 | enum cx231xx_mute_video_mask { | ||
228 | CX231xx_MUTE_VIDEO_V_MASK = 0x0000FF00, | ||
229 | CX231xx_MUTE_VIDEO_U_MASK = 0x00FF0000, | ||
230 | CX231xx_MUTE_VIDEO_Y_MASK = 0xFF000000, | ||
231 | }; | ||
232 | enum cx231xx_mute_video_shift { | ||
233 | CX231xx_MUTE_VIDEO_V_SHIFT = 8, | ||
234 | CX231xx_MUTE_VIDEO_U_SHIFT = 16, | ||
235 | CX231xx_MUTE_VIDEO_Y_SHIFT = 24, | ||
236 | }; | ||
237 | |||
238 | /* defines below are from ivtv-driver.h */ | ||
239 | #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF | ||
240 | |||
241 | /* Firmware API commands */ | ||
242 | #define IVTV_API_STD_TIMEOUT 500 | ||
243 | |||
244 | /* Registers */ | ||
245 | /* IVTV_REG_OFFSET */ | ||
246 | #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) | ||
247 | #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) | ||
248 | #define IVTV_REG_SPU (0x9050) | ||
249 | #define IVTV_REG_HW_BLOCKS (0x9054) | ||
250 | #define IVTV_REG_VPU (0x9058) | ||
251 | #define IVTV_REG_APU (0xA064) | ||
252 | |||
253 | /* | ||
254 | * Bit definitions for MC417_RWD and MC417_OEN registers | ||
255 | * | ||
256 | * bits 31-16 | ||
257 | *+-----------+ | ||
258 | *| Reserved | | ||
259 | *|+-----------+ | ||
260 | *| bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 | ||
261 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ | ||
262 | *|| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0| | ||
263 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ | ||
264 | *| bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 | ||
265 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ | ||
266 | *||MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0| | ||
267 | *|+-------+-------+-------+-------+-------+-------+-------+-------+ | ||
268 | */ | ||
269 | #define MC417_MIWR 0x8000 | ||
270 | #define MC417_MIRD 0x4000 | ||
271 | #define MC417_MICS 0x2000 | ||
272 | #define MC417_MIRDY 0x1000 | ||
273 | #define MC417_MIADDR 0x0F00 | ||
274 | #define MC417_MIDATA 0x00FF | ||
275 | |||
276 | |||
277 | /* Bit definitions for MC417_CTL register **** | ||
278 | *bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0 | ||
279 | *+--------+-------------+--------+--------------+------------+ | ||
280 | *|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN| | ||
281 | *+--------+-------------+--------+--------------+------------+ | ||
282 | */ | ||
283 | #define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030) | ||
284 | #define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006) | ||
285 | #define MC417_UART_GPIO_EN 0x00000001 | ||
286 | |||
287 | /* Values for speed control */ | ||
288 | #define MC417_SPD_CTL_SLOW 0x1 | ||
289 | #define MC417_SPD_CTL_MEDIUM 0x0 | ||
290 | #define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */ | ||
291 | |||
292 | /* Values for GPIO select */ | ||
293 | #define MC417_GPIO_SEL_GPIO3 0x3 | ||
294 | #define MC417_GPIO_SEL_GPIO2 0x2 | ||
295 | #define MC417_GPIO_SEL_GPIO1 0x1 | ||
296 | #define MC417_GPIO_SEL_GPIO0 0x0 | ||
297 | |||
298 | |||
299 | #define CX23417_GPIO_MASK 0xFC0003FF | ||
300 | static int setITVCReg(struct cx231xx *dev, u32 gpio_direction, u32 value) | ||
301 | { | ||
302 | int status = 0; | ||
303 | u32 _gpio_direction = 0; | ||
304 | |||
305 | _gpio_direction = _gpio_direction & CX23417_GPIO_MASK; | ||
306 | _gpio_direction = _gpio_direction|gpio_direction; | ||
307 | status = cx231xx_send_gpio_cmd(dev, _gpio_direction, | ||
308 | (u8 *)&value, 4, 0, 0); | ||
309 | return status; | ||
310 | } | ||
311 | static int getITVCReg(struct cx231xx *dev, u32 gpio_direction, u32 *pValue) | ||
312 | { | ||
313 | int status = 0; | ||
314 | u32 _gpio_direction = 0; | ||
315 | |||
316 | _gpio_direction = _gpio_direction & CX23417_GPIO_MASK; | ||
317 | _gpio_direction = _gpio_direction|gpio_direction; | ||
318 | |||
319 | status = cx231xx_send_gpio_cmd(dev, _gpio_direction, | ||
320 | (u8 *)pValue, 4, 0, 1); | ||
321 | return status; | ||
322 | } | ||
323 | |||
324 | static int waitForMciComplete(struct cx231xx *dev) | ||
325 | { | ||
326 | u32 gpio; | ||
327 | u32 gpio_driection = 0; | ||
328 | u8 count = 0; | ||
329 | getITVCReg(dev, gpio_driection, &gpio); | ||
330 | |||
331 | while (!(gpio&0x020000)) { | ||
332 | msleep(10); | ||
333 | |||
334 | getITVCReg(dev, gpio_driection, &gpio); | ||
335 | |||
336 | if (count++ > 100) { | ||
337 | dprintk(3, "ERROR: Timeout - gpio=%x\n", gpio); | ||
338 | return -1; | ||
339 | } | ||
340 | } | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int mc417_register_write(struct cx231xx *dev, u16 address, u32 value) | ||
345 | { | ||
346 | u32 temp; | ||
347 | int status = 0; | ||
348 | |||
349 | temp = 0x82|MCI_REGISTER_DATA_BYTE0|((value&0x000000FF)<<8); | ||
350 | temp = temp<<10; | ||
351 | status = setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
352 | if (status < 0) | ||
353 | return status; | ||
354 | temp = temp|((0x05)<<10); | ||
355 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
356 | |||
357 | /*write data byte 1;*/ | ||
358 | temp = 0x82|MCI_REGISTER_DATA_BYTE1|(value&0x0000FF00); | ||
359 | temp = temp<<10; | ||
360 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
361 | temp = temp|((0x05)<<10); | ||
362 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
363 | |||
364 | /*write data byte 2;*/ | ||
365 | temp = 0x82|MCI_REGISTER_DATA_BYTE2|((value&0x00FF0000)>>8); | ||
366 | temp = temp<<10; | ||
367 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
368 | temp = temp|((0x05)<<10); | ||
369 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
370 | |||
371 | /*write data byte 3;*/ | ||
372 | temp = 0x82|MCI_REGISTER_DATA_BYTE3|((value&0xFF000000)>>16); | ||
373 | temp = temp<<10; | ||
374 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
375 | temp = temp|((0x05)<<10); | ||
376 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
377 | |||
378 | /*write address byte 0;*/ | ||
379 | temp = 0x82|MCI_REGISTER_ADDRESS_BYTE0|((address&0x000000FF)<<8); | ||
380 | temp = temp<<10; | ||
381 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
382 | temp = temp|((0x05)<<10); | ||
383 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
384 | |||
385 | /*write address byte 1;*/ | ||
386 | temp = 0x82|MCI_REGISTER_ADDRESS_BYTE1|(address&0x0000FF00); | ||
387 | temp = temp<<10; | ||
388 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
389 | temp = temp|((0x05)<<10); | ||
390 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
391 | |||
392 | /*Write that the mode is write.*/ | ||
393 | temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_WRITE; | ||
394 | temp = temp<<10; | ||
395 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
396 | temp = temp|((0x05)<<10); | ||
397 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
398 | |||
399 | return waitForMciComplete(dev); | ||
400 | } | ||
401 | |||
402 | static int mc417_register_read(struct cx231xx *dev, u16 address, u32 *value) | ||
403 | { | ||
404 | /*write address byte 0;*/ | ||
405 | u32 temp; | ||
406 | u32 return_value = 0; | ||
407 | int ret = 0; | ||
408 | |||
409 | temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); | ||
410 | temp = temp << 10; | ||
411 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
412 | temp = temp | ((0x05) << 10); | ||
413 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
414 | |||
415 | /*write address byte 1;*/ | ||
416 | temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0xFF00); | ||
417 | temp = temp << 10; | ||
418 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
419 | temp = temp | ((0x05) << 10); | ||
420 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
421 | |||
422 | /*write that the mode is read;*/ | ||
423 | temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_READ; | ||
424 | temp = temp << 10; | ||
425 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
426 | temp = temp | ((0x05) << 10); | ||
427 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
428 | |||
429 | /*wait for the MIRDY line to be asserted , | ||
430 | signalling that the read is done;*/ | ||
431 | ret = waitForMciComplete(dev); | ||
432 | |||
433 | /*switch the DATA- GPIO to input mode;*/ | ||
434 | |||
435 | /*Read data byte 0;*/ | ||
436 | temp = (0x82 | MCI_REGISTER_DATA_BYTE0) << 10; | ||
437 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
438 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE0) << 10); | ||
439 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
440 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
441 | return_value |= ((temp & 0x03FC0000) >> 18); | ||
442 | setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); | ||
443 | |||
444 | /* Read data byte 1;*/ | ||
445 | temp = (0x82 | MCI_REGISTER_DATA_BYTE1) << 10; | ||
446 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
447 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE1) << 10); | ||
448 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
449 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
450 | |||
451 | return_value |= ((temp & 0x03FC0000) >> 10); | ||
452 | setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); | ||
453 | |||
454 | /*Read data byte 2;*/ | ||
455 | temp = (0x82 | MCI_REGISTER_DATA_BYTE2) << 10; | ||
456 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
457 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE2) << 10); | ||
458 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
459 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
460 | return_value |= ((temp & 0x03FC0000) >> 2); | ||
461 | setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); | ||
462 | |||
463 | /*Read data byte 3;*/ | ||
464 | temp = (0x82 | MCI_REGISTER_DATA_BYTE3) << 10; | ||
465 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
466 | temp = ((0x81 | MCI_REGISTER_DATA_BYTE3) << 10); | ||
467 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
468 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
469 | return_value |= ((temp & 0x03FC0000) << 6); | ||
470 | setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); | ||
471 | |||
472 | *value = return_value; | ||
473 | |||
474 | |||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static int mc417_memory_write(struct cx231xx *dev, u32 address, u32 value) | ||
479 | { | ||
480 | /*write data byte 0;*/ | ||
481 | |||
482 | u32 temp; | ||
483 | int ret = 0; | ||
484 | |||
485 | temp = 0x82 | MCI_MEMORY_DATA_BYTE0|((value & 0x000000FF) << 8); | ||
486 | temp = temp << 10; | ||
487 | ret = setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
488 | if (ret < 0) | ||
489 | return ret; | ||
490 | temp = temp | ((0x05) << 10); | ||
491 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
492 | |||
493 | /*write data byte 1;*/ | ||
494 | temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00); | ||
495 | temp = temp << 10; | ||
496 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
497 | temp = temp | ((0x05) << 10); | ||
498 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
499 | |||
500 | /*write data byte 2;*/ | ||
501 | temp = 0x82|MCI_MEMORY_DATA_BYTE2|((value&0x00FF0000)>>8); | ||
502 | temp = temp<<10; | ||
503 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
504 | temp = temp|((0x05)<<10); | ||
505 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
506 | |||
507 | /*write data byte 3;*/ | ||
508 | temp = 0x82|MCI_MEMORY_DATA_BYTE3|((value&0xFF000000)>>16); | ||
509 | temp = temp<<10; | ||
510 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
511 | temp = temp|((0x05)<<10); | ||
512 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
513 | |||
514 | /* write address byte 2;*/ | ||
515 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | | ||
516 | ((address & 0x003F0000)>>8); | ||
517 | temp = temp<<10; | ||
518 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
519 | temp = temp|((0x05)<<10); | ||
520 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
521 | |||
522 | /* write address byte 1;*/ | ||
523 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); | ||
524 | temp = temp<<10; | ||
525 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
526 | temp = temp|((0x05)<<10); | ||
527 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
528 | |||
529 | /* write address byte 0;*/ | ||
530 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0|((address & 0x00FF)<<8); | ||
531 | temp = temp<<10; | ||
532 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
533 | temp = temp|((0x05)<<10); | ||
534 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
535 | |||
536 | /*wait for MIRDY line;*/ | ||
537 | waitForMciComplete(dev); | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static int mc417_memory_read(struct cx231xx *dev, u32 address, u32 *value) | ||
543 | { | ||
544 | u32 temp = 0; | ||
545 | u32 return_value = 0; | ||
546 | int ret = 0; | ||
547 | |||
548 | /*write address byte 2;*/ | ||
549 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_READ | | ||
550 | ((address & 0x003F0000)>>8); | ||
551 | temp = temp<<10; | ||
552 | ret = setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
553 | if (ret < 0) | ||
554 | return ret; | ||
555 | temp = temp|((0x05)<<10); | ||
556 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
557 | |||
558 | /*write address byte 1*/ | ||
559 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); | ||
560 | temp = temp<<10; | ||
561 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
562 | temp = temp|((0x05)<<10); | ||
563 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
564 | |||
565 | /*write address byte 0*/ | ||
566 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF)<<8); | ||
567 | temp = temp<<10; | ||
568 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
569 | temp = temp|((0x05)<<10); | ||
570 | setITVCReg(dev, ITVC_WRITE_DIR, temp); | ||
571 | |||
572 | /*Wait for MIRDY line*/ | ||
573 | ret = waitForMciComplete(dev); | ||
574 | |||
575 | |||
576 | /*Read data byte 3;*/ | ||
577 | temp = (0x82|MCI_MEMORY_DATA_BYTE3)<<10; | ||
578 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
579 | temp = ((0x81|MCI_MEMORY_DATA_BYTE3)<<10); | ||
580 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
581 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
582 | return_value |= ((temp&0x03FC0000)<<6); | ||
583 | setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); | ||
584 | |||
585 | /*Read data byte 2;*/ | ||
586 | temp = (0x82|MCI_MEMORY_DATA_BYTE2)<<10; | ||
587 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
588 | temp = ((0x81|MCI_MEMORY_DATA_BYTE2)<<10); | ||
589 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
590 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
591 | return_value |= ((temp&0x03FC0000)>>2); | ||
592 | setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); | ||
593 | |||
594 | /* Read data byte 1;*/ | ||
595 | temp = (0x82|MCI_MEMORY_DATA_BYTE1)<<10; | ||
596 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
597 | temp = ((0x81|MCI_MEMORY_DATA_BYTE1)<<10); | ||
598 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
599 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
600 | return_value |= ((temp&0x03FC0000)>>10); | ||
601 | setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); | ||
602 | |||
603 | /*Read data byte 0;*/ | ||
604 | temp = (0x82|MCI_MEMORY_DATA_BYTE0)<<10; | ||
605 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
606 | temp = ((0x81|MCI_MEMORY_DATA_BYTE0)<<10); | ||
607 | setITVCReg(dev, ITVC_READ_DIR, temp); | ||
608 | getITVCReg(dev, ITVC_READ_DIR, &temp); | ||
609 | return_value |= ((temp&0x03FC0000)>>18); | ||
610 | setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); | ||
611 | |||
612 | *value = return_value; | ||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | /* ------------------------------------------------------------------ */ | ||
617 | |||
618 | /* MPEG encoder API */ | ||
619 | static char *cmd_to_str(int cmd) | ||
620 | { | ||
621 | switch (cmd) { | ||
622 | case CX2341X_ENC_PING_FW: | ||
623 | return "PING_FW"; | ||
624 | case CX2341X_ENC_START_CAPTURE: | ||
625 | return "START_CAPTURE"; | ||
626 | case CX2341X_ENC_STOP_CAPTURE: | ||
627 | return "STOP_CAPTURE"; | ||
628 | case CX2341X_ENC_SET_AUDIO_ID: | ||
629 | return "SET_AUDIO_ID"; | ||
630 | case CX2341X_ENC_SET_VIDEO_ID: | ||
631 | return "SET_VIDEO_ID"; | ||
632 | case CX2341X_ENC_SET_PCR_ID: | ||
633 | return "SET_PCR_PID"; | ||
634 | case CX2341X_ENC_SET_FRAME_RATE: | ||
635 | return "SET_FRAME_RATE"; | ||
636 | case CX2341X_ENC_SET_FRAME_SIZE: | ||
637 | return "SET_FRAME_SIZE"; | ||
638 | case CX2341X_ENC_SET_BIT_RATE: | ||
639 | return "SET_BIT_RATE"; | ||
640 | case CX2341X_ENC_SET_GOP_PROPERTIES: | ||
641 | return "SET_GOP_PROPERTIES"; | ||
642 | case CX2341X_ENC_SET_ASPECT_RATIO: | ||
643 | return "SET_ASPECT_RATIO"; | ||
644 | case CX2341X_ENC_SET_DNR_FILTER_MODE: | ||
645 | return "SET_DNR_FILTER_PROPS"; | ||
646 | case CX2341X_ENC_SET_DNR_FILTER_PROPS: | ||
647 | return "SET_DNR_FILTER_PROPS"; | ||
648 | case CX2341X_ENC_SET_CORING_LEVELS: | ||
649 | return "SET_CORING_LEVELS"; | ||
650 | case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: | ||
651 | return "SET_SPATIAL_FILTER_TYPE"; | ||
652 | case CX2341X_ENC_SET_VBI_LINE: | ||
653 | return "SET_VBI_LINE"; | ||
654 | case CX2341X_ENC_SET_STREAM_TYPE: | ||
655 | return "SET_STREAM_TYPE"; | ||
656 | case CX2341X_ENC_SET_OUTPUT_PORT: | ||
657 | return "SET_OUTPUT_PORT"; | ||
658 | case CX2341X_ENC_SET_AUDIO_PROPERTIES: | ||
659 | return "SET_AUDIO_PROPERTIES"; | ||
660 | case CX2341X_ENC_HALT_FW: | ||
661 | return "HALT_FW"; | ||
662 | case CX2341X_ENC_GET_VERSION: | ||
663 | return "GET_VERSION"; | ||
664 | case CX2341X_ENC_SET_GOP_CLOSURE: | ||
665 | return "SET_GOP_CLOSURE"; | ||
666 | case CX2341X_ENC_GET_SEQ_END: | ||
667 | return "GET_SEQ_END"; | ||
668 | case CX2341X_ENC_SET_PGM_INDEX_INFO: | ||
669 | return "SET_PGM_INDEX_INFO"; | ||
670 | case CX2341X_ENC_SET_VBI_CONFIG: | ||
671 | return "SET_VBI_CONFIG"; | ||
672 | case CX2341X_ENC_SET_DMA_BLOCK_SIZE: | ||
673 | return "SET_DMA_BLOCK_SIZE"; | ||
674 | case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10: | ||
675 | return "GET_PREV_DMA_INFO_MB_10"; | ||
676 | case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9: | ||
677 | return "GET_PREV_DMA_INFO_MB_9"; | ||
678 | case CX2341X_ENC_SCHED_DMA_TO_HOST: | ||
679 | return "SCHED_DMA_TO_HOST"; | ||
680 | case CX2341X_ENC_INITIALIZE_INPUT: | ||
681 | return "INITIALIZE_INPUT"; | ||
682 | case CX2341X_ENC_SET_FRAME_DROP_RATE: | ||
683 | return "SET_FRAME_DROP_RATE"; | ||
684 | case CX2341X_ENC_PAUSE_ENCODER: | ||
685 | return "PAUSE_ENCODER"; | ||
686 | case CX2341X_ENC_REFRESH_INPUT: | ||
687 | return "REFRESH_INPUT"; | ||
688 | case CX2341X_ENC_SET_COPYRIGHT: | ||
689 | return "SET_COPYRIGHT"; | ||
690 | case CX2341X_ENC_SET_EVENT_NOTIFICATION: | ||
691 | return "SET_EVENT_NOTIFICATION"; | ||
692 | case CX2341X_ENC_SET_NUM_VSYNC_LINES: | ||
693 | return "SET_NUM_VSYNC_LINES"; | ||
694 | case CX2341X_ENC_SET_PLACEHOLDER: | ||
695 | return "SET_PLACEHOLDER"; | ||
696 | case CX2341X_ENC_MUTE_VIDEO: | ||
697 | return "MUTE_VIDEO"; | ||
698 | case CX2341X_ENC_MUTE_AUDIO: | ||
699 | return "MUTE_AUDIO"; | ||
700 | case CX2341X_ENC_MISC: | ||
701 | return "MISC"; | ||
702 | default: | ||
703 | return "UNKNOWN"; | ||
704 | } | ||
705 | } | ||
706 | |||
707 | static int cx231xx_mbox_func(void *priv, | ||
708 | u32 command, | ||
709 | int in, | ||
710 | int out, | ||
711 | u32 data[CX2341X_MBOX_MAX_DATA]) | ||
712 | { | ||
713 | struct cx231xx *dev = priv; | ||
714 | unsigned long timeout; | ||
715 | u32 value, flag, retval = 0; | ||
716 | int i; | ||
717 | |||
718 | dprintk(3, "%s: command(0x%X) = %s\n", __func__, command, | ||
719 | cmd_to_str(command)); | ||
720 | |||
721 | /* this may not be 100% safe if we can't read any memory location | ||
722 | without side effects */ | ||
723 | mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); | ||
724 | if (value != 0x12345678) { | ||
725 | dprintk(3, | ||
726 | "Firmware and/or mailbox pointer not initialized " | ||
727 | "or corrupted, signature = 0x%x, cmd = %s\n", value, | ||
728 | cmd_to_str(command)); | ||
729 | return -1; | ||
730 | } | ||
731 | |||
732 | /* This read looks at 32 bits, but flag is only 8 bits. | ||
733 | * Seems we also bail if CMD or TIMEOUT bytes are set??? | ||
734 | */ | ||
735 | mc417_memory_read(dev, dev->cx23417_mailbox, &flag); | ||
736 | if (flag) { | ||
737 | dprintk(3, "ERROR: Mailbox appears to be in use " | ||
738 | "(%x), cmd = %s\n", flag, cmd_to_str(command)); | ||
739 | return -1; | ||
740 | } | ||
741 | |||
742 | flag |= 1; /* tell 'em we're working on it */ | ||
743 | mc417_memory_write(dev, dev->cx23417_mailbox, flag); | ||
744 | |||
745 | /* write command + args + fill remaining with zeros */ | ||
746 | /* command code */ | ||
747 | mc417_memory_write(dev, dev->cx23417_mailbox + 1, command); | ||
748 | mc417_memory_write(dev, dev->cx23417_mailbox + 3, | ||
749 | IVTV_API_STD_TIMEOUT); /* timeout */ | ||
750 | for (i = 0; i < in; i++) { | ||
751 | mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]); | ||
752 | dprintk(3, "API Input %d = %d\n", i, data[i]); | ||
753 | } | ||
754 | for (; i < CX2341X_MBOX_MAX_DATA; i++) | ||
755 | mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0); | ||
756 | |||
757 | flag |= 3; /* tell 'em we're done writing */ | ||
758 | mc417_memory_write(dev, dev->cx23417_mailbox, flag); | ||
759 | |||
760 | /* wait for firmware to handle the API command */ | ||
761 | timeout = jiffies + msecs_to_jiffies(10); | ||
762 | for (;;) { | ||
763 | mc417_memory_read(dev, dev->cx23417_mailbox, &flag); | ||
764 | if (0 != (flag & 4)) | ||
765 | break; | ||
766 | if (time_after(jiffies, timeout)) { | ||
767 | dprintk(3, "ERROR: API Mailbox timeout\n"); | ||
768 | return -1; | ||
769 | } | ||
770 | udelay(10); | ||
771 | } | ||
772 | |||
773 | /* read output values */ | ||
774 | for (i = 0; i < out; i++) { | ||
775 | mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i); | ||
776 | dprintk(3, "API Output %d = %d\n", i, data[i]); | ||
777 | } | ||
778 | |||
779 | mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval); | ||
780 | dprintk(3, "API result = %d\n", retval); | ||
781 | |||
782 | flag = 0; | ||
783 | mc417_memory_write(dev, dev->cx23417_mailbox, flag); | ||
784 | |||
785 | return retval; | ||
786 | } | ||
787 | |||
788 | /* We don't need to call the API often, so using just one | ||
789 | * mailbox will probably suffice | ||
790 | */ | ||
791 | static int cx231xx_api_cmd(struct cx231xx *dev, | ||
792 | u32 command, | ||
793 | u32 inputcnt, | ||
794 | u32 outputcnt, | ||
795 | ...) | ||
796 | { | ||
797 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
798 | va_list vargs; | ||
799 | int i, err; | ||
800 | |||
801 | dprintk(3, "%s() cmds = 0x%08x\n", __func__, command); | ||
802 | |||
803 | va_start(vargs, outputcnt); | ||
804 | for (i = 0; i < inputcnt; i++) | ||
805 | data[i] = va_arg(vargs, int); | ||
806 | |||
807 | err = cx231xx_mbox_func(dev, command, inputcnt, outputcnt, data); | ||
808 | for (i = 0; i < outputcnt; i++) { | ||
809 | int *vptr = va_arg(vargs, int *); | ||
810 | *vptr = data[i]; | ||
811 | } | ||
812 | va_end(vargs); | ||
813 | |||
814 | return err; | ||
815 | } | ||
816 | |||
817 | static int cx231xx_find_mailbox(struct cx231xx *dev) | ||
818 | { | ||
819 | u32 signature[4] = { | ||
820 | 0x12345678, 0x34567812, 0x56781234, 0x78123456 | ||
821 | }; | ||
822 | int signaturecnt = 0; | ||
823 | u32 value; | ||
824 | int i; | ||
825 | int ret = 0; | ||
826 | |||
827 | dprintk(2, "%s()\n", __func__); | ||
828 | |||
829 | for (i = 0; i < 0x100; i++) {/*CX231xx_FIRM_IMAGE_SIZE*/ | ||
830 | ret = mc417_memory_read(dev, i, &value); | ||
831 | if (ret < 0) | ||
832 | return ret; | ||
833 | if (value == signature[signaturecnt]) | ||
834 | signaturecnt++; | ||
835 | else | ||
836 | signaturecnt = 0; | ||
837 | if (4 == signaturecnt) { | ||
838 | dprintk(1, "Mailbox signature found at 0x%x\n", i+1); | ||
839 | return i+1; | ||
840 | } | ||
841 | } | ||
842 | dprintk(3, "Mailbox signature values not found!\n"); | ||
843 | return -1; | ||
844 | } | ||
845 | |||
846 | static void mciWriteMemoryToGPIO(struct cx231xx *dev, u32 address, u32 value, | ||
847 | u32 *p_fw_image) | ||
848 | { | ||
849 | |||
850 | u32 temp = 0; | ||
851 | int i = 0; | ||
852 | |||
853 | temp = 0x82|MCI_MEMORY_DATA_BYTE0|((value&0x000000FF)<<8); | ||
854 | temp = temp<<10; | ||
855 | *p_fw_image = temp; | ||
856 | p_fw_image++; | ||
857 | temp = temp|((0x05)<<10); | ||
858 | *p_fw_image = temp; | ||
859 | p_fw_image++; | ||
860 | |||
861 | /*write data byte 1;*/ | ||
862 | temp = 0x82|MCI_MEMORY_DATA_BYTE1|(value&0x0000FF00); | ||
863 | temp = temp<<10; | ||
864 | *p_fw_image = temp; | ||
865 | p_fw_image++; | ||
866 | temp = temp|((0x05)<<10); | ||
867 | *p_fw_image = temp; | ||
868 | p_fw_image++; | ||
869 | |||
870 | /*write data byte 2;*/ | ||
871 | temp = 0x82|MCI_MEMORY_DATA_BYTE2|((value&0x00FF0000)>>8); | ||
872 | temp = temp<<10; | ||
873 | *p_fw_image = temp; | ||
874 | p_fw_image++; | ||
875 | temp = temp|((0x05)<<10); | ||
876 | *p_fw_image = temp; | ||
877 | p_fw_image++; | ||
878 | |||
879 | /*write data byte 3;*/ | ||
880 | temp = 0x82|MCI_MEMORY_DATA_BYTE3|((value&0xFF000000)>>16); | ||
881 | temp = temp<<10; | ||
882 | *p_fw_image = temp; | ||
883 | p_fw_image++; | ||
884 | temp = temp|((0x05)<<10); | ||
885 | *p_fw_image = temp; | ||
886 | p_fw_image++; | ||
887 | |||
888 | /* write address byte 2;*/ | ||
889 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | | ||
890 | ((address & 0x003F0000)>>8); | ||
891 | temp = temp<<10; | ||
892 | *p_fw_image = temp; | ||
893 | p_fw_image++; | ||
894 | temp = temp|((0x05)<<10); | ||
895 | *p_fw_image = temp; | ||
896 | p_fw_image++; | ||
897 | |||
898 | /* write address byte 1;*/ | ||
899 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); | ||
900 | temp = temp<<10; | ||
901 | *p_fw_image = temp; | ||
902 | p_fw_image++; | ||
903 | temp = temp|((0x05)<<10); | ||
904 | *p_fw_image = temp; | ||
905 | p_fw_image++; | ||
906 | |||
907 | /* write address byte 0;*/ | ||
908 | temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0|((address & 0x00FF)<<8); | ||
909 | temp = temp<<10; | ||
910 | *p_fw_image = temp; | ||
911 | p_fw_image++; | ||
912 | temp = temp|((0x05)<<10); | ||
913 | *p_fw_image = temp; | ||
914 | p_fw_image++; | ||
915 | |||
916 | for (i = 0; i < 6; i++) { | ||
917 | *p_fw_image = 0xFFFFFFFF; | ||
918 | p_fw_image++; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | |||
923 | static int cx231xx_load_firmware(struct cx231xx *dev) | ||
924 | { | ||
925 | static const unsigned char magic[8] = { | ||
926 | 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa | ||
927 | }; | ||
928 | const struct firmware *firmware; | ||
929 | int i, retval = 0; | ||
930 | u32 value = 0; | ||
931 | u32 gpio_output = 0; | ||
932 | /*u32 checksum = 0;*/ | ||
933 | /*u32 *dataptr;*/ | ||
934 | u32 transfer_size = 0; | ||
935 | u32 fw_data = 0; | ||
936 | u32 address = 0; | ||
937 | /*u32 current_fw[800];*/ | ||
938 | u32 *p_current_fw, *p_fw; | ||
939 | u32 *p_fw_data; | ||
940 | int frame = 0; | ||
941 | u16 _buffer_size = 4096; | ||
942 | u8 *p_buffer; | ||
943 | |||
944 | p_current_fw = (u32 *)vmalloc(1884180*4); | ||
945 | p_fw = p_current_fw; | ||
946 | if (p_current_fw == 0) { | ||
947 | dprintk(2, "FAIL!!!\n"); | ||
948 | return -1; | ||
949 | } | ||
950 | |||
951 | p_buffer = (u8 *)vmalloc(4096); | ||
952 | if (p_buffer == 0) { | ||
953 | dprintk(2, "FAIL!!!\n"); | ||
954 | return -1; | ||
955 | } | ||
956 | |||
957 | dprintk(2, "%s()\n", __func__); | ||
958 | |||
959 | /* Save GPIO settings before reset of APU */ | ||
960 | retval |= mc417_memory_read(dev, 0x9020, &gpio_output); | ||
961 | retval |= mc417_memory_read(dev, 0x900C, &value); | ||
962 | |||
963 | retval = mc417_register_write(dev, | ||
964 | IVTV_REG_VPU, 0xFFFFFFED); | ||
965 | retval |= mc417_register_write(dev, | ||
966 | IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); | ||
967 | retval |= mc417_register_write(dev, | ||
968 | IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800); | ||
969 | retval |= mc417_register_write(dev, | ||
970 | IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); | ||
971 | retval |= mc417_register_write(dev, | ||
972 | IVTV_REG_APU, 0); | ||
973 | |||
974 | if (retval != 0) { | ||
975 | printk(KERN_ERR "%s: Error with mc417_register_write\n", | ||
976 | __func__); | ||
977 | return -1; | ||
978 | } | ||
979 | |||
980 | retval = request_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME, | ||
981 | &dev->udev->dev); | ||
982 | |||
983 | if (retval != 0) { | ||
984 | printk(KERN_ERR | ||
985 | "ERROR: Hotplug firmware request failed (%s).\n", | ||
986 | CX231xx_FIRM_IMAGE_NAME); | ||
987 | printk(KERN_ERR "Please fix your hotplug setup, the board will " | ||
988 | "not work without firmware loaded!\n"); | ||
989 | return -1; | ||
990 | } | ||
991 | |||
992 | if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { | ||
993 | printk(KERN_ERR "ERROR: Firmware size mismatch " | ||
994 | "(have %zd, expected %d)\n", | ||
995 | firmware->size, CX231xx_FIRM_IMAGE_SIZE); | ||
996 | release_firmware(firmware); | ||
997 | return -1; | ||
998 | } | ||
999 | |||
1000 | if (0 != memcmp(firmware->data, magic, 8)) { | ||
1001 | printk(KERN_ERR | ||
1002 | "ERROR: Firmware magic mismatch, wrong file?\n"); | ||
1003 | release_firmware(firmware); | ||
1004 | return -1; | ||
1005 | } | ||
1006 | |||
1007 | initGPIO(dev); | ||
1008 | |||
1009 | /* transfer to the chip */ | ||
1010 | dprintk(2, "Loading firmware to GPIO...\n"); | ||
1011 | p_fw_data = (u32 *)firmware->data; | ||
1012 | dprintk(2, "firmware->size=%zd\n", firmware->size); | ||
1013 | for (transfer_size = 0; transfer_size < firmware->size; | ||
1014 | transfer_size += 4) { | ||
1015 | fw_data = *p_fw_data; | ||
1016 | |||
1017 | mciWriteMemoryToGPIO(dev, address, fw_data, p_current_fw); | ||
1018 | address = address + 1; | ||
1019 | p_current_fw += 20; | ||
1020 | p_fw_data += 1; | ||
1021 | } | ||
1022 | |||
1023 | /*download the firmware by ep5-out*/ | ||
1024 | |||
1025 | for (frame = 0; frame < (int)(CX231xx_FIRM_IMAGE_SIZE*20/_buffer_size); | ||
1026 | frame++) { | ||
1027 | for (i = 0; i < _buffer_size; i++) { | ||
1028 | *(p_buffer + i) = (u8)(*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x000000FF); | ||
1029 | i++; | ||
1030 | *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x0000FF00) >> 8); | ||
1031 | i++; | ||
1032 | *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x00FF0000) >> 16); | ||
1033 | i++; | ||
1034 | *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0xFF000000) >> 24); | ||
1035 | } | ||
1036 | cx231xx_ep5_bulkout(dev, p_buffer, _buffer_size); | ||
1037 | } | ||
1038 | |||
1039 | p_current_fw = p_fw; | ||
1040 | vfree(p_current_fw); | ||
1041 | p_current_fw = NULL; | ||
1042 | uninitGPIO(dev); | ||
1043 | release_firmware(firmware); | ||
1044 | dprintk(1, "Firmware upload successful.\n"); | ||
1045 | |||
1046 | retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, | ||
1047 | IVTV_CMD_HW_BLOCKS_RST); | ||
1048 | if (retval < 0) { | ||
1049 | printk(KERN_ERR "%s: Error with mc417_register_write\n", | ||
1050 | __func__); | ||
1051 | return retval; | ||
1052 | } | ||
1053 | /* F/W power up disturbs the GPIOs, restore state */ | ||
1054 | retval |= mc417_register_write(dev, 0x9020, gpio_output); | ||
1055 | retval |= mc417_register_write(dev, 0x900C, value); | ||
1056 | |||
1057 | retval |= mc417_register_read(dev, IVTV_REG_VPU, &value); | ||
1058 | retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); | ||
1059 | |||
1060 | if (retval < 0) { | ||
1061 | printk(KERN_ERR "%s: Error with mc417_register_write\n", | ||
1062 | __func__); | ||
1063 | return retval; | ||
1064 | } | ||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | static void cx231xx_417_check_encoder(struct cx231xx *dev) | ||
1069 | { | ||
1070 | u32 status, seq; | ||
1071 | |||
1072 | status = 0; | ||
1073 | seq = 0; | ||
1074 | cx231xx_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq); | ||
1075 | dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq); | ||
1076 | } | ||
1077 | |||
1078 | static void cx231xx_codec_settings(struct cx231xx *dev) | ||
1079 | { | ||
1080 | dprintk(1, "%s()\n", __func__); | ||
1081 | |||
1082 | /* assign frame size */ | ||
1083 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, | ||
1084 | dev->ts1.height, dev->ts1.width); | ||
1085 | |||
1086 | dev->mpeg_params.width = dev->ts1.width; | ||
1087 | dev->mpeg_params.height = dev->ts1.height; | ||
1088 | |||
1089 | cx2341x_update(dev, cx231xx_mbox_func, NULL, &dev->mpeg_params); | ||
1090 | |||
1091 | cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1); | ||
1092 | cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1); | ||
1093 | } | ||
1094 | |||
1095 | static int cx231xx_initialize_codec(struct cx231xx *dev) | ||
1096 | { | ||
1097 | int version; | ||
1098 | int retval; | ||
1099 | u32 i, data[7]; | ||
1100 | u32 val = 0; | ||
1101 | |||
1102 | dprintk(1, "%s()\n", __func__); | ||
1103 | cx231xx_disable656(dev); | ||
1104 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ | ||
1105 | if (retval < 0) { | ||
1106 | dprintk(2, "%s() PING OK\n", __func__); | ||
1107 | retval = cx231xx_load_firmware(dev); | ||
1108 | if (retval < 0) { | ||
1109 | printk(KERN_ERR "%s() f/w load failed\n", __func__); | ||
1110 | return retval; | ||
1111 | } | ||
1112 | retval = cx231xx_find_mailbox(dev); | ||
1113 | if (retval < 0) { | ||
1114 | printk(KERN_ERR "%s() mailbox < 0, error\n", | ||
1115 | __func__); | ||
1116 | return -1; | ||
1117 | } | ||
1118 | dev->cx23417_mailbox = retval; | ||
1119 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); | ||
1120 | if (retval < 0) { | ||
1121 | printk(KERN_ERR | ||
1122 | "ERROR: cx23417 firmware ping failed!\n"); | ||
1123 | return -1; | ||
1124 | } | ||
1125 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, | ||
1126 | &version); | ||
1127 | if (retval < 0) { | ||
1128 | printk(KERN_ERR "ERROR: cx23417 firmware get encoder :" | ||
1129 | "version failed!\n"); | ||
1130 | return -1; | ||
1131 | } | ||
1132 | dprintk(1, "cx23417 firmware version is 0x%08x\n", version); | ||
1133 | msleep(200); | ||
1134 | } | ||
1135 | |||
1136 | for (i = 0; i < 1; i++) { | ||
1137 | retval = mc417_register_read(dev, 0x20f8, &val); | ||
1138 | dprintk(3, "***before enable656() VIM Capture Lines =%d ***\n", | ||
1139 | val); | ||
1140 | if (retval < 0) | ||
1141 | return retval; | ||
1142 | } | ||
1143 | |||
1144 | cx231xx_enable656(dev); | ||
1145 | /* stop mpeg capture */ | ||
1146 | cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, | ||
1147 | 3, 0, 1, 3, 4); | ||
1148 | |||
1149 | cx231xx_codec_settings(dev); | ||
1150 | msleep(60); | ||
1151 | |||
1152 | /* cx231xx_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, | ||
1153 | CX231xx_FIELD1_SAA7115, CX231xx_FIELD2_SAA7115); | ||
1154 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, | ||
1155 | CX231xx_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
1156 | 0, 0); | ||
1157 | */ | ||
1158 | /* Setup to capture VBI */ | ||
1159 | data[0] = 0x0001BD00; | ||
1160 | data[1] = 1; /* frames per interrupt */ | ||
1161 | data[2] = 4; /* total bufs */ | ||
1162 | data[3] = 0x91559155; /* start codes */ | ||
1163 | data[4] = 0x206080C0; /* stop codes */ | ||
1164 | data[5] = 6; /* lines */ | ||
1165 | data[6] = 64; /* BPL */ | ||
1166 | /* | ||
1167 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1], | ||
1168 | data[2], data[3], data[4], data[5], data[6]); | ||
1169 | |||
1170 | for (i = 2; i <= 24; i++) { | ||
1171 | int valid; | ||
1172 | |||
1173 | valid = ((i >= 19) && (i <= 21)); | ||
1174 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i, | ||
1175 | valid, 0 , 0, 0); | ||
1176 | cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, | ||
1177 | i | 0x80000000, valid, 0, 0, 0); | ||
1178 | } | ||
1179 | */ | ||
1180 | /* cx231xx_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX231xx_UNMUTE); | ||
1181 | msleep(60); | ||
1182 | */ | ||
1183 | /* initialize the video input */ | ||
1184 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); | ||
1185 | if (retval < 0) | ||
1186 | return retval; | ||
1187 | msleep(60); | ||
1188 | |||
1189 | /* Enable VIP style pixel invalidation so we work with scaled mode */ | ||
1190 | mc417_memory_write(dev, 2120, 0x00000080); | ||
1191 | |||
1192 | /* start capturing to the host interface */ | ||
1193 | retval = cx231xx_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, | ||
1194 | CX231xx_MPEG_CAPTURE, CX231xx_RAW_BITS_NONE); | ||
1195 | if (retval < 0) | ||
1196 | return retval; | ||
1197 | msleep(10); | ||
1198 | |||
1199 | for (i = 0; i < 1; i++) { | ||
1200 | mc417_register_read(dev, 0x20f8, &val); | ||
1201 | dprintk(3, "***VIM Capture Lines =%d ***\n", val); | ||
1202 | } | ||
1203 | |||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | /* ------------------------------------------------------------------ */ | ||
1208 | |||
1209 | static int bb_buf_setup(struct videobuf_queue *q, | ||
1210 | unsigned int *count, unsigned int *size) | ||
1211 | { | ||
1212 | struct cx231xx_fh *fh = q->priv_data; | ||
1213 | |||
1214 | fh->dev->ts1.ts_packet_size = mpeglinesize; | ||
1215 | fh->dev->ts1.ts_packet_count = mpeglines; | ||
1216 | |||
1217 | *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; | ||
1218 | *count = mpegbufs; | ||
1219 | |||
1220 | return 0; | ||
1221 | } | ||
1222 | static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) | ||
1223 | { | ||
1224 | struct cx231xx_fh *fh = vq->priv_data; | ||
1225 | struct cx231xx *dev = fh->dev; | ||
1226 | unsigned long flags = 0; | ||
1227 | |||
1228 | if (in_interrupt()) | ||
1229 | BUG(); | ||
1230 | |||
1231 | spin_lock_irqsave(&dev->video_mode.slock, flags); | ||
1232 | if (dev->USE_ISO) { | ||
1233 | if (dev->video_mode.isoc_ctl.buf == buf) | ||
1234 | dev->video_mode.isoc_ctl.buf = NULL; | ||
1235 | } else { | ||
1236 | if (dev->video_mode.bulk_ctl.buf == buf) | ||
1237 | dev->video_mode.bulk_ctl.buf = NULL; | ||
1238 | } | ||
1239 | spin_unlock_irqrestore(&dev->video_mode.slock, flags); | ||
1240 | videobuf_waiton(vq, &buf->vb, 0, 0); | ||
1241 | videobuf_vmalloc_free(&buf->vb); | ||
1242 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
1243 | } | ||
1244 | |||
1245 | static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb, | ||
1246 | struct cx231xx_dmaqueue *dma_q) | ||
1247 | { | ||
1248 | void *vbuf; | ||
1249 | struct cx231xx_buffer *buf; | ||
1250 | u32 tail_data = 0; | ||
1251 | char *p_data; | ||
1252 | |||
1253 | if (dma_q->mpeg_buffer_done == 0) { | ||
1254 | if (list_empty(&dma_q->active)) | ||
1255 | return; | ||
1256 | |||
1257 | buf = list_entry(dma_q->active.next, | ||
1258 | struct cx231xx_buffer, vb.queue); | ||
1259 | dev->video_mode.isoc_ctl.buf = buf; | ||
1260 | dma_q->mpeg_buffer_done = 1; | ||
1261 | } | ||
1262 | /* Fill buffer */ | ||
1263 | buf = dev->video_mode.isoc_ctl.buf; | ||
1264 | vbuf = videobuf_to_vmalloc(&buf->vb); | ||
1265 | |||
1266 | if ((dma_q->mpeg_buffer_completed+len) < | ||
1267 | mpeglines*mpeglinesize) { | ||
1268 | if (dma_q->add_ps_package_head == | ||
1269 | CX231XX_NEED_ADD_PS_PACKAGE_HEAD) { | ||
1270 | memcpy(vbuf+dma_q->mpeg_buffer_completed, | ||
1271 | dma_q->ps_head, 3); | ||
1272 | dma_q->mpeg_buffer_completed = | ||
1273 | dma_q->mpeg_buffer_completed + 3; | ||
1274 | dma_q->add_ps_package_head = | ||
1275 | CX231XX_NONEED_PS_PACKAGE_HEAD; | ||
1276 | } | ||
1277 | memcpy(vbuf+dma_q->mpeg_buffer_completed, data, len); | ||
1278 | dma_q->mpeg_buffer_completed = | ||
1279 | dma_q->mpeg_buffer_completed + len; | ||
1280 | } else { | ||
1281 | dma_q->mpeg_buffer_done = 0; | ||
1282 | |||
1283 | tail_data = | ||
1284 | mpeglines*mpeglinesize - dma_q->mpeg_buffer_completed; | ||
1285 | memcpy(vbuf+dma_q->mpeg_buffer_completed, | ||
1286 | data, tail_data); | ||
1287 | |||
1288 | buf->vb.state = VIDEOBUF_DONE; | ||
1289 | buf->vb.field_count++; | ||
1290 | do_gettimeofday(&buf->vb.ts); | ||
1291 | list_del(&buf->vb.queue); | ||
1292 | wake_up(&buf->vb.done); | ||
1293 | dma_q->mpeg_buffer_completed = 0; | ||
1294 | |||
1295 | if (len - tail_data > 0) { | ||
1296 | p_data = data + tail_data; | ||
1297 | dma_q->left_data_count = len - tail_data; | ||
1298 | memcpy(dma_q->p_left_data, | ||
1299 | p_data, len - tail_data); | ||
1300 | } | ||
1301 | |||
1302 | } | ||
1303 | |||
1304 | return; | ||
1305 | } | ||
1306 | |||
1307 | static void buffer_filled(char *data, int len, struct urb *urb, | ||
1308 | struct cx231xx_dmaqueue *dma_q) | ||
1309 | { | ||
1310 | void *vbuf; | ||
1311 | struct cx231xx_buffer *buf; | ||
1312 | |||
1313 | if (list_empty(&dma_q->active)) | ||
1314 | return; | ||
1315 | |||
1316 | |||
1317 | buf = list_entry(dma_q->active.next, | ||
1318 | struct cx231xx_buffer, vb.queue); | ||
1319 | |||
1320 | |||
1321 | /* Fill buffer */ | ||
1322 | vbuf = videobuf_to_vmalloc(&buf->vb); | ||
1323 | memcpy(vbuf, data, len); | ||
1324 | buf->vb.state = VIDEOBUF_DONE; | ||
1325 | buf->vb.field_count++; | ||
1326 | do_gettimeofday(&buf->vb.ts); | ||
1327 | list_del(&buf->vb.queue); | ||
1328 | wake_up(&buf->vb.done); | ||
1329 | |||
1330 | return; | ||
1331 | } | ||
1332 | static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) | ||
1333 | { | ||
1334 | struct cx231xx_dmaqueue *dma_q = urb->context; | ||
1335 | unsigned char *p_buffer; | ||
1336 | u32 buffer_size = 0; | ||
1337 | u32 i = 0; | ||
1338 | |||
1339 | for (i = 0; i < urb->number_of_packets; i++) { | ||
1340 | if (dma_q->left_data_count > 0) { | ||
1341 | buffer_copy(dev, dma_q->p_left_data, | ||
1342 | dma_q->left_data_count, urb, dma_q); | ||
1343 | dma_q->mpeg_buffer_completed = dma_q->left_data_count; | ||
1344 | dma_q->left_data_count = 0; | ||
1345 | } | ||
1346 | |||
1347 | p_buffer = urb->transfer_buffer + | ||
1348 | urb->iso_frame_desc[i].offset; | ||
1349 | buffer_size = urb->iso_frame_desc[i].actual_length; | ||
1350 | |||
1351 | if (buffer_size > 0) | ||
1352 | buffer_copy(dev, p_buffer, buffer_size, urb, dma_q); | ||
1353 | } | ||
1354 | |||
1355 | return 0; | ||
1356 | } | ||
1357 | static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) | ||
1358 | { | ||
1359 | |||
1360 | /*char *outp;*/ | ||
1361 | /*struct cx231xx_buffer *buf;*/ | ||
1362 | struct cx231xx_dmaqueue *dma_q = urb->context; | ||
1363 | unsigned char *p_buffer, *buffer; | ||
1364 | u32 buffer_size = 0; | ||
1365 | |||
1366 | p_buffer = urb->transfer_buffer; | ||
1367 | buffer_size = urb->actual_length; | ||
1368 | |||
1369 | buffer = kmalloc(buffer_size, GFP_ATOMIC); | ||
1370 | |||
1371 | memcpy(buffer, dma_q->ps_head, 3); | ||
1372 | memcpy(buffer+3, p_buffer, buffer_size-3); | ||
1373 | memcpy(dma_q->ps_head, p_buffer+buffer_size-3, 3); | ||
1374 | |||
1375 | p_buffer = buffer; | ||
1376 | buffer_filled(p_buffer, buffer_size, urb, dma_q); | ||
1377 | |||
1378 | kfree(buffer); | ||
1379 | return 0; | ||
1380 | } | ||
1381 | |||
1382 | static int bb_buf_prepare(struct videobuf_queue *q, | ||
1383 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
1384 | { | ||
1385 | struct cx231xx_fh *fh = q->priv_data; | ||
1386 | struct cx231xx_buffer *buf = | ||
1387 | container_of(vb, struct cx231xx_buffer, vb); | ||
1388 | struct cx231xx *dev = fh->dev; | ||
1389 | int rc = 0, urb_init = 0; | ||
1390 | int size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; | ||
1391 | |||
1392 | dma_qq = &dev->video_mode.vidq; | ||
1393 | |||
1394 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | ||
1395 | return -EINVAL; | ||
1396 | buf->vb.width = fh->dev->ts1.ts_packet_size; | ||
1397 | buf->vb.height = fh->dev->ts1.ts_packet_count; | ||
1398 | buf->vb.size = size; | ||
1399 | buf->vb.field = field; | ||
1400 | |||
1401 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
1402 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
1403 | if (rc < 0) | ||
1404 | goto fail; | ||
1405 | } | ||
1406 | |||
1407 | if (dev->USE_ISO) { | ||
1408 | if (!dev->video_mode.isoc_ctl.num_bufs) | ||
1409 | urb_init = 1; | ||
1410 | } else { | ||
1411 | if (!dev->video_mode.bulk_ctl.num_bufs) | ||
1412 | urb_init = 1; | ||
1413 | } | ||
1414 | /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", | ||
1415 | urb_init, dev->video_mode.max_pkt_size);*/ | ||
1416 | dev->mode_tv = 1; | ||
1417 | |||
1418 | if (urb_init) { | ||
1419 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | ||
1420 | rc = cx231xx_unmute_audio(dev); | ||
1421 | if (dev->USE_ISO) { | ||
1422 | cx231xx_set_alt_setting(dev, INDEX_TS1, 4); | ||
1423 | rc = cx231xx_init_isoc(dev, mpeglines, | ||
1424 | mpegbufs, | ||
1425 | dev->ts1_mode.max_pkt_size, | ||
1426 | cx231xx_isoc_copy); | ||
1427 | } else { | ||
1428 | cx231xx_set_alt_setting(dev, INDEX_TS1, 0); | ||
1429 | rc = cx231xx_init_bulk(dev, mpeglines, | ||
1430 | mpegbufs, | ||
1431 | dev->ts1_mode.max_pkt_size, | ||
1432 | cx231xx_bulk_copy); | ||
1433 | } | ||
1434 | if (rc < 0) | ||
1435 | goto fail; | ||
1436 | } | ||
1437 | |||
1438 | buf->vb.state = VIDEOBUF_PREPARED; | ||
1439 | return 0; | ||
1440 | |||
1441 | fail: | ||
1442 | free_buffer(q, buf); | ||
1443 | return rc; | ||
1444 | } | ||
1445 | |||
1446 | static void bb_buf_queue(struct videobuf_queue *q, | ||
1447 | struct videobuf_buffer *vb) | ||
1448 | { | ||
1449 | struct cx231xx_fh *fh = q->priv_data; | ||
1450 | |||
1451 | struct cx231xx_buffer *buf = | ||
1452 | container_of(vb, struct cx231xx_buffer, vb); | ||
1453 | struct cx231xx *dev = fh->dev; | ||
1454 | struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; | ||
1455 | |||
1456 | buf->vb.state = VIDEOBUF_QUEUED; | ||
1457 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
1458 | |||
1459 | } | ||
1460 | |||
1461 | static void bb_buf_release(struct videobuf_queue *q, | ||
1462 | struct videobuf_buffer *vb) | ||
1463 | { | ||
1464 | struct cx231xx_buffer *buf = | ||
1465 | container_of(vb, struct cx231xx_buffer, vb); | ||
1466 | /*struct cx231xx_fh *fh = q->priv_data;*/ | ||
1467 | /*struct cx231xx *dev = (struct cx231xx *)fh->dev;*/ | ||
1468 | |||
1469 | free_buffer(q, buf); | ||
1470 | } | ||
1471 | |||
1472 | static struct videobuf_queue_ops cx231xx_qops = { | ||
1473 | .buf_setup = bb_buf_setup, | ||
1474 | .buf_prepare = bb_buf_prepare, | ||
1475 | .buf_queue = bb_buf_queue, | ||
1476 | .buf_release = bb_buf_release, | ||
1477 | }; | ||
1478 | |||
1479 | /* ------------------------------------------------------------------ */ | ||
1480 | |||
1481 | static const u32 *ctrl_classes[] = { | ||
1482 | cx2341x_mpeg_ctrls, | ||
1483 | NULL | ||
1484 | }; | ||
1485 | |||
1486 | static int cx231xx_queryctrl(struct cx231xx *dev, | ||
1487 | struct v4l2_queryctrl *qctrl) | ||
1488 | { | ||
1489 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | ||
1490 | if (qctrl->id == 0) | ||
1491 | return -EINVAL; | ||
1492 | |||
1493 | /* MPEG V4L2 controls */ | ||
1494 | if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl)) | ||
1495 | qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
1496 | |||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1500 | static int cx231xx_querymenu(struct cx231xx *dev, | ||
1501 | struct v4l2_querymenu *qmenu) | ||
1502 | { | ||
1503 | struct v4l2_queryctrl qctrl; | ||
1504 | |||
1505 | qctrl.id = qmenu->id; | ||
1506 | cx231xx_queryctrl(dev, &qctrl); | ||
1507 | return v4l2_ctrl_query_menu(qmenu, &qctrl, | ||
1508 | cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id)); | ||
1509 | } | ||
1510 | |||
1511 | static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm) | ||
1512 | { | ||
1513 | struct cx231xx_fh *fh = file->private_data; | ||
1514 | struct cx231xx *dev = fh->dev; | ||
1515 | |||
1516 | *norm = dev->encodernorm.id; | ||
1517 | return 0; | ||
1518 | } | ||
1519 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) | ||
1520 | { | ||
1521 | struct cx231xx_fh *fh = file->private_data; | ||
1522 | struct cx231xx *dev = fh->dev; | ||
1523 | unsigned int i; | ||
1524 | |||
1525 | for (i = 0; i < ARRAY_SIZE(cx231xx_tvnorms); i++) | ||
1526 | if (*id & cx231xx_tvnorms[i].id) | ||
1527 | break; | ||
1528 | if (i == ARRAY_SIZE(cx231xx_tvnorms)) | ||
1529 | return -EINVAL; | ||
1530 | dev->encodernorm = cx231xx_tvnorms[i]; | ||
1531 | |||
1532 | if (dev->encodernorm.id & 0xb000) { | ||
1533 | dprintk(3, "encodernorm set to NTSC\n"); | ||
1534 | dev->norm = V4L2_STD_NTSC; | ||
1535 | dev->ts1.height = 480; | ||
1536 | dev->mpeg_params.is_50hz = 0; | ||
1537 | } else { | ||
1538 | dprintk(3, "encodernorm set to PAL\n"); | ||
1539 | dev->norm = V4L2_STD_PAL_B; | ||
1540 | dev->ts1.height = 576; | ||
1541 | dev->mpeg_params.is_50hz = 1; | ||
1542 | } | ||
1543 | call_all(dev, core, s_std, dev->norm); | ||
1544 | /* do mode control overrides */ | ||
1545 | cx231xx_do_mode_ctrl_overrides(dev); | ||
1546 | |||
1547 | dprintk(3, "exit vidioc_s_std() i=0x%x\n", i); | ||
1548 | return 0; | ||
1549 | } | ||
1550 | static int vidioc_g_audio(struct file *file, void *fh, | ||
1551 | struct v4l2_audio *a) | ||
1552 | { | ||
1553 | struct v4l2_audio *vin = a; | ||
1554 | |||
1555 | int ret = -EINVAL; | ||
1556 | if (vin->index > 0) | ||
1557 | return ret; | ||
1558 | strncpy(vin->name, "VideoGrabber Audio", 14); | ||
1559 | vin->capability = V4L2_AUDCAP_STEREO; | ||
1560 | return 0; | ||
1561 | } | ||
1562 | static int vidioc_enumaudio(struct file *file, void *fh, | ||
1563 | struct v4l2_audio *a) | ||
1564 | { | ||
1565 | struct v4l2_audio *vin = a; | ||
1566 | |||
1567 | int ret = -EINVAL; | ||
1568 | |||
1569 | if (vin->index > 0) | ||
1570 | return ret; | ||
1571 | strncpy(vin->name, "VideoGrabber Audio", 14); | ||
1572 | vin->capability = V4L2_AUDCAP_STEREO; | ||
1573 | |||
1574 | |||
1575 | return 0; | ||
1576 | } | ||
1577 | static const char *iname[] = { | ||
1578 | [CX231XX_VMUX_COMPOSITE1] = "Composite1", | ||
1579 | [CX231XX_VMUX_SVIDEO] = "S-Video", | ||
1580 | [CX231XX_VMUX_TELEVISION] = "Television", | ||
1581 | [CX231XX_VMUX_CABLE] = "Cable TV", | ||
1582 | [CX231XX_VMUX_DVB] = "DVB", | ||
1583 | [CX231XX_VMUX_DEBUG] = "for debug only", | ||
1584 | }; | ||
1585 | static int vidioc_enum_input(struct file *file, void *priv, | ||
1586 | struct v4l2_input *i) | ||
1587 | { | ||
1588 | struct cx231xx_fh *fh = file->private_data; | ||
1589 | struct cx231xx *dev = fh->dev; | ||
1590 | struct cx231xx_input *input; | ||
1591 | int n; | ||
1592 | dprintk(3, "enter vidioc_enum_input()i->index=%d\n", i->index); | ||
1593 | |||
1594 | if (i->index >= 4) | ||
1595 | return -EINVAL; | ||
1596 | |||
1597 | |||
1598 | input = &cx231xx_boards[dev->model].input[i->index]; | ||
1599 | |||
1600 | if (input->type == 0) | ||
1601 | return -EINVAL; | ||
1602 | |||
1603 | /* FIXME | ||
1604 | * strcpy(i->name, input->name); */ | ||
1605 | |||
1606 | n = i->index; | ||
1607 | strcpy(i->name, iname[INPUT(n)->type]); | ||
1608 | |||
1609 | if (input->type == CX231XX_VMUX_TELEVISION || | ||
1610 | input->type == CX231XX_VMUX_CABLE) | ||
1611 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1612 | else | ||
1613 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1614 | |||
1615 | |||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
1620 | { | ||
1621 | *i = 0; | ||
1622 | return 0; | ||
1623 | } | ||
1624 | |||
1625 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
1626 | { | ||
1627 | struct cx231xx_fh *fh = file->private_data; | ||
1628 | struct cx231xx *dev = fh->dev; | ||
1629 | |||
1630 | dprintk(3, "enter vidioc_s_input() i=%d\n", i); | ||
1631 | |||
1632 | mutex_lock(&dev->lock); | ||
1633 | |||
1634 | video_mux(dev, i); | ||
1635 | |||
1636 | mutex_unlock(&dev->lock); | ||
1637 | |||
1638 | if (i >= 4) | ||
1639 | return -EINVAL; | ||
1640 | dev->input = i; | ||
1641 | dprintk(3, "exit vidioc_s_input()\n"); | ||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1645 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
1646 | struct v4l2_tuner *t) | ||
1647 | { | ||
1648 | return 0; | ||
1649 | } | ||
1650 | |||
1651 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
1652 | struct v4l2_tuner *t) | ||
1653 | { | ||
1654 | return 0; | ||
1655 | } | ||
1656 | |||
1657 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
1658 | struct v4l2_frequency *f) | ||
1659 | { | ||
1660 | return 0; | ||
1661 | } | ||
1662 | |||
1663 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
1664 | struct v4l2_frequency *f) | ||
1665 | { | ||
1666 | |||
1667 | |||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1672 | struct v4l2_control *ctl) | ||
1673 | { | ||
1674 | struct cx231xx_fh *fh = file->private_data; | ||
1675 | struct cx231xx *dev = fh->dev; | ||
1676 | dprintk(3, "enter vidioc_s_ctrl()\n"); | ||
1677 | /* Update the A/V core */ | ||
1678 | call_all(dev, core, s_ctrl, ctl); | ||
1679 | dprintk(3, "exit vidioc_s_ctrl()\n"); | ||
1680 | return 0; | ||
1681 | } | ||
1682 | static struct v4l2_capability pvr_capability = { | ||
1683 | .driver = "cx231xx", | ||
1684 | .card = "VideoGrabber", | ||
1685 | .bus_info = "usb", | ||
1686 | .version = 1, | ||
1687 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | | ||
1688 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | | ||
1689 | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE), | ||
1690 | .reserved = {0, 0, 0, 0} | ||
1691 | }; | ||
1692 | static int vidioc_querycap(struct file *file, void *priv, | ||
1693 | struct v4l2_capability *cap) | ||
1694 | { | ||
1695 | |||
1696 | |||
1697 | |||
1698 | memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); | ||
1699 | return 0; | ||
1700 | } | ||
1701 | |||
1702 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
1703 | struct v4l2_fmtdesc *f) | ||
1704 | { | ||
1705 | |||
1706 | if (f->index != 0) | ||
1707 | return -EINVAL; | ||
1708 | |||
1709 | strlcpy(f->description, "MPEG", sizeof(f->description)); | ||
1710 | f->pixelformat = V4L2_PIX_FMT_MPEG; | ||
1711 | |||
1712 | return 0; | ||
1713 | } | ||
1714 | |||
1715 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
1716 | struct v4l2_format *f) | ||
1717 | { | ||
1718 | struct cx231xx_fh *fh = file->private_data; | ||
1719 | struct cx231xx *dev = fh->dev; | ||
1720 | dprintk(3, "enter vidioc_g_fmt_vid_cap()\n"); | ||
1721 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1722 | f->fmt.pix.bytesperline = 0; | ||
1723 | f->fmt.pix.sizeimage = | ||
1724 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | ||
1725 | f->fmt.pix.colorspace = 0; | ||
1726 | f->fmt.pix.width = dev->ts1.width; | ||
1727 | f->fmt.pix.height = dev->ts1.height; | ||
1728 | f->fmt.pix.field = fh->vidq.field; | ||
1729 | dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", | ||
1730 | dev->ts1.width, dev->ts1.height, fh->vidq.field); | ||
1731 | dprintk(3, "exit vidioc_g_fmt_vid_cap()\n"); | ||
1732 | return 0; | ||
1733 | } | ||
1734 | |||
1735 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
1736 | struct v4l2_format *f) | ||
1737 | { | ||
1738 | struct cx231xx_fh *fh = file->private_data; | ||
1739 | struct cx231xx *dev = fh->dev; | ||
1740 | dprintk(3, "enter vidioc_try_fmt_vid_cap()\n"); | ||
1741 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1742 | f->fmt.pix.bytesperline = 0; | ||
1743 | f->fmt.pix.sizeimage = | ||
1744 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | ||
1745 | f->fmt.pix.colorspace = 0; | ||
1746 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", | ||
1747 | dev->ts1.width, dev->ts1.height, fh->vidq.field); | ||
1748 | dprintk(3, "exit vidioc_try_fmt_vid_cap()\n"); | ||
1749 | return 0; | ||
1750 | } | ||
1751 | |||
1752 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
1753 | struct v4l2_format *f) | ||
1754 | { | ||
1755 | |||
1756 | return 0; | ||
1757 | } | ||
1758 | |||
1759 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
1760 | struct v4l2_requestbuffers *p) | ||
1761 | { | ||
1762 | struct cx231xx_fh *fh = file->private_data; | ||
1763 | |||
1764 | return videobuf_reqbufs(&fh->vidq, p); | ||
1765 | } | ||
1766 | |||
1767 | static int vidioc_querybuf(struct file *file, void *priv, | ||
1768 | struct v4l2_buffer *p) | ||
1769 | { | ||
1770 | struct cx231xx_fh *fh = file->private_data; | ||
1771 | |||
1772 | return videobuf_querybuf(&fh->vidq, p); | ||
1773 | } | ||
1774 | |||
1775 | static int vidioc_qbuf(struct file *file, void *priv, | ||
1776 | struct v4l2_buffer *p) | ||
1777 | { | ||
1778 | struct cx231xx_fh *fh = file->private_data; | ||
1779 | |||
1780 | return videobuf_qbuf(&fh->vidq, p); | ||
1781 | } | ||
1782 | |||
1783 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
1784 | { | ||
1785 | struct cx231xx_fh *fh = priv; | ||
1786 | |||
1787 | return videobuf_dqbuf(&fh->vidq, b, file->f_flags & O_NONBLOCK); | ||
1788 | } | ||
1789 | |||
1790 | |||
1791 | static int vidioc_streamon(struct file *file, void *priv, | ||
1792 | enum v4l2_buf_type i) | ||
1793 | { | ||
1794 | struct cx231xx_fh *fh = file->private_data; | ||
1795 | |||
1796 | struct cx231xx *dev = fh->dev; | ||
1797 | int rc = 0; | ||
1798 | dprintk(3, "enter vidioc_streamon()\n"); | ||
1799 | cx231xx_set_alt_setting(dev, INDEX_TS1, 0); | ||
1800 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | ||
1801 | if (dev->USE_ISO) | ||
1802 | rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, | ||
1803 | CX231XX_NUM_BUFS, | ||
1804 | dev->video_mode.max_pkt_size, | ||
1805 | cx231xx_isoc_copy); | ||
1806 | else { | ||
1807 | rc = cx231xx_init_bulk(dev, 320, | ||
1808 | 5, | ||
1809 | dev->ts1_mode.max_pkt_size, | ||
1810 | cx231xx_bulk_copy); | ||
1811 | } | ||
1812 | dprintk(3, "exit vidioc_streamon()\n"); | ||
1813 | return videobuf_streamon(&fh->vidq); | ||
1814 | } | ||
1815 | |||
1816 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | ||
1817 | { | ||
1818 | struct cx231xx_fh *fh = file->private_data; | ||
1819 | |||
1820 | return videobuf_streamoff(&fh->vidq); | ||
1821 | } | ||
1822 | |||
1823 | static int vidioc_g_ext_ctrls(struct file *file, void *priv, | ||
1824 | struct v4l2_ext_controls *f) | ||
1825 | { | ||
1826 | struct cx231xx_fh *fh = priv; | ||
1827 | struct cx231xx *dev = fh->dev; | ||
1828 | dprintk(3, "enter vidioc_g_ext_ctrls()\n"); | ||
1829 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
1830 | return -EINVAL; | ||
1831 | dprintk(3, "exit vidioc_g_ext_ctrls()\n"); | ||
1832 | return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS); | ||
1833 | } | ||
1834 | |||
1835 | static int vidioc_s_ext_ctrls(struct file *file, void *priv, | ||
1836 | struct v4l2_ext_controls *f) | ||
1837 | { | ||
1838 | struct cx231xx_fh *fh = priv; | ||
1839 | struct cx231xx *dev = fh->dev; | ||
1840 | struct cx2341x_mpeg_params p; | ||
1841 | int err; | ||
1842 | dprintk(3, "enter vidioc_s_ext_ctrls()\n"); | ||
1843 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
1844 | return -EINVAL; | ||
1845 | |||
1846 | p = dev->mpeg_params; | ||
1847 | err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); | ||
1848 | if (err == 0) { | ||
1849 | err = cx2341x_update(dev, cx231xx_mbox_func, | ||
1850 | &dev->mpeg_params, &p); | ||
1851 | dev->mpeg_params = p; | ||
1852 | } | ||
1853 | |||
1854 | return err; | ||
1855 | |||
1856 | |||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | static int vidioc_try_ext_ctrls(struct file *file, void *priv, | ||
1861 | struct v4l2_ext_controls *f) | ||
1862 | { | ||
1863 | struct cx231xx_fh *fh = priv; | ||
1864 | struct cx231xx *dev = fh->dev; | ||
1865 | struct cx2341x_mpeg_params p; | ||
1866 | int err; | ||
1867 | dprintk(3, "enter vidioc_try_ext_ctrls()\n"); | ||
1868 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
1869 | return -EINVAL; | ||
1870 | |||
1871 | p = dev->mpeg_params; | ||
1872 | err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); | ||
1873 | dprintk(3, "exit vidioc_try_ext_ctrls() err=%d\n", err); | ||
1874 | return err; | ||
1875 | } | ||
1876 | |||
1877 | static int vidioc_log_status(struct file *file, void *priv) | ||
1878 | { | ||
1879 | struct cx231xx_fh *fh = priv; | ||
1880 | struct cx231xx *dev = fh->dev; | ||
1881 | char name[32 + 2]; | ||
1882 | |||
1883 | snprintf(name, sizeof(name), "%s/2", dev->name); | ||
1884 | dprintk(3, | ||
1885 | "%s/2: ============ START LOG STATUS ============\n", | ||
1886 | dev->name); | ||
1887 | call_all(dev, core, log_status); | ||
1888 | cx2341x_log_status(&dev->mpeg_params, name); | ||
1889 | dprintk(3, | ||
1890 | "%s/2: ============= END LOG STATUS =============\n", | ||
1891 | dev->name); | ||
1892 | return 0; | ||
1893 | } | ||
1894 | |||
1895 | static int vidioc_querymenu(struct file *file, void *priv, | ||
1896 | struct v4l2_querymenu *a) | ||
1897 | { | ||
1898 | struct cx231xx_fh *fh = priv; | ||
1899 | struct cx231xx *dev = fh->dev; | ||
1900 | dprintk(3, "enter vidioc_querymenu()\n"); | ||
1901 | dprintk(3, "exit vidioc_querymenu()\n"); | ||
1902 | return cx231xx_querymenu(dev, a); | ||
1903 | } | ||
1904 | |||
1905 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
1906 | struct v4l2_queryctrl *c) | ||
1907 | { | ||
1908 | struct cx231xx_fh *fh = priv; | ||
1909 | struct cx231xx *dev = fh->dev; | ||
1910 | dprintk(3, "enter vidioc_queryctrl()\n"); | ||
1911 | dprintk(3, "exit vidioc_queryctrl()\n"); | ||
1912 | return cx231xx_queryctrl(dev, c); | ||
1913 | } | ||
1914 | |||
1915 | static int mpeg_open(struct file *file) | ||
1916 | { | ||
1917 | int minor = video_devdata(file)->minor; | ||
1918 | struct cx231xx *h, *dev = NULL; | ||
1919 | /*struct list_head *list;*/ | ||
1920 | struct cx231xx_fh *fh; | ||
1921 | /*u32 value = 0;*/ | ||
1922 | |||
1923 | dprintk(2, "%s()\n", __func__); | ||
1924 | |||
1925 | list_for_each_entry(h, &cx231xx_devlist, devlist) { | ||
1926 | if (h->v4l_device->minor == minor) | ||
1927 | dev = h; | ||
1928 | } | ||
1929 | |||
1930 | if (dev == NULL) { | ||
1931 | unlock_kernel(); | ||
1932 | return -ENODEV; | ||
1933 | } | ||
1934 | mutex_lock(&dev->lock); | ||
1935 | |||
1936 | /* allocate + initialize per filehandle data */ | ||
1937 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1938 | if (NULL == fh) { | ||
1939 | mutex_unlock(&dev->lock); | ||
1940 | return -ENOMEM; | ||
1941 | } | ||
1942 | |||
1943 | file->private_data = fh; | ||
1944 | fh->dev = dev; | ||
1945 | |||
1946 | |||
1947 | videobuf_queue_vmalloc_init(&fh->vidq, &cx231xx_qops, | ||
1948 | NULL, &dev->video_mode.slock, | ||
1949 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, | ||
1950 | sizeof(struct cx231xx_buffer), fh, NULL); | ||
1951 | /* | ||
1952 | videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops, | ||
1953 | &dev->udev->dev, &dev->ts1.slock, | ||
1954 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1955 | V4L2_FIELD_INTERLACED, | ||
1956 | sizeof(struct cx231xx_buffer), | ||
1957 | fh, NULL); | ||
1958 | */ | ||
1959 | |||
1960 | |||
1961 | cx231xx_set_alt_setting(dev, INDEX_VANC, 1); | ||
1962 | cx231xx_set_gpio_value(dev, 2, 0); | ||
1963 | |||
1964 | cx231xx_initialize_codec(dev); | ||
1965 | |||
1966 | mutex_unlock(&dev->lock); | ||
1967 | cx231xx_start_TS1(dev); | ||
1968 | |||
1969 | return 0; | ||
1970 | } | ||
1971 | |||
1972 | static int mpeg_release(struct file *file) | ||
1973 | { | ||
1974 | struct cx231xx_fh *fh = file->private_data; | ||
1975 | struct cx231xx *dev = fh->dev; | ||
1976 | |||
1977 | dprintk(3, "mpeg_release()! dev=0x%p\n", dev); | ||
1978 | |||
1979 | if (!dev) { | ||
1980 | dprintk(3, "abort!!!\n"); | ||
1981 | return 0; | ||
1982 | } | ||
1983 | |||
1984 | mutex_lock(&dev->lock); | ||
1985 | |||
1986 | cx231xx_stop_TS1(dev); | ||
1987 | |||
1988 | /* do this before setting alternate! */ | ||
1989 | if (dev->USE_ISO) | ||
1990 | cx231xx_uninit_isoc(dev); | ||
1991 | else | ||
1992 | cx231xx_uninit_bulk(dev); | ||
1993 | cx231xx_set_mode(dev, CX231XX_SUSPEND); | ||
1994 | |||
1995 | cx231xx_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | ||
1996 | CX231xx_END_NOW, CX231xx_MPEG_CAPTURE, | ||
1997 | CX231xx_RAW_BITS_NONE); | ||
1998 | |||
1999 | /* FIXME: Review this crap */ | ||
2000 | /* Shut device down on last close */ | ||
2001 | if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { | ||
2002 | if (atomic_dec_return(&dev->v4l_reader_count) == 0) { | ||
2003 | /* stop mpeg capture */ | ||
2004 | |||
2005 | msleep(500); | ||
2006 | cx231xx_417_check_encoder(dev); | ||
2007 | |||
2008 | } | ||
2009 | } | ||
2010 | |||
2011 | if (fh->vidq.streaming) | ||
2012 | videobuf_streamoff(&fh->vidq); | ||
2013 | if (fh->vidq.reading) | ||
2014 | videobuf_read_stop(&fh->vidq); | ||
2015 | |||
2016 | videobuf_mmap_free(&fh->vidq); | ||
2017 | file->private_data = NULL; | ||
2018 | kfree(fh); | ||
2019 | mutex_unlock(&dev->lock); | ||
2020 | return 0; | ||
2021 | } | ||
2022 | |||
2023 | static ssize_t mpeg_read(struct file *file, char __user *data, | ||
2024 | size_t count, loff_t *ppos) | ||
2025 | { | ||
2026 | struct cx231xx_fh *fh = file->private_data; | ||
2027 | struct cx231xx *dev = fh->dev; | ||
2028 | |||
2029 | |||
2030 | /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ | ||
2031 | /* Start mpeg encoder on first read. */ | ||
2032 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
2033 | if (atomic_inc_return(&dev->v4l_reader_count) == 1) { | ||
2034 | if (cx231xx_initialize_codec(dev) < 0) | ||
2035 | return -EINVAL; | ||
2036 | } | ||
2037 | } | ||
2038 | |||
2039 | return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, | ||
2040 | file->f_flags & O_NONBLOCK); | ||
2041 | } | ||
2042 | |||
2043 | static unsigned int mpeg_poll(struct file *file, | ||
2044 | struct poll_table_struct *wait) | ||
2045 | { | ||
2046 | struct cx231xx_fh *fh = file->private_data; | ||
2047 | /*struct cx231xx *dev = fh->dev;*/ | ||
2048 | |||
2049 | /*dprintk(2, "%s\n", __func__);*/ | ||
2050 | |||
2051 | return videobuf_poll_stream(file, &fh->vidq, wait); | ||
2052 | } | ||
2053 | |||
2054 | static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) | ||
2055 | { | ||
2056 | struct cx231xx_fh *fh = file->private_data; | ||
2057 | struct cx231xx *dev = fh->dev; | ||
2058 | |||
2059 | dprintk(2, "%s()\n", __func__); | ||
2060 | |||
2061 | return videobuf_mmap_mapper(&fh->vidq, vma); | ||
2062 | } | ||
2063 | |||
2064 | static struct v4l2_file_operations mpeg_fops = { | ||
2065 | .owner = THIS_MODULE, | ||
2066 | .open = mpeg_open, | ||
2067 | .release = mpeg_release, | ||
2068 | .read = mpeg_read, | ||
2069 | .poll = mpeg_poll, | ||
2070 | .mmap = mpeg_mmap, | ||
2071 | .ioctl = video_ioctl2, | ||
2072 | }; | ||
2073 | |||
2074 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | ||
2075 | .vidioc_s_std = vidioc_s_std, | ||
2076 | .vidioc_g_std = vidioc_g_std, | ||
2077 | .vidioc_enum_input = vidioc_enum_input, | ||
2078 | .vidioc_enumaudio = vidioc_enumaudio, | ||
2079 | .vidioc_g_audio = vidioc_g_audio, | ||
2080 | .vidioc_g_input = vidioc_g_input, | ||
2081 | .vidioc_s_input = vidioc_s_input, | ||
2082 | .vidioc_g_tuner = vidioc_g_tuner, | ||
2083 | .vidioc_s_tuner = vidioc_s_tuner, | ||
2084 | .vidioc_g_frequency = vidioc_g_frequency, | ||
2085 | .vidioc_s_frequency = vidioc_s_frequency, | ||
2086 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2087 | .vidioc_querycap = vidioc_querycap, | ||
2088 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
2089 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
2090 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
2091 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
2092 | .vidioc_reqbufs = vidioc_reqbufs, | ||
2093 | .vidioc_querybuf = vidioc_querybuf, | ||
2094 | .vidioc_qbuf = vidioc_qbuf, | ||
2095 | .vidioc_dqbuf = vidioc_dqbuf, | ||
2096 | .vidioc_streamon = vidioc_streamon, | ||
2097 | .vidioc_streamoff = vidioc_streamoff, | ||
2098 | .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, | ||
2099 | .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, | ||
2100 | .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, | ||
2101 | .vidioc_log_status = vidioc_log_status, | ||
2102 | .vidioc_querymenu = vidioc_querymenu, | ||
2103 | .vidioc_queryctrl = vidioc_queryctrl, | ||
2104 | /* .vidioc_g_chip_ident = cx231xx_g_chip_ident,*/ | ||
2105 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2106 | /* .vidioc_g_register = cx231xx_g_register,*/ | ||
2107 | /* .vidioc_s_register = cx231xx_s_register,*/ | ||
2108 | #endif | ||
2109 | }; | ||
2110 | |||
2111 | static struct video_device cx231xx_mpeg_template = { | ||
2112 | .name = "cx231xx", | ||
2113 | .fops = &mpeg_fops, | ||
2114 | .ioctl_ops = &mpeg_ioctl_ops, | ||
2115 | .minor = -1, | ||
2116 | .tvnorms = CX231xx_NORMS, | ||
2117 | .current_norm = V4L2_STD_NTSC_M, | ||
2118 | }; | ||
2119 | |||
2120 | void cx231xx_417_unregister(struct cx231xx *dev) | ||
2121 | { | ||
2122 | dprintk(1, "%s()\n", __func__); | ||
2123 | dprintk(3, "%s()\n", __func__); | ||
2124 | |||
2125 | if (dev->v4l_device) { | ||
2126 | if (-1 != dev->v4l_device->minor) | ||
2127 | video_unregister_device(dev->v4l_device); | ||
2128 | else | ||
2129 | video_device_release(dev->v4l_device); | ||
2130 | dev->v4l_device = NULL; | ||
2131 | } | ||
2132 | } | ||
2133 | |||
2134 | static struct video_device *cx231xx_video_dev_alloc( | ||
2135 | struct cx231xx *dev, | ||
2136 | struct usb_device *usbdev, | ||
2137 | struct video_device *template, | ||
2138 | char *type) | ||
2139 | { | ||
2140 | struct video_device *vfd; | ||
2141 | |||
2142 | dprintk(1, "%s()\n", __func__); | ||
2143 | vfd = video_device_alloc(); | ||
2144 | if (NULL == vfd) | ||
2145 | return NULL; | ||
2146 | *vfd = *template; | ||
2147 | vfd->minor = -1; | ||
2148 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | ||
2149 | type, cx231xx_boards[dev->model].name); | ||
2150 | |||
2151 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
2152 | vfd->release = video_device_release; | ||
2153 | |||
2154 | return vfd; | ||
2155 | |||
2156 | } | ||
2157 | |||
2158 | int cx231xx_417_register(struct cx231xx *dev) | ||
2159 | { | ||
2160 | /* FIXME: Port1 hardcoded here */ | ||
2161 | int err = -ENODEV; | ||
2162 | struct cx231xx_tsport *tsport = &dev->ts1; | ||
2163 | |||
2164 | dprintk(1, "%s()\n", __func__); | ||
2165 | |||
2166 | /* Set default TV standard */ | ||
2167 | dev->encodernorm = cx231xx_tvnorms[0]; | ||
2168 | |||
2169 | if (dev->encodernorm.id & V4L2_STD_525_60) | ||
2170 | tsport->height = 480; | ||
2171 | else | ||
2172 | tsport->height = 576; | ||
2173 | |||
2174 | tsport->width = 720; | ||
2175 | cx2341x_fill_defaults(&dev->mpeg_params); | ||
2176 | dev->norm = V4L2_STD_NTSC; | ||
2177 | |||
2178 | dev->mpeg_params.port = CX2341X_PORT_SERIAL; | ||
2179 | |||
2180 | /* Allocate and initialize V4L video device */ | ||
2181 | dev->v4l_device = cx231xx_video_dev_alloc(dev, | ||
2182 | dev->udev, &cx231xx_mpeg_template, "mpeg"); | ||
2183 | err = video_register_device(dev->v4l_device, | ||
2184 | VFL_TYPE_GRABBER, -1); | ||
2185 | if (err < 0) { | ||
2186 | dprintk(3, "%s: can't register mpeg device\n", dev->name); | ||
2187 | return err; | ||
2188 | } | ||
2189 | |||
2190 | dprintk(3, "%s: registered device video%d [mpeg]\n", | ||
2191 | dev->name, dev->v4l_device->num); | ||
2192 | |||
2193 | return 0; | ||
2194 | } | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c index 7cae95a2245..30d13c15739 100644 --- a/drivers/media/video/cx231xx/cx231xx-audio.c +++ b/drivers/media/video/cx231xx/cx231xx-audio.c | |||
@@ -75,6 +75,30 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int cx231xx_bulk_audio_deinit(struct cx231xx *dev) | ||
79 | { | ||
80 | int i; | ||
81 | |||
82 | dprintk("Stopping bulk\n"); | ||
83 | |||
84 | for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { | ||
85 | if (dev->adev.urb[i]) { | ||
86 | if (!irqs_disabled()) | ||
87 | usb_kill_urb(dev->adev.urb[i]); | ||
88 | else | ||
89 | usb_unlink_urb(dev->adev.urb[i]); | ||
90 | |||
91 | usb_free_urb(dev->adev.urb[i]); | ||
92 | dev->adev.urb[i] = NULL; | ||
93 | |||
94 | kfree(dev->adev.transfer_buffer[i]); | ||
95 | dev->adev.transfer_buffer[i] = NULL; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
78 | static void cx231xx_audio_isocirq(struct urb *urb) | 102 | static void cx231xx_audio_isocirq(struct urb *urb) |
79 | { | 103 | { |
80 | struct cx231xx *dev = urb->context; | 104 | struct cx231xx *dev = urb->context; |
@@ -100,6 +124,9 @@ static void cx231xx_audio_isocirq(struct urb *urb) | |||
100 | break; | 124 | break; |
101 | } | 125 | } |
102 | 126 | ||
127 | if (atomic_read(&dev->stream_started) == 0) | ||
128 | return; | ||
129 | |||
103 | if (dev->adev.capture_pcm_substream) { | 130 | if (dev->adev.capture_pcm_substream) { |
104 | substream = dev->adev.capture_pcm_substream; | 131 | substream = dev->adev.capture_pcm_substream; |
105 | runtime = substream->runtime; | 132 | runtime = substream->runtime; |
@@ -158,14 +185,95 @@ static void cx231xx_audio_isocirq(struct urb *urb) | |||
158 | return; | 185 | return; |
159 | } | 186 | } |
160 | 187 | ||
188 | static void cx231xx_audio_bulkirq(struct urb *urb) | ||
189 | { | ||
190 | struct cx231xx *dev = urb->context; | ||
191 | unsigned int oldptr; | ||
192 | int period_elapsed = 0; | ||
193 | int status; | ||
194 | unsigned char *cp; | ||
195 | unsigned int stride; | ||
196 | struct snd_pcm_substream *substream; | ||
197 | struct snd_pcm_runtime *runtime; | ||
198 | |||
199 | switch (urb->status) { | ||
200 | case 0: /* success */ | ||
201 | case -ETIMEDOUT: /* NAK */ | ||
202 | break; | ||
203 | case -ECONNRESET: /* kill */ | ||
204 | case -ENOENT: | ||
205 | case -ESHUTDOWN: | ||
206 | return; | ||
207 | default: /* error */ | ||
208 | dprintk("urb completition error %d.\n", urb->status); | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | if (atomic_read(&dev->stream_started) == 0) | ||
213 | return; | ||
214 | |||
215 | if (dev->adev.capture_pcm_substream) { | ||
216 | substream = dev->adev.capture_pcm_substream; | ||
217 | runtime = substream->runtime; | ||
218 | stride = runtime->frame_bits >> 3; | ||
219 | |||
220 | if (1) { | ||
221 | int length = urb->actual_length / | ||
222 | stride; | ||
223 | cp = (unsigned char *)urb->transfer_buffer; | ||
224 | |||
225 | oldptr = dev->adev.hwptr_done_capture; | ||
226 | if (oldptr + length >= runtime->buffer_size) { | ||
227 | unsigned int cnt; | ||
228 | |||
229 | cnt = runtime->buffer_size - oldptr; | ||
230 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
231 | cnt * stride); | ||
232 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
233 | length * stride - cnt * stride); | ||
234 | } else { | ||
235 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
236 | length * stride); | ||
237 | } | ||
238 | |||
239 | snd_pcm_stream_lock(substream); | ||
240 | |||
241 | dev->adev.hwptr_done_capture += length; | ||
242 | if (dev->adev.hwptr_done_capture >= | ||
243 | runtime->buffer_size) | ||
244 | dev->adev.hwptr_done_capture -= | ||
245 | runtime->buffer_size; | ||
246 | |||
247 | dev->adev.capture_transfer_done += length; | ||
248 | if (dev->adev.capture_transfer_done >= | ||
249 | runtime->period_size) { | ||
250 | dev->adev.capture_transfer_done -= | ||
251 | runtime->period_size; | ||
252 | period_elapsed = 1; | ||
253 | } | ||
254 | snd_pcm_stream_unlock(substream); | ||
255 | } | ||
256 | if (period_elapsed) | ||
257 | snd_pcm_period_elapsed(substream); | ||
258 | } | ||
259 | urb->status = 0; | ||
260 | |||
261 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
262 | if (status < 0) { | ||
263 | cx231xx_errdev("resubmit of audio urb failed (error=%i)\n", | ||
264 | status); | ||
265 | } | ||
266 | return; | ||
267 | } | ||
268 | |||
161 | static int cx231xx_init_audio_isoc(struct cx231xx *dev) | 269 | static int cx231xx_init_audio_isoc(struct cx231xx *dev) |
162 | { | 270 | { |
163 | int i, errCode; | 271 | int i, errCode; |
164 | int sb_size; | 272 | int sb_size; |
165 | 273 | ||
166 | cx231xx_info("%s: Starting AUDIO transfers\n", __func__); | 274 | cx231xx_info("%s: Starting ISO AUDIO transfers\n", __func__); |
167 | 275 | ||
168 | sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; | 276 | sb_size = CX231XX_ISO_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; |
169 | 277 | ||
170 | for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { | 278 | for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { |
171 | struct urb *urb; | 279 | struct urb *urb; |
@@ -176,7 +284,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) | |||
176 | return -ENOMEM; | 284 | return -ENOMEM; |
177 | 285 | ||
178 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); | 286 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); |
179 | urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); | 287 | urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); |
180 | if (!urb) { | 288 | if (!urb) { |
181 | cx231xx_errdev("usb_alloc_urb failed!\n"); | 289 | cx231xx_errdev("usb_alloc_urb failed!\n"); |
182 | for (j = 0; j < i; j++) { | 290 | for (j = 0; j < i; j++) { |
@@ -194,10 +302,10 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) | |||
194 | urb->transfer_buffer = dev->adev.transfer_buffer[i]; | 302 | urb->transfer_buffer = dev->adev.transfer_buffer[i]; |
195 | urb->interval = 1; | 303 | urb->interval = 1; |
196 | urb->complete = cx231xx_audio_isocirq; | 304 | urb->complete = cx231xx_audio_isocirq; |
197 | urb->number_of_packets = CX231XX_NUM_AUDIO_PACKETS; | 305 | urb->number_of_packets = CX231XX_ISO_NUM_AUDIO_PACKETS; |
198 | urb->transfer_buffer_length = sb_size; | 306 | urb->transfer_buffer_length = sb_size; |
199 | 307 | ||
200 | for (j = k = 0; j < CX231XX_NUM_AUDIO_PACKETS; | 308 | for (j = k = 0; j < CX231XX_ISO_NUM_AUDIO_PACKETS; |
201 | j++, k += dev->adev.max_pkt_size) { | 309 | j++, k += dev->adev.max_pkt_size) { |
202 | urb->iso_frame_desc[j].offset = k; | 310 | urb->iso_frame_desc[j].offset = k; |
203 | urb->iso_frame_desc[j].length = dev->adev.max_pkt_size; | 311 | urb->iso_frame_desc[j].length = dev->adev.max_pkt_size; |
@@ -216,27 +324,56 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) | |||
216 | return errCode; | 324 | return errCode; |
217 | } | 325 | } |
218 | 326 | ||
219 | static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg) | 327 | static int cx231xx_init_audio_bulk(struct cx231xx *dev) |
220 | { | 328 | { |
221 | dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ? | 329 | int i, errCode; |
222 | "stop" : "start"); | 330 | int sb_size; |
223 | 331 | ||
224 | switch (cmd) { | 332 | cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__); |
225 | case CX231XX_CAPTURE_STREAM_EN: | 333 | |
226 | if (dev->adev.capture_stream == STREAM_OFF && arg == 1) { | 334 | sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; |
227 | dev->adev.capture_stream = STREAM_ON; | 335 | |
228 | cx231xx_init_audio_isoc(dev); | 336 | for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { |
229 | } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { | 337 | struct urb *urb; |
230 | dev->adev.capture_stream = STREAM_OFF; | 338 | int j; |
231 | cx231xx_isoc_audio_deinit(dev); | 339 | |
232 | } else { | 340 | dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); |
233 | cx231xx_errdev("An underrun very likely occurred. " | 341 | if (!dev->adev.transfer_buffer[i]) |
234 | "Ignoring it.\n"); | 342 | return -ENOMEM; |
343 | |||
344 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); | ||
345 | urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); | ||
346 | if (!urb) { | ||
347 | cx231xx_errdev("usb_alloc_urb failed!\n"); | ||
348 | for (j = 0; j < i; j++) { | ||
349 | usb_free_urb(dev->adev.urb[j]); | ||
350 | kfree(dev->adev.transfer_buffer[j]); | ||
351 | } | ||
352 | return -ENOMEM; | ||
235 | } | 353 | } |
236 | return 0; | 354 | |
237 | default: | 355 | urb->dev = dev->udev; |
238 | return -EINVAL; | 356 | urb->context = dev; |
357 | urb->pipe = usb_rcvbulkpipe(dev->udev, | ||
358 | dev->adev.end_point_addr); | ||
359 | urb->transfer_flags = 0; | ||
360 | urb->transfer_buffer = dev->adev.transfer_buffer[i]; | ||
361 | urb->complete = cx231xx_audio_bulkirq; | ||
362 | urb->transfer_buffer_length = sb_size; | ||
363 | |||
364 | dev->adev.urb[i] = urb; | ||
365 | |||
239 | } | 366 | } |
367 | |||
368 | for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { | ||
369 | errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); | ||
370 | if (errCode < 0) { | ||
371 | cx231xx_bulk_audio_deinit(dev); | ||
372 | return errCode; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | return errCode; | ||
240 | } | 377 | } |
241 | 378 | ||
242 | static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, | 379 | static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, |
@@ -300,19 +437,24 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) | |||
300 | 437 | ||
301 | /* set alternate setting for audio interface */ | 438 | /* set alternate setting for audio interface */ |
302 | /* 1 - 48000 samples per sec */ | 439 | /* 1 - 48000 samples per sec */ |
303 | ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1); | 440 | mutex_lock(&dev->lock); |
441 | if (dev->USE_ISO) | ||
442 | ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1); | ||
443 | else | ||
444 | ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); | ||
445 | mutex_unlock(&dev->lock); | ||
304 | if (ret < 0) { | 446 | if (ret < 0) { |
305 | cx231xx_errdev("failed to set alternate setting !\n"); | 447 | cx231xx_errdev("failed to set alternate setting !\n"); |
306 | 448 | ||
307 | return ret; | 449 | return ret; |
308 | } | 450 | } |
309 | 451 | ||
310 | /* inform hardware to start streaming */ | ||
311 | ret = cx231xx_capture_start(dev, 1, Audio); | ||
312 | |||
313 | runtime->hw = snd_cx231xx_hw_capture; | 452 | runtime->hw = snd_cx231xx_hw_capture; |
314 | 453 | ||
315 | mutex_lock(&dev->lock); | 454 | mutex_lock(&dev->lock); |
455 | /* inform hardware to start streaming */ | ||
456 | ret = cx231xx_capture_start(dev, 1, Audio); | ||
457 | |||
316 | dev->adev.users++; | 458 | dev->adev.users++; |
317 | mutex_unlock(&dev->lock); | 459 | mutex_unlock(&dev->lock); |
318 | 460 | ||
@@ -330,20 +472,21 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) | |||
330 | 472 | ||
331 | dprintk("closing device\n"); | 473 | dprintk("closing device\n"); |
332 | 474 | ||
475 | /* inform hardware to stop streaming */ | ||
476 | mutex_lock(&dev->lock); | ||
477 | ret = cx231xx_capture_start(dev, 0, Audio); | ||
478 | |||
333 | /* set alternate setting for audio interface */ | 479 | /* set alternate setting for audio interface */ |
334 | /* 1 - 48000 samples per sec */ | 480 | /* 1 - 48000 samples per sec */ |
335 | ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); | 481 | ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); |
336 | if (ret < 0) { | 482 | if (ret < 0) { |
337 | cx231xx_errdev("failed to set alternate setting !\n"); | 483 | cx231xx_errdev("failed to set alternate setting !\n"); |
338 | 484 | ||
485 | mutex_unlock(&dev->lock); | ||
339 | return ret; | 486 | return ret; |
340 | } | 487 | } |
341 | 488 | ||
342 | /* inform hardware to start streaming */ | ||
343 | ret = cx231xx_capture_start(dev, 0, Audio); | ||
344 | |||
345 | dev->mute = 1; | 489 | dev->mute = 1; |
346 | mutex_lock(&dev->lock); | ||
347 | dev->adev.users--; | 490 | dev->adev.users--; |
348 | mutex_unlock(&dev->lock); | 491 | mutex_unlock(&dev->lock); |
349 | 492 | ||
@@ -352,7 +495,10 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) | |||
352 | dprintk("disabling audio stream!\n"); | 495 | dprintk("disabling audio stream!\n"); |
353 | dev->adev.shutdown = 0; | 496 | dev->adev.shutdown = 0; |
354 | dprintk("released lock\n"); | 497 | dprintk("released lock\n"); |
355 | cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, 0); | 498 | if (atomic_read(&dev->stream_started) > 0) { |
499 | atomic_set(&dev->stream_started, 0); | ||
500 | schedule_work(&dev->wq_trigger); | ||
501 | } | ||
356 | } | 502 | } |
357 | return 0; | 503 | return 0; |
358 | } | 504 | } |
@@ -383,43 +529,64 @@ static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) | |||
383 | 529 | ||
384 | dprintk("Stop capture, if needed\n"); | 530 | dprintk("Stop capture, if needed\n"); |
385 | 531 | ||
386 | if (dev->adev.capture_stream == STREAM_ON) | 532 | if (atomic_read(&dev->stream_started) > 0) { |
387 | cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO); | 533 | atomic_set(&dev->stream_started, 0); |
534 | schedule_work(&dev->wq_trigger); | ||
535 | } | ||
388 | 536 | ||
389 | return 0; | 537 | return 0; |
390 | } | 538 | } |
391 | 539 | ||
392 | static int snd_cx231xx_prepare(struct snd_pcm_substream *substream) | 540 | static int snd_cx231xx_prepare(struct snd_pcm_substream *substream) |
393 | { | 541 | { |
542 | struct cx231xx *dev = snd_pcm_substream_chip(substream); | ||
543 | |||
544 | dev->adev.hwptr_done_capture = 0; | ||
545 | dev->adev.capture_transfer_done = 0; | ||
546 | |||
394 | return 0; | 547 | return 0; |
395 | } | 548 | } |
396 | 549 | ||
550 | static void audio_trigger(struct work_struct *work) | ||
551 | { | ||
552 | struct cx231xx *dev = container_of(work, struct cx231xx, wq_trigger); | ||
553 | |||
554 | if (atomic_read(&dev->stream_started)) { | ||
555 | dprintk("starting capture"); | ||
556 | if (is_fw_load(dev) == 0) | ||
557 | cx25840_call(dev, core, load_fw); | ||
558 | if (dev->USE_ISO) | ||
559 | cx231xx_init_audio_isoc(dev); | ||
560 | else | ||
561 | cx231xx_init_audio_bulk(dev); | ||
562 | } else { | ||
563 | dprintk("stopping capture"); | ||
564 | cx231xx_isoc_audio_deinit(dev); | ||
565 | } | ||
566 | } | ||
567 | |||
397 | static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream, | 568 | static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream, |
398 | int cmd) | 569 | int cmd) |
399 | { | 570 | { |
400 | struct cx231xx *dev = snd_pcm_substream_chip(substream); | 571 | struct cx231xx *dev = snd_pcm_substream_chip(substream); |
401 | int retval; | 572 | int retval; |
402 | 573 | ||
403 | dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ? | ||
404 | "start" : "stop"); | ||
405 | |||
406 | spin_lock(&dev->adev.slock); | 574 | spin_lock(&dev->adev.slock); |
407 | switch (cmd) { | 575 | switch (cmd) { |
408 | case SNDRV_PCM_TRIGGER_START: | 576 | case SNDRV_PCM_TRIGGER_START: |
409 | cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, | 577 | atomic_set(&dev->stream_started, 1); |
410 | CX231XX_START_AUDIO); | ||
411 | retval = 0; | ||
412 | break; | 578 | break; |
413 | case SNDRV_PCM_TRIGGER_STOP: | 579 | case SNDRV_PCM_TRIGGER_STOP: |
414 | cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO); | 580 | atomic_set(&dev->stream_started, 0); |
415 | retval = 0; | ||
416 | break; | 581 | break; |
417 | default: | 582 | default: |
418 | retval = -EINVAL; | 583 | retval = -EINVAL; |
419 | } | 584 | } |
420 | |||
421 | spin_unlock(&dev->adev.slock); | 585 | spin_unlock(&dev->adev.slock); |
422 | return retval; | 586 | |
587 | schedule_work(&dev->wq_trigger); | ||
588 | |||
589 | return 0; | ||
423 | } | 590 | } |
424 | 591 | ||
425 | static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream | 592 | static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream |
@@ -495,10 +662,13 @@ static int cx231xx_audio_init(struct cx231xx *dev) | |||
495 | pcm->info_flags = 0; | 662 | pcm->info_flags = 0; |
496 | pcm->private_data = dev; | 663 | pcm->private_data = dev; |
497 | strcpy(pcm->name, "Conexant cx231xx Capture"); | 664 | strcpy(pcm->name, "Conexant cx231xx Capture"); |
665 | snd_card_set_dev(card, &dev->udev->dev); | ||
498 | strcpy(card->driver, "Cx231xx-Audio"); | 666 | strcpy(card->driver, "Cx231xx-Audio"); |
499 | strcpy(card->shortname, "Cx231xx Audio"); | 667 | strcpy(card->shortname, "Cx231xx Audio"); |
500 | strcpy(card->longname, "Conexant cx231xx Audio"); | 668 | strcpy(card->longname, "Conexant cx231xx Audio"); |
501 | 669 | ||
670 | INIT_WORK(&dev->wq_trigger, audio_trigger); | ||
671 | |||
502 | err = snd_card_register(card); | 672 | err = snd_card_register(card); |
503 | if (err < 0) { | 673 | if (err < 0) { |
504 | snd_card_free(card); | 674 | snd_card_free(card); |
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c index c2174413ab2..cf50fafa8ab 100644 --- a/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/drivers/media/video/cx231xx/cx231xx-avcore.c | |||
@@ -31,13 +31,16 @@ | |||
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <media/tuner.h> | ||
34 | 35 | ||
35 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
36 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
37 | #include <media/v4l2-chip-ident.h> | 38 | #include <media/v4l2-chip-ident.h> |
38 | 39 | ||
39 | #include "cx231xx.h" | 40 | #include "cx231xx.h" |
41 | #include "cx231xx-dif.h" | ||
40 | 42 | ||
43 | #define TUNER_MODE_FM_RADIO 0 | ||
41 | /****************************************************************************** | 44 | /****************************************************************************** |
42 | -: BLOCK ARRANGEMENT :- | 45 | -: BLOCK ARRANGEMENT :- |
43 | I2S block ----------------------| | 46 | I2S block ----------------------| |
@@ -50,6 +53,57 @@ | |||
50 | [Video] | 53 | [Video] |
51 | 54 | ||
52 | *******************************************************************************/ | 55 | *******************************************************************************/ |
56 | /****************************************************************************** | ||
57 | * VERVE REGISTER * | ||
58 | * * | ||
59 | ******************************************************************************/ | ||
60 | static int verve_write_byte(struct cx231xx *dev, u8 saddr, u8 data) | ||
61 | { | ||
62 | return cx231xx_write_i2c_data(dev, VERVE_I2C_ADDRESS, | ||
63 | saddr, 1, data, 1); | ||
64 | } | ||
65 | |||
66 | static int verve_read_byte(struct cx231xx *dev, u8 saddr, u8 *data) | ||
67 | { | ||
68 | int status; | ||
69 | u32 temp = 0; | ||
70 | |||
71 | status = cx231xx_read_i2c_data(dev, VERVE_I2C_ADDRESS, | ||
72 | saddr, 1, &temp, 1); | ||
73 | *data = (u8) temp; | ||
74 | return status; | ||
75 | } | ||
76 | void initGPIO(struct cx231xx *dev) | ||
77 | { | ||
78 | u32 _gpio_direction = 0; | ||
79 | u32 value = 0; | ||
80 | u8 val = 0; | ||
81 | |||
82 | _gpio_direction = _gpio_direction & 0xFC0003FF; | ||
83 | _gpio_direction = _gpio_direction | 0x03FDFC00; | ||
84 | cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); | ||
85 | |||
86 | verve_read_byte(dev, 0x07, &val); | ||
87 | cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); | ||
88 | verve_write_byte(dev, 0x07, 0xF4); | ||
89 | verve_read_byte(dev, 0x07, &val); | ||
90 | cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); | ||
91 | |||
92 | cx231xx_capture_start(dev, 1, 2); | ||
93 | |||
94 | cx231xx_mode_register(dev, EP_MODE_SET, 0x0500FE00); | ||
95 | cx231xx_mode_register(dev, GBULK_BIT_EN, 0xFFFDFFFF); | ||
96 | |||
97 | } | ||
98 | void uninitGPIO(struct cx231xx *dev) | ||
99 | { | ||
100 | u8 value[4] = { 0, 0, 0, 0 }; | ||
101 | |||
102 | cx231xx_capture_start(dev, 0, 2); | ||
103 | verve_write_byte(dev, 0x07, 0x14); | ||
104 | cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
105 | 0x68, value, 4); | ||
106 | } | ||
53 | 107 | ||
54 | /****************************************************************************** | 108 | /****************************************************************************** |
55 | * A F E - B L O C K C O N T R O L functions * | 109 | * A F E - B L O C K C O N T R O L functions * |
@@ -258,7 +312,7 @@ int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode) | |||
258 | 312 | ||
259 | switch (mode) { | 313 | switch (mode) { |
260 | case AFE_MODE_LOW_IF: | 314 | case AFE_MODE_LOW_IF: |
261 | /* SetupAFEforLowIF(); */ | 315 | cx231xx_Setup_AFE_for_LowIF(dev); |
262 | break; | 316 | break; |
263 | case AFE_MODE_BASEBAND: | 317 | case AFE_MODE_BASEBAND: |
264 | status = cx231xx_afe_setup_AFE_for_baseband(dev); | 318 | status = cx231xx_afe_setup_AFE_for_baseband(dev); |
@@ -291,8 +345,15 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, | |||
291 | int status = 0; | 345 | int status = 0; |
292 | 346 | ||
293 | switch (dev->model) { | 347 | switch (dev->model) { |
348 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
294 | case CX231XX_BOARD_CNXT_RDE_250: | 349 | case CX231XX_BOARD_CNXT_RDE_250: |
350 | case CX231XX_BOARD_CNXT_SHELBY: | ||
295 | case CX231XX_BOARD_CNXT_RDU_250: | 351 | case CX231XX_BOARD_CNXT_RDU_250: |
352 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
353 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
354 | case CX231XX_BOARD_CNXT_VIDEO_GRABBER: | ||
355 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | ||
356 | case CX231XX_BOARD_HAUPPAUGE_USBLIVE2: | ||
296 | if (avmode == POLARIS_AVMODE_ANALOGT_TV) { | 357 | if (avmode == POLARIS_AVMODE_ANALOGT_TV) { |
297 | while (afe_power_status != (FLD_PWRDN_TUNING_BIAS | | 358 | while (afe_power_status != (FLD_PWRDN_TUNING_BIAS | |
298 | FLD_PWRDN_ENABLE_PLL)) { | 359 | FLD_PWRDN_ENABLE_PLL)) { |
@@ -483,6 +544,17 @@ static int vid_blk_read_word(struct cx231xx *dev, u16 saddr, u32 *data) | |||
483 | return cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS, | 544 | return cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS, |
484 | saddr, 2, data, 4); | 545 | saddr, 2, data, 4); |
485 | } | 546 | } |
547 | int cx231xx_check_fw(struct cx231xx *dev) | ||
548 | { | ||
549 | u8 temp = 0; | ||
550 | int status = 0; | ||
551 | status = vid_blk_read_byte(dev, DL_CTL_ADDRESS_LOW, &temp); | ||
552 | if (status < 0) | ||
553 | return status; | ||
554 | else | ||
555 | return temp; | ||
556 | |||
557 | } | ||
486 | 558 | ||
487 | int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) | 559 | int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) |
488 | { | 560 | { |
@@ -521,9 +593,15 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) | |||
521 | return status; | 593 | return status; |
522 | } | 594 | } |
523 | } | 595 | } |
524 | status = cx231xx_set_decoder_video_input(dev, | 596 | if (dev->tuner_type == TUNER_NXP_TDA18271) |
597 | status = cx231xx_set_decoder_video_input(dev, | ||
598 | CX231XX_VMUX_TELEVISION, | ||
599 | INPUT(input)->vmux); | ||
600 | else | ||
601 | status = cx231xx_set_decoder_video_input(dev, | ||
525 | CX231XX_VMUX_COMPOSITE1, | 602 | CX231XX_VMUX_COMPOSITE1, |
526 | INPUT(input)->vmux); | 603 | INPUT(input)->vmux); |
604 | |||
527 | break; | 605 | break; |
528 | default: | 606 | default: |
529 | cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n", | 607 | cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n", |
@@ -578,12 +656,12 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, | |||
578 | value |= (1 << 7); | 656 | value |= (1 << 7); |
579 | status = vid_blk_write_word(dev, OUT_CTRL1, value); | 657 | status = vid_blk_write_word(dev, OUT_CTRL1, value); |
580 | 658 | ||
581 | /* Set vip 1.1 output mode */ | 659 | /* Set output mode */ |
582 | status = cx231xx_read_modify_write_i2c_dword(dev, | 660 | status = cx231xx_read_modify_write_i2c_dword(dev, |
583 | VID_BLK_I2C_ADDRESS, | 661 | VID_BLK_I2C_ADDRESS, |
584 | OUT_CTRL1, | 662 | OUT_CTRL1, |
585 | FLD_OUT_MODE, | 663 | FLD_OUT_MODE, |
586 | OUT_MODE_VIP11); | 664 | dev->board.output_mode); |
587 | 665 | ||
588 | /* Tell DIF object to go to baseband mode */ | 666 | /* Tell DIF object to go to baseband mode */ |
589 | status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); | 667 | status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); |
@@ -681,7 +759,9 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, | |||
681 | case CX231XX_VMUX_CABLE: | 759 | case CX231XX_VMUX_CABLE: |
682 | default: | 760 | default: |
683 | switch (dev->model) { | 761 | switch (dev->model) { |
762 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
684 | case CX231XX_BOARD_CNXT_RDE_250: | 763 | case CX231XX_BOARD_CNXT_RDE_250: |
764 | case CX231XX_BOARD_CNXT_SHELBY: | ||
685 | case CX231XX_BOARD_CNXT_RDU_250: | 765 | case CX231XX_BOARD_CNXT_RDU_250: |
686 | /* Disable the use of DIF */ | 766 | /* Disable the use of DIF */ |
687 | 767 | ||
@@ -699,11 +779,11 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, | |||
699 | value |= (1 << 7); | 779 | value |= (1 << 7); |
700 | status = vid_blk_write_word(dev, OUT_CTRL1, value); | 780 | status = vid_blk_write_word(dev, OUT_CTRL1, value); |
701 | 781 | ||
702 | /* Set vip 1.1 output mode */ | 782 | /* Set output mode */ |
703 | status = cx231xx_read_modify_write_i2c_dword(dev, | 783 | status = cx231xx_read_modify_write_i2c_dword(dev, |
704 | VID_BLK_I2C_ADDRESS, | 784 | VID_BLK_I2C_ADDRESS, |
705 | OUT_CTRL1, FLD_OUT_MODE, | 785 | OUT_CTRL1, FLD_OUT_MODE, |
706 | OUT_MODE_VIP11); | 786 | dev->board.output_mode); |
707 | 787 | ||
708 | /* Tell DIF object to go to baseband mode */ | 788 | /* Tell DIF object to go to baseband mode */ |
709 | status = cx231xx_dif_set_standard(dev, | 789 | status = cx231xx_dif_set_standard(dev, |
@@ -790,11 +870,11 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, | |||
790 | (FLD_OEF_AGC_IF); | 870 | (FLD_OEF_AGC_IF); |
791 | status = vid_blk_write_word(dev, PIN_CTRL, value); | 871 | status = vid_blk_write_word(dev, PIN_CTRL, value); |
792 | 872 | ||
793 | /* Set vip 1.1 output mode */ | 873 | /* Set output mode */ |
794 | status = cx231xx_read_modify_write_i2c_dword(dev, | 874 | status = cx231xx_read_modify_write_i2c_dword(dev, |
795 | VID_BLK_I2C_ADDRESS, | 875 | VID_BLK_I2C_ADDRESS, |
796 | OUT_CTRL1, FLD_OUT_MODE, | 876 | OUT_CTRL1, FLD_OUT_MODE, |
797 | OUT_MODE_VIP11); | 877 | dev->board.output_mode); |
798 | 878 | ||
799 | /* Disable auto config of registers */ | 879 | /* Disable auto config of registers */ |
800 | status = cx231xx_read_modify_write_i2c_dword(dev, | 880 | status = cx231xx_read_modify_write_i2c_dword(dev, |
@@ -816,9 +896,21 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, | |||
816 | /* Set VGA_SEL (for audio control) (bit 7-8) */ | 896 | /* Set VGA_SEL (for audio control) (bit 7-8) */ |
817 | status = vid_blk_read_word(dev, AFE_CTRL, &value); | 897 | status = vid_blk_read_word(dev, AFE_CTRL, &value); |
818 | 898 | ||
899 | /*Set Func mode:01-DIF 10-baseband 11-YUV*/ | ||
900 | value &= (~(FLD_FUNC_MODE)); | ||
901 | value |= 0x800000; | ||
902 | |||
819 | value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2; | 903 | value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2; |
820 | 904 | ||
821 | status = vid_blk_write_word(dev, AFE_CTRL, value); | 905 | status = vid_blk_write_word(dev, AFE_CTRL, value); |
906 | |||
907 | if (dev->tuner_type == TUNER_NXP_TDA18271) { | ||
908 | status = vid_blk_read_word(dev, PIN_CTRL, | ||
909 | &value); | ||
910 | status = vid_blk_write_word(dev, PIN_CTRL, | ||
911 | (value & 0xFFFFFFEF)); | ||
912 | } | ||
913 | |||
822 | break; | 914 | break; |
823 | 915 | ||
824 | } | 916 | } |
@@ -840,6 +932,39 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, | |||
840 | return status; | 932 | return status; |
841 | } | 933 | } |
842 | 934 | ||
935 | void cx231xx_enable656(struct cx231xx *dev) | ||
936 | { | ||
937 | u8 temp = 0; | ||
938 | int status; | ||
939 | /*enable TS1 data[0:7] as output to export 656*/ | ||
940 | |||
941 | status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0xFF); | ||
942 | |||
943 | /*enable TS1 clock as output to export 656*/ | ||
944 | |||
945 | status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp); | ||
946 | temp = temp|0x04; | ||
947 | |||
948 | status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp); | ||
949 | |||
950 | } | ||
951 | EXPORT_SYMBOL_GPL(cx231xx_enable656); | ||
952 | |||
953 | void cx231xx_disable656(struct cx231xx *dev) | ||
954 | { | ||
955 | u8 temp = 0; | ||
956 | int status; | ||
957 | |||
958 | |||
959 | status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0x00); | ||
960 | |||
961 | status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp); | ||
962 | temp = temp&0xFB; | ||
963 | |||
964 | status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp); | ||
965 | } | ||
966 | EXPORT_SYMBOL_GPL(cx231xx_disable656); | ||
967 | |||
843 | /* | 968 | /* |
844 | * Handle any video-mode specific overrides that are different | 969 | * Handle any video-mode specific overrides that are different |
845 | * on a per video standards basis after touching the MODE_CTRL | 970 | * on a per video standards basis after touching the MODE_CTRL |
@@ -868,12 +993,12 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) | |||
868 | VID_BLK_I2C_ADDRESS, | 993 | VID_BLK_I2C_ADDRESS, |
869 | VERT_TIM_CTRL, | 994 | VERT_TIM_CTRL, |
870 | FLD_VACTIVE_CNT, | 995 | FLD_VACTIVE_CNT, |
871 | 0x1E6000); | 996 | 0x1E7000); |
872 | status = cx231xx_read_modify_write_i2c_dword(dev, | 997 | status = cx231xx_read_modify_write_i2c_dword(dev, |
873 | VID_BLK_I2C_ADDRESS, | 998 | VID_BLK_I2C_ADDRESS, |
874 | VERT_TIM_CTRL, | 999 | VERT_TIM_CTRL, |
875 | FLD_V656BLANK_CNT, | 1000 | FLD_V656BLANK_CNT, |
876 | 0x1E000000); | 1001 | 0x1C000000); |
877 | 1002 | ||
878 | status = cx231xx_read_modify_write_i2c_dword(dev, | 1003 | status = cx231xx_read_modify_write_i2c_dword(dev, |
879 | VID_BLK_I2C_ADDRESS, | 1004 | VID_BLK_I2C_ADDRESS, |
@@ -881,12 +1006,27 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) | |||
881 | FLD_HBLANK_CNT, | 1006 | FLD_HBLANK_CNT, |
882 | cx231xx_set_field | 1007 | cx231xx_set_field |
883 | (FLD_HBLANK_CNT, 0x79)); | 1008 | (FLD_HBLANK_CNT, 0x79)); |
1009 | |||
884 | } else if (dev->norm & V4L2_STD_SECAM) { | 1010 | } else if (dev->norm & V4L2_STD_SECAM) { |
885 | cx231xx_info("do_mode_ctrl_overrides SECAM\n"); | 1011 | cx231xx_info("do_mode_ctrl_overrides SECAM\n"); |
886 | status = cx231xx_read_modify_write_i2c_dword(dev, | 1012 | status = cx231xx_read_modify_write_i2c_dword(dev, |
887 | VID_BLK_I2C_ADDRESS, | 1013 | VID_BLK_I2C_ADDRESS, |
888 | VERT_TIM_CTRL, | 1014 | VERT_TIM_CTRL, |
889 | FLD_VBLANK_CNT, 0x24); | 1015 | FLD_VBLANK_CNT, 0x20); |
1016 | status = cx231xx_read_modify_write_i2c_dword(dev, | ||
1017 | VID_BLK_I2C_ADDRESS, | ||
1018 | VERT_TIM_CTRL, | ||
1019 | FLD_VACTIVE_CNT, | ||
1020 | cx231xx_set_field | ||
1021 | (FLD_VACTIVE_CNT, | ||
1022 | 0x244)); | ||
1023 | status = cx231xx_read_modify_write_i2c_dword(dev, | ||
1024 | VID_BLK_I2C_ADDRESS, | ||
1025 | VERT_TIM_CTRL, | ||
1026 | FLD_V656BLANK_CNT, | ||
1027 | cx231xx_set_field | ||
1028 | (FLD_V656BLANK_CNT, | ||
1029 | 0x24)); | ||
890 | /* Adjust the active video horizontal start point */ | 1030 | /* Adjust the active video horizontal start point */ |
891 | status = cx231xx_read_modify_write_i2c_dword(dev, | 1031 | status = cx231xx_read_modify_write_i2c_dword(dev, |
892 | VID_BLK_I2C_ADDRESS, | 1032 | VID_BLK_I2C_ADDRESS, |
@@ -899,7 +1039,21 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) | |||
899 | status = cx231xx_read_modify_write_i2c_dword(dev, | 1039 | status = cx231xx_read_modify_write_i2c_dword(dev, |
900 | VID_BLK_I2C_ADDRESS, | 1040 | VID_BLK_I2C_ADDRESS, |
901 | VERT_TIM_CTRL, | 1041 | VERT_TIM_CTRL, |
902 | FLD_VBLANK_CNT, 0x24); | 1042 | FLD_VBLANK_CNT, 0x20); |
1043 | status = cx231xx_read_modify_write_i2c_dword(dev, | ||
1044 | VID_BLK_I2C_ADDRESS, | ||
1045 | VERT_TIM_CTRL, | ||
1046 | FLD_VACTIVE_CNT, | ||
1047 | cx231xx_set_field | ||
1048 | (FLD_VACTIVE_CNT, | ||
1049 | 0x244)); | ||
1050 | status = cx231xx_read_modify_write_i2c_dword(dev, | ||
1051 | VID_BLK_I2C_ADDRESS, | ||
1052 | VERT_TIM_CTRL, | ||
1053 | FLD_V656BLANK_CNT, | ||
1054 | cx231xx_set_field | ||
1055 | (FLD_V656BLANK_CNT, | ||
1056 | 0x24)); | ||
903 | /* Adjust the active video horizontal start point */ | 1057 | /* Adjust the active video horizontal start point */ |
904 | status = cx231xx_read_modify_write_i2c_dword(dev, | 1058 | status = cx231xx_read_modify_write_i2c_dword(dev, |
905 | VID_BLK_I2C_ADDRESS, | 1059 | VID_BLK_I2C_ADDRESS, |
@@ -907,11 +1061,28 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) | |||
907 | FLD_HBLANK_CNT, | 1061 | FLD_HBLANK_CNT, |
908 | cx231xx_set_field | 1062 | cx231xx_set_field |
909 | (FLD_HBLANK_CNT, 0x85)); | 1063 | (FLD_HBLANK_CNT, 0x85)); |
1064 | |||
910 | } | 1065 | } |
911 | 1066 | ||
912 | return status; | 1067 | return status; |
913 | } | 1068 | } |
914 | 1069 | ||
1070 | int cx231xx_unmute_audio(struct cx231xx *dev) | ||
1071 | { | ||
1072 | return vid_blk_write_byte(dev, PATH1_VOL_CTL, 0x24); | ||
1073 | } | ||
1074 | EXPORT_SYMBOL_GPL(cx231xx_unmute_audio); | ||
1075 | |||
1076 | int stopAudioFirmware(struct cx231xx *dev) | ||
1077 | { | ||
1078 | return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x03); | ||
1079 | } | ||
1080 | |||
1081 | int restartAudioFirmware(struct cx231xx *dev) | ||
1082 | { | ||
1083 | return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x13); | ||
1084 | } | ||
1085 | |||
915 | int cx231xx_set_audio_input(struct cx231xx *dev, u8 input) | 1086 | int cx231xx_set_audio_input(struct cx231xx *dev, u8 input) |
916 | { | 1087 | { |
917 | int status = 0; | 1088 | int status = 0; |
@@ -970,6 +1141,7 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, | |||
970 | 1141 | ||
971 | /* unmute all, AC97 in, independence mode | 1142 | /* unmute all, AC97 in, independence mode |
972 | adr 08d0, data 0x00063073 */ | 1143 | adr 08d0, data 0x00063073 */ |
1144 | status = vid_blk_write_word(dev, DL_CTL, 0x3000001); | ||
973 | status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073); | 1145 | status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073); |
974 | 1146 | ||
975 | /* set AVC maximum threshold, adr 08d4, dat ffff0024 */ | 1147 | /* set AVC maximum threshold, adr 08d4, dat ffff0024 */ |
@@ -985,7 +1157,7 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, | |||
985 | 1157 | ||
986 | case AUDIO_INPUT_TUNER_TV: | 1158 | case AUDIO_INPUT_TUNER_TV: |
987 | default: | 1159 | default: |
988 | 1160 | status = stopAudioFirmware(dev); | |
989 | /* Setup SRC sources and clocks */ | 1161 | /* Setup SRC sources and clocks */ |
990 | status = vid_blk_write_word(dev, BAND_OUT_SEL, | 1162 | status = vid_blk_write_word(dev, BAND_OUT_SEL, |
991 | cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00) | | 1163 | cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00) | |
@@ -1013,18 +1185,32 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, | |||
1013 | status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870); | 1185 | status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870); |
1014 | 1186 | ||
1015 | /* setAudioStandard(_audio_standard); */ | 1187 | /* setAudioStandard(_audio_standard); */ |
1016 | |||
1017 | status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870); | 1188 | status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870); |
1018 | switch (dev->model) { | 1189 | |
1019 | case CX231XX_BOARD_CNXT_RDE_250: | 1190 | status = restartAudioFirmware(dev); |
1020 | case CX231XX_BOARD_CNXT_RDU_250: | 1191 | |
1192 | switch (dev->board.tuner_type) { | ||
1193 | case TUNER_XC5000: | ||
1194 | /* SIF passthrough at 28.6363 MHz sample rate */ | ||
1021 | status = cx231xx_read_modify_write_i2c_dword(dev, | 1195 | status = cx231xx_read_modify_write_i2c_dword(dev, |
1022 | VID_BLK_I2C_ADDRESS, | 1196 | VID_BLK_I2C_ADDRESS, |
1023 | CHIP_CTRL, | 1197 | CHIP_CTRL, |
1024 | FLD_SIF_EN, | 1198 | FLD_SIF_EN, |
1025 | cx231xx_set_field(FLD_SIF_EN, 1)); | 1199 | cx231xx_set_field(FLD_SIF_EN, 1)); |
1026 | break; | 1200 | break; |
1201 | case TUNER_NXP_TDA18271: | ||
1202 | /* Normal mode: SIF passthrough at 14.32 MHz */ | ||
1203 | status = cx231xx_read_modify_write_i2c_dword(dev, | ||
1204 | VID_BLK_I2C_ADDRESS, | ||
1205 | CHIP_CTRL, | ||
1206 | FLD_SIF_EN, | ||
1207 | cx231xx_set_field(FLD_SIF_EN, 0)); | ||
1208 | break; | ||
1027 | default: | 1209 | default: |
1210 | /* This is just a casual suggestion to people adding | ||
1211 | new boards in case they use a tuner type we don't | ||
1212 | currently know about */ | ||
1213 | printk(KERN_INFO "Unknown tuner type configuring SIF"); | ||
1028 | break; | 1214 | break; |
1029 | } | 1215 | } |
1030 | break; | 1216 | break; |
@@ -1049,18 +1235,6 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, | |||
1049 | return status; | 1235 | return status; |
1050 | } | 1236 | } |
1051 | 1237 | ||
1052 | /* Set resolution of the video */ | ||
1053 | int cx231xx_resolution_set(struct cx231xx *dev) | ||
1054 | { | ||
1055 | /* set horzontal scale */ | ||
1056 | int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale); | ||
1057 | if (status) | ||
1058 | return status; | ||
1059 | |||
1060 | /* set vertical scale */ | ||
1061 | return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale); | ||
1062 | } | ||
1063 | |||
1064 | /****************************************************************************** | 1238 | /****************************************************************************** |
1065 | * C H I P Specific C O N T R O L functions * | 1239 | * C H I P Specific C O N T R O L functions * |
1066 | ******************************************************************************/ | 1240 | ******************************************************************************/ |
@@ -1094,34 +1268,350 @@ int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, | |||
1094 | return status; | 1268 | return status; |
1095 | } | 1269 | } |
1096 | 1270 | ||
1097 | int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex) | 1271 | int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) |
1098 | { | 1272 | { |
1099 | u8 value[4] = { 0, 0, 0, 0 }; | 1273 | u8 value[4] = { 0, 0, 0, 0 }; |
1100 | int status = 0; | 1274 | int status = 0; |
1101 | 1275 | bool current_is_port_3; | |
1102 | cx231xx_info("Changing the i2c port for tuner to %d\n", I2CIndex); | ||
1103 | 1276 | ||
1104 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, | 1277 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, |
1105 | PWR_CTL_EN, value, 4); | 1278 | PWR_CTL_EN, value, 4); |
1106 | if (status < 0) | 1279 | if (status < 0) |
1107 | return status; | 1280 | return status; |
1108 | 1281 | ||
1109 | if (I2CIndex == I2C_1) { | 1282 | current_is_port_3 = value[0] & I2C_DEMOD_EN ? true : false; |
1110 | if (value[0] & I2C_DEMOD_EN) { | 1283 | |
1111 | value[0] &= ~I2C_DEMOD_EN; | 1284 | /* Just return, if already using the right port */ |
1112 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | 1285 | if (current_is_port_3 == is_port_3) |
1113 | PWR_CTL_EN, value, 4); | 1286 | return 0; |
1114 | } | 1287 | |
1288 | if (is_port_3) | ||
1289 | value[0] |= I2C_DEMOD_EN; | ||
1290 | else | ||
1291 | value[0] &= ~I2C_DEMOD_EN; | ||
1292 | |||
1293 | cx231xx_info("Changing the i2c master port to %d\n", | ||
1294 | is_port_3 ? 3 : 1); | ||
1295 | |||
1296 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
1297 | PWR_CTL_EN, value, 4); | ||
1298 | |||
1299 | return status; | ||
1300 | |||
1301 | } | ||
1302 | EXPORT_SYMBOL_GPL(cx231xx_enable_i2c_port_3); | ||
1303 | |||
1304 | void update_HH_register_after_set_DIF(struct cx231xx *dev) | ||
1305 | { | ||
1306 | /* | ||
1307 | u8 status = 0; | ||
1308 | u32 value = 0; | ||
1309 | |||
1310 | vid_blk_write_word(dev, PIN_CTRL, 0xA0FFF82F); | ||
1311 | vid_blk_write_word(dev, DIF_MISC_CTRL, 0x0A203F11); | ||
1312 | vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0x1BEFBF06); | ||
1313 | |||
1314 | status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); | ||
1315 | vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); | ||
1316 | status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); | ||
1317 | */ | ||
1318 | } | ||
1319 | |||
1320 | void cx231xx_dump_HH_reg(struct cx231xx *dev) | ||
1321 | { | ||
1322 | u8 status = 0; | ||
1323 | u32 value = 0; | ||
1324 | u16 i = 0; | ||
1325 | |||
1326 | value = 0x45005390; | ||
1327 | status = vid_blk_write_word(dev, 0x104, value); | ||
1328 | |||
1329 | for (i = 0x100; i < 0x140; i++) { | ||
1330 | status = vid_blk_read_word(dev, i, &value); | ||
1331 | cx231xx_info("reg0x%x=0x%x\n", i, value); | ||
1332 | i = i+3; | ||
1333 | } | ||
1334 | |||
1335 | for (i = 0x300; i < 0x400; i++) { | ||
1336 | status = vid_blk_read_word(dev, i, &value); | ||
1337 | cx231xx_info("reg0x%x=0x%x\n", i, value); | ||
1338 | i = i+3; | ||
1339 | } | ||
1340 | |||
1341 | for (i = 0x400; i < 0x440; i++) { | ||
1342 | status = vid_blk_read_word(dev, i, &value); | ||
1343 | cx231xx_info("reg0x%x=0x%x\n", i, value); | ||
1344 | i = i+3; | ||
1345 | } | ||
1346 | |||
1347 | status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); | ||
1348 | cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); | ||
1349 | vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); | ||
1350 | status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); | ||
1351 | cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); | ||
1352 | } | ||
1353 | |||
1354 | void cx231xx_dump_SC_reg(struct cx231xx *dev) | ||
1355 | { | ||
1356 | u8 value[4] = { 0, 0, 0, 0 }; | ||
1357 | int status = 0; | ||
1358 | cx231xx_info("cx231xx_dump_SC_reg %s!\n", __TIME__); | ||
1359 | |||
1360 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, | ||
1361 | value, 4); | ||
1362 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], | ||
1363 | value[1], value[2], value[3]); | ||
1364 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, | ||
1365 | value, 4); | ||
1366 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], | ||
1367 | value[1], value[2], value[3]); | ||
1368 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, | ||
1369 | value, 4); | ||
1370 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], | ||
1371 | value[1], value[2], value[3]); | ||
1372 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, | ||
1373 | value, 4); | ||
1374 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], | ||
1375 | value[1], value[2], value[3]); | ||
1376 | |||
1377 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, | ||
1378 | value, 4); | ||
1379 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], | ||
1380 | value[1], value[2], value[3]); | ||
1381 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, | ||
1382 | value, 4); | ||
1383 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], | ||
1384 | value[1], value[2], value[3]); | ||
1385 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, | ||
1386 | value, 4); | ||
1387 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], | ||
1388 | value[1], value[2], value[3]); | ||
1389 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, | ||
1390 | value, 4); | ||
1391 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], | ||
1392 | value[1], value[2], value[3]); | ||
1393 | |||
1394 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, | ||
1395 | value, 4); | ||
1396 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], | ||
1397 | value[1], value[2], value[3]); | ||
1398 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, | ||
1399 | value, 4); | ||
1400 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], | ||
1401 | value[1], value[2], value[3]); | ||
1402 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, | ||
1403 | value, 4); | ||
1404 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], | ||
1405 | value[1], value[2], value[3]); | ||
1406 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, | ||
1407 | value, 4); | ||
1408 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], | ||
1409 | value[1], value[2], value[3]); | ||
1410 | |||
1411 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, | ||
1412 | value, 4); | ||
1413 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], | ||
1414 | value[1], value[2], value[3]); | ||
1415 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, | ||
1416 | value, 4); | ||
1417 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], | ||
1418 | value[1], value[2], value[3]); | ||
1419 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, | ||
1420 | value, 4); | ||
1421 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], | ||
1422 | value[1], value[2], value[3]); | ||
1423 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, | ||
1424 | value, 4); | ||
1425 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], | ||
1426 | value[1], value[2], value[3]); | ||
1427 | |||
1428 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, | ||
1429 | value, 4); | ||
1430 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], | ||
1431 | value[1], value[2], value[3]); | ||
1432 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, | ||
1433 | value, 4); | ||
1434 | cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], | ||
1435 | value[1], value[2], value[3]); | ||
1436 | |||
1437 | |||
1438 | } | ||
1439 | |||
1440 | void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev) | ||
1441 | |||
1442 | { | ||
1443 | u8 status = 0; | ||
1444 | u8 value = 0; | ||
1445 | |||
1446 | |||
1447 | |||
1448 | status = afe_read_byte(dev, ADC_STATUS2_CH3, &value); | ||
1449 | value = (value & 0xFE)|0x01; | ||
1450 | status = afe_write_byte(dev, ADC_STATUS2_CH3, value); | ||
1451 | |||
1452 | status = afe_read_byte(dev, ADC_STATUS2_CH3, &value); | ||
1453 | value = (value & 0xFE)|0x00; | ||
1454 | status = afe_write_byte(dev, ADC_STATUS2_CH3, value); | ||
1455 | |||
1456 | |||
1457 | /* | ||
1458 | config colibri to lo-if mode | ||
1459 | |||
1460 | FIXME: ntf_mode = 2'b00 by default. But set 0x1 would reduce | ||
1461 | the diff IF input by half, | ||
1462 | |||
1463 | for low-if agc defect | ||
1464 | */ | ||
1465 | |||
1466 | status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value); | ||
1467 | value = (value & 0xFC)|0x00; | ||
1468 | status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, value); | ||
1469 | |||
1470 | status = afe_read_byte(dev, ADC_INPUT_CH3, &value); | ||
1471 | value = (value & 0xF9)|0x02; | ||
1472 | status = afe_write_byte(dev, ADC_INPUT_CH3, value); | ||
1473 | |||
1474 | status = afe_read_byte(dev, ADC_FB_FRCRST_CH3, &value); | ||
1475 | value = (value & 0xFB)|0x04; | ||
1476 | status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, value); | ||
1477 | |||
1478 | status = afe_read_byte(dev, ADC_DCSERVO_DEM_CH3, &value); | ||
1479 | value = (value & 0xFC)|0x03; | ||
1480 | status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, value); | ||
1481 | |||
1482 | status = afe_read_byte(dev, ADC_CTRL_DAC1_CH3, &value); | ||
1483 | value = (value & 0xFB)|0x04; | ||
1484 | status = afe_write_byte(dev, ADC_CTRL_DAC1_CH3, value); | ||
1485 | |||
1486 | status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value); | ||
1487 | value = (value & 0xF8)|0x06; | ||
1488 | status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value); | ||
1489 | |||
1490 | status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value); | ||
1491 | value = (value & 0x8F)|0x40; | ||
1492 | status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value); | ||
1493 | |||
1494 | status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH3, &value); | ||
1495 | value = (value & 0xDF)|0x20; | ||
1496 | status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, value); | ||
1497 | } | ||
1498 | |||
1499 | void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, | ||
1500 | u8 spectral_invert, u32 mode) | ||
1501 | { | ||
1502 | u32 colibri_carrier_offset = 0; | ||
1503 | u8 status = 0; | ||
1504 | u32 func_mode = 0x01; /* Device has a DIF if this function is called */ | ||
1505 | u32 standard = 0; | ||
1506 | u8 value[4] = { 0, 0, 0, 0 }; | ||
1507 | |||
1508 | cx231xx_info("Enter cx231xx_set_Colibri_For_LowIF()\n"); | ||
1509 | value[0] = (u8) 0x6F; | ||
1510 | value[1] = (u8) 0x6F; | ||
1511 | value[2] = (u8) 0x6F; | ||
1512 | value[3] = (u8) 0x6F; | ||
1513 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
1514 | PWR_CTL_EN, value, 4); | ||
1515 | |||
1516 | /*Set colibri for low IF*/ | ||
1517 | status = cx231xx_afe_set_mode(dev, AFE_MODE_LOW_IF); | ||
1518 | |||
1519 | /* Set C2HH for low IF operation.*/ | ||
1520 | standard = dev->norm; | ||
1521 | status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode, | ||
1522 | func_mode, standard); | ||
1523 | |||
1524 | /* Get colibri offsets.*/ | ||
1525 | colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode, | ||
1526 | standard); | ||
1527 | |||
1528 | cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n", | ||
1529 | colibri_carrier_offset, standard); | ||
1530 | |||
1531 | /* Set the band Pass filter for DIF*/ | ||
1532 | cx231xx_set_DIF_bandpass(dev, (if_freq+colibri_carrier_offset), | ||
1533 | spectral_invert, mode); | ||
1534 | } | ||
1535 | |||
1536 | u32 cx231xx_Get_Colibri_CarrierOffset(u32 mode, u32 standerd) | ||
1537 | { | ||
1538 | u32 colibri_carrier_offset = 0; | ||
1539 | |||
1540 | if (mode == TUNER_MODE_FM_RADIO) { | ||
1541 | colibri_carrier_offset = 1100000; | ||
1542 | } else if (standerd & (V4L2_STD_MN | V4L2_STD_NTSC_M_JP)) { | ||
1543 | colibri_carrier_offset = 4832000; /*4.83MHz */ | ||
1544 | } else if (standerd & (V4L2_STD_PAL_B | V4L2_STD_PAL_G)) { | ||
1545 | colibri_carrier_offset = 2700000; /*2.70MHz */ | ||
1546 | } else if (standerd & (V4L2_STD_PAL_D | V4L2_STD_PAL_I | ||
1547 | | V4L2_STD_SECAM)) { | ||
1548 | colibri_carrier_offset = 2100000; /*2.10MHz */ | ||
1549 | } | ||
1550 | |||
1551 | return colibri_carrier_offset; | ||
1552 | } | ||
1553 | |||
1554 | void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, | ||
1555 | u8 spectral_invert, u32 mode) | ||
1556 | { | ||
1557 | unsigned long pll_freq_word; | ||
1558 | int status = 0; | ||
1559 | u32 dif_misc_ctrl_value = 0; | ||
1560 | u64 pll_freq_u64 = 0; | ||
1561 | u32 i = 0; | ||
1562 | |||
1563 | cx231xx_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", | ||
1564 | if_freq, spectral_invert, mode); | ||
1565 | |||
1566 | |||
1567 | if (mode == TUNER_MODE_FM_RADIO) { | ||
1568 | pll_freq_word = 0x905A1CAC; | ||
1569 | status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word); | ||
1570 | |||
1571 | } else /*KSPROPERTY_TUNER_MODE_TV*/{ | ||
1572 | /* Calculate the PLL frequency word based on the adjusted if_freq*/ | ||
1573 | pll_freq_word = if_freq; | ||
1574 | pll_freq_u64 = (u64)pll_freq_word << 28L; | ||
1575 | do_div(pll_freq_u64, 50000000); | ||
1576 | pll_freq_word = (u32)pll_freq_u64; | ||
1577 | /*pll_freq_word = 0x3463497;*/ | ||
1578 | status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word); | ||
1579 | |||
1580 | if (spectral_invert) { | ||
1581 | if_freq -= 400000; | ||
1582 | /* Enable Spectral Invert*/ | ||
1583 | status = vid_blk_read_word(dev, DIF_MISC_CTRL, | ||
1584 | &dif_misc_ctrl_value); | ||
1585 | dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000; | ||
1586 | status = vid_blk_write_word(dev, DIF_MISC_CTRL, | ||
1587 | dif_misc_ctrl_value); | ||
1115 | } else { | 1588 | } else { |
1116 | if (!(value[0] & I2C_DEMOD_EN)) { | 1589 | if_freq += 400000; |
1117 | value[0] |= I2C_DEMOD_EN; | 1590 | /* Disable Spectral Invert*/ |
1118 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | 1591 | status = vid_blk_read_word(dev, DIF_MISC_CTRL, |
1119 | PWR_CTL_EN, value, 4); | 1592 | &dif_misc_ctrl_value); |
1120 | } | 1593 | dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF; |
1594 | status = vid_blk_write_word(dev, DIF_MISC_CTRL, | ||
1595 | dif_misc_ctrl_value); | ||
1121 | } | 1596 | } |
1122 | 1597 | ||
1123 | return status; | 1598 | if_freq = (if_freq/100000)*100000; |
1124 | 1599 | ||
1600 | if (if_freq < 3000000) | ||
1601 | if_freq = 3000000; | ||
1602 | |||
1603 | if (if_freq > 16000000) | ||
1604 | if_freq = 16000000; | ||
1605 | } | ||
1606 | |||
1607 | cx231xx_info("Enter IF=%zd\n", | ||
1608 | sizeof(Dif_set_array)/sizeof(struct dif_settings)); | ||
1609 | for (i = 0; i < sizeof(Dif_set_array)/sizeof(struct dif_settings); i++) { | ||
1610 | if (Dif_set_array[i].if_freq == if_freq) { | ||
1611 | status = vid_blk_write_word(dev, | ||
1612 | Dif_set_array[i].register_address, Dif_set_array[i].value); | ||
1613 | } | ||
1614 | } | ||
1125 | } | 1615 | } |
1126 | 1616 | ||
1127 | /****************************************************************************** | 1617 | /****************************************************************************** |
@@ -1132,6 +1622,7 @@ int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode, | |||
1132 | { | 1622 | { |
1133 | int status = 0; | 1623 | int status = 0; |
1134 | 1624 | ||
1625 | |||
1135 | if (mode == V4L2_TUNER_RADIO) { | 1626 | if (mode == V4L2_TUNER_RADIO) { |
1136 | /* C2HH */ | 1627 | /* C2HH */ |
1137 | /* lo if big signal */ | 1628 | /* lo if big signal */ |
@@ -1174,6 +1665,7 @@ int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode, | |||
1174 | VID_BLK_I2C_ADDRESS, 32, | 1665 | VID_BLK_I2C_ADDRESS, 32, |
1175 | AUD_IO_CTRL, 0, 31, 0x00000003); | 1666 | AUD_IO_CTRL, 0, 31, 0x00000003); |
1176 | } else if ((standard == V4L2_STD_PAL_I) | | 1667 | } else if ((standard == V4L2_STD_PAL_I) | |
1668 | (standard & V4L2_STD_PAL_D) | | ||
1177 | (standard & V4L2_STD_SECAM)) { | 1669 | (standard & V4L2_STD_SECAM)) { |
1178 | /* C2HH setup */ | 1670 | /* C2HH setup */ |
1179 | /* lo if big signal */ | 1671 | /* lo if big signal */ |
@@ -1232,10 +1724,18 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) | |||
1232 | dev->norm = standard; | 1724 | dev->norm = standard; |
1233 | 1725 | ||
1234 | switch (dev->model) { | 1726 | switch (dev->model) { |
1727 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
1235 | case CX231XX_BOARD_CNXT_RDE_250: | 1728 | case CX231XX_BOARD_CNXT_RDE_250: |
1729 | case CX231XX_BOARD_CNXT_SHELBY: | ||
1236 | case CX231XX_BOARD_CNXT_RDU_250: | 1730 | case CX231XX_BOARD_CNXT_RDU_250: |
1731 | case CX231XX_BOARD_CNXT_VIDEO_GRABBER: | ||
1732 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | ||
1237 | func_mode = 0x03; | 1733 | func_mode = 0x03; |
1238 | break; | 1734 | break; |
1735 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
1736 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
1737 | func_mode = 0x01; | ||
1738 | break; | ||
1239 | default: | 1739 | default: |
1240 | func_mode = 0x01; | 1740 | func_mode = 0x01; |
1241 | } | 1741 | } |
@@ -1617,17 +2117,27 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) | |||
1617 | { | 2117 | { |
1618 | int status = 0; | 2118 | int status = 0; |
1619 | u32 dwval; | 2119 | u32 dwval; |
1620 | 2120 | cx231xx_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n", | |
2121 | dev->tuner_type); | ||
1621 | /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for | 2122 | /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for |
1622 | * SECAM L/B/D standards */ | 2123 | * SECAM L/B/D standards */ |
1623 | status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval); | 2124 | status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval); |
1624 | dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF); | 2125 | dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF); |
1625 | 2126 | ||
1626 | if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B | | 2127 | if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B | |
1627 | V4L2_STD_SECAM_D)) | 2128 | V4L2_STD_SECAM_D)) { |
1628 | dwval |= 0x88000000; | 2129 | if (dev->tuner_type == TUNER_NXP_TDA18271) { |
1629 | else | 2130 | dwval &= ~FLD_DIF_IF_REF; |
1630 | dwval |= 0x44000000; | 2131 | dwval |= 0x88000300; |
2132 | } else | ||
2133 | dwval |= 0x88000000; | ||
2134 | } else { | ||
2135 | if (dev->tuner_type == TUNER_NXP_TDA18271) { | ||
2136 | dwval &= ~FLD_DIF_IF_REF; | ||
2137 | dwval |= 0xCC000300; | ||
2138 | } else | ||
2139 | dwval |= 0x44000000; | ||
2140 | } | ||
1631 | 2141 | ||
1632 | status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval); | 2142 | status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval); |
1633 | 2143 | ||
@@ -1714,8 +2224,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) | |||
1714 | return 0; | 2224 | return 0; |
1715 | } | 2225 | } |
1716 | 2226 | ||
1717 | cx231xx_info(" setPowerMode::mode = %d\n", mode); | ||
1718 | |||
1719 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, | 2227 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, |
1720 | 4); | 2228 | 4); |
1721 | if (status < 0) | 2229 | if (status < 0) |
@@ -1761,7 +2269,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) | |||
1761 | 2269 | ||
1762 | case POLARIS_AVMODE_ANALOGT_TV: | 2270 | case POLARIS_AVMODE_ANALOGT_TV: |
1763 | 2271 | ||
1764 | tmp &= (~PWR_DEMOD_EN); | 2272 | tmp |= PWR_DEMOD_EN; |
1765 | tmp |= (I2C_DEMOD_EN); | 2273 | tmp |= (I2C_DEMOD_EN); |
1766 | value[0] = (u8) tmp; | 2274 | value[0] = (u8) tmp; |
1767 | value[1] = (u8) (tmp >> 8); | 2275 | value[1] = (u8) (tmp >> 8); |
@@ -1814,14 +2322,18 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) | |||
1814 | msleep(PWR_SLEEP_INTERVAL); | 2322 | msleep(PWR_SLEEP_INTERVAL); |
1815 | } | 2323 | } |
1816 | 2324 | ||
1817 | if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) || | 2325 | if (dev->board.tuner_type != TUNER_ABSENT) { |
1818 | (dev->model == CX231XX_BOARD_CNXT_RDU_250)) { | 2326 | /* Enable tuner */ |
1819 | /* tuner path to channel 1 from port 3 */ | 2327 | cx231xx_enable_i2c_port_3(dev, true); |
1820 | cx231xx_enable_i2c_for_tuner(dev, I2C_3); | 2328 | |
2329 | /* reset the Tuner */ | ||
2330 | if (dev->board.tuner_gpio) | ||
2331 | cx231xx_gpio_set(dev, dev->board.tuner_gpio); | ||
1821 | 2332 | ||
1822 | if (dev->cx231xx_reset_analog_tuner) | 2333 | if (dev->cx231xx_reset_analog_tuner) |
1823 | dev->cx231xx_reset_analog_tuner(dev); | 2334 | dev->cx231xx_reset_analog_tuner(dev); |
1824 | } | 2335 | } |
2336 | |||
1825 | break; | 2337 | break; |
1826 | 2338 | ||
1827 | case POLARIS_AVMODE_DIGITAL: | 2339 | case POLARIS_AVMODE_DIGITAL: |
@@ -1856,6 +2368,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) | |||
1856 | msleep(PWR_SLEEP_INTERVAL); | 2368 | msleep(PWR_SLEEP_INTERVAL); |
1857 | } | 2369 | } |
1858 | 2370 | ||
2371 | tmp &= (~PWR_AV_MODE); | ||
1859 | tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN; | 2372 | tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN; |
1860 | value[0] = (u8) tmp; | 2373 | value[0] = (u8) tmp; |
1861 | value[1] = (u8) (tmp >> 8); | 2374 | value[1] = (u8) (tmp >> 8); |
@@ -1876,10 +2389,19 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) | |||
1876 | msleep(PWR_SLEEP_INTERVAL); | 2389 | msleep(PWR_SLEEP_INTERVAL); |
1877 | } | 2390 | } |
1878 | 2391 | ||
1879 | if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) || | 2392 | if (dev->board.tuner_type != TUNER_ABSENT) { |
1880 | (dev->model == CX231XX_BOARD_CNXT_RDU_250)) { | 2393 | /* |
1881 | /* tuner path to channel 1 from port 3 */ | 2394 | * Enable tuner |
1882 | cx231xx_enable_i2c_for_tuner(dev, I2C_3); | 2395 | * Hauppauge Exeter seems to need to do something different! |
2396 | */ | ||
2397 | if (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER) | ||
2398 | cx231xx_enable_i2c_port_3(dev, false); | ||
2399 | else | ||
2400 | cx231xx_enable_i2c_port_3(dev, true); | ||
2401 | |||
2402 | /* reset the Tuner */ | ||
2403 | if (dev->board.tuner_gpio) | ||
2404 | cx231xx_gpio_set(dev, dev->board.tuner_gpio); | ||
1883 | 2405 | ||
1884 | if (dev->cx231xx_reset_analog_tuner) | 2406 | if (dev->cx231xx_reset_analog_tuner) |
1885 | dev->cx231xx_reset_analog_tuner(dev); | 2407 | dev->cx231xx_reset_analog_tuner(dev); |
@@ -1913,9 +2435,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) | |||
1913 | 2435 | ||
1914 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, | 2436 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, |
1915 | 4); | 2437 | 4); |
1916 | cx231xx_info(" The data of PWR_CTL_EN register 0x74" | ||
1917 | "=0x%0x,0x%0x,0x%0x,0x%0x\n", | ||
1918 | value[0], value[1], value[2], value[3]); | ||
1919 | 2438 | ||
1920 | return status; | 2439 | return status; |
1921 | } | 2440 | } |
@@ -2000,6 +2519,8 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) | |||
2000 | int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) | 2519 | int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) |
2001 | { | 2520 | { |
2002 | int status = 0; | 2521 | int status = 0; |
2522 | u32 value = 0; | ||
2523 | u8 val[4] = { 0, 0, 0, 0 }; | ||
2003 | 2524 | ||
2004 | if (dev->udev->speed == USB_SPEED_HIGH) { | 2525 | if (dev->udev->speed == USB_SPEED_HIGH) { |
2005 | switch (media_type) { | 2526 | switch (media_type) { |
@@ -2026,10 +2547,36 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) | |||
2026 | break; | 2547 | break; |
2027 | 2548 | ||
2028 | case 4: /* ts1 */ | 2549 | case 4: /* ts1 */ |
2029 | cx231xx_info("%s: set ts1 registers\n", __func__); | 2550 | cx231xx_info("%s: set ts1 registers", __func__); |
2551 | |||
2552 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { | ||
2553 | cx231xx_info(" MPEG\n"); | ||
2554 | value &= 0xFFFFFFFC; | ||
2555 | value |= 0x3; | ||
2556 | |||
2557 | status = cx231xx_mode_register(dev, TS_MODE_REG, value); | ||
2558 | |||
2559 | val[0] = 0x04; | ||
2560 | val[1] = 0xA3; | ||
2561 | val[2] = 0x3B; | ||
2562 | val[3] = 0x00; | ||
2563 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
2564 | TS1_CFG_REG, val, 4); | ||
2565 | |||
2566 | val[0] = 0x00; | ||
2567 | val[1] = 0x08; | ||
2568 | val[2] = 0x00; | ||
2569 | val[3] = 0x08; | ||
2570 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
2571 | TS1_LENGTH_REG, val, 4); | ||
2572 | |||
2573 | } else { | ||
2574 | cx231xx_info(" BDA\n"); | ||
2030 | status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); | 2575 | status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); |
2031 | status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400); | 2576 | status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010); |
2577 | } | ||
2032 | break; | 2578 | break; |
2579 | |||
2033 | case 6: /* ts1 parallel mode */ | 2580 | case 6: /* ts1 parallel mode */ |
2034 | cx231xx_info("%s: set ts1 parrallel mode registers\n", | 2581 | cx231xx_info("%s: set ts1 parrallel mode registers\n", |
2035 | __func__); | 2582 | __func__); |
@@ -2128,7 +2675,7 @@ EXPORT_SYMBOL_GPL(cx231xx_capture_start); | |||
2128 | /***************************************************************************** | 2675 | /***************************************************************************** |
2129 | * G P I O B I T control functions * | 2676 | * G P I O B I T control functions * |
2130 | ******************************************************************************/ | 2677 | ******************************************************************************/ |
2131 | int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val) | 2678 | int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val) |
2132 | { | 2679 | { |
2133 | int status = 0; | 2680 | int status = 0; |
2134 | 2681 | ||
@@ -2137,7 +2684,7 @@ int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val) | |||
2137 | return status; | 2684 | return status; |
2138 | } | 2685 | } |
2139 | 2686 | ||
2140 | int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val) | 2687 | int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val) |
2141 | { | 2688 | { |
2142 | int status = 0; | 2689 | int status = 0; |
2143 | 2690 | ||
@@ -2344,7 +2891,7 @@ int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data) | |||
2344 | return status; | 2891 | return status; |
2345 | } | 2892 | } |
2346 | 2893 | ||
2347 | int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf) | 2894 | int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf) |
2348 | { | 2895 | { |
2349 | u8 value = 0; | 2896 | u8 value = 0; |
2350 | int status = 0; | 2897 | int status = 0; |
@@ -2494,7 +3041,7 @@ int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev) | |||
2494 | /* cx231xx_gpio_i2c_read | 3041 | /* cx231xx_gpio_i2c_read |
2495 | * Function to read data from gpio based I2C interface | 3042 | * Function to read data from gpio based I2C interface |
2496 | */ | 3043 | */ |
2497 | int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len) | 3044 | int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len) |
2498 | { | 3045 | { |
2499 | int status = 0; | 3046 | int status = 0; |
2500 | int i = 0; | 3047 | int i = 0; |
@@ -2538,7 +3085,7 @@ int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len) | |||
2538 | /* cx231xx_gpio_i2c_write | 3085 | /* cx231xx_gpio_i2c_write |
2539 | * Function to write data to gpio based I2C interface | 3086 | * Function to write data to gpio based I2C interface |
2540 | */ | 3087 | */ |
2541 | int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len) | 3088 | int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len) |
2542 | { | 3089 | { |
2543 | int status = 0; | 3090 | int status = 0; |
2544 | int i = 0; | 3091 | int i = 0; |
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index f2a4900014b..56c2d8195ac 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -41,6 +41,10 @@ static int tuner = -1; | |||
41 | module_param(tuner, int, 0444); | 41 | module_param(tuner, int, 0444); |
42 | MODULE_PARM_DESC(tuner, "tuner type"); | 42 | MODULE_PARM_DESC(tuner, "tuner type"); |
43 | 43 | ||
44 | static int transfer_mode = 1; | ||
45 | module_param(transfer_mode, int, 0444); | ||
46 | MODULE_PARM_DESC(transfer_mode, "transfer mode (1-ISO or 0-BULK)"); | ||
47 | |||
44 | static unsigned int disable_ir; | 48 | static unsigned int disable_ir; |
45 | module_param(disable_ir, int, 0444); | 49 | module_param(disable_ir, int, 0444); |
46 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); | 50 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); |
@@ -86,8 +90,8 @@ struct cx231xx_board cx231xx_boards[] = { | |||
86 | } | 90 | } |
87 | }, | 91 | }, |
88 | }, | 92 | }, |
89 | [CX231XX_BOARD_CNXT_RDE_250] = { | 93 | [CX231XX_BOARD_CNXT_CARRAERA] = { |
90 | .name = "Conexant Hybrid TV - RDE250", | 94 | .name = "Conexant Hybrid TV - CARRAERA", |
91 | .tuner_type = TUNER_XC5000, | 95 | .tuner_type = TUNER_XC5000, |
92 | .tuner_addr = 0x61, | 96 | .tuner_addr = 0x61, |
93 | .tuner_gpio = RDE250_XCV_TUNER, | 97 | .tuner_gpio = RDE250_XCV_TUNER, |
@@ -95,6 +99,7 @@ struct cx231xx_board cx231xx_boards[] = { | |||
95 | .tuner_scl_gpio = 0x1a, | 99 | .tuner_scl_gpio = 0x1a, |
96 | .tuner_sda_gpio = 0x1b, | 100 | .tuner_sda_gpio = 0x1b, |
97 | .decoder = CX231XX_AVDECODER, | 101 | .decoder = CX231XX_AVDECODER, |
102 | .output_mode = OUT_MODE_VIP11, | ||
98 | .demod_xfer_mode = 0, | 103 | .demod_xfer_mode = 0, |
99 | .ctl_pin_status_mask = 0xFFFFFFC4, | 104 | .ctl_pin_status_mask = 0xFFFFFFC4, |
100 | .agc_analog_digital_select_gpio = 0x0c, | 105 | .agc_analog_digital_select_gpio = 0x0c, |
@@ -125,9 +130,8 @@ struct cx231xx_board cx231xx_boards[] = { | |||
125 | } | 130 | } |
126 | }, | 131 | }, |
127 | }, | 132 | }, |
128 | 133 | [CX231XX_BOARD_CNXT_SHELBY] = { | |
129 | [CX231XX_BOARD_CNXT_RDU_250] = { | 134 | .name = "Conexant Hybrid TV - SHELBY", |
130 | .name = "Conexant Hybrid TV - RDU250", | ||
131 | .tuner_type = TUNER_XC5000, | 135 | .tuner_type = TUNER_XC5000, |
132 | .tuner_addr = 0x61, | 136 | .tuner_addr = 0x61, |
133 | .tuner_gpio = RDE250_XCV_TUNER, | 137 | .tuner_gpio = RDE250_XCV_TUNER, |
@@ -135,6 +139,7 @@ struct cx231xx_board cx231xx_boards[] = { | |||
135 | .tuner_scl_gpio = 0x1a, | 139 | .tuner_scl_gpio = 0x1a, |
136 | .tuner_sda_gpio = 0x1b, | 140 | .tuner_sda_gpio = 0x1b, |
137 | .decoder = CX231XX_AVDECODER, | 141 | .decoder = CX231XX_AVDECODER, |
142 | .output_mode = OUT_MODE_VIP11, | ||
138 | .demod_xfer_mode = 0, | 143 | .demod_xfer_mode = 0, |
139 | .ctl_pin_status_mask = 0xFFFFFFC4, | 144 | .ctl_pin_status_mask = 0xFFFFFFC4, |
140 | .agc_analog_digital_select_gpio = 0x0c, | 145 | .agc_analog_digital_select_gpio = 0x0c, |
@@ -165,6 +170,231 @@ struct cx231xx_board cx231xx_boards[] = { | |||
165 | } | 170 | } |
166 | }, | 171 | }, |
167 | }, | 172 | }, |
173 | [CX231XX_BOARD_CNXT_RDE_253S] = { | ||
174 | .name = "Conexant Hybrid TV - RDE253S", | ||
175 | .tuner_type = TUNER_NXP_TDA18271, | ||
176 | .tuner_addr = 0x60, | ||
177 | .tuner_gpio = RDE250_XCV_TUNER, | ||
178 | .tuner_sif_gpio = 0x05, | ||
179 | .tuner_scl_gpio = 0x1a, | ||
180 | .tuner_sda_gpio = 0x1b, | ||
181 | .decoder = CX231XX_AVDECODER, | ||
182 | .output_mode = OUT_MODE_VIP11, | ||
183 | .demod_xfer_mode = 0, | ||
184 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
185 | .agc_analog_digital_select_gpio = 0x1c, | ||
186 | .gpio_pin_status_mask = 0x4001000, | ||
187 | .tuner_i2c_master = 1, | ||
188 | .demod_i2c_master = 2, | ||
189 | .has_dvb = 1, | ||
190 | .demod_addr = 0x02, | ||
191 | .norm = V4L2_STD_PAL, | ||
192 | |||
193 | .input = {{ | ||
194 | .type = CX231XX_VMUX_TELEVISION, | ||
195 | .vmux = CX231XX_VIN_3_1, | ||
196 | .amux = CX231XX_AMUX_VIDEO, | ||
197 | .gpio = NULL, | ||
198 | }, { | ||
199 | .type = CX231XX_VMUX_COMPOSITE1, | ||
200 | .vmux = CX231XX_VIN_2_1, | ||
201 | .amux = CX231XX_AMUX_LINE_IN, | ||
202 | .gpio = NULL, | ||
203 | }, { | ||
204 | .type = CX231XX_VMUX_SVIDEO, | ||
205 | .vmux = CX231XX_VIN_1_1 | | ||
206 | (CX231XX_VIN_1_2 << 8) | | ||
207 | CX25840_SVIDEO_ON, | ||
208 | .amux = CX231XX_AMUX_LINE_IN, | ||
209 | .gpio = NULL, | ||
210 | } | ||
211 | }, | ||
212 | }, | ||
213 | |||
214 | [CX231XX_BOARD_CNXT_RDU_253S] = { | ||
215 | .name = "Conexant Hybrid TV - RDU253S", | ||
216 | .tuner_type = TUNER_NXP_TDA18271, | ||
217 | .tuner_addr = 0x60, | ||
218 | .tuner_gpio = RDE250_XCV_TUNER, | ||
219 | .tuner_sif_gpio = 0x05, | ||
220 | .tuner_scl_gpio = 0x1a, | ||
221 | .tuner_sda_gpio = 0x1b, | ||
222 | .decoder = CX231XX_AVDECODER, | ||
223 | .output_mode = OUT_MODE_VIP11, | ||
224 | .demod_xfer_mode = 0, | ||
225 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
226 | .agc_analog_digital_select_gpio = 0x1c, | ||
227 | .gpio_pin_status_mask = 0x4001000, | ||
228 | .tuner_i2c_master = 1, | ||
229 | .demod_i2c_master = 2, | ||
230 | .has_dvb = 1, | ||
231 | .demod_addr = 0x02, | ||
232 | .norm = V4L2_STD_PAL, | ||
233 | |||
234 | .input = {{ | ||
235 | .type = CX231XX_VMUX_TELEVISION, | ||
236 | .vmux = CX231XX_VIN_3_1, | ||
237 | .amux = CX231XX_AMUX_VIDEO, | ||
238 | .gpio = NULL, | ||
239 | }, { | ||
240 | .type = CX231XX_VMUX_COMPOSITE1, | ||
241 | .vmux = CX231XX_VIN_2_1, | ||
242 | .amux = CX231XX_AMUX_LINE_IN, | ||
243 | .gpio = NULL, | ||
244 | }, { | ||
245 | .type = CX231XX_VMUX_SVIDEO, | ||
246 | .vmux = CX231XX_VIN_1_1 | | ||
247 | (CX231XX_VIN_1_2 << 8) | | ||
248 | CX25840_SVIDEO_ON, | ||
249 | .amux = CX231XX_AMUX_LINE_IN, | ||
250 | .gpio = NULL, | ||
251 | } | ||
252 | }, | ||
253 | }, | ||
254 | [CX231XX_BOARD_CNXT_VIDEO_GRABBER] = { | ||
255 | .name = "Conexant VIDEO GRABBER", | ||
256 | .tuner_type = TUNER_ABSENT, | ||
257 | .decoder = CX231XX_AVDECODER, | ||
258 | .output_mode = OUT_MODE_VIP11, | ||
259 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
260 | .agc_analog_digital_select_gpio = 0x1c, | ||
261 | .gpio_pin_status_mask = 0x4001000, | ||
262 | .norm = V4L2_STD_PAL, | ||
263 | |||
264 | .input = {{ | ||
265 | .type = CX231XX_VMUX_COMPOSITE1, | ||
266 | .vmux = CX231XX_VIN_2_1, | ||
267 | .amux = CX231XX_AMUX_LINE_IN, | ||
268 | .gpio = NULL, | ||
269 | }, { | ||
270 | .type = CX231XX_VMUX_SVIDEO, | ||
271 | .vmux = CX231XX_VIN_1_1 | | ||
272 | (CX231XX_VIN_1_2 << 8) | | ||
273 | CX25840_SVIDEO_ON, | ||
274 | .amux = CX231XX_AMUX_LINE_IN, | ||
275 | .gpio = NULL, | ||
276 | } | ||
277 | }, | ||
278 | }, | ||
279 | [CX231XX_BOARD_CNXT_RDE_250] = { | ||
280 | .name = "Conexant Hybrid TV - rde 250", | ||
281 | .tuner_type = TUNER_XC5000, | ||
282 | .tuner_addr = 0x61, | ||
283 | .tuner_gpio = RDE250_XCV_TUNER, | ||
284 | .tuner_sif_gpio = 0x05, | ||
285 | .tuner_scl_gpio = 0x1a, | ||
286 | .tuner_sda_gpio = 0x1b, | ||
287 | .decoder = CX231XX_AVDECODER, | ||
288 | .output_mode = OUT_MODE_VIP11, | ||
289 | .demod_xfer_mode = 0, | ||
290 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
291 | .agc_analog_digital_select_gpio = 0x0c, | ||
292 | .gpio_pin_status_mask = 0x4001000, | ||
293 | .tuner_i2c_master = 1, | ||
294 | .demod_i2c_master = 2, | ||
295 | .has_dvb = 1, | ||
296 | .demod_addr = 0x02, | ||
297 | .norm = V4L2_STD_PAL, | ||
298 | |||
299 | .input = {{ | ||
300 | .type = CX231XX_VMUX_TELEVISION, | ||
301 | .vmux = CX231XX_VIN_2_1, | ||
302 | .amux = CX231XX_AMUX_VIDEO, | ||
303 | .gpio = NULL, | ||
304 | } | ||
305 | }, | ||
306 | }, | ||
307 | [CX231XX_BOARD_CNXT_RDU_250] = { | ||
308 | .name = "Conexant Hybrid TV - RDU 250", | ||
309 | .tuner_type = TUNER_XC5000, | ||
310 | .tuner_addr = 0x61, | ||
311 | .tuner_gpio = RDE250_XCV_TUNER, | ||
312 | .tuner_sif_gpio = 0x05, | ||
313 | .tuner_scl_gpio = 0x1a, | ||
314 | .tuner_sda_gpio = 0x1b, | ||
315 | .decoder = CX231XX_AVDECODER, | ||
316 | .output_mode = OUT_MODE_VIP11, | ||
317 | .demod_xfer_mode = 0, | ||
318 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
319 | .agc_analog_digital_select_gpio = 0x0c, | ||
320 | .gpio_pin_status_mask = 0x4001000, | ||
321 | .tuner_i2c_master = 1, | ||
322 | .demod_i2c_master = 2, | ||
323 | .has_dvb = 1, | ||
324 | .demod_addr = 0x32, | ||
325 | .norm = V4L2_STD_NTSC, | ||
326 | |||
327 | .input = {{ | ||
328 | .type = CX231XX_VMUX_TELEVISION, | ||
329 | .vmux = CX231XX_VIN_2_1, | ||
330 | .amux = CX231XX_AMUX_VIDEO, | ||
331 | .gpio = NULL, | ||
332 | } | ||
333 | }, | ||
334 | }, | ||
335 | [CX231XX_BOARD_HAUPPAUGE_EXETER] = { | ||
336 | .name = "Hauppauge EXETER", | ||
337 | .tuner_type = TUNER_NXP_TDA18271, | ||
338 | .tuner_addr = 0x60, | ||
339 | .tuner_gpio = RDE250_XCV_TUNER, | ||
340 | .tuner_sif_gpio = 0x05, | ||
341 | .tuner_scl_gpio = 0x1a, | ||
342 | .tuner_sda_gpio = 0x1b, | ||
343 | .decoder = CX231XX_AVDECODER, | ||
344 | .output_mode = OUT_MODE_VIP11, | ||
345 | .demod_xfer_mode = 0, | ||
346 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
347 | .agc_analog_digital_select_gpio = 0x0c, | ||
348 | .gpio_pin_status_mask = 0x4001000, | ||
349 | .tuner_i2c_master = 1, | ||
350 | .demod_i2c_master = 2, | ||
351 | .has_dvb = 1, | ||
352 | .demod_addr = 0x0e, | ||
353 | .norm = V4L2_STD_NTSC, | ||
354 | |||
355 | .input = {{ | ||
356 | .type = CX231XX_VMUX_TELEVISION, | ||
357 | .vmux = CX231XX_VIN_3_1, | ||
358 | .amux = CX231XX_AMUX_VIDEO, | ||
359 | .gpio = 0, | ||
360 | }, { | ||
361 | .type = CX231XX_VMUX_COMPOSITE1, | ||
362 | .vmux = CX231XX_VIN_2_1, | ||
363 | .amux = CX231XX_AMUX_LINE_IN, | ||
364 | .gpio = 0, | ||
365 | }, { | ||
366 | .type = CX231XX_VMUX_SVIDEO, | ||
367 | .vmux = CX231XX_VIN_1_1 | | ||
368 | (CX231XX_VIN_1_2 << 8) | | ||
369 | CX25840_SVIDEO_ON, | ||
370 | .amux = CX231XX_AMUX_LINE_IN, | ||
371 | .gpio = 0, | ||
372 | } }, | ||
373 | }, | ||
374 | [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = { | ||
375 | .name = "Hauppauge USB Live 2", | ||
376 | .tuner_type = TUNER_ABSENT, | ||
377 | .decoder = CX231XX_AVDECODER, | ||
378 | .output_mode = OUT_MODE_VIP11, | ||
379 | .demod_xfer_mode = 0, | ||
380 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
381 | .agc_analog_digital_select_gpio = 0x0c, | ||
382 | .gpio_pin_status_mask = 0x4001000, | ||
383 | .norm = V4L2_STD_NTSC, | ||
384 | .input = {{ | ||
385 | .type = CX231XX_VMUX_COMPOSITE1, | ||
386 | .vmux = CX231XX_VIN_2_1, | ||
387 | .amux = CX231XX_AMUX_LINE_IN, | ||
388 | .gpio = 0, | ||
389 | }, { | ||
390 | .type = CX231XX_VMUX_SVIDEO, | ||
391 | .vmux = CX231XX_VIN_1_1 | | ||
392 | (CX231XX_VIN_1_2 << 8) | | ||
393 | CX25840_SVIDEO_ON, | ||
394 | .amux = CX231XX_AMUX_LINE_IN, | ||
395 | .gpio = 0, | ||
396 | } }, | ||
397 | }, | ||
168 | }; | 398 | }; |
169 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | 399 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); |
170 | 400 | ||
@@ -172,12 +402,28 @@ const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | |||
172 | struct usb_device_id cx231xx_id_table[] = { | 402 | struct usb_device_id cx231xx_id_table[] = { |
173 | {USB_DEVICE(0x0572, 0x5A3C), | 403 | {USB_DEVICE(0x0572, 0x5A3C), |
174 | .driver_info = CX231XX_BOARD_UNKNOWN}, | 404 | .driver_info = CX231XX_BOARD_UNKNOWN}, |
405 | {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), | ||
406 | .driver_info = CX231XX_BOARD_UNKNOWN}, | ||
175 | {USB_DEVICE(0x0572, 0x58A2), | 407 | {USB_DEVICE(0x0572, 0x58A2), |
176 | .driver_info = CX231XX_BOARD_CNXT_RDE_250}, | 408 | .driver_info = CX231XX_BOARD_CNXT_CARRAERA}, |
177 | {USB_DEVICE(0x0572, 0x58A1), | 409 | {USB_DEVICE(0x0572, 0x58A1), |
410 | .driver_info = CX231XX_BOARD_CNXT_SHELBY}, | ||
411 | {USB_DEVICE(0x0572, 0x58A4), | ||
412 | .driver_info = CX231XX_BOARD_CNXT_RDE_253S}, | ||
413 | {USB_DEVICE(0x0572, 0x58A5), | ||
414 | .driver_info = CX231XX_BOARD_CNXT_RDU_253S}, | ||
415 | {USB_DEVICE(0x0572, 0x58A6), | ||
416 | .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER}, | ||
417 | {USB_DEVICE(0x0572, 0x589E), | ||
418 | .driver_info = CX231XX_BOARD_CNXT_RDE_250}, | ||
419 | {USB_DEVICE(0x0572, 0x58A0), | ||
178 | .driver_info = CX231XX_BOARD_CNXT_RDU_250}, | 420 | .driver_info = CX231XX_BOARD_CNXT_RDU_250}, |
179 | {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), | 421 | {USB_DEVICE(0x2040, 0xb120), |
180 | .driver_info = CX231XX_BOARD_UNKNOWN}, | 422 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, |
423 | {USB_DEVICE(0x2040, 0xb140), | ||
424 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, | ||
425 | {USB_DEVICE(0x2040, 0xc200), | ||
426 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, | ||
181 | {}, | 427 | {}, |
182 | }; | 428 | }; |
183 | 429 | ||
@@ -212,6 +458,23 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) | |||
212 | } | 458 | } |
213 | EXPORT_SYMBOL_GPL(cx231xx_tuner_callback); | 459 | EXPORT_SYMBOL_GPL(cx231xx_tuner_callback); |
214 | 460 | ||
461 | void cx231xx_reset_out(struct cx231xx *dev) | ||
462 | { | ||
463 | cx231xx_set_gpio_value(dev, CX23417_RESET, 1); | ||
464 | msleep(200); | ||
465 | cx231xx_set_gpio_value(dev, CX23417_RESET, 0); | ||
466 | msleep(200); | ||
467 | cx231xx_set_gpio_value(dev, CX23417_RESET, 1); | ||
468 | } | ||
469 | void cx231xx_enable_OSC(struct cx231xx *dev) | ||
470 | { | ||
471 | cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1); | ||
472 | } | ||
473 | void cx231xx_sleep_s5h1432(struct cx231xx *dev) | ||
474 | { | ||
475 | cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0); | ||
476 | } | ||
477 | |||
215 | static inline void cx231xx_set_model(struct cx231xx *dev) | 478 | static inline void cx231xx_set_model(struct cx231xx *dev) |
216 | { | 479 | { |
217 | memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board)); | 480 | memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board)); |
@@ -232,13 +495,11 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) | |||
232 | if (dev->board.tuner_gpio) { | 495 | if (dev->board.tuner_gpio) { |
233 | cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); | 496 | cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); |
234 | cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); | 497 | cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); |
498 | } | ||
499 | if (dev->board.tuner_sif_gpio >= 0) | ||
235 | cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); | 500 | cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); |
236 | 501 | ||
237 | /* request some modules if any required */ | 502 | /* request some modules if any required */ |
238 | |||
239 | /* reset the Tuner */ | ||
240 | cx231xx_gpio_set(dev, dev->board.tuner_gpio); | ||
241 | } | ||
242 | 503 | ||
243 | /* set the mode to Analog mode initially */ | 504 | /* set the mode to Analog mode initially */ |
244 | cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); | 505 | cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); |
@@ -286,26 +547,6 @@ static void cx231xx_config_tuner(struct cx231xx *dev) | |||
286 | 547 | ||
287 | } | 548 | } |
288 | 549 | ||
289 | /* ----------------------------------------------------------------------- */ | ||
290 | void cx231xx_register_i2c_ir(struct cx231xx *dev) | ||
291 | { | ||
292 | if (disable_ir) | ||
293 | return; | ||
294 | |||
295 | /* REVISIT: instantiate IR device */ | ||
296 | |||
297 | /* detect & configure */ | ||
298 | switch (dev->model) { | ||
299 | |||
300 | case CX231XX_BOARD_CNXT_RDE_250: | ||
301 | break; | ||
302 | case CX231XX_BOARD_CNXT_RDU_250: | ||
303 | break; | ||
304 | default: | ||
305 | break; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | void cx231xx_card_setup(struct cx231xx *dev) | 550 | void cx231xx_card_setup(struct cx231xx *dev) |
310 | { | 551 | { |
311 | 552 | ||
@@ -319,29 +560,24 @@ void cx231xx_card_setup(struct cx231xx *dev) | |||
319 | if (dev->board.decoder == CX231XX_AVDECODER) { | 560 | if (dev->board.decoder == CX231XX_AVDECODER) { |
320 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 561 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
321 | &dev->i2c_bus[0].i2c_adap, | 562 | &dev->i2c_bus[0].i2c_adap, |
322 | "cx25840", "cx25840", 0x88 >> 1, NULL); | 563 | NULL, "cx25840", 0x88 >> 1, NULL); |
323 | if (dev->sd_cx25840 == NULL) | 564 | if (dev->sd_cx25840 == NULL) |
324 | cx231xx_info("cx25840 subdev registration failure\n"); | 565 | cx231xx_info("cx25840 subdev registration failure\n"); |
325 | cx25840_call(dev, core, load_fw); | 566 | cx25840_call(dev, core, load_fw); |
326 | 567 | ||
327 | } | 568 | } |
328 | 569 | ||
570 | /* Initialize the tuner */ | ||
329 | if (dev->board.tuner_type != TUNER_ABSENT) { | 571 | if (dev->board.tuner_type != TUNER_ABSENT) { |
330 | dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 572 | dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
331 | &dev->i2c_bus[1].i2c_adap, | 573 | &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, |
332 | "tuner", "tuner", 0xc2 >> 1, NULL); | 574 | NULL, "tuner", |
575 | dev->tuner_addr, NULL); | ||
333 | if (dev->sd_tuner == NULL) | 576 | if (dev->sd_tuner == NULL) |
334 | cx231xx_info("tuner subdev registration failure\n"); | 577 | cx231xx_info("tuner subdev registration failure\n"); |
335 | 578 | else | |
336 | cx231xx_config_tuner(dev); | 579 | cx231xx_config_tuner(dev); |
337 | } | 580 | } |
338 | |||
339 | cx231xx_config_tuner(dev); | ||
340 | |||
341 | #if 0 | ||
342 | /* TBD IR will be added later */ | ||
343 | cx231xx_ir_init(dev); | ||
344 | #endif | ||
345 | } | 581 | } |
346 | 582 | ||
347 | /* | 583 | /* |
@@ -375,12 +611,6 @@ void cx231xx_config_i2c(struct cx231xx *dev) | |||
375 | */ | 611 | */ |
376 | void cx231xx_release_resources(struct cx231xx *dev) | 612 | void cx231xx_release_resources(struct cx231xx *dev) |
377 | { | 613 | { |
378 | |||
379 | #if 0 /* TBD IR related */ | ||
380 | if (dev->ir) | ||
381 | cx231xx_ir_fini(dev); | ||
382 | #endif | ||
383 | |||
384 | cx231xx_release_analog_resources(dev); | 614 | cx231xx_release_analog_resources(dev); |
385 | 615 | ||
386 | cx231xx_remove_from_devlist(dev); | 616 | cx231xx_remove_from_devlist(dev); |
@@ -409,6 +639,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, | |||
409 | mutex_init(&dev->lock); | 639 | mutex_init(&dev->lock); |
410 | mutex_init(&dev->ctrl_urb_lock); | 640 | mutex_init(&dev->ctrl_urb_lock); |
411 | mutex_init(&dev->gpio_i2c_lock); | 641 | mutex_init(&dev->gpio_i2c_lock); |
642 | mutex_init(&dev->i2c_lock); | ||
412 | 643 | ||
413 | spin_lock_init(&dev->video_mode.slock); | 644 | spin_lock_init(&dev->video_mode.slock); |
414 | spin_lock_init(&dev->vbi_mode.slock); | 645 | spin_lock_init(&dev->vbi_mode.slock); |
@@ -427,6 +658,13 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, | |||
427 | /* Query cx231xx to find what pcb config it is related to */ | 658 | /* Query cx231xx to find what pcb config it is related to */ |
428 | initialize_cx231xx(dev); | 659 | initialize_cx231xx(dev); |
429 | 660 | ||
661 | /*To workaround error number=-71 on EP0 for VideoGrabber, | ||
662 | need set alt here.*/ | ||
663 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || | ||
664 | dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) { | ||
665 | cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3); | ||
666 | cx231xx_set_alt_setting(dev, INDEX_VANC, 1); | ||
667 | } | ||
430 | /* Cx231xx pre card setup */ | 668 | /* Cx231xx pre card setup */ |
431 | cx231xx_pre_card_setup(dev); | 669 | cx231xx_pre_card_setup(dev); |
432 | 670 | ||
@@ -442,6 +680,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, | |||
442 | /* register i2c bus */ | 680 | /* register i2c bus */ |
443 | errCode = cx231xx_dev_init(dev); | 681 | errCode = cx231xx_dev_init(dev); |
444 | if (errCode < 0) { | 682 | if (errCode < 0) { |
683 | cx231xx_dev_uninit(dev); | ||
445 | cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", | 684 | cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", |
446 | __func__, errCode); | 685 | __func__, errCode); |
447 | return errCode; | 686 | return errCode; |
@@ -460,8 +699,6 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, | |||
460 | dev->width = maxw; | 699 | dev->width = maxw; |
461 | dev->height = maxh; | 700 | dev->height = maxh; |
462 | dev->interlaced = 0; | 701 | dev->interlaced = 0; |
463 | dev->hscale = 0; | ||
464 | dev->vscale = 0; | ||
465 | dev->video_input = 0; | 702 | dev->video_input = 0; |
466 | 703 | ||
467 | errCode = cx231xx_config(dev); | 704 | errCode = cx231xx_config(dev); |
@@ -480,9 +717,17 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, | |||
480 | INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued); | 717 | INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued); |
481 | 718 | ||
482 | /* Reset other chips required if they are tied up with GPIO pins */ | 719 | /* Reset other chips required if they are tied up with GPIO pins */ |
483 | |||
484 | cx231xx_add_into_devlist(dev); | 720 | cx231xx_add_into_devlist(dev); |
485 | 721 | ||
722 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { | ||
723 | printk(KERN_INFO "attach 417 %d\n", dev->model); | ||
724 | if (cx231xx_417_register(dev) < 0) { | ||
725 | printk(KERN_ERR | ||
726 | "%s() Failed to register 417 on VID_B\n", | ||
727 | __func__); | ||
728 | } | ||
729 | } | ||
730 | |||
486 | retval = cx231xx_register_analog_devices(dev); | 731 | retval = cx231xx_register_analog_devices(dev); |
487 | if (retval < 0) { | 732 | if (retval < 0) { |
488 | cx231xx_release_resources(dev); | 733 | cx231xx_release_resources(dev); |
@@ -537,13 +782,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
537 | char *speed; | 782 | char *speed; |
538 | char descr[255] = ""; | 783 | char descr[255] = ""; |
539 | struct usb_interface *lif = NULL; | 784 | struct usb_interface *lif = NULL; |
540 | int skip_interface = 0; | ||
541 | struct usb_interface_assoc_descriptor *assoc_desc; | 785 | struct usb_interface_assoc_descriptor *assoc_desc; |
542 | 786 | ||
543 | udev = usb_get_dev(interface_to_usbdev(interface)); | 787 | udev = usb_get_dev(interface_to_usbdev(interface)); |
544 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | 788 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; |
545 | 789 | ||
546 | if (!ifnum) { | 790 | if (ifnum == 1) { |
547 | /* | 791 | /* |
548 | * Interface number 0 - IR interface | 792 | * Interface number 0 - IR interface |
549 | */ | 793 | */ |
@@ -552,8 +796,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
552 | cx231xx_devused |= 1 << nr; | 796 | cx231xx_devused |= 1 << nr; |
553 | 797 | ||
554 | if (nr >= CX231XX_MAXBOARDS) { | 798 | if (nr >= CX231XX_MAXBOARDS) { |
555 | cx231xx_err(DRIVER_NAME ": Supports only %i cx231xx boards.\n", | 799 | cx231xx_err(DRIVER_NAME |
556 | CX231XX_MAXBOARDS); | 800 | ": Supports only %i cx231xx boards.\n", CX231XX_MAXBOARDS); |
557 | cx231xx_devused &= ~(1 << nr); | 801 | cx231xx_devused &= ~(1 << nr); |
558 | return -ENOMEM; | 802 | return -ENOMEM; |
559 | } | 803 | } |
@@ -578,6 +822,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
578 | dev->xc_fw_load_done = 0; | 822 | dev->xc_fw_load_done = 0; |
579 | dev->has_alsa_audio = 1; | 823 | dev->has_alsa_audio = 1; |
580 | dev->power_mode = -1; | 824 | dev->power_mode = -1; |
825 | atomic_set(&dev->devlist_count, 0); | ||
581 | 826 | ||
582 | /* 0 - vbi ; 1 -sliced cc mode */ | 827 | /* 0 - vbi ; 1 -sliced cc mode */ |
583 | dev->vbi_or_sliced_cc_mode = 0; | 828 | dev->vbi_or_sliced_cc_mode = 0; |
@@ -591,6 +836,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
591 | /* store the current interface */ | 836 | /* store the current interface */ |
592 | lif = interface; | 837 | lif = interface; |
593 | 838 | ||
839 | /*mode_tv: digital=1 or analog=0*/ | ||
840 | dev->mode_tv = 0; | ||
841 | |||
842 | dev->USE_ISO = transfer_mode; | ||
843 | |||
594 | switch (udev->speed) { | 844 | switch (udev->speed) { |
595 | case USB_SPEED_LOW: | 845 | case USB_SPEED_LOW: |
596 | speed = "1.5"; | 846 | speed = "1.5"; |
@@ -624,13 +874,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
624 | le16_to_cpu(udev->descriptor.idVendor), | 874 | le16_to_cpu(udev->descriptor.idVendor), |
625 | le16_to_cpu(udev->descriptor.idProduct), | 875 | le16_to_cpu(udev->descriptor.idProduct), |
626 | dev->max_iad_interface_count); | 876 | dev->max_iad_interface_count); |
627 | } else { | ||
628 | /* Get dev structure first */ | ||
629 | dev = usb_get_intfdata(udev->actconfig->interface[0]); | ||
630 | if (dev == NULL) { | ||
631 | cx231xx_err(DRIVER_NAME ": out of first interface!\n"); | ||
632 | return -ENODEV; | ||
633 | } | ||
634 | 877 | ||
635 | /* store the interface 0 back */ | 878 | /* store the interface 0 back */ |
636 | lif = udev->actconfig->interface[0]; | 879 | lif = udev->actconfig->interface[0]; |
@@ -641,35 +884,21 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
641 | /* get device number */ | 884 | /* get device number */ |
642 | nr = dev->devno; | 885 | nr = dev->devno; |
643 | 886 | ||
644 | /* | 887 | assoc_desc = udev->actconfig->intf_assoc[0]; |
645 | * set skip interface, for all interfaces but | 888 | if (assoc_desc->bFirstInterface != ifnum) { |
646 | * interface 1 and the last one | 889 | cx231xx_err(DRIVER_NAME ": Not found " |
647 | */ | 890 | "matching IAD interface\n"); |
648 | if ((ifnum != 1) && ((dev->interface_count - 1) | 891 | return -ENODEV; |
649 | != dev->max_iad_interface_count)) | ||
650 | skip_interface = 1; | ||
651 | |||
652 | if (ifnum == 1) { | ||
653 | assoc_desc = udev->actconfig->intf_assoc[0]; | ||
654 | if (assoc_desc->bFirstInterface != ifnum) { | ||
655 | cx231xx_err(DRIVER_NAME ": Not found " | ||
656 | "matching IAD interface\n"); | ||
657 | return -ENODEV; | ||
658 | } | ||
659 | } | 892 | } |
660 | } | 893 | } else { |
661 | |||
662 | if (skip_interface) | ||
663 | return -ENODEV; | 894 | return -ENODEV; |
895 | } | ||
664 | 896 | ||
665 | cx231xx_info("registering interface %d\n", ifnum); | 897 | cx231xx_info("registering interface %d\n", ifnum); |
666 | 898 | ||
667 | /* save our data pointer in this interface device */ | 899 | /* save our data pointer in this interface device */ |
668 | usb_set_intfdata(lif, dev); | 900 | usb_set_intfdata(lif, dev); |
669 | 901 | ||
670 | if ((dev->interface_count - 1) != dev->max_iad_interface_count) | ||
671 | return 0; | ||
672 | |||
673 | /* | 902 | /* |
674 | * AV device initialization - only done at the last interface | 903 | * AV device initialization - only done at the last interface |
675 | */ | 904 | */ |
@@ -680,15 +909,18 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
680 | cx231xx_errdev("v4l2_device_register failed\n"); | 909 | cx231xx_errdev("v4l2_device_register failed\n"); |
681 | cx231xx_devused &= ~(1 << nr); | 910 | cx231xx_devused &= ~(1 << nr); |
682 | kfree(dev); | 911 | kfree(dev); |
912 | dev = NULL; | ||
683 | return -EIO; | 913 | return -EIO; |
684 | } | 914 | } |
685 | |||
686 | /* allocate device struct */ | 915 | /* allocate device struct */ |
687 | retval = cx231xx_init_dev(&dev, udev, nr); | 916 | retval = cx231xx_init_dev(&dev, udev, nr); |
688 | if (retval) { | 917 | if (retval) { |
689 | cx231xx_devused &= ~(1 << dev->devno); | 918 | cx231xx_devused &= ~(1 << dev->devno); |
690 | v4l2_device_unregister(&dev->v4l2_dev); | 919 | v4l2_device_unregister(&dev->v4l2_dev); |
691 | kfree(dev); | 920 | kfree(dev); |
921 | dev = NULL; | ||
922 | usb_set_intfdata(lif, NULL); | ||
923 | |||
692 | return retval; | 924 | return retval; |
693 | } | 925 | } |
694 | 926 | ||
@@ -711,6 +943,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
711 | cx231xx_devused &= ~(1 << nr); | 943 | cx231xx_devused &= ~(1 << nr); |
712 | v4l2_device_unregister(&dev->v4l2_dev); | 944 | v4l2_device_unregister(&dev->v4l2_dev); |
713 | kfree(dev); | 945 | kfree(dev); |
946 | dev = NULL; | ||
714 | return -ENOMEM; | 947 | return -ENOMEM; |
715 | } | 948 | } |
716 | 949 | ||
@@ -744,6 +977,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
744 | cx231xx_devused &= ~(1 << nr); | 977 | cx231xx_devused &= ~(1 << nr); |
745 | v4l2_device_unregister(&dev->v4l2_dev); | 978 | v4l2_device_unregister(&dev->v4l2_dev); |
746 | kfree(dev); | 979 | kfree(dev); |
980 | dev = NULL; | ||
747 | return -ENOMEM; | 981 | return -ENOMEM; |
748 | } | 982 | } |
749 | 983 | ||
@@ -778,6 +1012,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
778 | cx231xx_devused &= ~(1 << nr); | 1012 | cx231xx_devused &= ~(1 << nr); |
779 | v4l2_device_unregister(&dev->v4l2_dev); | 1013 | v4l2_device_unregister(&dev->v4l2_dev); |
780 | kfree(dev); | 1014 | kfree(dev); |
1015 | dev = NULL; | ||
781 | return -ENOMEM; | 1016 | return -ENOMEM; |
782 | } | 1017 | } |
783 | 1018 | ||
@@ -813,6 +1048,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
813 | cx231xx_devused &= ~(1 << nr); | 1048 | cx231xx_devused &= ~(1 << nr); |
814 | v4l2_device_unregister(&dev->v4l2_dev); | 1049 | v4l2_device_unregister(&dev->v4l2_dev); |
815 | kfree(dev); | 1050 | kfree(dev); |
1051 | dev = NULL; | ||
816 | return -ENOMEM; | 1052 | return -ENOMEM; |
817 | } | 1053 | } |
818 | 1054 | ||
@@ -827,6 +1063,15 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
827 | } | 1063 | } |
828 | } | 1064 | } |
829 | 1065 | ||
1066 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { | ||
1067 | cx231xx_enable_OSC(dev); | ||
1068 | cx231xx_reset_out(dev); | ||
1069 | cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3); | ||
1070 | } | ||
1071 | |||
1072 | if (dev->model == CX231XX_BOARD_CNXT_RDE_253S) | ||
1073 | cx231xx_sleep_s5h1432(dev); | ||
1074 | |||
830 | /* load other modules required */ | 1075 | /* load other modules required */ |
831 | request_modules(dev); | 1076 | request_modules(dev); |
832 | 1077 | ||
@@ -867,7 +1112,10 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) | |||
867 | video_device_node_name(dev->vdev)); | 1112 | video_device_node_name(dev->vdev)); |
868 | 1113 | ||
869 | dev->state |= DEV_MISCONFIGURED; | 1114 | dev->state |= DEV_MISCONFIGURED; |
870 | cx231xx_uninit_isoc(dev); | 1115 | if (dev->USE_ISO) |
1116 | cx231xx_uninit_isoc(dev); | ||
1117 | else | ||
1118 | cx231xx_uninit_bulk(dev); | ||
871 | dev->state |= DEV_DISCONNECTED; | 1119 | dev->state |= DEV_DISCONNECTED; |
872 | wake_up_interruptible(&dev->wait_frame); | 1120 | wake_up_interruptible(&dev->wait_frame); |
873 | wake_up_interruptible(&dev->wait_stream); | 1121 | wake_up_interruptible(&dev->wait_stream); |
@@ -886,6 +1134,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) | |||
886 | kfree(dev->sliced_cc_mode.alt_max_pkt_size); | 1134 | kfree(dev->sliced_cc_mode.alt_max_pkt_size); |
887 | kfree(dev->ts1_mode.alt_max_pkt_size); | 1135 | kfree(dev->ts1_mode.alt_max_pkt_size); |
888 | kfree(dev); | 1136 | kfree(dev); |
1137 | dev = NULL; | ||
889 | } | 1138 | } |
890 | } | 1139 | } |
891 | 1140 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-conf-reg.h b/drivers/media/video/cx231xx/cx231xx-conf-reg.h index 31a8759f6e5..25593f212ab 100644 --- a/drivers/media/video/cx231xx/cx231xx-conf-reg.h +++ b/drivers/media/video/cx231xx/cx231xx-conf-reg.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define CIR_CAR_REG 0x38 | 39 | #define CIR_CAR_REG 0x38 |
40 | #define CIR_OT_CFG1 0x40 | 40 | #define CIR_OT_CFG1 0x40 |
41 | #define CIR_OT_CFG2 0x44 | 41 | #define CIR_OT_CFG2 0x44 |
42 | #define GBULK_BIT_EN 0x68 | ||
42 | #define PWR_CTL_EN 0x74 | 43 | #define PWR_CTL_EN 0x74 |
43 | 44 | ||
44 | /* Polaris Endpoints capture mask for register EP_MODE_SET */ | 45 | /* Polaris Endpoints capture mask for register EP_MODE_SET */ |
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c index 912a4d74020..4af46fca9b0 100644 --- a/drivers/media/video/cx231xx/cx231xx-core.c +++ b/drivers/media/video/cx231xx/cx231xx-core.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <media/v4l2-common.h> | 29 | #include <media/v4l2-common.h> |
30 | #include <media/tuner.h> | ||
30 | 31 | ||
31 | #include "cx231xx.h" | 32 | #include "cx231xx.h" |
32 | #include "cx231xx-reg.h" | 33 | #include "cx231xx-reg.h" |
@@ -46,11 +47,6 @@ static unsigned int reg_debug; | |||
46 | module_param(reg_debug, int, 0644); | 47 | module_param(reg_debug, int, 0644); |
47 | MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); | 48 | MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); |
48 | 49 | ||
49 | #define cx231xx_regdbg(fmt, arg...) do {\ | ||
50 | if (reg_debug) \ | ||
51 | printk(KERN_INFO "%s %s :"fmt, \ | ||
52 | dev->name, __func__ , ##arg); } while (0) | ||
53 | |||
54 | static int alt = CX231XX_PINOUT; | 50 | static int alt = CX231XX_PINOUT; |
55 | module_param(alt, int, 0644); | 51 | module_param(alt, int, 0644); |
56 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | 52 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); |
@@ -64,7 +60,7 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | |||
64 | * Device control list functions * | 60 | * Device control list functions * |
65 | ******************************************************************/ | 61 | ******************************************************************/ |
66 | 62 | ||
67 | static LIST_HEAD(cx231xx_devlist); | 63 | LIST_HEAD(cx231xx_devlist); |
68 | static DEFINE_MUTEX(cx231xx_devlist_mutex); | 64 | static DEFINE_MUTEX(cx231xx_devlist_mutex); |
69 | 65 | ||
70 | /* | 66 | /* |
@@ -74,33 +70,39 @@ static DEFINE_MUTEX(cx231xx_devlist_mutex); | |||
74 | */ | 70 | */ |
75 | void cx231xx_remove_from_devlist(struct cx231xx *dev) | 71 | void cx231xx_remove_from_devlist(struct cx231xx *dev) |
76 | { | 72 | { |
77 | mutex_lock(&cx231xx_devlist_mutex); | 73 | if (dev == NULL) |
78 | list_del(&dev->devlist); | 74 | return; |
79 | mutex_unlock(&cx231xx_devlist_mutex); | 75 | if (dev->udev == NULL) |
76 | return; | ||
77 | |||
78 | if (atomic_read(&dev->devlist_count) > 0) { | ||
79 | mutex_lock(&cx231xx_devlist_mutex); | ||
80 | list_del(&dev->devlist); | ||
81 | atomic_dec(&dev->devlist_count); | ||
82 | mutex_unlock(&cx231xx_devlist_mutex); | ||
83 | } | ||
80 | }; | 84 | }; |
81 | 85 | ||
82 | void cx231xx_add_into_devlist(struct cx231xx *dev) | 86 | void cx231xx_add_into_devlist(struct cx231xx *dev) |
83 | { | 87 | { |
84 | mutex_lock(&cx231xx_devlist_mutex); | 88 | mutex_lock(&cx231xx_devlist_mutex); |
85 | list_add_tail(&dev->devlist, &cx231xx_devlist); | 89 | list_add_tail(&dev->devlist, &cx231xx_devlist); |
90 | atomic_inc(&dev->devlist_count); | ||
86 | mutex_unlock(&cx231xx_devlist_mutex); | 91 | mutex_unlock(&cx231xx_devlist_mutex); |
87 | }; | 92 | }; |
88 | 93 | ||
89 | static LIST_HEAD(cx231xx_extension_devlist); | 94 | static LIST_HEAD(cx231xx_extension_devlist); |
90 | static DEFINE_MUTEX(cx231xx_extension_devlist_lock); | ||
91 | 95 | ||
92 | int cx231xx_register_extension(struct cx231xx_ops *ops) | 96 | int cx231xx_register_extension(struct cx231xx_ops *ops) |
93 | { | 97 | { |
94 | struct cx231xx *dev = NULL; | 98 | struct cx231xx *dev = NULL; |
95 | 99 | ||
96 | mutex_lock(&cx231xx_devlist_mutex); | 100 | mutex_lock(&cx231xx_devlist_mutex); |
97 | mutex_lock(&cx231xx_extension_devlist_lock); | ||
98 | list_add_tail(&ops->next, &cx231xx_extension_devlist); | 101 | list_add_tail(&ops->next, &cx231xx_extension_devlist); |
99 | list_for_each_entry(dev, &cx231xx_devlist, devlist) | 102 | list_for_each_entry(dev, &cx231xx_devlist, devlist) |
100 | ops->init(dev); | 103 | ops->init(dev); |
101 | 104 | ||
102 | printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name); | 105 | printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name); |
103 | mutex_unlock(&cx231xx_extension_devlist_lock); | ||
104 | mutex_unlock(&cx231xx_devlist_mutex); | 106 | mutex_unlock(&cx231xx_devlist_mutex); |
105 | return 0; | 107 | return 0; |
106 | } | 108 | } |
@@ -114,10 +116,9 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops) | |||
114 | list_for_each_entry(dev, &cx231xx_devlist, devlist) | 116 | list_for_each_entry(dev, &cx231xx_devlist, devlist) |
115 | ops->fini(dev); | 117 | ops->fini(dev); |
116 | 118 | ||
117 | mutex_lock(&cx231xx_extension_devlist_lock); | 119 | |
118 | printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name); | 120 | printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name); |
119 | list_del(&ops->next); | 121 | list_del(&ops->next); |
120 | mutex_unlock(&cx231xx_extension_devlist_lock); | ||
121 | mutex_unlock(&cx231xx_devlist_mutex); | 122 | mutex_unlock(&cx231xx_devlist_mutex); |
122 | } | 123 | } |
123 | EXPORT_SYMBOL(cx231xx_unregister_extension); | 124 | EXPORT_SYMBOL(cx231xx_unregister_extension); |
@@ -126,28 +127,28 @@ void cx231xx_init_extension(struct cx231xx *dev) | |||
126 | { | 127 | { |
127 | struct cx231xx_ops *ops = NULL; | 128 | struct cx231xx_ops *ops = NULL; |
128 | 129 | ||
129 | mutex_lock(&cx231xx_extension_devlist_lock); | 130 | mutex_lock(&cx231xx_devlist_mutex); |
130 | if (!list_empty(&cx231xx_extension_devlist)) { | 131 | if (!list_empty(&cx231xx_extension_devlist)) { |
131 | list_for_each_entry(ops, &cx231xx_extension_devlist, next) { | 132 | list_for_each_entry(ops, &cx231xx_extension_devlist, next) { |
132 | if (ops->init) | 133 | if (ops->init) |
133 | ops->init(dev); | 134 | ops->init(dev); |
134 | } | 135 | } |
135 | } | 136 | } |
136 | mutex_unlock(&cx231xx_extension_devlist_lock); | 137 | mutex_unlock(&cx231xx_devlist_mutex); |
137 | } | 138 | } |
138 | 139 | ||
139 | void cx231xx_close_extension(struct cx231xx *dev) | 140 | void cx231xx_close_extension(struct cx231xx *dev) |
140 | { | 141 | { |
141 | struct cx231xx_ops *ops = NULL; | 142 | struct cx231xx_ops *ops = NULL; |
142 | 143 | ||
143 | mutex_lock(&cx231xx_extension_devlist_lock); | 144 | mutex_lock(&cx231xx_devlist_mutex); |
144 | if (!list_empty(&cx231xx_extension_devlist)) { | 145 | if (!list_empty(&cx231xx_extension_devlist)) { |
145 | list_for_each_entry(ops, &cx231xx_extension_devlist, next) { | 146 | list_for_each_entry(ops, &cx231xx_extension_devlist, next) { |
146 | if (ops->fini) | 147 | if (ops->fini) |
147 | ops->fini(dev); | 148 | ops->fini(dev); |
148 | } | 149 | } |
149 | } | 150 | } |
150 | mutex_unlock(&cx231xx_extension_devlist_lock); | 151 | mutex_unlock(&cx231xx_devlist_mutex); |
151 | } | 152 | } |
152 | 153 | ||
153 | /**************************************************************** | 154 | /**************************************************************** |
@@ -234,6 +235,66 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, | |||
234 | EXPORT_SYMBOL_GPL(cx231xx_send_usb_command); | 235 | EXPORT_SYMBOL_GPL(cx231xx_send_usb_command); |
235 | 236 | ||
236 | /* | 237 | /* |
238 | * Sends/Receives URB control messages, assuring to use a kalloced buffer | ||
239 | * for all operations (dev->urb_buf), to avoid using stacked buffers, as | ||
240 | * they aren't safe for usage with USB, due to DMA restrictions. | ||
241 | * Also implements the debug code for control URB's. | ||
242 | */ | ||
243 | static int __usb_control_msg(struct cx231xx *dev, unsigned int pipe, | ||
244 | __u8 request, __u8 requesttype, __u16 value, __u16 index, | ||
245 | void *data, __u16 size, int timeout) | ||
246 | { | ||
247 | int rc, i; | ||
248 | |||
249 | if (reg_debug) { | ||
250 | printk(KERN_DEBUG "%s: (pipe 0x%08x): " | ||
251 | "%s: %02x %02x %02x %02x %02x %02x %02x %02x ", | ||
252 | dev->name, | ||
253 | pipe, | ||
254 | (requesttype & USB_DIR_IN) ? "IN" : "OUT", | ||
255 | requesttype, | ||
256 | request, | ||
257 | value & 0xff, value >> 8, | ||
258 | index & 0xff, index >> 8, | ||
259 | size & 0xff, size >> 8); | ||
260 | if (!(requesttype & USB_DIR_IN)) { | ||
261 | printk(KERN_CONT ">>>"); | ||
262 | for (i = 0; i < size; i++) | ||
263 | printk(KERN_CONT " %02x", | ||
264 | ((unsigned char *)data)[i]); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /* Do the real call to usb_control_msg */ | ||
269 | mutex_lock(&dev->ctrl_urb_lock); | ||
270 | if (!(requesttype & USB_DIR_IN) && size) | ||
271 | memcpy(dev->urb_buf, data, size); | ||
272 | rc = usb_control_msg(dev->udev, pipe, request, requesttype, value, | ||
273 | index, dev->urb_buf, size, timeout); | ||
274 | if ((requesttype & USB_DIR_IN) && size) | ||
275 | memcpy(data, dev->urb_buf, size); | ||
276 | mutex_unlock(&dev->ctrl_urb_lock); | ||
277 | |||
278 | if (reg_debug) { | ||
279 | if (unlikely(rc < 0)) { | ||
280 | printk(KERN_CONT "FAILED!\n"); | ||
281 | return rc; | ||
282 | } | ||
283 | |||
284 | if ((requesttype & USB_DIR_IN)) { | ||
285 | printk(KERN_CONT "<<<"); | ||
286 | for (i = 0; i < size; i++) | ||
287 | printk(KERN_CONT " %02x", | ||
288 | ((unsigned char *)data)[i]); | ||
289 | } | ||
290 | printk(KERN_CONT "\n"); | ||
291 | } | ||
292 | |||
293 | return rc; | ||
294 | } | ||
295 | |||
296 | |||
297 | /* | ||
237 | * cx231xx_read_ctrl_reg() | 298 | * cx231xx_read_ctrl_reg() |
238 | * reads data from the usb device specifying bRequest and wValue | 299 | * reads data from the usb device specifying bRequest and wValue |
239 | */ | 300 | */ |
@@ -270,39 +331,9 @@ int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, | |||
270 | if (val == 0xFF) | 331 | if (val == 0xFF) |
271 | return -EINVAL; | 332 | return -EINVAL; |
272 | 333 | ||
273 | if (reg_debug) { | 334 | ret = __usb_control_msg(dev, pipe, req, |
274 | cx231xx_isocdbg("(pipe 0x%08x): " | ||
275 | "IN: %02x %02x %02x %02x %02x %02x %02x %02x ", | ||
276 | pipe, | ||
277 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
278 | req, 0, val, | ||
279 | reg & 0xff, reg >> 8, len & 0xff, len >> 8); | ||
280 | } | ||
281 | |||
282 | mutex_lock(&dev->ctrl_urb_lock); | ||
283 | ret = usb_control_msg(dev->udev, pipe, req, | ||
284 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 335 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
285 | val, reg, dev->urb_buf, len, HZ); | 336 | val, reg, buf, len, HZ); |
286 | if (ret < 0) { | ||
287 | cx231xx_isocdbg(" failed!\n"); | ||
288 | /* mutex_unlock(&dev->ctrl_urb_lock); */ | ||
289 | return ret; | ||
290 | } | ||
291 | |||
292 | if (len) | ||
293 | memcpy(buf, dev->urb_buf, len); | ||
294 | |||
295 | mutex_unlock(&dev->ctrl_urb_lock); | ||
296 | |||
297 | if (reg_debug) { | ||
298 | int byte; | ||
299 | |||
300 | cx231xx_isocdbg("<<<"); | ||
301 | for (byte = 0; byte < len; byte++) | ||
302 | cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]); | ||
303 | cx231xx_isocdbg("\n"); | ||
304 | } | ||
305 | |||
306 | return ret; | 337 | return ret; |
307 | } | 338 | } |
308 | 339 | ||
@@ -311,6 +342,8 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev, | |||
311 | { | 342 | { |
312 | int ret; | 343 | int ret; |
313 | int pipe = 0; | 344 | int pipe = 0; |
345 | int unsend_size = 0; | ||
346 | u8 *pdata; | ||
314 | 347 | ||
315 | if (dev->state & DEV_DISCONNECTED) | 348 | if (dev->state & DEV_DISCONNECTED) |
316 | return -ENODEV; | 349 | return -ENODEV; |
@@ -323,31 +356,54 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev, | |||
323 | else | 356 | else |
324 | pipe = usb_sndctrlpipe(dev->udev, 0); | 357 | pipe = usb_sndctrlpipe(dev->udev, 0); |
325 | 358 | ||
326 | if (reg_debug) { | 359 | /* |
327 | int byte; | 360 | * If the cx23102 read more than 4 bytes with i2c bus, |
361 | * need chop to 4 byte per request | ||
362 | */ | ||
363 | if ((ven_req->wLength > 4) && ((ven_req->bRequest == 0x4) || | ||
364 | (ven_req->bRequest == 0x5) || | ||
365 | (ven_req->bRequest == 0x6))) { | ||
366 | unsend_size = 0; | ||
367 | pdata = ven_req->pBuff; | ||
368 | |||
369 | |||
370 | unsend_size = ven_req->wLength; | ||
371 | |||
372 | /* the first package */ | ||
373 | ven_req->wValue = ven_req->wValue & 0xFFFB; | ||
374 | ven_req->wValue = (ven_req->wValue & 0xFFBD) | 0x2; | ||
375 | ret = __usb_control_msg(dev, pipe, ven_req->bRequest, | ||
376 | ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
377 | ven_req->wValue, ven_req->wIndex, pdata, | ||
378 | 0x0004, HZ); | ||
379 | unsend_size = unsend_size - 4; | ||
380 | |||
381 | /* the middle package */ | ||
382 | ven_req->wValue = (ven_req->wValue & 0xFFBD) | 0x42; | ||
383 | while (unsend_size - 4 > 0) { | ||
384 | pdata = pdata + 4; | ||
385 | ret = __usb_control_msg(dev, pipe, | ||
386 | ven_req->bRequest, | ||
387 | ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
388 | ven_req->wValue, ven_req->wIndex, pdata, | ||
389 | 0x0004, HZ); | ||
390 | unsend_size = unsend_size - 4; | ||
391 | } | ||
328 | 392 | ||
329 | cx231xx_isocdbg("(pipe 0x%08x): " | 393 | /* the last package */ |
330 | "OUT: %02x %02x %02x %04x %04x %04x >>>", | 394 | ven_req->wValue = (ven_req->wValue & 0xFFBD) | 0x40; |
331 | pipe, | 395 | pdata = pdata + 4; |
332 | ven_req-> | 396 | ret = __usb_control_msg(dev, pipe, ven_req->bRequest, |
333 | direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 397 | ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
334 | ven_req->bRequest, 0, ven_req->wValue, | 398 | ven_req->wValue, ven_req->wIndex, pdata, |
335 | ven_req->wIndex, ven_req->wLength); | 399 | unsend_size, HZ); |
336 | 400 | } else { | |
337 | for (byte = 0; byte < ven_req->wLength; byte++) | 401 | ret = __usb_control_msg(dev, pipe, ven_req->bRequest, |
338 | cx231xx_isocdbg(" %02x", | 402 | ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
339 | (unsigned char)ven_req->pBuff[byte]); | 403 | ven_req->wValue, ven_req->wIndex, |
340 | cx231xx_isocdbg("\n"); | 404 | ven_req->pBuff, ven_req->wLength, HZ); |
341 | } | 405 | } |
342 | 406 | ||
343 | mutex_lock(&dev->ctrl_urb_lock); | ||
344 | ret = usb_control_msg(dev->udev, pipe, ven_req->bRequest, | ||
345 | ven_req-> | ||
346 | direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
347 | ven_req->wValue, ven_req->wIndex, ven_req->pBuff, | ||
348 | ven_req->wLength, HZ); | ||
349 | mutex_unlock(&dev->ctrl_urb_lock); | ||
350 | |||
351 | return ret; | 407 | return ret; |
352 | } | 408 | } |
353 | 409 | ||
@@ -403,12 +459,9 @@ int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf, | |||
403 | cx231xx_isocdbg("\n"); | 459 | cx231xx_isocdbg("\n"); |
404 | } | 460 | } |
405 | 461 | ||
406 | mutex_lock(&dev->ctrl_urb_lock); | 462 | ret = __usb_control_msg(dev, pipe, req, |
407 | memcpy(dev->urb_buf, buf, len); | ||
408 | ret = usb_control_msg(dev->udev, pipe, req, | ||
409 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 463 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
410 | val, reg, dev->urb_buf, len, HZ); | 464 | val, reg, buf, len, HZ); |
411 | mutex_unlock(&dev->ctrl_urb_lock); | ||
412 | 465 | ||
413 | return ret; | 466 | return ret; |
414 | } | 467 | } |
@@ -444,6 +497,11 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) | |||
444 | dev->video_mode.alt = 0; | 497 | dev->video_mode.alt = 0; |
445 | } | 498 | } |
446 | 499 | ||
500 | if (dev->USE_ISO == 0) | ||
501 | dev->video_mode.alt = 0; | ||
502 | |||
503 | cx231xx_coredbg("dev->video_mode.alt= %d\n", dev->video_mode.alt); | ||
504 | |||
447 | /* Get the correct video interface Index */ | 505 | /* Get the correct video interface Index */ |
448 | usb_interface_index = | 506 | usb_interface_index = |
449 | dev->current_pcb_config.hs_config_info[0].interface_info. | 507 | dev->current_pcb_config.hs_config_info[0].interface_info. |
@@ -452,15 +510,13 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) | |||
452 | if (dev->video_mode.alt != prev_alt) { | 510 | if (dev->video_mode.alt != prev_alt) { |
453 | cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", | 511 | cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", |
454 | min_pkt_size, dev->video_mode.alt); | 512 | min_pkt_size, dev->video_mode.alt); |
455 | dev->video_mode.max_pkt_size = | 513 | |
456 | dev->video_mode.alt_max_pkt_size[dev->video_mode.alt]; | 514 | if (dev->video_mode.alt_max_pkt_size != NULL) |
515 | dev->video_mode.max_pkt_size = | ||
516 | dev->video_mode.alt_max_pkt_size[dev->video_mode.alt]; | ||
457 | cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", | 517 | cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", |
458 | dev->video_mode.alt, | 518 | dev->video_mode.alt, |
459 | dev->video_mode.max_pkt_size); | 519 | dev->video_mode.max_pkt_size); |
460 | cx231xx_info | ||
461 | (" setting alt %d with wMaxPktSize=%u , Interface = %d\n", | ||
462 | dev->video_mode.alt, dev->video_mode.max_pkt_size, | ||
463 | usb_interface_index); | ||
464 | errCode = | 520 | errCode = |
465 | usb_set_interface(dev->udev, usb_interface_index, | 521 | usb_set_interface(dev->udev, usb_interface_index, |
466 | dev->video_mode.alt); | 522 | dev->video_mode.alt); |
@@ -485,7 +541,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) | |||
485 | usb_interface_index = | 541 | usb_interface_index = |
486 | dev->current_pcb_config.hs_config_info[0].interface_info. | 542 | dev->current_pcb_config.hs_config_info[0].interface_info. |
487 | ts1_index + 1; | 543 | ts1_index + 1; |
488 | dev->video_mode.alt = alt; | 544 | dev->ts1_mode.alt = alt; |
489 | if (dev->ts1_mode.alt_max_pkt_size != NULL) | 545 | if (dev->ts1_mode.alt_max_pkt_size != NULL) |
490 | max_pkt_size = dev->ts1_mode.max_pkt_size = | 546 | max_pkt_size = dev->ts1_mode.max_pkt_size = |
491 | dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt]; | 547 | dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt]; |
@@ -542,12 +598,16 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) | |||
542 | cx231xx_errdev | 598 | cx231xx_errdev |
543 | ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", | 599 | ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", |
544 | usb_interface_index, alt); | 600 | usb_interface_index, alt); |
545 | return -1; | 601 | /*To workaround error number=-71 on EP0 for videograbber, |
602 | need add following codes.*/ | ||
603 | if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && | ||
604 | dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2) | ||
605 | return -1; | ||
546 | } | 606 | } |
547 | 607 | ||
548 | cx231xx_info | 608 | cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u," |
549 | (" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n", | 609 | "Interface = %d\n", alt, max_pkt_size, |
550 | alt, max_pkt_size, usb_interface_index); | 610 | usb_interface_index); |
551 | 611 | ||
552 | if (usb_interface_index > 0) { | 612 | if (usb_interface_index > 0) { |
553 | status = usb_set_interface(dev->udev, usb_interface_index, alt); | 613 | status = usb_set_interface(dev->udev, usb_interface_index, alt); |
@@ -584,8 +644,56 @@ int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio) | |||
584 | return rc; | 644 | return rc; |
585 | } | 645 | } |
586 | 646 | ||
647 | int cx231xx_demod_reset(struct cx231xx *dev) | ||
648 | { | ||
649 | |||
650 | u8 status = 0; | ||
651 | u8 value[4] = { 0, 0, 0, 0 }; | ||
652 | |||
653 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, | ||
654 | value, 4); | ||
655 | |||
656 | cx231xx_coredbg("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, | ||
657 | value[0], value[1], value[2], value[3]); | ||
658 | |||
659 | cx231xx_coredbg("Enter cx231xx_demod_reset()\n"); | ||
660 | |||
661 | value[1] = (u8) 0x3; | ||
662 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
663 | PWR_CTL_EN, value, 4); | ||
664 | msleep(10); | ||
665 | |||
666 | value[1] = (u8) 0x0; | ||
667 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
668 | PWR_CTL_EN, value, 4); | ||
669 | msleep(10); | ||
670 | |||
671 | value[1] = (u8) 0x3; | ||
672 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
673 | PWR_CTL_EN, value, 4); | ||
674 | msleep(10); | ||
675 | |||
676 | |||
677 | |||
678 | status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, | ||
679 | value, 4); | ||
680 | |||
681 | cx231xx_coredbg("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, | ||
682 | value[0], value[1], value[2], value[3]); | ||
683 | |||
684 | return status; | ||
685 | } | ||
686 | EXPORT_SYMBOL_GPL(cx231xx_demod_reset); | ||
687 | int is_fw_load(struct cx231xx *dev) | ||
688 | { | ||
689 | return cx231xx_check_fw(dev); | ||
690 | } | ||
691 | EXPORT_SYMBOL_GPL(is_fw_load); | ||
692 | |||
587 | int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) | 693 | int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) |
588 | { | 694 | { |
695 | int errCode = 0; | ||
696 | |||
589 | if (dev->mode == set_mode) | 697 | if (dev->mode == set_mode) |
590 | return 0; | 698 | return 0; |
591 | 699 | ||
@@ -600,15 +708,75 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) | |||
600 | 708 | ||
601 | dev->mode = set_mode; | 709 | dev->mode = set_mode; |
602 | 710 | ||
603 | if (dev->mode == CX231XX_DIGITAL_MODE) | 711 | if (dev->mode == CX231XX_DIGITAL_MODE)/* Set Digital power mode */ { |
604 | ;/* Set Digital power mode */ | 712 | /* set AGC mode to Digital */ |
605 | else | 713 | switch (dev->model) { |
606 | ;/* Set Analog Power mode */ | 714 | case CX231XX_BOARD_CNXT_CARRAERA: |
715 | case CX231XX_BOARD_CNXT_RDE_250: | ||
716 | case CX231XX_BOARD_CNXT_SHELBY: | ||
717 | case CX231XX_BOARD_CNXT_RDU_250: | ||
718 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); | ||
719 | break; | ||
720 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
721 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
722 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); | ||
723 | break; | ||
724 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | ||
725 | errCode = cx231xx_set_power_mode(dev, | ||
726 | POLARIS_AVMODE_DIGITAL); | ||
727 | break; | ||
728 | default: | ||
729 | break; | ||
730 | } | ||
731 | } else/* Set Analog Power mode */ { | ||
732 | /* set AGC mode to Analog */ | ||
733 | switch (dev->model) { | ||
734 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
735 | case CX231XX_BOARD_CNXT_RDE_250: | ||
736 | case CX231XX_BOARD_CNXT_SHELBY: | ||
737 | case CX231XX_BOARD_CNXT_RDU_250: | ||
738 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); | ||
739 | break; | ||
740 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
741 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
742 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | ||
743 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); | ||
744 | break; | ||
745 | default: | ||
746 | break; | ||
747 | } | ||
748 | } | ||
607 | 749 | ||
608 | return 0; | 750 | return 0; |
609 | } | 751 | } |
610 | EXPORT_SYMBOL_GPL(cx231xx_set_mode); | 752 | EXPORT_SYMBOL_GPL(cx231xx_set_mode); |
611 | 753 | ||
754 | int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) | ||
755 | { | ||
756 | int errCode = 0; | ||
757 | int actlen, ret = -ENOMEM; | ||
758 | u32 *buffer; | ||
759 | |||
760 | buffer = kzalloc(4096, GFP_KERNEL); | ||
761 | if (buffer == NULL) { | ||
762 | cx231xx_info("out of mem\n"); | ||
763 | return -ENOMEM; | ||
764 | } | ||
765 | memcpy(&buffer[0], firmware, 4096); | ||
766 | |||
767 | ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 5), | ||
768 | buffer, 4096, &actlen, 2000); | ||
769 | |||
770 | if (ret) | ||
771 | cx231xx_info("bulk message failed: %d (%d/%d)", ret, | ||
772 | size, actlen); | ||
773 | else { | ||
774 | errCode = actlen != size ? -1 : 0; | ||
775 | } | ||
776 | kfree(buffer); | ||
777 | return 0; | ||
778 | } | ||
779 | |||
612 | /***************************************************************** | 780 | /***************************************************************** |
613 | * URB Streaming functions * | 781 | * URB Streaming functions * |
614 | ******************************************************************/ | 782 | ******************************************************************/ |
@@ -616,7 +784,7 @@ EXPORT_SYMBOL_GPL(cx231xx_set_mode); | |||
616 | /* | 784 | /* |
617 | * IRQ callback, called by URB callback | 785 | * IRQ callback, called by URB callback |
618 | */ | 786 | */ |
619 | static void cx231xx_irq_callback(struct urb *urb) | 787 | static void cx231xx_isoc_irq_callback(struct urb *urb) |
620 | { | 788 | { |
621 | struct cx231xx_dmaqueue *dma_q = urb->context; | 789 | struct cx231xx_dmaqueue *dma_q = urb->context; |
622 | struct cx231xx_video_mode *vmode = | 790 | struct cx231xx_video_mode *vmode = |
@@ -655,12 +823,54 @@ static void cx231xx_irq_callback(struct urb *urb) | |||
655 | urb->status); | 823 | urb->status); |
656 | } | 824 | } |
657 | } | 825 | } |
826 | /***************************************************************** | ||
827 | * URB Streaming functions * | ||
828 | ******************************************************************/ | ||
658 | 829 | ||
659 | /* | 830 | /* |
831 | * IRQ callback, called by URB callback | ||
832 | */ | ||
833 | static void cx231xx_bulk_irq_callback(struct urb *urb) | ||
834 | { | ||
835 | struct cx231xx_dmaqueue *dma_q = urb->context; | ||
836 | struct cx231xx_video_mode *vmode = | ||
837 | container_of(dma_q, struct cx231xx_video_mode, vidq); | ||
838 | struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode); | ||
839 | int rc; | ||
840 | |||
841 | switch (urb->status) { | ||
842 | case 0: /* success */ | ||
843 | case -ETIMEDOUT: /* NAK */ | ||
844 | break; | ||
845 | case -ECONNRESET: /* kill */ | ||
846 | case -ENOENT: | ||
847 | case -ESHUTDOWN: | ||
848 | return; | ||
849 | default: /* error */ | ||
850 | cx231xx_isocdbg("urb completition error %d.\n", urb->status); | ||
851 | break; | ||
852 | } | ||
853 | |||
854 | /* Copy data from URB */ | ||
855 | spin_lock(&dev->video_mode.slock); | ||
856 | rc = dev->video_mode.bulk_ctl.bulk_copy(dev, urb); | ||
857 | spin_unlock(&dev->video_mode.slock); | ||
858 | |||
859 | /* Reset urb buffers */ | ||
860 | urb->status = 0; | ||
861 | |||
862 | urb->status = usb_submit_urb(urb, GFP_ATOMIC); | ||
863 | if (urb->status) { | ||
864 | cx231xx_isocdbg("urb resubmit failed (error=%i)\n", | ||
865 | urb->status); | ||
866 | } | ||
867 | } | ||
868 | /* | ||
660 | * Stop and Deallocate URBs | 869 | * Stop and Deallocate URBs |
661 | */ | 870 | */ |
662 | void cx231xx_uninit_isoc(struct cx231xx *dev) | 871 | void cx231xx_uninit_isoc(struct cx231xx *dev) |
663 | { | 872 | { |
873 | struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq; | ||
664 | struct urb *urb; | 874 | struct urb *urb; |
665 | int i; | 875 | int i; |
666 | 876 | ||
@@ -690,16 +900,71 @@ void cx231xx_uninit_isoc(struct cx231xx *dev) | |||
690 | 900 | ||
691 | kfree(dev->video_mode.isoc_ctl.urb); | 901 | kfree(dev->video_mode.isoc_ctl.urb); |
692 | kfree(dev->video_mode.isoc_ctl.transfer_buffer); | 902 | kfree(dev->video_mode.isoc_ctl.transfer_buffer); |
903 | kfree(dma_q->p_left_data); | ||
693 | 904 | ||
694 | dev->video_mode.isoc_ctl.urb = NULL; | 905 | dev->video_mode.isoc_ctl.urb = NULL; |
695 | dev->video_mode.isoc_ctl.transfer_buffer = NULL; | 906 | dev->video_mode.isoc_ctl.transfer_buffer = NULL; |
696 | dev->video_mode.isoc_ctl.num_bufs = 0; | 907 | dev->video_mode.isoc_ctl.num_bufs = 0; |
908 | dma_q->p_left_data = NULL; | ||
909 | |||
910 | if (dev->mode_tv == 0) | ||
911 | cx231xx_capture_start(dev, 0, Raw_Video); | ||
912 | else | ||
913 | cx231xx_capture_start(dev, 0, TS1_serial_mode); | ||
914 | |||
697 | 915 | ||
698 | cx231xx_capture_start(dev, 0, Raw_Video); | ||
699 | } | 916 | } |
700 | EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc); | 917 | EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc); |
701 | 918 | ||
702 | /* | 919 | /* |
920 | * Stop and Deallocate URBs | ||
921 | */ | ||
922 | void cx231xx_uninit_bulk(struct cx231xx *dev) | ||
923 | { | ||
924 | struct urb *urb; | ||
925 | int i; | ||
926 | |||
927 | cx231xx_isocdbg("cx231xx: called cx231xx_uninit_bulk\n"); | ||
928 | |||
929 | dev->video_mode.bulk_ctl.nfields = -1; | ||
930 | for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { | ||
931 | urb = dev->video_mode.bulk_ctl.urb[i]; | ||
932 | if (urb) { | ||
933 | if (!irqs_disabled()) | ||
934 | usb_kill_urb(urb); | ||
935 | else | ||
936 | usb_unlink_urb(urb); | ||
937 | |||
938 | if (dev->video_mode.bulk_ctl.transfer_buffer[i]) { | ||
939 | usb_free_coherent(dev->udev, | ||
940 | urb->transfer_buffer_length, | ||
941 | dev->video_mode.isoc_ctl. | ||
942 | transfer_buffer[i], | ||
943 | urb->transfer_dma); | ||
944 | } | ||
945 | usb_free_urb(urb); | ||
946 | dev->video_mode.bulk_ctl.urb[i] = NULL; | ||
947 | } | ||
948 | dev->video_mode.bulk_ctl.transfer_buffer[i] = NULL; | ||
949 | } | ||
950 | |||
951 | kfree(dev->video_mode.bulk_ctl.urb); | ||
952 | kfree(dev->video_mode.bulk_ctl.transfer_buffer); | ||
953 | |||
954 | dev->video_mode.bulk_ctl.urb = NULL; | ||
955 | dev->video_mode.bulk_ctl.transfer_buffer = NULL; | ||
956 | dev->video_mode.bulk_ctl.num_bufs = 0; | ||
957 | |||
958 | if (dev->mode_tv == 0) | ||
959 | cx231xx_capture_start(dev, 0, Raw_Video); | ||
960 | else | ||
961 | cx231xx_capture_start(dev, 0, TS1_serial_mode); | ||
962 | |||
963 | |||
964 | } | ||
965 | EXPORT_SYMBOL_GPL(cx231xx_uninit_bulk); | ||
966 | |||
967 | /* | ||
703 | * Allocate URBs and start IRQ | 968 | * Allocate URBs and start IRQ |
704 | */ | 969 | */ |
705 | int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | 970 | int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, |
@@ -713,15 +978,16 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | |||
713 | int j, k; | 978 | int j, k; |
714 | int rc; | 979 | int rc; |
715 | 980 | ||
716 | cx231xx_isocdbg("cx231xx: called cx231xx_prepare_isoc\n"); | 981 | /* De-allocates all pending stuff */ |
982 | cx231xx_uninit_isoc(dev); | ||
717 | 983 | ||
718 | dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; | 984 | dma_q->p_left_data = kzalloc(4096, GFP_KERNEL); |
985 | if (dma_q->p_left_data == NULL) { | ||
986 | cx231xx_info("out of mem\n"); | ||
987 | return -ENOMEM; | ||
988 | } | ||
719 | 989 | ||
720 | cx231xx_info("Setting Video mux to %d\n", dev->video_input); | ||
721 | video_mux(dev, dev->video_input); | ||
722 | 990 | ||
723 | /* De-allocates all pending stuff */ | ||
724 | cx231xx_uninit_isoc(dev); | ||
725 | 991 | ||
726 | dev->video_mode.isoc_ctl.isoc_copy = isoc_copy; | 992 | dev->video_mode.isoc_ctl.isoc_copy = isoc_copy; |
727 | dev->video_mode.isoc_ctl.num_bufs = num_bufs; | 993 | dev->video_mode.isoc_ctl.num_bufs = num_bufs; |
@@ -733,6 +999,14 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | |||
733 | dma_q->lines_per_field = dev->height / 2; | 999 | dma_q->lines_per_field = dev->height / 2; |
734 | dma_q->bytes_left_in_line = dev->width << 1; | 1000 | dma_q->bytes_left_in_line = dev->width << 1; |
735 | dma_q->lines_completed = 0; | 1001 | dma_q->lines_completed = 0; |
1002 | dma_q->mpeg_buffer_done = 0; | ||
1003 | dma_q->left_data_count = 0; | ||
1004 | dma_q->mpeg_buffer_completed = 0; | ||
1005 | dma_q->add_ps_package_head = CX231XX_NEED_ADD_PS_PACKAGE_HEAD; | ||
1006 | dma_q->ps_head[0] = 0x00; | ||
1007 | dma_q->ps_head[1] = 0x00; | ||
1008 | dma_q->ps_head[2] = 0x01; | ||
1009 | dma_q->ps_head[3] = 0xBA; | ||
736 | for (i = 0; i < 8; i++) | 1010 | for (i = 0; i < 8; i++) |
737 | dma_q->partial_buf[i] = 0; | 1011 | dma_q->partial_buf[i] = 0; |
738 | 1012 | ||
@@ -756,6 +1030,12 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | |||
756 | 1030 | ||
757 | sb_size = max_packets * dev->video_mode.isoc_ctl.max_pkt_size; | 1031 | sb_size = max_packets * dev->video_mode.isoc_ctl.max_pkt_size; |
758 | 1032 | ||
1033 | if (dev->mode_tv == 1) | ||
1034 | dev->video_mode.end_point_addr = 0x81; | ||
1035 | else | ||
1036 | dev->video_mode.end_point_addr = 0x84; | ||
1037 | |||
1038 | |||
759 | /* allocate urbs and transfer buffers */ | 1039 | /* allocate urbs and transfer buffers */ |
760 | for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { | 1040 | for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { |
761 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | 1041 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); |
@@ -784,7 +1064,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | |||
784 | 1064 | ||
785 | usb_fill_int_urb(urb, dev->udev, pipe, | 1065 | usb_fill_int_urb(urb, dev->udev, pipe, |
786 | dev->video_mode.isoc_ctl.transfer_buffer[i], | 1066 | dev->video_mode.isoc_ctl.transfer_buffer[i], |
787 | sb_size, cx231xx_irq_callback, dma_q, 1); | 1067 | sb_size, cx231xx_isoc_irq_callback, dma_q, 1); |
788 | 1068 | ||
789 | urb->number_of_packets = max_packets; | 1069 | urb->number_of_packets = max_packets; |
790 | urb->transfer_flags = URB_ISO_ASAP; | 1070 | urb->transfer_flags = URB_ISO_ASAP; |
@@ -812,12 +1092,176 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | |||
812 | } | 1092 | } |
813 | } | 1093 | } |
814 | 1094 | ||
815 | cx231xx_capture_start(dev, 1, Raw_Video); | 1095 | if (dev->mode_tv == 0) |
1096 | cx231xx_capture_start(dev, 1, Raw_Video); | ||
1097 | else | ||
1098 | cx231xx_capture_start(dev, 1, TS1_serial_mode); | ||
816 | 1099 | ||
817 | return 0; | 1100 | return 0; |
818 | } | 1101 | } |
819 | EXPORT_SYMBOL_GPL(cx231xx_init_isoc); | 1102 | EXPORT_SYMBOL_GPL(cx231xx_init_isoc); |
820 | 1103 | ||
1104 | /* | ||
1105 | * Allocate URBs and start IRQ | ||
1106 | */ | ||
1107 | int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, | ||
1108 | int num_bufs, int max_pkt_size, | ||
1109 | int (*bulk_copy) (struct cx231xx *dev, struct urb *urb)) | ||
1110 | { | ||
1111 | struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq; | ||
1112 | int i; | ||
1113 | int sb_size, pipe; | ||
1114 | struct urb *urb; | ||
1115 | int rc; | ||
1116 | |||
1117 | dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; | ||
1118 | |||
1119 | cx231xx_coredbg("Setting Video mux to %d\n", dev->video_input); | ||
1120 | |||
1121 | video_mux(dev, dev->video_input); | ||
1122 | |||
1123 | /* De-allocates all pending stuff */ | ||
1124 | cx231xx_uninit_bulk(dev); | ||
1125 | |||
1126 | dev->video_mode.bulk_ctl.bulk_copy = bulk_copy; | ||
1127 | dev->video_mode.bulk_ctl.num_bufs = num_bufs; | ||
1128 | dma_q->pos = 0; | ||
1129 | dma_q->is_partial_line = 0; | ||
1130 | dma_q->last_sav = 0; | ||
1131 | dma_q->current_field = -1; | ||
1132 | dma_q->field1_done = 0; | ||
1133 | dma_q->lines_per_field = dev->height / 2; | ||
1134 | dma_q->bytes_left_in_line = dev->width << 1; | ||
1135 | dma_q->lines_completed = 0; | ||
1136 | dma_q->mpeg_buffer_done = 0; | ||
1137 | dma_q->left_data_count = 0; | ||
1138 | dma_q->mpeg_buffer_completed = 0; | ||
1139 | dma_q->ps_head[0] = 0x00; | ||
1140 | dma_q->ps_head[1] = 0x00; | ||
1141 | dma_q->ps_head[2] = 0x01; | ||
1142 | dma_q->ps_head[3] = 0xBA; | ||
1143 | for (i = 0; i < 8; i++) | ||
1144 | dma_q->partial_buf[i] = 0; | ||
1145 | |||
1146 | dev->video_mode.bulk_ctl.urb = | ||
1147 | kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); | ||
1148 | if (!dev->video_mode.bulk_ctl.urb) { | ||
1149 | cx231xx_errdev("cannot alloc memory for usb buffers\n"); | ||
1150 | return -ENOMEM; | ||
1151 | } | ||
1152 | |||
1153 | dev->video_mode.bulk_ctl.transfer_buffer = | ||
1154 | kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); | ||
1155 | if (!dev->video_mode.bulk_ctl.transfer_buffer) { | ||
1156 | cx231xx_errdev("cannot allocate memory for usbtransfer\n"); | ||
1157 | kfree(dev->video_mode.bulk_ctl.urb); | ||
1158 | return -ENOMEM; | ||
1159 | } | ||
1160 | |||
1161 | dev->video_mode.bulk_ctl.max_pkt_size = max_pkt_size; | ||
1162 | dev->video_mode.bulk_ctl.buf = NULL; | ||
1163 | |||
1164 | sb_size = max_packets * dev->video_mode.bulk_ctl.max_pkt_size; | ||
1165 | |||
1166 | if (dev->mode_tv == 1) | ||
1167 | dev->video_mode.end_point_addr = 0x81; | ||
1168 | else | ||
1169 | dev->video_mode.end_point_addr = 0x84; | ||
1170 | |||
1171 | |||
1172 | /* allocate urbs and transfer buffers */ | ||
1173 | for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { | ||
1174 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
1175 | if (!urb) { | ||
1176 | cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i); | ||
1177 | cx231xx_uninit_bulk(dev); | ||
1178 | return -ENOMEM; | ||
1179 | } | ||
1180 | dev->video_mode.bulk_ctl.urb[i] = urb; | ||
1181 | urb->transfer_flags = 0; | ||
1182 | |||
1183 | dev->video_mode.bulk_ctl.transfer_buffer[i] = | ||
1184 | usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, | ||
1185 | &urb->transfer_dma); | ||
1186 | if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) { | ||
1187 | cx231xx_err("unable to allocate %i bytes for transfer" | ||
1188 | " buffer %i%s\n", | ||
1189 | sb_size, i, | ||
1190 | in_interrupt() ? " while in int" : ""); | ||
1191 | cx231xx_uninit_bulk(dev); | ||
1192 | return -ENOMEM; | ||
1193 | } | ||
1194 | memset(dev->video_mode.bulk_ctl.transfer_buffer[i], 0, sb_size); | ||
1195 | |||
1196 | pipe = usb_rcvbulkpipe(dev->udev, | ||
1197 | dev->video_mode.end_point_addr); | ||
1198 | usb_fill_bulk_urb(urb, dev->udev, pipe, | ||
1199 | dev->video_mode.bulk_ctl.transfer_buffer[i], | ||
1200 | sb_size, cx231xx_bulk_irq_callback, dma_q); | ||
1201 | } | ||
1202 | |||
1203 | init_waitqueue_head(&dma_q->wq); | ||
1204 | |||
1205 | /* submit urbs and enables IRQ */ | ||
1206 | for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { | ||
1207 | rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i], | ||
1208 | GFP_ATOMIC); | ||
1209 | if (rc) { | ||
1210 | cx231xx_err("submit of urb %i failed (error=%i)\n", i, | ||
1211 | rc); | ||
1212 | cx231xx_uninit_bulk(dev); | ||
1213 | return rc; | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | if (dev->mode_tv == 0) | ||
1218 | cx231xx_capture_start(dev, 1, Raw_Video); | ||
1219 | else | ||
1220 | cx231xx_capture_start(dev, 1, TS1_serial_mode); | ||
1221 | |||
1222 | return 0; | ||
1223 | } | ||
1224 | EXPORT_SYMBOL_GPL(cx231xx_init_bulk); | ||
1225 | void cx231xx_stop_TS1(struct cx231xx *dev) | ||
1226 | { | ||
1227 | int status = 0; | ||
1228 | u8 val[4] = { 0, 0, 0, 0 }; | ||
1229 | |||
1230 | val[0] = 0x00; | ||
1231 | val[1] = 0x03; | ||
1232 | val[2] = 0x00; | ||
1233 | val[3] = 0x00; | ||
1234 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
1235 | TS_MODE_REG, val, 4); | ||
1236 | |||
1237 | val[0] = 0x00; | ||
1238 | val[1] = 0x70; | ||
1239 | val[2] = 0x04; | ||
1240 | val[3] = 0x00; | ||
1241 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
1242 | TS1_CFG_REG, val, 4); | ||
1243 | } | ||
1244 | /* EXPORT_SYMBOL_GPL(cx231xx_stop_TS1); */ | ||
1245 | void cx231xx_start_TS1(struct cx231xx *dev) | ||
1246 | { | ||
1247 | int status = 0; | ||
1248 | u8 val[4] = { 0, 0, 0, 0 }; | ||
1249 | |||
1250 | val[0] = 0x03; | ||
1251 | val[1] = 0x03; | ||
1252 | val[2] = 0x00; | ||
1253 | val[3] = 0x00; | ||
1254 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
1255 | TS_MODE_REG, val, 4); | ||
1256 | |||
1257 | val[0] = 0x04; | ||
1258 | val[1] = 0xA3; | ||
1259 | val[2] = 0x3B; | ||
1260 | val[3] = 0x00; | ||
1261 | status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, | ||
1262 | TS1_CFG_REG, val, 4); | ||
1263 | } | ||
1264 | /* EXPORT_SYMBOL_GPL(cx231xx_start_TS1); */ | ||
821 | /***************************************************************** | 1265 | /***************************************************************** |
822 | * Device Init/UnInit functions * | 1266 | * Device Init/UnInit functions * |
823 | ******************************************************************/ | 1267 | ******************************************************************/ |
@@ -830,14 +1274,14 @@ int cx231xx_dev_init(struct cx231xx *dev) | |||
830 | /* External Master 1 Bus */ | 1274 | /* External Master 1 Bus */ |
831 | dev->i2c_bus[0].nr = 0; | 1275 | dev->i2c_bus[0].nr = 0; |
832 | dev->i2c_bus[0].dev = dev; | 1276 | dev->i2c_bus[0].dev = dev; |
833 | dev->i2c_bus[0].i2c_period = I2C_SPEED_1M; /* 1MHz */ | 1277 | dev->i2c_bus[0].i2c_period = I2C_SPEED_100K; /* 100 KHz */ |
834 | dev->i2c_bus[0].i2c_nostop = 0; | 1278 | dev->i2c_bus[0].i2c_nostop = 0; |
835 | dev->i2c_bus[0].i2c_reserve = 0; | 1279 | dev->i2c_bus[0].i2c_reserve = 0; |
836 | 1280 | ||
837 | /* External Master 2 Bus */ | 1281 | /* External Master 2 Bus */ |
838 | dev->i2c_bus[1].nr = 1; | 1282 | dev->i2c_bus[1].nr = 1; |
839 | dev->i2c_bus[1].dev = dev; | 1283 | dev->i2c_bus[1].dev = dev; |
840 | dev->i2c_bus[1].i2c_period = I2C_SPEED_1M; /* 1MHz */ | 1284 | dev->i2c_bus[1].i2c_period = I2C_SPEED_100K; /* 100 KHz */ |
841 | dev->i2c_bus[1].i2c_nostop = 0; | 1285 | dev->i2c_bus[1].i2c_nostop = 0; |
842 | dev->i2c_bus[1].i2c_reserve = 0; | 1286 | dev->i2c_bus[1].i2c_reserve = 0; |
843 | 1287 | ||
@@ -856,14 +1300,34 @@ int cx231xx_dev_init(struct cx231xx *dev) | |||
856 | /* init hardware */ | 1300 | /* init hardware */ |
857 | /* Note : with out calling set power mode function, | 1301 | /* Note : with out calling set power mode function, |
858 | afe can not be set up correctly */ | 1302 | afe can not be set up correctly */ |
859 | errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); | 1303 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || |
860 | if (errCode < 0) { | 1304 | dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) { |
861 | cx231xx_errdev | 1305 | errCode = cx231xx_set_power_mode(dev, |
862 | ("%s: Failed to set Power - errCode [%d]!\n", | 1306 | POLARIS_AVMODE_ENXTERNAL_AV); |
863 | __func__, errCode); | 1307 | if (errCode < 0) { |
864 | return errCode; | 1308 | cx231xx_errdev |
1309 | ("%s: Failed to set Power - errCode [%d]!\n", | ||
1310 | __func__, errCode); | ||
1311 | return errCode; | ||
1312 | } | ||
1313 | } else { | ||
1314 | errCode = cx231xx_set_power_mode(dev, | ||
1315 | POLARIS_AVMODE_ANALOGT_TV); | ||
1316 | if (errCode < 0) { | ||
1317 | cx231xx_errdev | ||
1318 | ("%s: Failed to set Power - errCode [%d]!\n", | ||
1319 | __func__, errCode); | ||
1320 | return errCode; | ||
1321 | } | ||
865 | } | 1322 | } |
866 | 1323 | ||
1324 | /* reset the Tuner */ | ||
1325 | if ((dev->model == CX231XX_BOARD_CNXT_CARRAERA) || | ||
1326 | (dev->model == CX231XX_BOARD_CNXT_RDE_250) || | ||
1327 | (dev->model == CX231XX_BOARD_CNXT_SHELBY) || | ||
1328 | (dev->model == CX231XX_BOARD_CNXT_RDU_250)) | ||
1329 | cx231xx_gpio_set(dev, dev->board.tuner_gpio); | ||
1330 | |||
867 | /* initialize Colibri block */ | 1331 | /* initialize Colibri block */ |
868 | errCode = cx231xx_afe_init_super_block(dev, 0x23c); | 1332 | errCode = cx231xx_afe_init_super_block(dev, 0x23c); |
869 | if (errCode < 0) { | 1333 | if (errCode < 0) { |
@@ -907,7 +1371,21 @@ int cx231xx_dev_init(struct cx231xx *dev) | |||
907 | } | 1371 | } |
908 | 1372 | ||
909 | /* set AGC mode to Analog */ | 1373 | /* set AGC mode to Analog */ |
1374 | switch (dev->model) { | ||
1375 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
1376 | case CX231XX_BOARD_CNXT_RDE_250: | ||
1377 | case CX231XX_BOARD_CNXT_SHELBY: | ||
1378 | case CX231XX_BOARD_CNXT_RDU_250: | ||
910 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); | 1379 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); |
1380 | break; | ||
1381 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
1382 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
1383 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | ||
1384 | errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); | ||
1385 | break; | ||
1386 | default: | ||
1387 | break; | ||
1388 | } | ||
911 | if (errCode < 0) { | 1389 | if (errCode < 0) { |
912 | cx231xx_errdev | 1390 | cx231xx_errdev |
913 | ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", | 1391 | ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", |
@@ -923,7 +1401,7 @@ int cx231xx_dev_init(struct cx231xx *dev) | |||
923 | cx231xx_set_alt_setting(dev, INDEX_TS1, 0); | 1401 | cx231xx_set_alt_setting(dev, INDEX_TS1, 0); |
924 | 1402 | ||
925 | /* set the I2C master port to 3 on channel 1 */ | 1403 | /* set the I2C master port to 3 on channel 1 */ |
926 | errCode = cx231xx_enable_i2c_for_tuner(dev, I2C_3); | 1404 | errCode = cx231xx_enable_i2c_port_3(dev, true); |
927 | 1405 | ||
928 | return errCode; | 1406 | return errCode; |
929 | } | 1407 | } |
@@ -941,7 +1419,7 @@ EXPORT_SYMBOL_GPL(cx231xx_dev_uninit); | |||
941 | /***************************************************************** | 1419 | /***************************************************************** |
942 | * G P I O related functions * | 1420 | * G P I O related functions * |
943 | ******************************************************************/ | 1421 | ******************************************************************/ |
944 | int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val, | 1422 | int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, |
945 | u8 len, u8 request, u8 direction) | 1423 | u8 len, u8 request, u8 direction) |
946 | { | 1424 | { |
947 | int status = 0; | 1425 | int status = 0; |
@@ -1026,6 +1504,91 @@ int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode) | |||
1026 | /***************************************************************** | 1504 | /***************************************************************** |
1027 | * I 2 C Internal C O N T R O L functions * | 1505 | * I 2 C Internal C O N T R O L functions * |
1028 | *****************************************************************/ | 1506 | *****************************************************************/ |
1507 | int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, | ||
1508 | u8 saddr_len, u32 *data, u8 data_len, int master) | ||
1509 | { | ||
1510 | int status = 0; | ||
1511 | struct cx231xx_i2c_xfer_data req_data; | ||
1512 | u8 value[64] = "0"; | ||
1513 | |||
1514 | if (saddr_len == 0) | ||
1515 | saddr = 0; | ||
1516 | else if (saddr_len == 0) | ||
1517 | saddr &= 0xff; | ||
1518 | |||
1519 | /* prepare xfer_data struct */ | ||
1520 | req_data.dev_addr = dev_addr >> 1; | ||
1521 | req_data.direction = I2C_M_RD; | ||
1522 | req_data.saddr_len = saddr_len; | ||
1523 | req_data.saddr_dat = saddr; | ||
1524 | req_data.buf_size = data_len; | ||
1525 | req_data.p_buffer = (u8 *) value; | ||
1526 | |||
1527 | /* usb send command */ | ||
1528 | if (master == 0) | ||
1529 | status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], | ||
1530 | &req_data); | ||
1531 | else if (master == 1) | ||
1532 | status = dev->cx231xx_send_usb_command(&dev->i2c_bus[1], | ||
1533 | &req_data); | ||
1534 | else if (master == 2) | ||
1535 | status = dev->cx231xx_send_usb_command(&dev->i2c_bus[2], | ||
1536 | &req_data); | ||
1537 | |||
1538 | if (status >= 0) { | ||
1539 | /* Copy the data read back to main buffer */ | ||
1540 | if (data_len == 1) | ||
1541 | *data = value[0]; | ||
1542 | else if (data_len == 4) | ||
1543 | *data = | ||
1544 | value[0] | value[1] << 8 | value[2] << 16 | value[3] | ||
1545 | << 24; | ||
1546 | else if (data_len > 4) | ||
1547 | *data = value[saddr]; | ||
1548 | } | ||
1549 | |||
1550 | return status; | ||
1551 | } | ||
1552 | |||
1553 | int cx231xx_write_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, | ||
1554 | u8 saddr_len, u32 data, u8 data_len, int master) | ||
1555 | { | ||
1556 | int status = 0; | ||
1557 | u8 value[4] = { 0, 0, 0, 0 }; | ||
1558 | struct cx231xx_i2c_xfer_data req_data; | ||
1559 | |||
1560 | value[0] = (u8) data; | ||
1561 | value[1] = (u8) (data >> 8); | ||
1562 | value[2] = (u8) (data >> 16); | ||
1563 | value[3] = (u8) (data >> 24); | ||
1564 | |||
1565 | if (saddr_len == 0) | ||
1566 | saddr = 0; | ||
1567 | else if (saddr_len == 0) | ||
1568 | saddr &= 0xff; | ||
1569 | |||
1570 | /* prepare xfer_data struct */ | ||
1571 | req_data.dev_addr = dev_addr >> 1; | ||
1572 | req_data.direction = 0; | ||
1573 | req_data.saddr_len = saddr_len; | ||
1574 | req_data.saddr_dat = saddr; | ||
1575 | req_data.buf_size = data_len; | ||
1576 | req_data.p_buffer = value; | ||
1577 | |||
1578 | /* usb send command */ | ||
1579 | if (master == 0) | ||
1580 | status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], | ||
1581 | &req_data); | ||
1582 | else if (master == 1) | ||
1583 | status = dev->cx231xx_send_usb_command(&dev->i2c_bus[1], | ||
1584 | &req_data); | ||
1585 | else if (master == 2) | ||
1586 | status = dev->cx231xx_send_usb_command(&dev->i2c_bus[2], | ||
1587 | &req_data); | ||
1588 | |||
1589 | return status; | ||
1590 | } | ||
1591 | |||
1029 | int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr, | 1592 | int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr, |
1030 | u8 saddr_len, u32 *data, u8 data_len) | 1593 | u8 saddr_len, u32 *data, u8 data_len) |
1031 | { | 1594 | { |
diff --git a/drivers/media/video/cx231xx/cx231xx-dif.h b/drivers/media/video/cx231xx/cx231xx-dif.h new file mode 100644 index 00000000000..2b63c2f6d3b --- /dev/null +++ b/drivers/media/video/cx231xx/cx231xx-dif.h | |||
@@ -0,0 +1,3178 @@ | |||
1 | /* | ||
2 | * cx231xx-dif.h - driver for Conexant Cx23100/101/102 USB video capture devices | ||
3 | * | ||
4 | * Copyright {C} 2009 <Bill.Liu@conexant.com> | ||
5 | * | ||
6 | * This program is free software, you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation, either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY, without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program, if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _CX231XX_DIF_H | ||
22 | #define _CX231XX_DIF_H | ||
23 | |||
24 | #include "cx231xx-reg.h" | ||
25 | |||
26 | struct dif_settings{ | ||
27 | u32 if_freq; | ||
28 | u32 register_address; | ||
29 | u32 value; | ||
30 | }; | ||
31 | |||
32 | static struct dif_settings Dif_set_array[] = { | ||
33 | |||
34 | /*case 3000000:*/ | ||
35 | /* BEGIN - DIF BPF register values from 30_quant.dat*/ | ||
36 | {3000000, DIF_BPF_COEFF01, 0x00000002}, | ||
37 | {3000000, DIF_BPF_COEFF23, 0x00080012}, | ||
38 | {3000000, DIF_BPF_COEFF45, 0x001e0024}, | ||
39 | {3000000, DIF_BPF_COEFF67, 0x001bfff8}, | ||
40 | {3000000, DIF_BPF_COEFF89, 0xffb4ff50}, | ||
41 | {3000000, DIF_BPF_COEFF1011, 0xfed8fe68}, | ||
42 | {3000000, DIF_BPF_COEFF1213, 0xfe24fe34}, | ||
43 | {3000000, DIF_BPF_COEFF1415, 0xfebaffc7}, | ||
44 | {3000000, DIF_BPF_COEFF1617, 0x014d031f}, | ||
45 | {3000000, DIF_BPF_COEFF1819, 0x04f0065d}, | ||
46 | {3000000, DIF_BPF_COEFF2021, 0x07010688}, | ||
47 | {3000000, DIF_BPF_COEFF2223, 0x04c901d6}, | ||
48 | {3000000, DIF_BPF_COEFF2425, 0xfe00f9d3}, | ||
49 | {3000000, DIF_BPF_COEFF2627, 0xf600f342}, | ||
50 | {3000000, DIF_BPF_COEFF2829, 0xf235f337}, | ||
51 | {3000000, DIF_BPF_COEFF3031, 0xf64efb22}, | ||
52 | {3000000, DIF_BPF_COEFF3233, 0x0105070f}, | ||
53 | {3000000, DIF_BPF_COEFF3435, 0x0c460fce}, | ||
54 | {3000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
55 | /* END - DIF BPF register values from 30_quant.dat*/ | ||
56 | |||
57 | |||
58 | /*case 3100000:*/ | ||
59 | /* BEGIN - DIF BPF register values from 31_quant.dat*/ | ||
60 | {3100000, DIF_BPF_COEFF01, 0x00000001}, | ||
61 | {3100000, DIF_BPF_COEFF23, 0x00070012}, | ||
62 | {3100000, DIF_BPF_COEFF45, 0x00220032}, | ||
63 | {3100000, DIF_BPF_COEFF67, 0x00370026}, | ||
64 | {3100000, DIF_BPF_COEFF89, 0xfff0ff91}, | ||
65 | {3100000, DIF_BPF_COEFF1011, 0xff0efe7c}, | ||
66 | {3100000, DIF_BPF_COEFF1213, 0xfe01fdcc}, | ||
67 | {3100000, DIF_BPF_COEFF1415, 0xfe0afedb}, | ||
68 | {3100000, DIF_BPF_COEFF1617, 0x00440224}, | ||
69 | {3100000, DIF_BPF_COEFF1819, 0x0434060c}, | ||
70 | {3100000, DIF_BPF_COEFF2021, 0x0738074e}, | ||
71 | {3100000, DIF_BPF_COEFF2223, 0x06090361}, | ||
72 | {3100000, DIF_BPF_COEFF2425, 0xff99fb39}, | ||
73 | {3100000, DIF_BPF_COEFF2627, 0xf6fef3b6}, | ||
74 | {3100000, DIF_BPF_COEFF2829, 0xf21af2a5}, | ||
75 | {3100000, DIF_BPF_COEFF3031, 0xf573fa33}, | ||
76 | {3100000, DIF_BPF_COEFF3233, 0x0034067d}, | ||
77 | {3100000, DIF_BPF_COEFF3435, 0x0bfb0fb9}, | ||
78 | {3100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
79 | /* END - DIF BPF register values from 31_quant.dat*/ | ||
80 | |||
81 | |||
82 | /*case 3200000:*/ | ||
83 | /* BEGIN - DIF BPF register values from 32_quant.dat*/ | ||
84 | {3200000, DIF_BPF_COEFF01, 0x00000000}, | ||
85 | {3200000, DIF_BPF_COEFF23, 0x0004000e}, | ||
86 | {3200000, DIF_BPF_COEFF45, 0x00200038}, | ||
87 | {3200000, DIF_BPF_COEFF67, 0x004c004f}, | ||
88 | {3200000, DIF_BPF_COEFF89, 0x002fffdf}, | ||
89 | {3200000, DIF_BPF_COEFF1011, 0xff5cfeb6}, | ||
90 | {3200000, DIF_BPF_COEFF1213, 0xfe0dfd92}, | ||
91 | {3200000, DIF_BPF_COEFF1415, 0xfd7ffe03}, | ||
92 | {3200000, DIF_BPF_COEFF1617, 0xff36010a}, | ||
93 | {3200000, DIF_BPF_COEFF1819, 0x03410575}, | ||
94 | {3200000, DIF_BPF_COEFF2021, 0x072607d2}, | ||
95 | {3200000, DIF_BPF_COEFF2223, 0x071804d5}, | ||
96 | {3200000, DIF_BPF_COEFF2425, 0x0134fcb7}, | ||
97 | {3200000, DIF_BPF_COEFF2627, 0xf81ff451}, | ||
98 | {3200000, DIF_BPF_COEFF2829, 0xf223f22e}, | ||
99 | {3200000, DIF_BPF_COEFF3031, 0xf4a7f94b}, | ||
100 | {3200000, DIF_BPF_COEFF3233, 0xff6405e8}, | ||
101 | {3200000, DIF_BPF_COEFF3435, 0x0bae0fa4}, | ||
102 | {3200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
103 | /* END - DIF BPF register values from 32_quant.dat*/ | ||
104 | |||
105 | |||
106 | /*case 3300000:*/ | ||
107 | /* BEGIN - DIF BPF register values from 33_quant.dat*/ | ||
108 | {3300000, DIF_BPF_COEFF01, 0x0000ffff}, | ||
109 | {3300000, DIF_BPF_COEFF23, 0x00000008}, | ||
110 | {3300000, DIF_BPF_COEFF45, 0x001a0036}, | ||
111 | {3300000, DIF_BPF_COEFF67, 0x0056006d}, | ||
112 | {3300000, DIF_BPF_COEFF89, 0x00670030}, | ||
113 | {3300000, DIF_BPF_COEFF1011, 0xffbdff10}, | ||
114 | {3300000, DIF_BPF_COEFF1213, 0xfe46fd8d}, | ||
115 | {3300000, DIF_BPF_COEFF1415, 0xfd25fd4f}, | ||
116 | {3300000, DIF_BPF_COEFF1617, 0xfe35ffe0}, | ||
117 | {3300000, DIF_BPF_COEFF1819, 0x0224049f}, | ||
118 | {3300000, DIF_BPF_COEFF2021, 0x06c9080e}, | ||
119 | {3300000, DIF_BPF_COEFF2223, 0x07ef0627}, | ||
120 | {3300000, DIF_BPF_COEFF2425, 0x02c9fe45}, | ||
121 | {3300000, DIF_BPF_COEFF2627, 0xf961f513}, | ||
122 | {3300000, DIF_BPF_COEFF2829, 0xf250f1d2}, | ||
123 | {3300000, DIF_BPF_COEFF3031, 0xf3ecf869}, | ||
124 | {3300000, DIF_BPF_COEFF3233, 0xfe930552}, | ||
125 | {3300000, DIF_BPF_COEFF3435, 0x0b5f0f8f}, | ||
126 | {3300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
127 | /* END - DIF BPF register values from 33_quant.dat*/ | ||
128 | |||
129 | |||
130 | /*case 3400000:*/ | ||
131 | /* BEGIN - DIF BPF register values from 34_quant.dat*/ | ||
132 | {3400000, DIF_BPF_COEFF01, 0xfffffffe}, | ||
133 | {3400000, DIF_BPF_COEFF23, 0xfffd0001}, | ||
134 | {3400000, DIF_BPF_COEFF45, 0x000f002c}, | ||
135 | {3400000, DIF_BPF_COEFF67, 0x0054007d}, | ||
136 | {3400000, DIF_BPF_COEFF89, 0x0093007c}, | ||
137 | {3400000, DIF_BPF_COEFF1011, 0x0024ff82}, | ||
138 | {3400000, DIF_BPF_COEFF1213, 0xfea6fdbb}, | ||
139 | {3400000, DIF_BPF_COEFF1415, 0xfd03fcca}, | ||
140 | {3400000, DIF_BPF_COEFF1617, 0xfd51feb9}, | ||
141 | {3400000, DIF_BPF_COEFF1819, 0x00eb0392}, | ||
142 | {3400000, DIF_BPF_COEFF2021, 0x06270802}, | ||
143 | {3400000, DIF_BPF_COEFF2223, 0x08880750}, | ||
144 | {3400000, DIF_BPF_COEFF2425, 0x044dffdb}, | ||
145 | {3400000, DIF_BPF_COEFF2627, 0xfabdf5f8}, | ||
146 | {3400000, DIF_BPF_COEFF2829, 0xf2a0f193}, | ||
147 | {3400000, DIF_BPF_COEFF3031, 0xf342f78f}, | ||
148 | {3400000, DIF_BPF_COEFF3233, 0xfdc404b9}, | ||
149 | {3400000, DIF_BPF_COEFF3435, 0x0b0e0f78}, | ||
150 | {3400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
151 | /* END - DIF BPF register values from 34_quant.dat*/ | ||
152 | |||
153 | |||
154 | /*case 3500000:*/ | ||
155 | /* BEGIN - DIF BPF register values from 35_quant.dat*/ | ||
156 | {3500000, DIF_BPF_COEFF01, 0xfffffffd}, | ||
157 | {3500000, DIF_BPF_COEFF23, 0xfffafff9}, | ||
158 | {3500000, DIF_BPF_COEFF45, 0x0002001b}, | ||
159 | {3500000, DIF_BPF_COEFF67, 0x0046007d}, | ||
160 | {3500000, DIF_BPF_COEFF89, 0x00ad00ba}, | ||
161 | {3500000, DIF_BPF_COEFF1011, 0x00870000}, | ||
162 | {3500000, DIF_BPF_COEFF1213, 0xff26fe1a}, | ||
163 | {3500000, DIF_BPF_COEFF1415, 0xfd1bfc7e}, | ||
164 | {3500000, DIF_BPF_COEFF1617, 0xfc99fda4}, | ||
165 | {3500000, DIF_BPF_COEFF1819, 0xffa5025c}, | ||
166 | {3500000, DIF_BPF_COEFF2021, 0x054507ad}, | ||
167 | {3500000, DIF_BPF_COEFF2223, 0x08dd0847}, | ||
168 | {3500000, DIF_BPF_COEFF2425, 0x05b80172}, | ||
169 | {3500000, DIF_BPF_COEFF2627, 0xfc2ef6ff}, | ||
170 | {3500000, DIF_BPF_COEFF2829, 0xf313f170}, | ||
171 | {3500000, DIF_BPF_COEFF3031, 0xf2abf6bd}, | ||
172 | {3500000, DIF_BPF_COEFF3233, 0xfcf6041f}, | ||
173 | {3500000, DIF_BPF_COEFF3435, 0x0abc0f61}, | ||
174 | {3500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
175 | /* END - DIF BPF register values from 35_quant.dat*/ | ||
176 | |||
177 | |||
178 | /*case 3600000:*/ | ||
179 | /* BEGIN - DIF BPF register values from 36_quant.dat*/ | ||
180 | {3600000, DIF_BPF_COEFF01, 0xfffffffd}, | ||
181 | {3600000, DIF_BPF_COEFF23, 0xfff8fff3}, | ||
182 | {3600000, DIF_BPF_COEFF45, 0xfff50006}, | ||
183 | {3600000, DIF_BPF_COEFF67, 0x002f006c}, | ||
184 | {3600000, DIF_BPF_COEFF89, 0x00b200e3}, | ||
185 | {3600000, DIF_BPF_COEFF1011, 0x00dc007e}, | ||
186 | {3600000, DIF_BPF_COEFF1213, 0xffb9fea0}, | ||
187 | {3600000, DIF_BPF_COEFF1415, 0xfd6bfc71}, | ||
188 | {3600000, DIF_BPF_COEFF1617, 0xfc17fcb1}, | ||
189 | {3600000, DIF_BPF_COEFF1819, 0xfe65010b}, | ||
190 | {3600000, DIF_BPF_COEFF2021, 0x042d0713}, | ||
191 | {3600000, DIF_BPF_COEFF2223, 0x08ec0906}, | ||
192 | {3600000, DIF_BPF_COEFF2425, 0x07020302}, | ||
193 | {3600000, DIF_BPF_COEFF2627, 0xfdaff823}, | ||
194 | {3600000, DIF_BPF_COEFF2829, 0xf3a7f16a}, | ||
195 | {3600000, DIF_BPF_COEFF3031, 0xf228f5f5}, | ||
196 | {3600000, DIF_BPF_COEFF3233, 0xfc2a0384}, | ||
197 | {3600000, DIF_BPF_COEFF3435, 0x0a670f4a}, | ||
198 | {3600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
199 | /* END - DIF BPF register values from 36_quant.dat*/ | ||
200 | |||
201 | |||
202 | /*case 3700000:*/ | ||
203 | /* BEGIN - DIF BPF register values from 37_quant.dat*/ | ||
204 | {3700000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
205 | {3700000, DIF_BPF_COEFF23, 0xfff7ffef}, | ||
206 | {3700000, DIF_BPF_COEFF45, 0xffe9fff1}, | ||
207 | {3700000, DIF_BPF_COEFF67, 0x0010004d}, | ||
208 | {3700000, DIF_BPF_COEFF89, 0x00a100f2}, | ||
209 | {3700000, DIF_BPF_COEFF1011, 0x011a00f0}, | ||
210 | {3700000, DIF_BPF_COEFF1213, 0x0053ff44}, | ||
211 | {3700000, DIF_BPF_COEFF1415, 0xfdedfca2}, | ||
212 | {3700000, DIF_BPF_COEFF1617, 0xfbd3fbef}, | ||
213 | {3700000, DIF_BPF_COEFF1819, 0xfd39ffae}, | ||
214 | {3700000, DIF_BPF_COEFF2021, 0x02ea0638}, | ||
215 | {3700000, DIF_BPF_COEFF2223, 0x08b50987}, | ||
216 | {3700000, DIF_BPF_COEFF2425, 0x08230483}, | ||
217 | {3700000, DIF_BPF_COEFF2627, 0xff39f960}, | ||
218 | {3700000, DIF_BPF_COEFF2829, 0xf45bf180}, | ||
219 | {3700000, DIF_BPF_COEFF3031, 0xf1b8f537}, | ||
220 | {3700000, DIF_BPF_COEFF3233, 0xfb6102e7}, | ||
221 | {3700000, DIF_BPF_COEFF3435, 0x0a110f32}, | ||
222 | {3700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
223 | /* END - DIF BPF register values from 37_quant.dat*/ | ||
224 | |||
225 | |||
226 | /*case 3800000:*/ | ||
227 | /* BEGIN - DIF BPF register values from 38_quant.dat*/ | ||
228 | {3800000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
229 | {3800000, DIF_BPF_COEFF23, 0xfff9ffee}, | ||
230 | {3800000, DIF_BPF_COEFF45, 0xffe1ffdd}, | ||
231 | {3800000, DIF_BPF_COEFF67, 0xfff00024}, | ||
232 | {3800000, DIF_BPF_COEFF89, 0x007c00e5}, | ||
233 | {3800000, DIF_BPF_COEFF1011, 0x013a014a}, | ||
234 | {3800000, DIF_BPF_COEFF1213, 0x00e6fff8}, | ||
235 | {3800000, DIF_BPF_COEFF1415, 0xfe98fd0f}, | ||
236 | {3800000, DIF_BPF_COEFF1617, 0xfbd3fb67}, | ||
237 | {3800000, DIF_BPF_COEFF1819, 0xfc32fe54}, | ||
238 | {3800000, DIF_BPF_COEFF2021, 0x01880525}, | ||
239 | {3800000, DIF_BPF_COEFF2223, 0x083909c7}, | ||
240 | {3800000, DIF_BPF_COEFF2425, 0x091505ee}, | ||
241 | {3800000, DIF_BPF_COEFF2627, 0x00c7fab3}, | ||
242 | {3800000, DIF_BPF_COEFF2829, 0xf52df1b4}, | ||
243 | {3800000, DIF_BPF_COEFF3031, 0xf15df484}, | ||
244 | {3800000, DIF_BPF_COEFF3233, 0xfa9b0249}, | ||
245 | {3800000, DIF_BPF_COEFF3435, 0x09ba0f19}, | ||
246 | {3800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
247 | /* END - DIF BPF register values from 38_quant.dat*/ | ||
248 | |||
249 | |||
250 | /*case 3900000:*/ | ||
251 | /* BEGIN - DIF BPF register values from 39_quant.dat*/ | ||
252 | {3900000, DIF_BPF_COEFF01, 0x00000000}, | ||
253 | {3900000, DIF_BPF_COEFF23, 0xfffbfff0}, | ||
254 | {3900000, DIF_BPF_COEFF45, 0xffdeffcf}, | ||
255 | {3900000, DIF_BPF_COEFF67, 0xffd1fff6}, | ||
256 | {3900000, DIF_BPF_COEFF89, 0x004800be}, | ||
257 | {3900000, DIF_BPF_COEFF1011, 0x01390184}, | ||
258 | {3900000, DIF_BPF_COEFF1213, 0x016300ac}, | ||
259 | {3900000, DIF_BPF_COEFF1415, 0xff5efdb1}, | ||
260 | {3900000, DIF_BPF_COEFF1617, 0xfc17fb23}, | ||
261 | {3900000, DIF_BPF_COEFF1819, 0xfb5cfd0d}, | ||
262 | {3900000, DIF_BPF_COEFF2021, 0x001703e4}, | ||
263 | {3900000, DIF_BPF_COEFF2223, 0x077b09c4}, | ||
264 | {3900000, DIF_BPF_COEFF2425, 0x09d2073c}, | ||
265 | {3900000, DIF_BPF_COEFF2627, 0x0251fc18}, | ||
266 | {3900000, DIF_BPF_COEFF2829, 0xf61cf203}, | ||
267 | {3900000, DIF_BPF_COEFF3031, 0xf118f3dc}, | ||
268 | {3900000, DIF_BPF_COEFF3233, 0xf9d801aa}, | ||
269 | {3900000, DIF_BPF_COEFF3435, 0x09600eff}, | ||
270 | {3900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
271 | /* END - DIF BPF register values from 39_quant.dat*/ | ||
272 | |||
273 | |||
274 | /*case 4000000:*/ | ||
275 | /* BEGIN - DIF BPF register values from 40_quant.dat*/ | ||
276 | {4000000, DIF_BPF_COEFF01, 0x00000001}, | ||
277 | {4000000, DIF_BPF_COEFF23, 0xfffefff4}, | ||
278 | {4000000, DIF_BPF_COEFF45, 0xffe1ffc8}, | ||
279 | {4000000, DIF_BPF_COEFF67, 0xffbaffca}, | ||
280 | {4000000, DIF_BPF_COEFF89, 0x000b0082}, | ||
281 | {4000000, DIF_BPF_COEFF1011, 0x01170198}, | ||
282 | {4000000, DIF_BPF_COEFF1213, 0x01c10152}, | ||
283 | {4000000, DIF_BPF_COEFF1415, 0x0030fe7b}, | ||
284 | {4000000, DIF_BPF_COEFF1617, 0xfc99fb24}, | ||
285 | {4000000, DIF_BPF_COEFF1819, 0xfac3fbe9}, | ||
286 | {4000000, DIF_BPF_COEFF2021, 0xfea5027f}, | ||
287 | {4000000, DIF_BPF_COEFF2223, 0x0683097f}, | ||
288 | {4000000, DIF_BPF_COEFF2425, 0x0a560867}, | ||
289 | {4000000, DIF_BPF_COEFF2627, 0x03d2fd89}, | ||
290 | {4000000, DIF_BPF_COEFF2829, 0xf723f26f}, | ||
291 | {4000000, DIF_BPF_COEFF3031, 0xf0e8f341}, | ||
292 | {4000000, DIF_BPF_COEFF3233, 0xf919010a}, | ||
293 | {4000000, DIF_BPF_COEFF3435, 0x09060ee5}, | ||
294 | {4000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
295 | /* END - DIF BPF register values from 40_quant.dat*/ | ||
296 | |||
297 | |||
298 | /*case 4100000:*/ | ||
299 | /* BEGIN - DIF BPF register values from 41_quant.dat*/ | ||
300 | {4100000, DIF_BPF_COEFF01, 0x00010002}, | ||
301 | {4100000, DIF_BPF_COEFF23, 0x0002fffb}, | ||
302 | {4100000, DIF_BPF_COEFF45, 0xffe8ffca}, | ||
303 | {4100000, DIF_BPF_COEFF67, 0xffacffa4}, | ||
304 | {4100000, DIF_BPF_COEFF89, 0xffcd0036}, | ||
305 | {4100000, DIF_BPF_COEFF1011, 0x00d70184}, | ||
306 | {4100000, DIF_BPF_COEFF1213, 0x01f601dc}, | ||
307 | {4100000, DIF_BPF_COEFF1415, 0x00ffff60}, | ||
308 | {4100000, DIF_BPF_COEFF1617, 0xfd51fb6d}, | ||
309 | {4100000, DIF_BPF_COEFF1819, 0xfa6efaf5}, | ||
310 | {4100000, DIF_BPF_COEFF2021, 0xfd410103}, | ||
311 | {4100000, DIF_BPF_COEFF2223, 0x055708f9}, | ||
312 | {4100000, DIF_BPF_COEFF2425, 0x0a9e0969}, | ||
313 | {4100000, DIF_BPF_COEFF2627, 0x0543ff02}, | ||
314 | {4100000, DIF_BPF_COEFF2829, 0xf842f2f5}, | ||
315 | {4100000, DIF_BPF_COEFF3031, 0xf0cef2b2}, | ||
316 | {4100000, DIF_BPF_COEFF3233, 0xf85e006b}, | ||
317 | {4100000, DIF_BPF_COEFF3435, 0x08aa0ecb}, | ||
318 | {4100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
319 | /* END - DIF BPF register values from 41_quant.dat*/ | ||
320 | |||
321 | |||
322 | /*case 4200000:*/ | ||
323 | /* BEGIN - DIF BPF register values from 42_quant.dat*/ | ||
324 | {4200000, DIF_BPF_COEFF01, 0x00010003}, | ||
325 | {4200000, DIF_BPF_COEFF23, 0x00050003}, | ||
326 | {4200000, DIF_BPF_COEFF45, 0xfff3ffd3}, | ||
327 | {4200000, DIF_BPF_COEFF67, 0xffaaff8b}, | ||
328 | {4200000, DIF_BPF_COEFF89, 0xff95ffe5}, | ||
329 | {4200000, DIF_BPF_COEFF1011, 0x0080014a}, | ||
330 | {4200000, DIF_BPF_COEFF1213, 0x01fe023f}, | ||
331 | {4200000, DIF_BPF_COEFF1415, 0x01ba0050}, | ||
332 | {4200000, DIF_BPF_COEFF1617, 0xfe35fbf8}, | ||
333 | {4200000, DIF_BPF_COEFF1819, 0xfa62fa3b}, | ||
334 | {4200000, DIF_BPF_COEFF2021, 0xfbf9ff7e}, | ||
335 | {4200000, DIF_BPF_COEFF2223, 0x04010836}, | ||
336 | {4200000, DIF_BPF_COEFF2425, 0x0aa90a3d}, | ||
337 | {4200000, DIF_BPF_COEFF2627, 0x069f007f}, | ||
338 | {4200000, DIF_BPF_COEFF2829, 0xf975f395}, | ||
339 | {4200000, DIF_BPF_COEFF3031, 0xf0cbf231}, | ||
340 | {4200000, DIF_BPF_COEFF3233, 0xf7a9ffcb}, | ||
341 | {4200000, DIF_BPF_COEFF3435, 0x084c0eaf}, | ||
342 | {4200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
343 | /* END - DIF BPF register values from 42_quant.dat*/ | ||
344 | |||
345 | |||
346 | /*case 4300000:*/ | ||
347 | /* BEGIN - DIF BPF register values from 43_quant.dat*/ | ||
348 | {4300000, DIF_BPF_COEFF01, 0x00010003}, | ||
349 | {4300000, DIF_BPF_COEFF23, 0x0008000a}, | ||
350 | {4300000, DIF_BPF_COEFF45, 0x0000ffe4}, | ||
351 | {4300000, DIF_BPF_COEFF67, 0xffb4ff81}, | ||
352 | {4300000, DIF_BPF_COEFF89, 0xff6aff96}, | ||
353 | {4300000, DIF_BPF_COEFF1011, 0x001c00f0}, | ||
354 | {4300000, DIF_BPF_COEFF1213, 0x01d70271}, | ||
355 | {4300000, DIF_BPF_COEFF1415, 0x0254013b}, | ||
356 | {4300000, DIF_BPF_COEFF1617, 0xff36fcbd}, | ||
357 | {4300000, DIF_BPF_COEFF1819, 0xfa9ff9c5}, | ||
358 | {4300000, DIF_BPF_COEFF2021, 0xfadbfdfe}, | ||
359 | {4300000, DIF_BPF_COEFF2223, 0x028c073b}, | ||
360 | {4300000, DIF_BPF_COEFF2425, 0x0a750adf}, | ||
361 | {4300000, DIF_BPF_COEFF2627, 0x07e101fa}, | ||
362 | {4300000, DIF_BPF_COEFF2829, 0xfab8f44e}, | ||
363 | {4300000, DIF_BPF_COEFF3031, 0xf0ddf1be}, | ||
364 | {4300000, DIF_BPF_COEFF3233, 0xf6f9ff2b}, | ||
365 | {4300000, DIF_BPF_COEFF3435, 0x07ed0e94}, | ||
366 | {4300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
367 | /* END - DIF BPF register values from 43_quant.dat*/ | ||
368 | |||
369 | |||
370 | /*case 4400000:*/ | ||
371 | /* BEGIN - DIF BPF register values from 44_quant.dat*/ | ||
372 | {4400000, DIF_BPF_COEFF01, 0x00000003}, | ||
373 | {4400000, DIF_BPF_COEFF23, 0x0009000f}, | ||
374 | {4400000, DIF_BPF_COEFF45, 0x000efff8}, | ||
375 | {4400000, DIF_BPF_COEFF67, 0xffc9ff87}, | ||
376 | {4400000, DIF_BPF_COEFF89, 0xff52ff54}, | ||
377 | {4400000, DIF_BPF_COEFF1011, 0xffb5007e}, | ||
378 | {4400000, DIF_BPF_COEFF1213, 0x01860270}, | ||
379 | {4400000, DIF_BPF_COEFF1415, 0x02c00210}, | ||
380 | {4400000, DIF_BPF_COEFF1617, 0x0044fdb2}, | ||
381 | {4400000, DIF_BPF_COEFF1819, 0xfb22f997}, | ||
382 | {4400000, DIF_BPF_COEFF2021, 0xf9f2fc90}, | ||
383 | {4400000, DIF_BPF_COEFF2223, 0x0102060f}, | ||
384 | {4400000, DIF_BPF_COEFF2425, 0x0a050b4c}, | ||
385 | {4400000, DIF_BPF_COEFF2627, 0x0902036e}, | ||
386 | {4400000, DIF_BPF_COEFF2829, 0xfc0af51e}, | ||
387 | {4400000, DIF_BPF_COEFF3031, 0xf106f15a}, | ||
388 | {4400000, DIF_BPF_COEFF3233, 0xf64efe8b}, | ||
389 | {4400000, DIF_BPF_COEFF3435, 0x078d0e77}, | ||
390 | {4400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
391 | /* END - DIF BPF register values from 44_quant.dat*/ | ||
392 | |||
393 | |||
394 | /*case 4500000:*/ | ||
395 | /* BEGIN - DIF BPF register values from 45_quant.dat*/ | ||
396 | {4500000, DIF_BPF_COEFF01, 0x00000002}, | ||
397 | {4500000, DIF_BPF_COEFF23, 0x00080012}, | ||
398 | {4500000, DIF_BPF_COEFF45, 0x0019000e}, | ||
399 | {4500000, DIF_BPF_COEFF67, 0xffe5ff9e}, | ||
400 | {4500000, DIF_BPF_COEFF89, 0xff4fff25}, | ||
401 | {4500000, DIF_BPF_COEFF1011, 0xff560000}, | ||
402 | {4500000, DIF_BPF_COEFF1213, 0x0112023b}, | ||
403 | {4500000, DIF_BPF_COEFF1415, 0x02f702c0}, | ||
404 | {4500000, DIF_BPF_COEFF1617, 0x014dfec8}, | ||
405 | {4500000, DIF_BPF_COEFF1819, 0xfbe5f9b3}, | ||
406 | {4500000, DIF_BPF_COEFF2021, 0xf947fb41}, | ||
407 | {4500000, DIF_BPF_COEFF2223, 0xff7004b9}, | ||
408 | {4500000, DIF_BPF_COEFF2425, 0x095a0b81}, | ||
409 | {4500000, DIF_BPF_COEFF2627, 0x0a0004d8}, | ||
410 | {4500000, DIF_BPF_COEFF2829, 0xfd65f603}, | ||
411 | {4500000, DIF_BPF_COEFF3031, 0xf144f104}, | ||
412 | {4500000, DIF_BPF_COEFF3233, 0xf5aafdec}, | ||
413 | {4500000, DIF_BPF_COEFF3435, 0x072b0e5a}, | ||
414 | {4500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
415 | /* END - DIF BPF register values from 45_quant.dat*/ | ||
416 | |||
417 | |||
418 | /*case 4600000:*/ | ||
419 | /* BEGIN - DIF BPF register values from 46_quant.dat*/ | ||
420 | {4600000, DIF_BPF_COEFF01, 0x00000001}, | ||
421 | {4600000, DIF_BPF_COEFF23, 0x00060012}, | ||
422 | {4600000, DIF_BPF_COEFF45, 0x00200022}, | ||
423 | {4600000, DIF_BPF_COEFF67, 0x0005ffc1}, | ||
424 | {4600000, DIF_BPF_COEFF89, 0xff61ff10}, | ||
425 | {4600000, DIF_BPF_COEFF1011, 0xff09ff82}, | ||
426 | {4600000, DIF_BPF_COEFF1213, 0x008601d7}, | ||
427 | {4600000, DIF_BPF_COEFF1415, 0x02f50340}, | ||
428 | {4600000, DIF_BPF_COEFF1617, 0x0241fff0}, | ||
429 | {4600000, DIF_BPF_COEFF1819, 0xfcddfa19}, | ||
430 | {4600000, DIF_BPF_COEFF2021, 0xf8e2fa1e}, | ||
431 | {4600000, DIF_BPF_COEFF2223, 0xfde30343}, | ||
432 | {4600000, DIF_BPF_COEFF2425, 0x08790b7f}, | ||
433 | {4600000, DIF_BPF_COEFF2627, 0x0ad50631}, | ||
434 | {4600000, DIF_BPF_COEFF2829, 0xfec7f6fc}, | ||
435 | {4600000, DIF_BPF_COEFF3031, 0xf198f0bd}, | ||
436 | {4600000, DIF_BPF_COEFF3233, 0xf50dfd4e}, | ||
437 | {4600000, DIF_BPF_COEFF3435, 0x06c90e3d}, | ||
438 | {4600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
439 | /* END - DIF BPF register values from 46_quant.dat*/ | ||
440 | |||
441 | |||
442 | /*case 4700000:*/ | ||
443 | /* BEGIN - DIF BPF register values from 47_quant.dat*/ | ||
444 | {4700000, DIF_BPF_COEFF01, 0x0000ffff}, | ||
445 | {4700000, DIF_BPF_COEFF23, 0x0003000f}, | ||
446 | {4700000, DIF_BPF_COEFF45, 0x00220030}, | ||
447 | {4700000, DIF_BPF_COEFF67, 0x0025ffed}, | ||
448 | {4700000, DIF_BPF_COEFF89, 0xff87ff15}, | ||
449 | {4700000, DIF_BPF_COEFF1011, 0xfed6ff10}, | ||
450 | {4700000, DIF_BPF_COEFF1213, 0xffed014c}, | ||
451 | {4700000, DIF_BPF_COEFF1415, 0x02b90386}, | ||
452 | {4700000, DIF_BPF_COEFF1617, 0x03110119}, | ||
453 | {4700000, DIF_BPF_COEFF1819, 0xfdfefac4}, | ||
454 | {4700000, DIF_BPF_COEFF2021, 0xf8c6f92f}, | ||
455 | {4700000, DIF_BPF_COEFF2223, 0xfc6701b7}, | ||
456 | {4700000, DIF_BPF_COEFF2425, 0x07670b44}, | ||
457 | {4700000, DIF_BPF_COEFF2627, 0x0b7e0776}, | ||
458 | {4700000, DIF_BPF_COEFF2829, 0x002df807}, | ||
459 | {4700000, DIF_BPF_COEFF3031, 0xf200f086}, | ||
460 | {4700000, DIF_BPF_COEFF3233, 0xf477fcb1}, | ||
461 | {4700000, DIF_BPF_COEFF3435, 0x06650e1e}, | ||
462 | {4700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
463 | /* END - DIF BPF register values from 47_quant.dat*/ | ||
464 | |||
465 | |||
466 | /*case 4800000:*/ | ||
467 | /* BEGIN - DIF BPF register values from 48_quant.dat*/ | ||
468 | {4800000, DIF_BPF_COEFF01, 0xfffffffe}, | ||
469 | {4800000, DIF_BPF_COEFF23, 0xffff0009}, | ||
470 | {4800000, DIF_BPF_COEFF45, 0x001e0038}, | ||
471 | {4800000, DIF_BPF_COEFF67, 0x003f001b}, | ||
472 | {4800000, DIF_BPF_COEFF89, 0xffbcff36}, | ||
473 | {4800000, DIF_BPF_COEFF1011, 0xfec2feb6}, | ||
474 | {4800000, DIF_BPF_COEFF1213, 0xff5600a5}, | ||
475 | {4800000, DIF_BPF_COEFF1415, 0x0248038d}, | ||
476 | {4800000, DIF_BPF_COEFF1617, 0x03b00232}, | ||
477 | {4800000, DIF_BPF_COEFF1819, 0xff39fbab}, | ||
478 | {4800000, DIF_BPF_COEFF2021, 0xf8f4f87f}, | ||
479 | {4800000, DIF_BPF_COEFF2223, 0xfb060020}, | ||
480 | {4800000, DIF_BPF_COEFF2425, 0x062a0ad2}, | ||
481 | {4800000, DIF_BPF_COEFF2627, 0x0bf908a3}, | ||
482 | {4800000, DIF_BPF_COEFF2829, 0x0192f922}, | ||
483 | {4800000, DIF_BPF_COEFF3031, 0xf27df05e}, | ||
484 | {4800000, DIF_BPF_COEFF3233, 0xf3e8fc14}, | ||
485 | {4800000, DIF_BPF_COEFF3435, 0x06000e00}, | ||
486 | {4800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
487 | /* END - DIF BPF register values from 48_quant.dat*/ | ||
488 | |||
489 | |||
490 | /*case 4900000:*/ | ||
491 | /* BEGIN - DIF BPF register values from 49_quant.dat*/ | ||
492 | {4900000, DIF_BPF_COEFF01, 0xfffffffd}, | ||
493 | {4900000, DIF_BPF_COEFF23, 0xfffc0002}, | ||
494 | {4900000, DIF_BPF_COEFF45, 0x00160037}, | ||
495 | {4900000, DIF_BPF_COEFF67, 0x00510046}, | ||
496 | {4900000, DIF_BPF_COEFF89, 0xfff9ff6d}, | ||
497 | {4900000, DIF_BPF_COEFF1011, 0xfed0fe7c}, | ||
498 | {4900000, DIF_BPF_COEFF1213, 0xfecefff0}, | ||
499 | {4900000, DIF_BPF_COEFF1415, 0x01aa0356}, | ||
500 | {4900000, DIF_BPF_COEFF1617, 0x0413032b}, | ||
501 | {4900000, DIF_BPF_COEFF1819, 0x007ffcc5}, | ||
502 | {4900000, DIF_BPF_COEFF2021, 0xf96cf812}, | ||
503 | {4900000, DIF_BPF_COEFF2223, 0xf9cefe87}, | ||
504 | {4900000, DIF_BPF_COEFF2425, 0x04c90a2c}, | ||
505 | {4900000, DIF_BPF_COEFF2627, 0x0c4309b4}, | ||
506 | {4900000, DIF_BPF_COEFF2829, 0x02f3fa4a}, | ||
507 | {4900000, DIF_BPF_COEFF3031, 0xf30ef046}, | ||
508 | {4900000, DIF_BPF_COEFF3233, 0xf361fb7a}, | ||
509 | {4900000, DIF_BPF_COEFF3435, 0x059b0de0}, | ||
510 | {4900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
511 | /* END - DIF BPF register values from 49_quant.dat*/ | ||
512 | |||
513 | |||
514 | /*case 5000000:*/ | ||
515 | /* BEGIN - DIF BPF register values from 50_quant.dat*/ | ||
516 | {5000000, DIF_BPF_COEFF01, 0xfffffffd}, | ||
517 | {5000000, DIF_BPF_COEFF23, 0xfff9fffa}, | ||
518 | {5000000, DIF_BPF_COEFF45, 0x000a002d}, | ||
519 | {5000000, DIF_BPF_COEFF67, 0x00570067}, | ||
520 | {5000000, DIF_BPF_COEFF89, 0x0037ffb5}, | ||
521 | {5000000, DIF_BPF_COEFF1011, 0xfefffe68}, | ||
522 | {5000000, DIF_BPF_COEFF1213, 0xfe62ff3d}, | ||
523 | {5000000, DIF_BPF_COEFF1415, 0x00ec02e3}, | ||
524 | {5000000, DIF_BPF_COEFF1617, 0x043503f6}, | ||
525 | {5000000, DIF_BPF_COEFF1819, 0x01befe05}, | ||
526 | {5000000, DIF_BPF_COEFF2021, 0xfa27f7ee}, | ||
527 | {5000000, DIF_BPF_COEFF2223, 0xf8c6fcf8}, | ||
528 | {5000000, DIF_BPF_COEFF2425, 0x034c0954}, | ||
529 | {5000000, DIF_BPF_COEFF2627, 0x0c5c0aa4}, | ||
530 | {5000000, DIF_BPF_COEFF2829, 0x044cfb7e}, | ||
531 | {5000000, DIF_BPF_COEFF3031, 0xf3b1f03f}, | ||
532 | {5000000, DIF_BPF_COEFF3233, 0xf2e2fae1}, | ||
533 | {5000000, DIF_BPF_COEFF3435, 0x05340dc0}, | ||
534 | {5000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
535 | /* END - DIF BPF register values from 50_quant.dat*/ | ||
536 | |||
537 | |||
538 | /*case 5100000:*/ | ||
539 | /* BEGIN - DIF BPF register values from 51_quant.dat*/ | ||
540 | {5100000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
541 | {5100000, DIF_BPF_COEFF23, 0xfff8fff4}, | ||
542 | {5100000, DIF_BPF_COEFF45, 0xfffd001e}, | ||
543 | {5100000, DIF_BPF_COEFF67, 0x0051007b}, | ||
544 | {5100000, DIF_BPF_COEFF89, 0x006e0006}, | ||
545 | {5100000, DIF_BPF_COEFF1011, 0xff48fe7c}, | ||
546 | {5100000, DIF_BPF_COEFF1213, 0xfe1bfe9a}, | ||
547 | {5100000, DIF_BPF_COEFF1415, 0x001d023e}, | ||
548 | {5100000, DIF_BPF_COEFF1617, 0x04130488}, | ||
549 | {5100000, DIF_BPF_COEFF1819, 0x02e6ff5b}, | ||
550 | {5100000, DIF_BPF_COEFF2021, 0xfb1ef812}, | ||
551 | {5100000, DIF_BPF_COEFF2223, 0xf7f7fb7f}, | ||
552 | {5100000, DIF_BPF_COEFF2425, 0x01bc084e}, | ||
553 | {5100000, DIF_BPF_COEFF2627, 0x0c430b72}, | ||
554 | {5100000, DIF_BPF_COEFF2829, 0x059afcba}, | ||
555 | {5100000, DIF_BPF_COEFF3031, 0xf467f046}, | ||
556 | {5100000, DIF_BPF_COEFF3233, 0xf26cfa4a}, | ||
557 | {5100000, DIF_BPF_COEFF3435, 0x04cd0da0}, | ||
558 | {5100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
559 | /* END - DIF BPF register values from 51_quant.dat*/ | ||
560 | |||
561 | |||
562 | /*case 5200000:*/ | ||
563 | /* BEGIN - DIF BPF register values from 52_quant.dat*/ | ||
564 | {5200000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
565 | {5200000, DIF_BPF_COEFF23, 0xfff8ffef}, | ||
566 | {5200000, DIF_BPF_COEFF45, 0xfff00009}, | ||
567 | {5200000, DIF_BPF_COEFF67, 0x003f007f}, | ||
568 | {5200000, DIF_BPF_COEFF89, 0x00980056}, | ||
569 | {5200000, DIF_BPF_COEFF1011, 0xffa5feb6}, | ||
570 | {5200000, DIF_BPF_COEFF1213, 0xfe00fe15}, | ||
571 | {5200000, DIF_BPF_COEFF1415, 0xff4b0170}, | ||
572 | {5200000, DIF_BPF_COEFF1617, 0x03b004d7}, | ||
573 | {5200000, DIF_BPF_COEFF1819, 0x03e800b9}, | ||
574 | {5200000, DIF_BPF_COEFF2021, 0xfc48f87f}, | ||
575 | {5200000, DIF_BPF_COEFF2223, 0xf768fa23}, | ||
576 | {5200000, DIF_BPF_COEFF2425, 0x0022071f}, | ||
577 | {5200000, DIF_BPF_COEFF2627, 0x0bf90c1b}, | ||
578 | {5200000, DIF_BPF_COEFF2829, 0x06dafdfd}, | ||
579 | {5200000, DIF_BPF_COEFF3031, 0xf52df05e}, | ||
580 | {5200000, DIF_BPF_COEFF3233, 0xf1fef9b5}, | ||
581 | {5200000, DIF_BPF_COEFF3435, 0x04640d7f}, | ||
582 | {5200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
583 | /* END - DIF BPF register values from 52_quant.dat*/ | ||
584 | |||
585 | |||
586 | /*case 5300000:*/ | ||
587 | /* BEGIN - DIF BPF register values from 53_quant.dat*/ | ||
588 | {5300000, DIF_BPF_COEFF01, 0x0000ffff}, | ||
589 | {5300000, DIF_BPF_COEFF23, 0xfff9ffee}, | ||
590 | {5300000, DIF_BPF_COEFF45, 0xffe6fff3}, | ||
591 | {5300000, DIF_BPF_COEFF67, 0x00250072}, | ||
592 | {5300000, DIF_BPF_COEFF89, 0x00af009c}, | ||
593 | {5300000, DIF_BPF_COEFF1011, 0x000cff10}, | ||
594 | {5300000, DIF_BPF_COEFF1213, 0xfe13fdb8}, | ||
595 | {5300000, DIF_BPF_COEFF1415, 0xfe870089}, | ||
596 | {5300000, DIF_BPF_COEFF1617, 0x031104e1}, | ||
597 | {5300000, DIF_BPF_COEFF1819, 0x04b8020f}, | ||
598 | {5300000, DIF_BPF_COEFF2021, 0xfd98f92f}, | ||
599 | {5300000, DIF_BPF_COEFF2223, 0xf71df8f0}, | ||
600 | {5300000, DIF_BPF_COEFF2425, 0xfe8805ce}, | ||
601 | {5300000, DIF_BPF_COEFF2627, 0x0b7e0c9c}, | ||
602 | {5300000, DIF_BPF_COEFF2829, 0x0808ff44}, | ||
603 | {5300000, DIF_BPF_COEFF3031, 0xf603f086}, | ||
604 | {5300000, DIF_BPF_COEFF3233, 0xf19af922}, | ||
605 | {5300000, DIF_BPF_COEFF3435, 0x03fb0d5e}, | ||
606 | {5300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
607 | /* END - DIF BPF register values from 53_quant.dat*/ | ||
608 | |||
609 | |||
610 | /*case 5400000:*/ | ||
611 | /* BEGIN - DIF BPF register values from 54_quant.dat*/ | ||
612 | {5400000, DIF_BPF_COEFF01, 0x00000001}, | ||
613 | {5400000, DIF_BPF_COEFF23, 0xfffcffef}, | ||
614 | {5400000, DIF_BPF_COEFF45, 0xffe0ffe0}, | ||
615 | {5400000, DIF_BPF_COEFF67, 0x00050056}, | ||
616 | {5400000, DIF_BPF_COEFF89, 0x00b000d1}, | ||
617 | {5400000, DIF_BPF_COEFF1011, 0x0071ff82}, | ||
618 | {5400000, DIF_BPF_COEFF1213, 0xfe53fd8c}, | ||
619 | {5400000, DIF_BPF_COEFF1415, 0xfddfff99}, | ||
620 | {5400000, DIF_BPF_COEFF1617, 0x024104a3}, | ||
621 | {5400000, DIF_BPF_COEFF1819, 0x054a034d}, | ||
622 | {5400000, DIF_BPF_COEFF2021, 0xff01fa1e}, | ||
623 | {5400000, DIF_BPF_COEFF2223, 0xf717f7ed}, | ||
624 | {5400000, DIF_BPF_COEFF2425, 0xfcf50461}, | ||
625 | {5400000, DIF_BPF_COEFF2627, 0x0ad50cf4}, | ||
626 | {5400000, DIF_BPF_COEFF2829, 0x0921008d}, | ||
627 | {5400000, DIF_BPF_COEFF3031, 0xf6e7f0bd}, | ||
628 | {5400000, DIF_BPF_COEFF3233, 0xf13ff891}, | ||
629 | {5400000, DIF_BPF_COEFF3435, 0x03920d3b}, | ||
630 | {5400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
631 | /* END - DIF BPF register values from 54_quant.dat*/ | ||
632 | |||
633 | |||
634 | /*case 5500000:*/ | ||
635 | /* BEGIN - DIF BPF register values from 55_quant.dat*/ | ||
636 | {5500000, DIF_BPF_COEFF01, 0x00010002}, | ||
637 | {5500000, DIF_BPF_COEFF23, 0xfffffff3}, | ||
638 | {5500000, DIF_BPF_COEFF45, 0xffdeffd1}, | ||
639 | {5500000, DIF_BPF_COEFF67, 0xffe5002f}, | ||
640 | {5500000, DIF_BPF_COEFF89, 0x009c00ed}, | ||
641 | {5500000, DIF_BPF_COEFF1011, 0x00cb0000}, | ||
642 | {5500000, DIF_BPF_COEFF1213, 0xfebafd94}, | ||
643 | {5500000, DIF_BPF_COEFF1415, 0xfd61feb0}, | ||
644 | {5500000, DIF_BPF_COEFF1617, 0x014d0422}, | ||
645 | {5500000, DIF_BPF_COEFF1819, 0x05970464}, | ||
646 | {5500000, DIF_BPF_COEFF2021, 0x0074fb41}, | ||
647 | {5500000, DIF_BPF_COEFF2223, 0xf759f721}, | ||
648 | {5500000, DIF_BPF_COEFF2425, 0xfb7502de}, | ||
649 | {5500000, DIF_BPF_COEFF2627, 0x0a000d21}, | ||
650 | {5500000, DIF_BPF_COEFF2829, 0x0a2201d4}, | ||
651 | {5500000, DIF_BPF_COEFF3031, 0xf7d9f104}, | ||
652 | {5500000, DIF_BPF_COEFF3233, 0xf0edf804}, | ||
653 | {5500000, DIF_BPF_COEFF3435, 0x03280d19}, | ||
654 | {5500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
655 | /* END - DIF BPF register values from 55_quant.dat*/ | ||
656 | |||
657 | |||
658 | /*case 5600000:*/ | ||
659 | /* BEGIN - DIF BPF register values from 56_quant.dat*/ | ||
660 | {5600000, DIF_BPF_COEFF01, 0x00010003}, | ||
661 | {5600000, DIF_BPF_COEFF23, 0x0003fffa}, | ||
662 | {5600000, DIF_BPF_COEFF45, 0xffe3ffc9}, | ||
663 | {5600000, DIF_BPF_COEFF67, 0xffc90002}, | ||
664 | {5600000, DIF_BPF_COEFF89, 0x007500ef}, | ||
665 | {5600000, DIF_BPF_COEFF1011, 0x010e007e}, | ||
666 | {5600000, DIF_BPF_COEFF1213, 0xff3dfdcf}, | ||
667 | {5600000, DIF_BPF_COEFF1415, 0xfd16fddd}, | ||
668 | {5600000, DIF_BPF_COEFF1617, 0x00440365}, | ||
669 | {5600000, DIF_BPF_COEFF1819, 0x059b0548}, | ||
670 | {5600000, DIF_BPF_COEFF2021, 0x01e3fc90}, | ||
671 | {5600000, DIF_BPF_COEFF2223, 0xf7dff691}, | ||
672 | {5600000, DIF_BPF_COEFF2425, 0xfa0f014d}, | ||
673 | {5600000, DIF_BPF_COEFF2627, 0x09020d23}, | ||
674 | {5600000, DIF_BPF_COEFF2829, 0x0b0a0318}, | ||
675 | {5600000, DIF_BPF_COEFF3031, 0xf8d7f15a}, | ||
676 | {5600000, DIF_BPF_COEFF3233, 0xf0a5f779}, | ||
677 | {5600000, DIF_BPF_COEFF3435, 0x02bd0cf6}, | ||
678 | {5600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
679 | /* END - DIF BPF register values from 56_quant.dat*/ | ||
680 | |||
681 | |||
682 | /*case 5700000:*/ | ||
683 | /* BEGIN - DIF BPF register values from 57_quant.dat*/ | ||
684 | {5700000, DIF_BPF_COEFF01, 0x00010003}, | ||
685 | {5700000, DIF_BPF_COEFF23, 0x00060001}, | ||
686 | {5700000, DIF_BPF_COEFF45, 0xffecffc9}, | ||
687 | {5700000, DIF_BPF_COEFF67, 0xffb4ffd4}, | ||
688 | {5700000, DIF_BPF_COEFF89, 0x004000d5}, | ||
689 | {5700000, DIF_BPF_COEFF1011, 0x013600f0}, | ||
690 | {5700000, DIF_BPF_COEFF1213, 0xffd3fe39}, | ||
691 | {5700000, DIF_BPF_COEFF1415, 0xfd04fd31}, | ||
692 | {5700000, DIF_BPF_COEFF1617, 0xff360277}, | ||
693 | {5700000, DIF_BPF_COEFF1819, 0x055605ef}, | ||
694 | {5700000, DIF_BPF_COEFF2021, 0x033efdfe}, | ||
695 | {5700000, DIF_BPF_COEFF2223, 0xf8a5f642}, | ||
696 | {5700000, DIF_BPF_COEFF2425, 0xf8cbffb6}, | ||
697 | {5700000, DIF_BPF_COEFF2627, 0x07e10cfb}, | ||
698 | {5700000, DIF_BPF_COEFF2829, 0x0bd50456}, | ||
699 | {5700000, DIF_BPF_COEFF3031, 0xf9dff1be}, | ||
700 | {5700000, DIF_BPF_COEFF3233, 0xf067f6f2}, | ||
701 | {5700000, DIF_BPF_COEFF3435, 0x02520cd2}, | ||
702 | {5700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
703 | /* END - DIF BPF register values from 57_quant.dat*/ | ||
704 | |||
705 | |||
706 | /*case 5800000:*/ | ||
707 | /* BEGIN - DIF BPF register values from 58_quant.dat*/ | ||
708 | {5800000, DIF_BPF_COEFF01, 0x00000003}, | ||
709 | {5800000, DIF_BPF_COEFF23, 0x00080009}, | ||
710 | {5800000, DIF_BPF_COEFF45, 0xfff8ffd2}, | ||
711 | {5800000, DIF_BPF_COEFF67, 0xffaaffac}, | ||
712 | {5800000, DIF_BPF_COEFF89, 0x000200a3}, | ||
713 | {5800000, DIF_BPF_COEFF1011, 0x013c014a}, | ||
714 | {5800000, DIF_BPF_COEFF1213, 0x006dfec9}, | ||
715 | {5800000, DIF_BPF_COEFF1415, 0xfd2bfcb7}, | ||
716 | {5800000, DIF_BPF_COEFF1617, 0xfe350165}, | ||
717 | {5800000, DIF_BPF_COEFF1819, 0x04cb0651}, | ||
718 | {5800000, DIF_BPF_COEFF2021, 0x0477ff7e}, | ||
719 | {5800000, DIF_BPF_COEFF2223, 0xf9a5f635}, | ||
720 | {5800000, DIF_BPF_COEFF2425, 0xf7b1fe20}, | ||
721 | {5800000, DIF_BPF_COEFF2627, 0x069f0ca8}, | ||
722 | {5800000, DIF_BPF_COEFF2829, 0x0c81058b}, | ||
723 | {5800000, DIF_BPF_COEFF3031, 0xfaf0f231}, | ||
724 | {5800000, DIF_BPF_COEFF3233, 0xf033f66d}, | ||
725 | {5800000, DIF_BPF_COEFF3435, 0x01e60cae}, | ||
726 | {5800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
727 | /* END - DIF BPF register values from 58_quant.dat*/ | ||
728 | |||
729 | |||
730 | /*case 5900000:*/ | ||
731 | /* BEGIN - DIF BPF register values from 59_quant.dat*/ | ||
732 | {5900000, DIF_BPF_COEFF01, 0x00000002}, | ||
733 | {5900000, DIF_BPF_COEFF23, 0x0009000e}, | ||
734 | {5900000, DIF_BPF_COEFF45, 0x0005ffe1}, | ||
735 | {5900000, DIF_BPF_COEFF67, 0xffacff90}, | ||
736 | {5900000, DIF_BPF_COEFF89, 0xffc5005f}, | ||
737 | {5900000, DIF_BPF_COEFF1011, 0x01210184}, | ||
738 | {5900000, DIF_BPF_COEFF1213, 0x00fcff72}, | ||
739 | {5900000, DIF_BPF_COEFF1415, 0xfd8afc77}, | ||
740 | {5900000, DIF_BPF_COEFF1617, 0xfd51003f}, | ||
741 | {5900000, DIF_BPF_COEFF1819, 0x04020669}, | ||
742 | {5900000, DIF_BPF_COEFF2021, 0x05830103}, | ||
743 | {5900000, DIF_BPF_COEFF2223, 0xfad7f66b}, | ||
744 | {5900000, DIF_BPF_COEFF2425, 0xf6c8fc93}, | ||
745 | {5900000, DIF_BPF_COEFF2627, 0x05430c2b}, | ||
746 | {5900000, DIF_BPF_COEFF2829, 0x0d0d06b5}, | ||
747 | {5900000, DIF_BPF_COEFF3031, 0xfc08f2b2}, | ||
748 | {5900000, DIF_BPF_COEFF3233, 0xf00af5ec}, | ||
749 | {5900000, DIF_BPF_COEFF3435, 0x017b0c89}, | ||
750 | {5900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
751 | /* END - DIF BPF register values from 59_quant.dat*/ | ||
752 | |||
753 | |||
754 | /*case 6000000:*/ | ||
755 | /* BEGIN - DIF BPF register values from 60_quant.dat*/ | ||
756 | {6000000, DIF_BPF_COEFF01, 0x00000001}, | ||
757 | {6000000, DIF_BPF_COEFF23, 0x00070012}, | ||
758 | {6000000, DIF_BPF_COEFF45, 0x0012fff5}, | ||
759 | {6000000, DIF_BPF_COEFF67, 0xffbaff82}, | ||
760 | {6000000, DIF_BPF_COEFF89, 0xff8e000f}, | ||
761 | {6000000, DIF_BPF_COEFF1011, 0x00e80198}, | ||
762 | {6000000, DIF_BPF_COEFF1213, 0x01750028}, | ||
763 | {6000000, DIF_BPF_COEFF1415, 0xfe18fc75}, | ||
764 | {6000000, DIF_BPF_COEFF1617, 0xfc99ff15}, | ||
765 | {6000000, DIF_BPF_COEFF1819, 0x03050636}, | ||
766 | {6000000, DIF_BPF_COEFF2021, 0x0656027f}, | ||
767 | {6000000, DIF_BPF_COEFF2223, 0xfc32f6e2}, | ||
768 | {6000000, DIF_BPF_COEFF2425, 0xf614fb17}, | ||
769 | {6000000, DIF_BPF_COEFF2627, 0x03d20b87}, | ||
770 | {6000000, DIF_BPF_COEFF2829, 0x0d7707d2}, | ||
771 | {6000000, DIF_BPF_COEFF3031, 0xfd26f341}, | ||
772 | {6000000, DIF_BPF_COEFF3233, 0xefeaf56f}, | ||
773 | {6000000, DIF_BPF_COEFF3435, 0x010f0c64}, | ||
774 | {6000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
775 | /* END - DIF BPF register values from 60_quant.dat*/ | ||
776 | |||
777 | |||
778 | /*case 6100000:*/ | ||
779 | /* BEGIN - DIF BPF register values from 61_quant.dat*/ | ||
780 | {6100000, DIF_BPF_COEFF01, 0xffff0000}, | ||
781 | {6100000, DIF_BPF_COEFF23, 0x00050012}, | ||
782 | {6100000, DIF_BPF_COEFF45, 0x001c000b}, | ||
783 | {6100000, DIF_BPF_COEFF67, 0xffd1ff84}, | ||
784 | {6100000, DIF_BPF_COEFF89, 0xff66ffbe}, | ||
785 | {6100000, DIF_BPF_COEFF1011, 0x00960184}, | ||
786 | {6100000, DIF_BPF_COEFF1213, 0x01cd00da}, | ||
787 | {6100000, DIF_BPF_COEFF1415, 0xfeccfcb2}, | ||
788 | {6100000, DIF_BPF_COEFF1617, 0xfc17fdf9}, | ||
789 | {6100000, DIF_BPF_COEFF1819, 0x01e005bc}, | ||
790 | {6100000, DIF_BPF_COEFF2021, 0x06e703e4}, | ||
791 | {6100000, DIF_BPF_COEFF2223, 0xfdabf798}, | ||
792 | {6100000, DIF_BPF_COEFF2425, 0xf599f9b3}, | ||
793 | {6100000, DIF_BPF_COEFF2627, 0x02510abd}, | ||
794 | {6100000, DIF_BPF_COEFF2829, 0x0dbf08df}, | ||
795 | {6100000, DIF_BPF_COEFF3031, 0xfe48f3dc}, | ||
796 | {6100000, DIF_BPF_COEFF3233, 0xefd5f4f6}, | ||
797 | {6100000, DIF_BPF_COEFF3435, 0x00a20c3e}, | ||
798 | {6100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
799 | /* END - DIF BPF register values from 61_quant.dat*/ | ||
800 | |||
801 | |||
802 | /*case 6200000:*/ | ||
803 | /* BEGIN - DIF BPF register values from 62_quant.dat*/ | ||
804 | {6200000, DIF_BPF_COEFF01, 0xfffffffe}, | ||
805 | {6200000, DIF_BPF_COEFF23, 0x0002000f}, | ||
806 | {6200000, DIF_BPF_COEFF45, 0x0021001f}, | ||
807 | {6200000, DIF_BPF_COEFF67, 0xfff0ff97}, | ||
808 | {6200000, DIF_BPF_COEFF89, 0xff50ff74}, | ||
809 | {6200000, DIF_BPF_COEFF1011, 0x0034014a}, | ||
810 | {6200000, DIF_BPF_COEFF1213, 0x01fa0179}, | ||
811 | {6200000, DIF_BPF_COEFF1415, 0xff97fd2a}, | ||
812 | {6200000, DIF_BPF_COEFF1617, 0xfbd3fcfa}, | ||
813 | {6200000, DIF_BPF_COEFF1819, 0x00a304fe}, | ||
814 | {6200000, DIF_BPF_COEFF2021, 0x07310525}, | ||
815 | {6200000, DIF_BPF_COEFF2223, 0xff37f886}, | ||
816 | {6200000, DIF_BPF_COEFF2425, 0xf55cf86e}, | ||
817 | {6200000, DIF_BPF_COEFF2627, 0x00c709d0}, | ||
818 | {6200000, DIF_BPF_COEFF2829, 0x0de209db}, | ||
819 | {6200000, DIF_BPF_COEFF3031, 0xff6df484}, | ||
820 | {6200000, DIF_BPF_COEFF3233, 0xefcbf481}, | ||
821 | {6200000, DIF_BPF_COEFF3435, 0x00360c18}, | ||
822 | {6200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
823 | /* END - DIF BPF register values from 62_quant.dat*/ | ||
824 | |||
825 | |||
826 | /*case 6300000:*/ | ||
827 | /* BEGIN - DIF BPF register values from 63_quant.dat*/ | ||
828 | {6300000, DIF_BPF_COEFF01, 0xfffffffd}, | ||
829 | {6300000, DIF_BPF_COEFF23, 0xfffe000a}, | ||
830 | {6300000, DIF_BPF_COEFF45, 0x0021002f}, | ||
831 | {6300000, DIF_BPF_COEFF67, 0x0010ffb8}, | ||
832 | {6300000, DIF_BPF_COEFF89, 0xff50ff3b}, | ||
833 | {6300000, DIF_BPF_COEFF1011, 0xffcc00f0}, | ||
834 | {6300000, DIF_BPF_COEFF1213, 0x01fa01fa}, | ||
835 | {6300000, DIF_BPF_COEFF1415, 0x0069fdd4}, | ||
836 | {6300000, DIF_BPF_COEFF1617, 0xfbd3fc26}, | ||
837 | {6300000, DIF_BPF_COEFF1819, 0xff5d0407}, | ||
838 | {6300000, DIF_BPF_COEFF2021, 0x07310638}, | ||
839 | {6300000, DIF_BPF_COEFF2223, 0x00c9f9a8}, | ||
840 | {6300000, DIF_BPF_COEFF2425, 0xf55cf74e}, | ||
841 | {6300000, DIF_BPF_COEFF2627, 0xff3908c3}, | ||
842 | {6300000, DIF_BPF_COEFF2829, 0x0de20ac3}, | ||
843 | {6300000, DIF_BPF_COEFF3031, 0x0093f537}, | ||
844 | {6300000, DIF_BPF_COEFF3233, 0xefcbf410}, | ||
845 | {6300000, DIF_BPF_COEFF3435, 0xffca0bf2}, | ||
846 | {6300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
847 | /* END - DIF BPF register values from 63_quant.dat*/ | ||
848 | |||
849 | |||
850 | /*case 6400000:*/ | ||
851 | /* BEGIN - DIF BPF register values from 64_quant.dat*/ | ||
852 | {6400000, DIF_BPF_COEFF01, 0xfffffffd}, | ||
853 | {6400000, DIF_BPF_COEFF23, 0xfffb0003}, | ||
854 | {6400000, DIF_BPF_COEFF45, 0x001c0037}, | ||
855 | {6400000, DIF_BPF_COEFF67, 0x002fffe2}, | ||
856 | {6400000, DIF_BPF_COEFF89, 0xff66ff17}, | ||
857 | {6400000, DIF_BPF_COEFF1011, 0xff6a007e}, | ||
858 | {6400000, DIF_BPF_COEFF1213, 0x01cd0251}, | ||
859 | {6400000, DIF_BPF_COEFF1415, 0x0134fea5}, | ||
860 | {6400000, DIF_BPF_COEFF1617, 0xfc17fb8b}, | ||
861 | {6400000, DIF_BPF_COEFF1819, 0xfe2002e0}, | ||
862 | {6400000, DIF_BPF_COEFF2021, 0x06e70713}, | ||
863 | {6400000, DIF_BPF_COEFF2223, 0x0255faf5}, | ||
864 | {6400000, DIF_BPF_COEFF2425, 0xf599f658}, | ||
865 | {6400000, DIF_BPF_COEFF2627, 0xfdaf0799}, | ||
866 | {6400000, DIF_BPF_COEFF2829, 0x0dbf0b96}, | ||
867 | {6400000, DIF_BPF_COEFF3031, 0x01b8f5f5}, | ||
868 | {6400000, DIF_BPF_COEFF3233, 0xefd5f3a3}, | ||
869 | {6400000, DIF_BPF_COEFF3435, 0xff5e0bca}, | ||
870 | {6400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
871 | /* END - DIF BPF register values from 64_quant.dat*/ | ||
872 | |||
873 | |||
874 | /*case 6500000:*/ | ||
875 | /* BEGIN - DIF BPF register values from 65_quant.dat*/ | ||
876 | {6500000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
877 | {6500000, DIF_BPF_COEFF23, 0xfff9fffb}, | ||
878 | {6500000, DIF_BPF_COEFF45, 0x00120037}, | ||
879 | {6500000, DIF_BPF_COEFF67, 0x00460010}, | ||
880 | {6500000, DIF_BPF_COEFF89, 0xff8eff0f}, | ||
881 | {6500000, DIF_BPF_COEFF1011, 0xff180000}, | ||
882 | {6500000, DIF_BPF_COEFF1213, 0x01750276}, | ||
883 | {6500000, DIF_BPF_COEFF1415, 0x01e8ff8d}, | ||
884 | {6500000, DIF_BPF_COEFF1617, 0xfc99fb31}, | ||
885 | {6500000, DIF_BPF_COEFF1819, 0xfcfb0198}, | ||
886 | {6500000, DIF_BPF_COEFF2021, 0x065607ad}, | ||
887 | {6500000, DIF_BPF_COEFF2223, 0x03cefc64}, | ||
888 | {6500000, DIF_BPF_COEFF2425, 0xf614f592}, | ||
889 | {6500000, DIF_BPF_COEFF2627, 0xfc2e0656}, | ||
890 | {6500000, DIF_BPF_COEFF2829, 0x0d770c52}, | ||
891 | {6500000, DIF_BPF_COEFF3031, 0x02daf6bd}, | ||
892 | {6500000, DIF_BPF_COEFF3233, 0xefeaf33b}, | ||
893 | {6500000, DIF_BPF_COEFF3435, 0xfef10ba3}, | ||
894 | {6500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
895 | /* END - DIF BPF register values from 65_quant.dat*/ | ||
896 | |||
897 | |||
898 | /*case 6600000:*/ | ||
899 | /* BEGIN - DIF BPF register values from 66_quant.dat*/ | ||
900 | {6600000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
901 | {6600000, DIF_BPF_COEFF23, 0xfff7fff5}, | ||
902 | {6600000, DIF_BPF_COEFF45, 0x0005002f}, | ||
903 | {6600000, DIF_BPF_COEFF67, 0x0054003c}, | ||
904 | {6600000, DIF_BPF_COEFF89, 0xffc5ff22}, | ||
905 | {6600000, DIF_BPF_COEFF1011, 0xfedfff82}, | ||
906 | {6600000, DIF_BPF_COEFF1213, 0x00fc0267}, | ||
907 | {6600000, DIF_BPF_COEFF1415, 0x0276007e}, | ||
908 | {6600000, DIF_BPF_COEFF1617, 0xfd51fb1c}, | ||
909 | {6600000, DIF_BPF_COEFF1819, 0xfbfe003e}, | ||
910 | {6600000, DIF_BPF_COEFF2021, 0x05830802}, | ||
911 | {6600000, DIF_BPF_COEFF2223, 0x0529fdec}, | ||
912 | {6600000, DIF_BPF_COEFF2425, 0xf6c8f4fe}, | ||
913 | {6600000, DIF_BPF_COEFF2627, 0xfabd04ff}, | ||
914 | {6600000, DIF_BPF_COEFF2829, 0x0d0d0cf6}, | ||
915 | {6600000, DIF_BPF_COEFF3031, 0x03f8f78f}, | ||
916 | {6600000, DIF_BPF_COEFF3233, 0xf00af2d7}, | ||
917 | {6600000, DIF_BPF_COEFF3435, 0xfe850b7b}, | ||
918 | {6600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
919 | /* END - DIF BPF register values from 66_quant.dat*/ | ||
920 | |||
921 | |||
922 | /*case 6700000:*/ | ||
923 | /* BEGIN - DIF BPF register values from 67_quant.dat*/ | ||
924 | {6700000, DIF_BPF_COEFF01, 0x0000ffff}, | ||
925 | {6700000, DIF_BPF_COEFF23, 0xfff8fff0}, | ||
926 | {6700000, DIF_BPF_COEFF45, 0xfff80020}, | ||
927 | {6700000, DIF_BPF_COEFF67, 0x00560060}, | ||
928 | {6700000, DIF_BPF_COEFF89, 0x0002ff4e}, | ||
929 | {6700000, DIF_BPF_COEFF1011, 0xfec4ff10}, | ||
930 | {6700000, DIF_BPF_COEFF1213, 0x006d0225}, | ||
931 | {6700000, DIF_BPF_COEFF1415, 0x02d50166}, | ||
932 | {6700000, DIF_BPF_COEFF1617, 0xfe35fb4e}, | ||
933 | {6700000, DIF_BPF_COEFF1819, 0xfb35fee1}, | ||
934 | {6700000, DIF_BPF_COEFF2021, 0x0477080e}, | ||
935 | {6700000, DIF_BPF_COEFF2223, 0x065bff82}, | ||
936 | {6700000, DIF_BPF_COEFF2425, 0xf7b1f4a0}, | ||
937 | {6700000, DIF_BPF_COEFF2627, 0xf9610397}, | ||
938 | {6700000, DIF_BPF_COEFF2829, 0x0c810d80}, | ||
939 | {6700000, DIF_BPF_COEFF3031, 0x0510f869}, | ||
940 | {6700000, DIF_BPF_COEFF3233, 0xf033f278}, | ||
941 | {6700000, DIF_BPF_COEFF3435, 0xfe1a0b52}, | ||
942 | {6700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
943 | /* END - DIF BPF register values from 67_quant.dat*/ | ||
944 | |||
945 | |||
946 | /*case 6800000:*/ | ||
947 | /* BEGIN - DIF BPF register values from 68_quant.dat*/ | ||
948 | {6800000, DIF_BPF_COEFF01, 0x00010000}, | ||
949 | {6800000, DIF_BPF_COEFF23, 0xfffaffee}, | ||
950 | {6800000, DIF_BPF_COEFF45, 0xffec000c}, | ||
951 | {6800000, DIF_BPF_COEFF67, 0x004c0078}, | ||
952 | {6800000, DIF_BPF_COEFF89, 0x0040ff8e}, | ||
953 | {6800000, DIF_BPF_COEFF1011, 0xfecafeb6}, | ||
954 | {6800000, DIF_BPF_COEFF1213, 0xffd301b6}, | ||
955 | {6800000, DIF_BPF_COEFF1415, 0x02fc0235}, | ||
956 | {6800000, DIF_BPF_COEFF1617, 0xff36fbc5}, | ||
957 | {6800000, DIF_BPF_COEFF1819, 0xfaaafd90}, | ||
958 | {6800000, DIF_BPF_COEFF2021, 0x033e07d2}, | ||
959 | {6800000, DIF_BPF_COEFF2223, 0x075b011b}, | ||
960 | {6800000, DIF_BPF_COEFF2425, 0xf8cbf47a}, | ||
961 | {6800000, DIF_BPF_COEFF2627, 0xf81f0224}, | ||
962 | {6800000, DIF_BPF_COEFF2829, 0x0bd50def}, | ||
963 | {6800000, DIF_BPF_COEFF3031, 0x0621f94b}, | ||
964 | {6800000, DIF_BPF_COEFF3233, 0xf067f21e}, | ||
965 | {6800000, DIF_BPF_COEFF3435, 0xfdae0b29}, | ||
966 | {6800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
967 | /* END - DIF BPF register values from 68_quant.dat*/ | ||
968 | |||
969 | |||
970 | /*case 6900000:*/ | ||
971 | /* BEGIN - DIF BPF register values from 69_quant.dat*/ | ||
972 | {6900000, DIF_BPF_COEFF01, 0x00010001}, | ||
973 | {6900000, DIF_BPF_COEFF23, 0xfffdffef}, | ||
974 | {6900000, DIF_BPF_COEFF45, 0xffe3fff6}, | ||
975 | {6900000, DIF_BPF_COEFF67, 0x0037007f}, | ||
976 | {6900000, DIF_BPF_COEFF89, 0x0075ffdc}, | ||
977 | {6900000, DIF_BPF_COEFF1011, 0xfef2fe7c}, | ||
978 | {6900000, DIF_BPF_COEFF1213, 0xff3d0122}, | ||
979 | {6900000, DIF_BPF_COEFF1415, 0x02ea02dd}, | ||
980 | {6900000, DIF_BPF_COEFF1617, 0x0044fc79}, | ||
981 | {6900000, DIF_BPF_COEFF1819, 0xfa65fc5d}, | ||
982 | {6900000, DIF_BPF_COEFF2021, 0x01e3074e}, | ||
983 | {6900000, DIF_BPF_COEFF2223, 0x082102ad}, | ||
984 | {6900000, DIF_BPF_COEFF2425, 0xfa0ff48c}, | ||
985 | {6900000, DIF_BPF_COEFF2627, 0xf6fe00a9}, | ||
986 | {6900000, DIF_BPF_COEFF2829, 0x0b0a0e43}, | ||
987 | {6900000, DIF_BPF_COEFF3031, 0x0729fa33}, | ||
988 | {6900000, DIF_BPF_COEFF3233, 0xf0a5f1c9}, | ||
989 | {6900000, DIF_BPF_COEFF3435, 0xfd430b00}, | ||
990 | {6900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
991 | /* END - DIF BPF register values from 69_quant.dat*/ | ||
992 | |||
993 | |||
994 | /*case 7000000:*/ | ||
995 | /* BEGIN - DIF BPF register values from 70_quant.dat*/ | ||
996 | {7000000, DIF_BPF_COEFF01, 0x00010002}, | ||
997 | {7000000, DIF_BPF_COEFF23, 0x0001fff3}, | ||
998 | {7000000, DIF_BPF_COEFF45, 0xffdeffe2}, | ||
999 | {7000000, DIF_BPF_COEFF67, 0x001b0076}, | ||
1000 | {7000000, DIF_BPF_COEFF89, 0x009c002d}, | ||
1001 | {7000000, DIF_BPF_COEFF1011, 0xff35fe68}, | ||
1002 | {7000000, DIF_BPF_COEFF1213, 0xfeba0076}, | ||
1003 | {7000000, DIF_BPF_COEFF1415, 0x029f0352}, | ||
1004 | {7000000, DIF_BPF_COEFF1617, 0x014dfd60}, | ||
1005 | {7000000, DIF_BPF_COEFF1819, 0xfa69fb53}, | ||
1006 | {7000000, DIF_BPF_COEFF2021, 0x00740688}, | ||
1007 | {7000000, DIF_BPF_COEFF2223, 0x08a7042d}, | ||
1008 | {7000000, DIF_BPF_COEFF2425, 0xfb75f4d6}, | ||
1009 | {7000000, DIF_BPF_COEFF2627, 0xf600ff2d}, | ||
1010 | {7000000, DIF_BPF_COEFF2829, 0x0a220e7a}, | ||
1011 | {7000000, DIF_BPF_COEFF3031, 0x0827fb22}, | ||
1012 | {7000000, DIF_BPF_COEFF3233, 0xf0edf17a}, | ||
1013 | {7000000, DIF_BPF_COEFF3435, 0xfcd80ad6}, | ||
1014 | {7000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1015 | /* END - DIF BPF register values from 70_quant.dat*/ | ||
1016 | |||
1017 | |||
1018 | /*case 7100000:*/ | ||
1019 | /* BEGIN - DIF BPF register values from 71_quant.dat*/ | ||
1020 | {7100000, DIF_BPF_COEFF01, 0x00000003}, | ||
1021 | {7100000, DIF_BPF_COEFF23, 0x0004fff9}, | ||
1022 | {7100000, DIF_BPF_COEFF45, 0xffe0ffd2}, | ||
1023 | {7100000, DIF_BPF_COEFF67, 0xfffb005e}, | ||
1024 | {7100000, DIF_BPF_COEFF89, 0x00b0007a}, | ||
1025 | {7100000, DIF_BPF_COEFF1011, 0xff8ffe7c}, | ||
1026 | {7100000, DIF_BPF_COEFF1213, 0xfe53ffc1}, | ||
1027 | {7100000, DIF_BPF_COEFF1415, 0x0221038c}, | ||
1028 | {7100000, DIF_BPF_COEFF1617, 0x0241fe6e}, | ||
1029 | {7100000, DIF_BPF_COEFF1819, 0xfab6fa80}, | ||
1030 | {7100000, DIF_BPF_COEFF2021, 0xff010587}, | ||
1031 | {7100000, DIF_BPF_COEFF2223, 0x08e90590}, | ||
1032 | {7100000, DIF_BPF_COEFF2425, 0xfcf5f556}, | ||
1033 | {7100000, DIF_BPF_COEFF2627, 0xf52bfdb3}, | ||
1034 | {7100000, DIF_BPF_COEFF2829, 0x09210e95}, | ||
1035 | {7100000, DIF_BPF_COEFF3031, 0x0919fc15}, | ||
1036 | {7100000, DIF_BPF_COEFF3233, 0xf13ff12f}, | ||
1037 | {7100000, DIF_BPF_COEFF3435, 0xfc6e0aab}, | ||
1038 | {7100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1039 | /* END - DIF BPF register values from 71_quant.dat*/ | ||
1040 | |||
1041 | |||
1042 | /*case 7200000:*/ | ||
1043 | /* BEGIN - DIF BPF register values from 72_quant.dat*/ | ||
1044 | {7200000, DIF_BPF_COEFF01, 0x00000003}, | ||
1045 | {7200000, DIF_BPF_COEFF23, 0x00070000}, | ||
1046 | {7200000, DIF_BPF_COEFF45, 0xffe6ffc9}, | ||
1047 | {7200000, DIF_BPF_COEFF67, 0xffdb0039}, | ||
1048 | {7200000, DIF_BPF_COEFF89, 0x00af00b8}, | ||
1049 | {7200000, DIF_BPF_COEFF1011, 0xfff4feb6}, | ||
1050 | {7200000, DIF_BPF_COEFF1213, 0xfe13ff10}, | ||
1051 | {7200000, DIF_BPF_COEFF1415, 0x01790388}, | ||
1052 | {7200000, DIF_BPF_COEFF1617, 0x0311ff92}, | ||
1053 | {7200000, DIF_BPF_COEFF1819, 0xfb48f9ed}, | ||
1054 | {7200000, DIF_BPF_COEFF2021, 0xfd980453}, | ||
1055 | {7200000, DIF_BPF_COEFF2223, 0x08e306cd}, | ||
1056 | {7200000, DIF_BPF_COEFF2425, 0xfe88f60a}, | ||
1057 | {7200000, DIF_BPF_COEFF2627, 0xf482fc40}, | ||
1058 | {7200000, DIF_BPF_COEFF2829, 0x08080e93}, | ||
1059 | {7200000, DIF_BPF_COEFF3031, 0x09fdfd0c}, | ||
1060 | {7200000, DIF_BPF_COEFF3233, 0xf19af0ea}, | ||
1061 | {7200000, DIF_BPF_COEFF3435, 0xfc050a81}, | ||
1062 | {7200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1063 | /* END - DIF BPF register values from 72_quant.dat*/ | ||
1064 | |||
1065 | |||
1066 | /*case 7300000:*/ | ||
1067 | /* BEGIN - DIF BPF register values from 73_quant.dat*/ | ||
1068 | {7300000, DIF_BPF_COEFF01, 0x00000002}, | ||
1069 | {7300000, DIF_BPF_COEFF23, 0x00080008}, | ||
1070 | {7300000, DIF_BPF_COEFF45, 0xfff0ffc9}, | ||
1071 | {7300000, DIF_BPF_COEFF67, 0xffc1000d}, | ||
1072 | {7300000, DIF_BPF_COEFF89, 0x009800e2}, | ||
1073 | {7300000, DIF_BPF_COEFF1011, 0x005bff10}, | ||
1074 | {7300000, DIF_BPF_COEFF1213, 0xfe00fe74}, | ||
1075 | {7300000, DIF_BPF_COEFF1415, 0x00b50345}, | ||
1076 | {7300000, DIF_BPF_COEFF1617, 0x03b000bc}, | ||
1077 | {7300000, DIF_BPF_COEFF1819, 0xfc18f9a1}, | ||
1078 | {7300000, DIF_BPF_COEFF2021, 0xfc4802f9}, | ||
1079 | {7300000, DIF_BPF_COEFF2223, 0x089807dc}, | ||
1080 | {7300000, DIF_BPF_COEFF2425, 0x0022f6f0}, | ||
1081 | {7300000, DIF_BPF_COEFF2627, 0xf407fada}, | ||
1082 | {7300000, DIF_BPF_COEFF2829, 0x06da0e74}, | ||
1083 | {7300000, DIF_BPF_COEFF3031, 0x0ad3fe06}, | ||
1084 | {7300000, DIF_BPF_COEFF3233, 0xf1fef0ab}, | ||
1085 | {7300000, DIF_BPF_COEFF3435, 0xfb9c0a55}, | ||
1086 | {7300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1087 | /* END - DIF BPF register values from 73_quant.dat*/ | ||
1088 | |||
1089 | |||
1090 | /*case 7400000:*/ | ||
1091 | /* BEGIN - DIF BPF register values from 74_quant.dat*/ | ||
1092 | {7400000, DIF_BPF_COEFF01, 0x00000001}, | ||
1093 | {7400000, DIF_BPF_COEFF23, 0x0008000e}, | ||
1094 | {7400000, DIF_BPF_COEFF45, 0xfffdffd0}, | ||
1095 | {7400000, DIF_BPF_COEFF67, 0xffafffdf}, | ||
1096 | {7400000, DIF_BPF_COEFF89, 0x006e00f2}, | ||
1097 | {7400000, DIF_BPF_COEFF1011, 0x00b8ff82}, | ||
1098 | {7400000, DIF_BPF_COEFF1213, 0xfe1bfdf8}, | ||
1099 | {7400000, DIF_BPF_COEFF1415, 0xffe302c8}, | ||
1100 | {7400000, DIF_BPF_COEFF1617, 0x041301dc}, | ||
1101 | {7400000, DIF_BPF_COEFF1819, 0xfd1af99e}, | ||
1102 | {7400000, DIF_BPF_COEFF2021, 0xfb1e0183}, | ||
1103 | {7400000, DIF_BPF_COEFF2223, 0x080908b5}, | ||
1104 | {7400000, DIF_BPF_COEFF2425, 0x01bcf801}, | ||
1105 | {7400000, DIF_BPF_COEFF2627, 0xf3bdf985}, | ||
1106 | {7400000, DIF_BPF_COEFF2829, 0x059a0e38}, | ||
1107 | {7400000, DIF_BPF_COEFF3031, 0x0b99ff03}, | ||
1108 | {7400000, DIF_BPF_COEFF3233, 0xf26cf071}, | ||
1109 | {7400000, DIF_BPF_COEFF3435, 0xfb330a2a}, | ||
1110 | {7400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1111 | /* END - DIF BPF register values from 74_quant.dat*/ | ||
1112 | |||
1113 | |||
1114 | /*case 7500000:*/ | ||
1115 | /* BEGIN - DIF BPF register values from 75_quant.dat*/ | ||
1116 | {7500000, DIF_BPF_COEFF01, 0xffff0000}, | ||
1117 | {7500000, DIF_BPF_COEFF23, 0x00070011}, | ||
1118 | {7500000, DIF_BPF_COEFF45, 0x000affdf}, | ||
1119 | {7500000, DIF_BPF_COEFF67, 0xffa9ffb5}, | ||
1120 | {7500000, DIF_BPF_COEFF89, 0x003700e6}, | ||
1121 | {7500000, DIF_BPF_COEFF1011, 0x01010000}, | ||
1122 | {7500000, DIF_BPF_COEFF1213, 0xfe62fda8}, | ||
1123 | {7500000, DIF_BPF_COEFF1415, 0xff140219}, | ||
1124 | {7500000, DIF_BPF_COEFF1617, 0x043502e1}, | ||
1125 | {7500000, DIF_BPF_COEFF1819, 0xfe42f9e6}, | ||
1126 | {7500000, DIF_BPF_COEFF2021, 0xfa270000}, | ||
1127 | {7500000, DIF_BPF_COEFF2223, 0x073a0953}, | ||
1128 | {7500000, DIF_BPF_COEFF2425, 0x034cf939}, | ||
1129 | {7500000, DIF_BPF_COEFF2627, 0xf3a4f845}, | ||
1130 | {7500000, DIF_BPF_COEFF2829, 0x044c0de1}, | ||
1131 | {7500000, DIF_BPF_COEFF3031, 0x0c4f0000}, | ||
1132 | {7500000, DIF_BPF_COEFF3233, 0xf2e2f03c}, | ||
1133 | {7500000, DIF_BPF_COEFF3435, 0xfacc09fe}, | ||
1134 | {7500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1135 | /* END - DIF BPF register values from 75_quant.dat*/ | ||
1136 | |||
1137 | |||
1138 | /*case 7600000:*/ | ||
1139 | /* BEGIN - DIF BPF register values from 76_quant.dat*/ | ||
1140 | {7600000, DIF_BPF_COEFF01, 0xffffffff}, | ||
1141 | {7600000, DIF_BPF_COEFF23, 0x00040012}, | ||
1142 | {7600000, DIF_BPF_COEFF45, 0x0016fff3}, | ||
1143 | {7600000, DIF_BPF_COEFF67, 0xffafff95}, | ||
1144 | {7600000, DIF_BPF_COEFF89, 0xfff900c0}, | ||
1145 | {7600000, DIF_BPF_COEFF1011, 0x0130007e}, | ||
1146 | {7600000, DIF_BPF_COEFF1213, 0xfecefd89}, | ||
1147 | {7600000, DIF_BPF_COEFF1415, 0xfe560146}, | ||
1148 | {7600000, DIF_BPF_COEFF1617, 0x041303bc}, | ||
1149 | {7600000, DIF_BPF_COEFF1819, 0xff81fa76}, | ||
1150 | {7600000, DIF_BPF_COEFF2021, 0xf96cfe7d}, | ||
1151 | {7600000, DIF_BPF_COEFF2223, 0x063209b1}, | ||
1152 | {7600000, DIF_BPF_COEFF2425, 0x04c9fa93}, | ||
1153 | {7600000, DIF_BPF_COEFF2627, 0xf3bdf71e}, | ||
1154 | {7600000, DIF_BPF_COEFF2829, 0x02f30d6e}, | ||
1155 | {7600000, DIF_BPF_COEFF3031, 0x0cf200fd}, | ||
1156 | {7600000, DIF_BPF_COEFF3233, 0xf361f00e}, | ||
1157 | {7600000, DIF_BPF_COEFF3435, 0xfa6509d1}, | ||
1158 | {7600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1159 | /* END - DIF BPF register values from 76_quant.dat*/ | ||
1160 | |||
1161 | |||
1162 | /*case 7700000:*/ | ||
1163 | /* BEGIN - DIF BPF register values from 77_quant.dat*/ | ||
1164 | {7700000, DIF_BPF_COEFF01, 0xfffffffe}, | ||
1165 | {7700000, DIF_BPF_COEFF23, 0x00010010}, | ||
1166 | {7700000, DIF_BPF_COEFF45, 0x001e0008}, | ||
1167 | {7700000, DIF_BPF_COEFF67, 0xffc1ff84}, | ||
1168 | {7700000, DIF_BPF_COEFF89, 0xffbc0084}, | ||
1169 | {7700000, DIF_BPF_COEFF1011, 0x013e00f0}, | ||
1170 | {7700000, DIF_BPF_COEFF1213, 0xff56fd9f}, | ||
1171 | {7700000, DIF_BPF_COEFF1415, 0xfdb8005c}, | ||
1172 | {7700000, DIF_BPF_COEFF1617, 0x03b00460}, | ||
1173 | {7700000, DIF_BPF_COEFF1819, 0x00c7fb45}, | ||
1174 | {7700000, DIF_BPF_COEFF2021, 0xf8f4fd07}, | ||
1175 | {7700000, DIF_BPF_COEFF2223, 0x04fa09ce}, | ||
1176 | {7700000, DIF_BPF_COEFF2425, 0x062afc07}, | ||
1177 | {7700000, DIF_BPF_COEFF2627, 0xf407f614}, | ||
1178 | {7700000, DIF_BPF_COEFF2829, 0x01920ce0}, | ||
1179 | {7700000, DIF_BPF_COEFF3031, 0x0d8301fa}, | ||
1180 | {7700000, DIF_BPF_COEFF3233, 0xf3e8efe5}, | ||
1181 | {7700000, DIF_BPF_COEFF3435, 0xfa0009a4}, | ||
1182 | {7700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1183 | /* END - DIF BPF register values from 77_quant.dat*/ | ||
1184 | |||
1185 | |||
1186 | /*case 7800000:*/ | ||
1187 | /* BEGIN - DIF BPF register values from 78_quant.dat*/ | ||
1188 | {7800000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1189 | {7800000, DIF_BPF_COEFF23, 0xfffd000b}, | ||
1190 | {7800000, DIF_BPF_COEFF45, 0x0022001d}, | ||
1191 | {7800000, DIF_BPF_COEFF67, 0xffdbff82}, | ||
1192 | {7800000, DIF_BPF_COEFF89, 0xff870039}, | ||
1193 | {7800000, DIF_BPF_COEFF1011, 0x012a014a}, | ||
1194 | {7800000, DIF_BPF_COEFF1213, 0xffedfde7}, | ||
1195 | {7800000, DIF_BPF_COEFF1415, 0xfd47ff6b}, | ||
1196 | {7800000, DIF_BPF_COEFF1617, 0x031104c6}, | ||
1197 | {7800000, DIF_BPF_COEFF1819, 0x0202fc4c}, | ||
1198 | {7800000, DIF_BPF_COEFF2021, 0xf8c6fbad}, | ||
1199 | {7800000, DIF_BPF_COEFF2223, 0x039909a7}, | ||
1200 | {7800000, DIF_BPF_COEFF2425, 0x0767fd8e}, | ||
1201 | {7800000, DIF_BPF_COEFF2627, 0xf482f52b}, | ||
1202 | {7800000, DIF_BPF_COEFF2829, 0x002d0c39}, | ||
1203 | {7800000, DIF_BPF_COEFF3031, 0x0e0002f4}, | ||
1204 | {7800000, DIF_BPF_COEFF3233, 0xf477efc2}, | ||
1205 | {7800000, DIF_BPF_COEFF3435, 0xf99b0977}, | ||
1206 | {7800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1207 | /* END - DIF BPF register values from 78_quant.dat*/ | ||
1208 | |||
1209 | |||
1210 | /*case 7900000:*/ | ||
1211 | /* BEGIN - DIF BPF register values from 79_quant.dat*/ | ||
1212 | {7900000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1213 | {7900000, DIF_BPF_COEFF23, 0xfffa0004}, | ||
1214 | {7900000, DIF_BPF_COEFF45, 0x0020002d}, | ||
1215 | {7900000, DIF_BPF_COEFF67, 0xfffbff91}, | ||
1216 | {7900000, DIF_BPF_COEFF89, 0xff61ffe8}, | ||
1217 | {7900000, DIF_BPF_COEFF1011, 0x00f70184}, | ||
1218 | {7900000, DIF_BPF_COEFF1213, 0x0086fe5c}, | ||
1219 | {7900000, DIF_BPF_COEFF1415, 0xfd0bfe85}, | ||
1220 | {7900000, DIF_BPF_COEFF1617, 0x024104e5}, | ||
1221 | {7900000, DIF_BPF_COEFF1819, 0x0323fd7d}, | ||
1222 | {7900000, DIF_BPF_COEFF2021, 0xf8e2fa79}, | ||
1223 | {7900000, DIF_BPF_COEFF2223, 0x021d093f}, | ||
1224 | {7900000, DIF_BPF_COEFF2425, 0x0879ff22}, | ||
1225 | {7900000, DIF_BPF_COEFF2627, 0xf52bf465}, | ||
1226 | {7900000, DIF_BPF_COEFF2829, 0xfec70b79}, | ||
1227 | {7900000, DIF_BPF_COEFF3031, 0x0e6803eb}, | ||
1228 | {7900000, DIF_BPF_COEFF3233, 0xf50defa5}, | ||
1229 | {7900000, DIF_BPF_COEFF3435, 0xf937094a}, | ||
1230 | {7900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1231 | /* END - DIF BPF register values from 79_quant.dat*/ | ||
1232 | |||
1233 | |||
1234 | /*case 8000000:*/ | ||
1235 | /* BEGIN - DIF BPF register values from 80_quant.dat*/ | ||
1236 | {8000000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
1237 | {8000000, DIF_BPF_COEFF23, 0xfff8fffd}, | ||
1238 | {8000000, DIF_BPF_COEFF45, 0x00190036}, | ||
1239 | {8000000, DIF_BPF_COEFF67, 0x001bffaf}, | ||
1240 | {8000000, DIF_BPF_COEFF89, 0xff4fff99}, | ||
1241 | {8000000, DIF_BPF_COEFF1011, 0x00aa0198}, | ||
1242 | {8000000, DIF_BPF_COEFF1213, 0x0112fef3}, | ||
1243 | {8000000, DIF_BPF_COEFF1415, 0xfd09fdb9}, | ||
1244 | {8000000, DIF_BPF_COEFF1617, 0x014d04be}, | ||
1245 | {8000000, DIF_BPF_COEFF1819, 0x041bfecc}, | ||
1246 | {8000000, DIF_BPF_COEFF2021, 0xf947f978}, | ||
1247 | {8000000, DIF_BPF_COEFF2223, 0x00900897}, | ||
1248 | {8000000, DIF_BPF_COEFF2425, 0x095a00b9}, | ||
1249 | {8000000, DIF_BPF_COEFF2627, 0xf600f3c5}, | ||
1250 | {8000000, DIF_BPF_COEFF2829, 0xfd650aa3}, | ||
1251 | {8000000, DIF_BPF_COEFF3031, 0x0ebc04de}, | ||
1252 | {8000000, DIF_BPF_COEFF3233, 0xf5aaef8e}, | ||
1253 | {8000000, DIF_BPF_COEFF3435, 0xf8d5091c}, | ||
1254 | {8000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1255 | /* END - DIF BPF register values from 80_quant.dat*/ | ||
1256 | |||
1257 | |||
1258 | /*case 8100000:*/ | ||
1259 | /* BEGIN - DIF BPF register values from 81_quant.dat*/ | ||
1260 | {8100000, DIF_BPF_COEFF01, 0x0000ffff}, | ||
1261 | {8100000, DIF_BPF_COEFF23, 0xfff7fff6}, | ||
1262 | {8100000, DIF_BPF_COEFF45, 0x000e0038}, | ||
1263 | {8100000, DIF_BPF_COEFF67, 0x0037ffd7}, | ||
1264 | {8100000, DIF_BPF_COEFF89, 0xff52ff56}, | ||
1265 | {8100000, DIF_BPF_COEFF1011, 0x004b0184}, | ||
1266 | {8100000, DIF_BPF_COEFF1213, 0x0186ffa1}, | ||
1267 | {8100000, DIF_BPF_COEFF1415, 0xfd40fd16}, | ||
1268 | {8100000, DIF_BPF_COEFF1617, 0x00440452}, | ||
1269 | {8100000, DIF_BPF_COEFF1819, 0x04de0029}, | ||
1270 | {8100000, DIF_BPF_COEFF2021, 0xf9f2f8b2}, | ||
1271 | {8100000, DIF_BPF_COEFF2223, 0xfefe07b5}, | ||
1272 | {8100000, DIF_BPF_COEFF2425, 0x0a05024d}, | ||
1273 | {8100000, DIF_BPF_COEFF2627, 0xf6fef34d}, | ||
1274 | {8100000, DIF_BPF_COEFF2829, 0xfc0a09b8}, | ||
1275 | {8100000, DIF_BPF_COEFF3031, 0x0efa05cd}, | ||
1276 | {8100000, DIF_BPF_COEFF3233, 0xf64eef7d}, | ||
1277 | {8100000, DIF_BPF_COEFF3435, 0xf87308ed}, | ||
1278 | {8100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1279 | /* END - DIF BPF register values from 81_quant.dat*/ | ||
1280 | |||
1281 | |||
1282 | /*case 8200000:*/ | ||
1283 | /* BEGIN - DIF BPF register values from 82_quant.dat*/ | ||
1284 | {8200000, DIF_BPF_COEFF01, 0x00010000}, | ||
1285 | {8200000, DIF_BPF_COEFF23, 0xfff8fff0}, | ||
1286 | {8200000, DIF_BPF_COEFF45, 0x00000031}, | ||
1287 | {8200000, DIF_BPF_COEFF67, 0x004c0005}, | ||
1288 | {8200000, DIF_BPF_COEFF89, 0xff6aff27}, | ||
1289 | {8200000, DIF_BPF_COEFF1011, 0xffe4014a}, | ||
1290 | {8200000, DIF_BPF_COEFF1213, 0x01d70057}, | ||
1291 | {8200000, DIF_BPF_COEFF1415, 0xfdacfca6}, | ||
1292 | {8200000, DIF_BPF_COEFF1617, 0xff3603a7}, | ||
1293 | {8200000, DIF_BPF_COEFF1819, 0x05610184}, | ||
1294 | {8200000, DIF_BPF_COEFF2021, 0xfadbf82e}, | ||
1295 | {8200000, DIF_BPF_COEFF2223, 0xfd74069f}, | ||
1296 | {8200000, DIF_BPF_COEFF2425, 0x0a7503d6}, | ||
1297 | {8200000, DIF_BPF_COEFF2627, 0xf81ff2ff}, | ||
1298 | {8200000, DIF_BPF_COEFF2829, 0xfab808b9}, | ||
1299 | {8200000, DIF_BPF_COEFF3031, 0x0f2306b5}, | ||
1300 | {8200000, DIF_BPF_COEFF3233, 0xf6f9ef72}, | ||
1301 | {8200000, DIF_BPF_COEFF3435, 0xf81308bf}, | ||
1302 | {8200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1303 | /* END - DIF BPF register values from 82_quant.dat*/ | ||
1304 | |||
1305 | |||
1306 | /*case 8300000:*/ | ||
1307 | /* BEGIN - DIF BPF register values from 83_quant.dat*/ | ||
1308 | {8300000, DIF_BPF_COEFF01, 0x00010001}, | ||
1309 | {8300000, DIF_BPF_COEFF23, 0xfffbffee}, | ||
1310 | {8300000, DIF_BPF_COEFF45, 0xfff30022}, | ||
1311 | {8300000, DIF_BPF_COEFF67, 0x00560032}, | ||
1312 | {8300000, DIF_BPF_COEFF89, 0xff95ff10}, | ||
1313 | {8300000, DIF_BPF_COEFF1011, 0xff8000f0}, | ||
1314 | {8300000, DIF_BPF_COEFF1213, 0x01fe0106}, | ||
1315 | {8300000, DIF_BPF_COEFF1415, 0xfe46fc71}, | ||
1316 | {8300000, DIF_BPF_COEFF1617, 0xfe3502c7}, | ||
1317 | {8300000, DIF_BPF_COEFF1819, 0x059e02ce}, | ||
1318 | {8300000, DIF_BPF_COEFF2021, 0xfbf9f7f2}, | ||
1319 | {8300000, DIF_BPF_COEFF2223, 0xfbff055b}, | ||
1320 | {8300000, DIF_BPF_COEFF2425, 0x0aa9054c}, | ||
1321 | {8300000, DIF_BPF_COEFF2627, 0xf961f2db}, | ||
1322 | {8300000, DIF_BPF_COEFF2829, 0xf97507aa}, | ||
1323 | {8300000, DIF_BPF_COEFF3031, 0x0f350797}, | ||
1324 | {8300000, DIF_BPF_COEFF3233, 0xf7a9ef6d}, | ||
1325 | {8300000, DIF_BPF_COEFF3435, 0xf7b40890}, | ||
1326 | {8300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1327 | /* END - DIF BPF register values from 83_quant.dat*/ | ||
1328 | |||
1329 | |||
1330 | /*case 8400000:*/ | ||
1331 | /* BEGIN - DIF BPF register values from 84_quant.dat*/ | ||
1332 | {8400000, DIF_BPF_COEFF01, 0x00010002}, | ||
1333 | {8400000, DIF_BPF_COEFF23, 0xfffeffee}, | ||
1334 | {8400000, DIF_BPF_COEFF45, 0xffe8000f}, | ||
1335 | {8400000, DIF_BPF_COEFF67, 0x00540058}, | ||
1336 | {8400000, DIF_BPF_COEFF89, 0xffcdff14}, | ||
1337 | {8400000, DIF_BPF_COEFF1011, 0xff29007e}, | ||
1338 | {8400000, DIF_BPF_COEFF1213, 0x01f6019e}, | ||
1339 | {8400000, DIF_BPF_COEFF1415, 0xff01fc7c}, | ||
1340 | {8400000, DIF_BPF_COEFF1617, 0xfd5101bf}, | ||
1341 | {8400000, DIF_BPF_COEFF1819, 0x059203f6}, | ||
1342 | {8400000, DIF_BPF_COEFF2021, 0xfd41f7fe}, | ||
1343 | {8400000, DIF_BPF_COEFF2223, 0xfaa903f3}, | ||
1344 | {8400000, DIF_BPF_COEFF2425, 0x0a9e06a9}, | ||
1345 | {8400000, DIF_BPF_COEFF2627, 0xfabdf2e2}, | ||
1346 | {8400000, DIF_BPF_COEFF2829, 0xf842068b}, | ||
1347 | {8400000, DIF_BPF_COEFF3031, 0x0f320871}, | ||
1348 | {8400000, DIF_BPF_COEFF3233, 0xf85eef6e}, | ||
1349 | {8400000, DIF_BPF_COEFF3435, 0xf7560860}, | ||
1350 | {8400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1351 | /* END - DIF BPF register values from 84_quant.dat*/ | ||
1352 | |||
1353 | |||
1354 | /*case 8500000:*/ | ||
1355 | /* BEGIN - DIF BPF register values from 85_quant.dat*/ | ||
1356 | {8500000, DIF_BPF_COEFF01, 0x00000003}, | ||
1357 | {8500000, DIF_BPF_COEFF23, 0x0002fff2}, | ||
1358 | {8500000, DIF_BPF_COEFF45, 0xffe1fff9}, | ||
1359 | {8500000, DIF_BPF_COEFF67, 0x00460073}, | ||
1360 | {8500000, DIF_BPF_COEFF89, 0x000bff34}, | ||
1361 | {8500000, DIF_BPF_COEFF1011, 0xfee90000}, | ||
1362 | {8500000, DIF_BPF_COEFF1213, 0x01c10215}, | ||
1363 | {8500000, DIF_BPF_COEFF1415, 0xffd0fcc5}, | ||
1364 | {8500000, DIF_BPF_COEFF1617, 0xfc99009d}, | ||
1365 | {8500000, DIF_BPF_COEFF1819, 0x053d04f1}, | ||
1366 | {8500000, DIF_BPF_COEFF2021, 0xfea5f853}, | ||
1367 | {8500000, DIF_BPF_COEFF2223, 0xf97d0270}, | ||
1368 | {8500000, DIF_BPF_COEFF2425, 0x0a5607e4}, | ||
1369 | {8500000, DIF_BPF_COEFF2627, 0xfc2ef314}, | ||
1370 | {8500000, DIF_BPF_COEFF2829, 0xf723055f}, | ||
1371 | {8500000, DIF_BPF_COEFF3031, 0x0f180943}, | ||
1372 | {8500000, DIF_BPF_COEFF3233, 0xf919ef75}, | ||
1373 | {8500000, DIF_BPF_COEFF3435, 0xf6fa0830}, | ||
1374 | {8500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1375 | /* END - DIF BPF register values from 85_quant.dat*/ | ||
1376 | |||
1377 | |||
1378 | /*case 8600000:*/ | ||
1379 | /* BEGIN - DIF BPF register values from 86_quant.dat*/ | ||
1380 | {8600000, DIF_BPF_COEFF01, 0x00000003}, | ||
1381 | {8600000, DIF_BPF_COEFF23, 0x0005fff8}, | ||
1382 | {8600000, DIF_BPF_COEFF45, 0xffdeffe4}, | ||
1383 | {8600000, DIF_BPF_COEFF67, 0x002f007f}, | ||
1384 | {8600000, DIF_BPF_COEFF89, 0x0048ff6b}, | ||
1385 | {8600000, DIF_BPF_COEFF1011, 0xfec7ff82}, | ||
1386 | {8600000, DIF_BPF_COEFF1213, 0x0163025f}, | ||
1387 | {8600000, DIF_BPF_COEFF1415, 0x00a2fd47}, | ||
1388 | {8600000, DIF_BPF_COEFF1617, 0xfc17ff73}, | ||
1389 | {8600000, DIF_BPF_COEFF1819, 0x04a405b2}, | ||
1390 | {8600000, DIF_BPF_COEFF2021, 0x0017f8ed}, | ||
1391 | {8600000, DIF_BPF_COEFF2223, 0xf88500dc}, | ||
1392 | {8600000, DIF_BPF_COEFF2425, 0x09d208f9}, | ||
1393 | {8600000, DIF_BPF_COEFF2627, 0xfdaff370}, | ||
1394 | {8600000, DIF_BPF_COEFF2829, 0xf61c0429}, | ||
1395 | {8600000, DIF_BPF_COEFF3031, 0x0ee80a0b}, | ||
1396 | {8600000, DIF_BPF_COEFF3233, 0xf9d8ef82}, | ||
1397 | {8600000, DIF_BPF_COEFF3435, 0xf6a00800}, | ||
1398 | {8600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1399 | /* END - DIF BPF register values from 86_quant.dat*/ | ||
1400 | |||
1401 | |||
1402 | /*case 8700000:*/ | ||
1403 | /* BEGIN - DIF BPF register values from 87_quant.dat*/ | ||
1404 | {8700000, DIF_BPF_COEFF01, 0x00000003}, | ||
1405 | {8700000, DIF_BPF_COEFF23, 0x0007ffff}, | ||
1406 | {8700000, DIF_BPF_COEFF45, 0xffe1ffd4}, | ||
1407 | {8700000, DIF_BPF_COEFF67, 0x0010007a}, | ||
1408 | {8700000, DIF_BPF_COEFF89, 0x007cffb2}, | ||
1409 | {8700000, DIF_BPF_COEFF1011, 0xfec6ff10}, | ||
1410 | {8700000, DIF_BPF_COEFF1213, 0x00e60277}, | ||
1411 | {8700000, DIF_BPF_COEFF1415, 0x0168fdf9}, | ||
1412 | {8700000, DIF_BPF_COEFF1617, 0xfbd3fe50}, | ||
1413 | {8700000, DIF_BPF_COEFF1819, 0x03ce0631}, | ||
1414 | {8700000, DIF_BPF_COEFF2021, 0x0188f9c8}, | ||
1415 | {8700000, DIF_BPF_COEFF2223, 0xf7c7ff43}, | ||
1416 | {8700000, DIF_BPF_COEFF2425, 0x091509e3}, | ||
1417 | {8700000, DIF_BPF_COEFF2627, 0xff39f3f6}, | ||
1418 | {8700000, DIF_BPF_COEFF2829, 0xf52d02ea}, | ||
1419 | {8700000, DIF_BPF_COEFF3031, 0x0ea30ac9}, | ||
1420 | {8700000, DIF_BPF_COEFF3233, 0xfa9bef95}, | ||
1421 | {8700000, DIF_BPF_COEFF3435, 0xf64607d0}, | ||
1422 | {8700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1423 | /* END - DIF BPF register values from 87_quant.dat*/ | ||
1424 | |||
1425 | |||
1426 | /*case 8800000:*/ | ||
1427 | /* BEGIN - DIF BPF register values from 88_quant.dat*/ | ||
1428 | {8800000, DIF_BPF_COEFF01, 0x00000002}, | ||
1429 | {8800000, DIF_BPF_COEFF23, 0x00090007}, | ||
1430 | {8800000, DIF_BPF_COEFF45, 0xffe9ffca}, | ||
1431 | {8800000, DIF_BPF_COEFF67, 0xfff00065}, | ||
1432 | {8800000, DIF_BPF_COEFF89, 0x00a10003}, | ||
1433 | {8800000, DIF_BPF_COEFF1011, 0xfee6feb6}, | ||
1434 | {8800000, DIF_BPF_COEFF1213, 0x0053025b}, | ||
1435 | {8800000, DIF_BPF_COEFF1415, 0x0213fed0}, | ||
1436 | {8800000, DIF_BPF_COEFF1617, 0xfbd3fd46}, | ||
1437 | {8800000, DIF_BPF_COEFF1819, 0x02c70668}, | ||
1438 | {8800000, DIF_BPF_COEFF2021, 0x02eafadb}, | ||
1439 | {8800000, DIF_BPF_COEFF2223, 0xf74bfdae}, | ||
1440 | {8800000, DIF_BPF_COEFF2425, 0x08230a9c}, | ||
1441 | {8800000, DIF_BPF_COEFF2627, 0x00c7f4a3}, | ||
1442 | {8800000, DIF_BPF_COEFF2829, 0xf45b01a6}, | ||
1443 | {8800000, DIF_BPF_COEFF3031, 0x0e480b7c}, | ||
1444 | {8800000, DIF_BPF_COEFF3233, 0xfb61efae}, | ||
1445 | {8800000, DIF_BPF_COEFF3435, 0xf5ef079f}, | ||
1446 | {8800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1447 | /* END - DIF BPF register values from 88_quant.dat*/ | ||
1448 | |||
1449 | |||
1450 | /*case 8900000:*/ | ||
1451 | /* BEGIN - DIF BPF register values from 89_quant.dat*/ | ||
1452 | {8900000, DIF_BPF_COEFF01, 0xffff0000}, | ||
1453 | {8900000, DIF_BPF_COEFF23, 0x0008000d}, | ||
1454 | {8900000, DIF_BPF_COEFF45, 0xfff5ffc8}, | ||
1455 | {8900000, DIF_BPF_COEFF67, 0xffd10043}, | ||
1456 | {8900000, DIF_BPF_COEFF89, 0x00b20053}, | ||
1457 | {8900000, DIF_BPF_COEFF1011, 0xff24fe7c}, | ||
1458 | {8900000, DIF_BPF_COEFF1213, 0xffb9020c}, | ||
1459 | {8900000, DIF_BPF_COEFF1415, 0x0295ffbb}, | ||
1460 | {8900000, DIF_BPF_COEFF1617, 0xfc17fc64}, | ||
1461 | {8900000, DIF_BPF_COEFF1819, 0x019b0654}, | ||
1462 | {8900000, DIF_BPF_COEFF2021, 0x042dfc1c}, | ||
1463 | {8900000, DIF_BPF_COEFF2223, 0xf714fc2a}, | ||
1464 | {8900000, DIF_BPF_COEFF2425, 0x07020b21}, | ||
1465 | {8900000, DIF_BPF_COEFF2627, 0x0251f575}, | ||
1466 | {8900000, DIF_BPF_COEFF2829, 0xf3a7005e}, | ||
1467 | {8900000, DIF_BPF_COEFF3031, 0x0dd80c24}, | ||
1468 | {8900000, DIF_BPF_COEFF3233, 0xfc2aefcd}, | ||
1469 | {8900000, DIF_BPF_COEFF3435, 0xf599076e}, | ||
1470 | {8900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1471 | /* END - DIF BPF register values from 89_quant.dat*/ | ||
1472 | |||
1473 | |||
1474 | /*case 9000000:*/ | ||
1475 | /* BEGIN - DIF BPF register values from 90_quant.dat*/ | ||
1476 | {9000000, DIF_BPF_COEFF01, 0xffffffff}, | ||
1477 | {9000000, DIF_BPF_COEFF23, 0x00060011}, | ||
1478 | {9000000, DIF_BPF_COEFF45, 0x0002ffcf}, | ||
1479 | {9000000, DIF_BPF_COEFF67, 0xffba0018}, | ||
1480 | {9000000, DIF_BPF_COEFF89, 0x00ad009a}, | ||
1481 | {9000000, DIF_BPF_COEFF1011, 0xff79fe68}, | ||
1482 | {9000000, DIF_BPF_COEFF1213, 0xff260192}, | ||
1483 | {9000000, DIF_BPF_COEFF1415, 0x02e500ab}, | ||
1484 | {9000000, DIF_BPF_COEFF1617, 0xfc99fbb6}, | ||
1485 | {9000000, DIF_BPF_COEFF1819, 0x005b05f7}, | ||
1486 | {9000000, DIF_BPF_COEFF2021, 0x0545fd81}, | ||
1487 | {9000000, DIF_BPF_COEFF2223, 0xf723fabf}, | ||
1488 | {9000000, DIF_BPF_COEFF2425, 0x05b80b70}, | ||
1489 | {9000000, DIF_BPF_COEFF2627, 0x03d2f669}, | ||
1490 | {9000000, DIF_BPF_COEFF2829, 0xf313ff15}, | ||
1491 | {9000000, DIF_BPF_COEFF3031, 0x0d550cbf}, | ||
1492 | {9000000, DIF_BPF_COEFF3233, 0xfcf6eff2}, | ||
1493 | {9000000, DIF_BPF_COEFF3435, 0xf544073d}, | ||
1494 | {9000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1495 | /* END - DIF BPF register values from 90_quant.dat*/ | ||
1496 | |||
1497 | |||
1498 | /*case 9100000:*/ | ||
1499 | /* BEGIN - DIF BPF register values from 91_quant.dat*/ | ||
1500 | {9100000, DIF_BPF_COEFF01, 0xfffffffe}, | ||
1501 | {9100000, DIF_BPF_COEFF23, 0x00030012}, | ||
1502 | {9100000, DIF_BPF_COEFF45, 0x000fffdd}, | ||
1503 | {9100000, DIF_BPF_COEFF67, 0xffacffea}, | ||
1504 | {9100000, DIF_BPF_COEFF89, 0x009300cf}, | ||
1505 | {9100000, DIF_BPF_COEFF1011, 0xffdcfe7c}, | ||
1506 | {9100000, DIF_BPF_COEFF1213, 0xfea600f7}, | ||
1507 | {9100000, DIF_BPF_COEFF1415, 0x02fd0190}, | ||
1508 | {9100000, DIF_BPF_COEFF1617, 0xfd51fb46}, | ||
1509 | {9100000, DIF_BPF_COEFF1819, 0xff150554}, | ||
1510 | {9100000, DIF_BPF_COEFF2021, 0x0627fefd}, | ||
1511 | {9100000, DIF_BPF_COEFF2223, 0xf778f978}, | ||
1512 | {9100000, DIF_BPF_COEFF2425, 0x044d0b87}, | ||
1513 | {9100000, DIF_BPF_COEFF2627, 0x0543f77d}, | ||
1514 | {9100000, DIF_BPF_COEFF2829, 0xf2a0fdcf}, | ||
1515 | {9100000, DIF_BPF_COEFF3031, 0x0cbe0d4e}, | ||
1516 | {9100000, DIF_BPF_COEFF3233, 0xfdc4f01d}, | ||
1517 | {9100000, DIF_BPF_COEFF3435, 0xf4f2070b}, | ||
1518 | {9100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1519 | /* END - DIF BPF register values from 91_quant.dat*/ | ||
1520 | |||
1521 | |||
1522 | /*case 9200000:*/ | ||
1523 | /* BEGIN - DIF BPF register values from 92_quant.dat*/ | ||
1524 | {9200000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1525 | {9200000, DIF_BPF_COEFF23, 0x00000010}, | ||
1526 | {9200000, DIF_BPF_COEFF45, 0x001afff0}, | ||
1527 | {9200000, DIF_BPF_COEFF67, 0xffaaffbf}, | ||
1528 | {9200000, DIF_BPF_COEFF89, 0x006700ed}, | ||
1529 | {9200000, DIF_BPF_COEFF1011, 0x0043feb6}, | ||
1530 | {9200000, DIF_BPF_COEFF1213, 0xfe460047}, | ||
1531 | {9200000, DIF_BPF_COEFF1415, 0x02db0258}, | ||
1532 | {9200000, DIF_BPF_COEFF1617, 0xfe35fb1b}, | ||
1533 | {9200000, DIF_BPF_COEFF1819, 0xfddc0473}, | ||
1534 | {9200000, DIF_BPF_COEFF2021, 0x06c90082}, | ||
1535 | {9200000, DIF_BPF_COEFF2223, 0xf811f85e}, | ||
1536 | {9200000, DIF_BPF_COEFF2425, 0x02c90b66}, | ||
1537 | {9200000, DIF_BPF_COEFF2627, 0x069ff8ad}, | ||
1538 | {9200000, DIF_BPF_COEFF2829, 0xf250fc8d}, | ||
1539 | {9200000, DIF_BPF_COEFF3031, 0x0c140dcf}, | ||
1540 | {9200000, DIF_BPF_COEFF3233, 0xfe93f04d}, | ||
1541 | {9200000, DIF_BPF_COEFF3435, 0xf4a106d9}, | ||
1542 | {9200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1543 | /* END - DIF BPF register values from 92_quant.dat*/ | ||
1544 | |||
1545 | |||
1546 | /*case 9300000:*/ | ||
1547 | /* BEGIN - DIF BPF register values from 93_quant.dat*/ | ||
1548 | {9300000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1549 | {9300000, DIF_BPF_COEFF23, 0xfffc000c}, | ||
1550 | {9300000, DIF_BPF_COEFF45, 0x00200006}, | ||
1551 | {9300000, DIF_BPF_COEFF67, 0xffb4ff9c}, | ||
1552 | {9300000, DIF_BPF_COEFF89, 0x002f00ef}, | ||
1553 | {9300000, DIF_BPF_COEFF1011, 0x00a4ff10}, | ||
1554 | {9300000, DIF_BPF_COEFF1213, 0xfe0dff92}, | ||
1555 | {9300000, DIF_BPF_COEFF1415, 0x028102f7}, | ||
1556 | {9300000, DIF_BPF_COEFF1617, 0xff36fb37}, | ||
1557 | {9300000, DIF_BPF_COEFF1819, 0xfcbf035e}, | ||
1558 | {9300000, DIF_BPF_COEFF2021, 0x07260202}, | ||
1559 | {9300000, DIF_BPF_COEFF2223, 0xf8e8f778}, | ||
1560 | {9300000, DIF_BPF_COEFF2425, 0x01340b0d}, | ||
1561 | {9300000, DIF_BPF_COEFF2627, 0x07e1f9f4}, | ||
1562 | {9300000, DIF_BPF_COEFF2829, 0xf223fb51}, | ||
1563 | {9300000, DIF_BPF_COEFF3031, 0x0b590e42}, | ||
1564 | {9300000, DIF_BPF_COEFF3233, 0xff64f083}, | ||
1565 | {9300000, DIF_BPF_COEFF3435, 0xf45206a7}, | ||
1566 | {9300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1567 | /* END - DIF BPF register values from 93_quant.dat*/ | ||
1568 | |||
1569 | |||
1570 | /*case 9400000:*/ | ||
1571 | /* BEGIN - DIF BPF register values from 94_quant.dat*/ | ||
1572 | {9400000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1573 | {9400000, DIF_BPF_COEFF23, 0xfff90005}, | ||
1574 | {9400000, DIF_BPF_COEFF45, 0x0022001a}, | ||
1575 | {9400000, DIF_BPF_COEFF67, 0xffc9ff86}, | ||
1576 | {9400000, DIF_BPF_COEFF89, 0xfff000d7}, | ||
1577 | {9400000, DIF_BPF_COEFF1011, 0x00f2ff82}, | ||
1578 | {9400000, DIF_BPF_COEFF1213, 0xfe01fee5}, | ||
1579 | {9400000, DIF_BPF_COEFF1415, 0x01f60362}, | ||
1580 | {9400000, DIF_BPF_COEFF1617, 0x0044fb99}, | ||
1581 | {9400000, DIF_BPF_COEFF1819, 0xfbcc0222}, | ||
1582 | {9400000, DIF_BPF_COEFF2021, 0x07380370}, | ||
1583 | {9400000, DIF_BPF_COEFF2223, 0xf9f7f6cc}, | ||
1584 | {9400000, DIF_BPF_COEFF2425, 0xff990a7e}, | ||
1585 | {9400000, DIF_BPF_COEFF2627, 0x0902fb50}, | ||
1586 | {9400000, DIF_BPF_COEFF2829, 0xf21afa1f}, | ||
1587 | {9400000, DIF_BPF_COEFF3031, 0x0a8d0ea6}, | ||
1588 | {9400000, DIF_BPF_COEFF3233, 0x0034f0bf}, | ||
1589 | {9400000, DIF_BPF_COEFF3435, 0xf4050675}, | ||
1590 | {9400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1591 | /* END - DIF BPF register values from 94_quant.dat*/ | ||
1592 | |||
1593 | |||
1594 | /*case 9500000:*/ | ||
1595 | /* BEGIN - DIF BPF register values from 95_quant.dat*/ | ||
1596 | {9500000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
1597 | {9500000, DIF_BPF_COEFF23, 0xfff8fffe}, | ||
1598 | {9500000, DIF_BPF_COEFF45, 0x001e002b}, | ||
1599 | {9500000, DIF_BPF_COEFF67, 0xffe5ff81}, | ||
1600 | {9500000, DIF_BPF_COEFF89, 0xffb400a5}, | ||
1601 | {9500000, DIF_BPF_COEFF1011, 0x01280000}, | ||
1602 | {9500000, DIF_BPF_COEFF1213, 0xfe24fe50}, | ||
1603 | {9500000, DIF_BPF_COEFF1415, 0x01460390}, | ||
1604 | {9500000, DIF_BPF_COEFF1617, 0x014dfc3a}, | ||
1605 | {9500000, DIF_BPF_COEFF1819, 0xfb1000ce}, | ||
1606 | {9500000, DIF_BPF_COEFF2021, 0x070104bf}, | ||
1607 | {9500000, DIF_BPF_COEFF2223, 0xfb37f65f}, | ||
1608 | {9500000, DIF_BPF_COEFF2425, 0xfe0009bc}, | ||
1609 | {9500000, DIF_BPF_COEFF2627, 0x0a00fcbb}, | ||
1610 | {9500000, DIF_BPF_COEFF2829, 0xf235f8f8}, | ||
1611 | {9500000, DIF_BPF_COEFF3031, 0x09b20efc}, | ||
1612 | {9500000, DIF_BPF_COEFF3233, 0x0105f101}, | ||
1613 | {9500000, DIF_BPF_COEFF3435, 0xf3ba0642}, | ||
1614 | {9500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1615 | /* END - DIF BPF register values from 95_quant.dat*/ | ||
1616 | |||
1617 | |||
1618 | /*case 9600000:*/ | ||
1619 | /* BEGIN - DIF BPF register values from 96_quant.dat*/ | ||
1620 | {9600000, DIF_BPF_COEFF01, 0x0001ffff}, | ||
1621 | {9600000, DIF_BPF_COEFF23, 0xfff8fff7}, | ||
1622 | {9600000, DIF_BPF_COEFF45, 0x00150036}, | ||
1623 | {9600000, DIF_BPF_COEFF67, 0x0005ff8c}, | ||
1624 | {9600000, DIF_BPF_COEFF89, 0xff810061}, | ||
1625 | {9600000, DIF_BPF_COEFF1011, 0x013d007e}, | ||
1626 | {9600000, DIF_BPF_COEFF1213, 0xfe71fddf}, | ||
1627 | {9600000, DIF_BPF_COEFF1415, 0x007c0380}, | ||
1628 | {9600000, DIF_BPF_COEFF1617, 0x0241fd13}, | ||
1629 | {9600000, DIF_BPF_COEFF1819, 0xfa94ff70}, | ||
1630 | {9600000, DIF_BPF_COEFF2021, 0x068005e2}, | ||
1631 | {9600000, DIF_BPF_COEFF2223, 0xfc9bf633}, | ||
1632 | {9600000, DIF_BPF_COEFF2425, 0xfc7308ca}, | ||
1633 | {9600000, DIF_BPF_COEFF2627, 0x0ad5fe30}, | ||
1634 | {9600000, DIF_BPF_COEFF2829, 0xf274f7e0}, | ||
1635 | {9600000, DIF_BPF_COEFF3031, 0x08c90f43}, | ||
1636 | {9600000, DIF_BPF_COEFF3233, 0x01d4f147}, | ||
1637 | {9600000, DIF_BPF_COEFF3435, 0xf371060f}, | ||
1638 | {9600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1639 | /* END - DIF BPF register values from 96_quant.dat*/ | ||
1640 | |||
1641 | |||
1642 | /*case 9700000:*/ | ||
1643 | /* BEGIN - DIF BPF register values from 97_quant.dat*/ | ||
1644 | {9700000, DIF_BPF_COEFF01, 0x00010001}, | ||
1645 | {9700000, DIF_BPF_COEFF23, 0xfff9fff1}, | ||
1646 | {9700000, DIF_BPF_COEFF45, 0x00090038}, | ||
1647 | {9700000, DIF_BPF_COEFF67, 0x0025ffa7}, | ||
1648 | {9700000, DIF_BPF_COEFF89, 0xff5e0012}, | ||
1649 | {9700000, DIF_BPF_COEFF1011, 0x013200f0}, | ||
1650 | {9700000, DIF_BPF_COEFF1213, 0xfee3fd9b}, | ||
1651 | {9700000, DIF_BPF_COEFF1415, 0xffaa0331}, | ||
1652 | {9700000, DIF_BPF_COEFF1617, 0x0311fe15}, | ||
1653 | {9700000, DIF_BPF_COEFF1819, 0xfa60fe18}, | ||
1654 | {9700000, DIF_BPF_COEFF2021, 0x05bd06d1}, | ||
1655 | {9700000, DIF_BPF_COEFF2223, 0xfe1bf64a}, | ||
1656 | {9700000, DIF_BPF_COEFF2425, 0xfafa07ae}, | ||
1657 | {9700000, DIF_BPF_COEFF2627, 0x0b7effab}, | ||
1658 | {9700000, DIF_BPF_COEFF2829, 0xf2d5f6d7}, | ||
1659 | {9700000, DIF_BPF_COEFF3031, 0x07d30f7a}, | ||
1660 | {9700000, DIF_BPF_COEFF3233, 0x02a3f194}, | ||
1661 | {9700000, DIF_BPF_COEFF3435, 0xf32905dc}, | ||
1662 | {9700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1663 | /* END - DIF BPF register values from 97_quant.dat*/ | ||
1664 | |||
1665 | |||
1666 | /*case 9800000:*/ | ||
1667 | /* BEGIN - DIF BPF register values from 98_quant.dat*/ | ||
1668 | {9800000, DIF_BPF_COEFF01, 0x00010002}, | ||
1669 | {9800000, DIF_BPF_COEFF23, 0xfffcffee}, | ||
1670 | {9800000, DIF_BPF_COEFF45, 0xfffb0032}, | ||
1671 | {9800000, DIF_BPF_COEFF67, 0x003fffcd}, | ||
1672 | {9800000, DIF_BPF_COEFF89, 0xff4effc1}, | ||
1673 | {9800000, DIF_BPF_COEFF1011, 0x0106014a}, | ||
1674 | {9800000, DIF_BPF_COEFF1213, 0xff6efd8a}, | ||
1675 | {9800000, DIF_BPF_COEFF1415, 0xfedd02aa}, | ||
1676 | {9800000, DIF_BPF_COEFF1617, 0x03b0ff34}, | ||
1677 | {9800000, DIF_BPF_COEFF1819, 0xfa74fcd7}, | ||
1678 | {9800000, DIF_BPF_COEFF2021, 0x04bf0781}, | ||
1679 | {9800000, DIF_BPF_COEFF2223, 0xffaaf6a3}, | ||
1680 | {9800000, DIF_BPF_COEFF2425, 0xf99e066b}, | ||
1681 | {9800000, DIF_BPF_COEFF2627, 0x0bf90128}, | ||
1682 | {9800000, DIF_BPF_COEFF2829, 0xf359f5e1}, | ||
1683 | {9800000, DIF_BPF_COEFF3031, 0x06d20fa2}, | ||
1684 | {9800000, DIF_BPF_COEFF3233, 0x0370f1e5}, | ||
1685 | {9800000, DIF_BPF_COEFF3435, 0xf2e405a8}, | ||
1686 | {9800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1687 | /* END - DIF BPF register values from 98_quant.dat*/ | ||
1688 | |||
1689 | |||
1690 | /*case 9900000:*/ | ||
1691 | /* BEGIN - DIF BPF register values from 99_quant.dat*/ | ||
1692 | {9900000, DIF_BPF_COEFF01, 0x00000003}, | ||
1693 | {9900000, DIF_BPF_COEFF23, 0xffffffee}, | ||
1694 | {9900000, DIF_BPF_COEFF45, 0xffef0024}, | ||
1695 | {9900000, DIF_BPF_COEFF67, 0x0051fffa}, | ||
1696 | {9900000, DIF_BPF_COEFF89, 0xff54ff77}, | ||
1697 | {9900000, DIF_BPF_COEFF1011, 0x00be0184}, | ||
1698 | {9900000, DIF_BPF_COEFF1213, 0x0006fdad}, | ||
1699 | {9900000, DIF_BPF_COEFF1415, 0xfe2701f3}, | ||
1700 | {9900000, DIF_BPF_COEFF1617, 0x0413005e}, | ||
1701 | {9900000, DIF_BPF_COEFF1819, 0xfad1fbba}, | ||
1702 | {9900000, DIF_BPF_COEFF2021, 0x039007ee}, | ||
1703 | {9900000, DIF_BPF_COEFF2223, 0x013bf73d}, | ||
1704 | {9900000, DIF_BPF_COEFF2425, 0xf868050a}, | ||
1705 | {9900000, DIF_BPF_COEFF2627, 0x0c4302a1}, | ||
1706 | {9900000, DIF_BPF_COEFF2829, 0xf3fdf4fe}, | ||
1707 | {9900000, DIF_BPF_COEFF3031, 0x05c70fba}, | ||
1708 | {9900000, DIF_BPF_COEFF3233, 0x043bf23c}, | ||
1709 | {9900000, DIF_BPF_COEFF3435, 0xf2a10575}, | ||
1710 | {9900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1711 | /* END - DIF BPF register values from 99_quant.dat*/ | ||
1712 | |||
1713 | |||
1714 | /*case 10000000:*/ | ||
1715 | /* BEGIN - DIF BPF register values from 100_quant.dat*/ | ||
1716 | {10000000, DIF_BPF_COEFF01, 0x00000003}, | ||
1717 | {10000000, DIF_BPF_COEFF23, 0x0003fff1}, | ||
1718 | {10000000, DIF_BPF_COEFF45, 0xffe50011}, | ||
1719 | {10000000, DIF_BPF_COEFF67, 0x00570027}, | ||
1720 | {10000000, DIF_BPF_COEFF89, 0xff70ff3c}, | ||
1721 | {10000000, DIF_BPF_COEFF1011, 0x00620198}, | ||
1722 | {10000000, DIF_BPF_COEFF1213, 0x009efe01}, | ||
1723 | {10000000, DIF_BPF_COEFF1415, 0xfd95011a}, | ||
1724 | {10000000, DIF_BPF_COEFF1617, 0x04350183}, | ||
1725 | {10000000, DIF_BPF_COEFF1819, 0xfb71fad0}, | ||
1726 | {10000000, DIF_BPF_COEFF2021, 0x023c0812}, | ||
1727 | {10000000, DIF_BPF_COEFF2223, 0x02c3f811}, | ||
1728 | {10000000, DIF_BPF_COEFF2425, 0xf75e0390}, | ||
1729 | {10000000, DIF_BPF_COEFF2627, 0x0c5c0411}, | ||
1730 | {10000000, DIF_BPF_COEFF2829, 0xf4c1f432}, | ||
1731 | {10000000, DIF_BPF_COEFF3031, 0x04b30fc1}, | ||
1732 | {10000000, DIF_BPF_COEFF3233, 0x0503f297}, | ||
1733 | {10000000, DIF_BPF_COEFF3435, 0xf2610541}, | ||
1734 | {10000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1735 | /* END - DIF BPF register values from 100_quant.dat*/ | ||
1736 | |||
1737 | |||
1738 | /*case 10100000:*/ | ||
1739 | /* BEGIN - DIF BPF register values from 101_quant.dat*/ | ||
1740 | {10100000, DIF_BPF_COEFF01, 0x00000003}, | ||
1741 | {10100000, DIF_BPF_COEFF23, 0x0006fff7}, | ||
1742 | {10100000, DIF_BPF_COEFF45, 0xffdffffc}, | ||
1743 | {10100000, DIF_BPF_COEFF67, 0x00510050}, | ||
1744 | {10100000, DIF_BPF_COEFF89, 0xff9dff18}, | ||
1745 | {10100000, DIF_BPF_COEFF1011, 0xfffc0184}, | ||
1746 | {10100000, DIF_BPF_COEFF1213, 0x0128fe80}, | ||
1747 | {10100000, DIF_BPF_COEFF1415, 0xfd32002e}, | ||
1748 | {10100000, DIF_BPF_COEFF1617, 0x04130292}, | ||
1749 | {10100000, DIF_BPF_COEFF1819, 0xfc4dfa21}, | ||
1750 | {10100000, DIF_BPF_COEFF2021, 0x00d107ee}, | ||
1751 | {10100000, DIF_BPF_COEFF2223, 0x0435f91c}, | ||
1752 | {10100000, DIF_BPF_COEFF2425, 0xf6850205}, | ||
1753 | {10100000, DIF_BPF_COEFF2627, 0x0c430573}, | ||
1754 | {10100000, DIF_BPF_COEFF2829, 0xf5a1f37d}, | ||
1755 | {10100000, DIF_BPF_COEFF3031, 0x03990fba}, | ||
1756 | {10100000, DIF_BPF_COEFF3233, 0x05c7f2f8}, | ||
1757 | {10100000, DIF_BPF_COEFF3435, 0xf222050d}, | ||
1758 | {10100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1759 | /* END - DIF BPF register values from 101_quant.dat*/ | ||
1760 | |||
1761 | |||
1762 | /*case 10200000:*/ | ||
1763 | /* BEGIN - DIF BPF register values from 102_quant.dat*/ | ||
1764 | {10200000, DIF_BPF_COEFF01, 0x00000002}, | ||
1765 | {10200000, DIF_BPF_COEFF23, 0x0008fffe}, | ||
1766 | {10200000, DIF_BPF_COEFF45, 0xffdfffe7}, | ||
1767 | {10200000, DIF_BPF_COEFF67, 0x003f006e}, | ||
1768 | {10200000, DIF_BPF_COEFF89, 0xffd6ff0f}, | ||
1769 | {10200000, DIF_BPF_COEFF1011, 0xff96014a}, | ||
1770 | {10200000, DIF_BPF_COEFF1213, 0x0197ff1f}, | ||
1771 | {10200000, DIF_BPF_COEFF1415, 0xfd05ff3e}, | ||
1772 | {10200000, DIF_BPF_COEFF1617, 0x03b0037c}, | ||
1773 | {10200000, DIF_BPF_COEFF1819, 0xfd59f9b7}, | ||
1774 | {10200000, DIF_BPF_COEFF2021, 0xff5d0781}, | ||
1775 | {10200000, DIF_BPF_COEFF2223, 0x0585fa56}, | ||
1776 | {10200000, DIF_BPF_COEFF2425, 0xf5e4006f}, | ||
1777 | {10200000, DIF_BPF_COEFF2627, 0x0bf906c4}, | ||
1778 | {10200000, DIF_BPF_COEFF2829, 0xf69df2e0}, | ||
1779 | {10200000, DIF_BPF_COEFF3031, 0x02790fa2}, | ||
1780 | {10200000, DIF_BPF_COEFF3233, 0x0688f35d}, | ||
1781 | {10200000, DIF_BPF_COEFF3435, 0xf1e604d8}, | ||
1782 | {10200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1783 | /* END - DIF BPF register values from 102_quant.dat*/ | ||
1784 | |||
1785 | |||
1786 | /*case 10300000:*/ | ||
1787 | /* BEGIN - DIF BPF register values from 103_quant.dat*/ | ||
1788 | {10300000, DIF_BPF_COEFF01, 0xffff0001}, | ||
1789 | {10300000, DIF_BPF_COEFF23, 0x00090005}, | ||
1790 | {10300000, DIF_BPF_COEFF45, 0xffe4ffd6}, | ||
1791 | {10300000, DIF_BPF_COEFF67, 0x0025007e}, | ||
1792 | {10300000, DIF_BPF_COEFF89, 0x0014ff20}, | ||
1793 | {10300000, DIF_BPF_COEFF1011, 0xff3c00f0}, | ||
1794 | {10300000, DIF_BPF_COEFF1213, 0x01e1ffd0}, | ||
1795 | {10300000, DIF_BPF_COEFF1415, 0xfd12fe5c}, | ||
1796 | {10300000, DIF_BPF_COEFF1617, 0x03110433}, | ||
1797 | {10300000, DIF_BPF_COEFF1819, 0xfe88f996}, | ||
1798 | {10300000, DIF_BPF_COEFF2021, 0xfdf106d1}, | ||
1799 | {10300000, DIF_BPF_COEFF2223, 0x06aafbb7}, | ||
1800 | {10300000, DIF_BPF_COEFF2425, 0xf57efed8}, | ||
1801 | {10300000, DIF_BPF_COEFF2627, 0x0b7e07ff}, | ||
1802 | {10300000, DIF_BPF_COEFF2829, 0xf7b0f25e}, | ||
1803 | {10300000, DIF_BPF_COEFF3031, 0x01560f7a}, | ||
1804 | {10300000, DIF_BPF_COEFF3233, 0x0745f3c7}, | ||
1805 | {10300000, DIF_BPF_COEFF3435, 0xf1ac04a4}, | ||
1806 | {10300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1807 | /* END - DIF BPF register values from 103_quant.dat*/ | ||
1808 | |||
1809 | |||
1810 | /*case 10400000:*/ | ||
1811 | /* BEGIN - DIF BPF register values from 104_quant.dat*/ | ||
1812 | {10400000, DIF_BPF_COEFF01, 0xffffffff}, | ||
1813 | {10400000, DIF_BPF_COEFF23, 0x0008000c}, | ||
1814 | {10400000, DIF_BPF_COEFF45, 0xffedffcb}, | ||
1815 | {10400000, DIF_BPF_COEFF67, 0x0005007d}, | ||
1816 | {10400000, DIF_BPF_COEFF89, 0x0050ff4c}, | ||
1817 | {10400000, DIF_BPF_COEFF1011, 0xfef6007e}, | ||
1818 | {10400000, DIF_BPF_COEFF1213, 0x01ff0086}, | ||
1819 | {10400000, DIF_BPF_COEFF1415, 0xfd58fd97}, | ||
1820 | {10400000, DIF_BPF_COEFF1617, 0x024104ad}, | ||
1821 | {10400000, DIF_BPF_COEFF1819, 0xffcaf9c0}, | ||
1822 | {10400000, DIF_BPF_COEFF2021, 0xfc9905e2}, | ||
1823 | {10400000, DIF_BPF_COEFF2223, 0x079afd35}, | ||
1824 | {10400000, DIF_BPF_COEFF2425, 0xf555fd46}, | ||
1825 | {10400000, DIF_BPF_COEFF2627, 0x0ad50920}, | ||
1826 | {10400000, DIF_BPF_COEFF2829, 0xf8d9f1f6}, | ||
1827 | {10400000, DIF_BPF_COEFF3031, 0x00310f43}, | ||
1828 | {10400000, DIF_BPF_COEFF3233, 0x07fdf435}, | ||
1829 | {10400000, DIF_BPF_COEFF3435, 0xf174046f}, | ||
1830 | {10400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1831 | /* END - DIF BPF register values from 104_quant.dat*/ | ||
1832 | |||
1833 | |||
1834 | /*case 10500000:*/ | ||
1835 | /* BEGIN - DIF BPF register values from 105_quant.dat*/ | ||
1836 | {10500000, DIF_BPF_COEFF01, 0xfffffffe}, | ||
1837 | {10500000, DIF_BPF_COEFF23, 0x00050011}, | ||
1838 | {10500000, DIF_BPF_COEFF45, 0xfffaffc8}, | ||
1839 | {10500000, DIF_BPF_COEFF67, 0xffe5006b}, | ||
1840 | {10500000, DIF_BPF_COEFF89, 0x0082ff8c}, | ||
1841 | {10500000, DIF_BPF_COEFF1011, 0xfecc0000}, | ||
1842 | {10500000, DIF_BPF_COEFF1213, 0x01f00130}, | ||
1843 | {10500000, DIF_BPF_COEFF1415, 0xfdd2fcfc}, | ||
1844 | {10500000, DIF_BPF_COEFF1617, 0x014d04e3}, | ||
1845 | {10500000, DIF_BPF_COEFF1819, 0x010efa32}, | ||
1846 | {10500000, DIF_BPF_COEFF2021, 0xfb6404bf}, | ||
1847 | {10500000, DIF_BPF_COEFF2223, 0x084efec5}, | ||
1848 | {10500000, DIF_BPF_COEFF2425, 0xf569fbc2}, | ||
1849 | {10500000, DIF_BPF_COEFF2627, 0x0a000a23}, | ||
1850 | {10500000, DIF_BPF_COEFF2829, 0xfa15f1ab}, | ||
1851 | {10500000, DIF_BPF_COEFF3031, 0xff0b0efc}, | ||
1852 | {10500000, DIF_BPF_COEFF3233, 0x08b0f4a7}, | ||
1853 | {10500000, DIF_BPF_COEFF3435, 0xf13f043a}, | ||
1854 | {10500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1855 | /* END - DIF BPF register values from 105_quant.dat*/ | ||
1856 | |||
1857 | |||
1858 | /*case 10600000:*/ | ||
1859 | /* BEGIN - DIF BPF register values from 106_quant.dat*/ | ||
1860 | {10600000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1861 | {10600000, DIF_BPF_COEFF23, 0x00020012}, | ||
1862 | {10600000, DIF_BPF_COEFF45, 0x0007ffcd}, | ||
1863 | {10600000, DIF_BPF_COEFF67, 0xffc9004c}, | ||
1864 | {10600000, DIF_BPF_COEFF89, 0x00a4ffd9}, | ||
1865 | {10600000, DIF_BPF_COEFF1011, 0xfec3ff82}, | ||
1866 | {10600000, DIF_BPF_COEFF1213, 0x01b401c1}, | ||
1867 | {10600000, DIF_BPF_COEFF1415, 0xfe76fc97}, | ||
1868 | {10600000, DIF_BPF_COEFF1617, 0x004404d2}, | ||
1869 | {10600000, DIF_BPF_COEFF1819, 0x0245fae8}, | ||
1870 | {10600000, DIF_BPF_COEFF2021, 0xfa5f0370}, | ||
1871 | {10600000, DIF_BPF_COEFF2223, 0x08c1005f}, | ||
1872 | {10600000, DIF_BPF_COEFF2425, 0xf5bcfa52}, | ||
1873 | {10600000, DIF_BPF_COEFF2627, 0x09020b04}, | ||
1874 | {10600000, DIF_BPF_COEFF2829, 0xfb60f17b}, | ||
1875 | {10600000, DIF_BPF_COEFF3031, 0xfde70ea6}, | ||
1876 | {10600000, DIF_BPF_COEFF3233, 0x095df51e}, | ||
1877 | {10600000, DIF_BPF_COEFF3435, 0xf10c0405}, | ||
1878 | {10600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1879 | /* END - DIF BPF register values from 106_quant.dat*/ | ||
1880 | |||
1881 | |||
1882 | /*case 10700000:*/ | ||
1883 | /* BEGIN - DIF BPF register values from 107_quant.dat*/ | ||
1884 | {10700000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1885 | {10700000, DIF_BPF_COEFF23, 0xffff0011}, | ||
1886 | {10700000, DIF_BPF_COEFF45, 0x0014ffdb}, | ||
1887 | {10700000, DIF_BPF_COEFF67, 0xffb40023}, | ||
1888 | {10700000, DIF_BPF_COEFF89, 0x00b2002a}, | ||
1889 | {10700000, DIF_BPF_COEFF1011, 0xfedbff10}, | ||
1890 | {10700000, DIF_BPF_COEFF1213, 0x0150022d}, | ||
1891 | {10700000, DIF_BPF_COEFF1415, 0xff38fc6f}, | ||
1892 | {10700000, DIF_BPF_COEFF1617, 0xff36047b}, | ||
1893 | {10700000, DIF_BPF_COEFF1819, 0x035efbda}, | ||
1894 | {10700000, DIF_BPF_COEFF2021, 0xf9940202}, | ||
1895 | {10700000, DIF_BPF_COEFF2223, 0x08ee01f5}, | ||
1896 | {10700000, DIF_BPF_COEFF2425, 0xf649f8fe}, | ||
1897 | {10700000, DIF_BPF_COEFF2627, 0x07e10bc2}, | ||
1898 | {10700000, DIF_BPF_COEFF2829, 0xfcb6f169}, | ||
1899 | {10700000, DIF_BPF_COEFF3031, 0xfcc60e42}, | ||
1900 | {10700000, DIF_BPF_COEFF3233, 0x0a04f599}, | ||
1901 | {10700000, DIF_BPF_COEFF3435, 0xf0db03d0}, | ||
1902 | {10700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1903 | /* END - DIF BPF register values from 107_quant.dat*/ | ||
1904 | |||
1905 | |||
1906 | /*case 10800000:*/ | ||
1907 | /* BEGIN - DIF BPF register values from 108_quant.dat*/ | ||
1908 | {10800000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
1909 | {10800000, DIF_BPF_COEFF23, 0xfffb000d}, | ||
1910 | {10800000, DIF_BPF_COEFF45, 0x001dffed}, | ||
1911 | {10800000, DIF_BPF_COEFF67, 0xffaafff5}, | ||
1912 | {10800000, DIF_BPF_COEFF89, 0x00aa0077}, | ||
1913 | {10800000, DIF_BPF_COEFF1011, 0xff13feb6}, | ||
1914 | {10800000, DIF_BPF_COEFF1213, 0x00ce026b}, | ||
1915 | {10800000, DIF_BPF_COEFF1415, 0x000afc85}, | ||
1916 | {10800000, DIF_BPF_COEFF1617, 0xfe3503e3}, | ||
1917 | {10800000, DIF_BPF_COEFF1819, 0x044cfcfb}, | ||
1918 | {10800000, DIF_BPF_COEFF2021, 0xf90c0082}, | ||
1919 | {10800000, DIF_BPF_COEFF2223, 0x08d5037f}, | ||
1920 | {10800000, DIF_BPF_COEFF2425, 0xf710f7cc}, | ||
1921 | {10800000, DIF_BPF_COEFF2627, 0x069f0c59}, | ||
1922 | {10800000, DIF_BPF_COEFF2829, 0xfe16f173}, | ||
1923 | {10800000, DIF_BPF_COEFF3031, 0xfbaa0dcf}, | ||
1924 | {10800000, DIF_BPF_COEFF3233, 0x0aa5f617}, | ||
1925 | {10800000, DIF_BPF_COEFF3435, 0xf0ad039b}, | ||
1926 | {10800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1927 | /* END - DIF BPF register values from 108_quant.dat*/ | ||
1928 | |||
1929 | |||
1930 | /*case 10900000:*/ | ||
1931 | /* BEGIN - DIF BPF register values from 109_quant.dat*/ | ||
1932 | {10900000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
1933 | {10900000, DIF_BPF_COEFF23, 0xfff90006}, | ||
1934 | {10900000, DIF_BPF_COEFF45, 0x00210003}, | ||
1935 | {10900000, DIF_BPF_COEFF67, 0xffacffc8}, | ||
1936 | {10900000, DIF_BPF_COEFF89, 0x008e00b6}, | ||
1937 | {10900000, DIF_BPF_COEFF1011, 0xff63fe7c}, | ||
1938 | {10900000, DIF_BPF_COEFF1213, 0x003a0275}, | ||
1939 | {10900000, DIF_BPF_COEFF1415, 0x00dafcda}, | ||
1940 | {10900000, DIF_BPF_COEFF1617, 0xfd510313}, | ||
1941 | {10900000, DIF_BPF_COEFF1819, 0x0501fe40}, | ||
1942 | {10900000, DIF_BPF_COEFF2021, 0xf8cbfefd}, | ||
1943 | {10900000, DIF_BPF_COEFF2223, 0x087604f0}, | ||
1944 | {10900000, DIF_BPF_COEFF2425, 0xf80af6c2}, | ||
1945 | {10900000, DIF_BPF_COEFF2627, 0x05430cc8}, | ||
1946 | {10900000, DIF_BPF_COEFF2829, 0xff7af19a}, | ||
1947 | {10900000, DIF_BPF_COEFF3031, 0xfa940d4e}, | ||
1948 | {10900000, DIF_BPF_COEFF3233, 0x0b3ff699}, | ||
1949 | {10900000, DIF_BPF_COEFF3435, 0xf0810365}, | ||
1950 | {10900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1951 | /* END - DIF BPF register values from 109_quant.dat*/ | ||
1952 | |||
1953 | |||
1954 | /*case 11000000:*/ | ||
1955 | /* BEGIN - DIF BPF register values from 110_quant.dat*/ | ||
1956 | {11000000, DIF_BPF_COEFF01, 0x0001ffff}, | ||
1957 | {11000000, DIF_BPF_COEFF23, 0xfff8ffff}, | ||
1958 | {11000000, DIF_BPF_COEFF45, 0x00210018}, | ||
1959 | {11000000, DIF_BPF_COEFF67, 0xffbaffa3}, | ||
1960 | {11000000, DIF_BPF_COEFF89, 0x006000e1}, | ||
1961 | {11000000, DIF_BPF_COEFF1011, 0xffc4fe68}, | ||
1962 | {11000000, DIF_BPF_COEFF1213, 0xffa0024b}, | ||
1963 | {11000000, DIF_BPF_COEFF1415, 0x019afd66}, | ||
1964 | {11000000, DIF_BPF_COEFF1617, 0xfc990216}, | ||
1965 | {11000000, DIF_BPF_COEFF1819, 0x0575ff99}, | ||
1966 | {11000000, DIF_BPF_COEFF2021, 0xf8d4fd81}, | ||
1967 | {11000000, DIF_BPF_COEFF2223, 0x07d40640}, | ||
1968 | {11000000, DIF_BPF_COEFF2425, 0xf932f5e6}, | ||
1969 | {11000000, DIF_BPF_COEFF2627, 0x03d20d0d}, | ||
1970 | {11000000, DIF_BPF_COEFF2829, 0x00dff1de}, | ||
1971 | {11000000, DIF_BPF_COEFF3031, 0xf9860cbf}, | ||
1972 | {11000000, DIF_BPF_COEFF3233, 0x0bd1f71e}, | ||
1973 | {11000000, DIF_BPF_COEFF3435, 0xf058032f}, | ||
1974 | {11000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1975 | /* END - DIF BPF register values from 110_quant.dat*/ | ||
1976 | |||
1977 | |||
1978 | /*case 11100000:*/ | ||
1979 | /* BEGIN - DIF BPF register values from 111_quant.dat*/ | ||
1980 | {11100000, DIF_BPF_COEFF01, 0x00010000}, | ||
1981 | {11100000, DIF_BPF_COEFF23, 0xfff8fff8}, | ||
1982 | {11100000, DIF_BPF_COEFF45, 0x001b0029}, | ||
1983 | {11100000, DIF_BPF_COEFF67, 0xffd1ff8a}, | ||
1984 | {11100000, DIF_BPF_COEFF89, 0x002600f2}, | ||
1985 | {11100000, DIF_BPF_COEFF1011, 0x002cfe7c}, | ||
1986 | {11100000, DIF_BPF_COEFF1213, 0xff0f01f0}, | ||
1987 | {11100000, DIF_BPF_COEFF1415, 0x023bfe20}, | ||
1988 | {11100000, DIF_BPF_COEFF1617, 0xfc1700fa}, | ||
1989 | {11100000, DIF_BPF_COEFF1819, 0x05a200f7}, | ||
1990 | {11100000, DIF_BPF_COEFF2021, 0xf927fc1c}, | ||
1991 | {11100000, DIF_BPF_COEFF2223, 0x06f40765}, | ||
1992 | {11100000, DIF_BPF_COEFF2425, 0xfa82f53b}, | ||
1993 | {11100000, DIF_BPF_COEFF2627, 0x02510d27}, | ||
1994 | {11100000, DIF_BPF_COEFF2829, 0x0243f23d}, | ||
1995 | {11100000, DIF_BPF_COEFF3031, 0xf8810c24}, | ||
1996 | {11100000, DIF_BPF_COEFF3233, 0x0c5cf7a7}, | ||
1997 | {11100000, DIF_BPF_COEFF3435, 0xf03102fa}, | ||
1998 | {11100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
1999 | /* END - DIF BPF register values from 111_quant.dat*/ | ||
2000 | |||
2001 | |||
2002 | /*case 11200000:*/ | ||
2003 | /* BEGIN - DIF BPF register values from 112_quant.dat*/ | ||
2004 | {11200000, DIF_BPF_COEFF01, 0x00010002}, | ||
2005 | {11200000, DIF_BPF_COEFF23, 0xfffafff2}, | ||
2006 | {11200000, DIF_BPF_COEFF45, 0x00110035}, | ||
2007 | {11200000, DIF_BPF_COEFF67, 0xfff0ff81}, | ||
2008 | {11200000, DIF_BPF_COEFF89, 0xffe700e7}, | ||
2009 | {11200000, DIF_BPF_COEFF1011, 0x008ffeb6}, | ||
2010 | {11200000, DIF_BPF_COEFF1213, 0xfe94016d}, | ||
2011 | {11200000, DIF_BPF_COEFF1415, 0x02b0fefb}, | ||
2012 | {11200000, DIF_BPF_COEFF1617, 0xfbd3ffd1}, | ||
2013 | {11200000, DIF_BPF_COEFF1819, 0x05850249}, | ||
2014 | {11200000, DIF_BPF_COEFF2021, 0xf9c1fadb}, | ||
2015 | {11200000, DIF_BPF_COEFF2223, 0x05de0858}, | ||
2016 | {11200000, DIF_BPF_COEFF2425, 0xfbf2f4c4}, | ||
2017 | {11200000, DIF_BPF_COEFF2627, 0x00c70d17}, | ||
2018 | {11200000, DIF_BPF_COEFF2829, 0x03a0f2b8}, | ||
2019 | {11200000, DIF_BPF_COEFF3031, 0xf7870b7c}, | ||
2020 | {11200000, DIF_BPF_COEFF3233, 0x0cdff833}, | ||
2021 | {11200000, DIF_BPF_COEFF3435, 0xf00d02c4}, | ||
2022 | {11200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2023 | /* END - DIF BPF register values from 112_quant.dat*/ | ||
2024 | |||
2025 | |||
2026 | /*case 11300000:*/ | ||
2027 | /* BEGIN - DIF BPF register values from 113_quant.dat*/ | ||
2028 | {11300000, DIF_BPF_COEFF01, 0x00000003}, | ||
2029 | {11300000, DIF_BPF_COEFF23, 0xfffdffee}, | ||
2030 | {11300000, DIF_BPF_COEFF45, 0x00040038}, | ||
2031 | {11300000, DIF_BPF_COEFF67, 0x0010ff88}, | ||
2032 | {11300000, DIF_BPF_COEFF89, 0xffac00c2}, | ||
2033 | {11300000, DIF_BPF_COEFF1011, 0x00e2ff10}, | ||
2034 | {11300000, DIF_BPF_COEFF1213, 0xfe3900cb}, | ||
2035 | {11300000, DIF_BPF_COEFF1415, 0x02f1ffe9}, | ||
2036 | {11300000, DIF_BPF_COEFF1617, 0xfbd3feaa}, | ||
2037 | {11300000, DIF_BPF_COEFF1819, 0x05210381}, | ||
2038 | {11300000, DIF_BPF_COEFF2021, 0xfa9cf9c8}, | ||
2039 | {11300000, DIF_BPF_COEFF2223, 0x04990912}, | ||
2040 | {11300000, DIF_BPF_COEFF2425, 0xfd7af484}, | ||
2041 | {11300000, DIF_BPF_COEFF2627, 0xff390cdb}, | ||
2042 | {11300000, DIF_BPF_COEFF2829, 0x04f4f34d}, | ||
2043 | {11300000, DIF_BPF_COEFF3031, 0xf69a0ac9}, | ||
2044 | {11300000, DIF_BPF_COEFF3233, 0x0d5af8c1}, | ||
2045 | {11300000, DIF_BPF_COEFF3435, 0xefec028e}, | ||
2046 | {11300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2047 | /* END - DIF BPF register values from 113_quant.dat*/ | ||
2048 | |||
2049 | |||
2050 | /*case 11400000:*/ | ||
2051 | /* BEGIN - DIF BPF register values from 114_quant.dat*/ | ||
2052 | {11400000, DIF_BPF_COEFF01, 0x00000003}, | ||
2053 | {11400000, DIF_BPF_COEFF23, 0x0000ffee}, | ||
2054 | {11400000, DIF_BPF_COEFF45, 0xfff60033}, | ||
2055 | {11400000, DIF_BPF_COEFF67, 0x002fff9f}, | ||
2056 | {11400000, DIF_BPF_COEFF89, 0xff7b0087}, | ||
2057 | {11400000, DIF_BPF_COEFF1011, 0x011eff82}, | ||
2058 | {11400000, DIF_BPF_COEFF1213, 0xfe080018}, | ||
2059 | {11400000, DIF_BPF_COEFF1415, 0x02f900d8}, | ||
2060 | {11400000, DIF_BPF_COEFF1617, 0xfc17fd96}, | ||
2061 | {11400000, DIF_BPF_COEFF1819, 0x04790490}, | ||
2062 | {11400000, DIF_BPF_COEFF2021, 0xfbadf8ed}, | ||
2063 | {11400000, DIF_BPF_COEFF2223, 0x032f098e}, | ||
2064 | {11400000, DIF_BPF_COEFF2425, 0xff10f47d}, | ||
2065 | {11400000, DIF_BPF_COEFF2627, 0xfdaf0c75}, | ||
2066 | {11400000, DIF_BPF_COEFF2829, 0x063cf3fc}, | ||
2067 | {11400000, DIF_BPF_COEFF3031, 0xf5ba0a0b}, | ||
2068 | {11400000, DIF_BPF_COEFF3233, 0x0dccf952}, | ||
2069 | {11400000, DIF_BPF_COEFF3435, 0xefcd0258}, | ||
2070 | {11400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2071 | /* END - DIF BPF register values from 114_quant.dat*/ | ||
2072 | |||
2073 | |||
2074 | /*case 11500000:*/ | ||
2075 | /* BEGIN - DIF BPF register values from 115_quant.dat*/ | ||
2076 | {11500000, DIF_BPF_COEFF01, 0x00000003}, | ||
2077 | {11500000, DIF_BPF_COEFF23, 0x0004fff1}, | ||
2078 | {11500000, DIF_BPF_COEFF45, 0xffea0026}, | ||
2079 | {11500000, DIF_BPF_COEFF67, 0x0046ffc3}, | ||
2080 | {11500000, DIF_BPF_COEFF89, 0xff5a003c}, | ||
2081 | {11500000, DIF_BPF_COEFF1011, 0x013b0000}, | ||
2082 | {11500000, DIF_BPF_COEFF1213, 0xfe04ff63}, | ||
2083 | {11500000, DIF_BPF_COEFF1415, 0x02c801b8}, | ||
2084 | {11500000, DIF_BPF_COEFF1617, 0xfc99fca6}, | ||
2085 | {11500000, DIF_BPF_COEFF1819, 0x0397056a}, | ||
2086 | {11500000, DIF_BPF_COEFF2021, 0xfcecf853}, | ||
2087 | {11500000, DIF_BPF_COEFF2223, 0x01ad09c9}, | ||
2088 | {11500000, DIF_BPF_COEFF2425, 0x00acf4ad}, | ||
2089 | {11500000, DIF_BPF_COEFF2627, 0xfc2e0be7}, | ||
2090 | {11500000, DIF_BPF_COEFF2829, 0x0773f4c2}, | ||
2091 | {11500000, DIF_BPF_COEFF3031, 0xf4e90943}, | ||
2092 | {11500000, DIF_BPF_COEFF3233, 0x0e35f9e6}, | ||
2093 | {11500000, DIF_BPF_COEFF3435, 0xefb10221}, | ||
2094 | {11500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2095 | /* END - DIF BPF register values from 115_quant.dat*/ | ||
2096 | |||
2097 | |||
2098 | /*case 11600000:*/ | ||
2099 | /* BEGIN - DIF BPF register values from 116_quant.dat*/ | ||
2100 | {11600000, DIF_BPF_COEFF01, 0x00000002}, | ||
2101 | {11600000, DIF_BPF_COEFF23, 0x0007fff6}, | ||
2102 | {11600000, DIF_BPF_COEFF45, 0xffe20014}, | ||
2103 | {11600000, DIF_BPF_COEFF67, 0x0054ffee}, | ||
2104 | {11600000, DIF_BPF_COEFF89, 0xff4effeb}, | ||
2105 | {11600000, DIF_BPF_COEFF1011, 0x0137007e}, | ||
2106 | {11600000, DIF_BPF_COEFF1213, 0xfe2efebb}, | ||
2107 | {11600000, DIF_BPF_COEFF1415, 0x0260027a}, | ||
2108 | {11600000, DIF_BPF_COEFF1617, 0xfd51fbe6}, | ||
2109 | {11600000, DIF_BPF_COEFF1819, 0x02870605}, | ||
2110 | {11600000, DIF_BPF_COEFF2021, 0xfe4af7fe}, | ||
2111 | {11600000, DIF_BPF_COEFF2223, 0x001d09c1}, | ||
2112 | {11600000, DIF_BPF_COEFF2425, 0x0243f515}, | ||
2113 | {11600000, DIF_BPF_COEFF2627, 0xfabd0b32}, | ||
2114 | {11600000, DIF_BPF_COEFF2829, 0x0897f59e}, | ||
2115 | {11600000, DIF_BPF_COEFF3031, 0xf4280871}, | ||
2116 | {11600000, DIF_BPF_COEFF3233, 0x0e95fa7c}, | ||
2117 | {11600000, DIF_BPF_COEFF3435, 0xef9701eb}, | ||
2118 | {11600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2119 | /* END - DIF BPF register values from 116_quant.dat*/ | ||
2120 | |||
2121 | |||
2122 | /*case 11700000:*/ | ||
2123 | /* BEGIN - DIF BPF register values from 117_quant.dat*/ | ||
2124 | {11700000, DIF_BPF_COEFF01, 0xffff0001}, | ||
2125 | {11700000, DIF_BPF_COEFF23, 0x0008fffd}, | ||
2126 | {11700000, DIF_BPF_COEFF45, 0xffdeffff}, | ||
2127 | {11700000, DIF_BPF_COEFF67, 0x0056001d}, | ||
2128 | {11700000, DIF_BPF_COEFF89, 0xff57ff9c}, | ||
2129 | {11700000, DIF_BPF_COEFF1011, 0x011300f0}, | ||
2130 | {11700000, DIF_BPF_COEFF1213, 0xfe82fe2e}, | ||
2131 | {11700000, DIF_BPF_COEFF1415, 0x01ca0310}, | ||
2132 | {11700000, DIF_BPF_COEFF1617, 0xfe35fb62}, | ||
2133 | {11700000, DIF_BPF_COEFF1819, 0x0155065a}, | ||
2134 | {11700000, DIF_BPF_COEFF2021, 0xffbaf7f2}, | ||
2135 | {11700000, DIF_BPF_COEFF2223, 0xfe8c0977}, | ||
2136 | {11700000, DIF_BPF_COEFF2425, 0x03cef5b2}, | ||
2137 | {11700000, DIF_BPF_COEFF2627, 0xf9610a58}, | ||
2138 | {11700000, DIF_BPF_COEFF2829, 0x09a5f68f}, | ||
2139 | {11700000, DIF_BPF_COEFF3031, 0xf3790797}, | ||
2140 | {11700000, DIF_BPF_COEFF3233, 0x0eebfb14}, | ||
2141 | {11700000, DIF_BPF_COEFF3435, 0xef8001b5}, | ||
2142 | {11700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2143 | /* END - DIF BPF register values from 117_quant.dat*/ | ||
2144 | |||
2145 | |||
2146 | /*case 11800000:*/ | ||
2147 | /* BEGIN - DIF BPF register values from 118_quant.dat*/ | ||
2148 | {11800000, DIF_BPF_COEFF01, 0xffff0000}, | ||
2149 | {11800000, DIF_BPF_COEFF23, 0x00080004}, | ||
2150 | {11800000, DIF_BPF_COEFF45, 0xffe0ffe9}, | ||
2151 | {11800000, DIF_BPF_COEFF67, 0x004c0047}, | ||
2152 | {11800000, DIF_BPF_COEFF89, 0xff75ff58}, | ||
2153 | {11800000, DIF_BPF_COEFF1011, 0x00d1014a}, | ||
2154 | {11800000, DIF_BPF_COEFF1213, 0xfef9fdc8}, | ||
2155 | {11800000, DIF_BPF_COEFF1415, 0x0111036f}, | ||
2156 | {11800000, DIF_BPF_COEFF1617, 0xff36fb21}, | ||
2157 | {11800000, DIF_BPF_COEFF1819, 0x00120665}, | ||
2158 | {11800000, DIF_BPF_COEFF2021, 0x012df82e}, | ||
2159 | {11800000, DIF_BPF_COEFF2223, 0xfd0708ec}, | ||
2160 | {11800000, DIF_BPF_COEFF2425, 0x0542f682}, | ||
2161 | {11800000, DIF_BPF_COEFF2627, 0xf81f095c}, | ||
2162 | {11800000, DIF_BPF_COEFF2829, 0x0a9af792}, | ||
2163 | {11800000, DIF_BPF_COEFF3031, 0xf2db06b5}, | ||
2164 | {11800000, DIF_BPF_COEFF3233, 0x0f38fbad}, | ||
2165 | {11800000, DIF_BPF_COEFF3435, 0xef6c017e}, | ||
2166 | {11800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2167 | /* END - DIF BPF register values from 118_quant.dat*/ | ||
2168 | |||
2169 | |||
2170 | /*case 11900000:*/ | ||
2171 | /* BEGIN - DIF BPF register values from 119_quant.dat*/ | ||
2172 | {11900000, DIF_BPF_COEFF01, 0xffffffff}, | ||
2173 | {11900000, DIF_BPF_COEFF23, 0x0007000b}, | ||
2174 | {11900000, DIF_BPF_COEFF45, 0xffe7ffd8}, | ||
2175 | {11900000, DIF_BPF_COEFF67, 0x00370068}, | ||
2176 | {11900000, DIF_BPF_COEFF89, 0xffa4ff28}, | ||
2177 | {11900000, DIF_BPF_COEFF1011, 0x00790184}, | ||
2178 | {11900000, DIF_BPF_COEFF1213, 0xff87fd91}, | ||
2179 | {11900000, DIF_BPF_COEFF1415, 0x00430392}, | ||
2180 | {11900000, DIF_BPF_COEFF1617, 0x0044fb26}, | ||
2181 | {11900000, DIF_BPF_COEFF1819, 0xfece0626}, | ||
2182 | {11900000, DIF_BPF_COEFF2021, 0x0294f8b2}, | ||
2183 | {11900000, DIF_BPF_COEFF2223, 0xfb990825}, | ||
2184 | {11900000, DIF_BPF_COEFF2425, 0x0698f77f}, | ||
2185 | {11900000, DIF_BPF_COEFF2627, 0xf6fe0842}, | ||
2186 | {11900000, DIF_BPF_COEFF2829, 0x0b73f8a7}, | ||
2187 | {11900000, DIF_BPF_COEFF3031, 0xf25105cd}, | ||
2188 | {11900000, DIF_BPF_COEFF3233, 0x0f7bfc48}, | ||
2189 | {11900000, DIF_BPF_COEFF3435, 0xef5a0148}, | ||
2190 | {11900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2191 | /* END - DIF BPF register values from 119_quant.dat*/ | ||
2192 | |||
2193 | |||
2194 | /*case 12000000:*/ | ||
2195 | /* BEGIN - DIF BPF register values from 120_quant.dat*/ | ||
2196 | {12000000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
2197 | {12000000, DIF_BPF_COEFF23, 0x00050010}, | ||
2198 | {12000000, DIF_BPF_COEFF45, 0xfff2ffcc}, | ||
2199 | {12000000, DIF_BPF_COEFF67, 0x001b007b}, | ||
2200 | {12000000, DIF_BPF_COEFF89, 0xffdfff10}, | ||
2201 | {12000000, DIF_BPF_COEFF1011, 0x00140198}, | ||
2202 | {12000000, DIF_BPF_COEFF1213, 0x0020fd8e}, | ||
2203 | {12000000, DIF_BPF_COEFF1415, 0xff710375}, | ||
2204 | {12000000, DIF_BPF_COEFF1617, 0x014dfb73}, | ||
2205 | {12000000, DIF_BPF_COEFF1819, 0xfd9a059f}, | ||
2206 | {12000000, DIF_BPF_COEFF2021, 0x03e0f978}, | ||
2207 | {12000000, DIF_BPF_COEFF2223, 0xfa4e0726}, | ||
2208 | {12000000, DIF_BPF_COEFF2425, 0x07c8f8a7}, | ||
2209 | {12000000, DIF_BPF_COEFF2627, 0xf600070c}, | ||
2210 | {12000000, DIF_BPF_COEFF2829, 0x0c2ff9c9}, | ||
2211 | {12000000, DIF_BPF_COEFF3031, 0xf1db04de}, | ||
2212 | {12000000, DIF_BPF_COEFF3233, 0x0fb4fce5}, | ||
2213 | {12000000, DIF_BPF_COEFF3435, 0xef4b0111}, | ||
2214 | {12000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2215 | /* END - DIF BPF register values from 120_quant.dat*/ | ||
2216 | |||
2217 | |||
2218 | /*case 12100000:*/ | ||
2219 | /* BEGIN - DIF BPF register values from 121_quant.dat*/ | ||
2220 | {12100000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2221 | {12100000, DIF_BPF_COEFF23, 0x00010012}, | ||
2222 | {12100000, DIF_BPF_COEFF45, 0xffffffc8}, | ||
2223 | {12100000, DIF_BPF_COEFF67, 0xfffb007e}, | ||
2224 | {12100000, DIF_BPF_COEFF89, 0x001dff14}, | ||
2225 | {12100000, DIF_BPF_COEFF1011, 0xffad0184}, | ||
2226 | {12100000, DIF_BPF_COEFF1213, 0x00b7fdbe}, | ||
2227 | {12100000, DIF_BPF_COEFF1415, 0xfea9031b}, | ||
2228 | {12100000, DIF_BPF_COEFF1617, 0x0241fc01}, | ||
2229 | {12100000, DIF_BPF_COEFF1819, 0xfc8504d6}, | ||
2230 | {12100000, DIF_BPF_COEFF2021, 0x0504fa79}, | ||
2231 | {12100000, DIF_BPF_COEFF2223, 0xf93005f6}, | ||
2232 | {12100000, DIF_BPF_COEFF2425, 0x08caf9f2}, | ||
2233 | {12100000, DIF_BPF_COEFF2627, 0xf52b05c0}, | ||
2234 | {12100000, DIF_BPF_COEFF2829, 0x0ccbfaf9}, | ||
2235 | {12100000, DIF_BPF_COEFF3031, 0xf17903eb}, | ||
2236 | {12100000, DIF_BPF_COEFF3233, 0x0fe3fd83}, | ||
2237 | {12100000, DIF_BPF_COEFF3435, 0xef3f00db}, | ||
2238 | {12100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2239 | /* END - DIF BPF register values from 121_quant.dat*/ | ||
2240 | |||
2241 | |||
2242 | /*case 12200000:*/ | ||
2243 | /* BEGIN - DIF BPF register values from 122_quant.dat*/ | ||
2244 | {12200000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2245 | {12200000, DIF_BPF_COEFF23, 0xfffe0011}, | ||
2246 | {12200000, DIF_BPF_COEFF45, 0x000cffcc}, | ||
2247 | {12200000, DIF_BPF_COEFF67, 0xffdb0071}, | ||
2248 | {12200000, DIF_BPF_COEFF89, 0x0058ff32}, | ||
2249 | {12200000, DIF_BPF_COEFF1011, 0xff4f014a}, | ||
2250 | {12200000, DIF_BPF_COEFF1213, 0x013cfe1f}, | ||
2251 | {12200000, DIF_BPF_COEFF1415, 0xfdfb028a}, | ||
2252 | {12200000, DIF_BPF_COEFF1617, 0x0311fcc9}, | ||
2253 | {12200000, DIF_BPF_COEFF1819, 0xfb9d03d6}, | ||
2254 | {12200000, DIF_BPF_COEFF2021, 0x05f4fbad}, | ||
2255 | {12200000, DIF_BPF_COEFF2223, 0xf848049d}, | ||
2256 | {12200000, DIF_BPF_COEFF2425, 0x0999fb5b}, | ||
2257 | {12200000, DIF_BPF_COEFF2627, 0xf4820461}, | ||
2258 | {12200000, DIF_BPF_COEFF2829, 0x0d46fc32}, | ||
2259 | {12200000, DIF_BPF_COEFF3031, 0xf12d02f4}, | ||
2260 | {12200000, DIF_BPF_COEFF3233, 0x1007fe21}, | ||
2261 | {12200000, DIF_BPF_COEFF3435, 0xef3600a4}, | ||
2262 | {12200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2263 | /* END - DIF BPF register values from 122_quant.dat*/ | ||
2264 | |||
2265 | |||
2266 | /*case 12300000:*/ | ||
2267 | /* BEGIN - DIF BPF register values from 123_quant.dat*/ | ||
2268 | {12300000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
2269 | {12300000, DIF_BPF_COEFF23, 0xfffa000e}, | ||
2270 | {12300000, DIF_BPF_COEFF45, 0x0017ffd9}, | ||
2271 | {12300000, DIF_BPF_COEFF67, 0xffc10055}, | ||
2272 | {12300000, DIF_BPF_COEFF89, 0x0088ff68}, | ||
2273 | {12300000, DIF_BPF_COEFF1011, 0xff0400f0}, | ||
2274 | {12300000, DIF_BPF_COEFF1213, 0x01a6fea7}, | ||
2275 | {12300000, DIF_BPF_COEFF1415, 0xfd7501cc}, | ||
2276 | {12300000, DIF_BPF_COEFF1617, 0x03b0fdc0}, | ||
2277 | {12300000, DIF_BPF_COEFF1819, 0xfaef02a8}, | ||
2278 | {12300000, DIF_BPF_COEFF2021, 0x06a7fd07}, | ||
2279 | {12300000, DIF_BPF_COEFF2223, 0xf79d0326}, | ||
2280 | {12300000, DIF_BPF_COEFF2425, 0x0a31fcda}, | ||
2281 | {12300000, DIF_BPF_COEFF2627, 0xf40702f3}, | ||
2282 | {12300000, DIF_BPF_COEFF2829, 0x0d9ffd72}, | ||
2283 | {12300000, DIF_BPF_COEFF3031, 0xf0f601fa}, | ||
2284 | {12300000, DIF_BPF_COEFF3233, 0x1021fec0}, | ||
2285 | {12300000, DIF_BPF_COEFF3435, 0xef2f006d}, | ||
2286 | {12300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2287 | /* END - DIF BPF register values from 123_quant.dat*/ | ||
2288 | |||
2289 | |||
2290 | /*case 12400000:*/ | ||
2291 | /* BEGIN - DIF BPF register values from 124_quant.dat*/ | ||
2292 | {12400000, DIF_BPF_COEFF01, 0x0001ffff}, | ||
2293 | {12400000, DIF_BPF_COEFF23, 0xfff80007}, | ||
2294 | {12400000, DIF_BPF_COEFF45, 0x001fffeb}, | ||
2295 | {12400000, DIF_BPF_COEFF67, 0xffaf002d}, | ||
2296 | {12400000, DIF_BPF_COEFF89, 0x00a8ffb0}, | ||
2297 | {12400000, DIF_BPF_COEFF1011, 0xfed3007e}, | ||
2298 | {12400000, DIF_BPF_COEFF1213, 0x01e9ff4c}, | ||
2299 | {12400000, DIF_BPF_COEFF1415, 0xfd2000ee}, | ||
2300 | {12400000, DIF_BPF_COEFF1617, 0x0413fed8}, | ||
2301 | {12400000, DIF_BPF_COEFF1819, 0xfa82015c}, | ||
2302 | {12400000, DIF_BPF_COEFF2021, 0x0715fe7d}, | ||
2303 | {12400000, DIF_BPF_COEFF2223, 0xf7340198}, | ||
2304 | {12400000, DIF_BPF_COEFF2425, 0x0a8dfe69}, | ||
2305 | {12400000, DIF_BPF_COEFF2627, 0xf3bd017c}, | ||
2306 | {12400000, DIF_BPF_COEFF2829, 0x0dd5feb8}, | ||
2307 | {12400000, DIF_BPF_COEFF3031, 0xf0d500fd}, | ||
2308 | {12400000, DIF_BPF_COEFF3233, 0x1031ff60}, | ||
2309 | {12400000, DIF_BPF_COEFF3435, 0xef2b0037}, | ||
2310 | {12400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2311 | /* END - DIF BPF register values from 124_quant.dat*/ | ||
2312 | |||
2313 | |||
2314 | /*case 12500000:*/ | ||
2315 | /* BEGIN - DIF BPF register values from 125_quant.dat*/ | ||
2316 | {12500000, DIF_BPF_COEFF01, 0x00010000}, | ||
2317 | {12500000, DIF_BPF_COEFF23, 0xfff70000}, | ||
2318 | {12500000, DIF_BPF_COEFF45, 0x00220000}, | ||
2319 | {12500000, DIF_BPF_COEFF67, 0xffa90000}, | ||
2320 | {12500000, DIF_BPF_COEFF89, 0x00b30000}, | ||
2321 | {12500000, DIF_BPF_COEFF1011, 0xfec20000}, | ||
2322 | {12500000, DIF_BPF_COEFF1213, 0x02000000}, | ||
2323 | {12500000, DIF_BPF_COEFF1415, 0xfd030000}, | ||
2324 | {12500000, DIF_BPF_COEFF1617, 0x04350000}, | ||
2325 | {12500000, DIF_BPF_COEFF1819, 0xfa5e0000}, | ||
2326 | {12500000, DIF_BPF_COEFF2021, 0x073b0000}, | ||
2327 | {12500000, DIF_BPF_COEFF2223, 0xf7110000}, | ||
2328 | {12500000, DIF_BPF_COEFF2425, 0x0aac0000}, | ||
2329 | {12500000, DIF_BPF_COEFF2627, 0xf3a40000}, | ||
2330 | {12500000, DIF_BPF_COEFF2829, 0x0de70000}, | ||
2331 | {12500000, DIF_BPF_COEFF3031, 0xf0c90000}, | ||
2332 | {12500000, DIF_BPF_COEFF3233, 0x10360000}, | ||
2333 | {12500000, DIF_BPF_COEFF3435, 0xef290000}, | ||
2334 | {12500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2335 | /* END - DIF BPF register values from 125_quant.dat*/ | ||
2336 | |||
2337 | |||
2338 | /*case 12600000:*/ | ||
2339 | /* BEGIN - DIF BPF register values from 126_quant.dat*/ | ||
2340 | {12600000, DIF_BPF_COEFF01, 0x00010001}, | ||
2341 | {12600000, DIF_BPF_COEFF23, 0xfff8fff9}, | ||
2342 | {12600000, DIF_BPF_COEFF45, 0x001f0015}, | ||
2343 | {12600000, DIF_BPF_COEFF67, 0xffafffd3}, | ||
2344 | {12600000, DIF_BPF_COEFF89, 0x00a80050}, | ||
2345 | {12600000, DIF_BPF_COEFF1011, 0xfed3ff82}, | ||
2346 | {12600000, DIF_BPF_COEFF1213, 0x01e900b4}, | ||
2347 | {12600000, DIF_BPF_COEFF1415, 0xfd20ff12}, | ||
2348 | {12600000, DIF_BPF_COEFF1617, 0x04130128}, | ||
2349 | {12600000, DIF_BPF_COEFF1819, 0xfa82fea4}, | ||
2350 | {12600000, DIF_BPF_COEFF2021, 0x07150183}, | ||
2351 | {12600000, DIF_BPF_COEFF2223, 0xf734fe68}, | ||
2352 | {12600000, DIF_BPF_COEFF2425, 0x0a8d0197}, | ||
2353 | {12600000, DIF_BPF_COEFF2627, 0xf3bdfe84}, | ||
2354 | {12600000, DIF_BPF_COEFF2829, 0x0dd50148}, | ||
2355 | {12600000, DIF_BPF_COEFF3031, 0xf0d5ff03}, | ||
2356 | {12600000, DIF_BPF_COEFF3233, 0x103100a0}, | ||
2357 | {12600000, DIF_BPF_COEFF3435, 0xef2bffc9}, | ||
2358 | {12600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2359 | /* END - DIF BPF register values from 126_quant.dat*/ | ||
2360 | |||
2361 | |||
2362 | /*case 12700000:*/ | ||
2363 | /* BEGIN - DIF BPF register values from 127_quant.dat*/ | ||
2364 | {12700000, DIF_BPF_COEFF01, 0x00000002}, | ||
2365 | {12700000, DIF_BPF_COEFF23, 0xfffafff2}, | ||
2366 | {12700000, DIF_BPF_COEFF45, 0x00170027}, | ||
2367 | {12700000, DIF_BPF_COEFF67, 0xffc1ffab}, | ||
2368 | {12700000, DIF_BPF_COEFF89, 0x00880098}, | ||
2369 | {12700000, DIF_BPF_COEFF1011, 0xff04ff10}, | ||
2370 | {12700000, DIF_BPF_COEFF1213, 0x01a60159}, | ||
2371 | {12700000, DIF_BPF_COEFF1415, 0xfd75fe34}, | ||
2372 | {12700000, DIF_BPF_COEFF1617, 0x03b00240}, | ||
2373 | {12700000, DIF_BPF_COEFF1819, 0xfaeffd58}, | ||
2374 | {12700000, DIF_BPF_COEFF2021, 0x06a702f9}, | ||
2375 | {12700000, DIF_BPF_COEFF2223, 0xf79dfcda}, | ||
2376 | {12700000, DIF_BPF_COEFF2425, 0x0a310326}, | ||
2377 | {12700000, DIF_BPF_COEFF2627, 0xf407fd0d}, | ||
2378 | {12700000, DIF_BPF_COEFF2829, 0x0d9f028e}, | ||
2379 | {12700000, DIF_BPF_COEFF3031, 0xf0f6fe06}, | ||
2380 | {12700000, DIF_BPF_COEFF3233, 0x10210140}, | ||
2381 | {12700000, DIF_BPF_COEFF3435, 0xef2fff93}, | ||
2382 | {12700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2383 | /* END - DIF BPF register values from 127_quant.dat*/ | ||
2384 | |||
2385 | |||
2386 | /*case 12800000:*/ | ||
2387 | /* BEGIN - DIF BPF register values from 128_quant.dat*/ | ||
2388 | {12800000, DIF_BPF_COEFF01, 0x00000003}, | ||
2389 | {12800000, DIF_BPF_COEFF23, 0xfffeffef}, | ||
2390 | {12800000, DIF_BPF_COEFF45, 0x000c0034}, | ||
2391 | {12800000, DIF_BPF_COEFF67, 0xffdbff8f}, | ||
2392 | {12800000, DIF_BPF_COEFF89, 0x005800ce}, | ||
2393 | {12800000, DIF_BPF_COEFF1011, 0xff4ffeb6}, | ||
2394 | {12800000, DIF_BPF_COEFF1213, 0x013c01e1}, | ||
2395 | {12800000, DIF_BPF_COEFF1415, 0xfdfbfd76}, | ||
2396 | {12800000, DIF_BPF_COEFF1617, 0x03110337}, | ||
2397 | {12800000, DIF_BPF_COEFF1819, 0xfb9dfc2a}, | ||
2398 | {12800000, DIF_BPF_COEFF2021, 0x05f40453}, | ||
2399 | {12800000, DIF_BPF_COEFF2223, 0xf848fb63}, | ||
2400 | {12800000, DIF_BPF_COEFF2425, 0x099904a5}, | ||
2401 | {12800000, DIF_BPF_COEFF2627, 0xf482fb9f}, | ||
2402 | {12800000, DIF_BPF_COEFF2829, 0x0d4603ce}, | ||
2403 | {12800000, DIF_BPF_COEFF3031, 0xf12dfd0c}, | ||
2404 | {12800000, DIF_BPF_COEFF3233, 0x100701df}, | ||
2405 | {12800000, DIF_BPF_COEFF3435, 0xef36ff5c}, | ||
2406 | {12800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2407 | /* END - DIF BPF register values from 128_quant.dat*/ | ||
2408 | |||
2409 | |||
2410 | /*case 12900000:*/ | ||
2411 | /* BEGIN - DIF BPF register values from 129_quant.dat*/ | ||
2412 | {12900000, DIF_BPF_COEFF01, 0x00000003}, | ||
2413 | {12900000, DIF_BPF_COEFF23, 0x0001ffee}, | ||
2414 | {12900000, DIF_BPF_COEFF45, 0xffff0038}, | ||
2415 | {12900000, DIF_BPF_COEFF67, 0xfffbff82}, | ||
2416 | {12900000, DIF_BPF_COEFF89, 0x001d00ec}, | ||
2417 | {12900000, DIF_BPF_COEFF1011, 0xffadfe7c}, | ||
2418 | {12900000, DIF_BPF_COEFF1213, 0x00b70242}, | ||
2419 | {12900000, DIF_BPF_COEFF1415, 0xfea9fce5}, | ||
2420 | {12900000, DIF_BPF_COEFF1617, 0x024103ff}, | ||
2421 | {12900000, DIF_BPF_COEFF1819, 0xfc85fb2a}, | ||
2422 | {12900000, DIF_BPF_COEFF2021, 0x05040587}, | ||
2423 | {12900000, DIF_BPF_COEFF2223, 0xf930fa0a}, | ||
2424 | {12900000, DIF_BPF_COEFF2425, 0x08ca060e}, | ||
2425 | {12900000, DIF_BPF_COEFF2627, 0xf52bfa40}, | ||
2426 | {12900000, DIF_BPF_COEFF2829, 0x0ccb0507}, | ||
2427 | {12900000, DIF_BPF_COEFF3031, 0xf179fc15}, | ||
2428 | {12900000, DIF_BPF_COEFF3233, 0x0fe3027d}, | ||
2429 | {12900000, DIF_BPF_COEFF3435, 0xef3fff25}, | ||
2430 | {12900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2431 | /* END - DIF BPF register values from 129_quant.dat*/ | ||
2432 | |||
2433 | |||
2434 | /*case 113000000:*/ | ||
2435 | /* BEGIN - DIF BPF register values from 130_quant.dat*/ | ||
2436 | {13000000, DIF_BPF_COEFF01, 0x00000002}, | ||
2437 | {13000000, DIF_BPF_COEFF23, 0x0005fff0}, | ||
2438 | {13000000, DIF_BPF_COEFF45, 0xfff20034}, | ||
2439 | {13000000, DIF_BPF_COEFF67, 0x001bff85}, | ||
2440 | {13000000, DIF_BPF_COEFF89, 0xffdf00f0}, | ||
2441 | {13000000, DIF_BPF_COEFF1011, 0x0014fe68}, | ||
2442 | {13000000, DIF_BPF_COEFF1213, 0x00200272}, | ||
2443 | {13000000, DIF_BPF_COEFF1415, 0xff71fc8b}, | ||
2444 | {13000000, DIF_BPF_COEFF1617, 0x014d048d}, | ||
2445 | {13000000, DIF_BPF_COEFF1819, 0xfd9afa61}, | ||
2446 | {13000000, DIF_BPF_COEFF2021, 0x03e00688}, | ||
2447 | {13000000, DIF_BPF_COEFF2223, 0xfa4ef8da}, | ||
2448 | {13000000, DIF_BPF_COEFF2425, 0x07c80759}, | ||
2449 | {13000000, DIF_BPF_COEFF2627, 0xf600f8f4}, | ||
2450 | {13000000, DIF_BPF_COEFF2829, 0x0c2f0637}, | ||
2451 | {13000000, DIF_BPF_COEFF3031, 0xf1dbfb22}, | ||
2452 | {13000000, DIF_BPF_COEFF3233, 0x0fb4031b}, | ||
2453 | {13000000, DIF_BPF_COEFF3435, 0xef4bfeef}, | ||
2454 | {13000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2455 | /* END - DIF BPF register values from 130_quant.dat*/ | ||
2456 | |||
2457 | |||
2458 | /*case 13100000:*/ | ||
2459 | /* BEGIN - DIF BPF register values from 131_quant.dat*/ | ||
2460 | {13100000, DIF_BPF_COEFF01, 0xffff0001}, | ||
2461 | {13100000, DIF_BPF_COEFF23, 0x0007fff5}, | ||
2462 | {13100000, DIF_BPF_COEFF45, 0xffe70028}, | ||
2463 | {13100000, DIF_BPF_COEFF67, 0x0037ff98}, | ||
2464 | {13100000, DIF_BPF_COEFF89, 0xffa400d8}, | ||
2465 | {13100000, DIF_BPF_COEFF1011, 0x0079fe7c}, | ||
2466 | {13100000, DIF_BPF_COEFF1213, 0xff87026f}, | ||
2467 | {13100000, DIF_BPF_COEFF1415, 0x0043fc6e}, | ||
2468 | {13100000, DIF_BPF_COEFF1617, 0x004404da}, | ||
2469 | {13100000, DIF_BPF_COEFF1819, 0xfecef9da}, | ||
2470 | {13100000, DIF_BPF_COEFF2021, 0x0294074e}, | ||
2471 | {13100000, DIF_BPF_COEFF2223, 0xfb99f7db}, | ||
2472 | {13100000, DIF_BPF_COEFF2425, 0x06980881}, | ||
2473 | {13100000, DIF_BPF_COEFF2627, 0xf6fef7be}, | ||
2474 | {13100000, DIF_BPF_COEFF2829, 0x0b730759}, | ||
2475 | {13100000, DIF_BPF_COEFF3031, 0xf251fa33}, | ||
2476 | {13100000, DIF_BPF_COEFF3233, 0x0f7b03b8}, | ||
2477 | {13100000, DIF_BPF_COEFF3435, 0xef5afeb8}, | ||
2478 | {13100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2479 | /* END - DIF BPF register values from 131_quant.dat*/ | ||
2480 | |||
2481 | |||
2482 | /*case 13200000:*/ | ||
2483 | /* BEGIN - DIF BPF register values from 132_quant.dat*/ | ||
2484 | {13200000, DIF_BPF_COEFF01, 0xffff0000}, | ||
2485 | {13200000, DIF_BPF_COEFF23, 0x0008fffc}, | ||
2486 | {13200000, DIF_BPF_COEFF45, 0xffe00017}, | ||
2487 | {13200000, DIF_BPF_COEFF67, 0x004cffb9}, | ||
2488 | {13200000, DIF_BPF_COEFF89, 0xff7500a8}, | ||
2489 | {13200000, DIF_BPF_COEFF1011, 0x00d1feb6}, | ||
2490 | {13200000, DIF_BPF_COEFF1213, 0xfef90238}, | ||
2491 | {13200000, DIF_BPF_COEFF1415, 0x0111fc91}, | ||
2492 | {13200000, DIF_BPF_COEFF1617, 0xff3604df}, | ||
2493 | {13200000, DIF_BPF_COEFF1819, 0x0012f99b}, | ||
2494 | {13200000, DIF_BPF_COEFF2021, 0x012d07d2}, | ||
2495 | {13200000, DIF_BPF_COEFF2223, 0xfd07f714}, | ||
2496 | {13200000, DIF_BPF_COEFF2425, 0x0542097e}, | ||
2497 | {13200000, DIF_BPF_COEFF2627, 0xf81ff6a4}, | ||
2498 | {13200000, DIF_BPF_COEFF2829, 0x0a9a086e}, | ||
2499 | {13200000, DIF_BPF_COEFF3031, 0xf2dbf94b}, | ||
2500 | {13200000, DIF_BPF_COEFF3233, 0x0f380453}, | ||
2501 | {13200000, DIF_BPF_COEFF3435, 0xef6cfe82}, | ||
2502 | {13200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2503 | /* END - DIF BPF register values from 132_quant.dat*/ | ||
2504 | |||
2505 | |||
2506 | /*case 13300000:*/ | ||
2507 | /* BEGIN - DIF BPF register values from 133_quant.dat*/ | ||
2508 | {13300000, DIF_BPF_COEFF01, 0xffffffff}, | ||
2509 | {13300000, DIF_BPF_COEFF23, 0x00080003}, | ||
2510 | {13300000, DIF_BPF_COEFF45, 0xffde0001}, | ||
2511 | {13300000, DIF_BPF_COEFF67, 0x0056ffe3}, | ||
2512 | {13300000, DIF_BPF_COEFF89, 0xff570064}, | ||
2513 | {13300000, DIF_BPF_COEFF1011, 0x0113ff10}, | ||
2514 | {13300000, DIF_BPF_COEFF1213, 0xfe8201d2}, | ||
2515 | {13300000, DIF_BPF_COEFF1415, 0x01cafcf0}, | ||
2516 | {13300000, DIF_BPF_COEFF1617, 0xfe35049e}, | ||
2517 | {13300000, DIF_BPF_COEFF1819, 0x0155f9a6}, | ||
2518 | {13300000, DIF_BPF_COEFF2021, 0xffba080e}, | ||
2519 | {13300000, DIF_BPF_COEFF2223, 0xfe8cf689}, | ||
2520 | {13300000, DIF_BPF_COEFF2425, 0x03ce0a4e}, | ||
2521 | {13300000, DIF_BPF_COEFF2627, 0xf961f5a8}, | ||
2522 | {13300000, DIF_BPF_COEFF2829, 0x09a50971}, | ||
2523 | {13300000, DIF_BPF_COEFF3031, 0xf379f869}, | ||
2524 | {13300000, DIF_BPF_COEFF3233, 0x0eeb04ec}, | ||
2525 | {13300000, DIF_BPF_COEFF3435, 0xef80fe4b}, | ||
2526 | {13300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2527 | /* END - DIF BPF register values from 133_quant.dat*/ | ||
2528 | |||
2529 | |||
2530 | /*case 13400000:*/ | ||
2531 | /* BEGIN - DIF BPF register values from 134_quant.dat*/ | ||
2532 | {13400000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
2533 | {13400000, DIF_BPF_COEFF23, 0x0007000a}, | ||
2534 | {13400000, DIF_BPF_COEFF45, 0xffe2ffec}, | ||
2535 | {13400000, DIF_BPF_COEFF67, 0x00540012}, | ||
2536 | {13400000, DIF_BPF_COEFF89, 0xff4e0015}, | ||
2537 | {13400000, DIF_BPF_COEFF1011, 0x0137ff82}, | ||
2538 | {13400000, DIF_BPF_COEFF1213, 0xfe2e0145}, | ||
2539 | {13400000, DIF_BPF_COEFF1415, 0x0260fd86}, | ||
2540 | {13400000, DIF_BPF_COEFF1617, 0xfd51041a}, | ||
2541 | {13400000, DIF_BPF_COEFF1819, 0x0287f9fb}, | ||
2542 | {13400000, DIF_BPF_COEFF2021, 0xfe4a0802}, | ||
2543 | {13400000, DIF_BPF_COEFF2223, 0x001df63f}, | ||
2544 | {13400000, DIF_BPF_COEFF2425, 0x02430aeb}, | ||
2545 | {13400000, DIF_BPF_COEFF2627, 0xfabdf4ce}, | ||
2546 | {13400000, DIF_BPF_COEFF2829, 0x08970a62}, | ||
2547 | {13400000, DIF_BPF_COEFF3031, 0xf428f78f}, | ||
2548 | {13400000, DIF_BPF_COEFF3233, 0x0e950584}, | ||
2549 | {13400000, DIF_BPF_COEFF3435, 0xef97fe15}, | ||
2550 | {13400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2551 | /* END - DIF BPF register values from 134_quant.dat*/ | ||
2552 | |||
2553 | |||
2554 | /*case 13500000:*/ | ||
2555 | /* BEGIN - DIF BPF register values from 135_quant.dat*/ | ||
2556 | {13500000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2557 | {13500000, DIF_BPF_COEFF23, 0x0004000f}, | ||
2558 | {13500000, DIF_BPF_COEFF45, 0xffeaffda}, | ||
2559 | {13500000, DIF_BPF_COEFF67, 0x0046003d}, | ||
2560 | {13500000, DIF_BPF_COEFF89, 0xff5affc4}, | ||
2561 | {13500000, DIF_BPF_COEFF1011, 0x013b0000}, | ||
2562 | {13500000, DIF_BPF_COEFF1213, 0xfe04009d}, | ||
2563 | {13500000, DIF_BPF_COEFF1415, 0x02c8fe48}, | ||
2564 | {13500000, DIF_BPF_COEFF1617, 0xfc99035a}, | ||
2565 | {13500000, DIF_BPF_COEFF1819, 0x0397fa96}, | ||
2566 | {13500000, DIF_BPF_COEFF2021, 0xfcec07ad}, | ||
2567 | {13500000, DIF_BPF_COEFF2223, 0x01adf637}, | ||
2568 | {13500000, DIF_BPF_COEFF2425, 0x00ac0b53}, | ||
2569 | {13500000, DIF_BPF_COEFF2627, 0xfc2ef419}, | ||
2570 | {13500000, DIF_BPF_COEFF2829, 0x07730b3e}, | ||
2571 | {13500000, DIF_BPF_COEFF3031, 0xf4e9f6bd}, | ||
2572 | {13500000, DIF_BPF_COEFF3233, 0x0e35061a}, | ||
2573 | {13500000, DIF_BPF_COEFF3435, 0xefb1fddf}, | ||
2574 | {13500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2575 | /* END - DIF BPF register values from 135_quant.dat*/ | ||
2576 | |||
2577 | |||
2578 | /*case 13600000:*/ | ||
2579 | /* BEGIN - DIF BPF register values from 136_quant.dat*/ | ||
2580 | {13600000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2581 | {13600000, DIF_BPF_COEFF23, 0x00000012}, | ||
2582 | {13600000, DIF_BPF_COEFF45, 0xfff6ffcd}, | ||
2583 | {13600000, DIF_BPF_COEFF67, 0x002f0061}, | ||
2584 | {13600000, DIF_BPF_COEFF89, 0xff7bff79}, | ||
2585 | {13600000, DIF_BPF_COEFF1011, 0x011e007e}, | ||
2586 | {13600000, DIF_BPF_COEFF1213, 0xfe08ffe8}, | ||
2587 | {13600000, DIF_BPF_COEFF1415, 0x02f9ff28}, | ||
2588 | {13600000, DIF_BPF_COEFF1617, 0xfc17026a}, | ||
2589 | {13600000, DIF_BPF_COEFF1819, 0x0479fb70}, | ||
2590 | {13600000, DIF_BPF_COEFF2021, 0xfbad0713}, | ||
2591 | {13600000, DIF_BPF_COEFF2223, 0x032ff672}, | ||
2592 | {13600000, DIF_BPF_COEFF2425, 0xff100b83}, | ||
2593 | {13600000, DIF_BPF_COEFF2627, 0xfdaff38b}, | ||
2594 | {13600000, DIF_BPF_COEFF2829, 0x063c0c04}, | ||
2595 | {13600000, DIF_BPF_COEFF3031, 0xf5baf5f5}, | ||
2596 | {13600000, DIF_BPF_COEFF3233, 0x0dcc06ae}, | ||
2597 | {13600000, DIF_BPF_COEFF3435, 0xefcdfda8}, | ||
2598 | {13600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2599 | /* END - DIF BPF register values from 136_quant.dat*/ | ||
2600 | |||
2601 | |||
2602 | /*case 13700000:*/ | ||
2603 | /* BEGIN - DIF BPF register values from 137_quant.dat*/ | ||
2604 | {13700000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2605 | {13700000, DIF_BPF_COEFF23, 0xfffd0012}, | ||
2606 | {13700000, DIF_BPF_COEFF45, 0x0004ffc8}, | ||
2607 | {13700000, DIF_BPF_COEFF67, 0x00100078}, | ||
2608 | {13700000, DIF_BPF_COEFF89, 0xffacff3e}, | ||
2609 | {13700000, DIF_BPF_COEFF1011, 0x00e200f0}, | ||
2610 | {13700000, DIF_BPF_COEFF1213, 0xfe39ff35}, | ||
2611 | {13700000, DIF_BPF_COEFF1415, 0x02f10017}, | ||
2612 | {13700000, DIF_BPF_COEFF1617, 0xfbd30156}, | ||
2613 | {13700000, DIF_BPF_COEFF1819, 0x0521fc7f}, | ||
2614 | {13700000, DIF_BPF_COEFF2021, 0xfa9c0638}, | ||
2615 | {13700000, DIF_BPF_COEFF2223, 0x0499f6ee}, | ||
2616 | {13700000, DIF_BPF_COEFF2425, 0xfd7a0b7c}, | ||
2617 | {13700000, DIF_BPF_COEFF2627, 0xff39f325}, | ||
2618 | {13700000, DIF_BPF_COEFF2829, 0x04f40cb3}, | ||
2619 | {13700000, DIF_BPF_COEFF3031, 0xf69af537}, | ||
2620 | {13700000, DIF_BPF_COEFF3233, 0x0d5a073f}, | ||
2621 | {13700000, DIF_BPF_COEFF3435, 0xefecfd72}, | ||
2622 | {13700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2623 | /* END - DIF BPF register values from 137_quant.dat*/ | ||
2624 | |||
2625 | |||
2626 | /*case 13800000:*/ | ||
2627 | /* BEGIN - DIF BPF register values from 138_quant.dat*/ | ||
2628 | {13800000, DIF_BPF_COEFF01, 0x0001fffe}, | ||
2629 | {13800000, DIF_BPF_COEFF23, 0xfffa000e}, | ||
2630 | {13800000, DIF_BPF_COEFF45, 0x0011ffcb}, | ||
2631 | {13800000, DIF_BPF_COEFF67, 0xfff0007f}, | ||
2632 | {13800000, DIF_BPF_COEFF89, 0xffe7ff19}, | ||
2633 | {13800000, DIF_BPF_COEFF1011, 0x008f014a}, | ||
2634 | {13800000, DIF_BPF_COEFF1213, 0xfe94fe93}, | ||
2635 | {13800000, DIF_BPF_COEFF1415, 0x02b00105}, | ||
2636 | {13800000, DIF_BPF_COEFF1617, 0xfbd3002f}, | ||
2637 | {13800000, DIF_BPF_COEFF1819, 0x0585fdb7}, | ||
2638 | {13800000, DIF_BPF_COEFF2021, 0xf9c10525}, | ||
2639 | {13800000, DIF_BPF_COEFF2223, 0x05def7a8}, | ||
2640 | {13800000, DIF_BPF_COEFF2425, 0xfbf20b3c}, | ||
2641 | {13800000, DIF_BPF_COEFF2627, 0x00c7f2e9}, | ||
2642 | {13800000, DIF_BPF_COEFF2829, 0x03a00d48}, | ||
2643 | {13800000, DIF_BPF_COEFF3031, 0xf787f484}, | ||
2644 | {13800000, DIF_BPF_COEFF3233, 0x0cdf07cd}, | ||
2645 | {13800000, DIF_BPF_COEFF3435, 0xf00dfd3c}, | ||
2646 | {13800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2647 | /* END - DIF BPF register values from 138_quant.dat*/ | ||
2648 | |||
2649 | |||
2650 | /*case 13900000:*/ | ||
2651 | /* BEGIN - DIF BPF register values from 139_quant.dat*/ | ||
2652 | {13900000, DIF_BPF_COEFF01, 0x00010000}, | ||
2653 | {13900000, DIF_BPF_COEFF23, 0xfff80008}, | ||
2654 | {13900000, DIF_BPF_COEFF45, 0x001bffd7}, | ||
2655 | {13900000, DIF_BPF_COEFF67, 0xffd10076}, | ||
2656 | {13900000, DIF_BPF_COEFF89, 0x0026ff0e}, | ||
2657 | {13900000, DIF_BPF_COEFF1011, 0x002c0184}, | ||
2658 | {13900000, DIF_BPF_COEFF1213, 0xff0ffe10}, | ||
2659 | {13900000, DIF_BPF_COEFF1415, 0x023b01e0}, | ||
2660 | {13900000, DIF_BPF_COEFF1617, 0xfc17ff06}, | ||
2661 | {13900000, DIF_BPF_COEFF1819, 0x05a2ff09}, | ||
2662 | {13900000, DIF_BPF_COEFF2021, 0xf92703e4}, | ||
2663 | {13900000, DIF_BPF_COEFF2223, 0x06f4f89b}, | ||
2664 | {13900000, DIF_BPF_COEFF2425, 0xfa820ac5}, | ||
2665 | {13900000, DIF_BPF_COEFF2627, 0x0251f2d9}, | ||
2666 | {13900000, DIF_BPF_COEFF2829, 0x02430dc3}, | ||
2667 | {13900000, DIF_BPF_COEFF3031, 0xf881f3dc}, | ||
2668 | {13900000, DIF_BPF_COEFF3233, 0x0c5c0859}, | ||
2669 | {13900000, DIF_BPF_COEFF3435, 0xf031fd06}, | ||
2670 | {13900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2671 | /* END - DIF BPF register values from 139_quant.dat*/ | ||
2672 | |||
2673 | |||
2674 | /*case 14000000:*/ | ||
2675 | /* BEGIN - DIF BPF register values from 140_quant.dat*/ | ||
2676 | {14000000, DIF_BPF_COEFF01, 0x00010001}, | ||
2677 | {14000000, DIF_BPF_COEFF23, 0xfff80001}, | ||
2678 | {14000000, DIF_BPF_COEFF45, 0x0021ffe8}, | ||
2679 | {14000000, DIF_BPF_COEFF67, 0xffba005d}, | ||
2680 | {14000000, DIF_BPF_COEFF89, 0x0060ff1f}, | ||
2681 | {14000000, DIF_BPF_COEFF1011, 0xffc40198}, | ||
2682 | {14000000, DIF_BPF_COEFF1213, 0xffa0fdb5}, | ||
2683 | {14000000, DIF_BPF_COEFF1415, 0x019a029a}, | ||
2684 | {14000000, DIF_BPF_COEFF1617, 0xfc99fdea}, | ||
2685 | {14000000, DIF_BPF_COEFF1819, 0x05750067}, | ||
2686 | {14000000, DIF_BPF_COEFF2021, 0xf8d4027f}, | ||
2687 | {14000000, DIF_BPF_COEFF2223, 0x07d4f9c0}, | ||
2688 | {14000000, DIF_BPF_COEFF2425, 0xf9320a1a}, | ||
2689 | {14000000, DIF_BPF_COEFF2627, 0x03d2f2f3}, | ||
2690 | {14000000, DIF_BPF_COEFF2829, 0x00df0e22}, | ||
2691 | {14000000, DIF_BPF_COEFF3031, 0xf986f341}, | ||
2692 | {14000000, DIF_BPF_COEFF3233, 0x0bd108e2}, | ||
2693 | {14000000, DIF_BPF_COEFF3435, 0xf058fcd1}, | ||
2694 | {14000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2695 | /* END - DIF BPF register values from 140_quant.dat*/ | ||
2696 | |||
2697 | |||
2698 | /*case 14100000:*/ | ||
2699 | /* BEGIN - DIF BPF register values from 141_quant.dat*/ | ||
2700 | {14100000, DIF_BPF_COEFF01, 0x00000002}, | ||
2701 | {14100000, DIF_BPF_COEFF23, 0xfff9fffa}, | ||
2702 | {14100000, DIF_BPF_COEFF45, 0x0021fffd}, | ||
2703 | {14100000, DIF_BPF_COEFF67, 0xffac0038}, | ||
2704 | {14100000, DIF_BPF_COEFF89, 0x008eff4a}, | ||
2705 | {14100000, DIF_BPF_COEFF1011, 0xff630184}, | ||
2706 | {14100000, DIF_BPF_COEFF1213, 0x003afd8b}, | ||
2707 | {14100000, DIF_BPF_COEFF1415, 0x00da0326}, | ||
2708 | {14100000, DIF_BPF_COEFF1617, 0xfd51fced}, | ||
2709 | {14100000, DIF_BPF_COEFF1819, 0x050101c0}, | ||
2710 | {14100000, DIF_BPF_COEFF2021, 0xf8cb0103}, | ||
2711 | {14100000, DIF_BPF_COEFF2223, 0x0876fb10}, | ||
2712 | {14100000, DIF_BPF_COEFF2425, 0xf80a093e}, | ||
2713 | {14100000, DIF_BPF_COEFF2627, 0x0543f338}, | ||
2714 | {14100000, DIF_BPF_COEFF2829, 0xff7a0e66}, | ||
2715 | {14100000, DIF_BPF_COEFF3031, 0xfa94f2b2}, | ||
2716 | {14100000, DIF_BPF_COEFF3233, 0x0b3f0967}, | ||
2717 | {14100000, DIF_BPF_COEFF3435, 0xf081fc9b}, | ||
2718 | {14100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2719 | /* END - DIF BPF register values from 141_quant.dat*/ | ||
2720 | |||
2721 | |||
2722 | /*case 14200000:*/ | ||
2723 | /* BEGIN - DIF BPF register values from 142_quant.dat*/ | ||
2724 | {14200000, DIF_BPF_COEFF01, 0x00000003}, | ||
2725 | {14200000, DIF_BPF_COEFF23, 0xfffbfff3}, | ||
2726 | {14200000, DIF_BPF_COEFF45, 0x001d0013}, | ||
2727 | {14200000, DIF_BPF_COEFF67, 0xffaa000b}, | ||
2728 | {14200000, DIF_BPF_COEFF89, 0x00aaff89}, | ||
2729 | {14200000, DIF_BPF_COEFF1011, 0xff13014a}, | ||
2730 | {14200000, DIF_BPF_COEFF1213, 0x00cefd95}, | ||
2731 | {14200000, DIF_BPF_COEFF1415, 0x000a037b}, | ||
2732 | {14200000, DIF_BPF_COEFF1617, 0xfe35fc1d}, | ||
2733 | {14200000, DIF_BPF_COEFF1819, 0x044c0305}, | ||
2734 | {14200000, DIF_BPF_COEFF2021, 0xf90cff7e}, | ||
2735 | {14200000, DIF_BPF_COEFF2223, 0x08d5fc81}, | ||
2736 | {14200000, DIF_BPF_COEFF2425, 0xf7100834}, | ||
2737 | {14200000, DIF_BPF_COEFF2627, 0x069ff3a7}, | ||
2738 | {14200000, DIF_BPF_COEFF2829, 0xfe160e8d}, | ||
2739 | {14200000, DIF_BPF_COEFF3031, 0xfbaaf231}, | ||
2740 | {14200000, DIF_BPF_COEFF3233, 0x0aa509e9}, | ||
2741 | {14200000, DIF_BPF_COEFF3435, 0xf0adfc65}, | ||
2742 | {14200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2743 | /* END - DIF BPF register values from 142_quant.dat*/ | ||
2744 | |||
2745 | |||
2746 | /*case 14300000:*/ | ||
2747 | /* BEGIN - DIF BPF register values from 143_quant.dat*/ | ||
2748 | {14300000, DIF_BPF_COEFF01, 0x00000003}, | ||
2749 | {14300000, DIF_BPF_COEFF23, 0xffffffef}, | ||
2750 | {14300000, DIF_BPF_COEFF45, 0x00140025}, | ||
2751 | {14300000, DIF_BPF_COEFF67, 0xffb4ffdd}, | ||
2752 | {14300000, DIF_BPF_COEFF89, 0x00b2ffd6}, | ||
2753 | {14300000, DIF_BPF_COEFF1011, 0xfedb00f0}, | ||
2754 | {14300000, DIF_BPF_COEFF1213, 0x0150fdd3}, | ||
2755 | {14300000, DIF_BPF_COEFF1415, 0xff380391}, | ||
2756 | {14300000, DIF_BPF_COEFF1617, 0xff36fb85}, | ||
2757 | {14300000, DIF_BPF_COEFF1819, 0x035e0426}, | ||
2758 | {14300000, DIF_BPF_COEFF2021, 0xf994fdfe}, | ||
2759 | {14300000, DIF_BPF_COEFF2223, 0x08eefe0b}, | ||
2760 | {14300000, DIF_BPF_COEFF2425, 0xf6490702}, | ||
2761 | {14300000, DIF_BPF_COEFF2627, 0x07e1f43e}, | ||
2762 | {14300000, DIF_BPF_COEFF2829, 0xfcb60e97}, | ||
2763 | {14300000, DIF_BPF_COEFF3031, 0xfcc6f1be}, | ||
2764 | {14300000, DIF_BPF_COEFF3233, 0x0a040a67}, | ||
2765 | {14300000, DIF_BPF_COEFF3435, 0xf0dbfc30}, | ||
2766 | {14300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2767 | /* END - DIF BPF register values from 143_quant.dat*/ | ||
2768 | |||
2769 | |||
2770 | /*case 14400000:*/ | ||
2771 | /* BEGIN - DIF BPF register values from 144_quant.dat*/ | ||
2772 | {14400000, DIF_BPF_COEFF01, 0x00000003}, | ||
2773 | {14400000, DIF_BPF_COEFF23, 0x0002ffee}, | ||
2774 | {14400000, DIF_BPF_COEFF45, 0x00070033}, | ||
2775 | {14400000, DIF_BPF_COEFF67, 0xffc9ffb4}, | ||
2776 | {14400000, DIF_BPF_COEFF89, 0x00a40027}, | ||
2777 | {14400000, DIF_BPF_COEFF1011, 0xfec3007e}, | ||
2778 | {14400000, DIF_BPF_COEFF1213, 0x01b4fe3f}, | ||
2779 | {14400000, DIF_BPF_COEFF1415, 0xfe760369}, | ||
2780 | {14400000, DIF_BPF_COEFF1617, 0x0044fb2e}, | ||
2781 | {14400000, DIF_BPF_COEFF1819, 0x02450518}, | ||
2782 | {14400000, DIF_BPF_COEFF2021, 0xfa5ffc90}, | ||
2783 | {14400000, DIF_BPF_COEFF2223, 0x08c1ffa1}, | ||
2784 | {14400000, DIF_BPF_COEFF2425, 0xf5bc05ae}, | ||
2785 | {14400000, DIF_BPF_COEFF2627, 0x0902f4fc}, | ||
2786 | {14400000, DIF_BPF_COEFF2829, 0xfb600e85}, | ||
2787 | {14400000, DIF_BPF_COEFF3031, 0xfde7f15a}, | ||
2788 | {14400000, DIF_BPF_COEFF3233, 0x095d0ae2}, | ||
2789 | {14400000, DIF_BPF_COEFF3435, 0xf10cfbfb}, | ||
2790 | {14400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2791 | /* END - DIF BPF register values from 144_quant.dat*/ | ||
2792 | |||
2793 | |||
2794 | /*case 14500000:*/ | ||
2795 | /* BEGIN - DIF BPF register values from 145_quant.dat*/ | ||
2796 | {14500000, DIF_BPF_COEFF01, 0xffff0002}, | ||
2797 | {14500000, DIF_BPF_COEFF23, 0x0005ffef}, | ||
2798 | {14500000, DIF_BPF_COEFF45, 0xfffa0038}, | ||
2799 | {14500000, DIF_BPF_COEFF67, 0xffe5ff95}, | ||
2800 | {14500000, DIF_BPF_COEFF89, 0x00820074}, | ||
2801 | {14500000, DIF_BPF_COEFF1011, 0xfecc0000}, | ||
2802 | {14500000, DIF_BPF_COEFF1213, 0x01f0fed0}, | ||
2803 | {14500000, DIF_BPF_COEFF1415, 0xfdd20304}, | ||
2804 | {14500000, DIF_BPF_COEFF1617, 0x014dfb1d}, | ||
2805 | {14500000, DIF_BPF_COEFF1819, 0x010e05ce}, | ||
2806 | {14500000, DIF_BPF_COEFF2021, 0xfb64fb41}, | ||
2807 | {14500000, DIF_BPF_COEFF2223, 0x084e013b}, | ||
2808 | {14500000, DIF_BPF_COEFF2425, 0xf569043e}, | ||
2809 | {14500000, DIF_BPF_COEFF2627, 0x0a00f5dd}, | ||
2810 | {14500000, DIF_BPF_COEFF2829, 0xfa150e55}, | ||
2811 | {14500000, DIF_BPF_COEFF3031, 0xff0bf104}, | ||
2812 | {14500000, DIF_BPF_COEFF3233, 0x08b00b59}, | ||
2813 | {14500000, DIF_BPF_COEFF3435, 0xf13ffbc6}, | ||
2814 | {14500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2815 | /* END - DIF BPF register values from 145_quant.dat*/ | ||
2816 | |||
2817 | |||
2818 | /*case 14600000:*/ | ||
2819 | /* BEGIN - DIF BPF register values from 146_quant.dat*/ | ||
2820 | {14600000, DIF_BPF_COEFF01, 0xffff0001}, | ||
2821 | {14600000, DIF_BPF_COEFF23, 0x0008fff4}, | ||
2822 | {14600000, DIF_BPF_COEFF45, 0xffed0035}, | ||
2823 | {14600000, DIF_BPF_COEFF67, 0x0005ff83}, | ||
2824 | {14600000, DIF_BPF_COEFF89, 0x005000b4}, | ||
2825 | {14600000, DIF_BPF_COEFF1011, 0xfef6ff82}, | ||
2826 | {14600000, DIF_BPF_COEFF1213, 0x01ffff7a}, | ||
2827 | {14600000, DIF_BPF_COEFF1415, 0xfd580269}, | ||
2828 | {14600000, DIF_BPF_COEFF1617, 0x0241fb53}, | ||
2829 | {14600000, DIF_BPF_COEFF1819, 0xffca0640}, | ||
2830 | {14600000, DIF_BPF_COEFF2021, 0xfc99fa1e}, | ||
2831 | {14600000, DIF_BPF_COEFF2223, 0x079a02cb}, | ||
2832 | {14600000, DIF_BPF_COEFF2425, 0xf55502ba}, | ||
2833 | {14600000, DIF_BPF_COEFF2627, 0x0ad5f6e0}, | ||
2834 | {14600000, DIF_BPF_COEFF2829, 0xf8d90e0a}, | ||
2835 | {14600000, DIF_BPF_COEFF3031, 0x0031f0bd}, | ||
2836 | {14600000, DIF_BPF_COEFF3233, 0x07fd0bcb}, | ||
2837 | {14600000, DIF_BPF_COEFF3435, 0xf174fb91}, | ||
2838 | {14600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2839 | /* END - DIF BPF register values from 146_quant.dat*/ | ||
2840 | |||
2841 | |||
2842 | /*case 14700000:*/ | ||
2843 | /* BEGIN - DIF BPF register values from 147_quant.dat*/ | ||
2844 | {14700000, DIF_BPF_COEFF01, 0xffffffff}, | ||
2845 | {14700000, DIF_BPF_COEFF23, 0x0009fffb}, | ||
2846 | {14700000, DIF_BPF_COEFF45, 0xffe4002a}, | ||
2847 | {14700000, DIF_BPF_COEFF67, 0x0025ff82}, | ||
2848 | {14700000, DIF_BPF_COEFF89, 0x001400e0}, | ||
2849 | {14700000, DIF_BPF_COEFF1011, 0xff3cff10}, | ||
2850 | {14700000, DIF_BPF_COEFF1213, 0x01e10030}, | ||
2851 | {14700000, DIF_BPF_COEFF1415, 0xfd1201a4}, | ||
2852 | {14700000, DIF_BPF_COEFF1617, 0x0311fbcd}, | ||
2853 | {14700000, DIF_BPF_COEFF1819, 0xfe88066a}, | ||
2854 | {14700000, DIF_BPF_COEFF2021, 0xfdf1f92f}, | ||
2855 | {14700000, DIF_BPF_COEFF2223, 0x06aa0449}, | ||
2856 | {14700000, DIF_BPF_COEFF2425, 0xf57e0128}, | ||
2857 | {14700000, DIF_BPF_COEFF2627, 0x0b7ef801}, | ||
2858 | {14700000, DIF_BPF_COEFF2829, 0xf7b00da2}, | ||
2859 | {14700000, DIF_BPF_COEFF3031, 0x0156f086}, | ||
2860 | {14700000, DIF_BPF_COEFF3233, 0x07450c39}, | ||
2861 | {14700000, DIF_BPF_COEFF3435, 0xf1acfb5c}, | ||
2862 | {14700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2863 | /* END - DIF BPF register values from 147_quant.dat*/ | ||
2864 | |||
2865 | |||
2866 | /*case 14800000:*/ | ||
2867 | /* BEGIN - DIF BPF register values from 148_quant.dat*/ | ||
2868 | {14800000, DIF_BPF_COEFF01, 0x0000fffe}, | ||
2869 | {14800000, DIF_BPF_COEFF23, 0x00080002}, | ||
2870 | {14800000, DIF_BPF_COEFF45, 0xffdf0019}, | ||
2871 | {14800000, DIF_BPF_COEFF67, 0x003fff92}, | ||
2872 | {14800000, DIF_BPF_COEFF89, 0xffd600f1}, | ||
2873 | {14800000, DIF_BPF_COEFF1011, 0xff96feb6}, | ||
2874 | {14800000, DIF_BPF_COEFF1213, 0x019700e1}, | ||
2875 | {14800000, DIF_BPF_COEFF1415, 0xfd0500c2}, | ||
2876 | {14800000, DIF_BPF_COEFF1617, 0x03b0fc84}, | ||
2877 | {14800000, DIF_BPF_COEFF1819, 0xfd590649}, | ||
2878 | {14800000, DIF_BPF_COEFF2021, 0xff5df87f}, | ||
2879 | {14800000, DIF_BPF_COEFF2223, 0x058505aa}, | ||
2880 | {14800000, DIF_BPF_COEFF2425, 0xf5e4ff91}, | ||
2881 | {14800000, DIF_BPF_COEFF2627, 0x0bf9f93c}, | ||
2882 | {14800000, DIF_BPF_COEFF2829, 0xf69d0d20}, | ||
2883 | {14800000, DIF_BPF_COEFF3031, 0x0279f05e}, | ||
2884 | {14800000, DIF_BPF_COEFF3233, 0x06880ca3}, | ||
2885 | {14800000, DIF_BPF_COEFF3435, 0xf1e6fb28}, | ||
2886 | {14800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2887 | /* END - DIF BPF register values from 148_quant.dat*/ | ||
2888 | |||
2889 | |||
2890 | /*case 14900000:*/ | ||
2891 | /* BEGIN - DIF BPF register values from 149_quant.dat*/ | ||
2892 | {14900000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2893 | {14900000, DIF_BPF_COEFF23, 0x00060009}, | ||
2894 | {14900000, DIF_BPF_COEFF45, 0xffdf0004}, | ||
2895 | {14900000, DIF_BPF_COEFF67, 0x0051ffb0}, | ||
2896 | {14900000, DIF_BPF_COEFF89, 0xff9d00e8}, | ||
2897 | {14900000, DIF_BPF_COEFF1011, 0xfffcfe7c}, | ||
2898 | {14900000, DIF_BPF_COEFF1213, 0x01280180}, | ||
2899 | {14900000, DIF_BPF_COEFF1415, 0xfd32ffd2}, | ||
2900 | {14900000, DIF_BPF_COEFF1617, 0x0413fd6e}, | ||
2901 | {14900000, DIF_BPF_COEFF1819, 0xfc4d05df}, | ||
2902 | {14900000, DIF_BPF_COEFF2021, 0x00d1f812}, | ||
2903 | {14900000, DIF_BPF_COEFF2223, 0x043506e4}, | ||
2904 | {14900000, DIF_BPF_COEFF2425, 0xf685fdfb}, | ||
2905 | {14900000, DIF_BPF_COEFF2627, 0x0c43fa8d}, | ||
2906 | {14900000, DIF_BPF_COEFF2829, 0xf5a10c83}, | ||
2907 | {14900000, DIF_BPF_COEFF3031, 0x0399f046}, | ||
2908 | {14900000, DIF_BPF_COEFF3233, 0x05c70d08}, | ||
2909 | {14900000, DIF_BPF_COEFF3435, 0xf222faf3}, | ||
2910 | {14900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2911 | /* END - DIF BPF register values from 149_quant.dat*/ | ||
2912 | |||
2913 | |||
2914 | /*case 15000000:*/ | ||
2915 | /* BEGIN - DIF BPF register values from 150_quant.dat*/ | ||
2916 | {15000000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2917 | {15000000, DIF_BPF_COEFF23, 0x0003000f}, | ||
2918 | {15000000, DIF_BPF_COEFF45, 0xffe5ffef}, | ||
2919 | {15000000, DIF_BPF_COEFF67, 0x0057ffd9}, | ||
2920 | {15000000, DIF_BPF_COEFF89, 0xff7000c4}, | ||
2921 | {15000000, DIF_BPF_COEFF1011, 0x0062fe68}, | ||
2922 | {15000000, DIF_BPF_COEFF1213, 0x009e01ff}, | ||
2923 | {15000000, DIF_BPF_COEFF1415, 0xfd95fee6}, | ||
2924 | {15000000, DIF_BPF_COEFF1617, 0x0435fe7d}, | ||
2925 | {15000000, DIF_BPF_COEFF1819, 0xfb710530}, | ||
2926 | {15000000, DIF_BPF_COEFF2021, 0x023cf7ee}, | ||
2927 | {15000000, DIF_BPF_COEFF2223, 0x02c307ef}, | ||
2928 | {15000000, DIF_BPF_COEFF2425, 0xf75efc70}, | ||
2929 | {15000000, DIF_BPF_COEFF2627, 0x0c5cfbef}, | ||
2930 | {15000000, DIF_BPF_COEFF2829, 0xf4c10bce}, | ||
2931 | {15000000, DIF_BPF_COEFF3031, 0x04b3f03f}, | ||
2932 | {15000000, DIF_BPF_COEFF3233, 0x05030d69}, | ||
2933 | {15000000, DIF_BPF_COEFF3435, 0xf261fabf}, | ||
2934 | {15000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2935 | /* END - DIF BPF register values from 150_quant.dat*/ | ||
2936 | |||
2937 | |||
2938 | /*case 15100000:*/ | ||
2939 | /* BEGIN - DIF BPF register values from 151_quant.dat*/ | ||
2940 | {15100000, DIF_BPF_COEFF01, 0x0000fffd}, | ||
2941 | {15100000, DIF_BPF_COEFF23, 0xffff0012}, | ||
2942 | {15100000, DIF_BPF_COEFF45, 0xffefffdc}, | ||
2943 | {15100000, DIF_BPF_COEFF67, 0x00510006}, | ||
2944 | {15100000, DIF_BPF_COEFF89, 0xff540089}, | ||
2945 | {15100000, DIF_BPF_COEFF1011, 0x00befe7c}, | ||
2946 | {15100000, DIF_BPF_COEFF1213, 0x00060253}, | ||
2947 | {15100000, DIF_BPF_COEFF1415, 0xfe27fe0d}, | ||
2948 | {15100000, DIF_BPF_COEFF1617, 0x0413ffa2}, | ||
2949 | {15100000, DIF_BPF_COEFF1819, 0xfad10446}, | ||
2950 | {15100000, DIF_BPF_COEFF2021, 0x0390f812}, | ||
2951 | {15100000, DIF_BPF_COEFF2223, 0x013b08c3}, | ||
2952 | {15100000, DIF_BPF_COEFF2425, 0xf868faf6}, | ||
2953 | {15100000, DIF_BPF_COEFF2627, 0x0c43fd5f}, | ||
2954 | {15100000, DIF_BPF_COEFF2829, 0xf3fd0b02}, | ||
2955 | {15100000, DIF_BPF_COEFF3031, 0x05c7f046}, | ||
2956 | {15100000, DIF_BPF_COEFF3233, 0x043b0dc4}, | ||
2957 | {15100000, DIF_BPF_COEFF3435, 0xf2a1fa8b}, | ||
2958 | {15100000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2959 | /* END - DIF BPF register values from 151_quant.dat*/ | ||
2960 | |||
2961 | |||
2962 | /*case 15200000:*/ | ||
2963 | /* BEGIN - DIF BPF register values from 152_quant.dat*/ | ||
2964 | {15200000, DIF_BPF_COEFF01, 0x0001fffe}, | ||
2965 | {15200000, DIF_BPF_COEFF23, 0xfffc0012}, | ||
2966 | {15200000, DIF_BPF_COEFF45, 0xfffbffce}, | ||
2967 | {15200000, DIF_BPF_COEFF67, 0x003f0033}, | ||
2968 | {15200000, DIF_BPF_COEFF89, 0xff4e003f}, | ||
2969 | {15200000, DIF_BPF_COEFF1011, 0x0106feb6}, | ||
2970 | {15200000, DIF_BPF_COEFF1213, 0xff6e0276}, | ||
2971 | {15200000, DIF_BPF_COEFF1415, 0xfeddfd56}, | ||
2972 | {15200000, DIF_BPF_COEFF1617, 0x03b000cc}, | ||
2973 | {15200000, DIF_BPF_COEFF1819, 0xfa740329}, | ||
2974 | {15200000, DIF_BPF_COEFF2021, 0x04bff87f}, | ||
2975 | {15200000, DIF_BPF_COEFF2223, 0xffaa095d}, | ||
2976 | {15200000, DIF_BPF_COEFF2425, 0xf99ef995}, | ||
2977 | {15200000, DIF_BPF_COEFF2627, 0x0bf9fed8}, | ||
2978 | {15200000, DIF_BPF_COEFF2829, 0xf3590a1f}, | ||
2979 | {15200000, DIF_BPF_COEFF3031, 0x06d2f05e}, | ||
2980 | {15200000, DIF_BPF_COEFF3233, 0x03700e1b}, | ||
2981 | {15200000, DIF_BPF_COEFF3435, 0xf2e4fa58}, | ||
2982 | {15200000, DIF_BPF_COEFF36, 0x110d0000}, | ||
2983 | /* END - DIF BPF register values from 152_quant.dat*/ | ||
2984 | |||
2985 | |||
2986 | /*case 115300000:*/ | ||
2987 | /* BEGIN - DIF BPF register values from 153_quant.dat*/ | ||
2988 | {15300000, DIF_BPF_COEFF01, 0x0001ffff}, | ||
2989 | {15300000, DIF_BPF_COEFF23, 0xfff9000f}, | ||
2990 | {15300000, DIF_BPF_COEFF45, 0x0009ffc8}, | ||
2991 | {15300000, DIF_BPF_COEFF67, 0x00250059}, | ||
2992 | {15300000, DIF_BPF_COEFF89, 0xff5effee}, | ||
2993 | {15300000, DIF_BPF_COEFF1011, 0x0132ff10}, | ||
2994 | {15300000, DIF_BPF_COEFF1213, 0xfee30265}, | ||
2995 | {15300000, DIF_BPF_COEFF1415, 0xffaafccf}, | ||
2996 | {15300000, DIF_BPF_COEFF1617, 0x031101eb}, | ||
2997 | {15300000, DIF_BPF_COEFF1819, 0xfa6001e8}, | ||
2998 | {15300000, DIF_BPF_COEFF2021, 0x05bdf92f}, | ||
2999 | {15300000, DIF_BPF_COEFF2223, 0xfe1b09b6}, | ||
3000 | {15300000, DIF_BPF_COEFF2425, 0xfafaf852}, | ||
3001 | {15300000, DIF_BPF_COEFF2627, 0x0b7e0055}, | ||
3002 | {15300000, DIF_BPF_COEFF2829, 0xf2d50929}, | ||
3003 | {15300000, DIF_BPF_COEFF3031, 0x07d3f086}, | ||
3004 | {15300000, DIF_BPF_COEFF3233, 0x02a30e6c}, | ||
3005 | {15300000, DIF_BPF_COEFF3435, 0xf329fa24}, | ||
3006 | {15300000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3007 | /* END - DIF BPF register values from 153_quant.dat*/ | ||
3008 | |||
3009 | |||
3010 | /*case 115400000:*/ | ||
3011 | /* BEGIN - DIF BPF register values from 154_quant.dat*/ | ||
3012 | {15400000, DIF_BPF_COEFF01, 0x00010001}, | ||
3013 | {15400000, DIF_BPF_COEFF23, 0xfff80009}, | ||
3014 | {15400000, DIF_BPF_COEFF45, 0x0015ffca}, | ||
3015 | {15400000, DIF_BPF_COEFF67, 0x00050074}, | ||
3016 | {15400000, DIF_BPF_COEFF89, 0xff81ff9f}, | ||
3017 | {15400000, DIF_BPF_COEFF1011, 0x013dff82}, | ||
3018 | {15400000, DIF_BPF_COEFF1213, 0xfe710221}, | ||
3019 | {15400000, DIF_BPF_COEFF1415, 0x007cfc80}, | ||
3020 | {15400000, DIF_BPF_COEFF1617, 0x024102ed}, | ||
3021 | {15400000, DIF_BPF_COEFF1819, 0xfa940090}, | ||
3022 | {15400000, DIF_BPF_COEFF2021, 0x0680fa1e}, | ||
3023 | {15400000, DIF_BPF_COEFF2223, 0xfc9b09cd}, | ||
3024 | {15400000, DIF_BPF_COEFF2425, 0xfc73f736}, | ||
3025 | {15400000, DIF_BPF_COEFF2627, 0x0ad501d0}, | ||
3026 | {15400000, DIF_BPF_COEFF2829, 0xf2740820}, | ||
3027 | {15400000, DIF_BPF_COEFF3031, 0x08c9f0bd}, | ||
3028 | {15400000, DIF_BPF_COEFF3233, 0x01d40eb9}, | ||
3029 | {15400000, DIF_BPF_COEFF3435, 0xf371f9f1}, | ||
3030 | {15400000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3031 | /* END - DIF BPF register values from 154_quant.dat*/ | ||
3032 | |||
3033 | |||
3034 | /*case 115500000:*/ | ||
3035 | /* BEGIN - DIF BPF register values from 155_quant.dat*/ | ||
3036 | {15500000, DIF_BPF_COEFF01, 0x00000002}, | ||
3037 | {15500000, DIF_BPF_COEFF23, 0xfff80002}, | ||
3038 | {15500000, DIF_BPF_COEFF45, 0x001effd5}, | ||
3039 | {15500000, DIF_BPF_COEFF67, 0xffe5007f}, | ||
3040 | {15500000, DIF_BPF_COEFF89, 0xffb4ff5b}, | ||
3041 | {15500000, DIF_BPF_COEFF1011, 0x01280000}, | ||
3042 | {15500000, DIF_BPF_COEFF1213, 0xfe2401b0}, | ||
3043 | {15500000, DIF_BPF_COEFF1415, 0x0146fc70}, | ||
3044 | {15500000, DIF_BPF_COEFF1617, 0x014d03c6}, | ||
3045 | {15500000, DIF_BPF_COEFF1819, 0xfb10ff32}, | ||
3046 | {15500000, DIF_BPF_COEFF2021, 0x0701fb41}, | ||
3047 | {15500000, DIF_BPF_COEFF2223, 0xfb3709a1}, | ||
3048 | {15500000, DIF_BPF_COEFF2425, 0xfe00f644}, | ||
3049 | {15500000, DIF_BPF_COEFF2627, 0x0a000345}, | ||
3050 | {15500000, DIF_BPF_COEFF2829, 0xf2350708}, | ||
3051 | {15500000, DIF_BPF_COEFF3031, 0x09b2f104}, | ||
3052 | {15500000, DIF_BPF_COEFF3233, 0x01050eff}, | ||
3053 | {15500000, DIF_BPF_COEFF3435, 0xf3baf9be}, | ||
3054 | {15500000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3055 | /* END - DIF BPF register values from 155_quant.dat*/ | ||
3056 | |||
3057 | |||
3058 | /*case 115600000:*/ | ||
3059 | /* BEGIN - DIF BPF register values from 156_quant.dat*/ | ||
3060 | {15600000, DIF_BPF_COEFF01, 0x00000003}, | ||
3061 | {15600000, DIF_BPF_COEFF23, 0xfff9fffb}, | ||
3062 | {15600000, DIF_BPF_COEFF45, 0x0022ffe6}, | ||
3063 | {15600000, DIF_BPF_COEFF67, 0xffc9007a}, | ||
3064 | {15600000, DIF_BPF_COEFF89, 0xfff0ff29}, | ||
3065 | {15600000, DIF_BPF_COEFF1011, 0x00f2007e}, | ||
3066 | {15600000, DIF_BPF_COEFF1213, 0xfe01011b}, | ||
3067 | {15600000, DIF_BPF_COEFF1415, 0x01f6fc9e}, | ||
3068 | {15600000, DIF_BPF_COEFF1617, 0x00440467}, | ||
3069 | {15600000, DIF_BPF_COEFF1819, 0xfbccfdde}, | ||
3070 | {15600000, DIF_BPF_COEFF2021, 0x0738fc90}, | ||
3071 | {15600000, DIF_BPF_COEFF2223, 0xf9f70934}, | ||
3072 | {15600000, DIF_BPF_COEFF2425, 0xff99f582}, | ||
3073 | {15600000, DIF_BPF_COEFF2627, 0x090204b0}, | ||
3074 | {15600000, DIF_BPF_COEFF2829, 0xf21a05e1}, | ||
3075 | {15600000, DIF_BPF_COEFF3031, 0x0a8df15a}, | ||
3076 | {15600000, DIF_BPF_COEFF3233, 0x00340f41}, | ||
3077 | {15600000, DIF_BPF_COEFF3435, 0xf405f98b}, | ||
3078 | {15600000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3079 | /* END - DIF BPF register values from 156_quant.dat*/ | ||
3080 | |||
3081 | |||
3082 | /*case 115700000:*/ | ||
3083 | /* BEGIN - DIF BPF register values from 157_quant.dat*/ | ||
3084 | {15700000, DIF_BPF_COEFF01, 0x00000003}, | ||
3085 | {15700000, DIF_BPF_COEFF23, 0xfffcfff4}, | ||
3086 | {15700000, DIF_BPF_COEFF45, 0x0020fffa}, | ||
3087 | {15700000, DIF_BPF_COEFF67, 0xffb40064}, | ||
3088 | {15700000, DIF_BPF_COEFF89, 0x002fff11}, | ||
3089 | {15700000, DIF_BPF_COEFF1011, 0x00a400f0}, | ||
3090 | {15700000, DIF_BPF_COEFF1213, 0xfe0d006e}, | ||
3091 | {15700000, DIF_BPF_COEFF1415, 0x0281fd09}, | ||
3092 | {15700000, DIF_BPF_COEFF1617, 0xff3604c9}, | ||
3093 | {15700000, DIF_BPF_COEFF1819, 0xfcbffca2}, | ||
3094 | {15700000, DIF_BPF_COEFF2021, 0x0726fdfe}, | ||
3095 | {15700000, DIF_BPF_COEFF2223, 0xf8e80888}, | ||
3096 | {15700000, DIF_BPF_COEFF2425, 0x0134f4f3}, | ||
3097 | {15700000, DIF_BPF_COEFF2627, 0x07e1060c}, | ||
3098 | {15700000, DIF_BPF_COEFF2829, 0xf22304af}, | ||
3099 | {15700000, DIF_BPF_COEFF3031, 0x0b59f1be}, | ||
3100 | {15700000, DIF_BPF_COEFF3233, 0xff640f7d}, | ||
3101 | {15700000, DIF_BPF_COEFF3435, 0xf452f959}, | ||
3102 | {15700000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3103 | /* END - DIF BPF register values from 157_quant.dat*/ | ||
3104 | |||
3105 | |||
3106 | /*case 115800000:*/ | ||
3107 | /* BEGIN - DIF BPF register values from 158_quant.dat*/ | ||
3108 | {15800000, DIF_BPF_COEFF01, 0x00000003}, | ||
3109 | {15800000, DIF_BPF_COEFF23, 0x0000fff0}, | ||
3110 | {15800000, DIF_BPF_COEFF45, 0x001a0010}, | ||
3111 | {15800000, DIF_BPF_COEFF67, 0xffaa0041}, | ||
3112 | {15800000, DIF_BPF_COEFF89, 0x0067ff13}, | ||
3113 | {15800000, DIF_BPF_COEFF1011, 0x0043014a}, | ||
3114 | {15800000, DIF_BPF_COEFF1213, 0xfe46ffb9}, | ||
3115 | {15800000, DIF_BPF_COEFF1415, 0x02dbfda8}, | ||
3116 | {15800000, DIF_BPF_COEFF1617, 0xfe3504e5}, | ||
3117 | {15800000, DIF_BPF_COEFF1819, 0xfddcfb8d}, | ||
3118 | {15800000, DIF_BPF_COEFF2021, 0x06c9ff7e}, | ||
3119 | {15800000, DIF_BPF_COEFF2223, 0xf81107a2}, | ||
3120 | {15800000, DIF_BPF_COEFF2425, 0x02c9f49a}, | ||
3121 | {15800000, DIF_BPF_COEFF2627, 0x069f0753}, | ||
3122 | {15800000, DIF_BPF_COEFF2829, 0xf2500373}, | ||
3123 | {15800000, DIF_BPF_COEFF3031, 0x0c14f231}, | ||
3124 | {15800000, DIF_BPF_COEFF3233, 0xfe930fb3}, | ||
3125 | {15800000, DIF_BPF_COEFF3435, 0xf4a1f927}, | ||
3126 | {15800000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3127 | /* END - DIF BPF register values from 158_quant.dat*/ | ||
3128 | |||
3129 | |||
3130 | /*case 115900000:*/ | ||
3131 | /* BEGIN - DIF BPF register values from 159_quant.dat*/ | ||
3132 | {15900000, DIF_BPF_COEFF01, 0xffff0002}, | ||
3133 | {15900000, DIF_BPF_COEFF23, 0x0003ffee}, | ||
3134 | {15900000, DIF_BPF_COEFF45, 0x000f0023}, | ||
3135 | {15900000, DIF_BPF_COEFF67, 0xffac0016}, | ||
3136 | {15900000, DIF_BPF_COEFF89, 0x0093ff31}, | ||
3137 | {15900000, DIF_BPF_COEFF1011, 0xffdc0184}, | ||
3138 | {15900000, DIF_BPF_COEFF1213, 0xfea6ff09}, | ||
3139 | {15900000, DIF_BPF_COEFF1415, 0x02fdfe70}, | ||
3140 | {15900000, DIF_BPF_COEFF1617, 0xfd5104ba}, | ||
3141 | {15900000, DIF_BPF_COEFF1819, 0xff15faac}, | ||
3142 | {15900000, DIF_BPF_COEFF2021, 0x06270103}, | ||
3143 | {15900000, DIF_BPF_COEFF2223, 0xf7780688}, | ||
3144 | {15900000, DIF_BPF_COEFF2425, 0x044df479}, | ||
3145 | {15900000, DIF_BPF_COEFF2627, 0x05430883}, | ||
3146 | {15900000, DIF_BPF_COEFF2829, 0xf2a00231}, | ||
3147 | {15900000, DIF_BPF_COEFF3031, 0x0cbef2b2}, | ||
3148 | {15900000, DIF_BPF_COEFF3233, 0xfdc40fe3}, | ||
3149 | {15900000, DIF_BPF_COEFF3435, 0xf4f2f8f5}, | ||
3150 | {15900000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3151 | /* END - DIF BPF register values from 159_quant.dat*/ | ||
3152 | |||
3153 | |||
3154 | /*case 116000000:*/ | ||
3155 | /* BEGIN - DIF BPF register values from 160_quant.dat*/ | ||
3156 | {16000000, DIF_BPF_COEFF01, 0xffff0001}, | ||
3157 | {16000000, DIF_BPF_COEFF23, 0x0006ffef}, | ||
3158 | {16000000, DIF_BPF_COEFF45, 0x00020031}, | ||
3159 | {16000000, DIF_BPF_COEFF67, 0xffbaffe8}, | ||
3160 | {16000000, DIF_BPF_COEFF89, 0x00adff66}, | ||
3161 | {16000000, DIF_BPF_COEFF1011, 0xff790198}, | ||
3162 | {16000000, DIF_BPF_COEFF1213, 0xff26fe6e}, | ||
3163 | {16000000, DIF_BPF_COEFF1415, 0x02e5ff55}, | ||
3164 | {16000000, DIF_BPF_COEFF1617, 0xfc99044a}, | ||
3165 | {16000000, DIF_BPF_COEFF1819, 0x005bfa09}, | ||
3166 | {16000000, DIF_BPF_COEFF2021, 0x0545027f}, | ||
3167 | {16000000, DIF_BPF_COEFF2223, 0xf7230541}, | ||
3168 | {16000000, DIF_BPF_COEFF2425, 0x05b8f490}, | ||
3169 | {16000000, DIF_BPF_COEFF2627, 0x03d20997}, | ||
3170 | {16000000, DIF_BPF_COEFF2829, 0xf31300eb}, | ||
3171 | {16000000, DIF_BPF_COEFF3031, 0x0d55f341}, | ||
3172 | {16000000, DIF_BPF_COEFF3233, 0xfcf6100e}, | ||
3173 | {16000000, DIF_BPF_COEFF3435, 0xf544f8c3}, | ||
3174 | {16000000, DIF_BPF_COEFF36, 0x110d0000}, | ||
3175 | /* END - DIF BPF register values from 160_quant.dat*/ | ||
3176 | }; | ||
3177 | |||
3178 | #endif | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c index 4ea3776b39f..5feb3ee640d 100644 --- a/drivers/media/video/cx231xx/cx231xx-dvb.c +++ b/drivers/media/video/cx231xx/cx231xx-dvb.c | |||
@@ -29,6 +29,10 @@ | |||
29 | 29 | ||
30 | #include "xc5000.h" | 30 | #include "xc5000.h" |
31 | #include "dvb_dummy_fe.h" | 31 | #include "dvb_dummy_fe.h" |
32 | #include "s5h1432.h" | ||
33 | #include "tda18271.h" | ||
34 | #include "s5h1411.h" | ||
35 | #include "lgdt3305.h" | ||
32 | 36 | ||
33 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); | 37 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); |
34 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); | 38 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); |
@@ -65,6 +69,72 @@ struct cx231xx_dvb { | |||
65 | struct dvb_net net; | 69 | struct dvb_net net; |
66 | }; | 70 | }; |
67 | 71 | ||
72 | static struct s5h1432_config dvico_s5h1432_config = { | ||
73 | .output_mode = S5H1432_SERIAL_OUTPUT, | ||
74 | .gpio = S5H1432_GPIO_ON, | ||
75 | .qam_if = S5H1432_IF_4000, | ||
76 | .vsb_if = S5H1432_IF_4000, | ||
77 | .inversion = S5H1432_INVERSION_OFF, | ||
78 | .status_mode = S5H1432_DEMODLOCKING, | ||
79 | .mpeg_timing = S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
80 | }; | ||
81 | |||
82 | static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { | ||
83 | .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4, | ||
84 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
85 | .dvbt_7 = { .if_freq = 4000, .agc_mode = 3, .std = 5, | ||
86 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
87 | .dvbt_8 = { .if_freq = 4000, .agc_mode = 3, .std = 6, | ||
88 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
89 | }; | ||
90 | |||
91 | static struct tda18271_config cnxt_rde253s_tunerconfig = { | ||
92 | .std_map = &cnxt_rde253s_tda18271_std_map, | ||
93 | .gate = TDA18271_GATE_ANALOG, | ||
94 | }; | ||
95 | |||
96 | static struct s5h1411_config tda18271_s5h1411_config = { | ||
97 | .output_mode = S5H1411_SERIAL_OUTPUT, | ||
98 | .gpio = S5H1411_GPIO_OFF, | ||
99 | .vsb_if = S5H1411_IF_3250, | ||
100 | .qam_if = S5H1411_IF_4000, | ||
101 | .inversion = S5H1411_INVERSION_ON, | ||
102 | .status_mode = S5H1411_DEMODLOCKING, | ||
103 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
104 | }; | ||
105 | static struct s5h1411_config xc5000_s5h1411_config = { | ||
106 | .output_mode = S5H1411_SERIAL_OUTPUT, | ||
107 | .gpio = S5H1411_GPIO_OFF, | ||
108 | .vsb_if = S5H1411_IF_3250, | ||
109 | .qam_if = S5H1411_IF_3250, | ||
110 | .inversion = S5H1411_INVERSION_OFF, | ||
111 | .status_mode = S5H1411_DEMODLOCKING, | ||
112 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
113 | }; | ||
114 | |||
115 | static struct lgdt3305_config hcw_lgdt3305_config = { | ||
116 | .i2c_addr = 0x0e, | ||
117 | .mpeg_mode = LGDT3305_MPEG_SERIAL, | ||
118 | .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, | ||
119 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
120 | .deny_i2c_rptr = 1, | ||
121 | .spectral_inversion = 1, | ||
122 | .qam_if_khz = 4000, | ||
123 | .vsb_if_khz = 3250, | ||
124 | }; | ||
125 | |||
126 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | ||
127 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, | ||
128 | .if_lvl = 1, .rfagc_top = 0x58, }, | ||
129 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, | ||
130 | .if_lvl = 1, .rfagc_top = 0x58, }, | ||
131 | }; | ||
132 | |||
133 | static struct tda18271_config hcw_tda18271_config = { | ||
134 | .std_map = &hauppauge_tda18271_std_map, | ||
135 | .gate = TDA18271_GATE_DIGITAL, | ||
136 | }; | ||
137 | |||
68 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) | 138 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) |
69 | { | 139 | { |
70 | char *errmsg = "Unknown"; | 140 | char *errmsg = "Unknown"; |
@@ -128,11 +198,33 @@ static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb) | |||
128 | continue; | 198 | continue; |
129 | } | 199 | } |
130 | 200 | ||
131 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + | 201 | dvb_dmx_swfilter(&dev->dvb->demux, |
132 | urb->iso_frame_desc[i].offset, | 202 | urb->transfer_buffer + |
133 | urb->iso_frame_desc[i].actual_length); | 203 | urb->iso_frame_desc[i].offset, |
204 | urb->iso_frame_desc[i].actual_length); | ||
205 | } | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb) | ||
211 | { | ||
212 | if (!dev) | ||
213 | return 0; | ||
214 | |||
215 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
216 | return 0; | ||
217 | |||
218 | if (urb->status < 0) { | ||
219 | print_err_status(dev, -1, urb->status); | ||
220 | if (urb->status == -ENOENT) | ||
221 | return 0; | ||
134 | } | 222 | } |
135 | 223 | ||
224 | /* Feed the transport payload into the kernel demux */ | ||
225 | dvb_dmx_swfilter(&dev->dvb->demux, | ||
226 | urb->transfer_buffer, urb->actual_length); | ||
227 | |||
136 | return 0; | 228 | return 0; |
137 | } | 229 | } |
138 | 230 | ||
@@ -141,21 +233,44 @@ static int start_streaming(struct cx231xx_dvb *dvb) | |||
141 | int rc; | 233 | int rc; |
142 | struct cx231xx *dev = dvb->adapter.priv; | 234 | struct cx231xx *dev = dvb->adapter.priv; |
143 | 235 | ||
144 | usb_set_interface(dev->udev, 0, 1); | 236 | if (dev->USE_ISO) { |
145 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | 237 | cx231xx_info("DVB transfer mode is ISO.\n"); |
146 | if (rc < 0) | 238 | mutex_lock(&dev->i2c_lock); |
147 | return rc; | 239 | cx231xx_enable_i2c_port_3(dev, false); |
240 | cx231xx_set_alt_setting(dev, INDEX_TS1, 4); | ||
241 | cx231xx_enable_i2c_port_3(dev, true); | ||
242 | mutex_unlock(&dev->i2c_lock); | ||
243 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | ||
244 | if (rc < 0) | ||
245 | return rc; | ||
246 | dev->mode_tv = 1; | ||
247 | return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS, | ||
248 | CX231XX_DVB_NUM_BUFS, | ||
249 | dev->ts1_mode.max_pkt_size, | ||
250 | dvb_isoc_copy); | ||
251 | } else { | ||
252 | cx231xx_info("DVB transfer mode is BULK.\n"); | ||
253 | cx231xx_set_alt_setting(dev, INDEX_TS1, 0); | ||
254 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | ||
255 | if (rc < 0) | ||
256 | return rc; | ||
257 | dev->mode_tv = 1; | ||
258 | return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS, | ||
259 | CX231XX_DVB_NUM_BUFS, | ||
260 | dev->ts1_mode.max_pkt_size, | ||
261 | dvb_bulk_copy); | ||
262 | } | ||
148 | 263 | ||
149 | return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS, | ||
150 | CX231XX_DVB_NUM_BUFS, | ||
151 | CX231XX_DVB_MAX_PACKETSIZE, dvb_isoc_copy); | ||
152 | } | 264 | } |
153 | 265 | ||
154 | static int stop_streaming(struct cx231xx_dvb *dvb) | 266 | static int stop_streaming(struct cx231xx_dvb *dvb) |
155 | { | 267 | { |
156 | struct cx231xx *dev = dvb->adapter.priv; | 268 | struct cx231xx *dev = dvb->adapter.priv; |
157 | 269 | ||
158 | cx231xx_uninit_isoc(dev); | 270 | if (dev->USE_ISO) |
271 | cx231xx_uninit_isoc(dev); | ||
272 | else | ||
273 | cx231xx_uninit_bulk(dev); | ||
159 | 274 | ||
160 | cx231xx_set_mode(dev, CX231XX_SUSPEND); | 275 | cx231xx_set_mode(dev, CX231XX_SUSPEND); |
161 | 276 | ||
@@ -216,7 +331,11 @@ static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | |||
216 | 331 | ||
217 | static struct xc5000_config cnxt_rde250_tunerconfig = { | 332 | static struct xc5000_config cnxt_rde250_tunerconfig = { |
218 | .i2c_address = 0x61, | 333 | .i2c_address = 0x61, |
219 | .if_khz = 5380, | 334 | .if_khz = 4000, |
335 | }; | ||
336 | static struct xc5000_config cnxt_rdu250_tunerconfig = { | ||
337 | .i2c_address = 0x61, | ||
338 | .if_khz = 3250, | ||
220 | }; | 339 | }; |
221 | 340 | ||
222 | /* ------------------------------------------------------------------ */ | 341 | /* ------------------------------------------------------------------ */ |
@@ -228,7 +347,7 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) | |||
228 | struct xc5000_config cfg; | 347 | struct xc5000_config cfg; |
229 | 348 | ||
230 | memset(&cfg, 0, sizeof(cfg)); | 349 | memset(&cfg, 0, sizeof(cfg)); |
231 | cfg.i2c_adap = &dev->i2c_bus[1].i2c_adap; | 350 | cfg.i2c_adap = &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap; |
232 | cfg.i2c_addr = addr; | 351 | cfg.i2c_addr = addr; |
233 | 352 | ||
234 | if (!dev->dvb->frontend) { | 353 | if (!dev->dvb->frontend) { |
@@ -268,7 +387,6 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) | |||
268 | /*params.audmode = ; */ | 387 | /*params.audmode = ; */ |
269 | 388 | ||
270 | /* Set the analog parameters to set the frequency */ | 389 | /* Set the analog parameters to set the frequency */ |
271 | cx231xx_info("Setting Frequency for XC5000\n"); | ||
272 | dops->set_analog_params(dev->dvb->frontend, ¶ms); | 390 | dops->set_analog_params(dev->dvb->frontend, ¶ms); |
273 | } | 391 | } |
274 | 392 | ||
@@ -445,19 +563,21 @@ static int dvb_init(struct cx231xx *dev) | |||
445 | dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; | 563 | dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; |
446 | dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; | 564 | dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; |
447 | 565 | ||
566 | mutex_lock(&dev->lock); | ||
448 | cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | 567 | cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); |
568 | cx231xx_demod_reset(dev); | ||
449 | /* init frontend */ | 569 | /* init frontend */ |
450 | switch (dev->model) { | 570 | switch (dev->model) { |
571 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
451 | case CX231XX_BOARD_CNXT_RDE_250: | 572 | case CX231XX_BOARD_CNXT_RDE_250: |
452 | 573 | ||
453 | /* dev->dvb->frontend = dvb_attach(s5h1411_attach, | 574 | dev->dvb->frontend = dvb_attach(s5h1432_attach, |
454 | &dvico_s5h1411_config, | 575 | &dvico_s5h1432_config, |
455 | &dev->i2c_bus[1].i2c_adap); */ | 576 | &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); |
456 | dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); | ||
457 | 577 | ||
458 | if (dev->dvb->frontend == NULL) { | 578 | if (dev->dvb->frontend == NULL) { |
459 | printk(DRIVER_NAME | 579 | printk(DRIVER_NAME |
460 | ": Failed to attach dummy front end\n"); | 580 | ": Failed to attach s5h1432 front end\n"); |
461 | result = -EINVAL; | 581 | result = -EINVAL; |
462 | goto out_free; | 582 | goto out_free; |
463 | } | 583 | } |
@@ -466,16 +586,19 @@ static int dvb_init(struct cx231xx *dev) | |||
466 | dvb->frontend->callback = cx231xx_tuner_callback; | 586 | dvb->frontend->callback = cx231xx_tuner_callback; |
467 | 587 | ||
468 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, | 588 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, |
469 | &dev->i2c_bus[1].i2c_adap, | 589 | &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, |
470 | &cnxt_rde250_tunerconfig)) { | 590 | &cnxt_rde250_tunerconfig)) { |
471 | result = -EINVAL; | 591 | result = -EINVAL; |
472 | goto out_free; | 592 | goto out_free; |
473 | } | 593 | } |
474 | 594 | ||
475 | break; | 595 | break; |
596 | case CX231XX_BOARD_CNXT_SHELBY: | ||
476 | case CX231XX_BOARD_CNXT_RDU_250: | 597 | case CX231XX_BOARD_CNXT_RDU_250: |
477 | 598 | ||
478 | dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); | 599 | dev->dvb->frontend = dvb_attach(s5h1411_attach, |
600 | &xc5000_s5h1411_config, | ||
601 | &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); | ||
479 | 602 | ||
480 | if (dev->dvb->frontend == NULL) { | 603 | if (dev->dvb->frontend == NULL) { |
481 | printk(DRIVER_NAME | 604 | printk(DRIVER_NAME |
@@ -488,12 +611,82 @@ static int dvb_init(struct cx231xx *dev) | |||
488 | dvb->frontend->callback = cx231xx_tuner_callback; | 611 | dvb->frontend->callback = cx231xx_tuner_callback; |
489 | 612 | ||
490 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, | 613 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, |
491 | &dev->i2c_bus[1].i2c_adap, | 614 | &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, |
492 | &cnxt_rde250_tunerconfig)) { | 615 | &cnxt_rdu250_tunerconfig)) { |
616 | result = -EINVAL; | ||
617 | goto out_free; | ||
618 | } | ||
619 | break; | ||
620 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
621 | |||
622 | dev->dvb->frontend = dvb_attach(s5h1432_attach, | ||
623 | &dvico_s5h1432_config, | ||
624 | &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); | ||
625 | |||
626 | if (dev->dvb->frontend == NULL) { | ||
627 | printk(DRIVER_NAME | ||
628 | ": Failed to attach s5h1432 front end\n"); | ||
629 | result = -EINVAL; | ||
630 | goto out_free; | ||
631 | } | ||
632 | |||
633 | /* define general-purpose callback pointer */ | ||
634 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
635 | |||
636 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend, | ||
637 | 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, | ||
638 | &cnxt_rde253s_tunerconfig)) { | ||
639 | result = -EINVAL; | ||
640 | goto out_free; | ||
641 | } | ||
642 | break; | ||
643 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
644 | |||
645 | dev->dvb->frontend = dvb_attach(s5h1411_attach, | ||
646 | &tda18271_s5h1411_config, | ||
647 | &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); | ||
648 | |||
649 | if (dev->dvb->frontend == NULL) { | ||
650 | printk(DRIVER_NAME | ||
651 | ": Failed to attach dummy front end\n"); | ||
652 | result = -EINVAL; | ||
653 | goto out_free; | ||
654 | } | ||
655 | |||
656 | /* define general-purpose callback pointer */ | ||
657 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
658 | |||
659 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend, | ||
660 | 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, | ||
661 | &cnxt_rde253s_tunerconfig)) { | ||
493 | result = -EINVAL; | 662 | result = -EINVAL; |
494 | goto out_free; | 663 | goto out_free; |
495 | } | 664 | } |
496 | break; | 665 | break; |
666 | case CX231XX_BOARD_HAUPPAUGE_EXETER: | ||
667 | |||
668 | printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n", | ||
669 | __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); | ||
670 | |||
671 | dev->dvb->frontend = dvb_attach(lgdt3305_attach, | ||
672 | &hcw_lgdt3305_config, | ||
673 | &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap); | ||
674 | |||
675 | if (dev->dvb->frontend == NULL) { | ||
676 | printk(DRIVER_NAME | ||
677 | ": Failed to attach LG3305 front end\n"); | ||
678 | result = -EINVAL; | ||
679 | goto out_free; | ||
680 | } | ||
681 | |||
682 | /* define general-purpose callback pointer */ | ||
683 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
684 | |||
685 | dvb_attach(tda18271_attach, dev->dvb->frontend, | ||
686 | 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, | ||
687 | &hcw_tda18271_config); | ||
688 | break; | ||
689 | |||
497 | 690 | ||
498 | default: | 691 | default: |
499 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" | 692 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" |
@@ -513,15 +706,18 @@ static int dvb_init(struct cx231xx *dev) | |||
513 | if (result < 0) | 706 | if (result < 0) |
514 | goto out_free; | 707 | goto out_free; |
515 | 708 | ||
516 | cx231xx_set_mode(dev, CX231XX_SUSPEND); | 709 | |
517 | printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); | 710 | printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); |
518 | return 0; | ||
519 | 711 | ||
520 | out_free: | 712 | ret: |
521 | cx231xx_set_mode(dev, CX231XX_SUSPEND); | 713 | cx231xx_set_mode(dev, CX231XX_SUSPEND); |
714 | mutex_unlock(&dev->lock); | ||
715 | return result; | ||
716 | |||
717 | out_free: | ||
522 | kfree(dvb); | 718 | kfree(dvb); |
523 | dev->dvb = NULL; | 719 | dev->dvb = NULL; |
524 | return result; | 720 | goto ret; |
525 | } | 721 | } |
526 | 722 | ||
527 | static int dvb_fini(struct cx231xx *dev) | 723 | static int dvb_fini(struct cx231xx *dev) |
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c index 58d9cc0867b..835670623df 100644 --- a/drivers/media/video/cx231xx/cx231xx-i2c.c +++ b/drivers/media/video/cx231xx/cx231xx-i2c.c | |||
@@ -359,7 +359,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
359 | 359 | ||
360 | if (num <= 0) | 360 | if (num <= 0) |
361 | return 0; | 361 | return 0; |
362 | 362 | mutex_lock(&dev->i2c_lock); | |
363 | for (i = 0; i < num; i++) { | 363 | for (i = 0; i < num; i++) { |
364 | 364 | ||
365 | addr = msgs[i].addr >> 1; | 365 | addr = msgs[i].addr >> 1; |
@@ -372,6 +372,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
372 | rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]); | 372 | rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]); |
373 | if (rc < 0) { | 373 | if (rc < 0) { |
374 | dprintk2(2, " no device\n"); | 374 | dprintk2(2, " no device\n"); |
375 | mutex_unlock(&dev->i2c_lock); | ||
375 | return rc; | 376 | return rc; |
376 | } | 377 | } |
377 | 378 | ||
@@ -384,7 +385,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
384 | } | 385 | } |
385 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && | 386 | } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && |
386 | msgs[i].addr == msgs[i + 1].addr | 387 | msgs[i].addr == msgs[i + 1].addr |
387 | && (msgs[i].len <= 2) && (bus->nr < 2)) { | 388 | && (msgs[i].len <= 2) && (bus->nr < 3)) { |
388 | /* read bytes */ | 389 | /* read bytes */ |
389 | rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, | 390 | rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, |
390 | &msgs[i], | 391 | &msgs[i], |
@@ -407,10 +408,11 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
407 | if (i2c_debug >= 2) | 408 | if (i2c_debug >= 2) |
408 | printk("\n"); | 409 | printk("\n"); |
409 | } | 410 | } |
410 | 411 | mutex_unlock(&dev->i2c_lock); | |
411 | return num; | 412 | return num; |
412 | err: | 413 | err: |
413 | dprintk2(2, " ERROR: %i\n", rc); | 414 | dprintk2(2, " ERROR: %i\n", rc); |
415 | mutex_unlock(&dev->i2c_lock); | ||
414 | return rc; | 416 | return rc; |
415 | } | 417 | } |
416 | 418 | ||
@@ -507,9 +509,6 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) | |||
507 | if (0 == bus->i2c_rc) { | 509 | if (0 == bus->i2c_rc) { |
508 | if (i2c_scan) | 510 | if (i2c_scan) |
509 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); | 511 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); |
510 | |||
511 | /* Instantiate the IR receiver device, if present */ | ||
512 | cx231xx_register_i2c_ir(dev); | ||
513 | } else | 512 | } else |
514 | cx231xx_warn("%s: i2c bus %d register FAILED\n", | 513 | cx231xx_warn("%s: i2c bus %d register FAILED\n", |
515 | dev->name, bus->nr); | 514 | dev->name, bus->nr); |
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c deleted file mode 100644 index fd099153b74..00000000000 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ /dev/null | |||
@@ -1,222 +0,0 @@ | |||
1 | /* | ||
2 | handle cx231xx IR remotes via linux kernel input layer. | ||
3 | |||
4 | Copyright (C) 2008 <srinivasa.deevi at conexant dot com> | ||
5 | Based on em28xx driver | ||
6 | |||
7 | < This is a place holder for IR now.> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/usb.h> | ||
30 | #include <linux/slab.h> | ||
31 | |||
32 | #include "cx231xx.h" | ||
33 | |||
34 | static unsigned int ir_debug; | ||
35 | module_param(ir_debug, int, 0644); | ||
36 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | ||
37 | |||
38 | #define MODULE_NAME "cx231xx" | ||
39 | |||
40 | #define i2cdprintk(fmt, arg...) \ | ||
41 | if (ir_debug) { \ | ||
42 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | ||
43 | } | ||
44 | |||
45 | #define dprintk(fmt, arg...) \ | ||
46 | if (ir_debug) { \ | ||
47 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | ||
48 | } | ||
49 | |||
50 | /********************************************************** | ||
51 | Polling structure used by cx231xx IR's | ||
52 | **********************************************************/ | ||
53 | |||
54 | struct cx231xx_ir_poll_result { | ||
55 | unsigned int toggle_bit:1; | ||
56 | unsigned int read_count:7; | ||
57 | u8 rc_address; | ||
58 | u8 rc_data[4]; | ||
59 | }; | ||
60 | |||
61 | struct cx231xx_IR { | ||
62 | struct cx231xx *dev; | ||
63 | struct input_dev *input; | ||
64 | char name[32]; | ||
65 | char phys[32]; | ||
66 | |||
67 | /* poll external decoder */ | ||
68 | int polling; | ||
69 | struct work_struct work; | ||
70 | struct timer_list timer; | ||
71 | unsigned int last_readcount; | ||
72 | |||
73 | int (*get_key) (struct cx231xx_IR *, struct cx231xx_ir_poll_result *); | ||
74 | }; | ||
75 | |||
76 | /********************************************************** | ||
77 | Polling code for cx231xx | ||
78 | **********************************************************/ | ||
79 | |||
80 | static void cx231xx_ir_handle_key(struct cx231xx_IR *ir) | ||
81 | { | ||
82 | int result; | ||
83 | struct cx231xx_ir_poll_result poll_result; | ||
84 | |||
85 | /* read the registers containing the IR status */ | ||
86 | result = ir->get_key(ir, &poll_result); | ||
87 | if (result < 0) { | ||
88 | dprintk("ir->get_key() failed %d\n", result); | ||
89 | return; | ||
90 | } | ||
91 | |||
92 | dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n", | ||
93 | poll_result.toggle_bit, poll_result.read_count, | ||
94 | ir->last_readcount, poll_result.rc_data[0]); | ||
95 | |||
96 | if (poll_result.read_count > 0 && | ||
97 | poll_result.read_count != ir->last_readcount) | ||
98 | ir_keydown(ir->input, | ||
99 | poll_result.rc_data[0], | ||
100 | poll_result.toggle_bit); | ||
101 | |||
102 | if (ir->dev->chip_id == CHIP_ID_EM2874) | ||
103 | /* The em2874 clears the readcount field every time the | ||
104 | register is read. The em2860/2880 datasheet says that it | ||
105 | is supposed to clear the readcount, but it doesn't. So with | ||
106 | the em2874, we are looking for a non-zero read count as | ||
107 | opposed to a readcount that is incrementing */ | ||
108 | ir->last_readcount = 0; | ||
109 | else | ||
110 | ir->last_readcount = poll_result.read_count; | ||
111 | |||
112 | } | ||
113 | } | ||
114 | |||
115 | static void ir_timer(unsigned long data) | ||
116 | { | ||
117 | struct cx231xx_IR *ir = (struct cx231xx_IR *)data; | ||
118 | |||
119 | schedule_work(&ir->work); | ||
120 | } | ||
121 | |||
122 | static void cx231xx_ir_work(struct work_struct *work) | ||
123 | { | ||
124 | struct cx231xx_IR *ir = container_of(work, struct cx231xx_IR, work); | ||
125 | |||
126 | cx231xx_ir_handle_key(ir); | ||
127 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | ||
128 | } | ||
129 | |||
130 | void cx231xx_ir_start(struct cx231xx_IR *ir) | ||
131 | { | ||
132 | setup_timer(&ir->timer, ir_timer, (unsigned long)ir); | ||
133 | INIT_WORK(&ir->work, cx231xx_ir_work); | ||
134 | schedule_work(&ir->work); | ||
135 | } | ||
136 | |||
137 | static void cx231xx_ir_stop(struct cx231xx_IR *ir) | ||
138 | { | ||
139 | del_timer_sync(&ir->timer); | ||
140 | flush_scheduled_work(); | ||
141 | } | ||
142 | |||
143 | int cx231xx_ir_init(struct cx231xx *dev) | ||
144 | { | ||
145 | struct cx231xx_IR *ir; | ||
146 | struct input_dev *input_dev; | ||
147 | u8 ir_config; | ||
148 | int err = -ENOMEM; | ||
149 | |||
150 | if (dev->board.ir_codes == NULL) { | ||
151 | /* No remote control support */ | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | ||
156 | input_dev = input_allocate_device(); | ||
157 | if (!ir || !input_dev) | ||
158 | goto err_out_free; | ||
159 | |||
160 | ir->input = input_dev; | ||
161 | |||
162 | /* Setup the proper handler based on the chip */ | ||
163 | switch (dev->chip_id) { | ||
164 | default: | ||
165 | printk("Unrecognized cx231xx chip id: IR not supported\n"); | ||
166 | goto err_out_free; | ||
167 | } | ||
168 | |||
169 | /* This is how often we ask the chip for IR information */ | ||
170 | ir->polling = 100; /* ms */ | ||
171 | |||
172 | /* init input device */ | ||
173 | snprintf(ir->name, sizeof(ir->name), "cx231xx IR (%s)", dev->name); | ||
174 | |||
175 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | ||
176 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | ||
177 | |||
178 | input_dev->name = ir->name; | ||
179 | input_dev->phys = ir->phys; | ||
180 | input_dev->id.bustype = BUS_USB; | ||
181 | input_dev->id.version = 1; | ||
182 | input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); | ||
183 | input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
184 | |||
185 | input_dev->dev.parent = &dev->udev->dev; | ||
186 | /* record handles to ourself */ | ||
187 | ir->dev = dev; | ||
188 | dev->ir = ir; | ||
189 | |||
190 | cx231xx_ir_start(ir); | ||
191 | |||
192 | /* all done */ | ||
193 | err = __ir_input_register(ir->input, dev->board.ir_codes, | ||
194 | NULL, MODULE_NAME); | ||
195 | if (err) | ||
196 | goto err_out_stop; | ||
197 | |||
198 | return 0; | ||
199 | err_out_stop: | ||
200 | cx231xx_ir_stop(ir); | ||
201 | dev->ir = NULL; | ||
202 | err_out_free: | ||
203 | kfree(ir); | ||
204 | return err; | ||
205 | } | ||
206 | |||
207 | int cx231xx_ir_fini(struct cx231xx *dev) | ||
208 | { | ||
209 | struct cx231xx_IR *ir = dev->ir; | ||
210 | |||
211 | /* skip detach on non attached boards */ | ||
212 | if (!ir) | ||
213 | return 0; | ||
214 | |||
215 | cx231xx_ir_stop(ir); | ||
216 | ir_input_unregister(ir->input); | ||
217 | kfree(ir); | ||
218 | |||
219 | /* done */ | ||
220 | dev->ir = NULL; | ||
221 | return 0; | ||
222 | } | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c index 689c5e25776..1d914488dbb 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/drivers/media/video/cx231xx/cx231xx-vbi.c | |||
@@ -102,7 +102,7 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) | |||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | buf = dev->vbi_mode.isoc_ctl.buf; | 105 | buf = dev->vbi_mode.bulk_ctl.buf; |
106 | 106 | ||
107 | /* get buffer pointer and length */ | 107 | /* get buffer pointer and length */ |
108 | p_buffer = urb->transfer_buffer; | 108 | p_buffer = urb->transfer_buffer; |
@@ -180,7 +180,7 @@ vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count, | |||
180 | height = ((dev->norm & V4L2_STD_625_50) ? | 180 | height = ((dev->norm & V4L2_STD_625_50) ? |
181 | PAL_VBI_LINES : NTSC_VBI_LINES); | 181 | PAL_VBI_LINES : NTSC_VBI_LINES); |
182 | 182 | ||
183 | *size = (dev->width * height * 2); | 183 | *size = (dev->width * height * 2 * 2); |
184 | if (0 == *count) | 184 | if (0 == *count) |
185 | *count = CX231XX_DEF_VBI_BUF; | 185 | *count = CX231XX_DEF_VBI_BUF; |
186 | 186 | ||
@@ -209,8 +209,8 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) | |||
209 | VIDEOBUF_ACTIVE, it won't be, though. | 209 | VIDEOBUF_ACTIVE, it won't be, though. |
210 | */ | 210 | */ |
211 | spin_lock_irqsave(&dev->vbi_mode.slock, flags); | 211 | spin_lock_irqsave(&dev->vbi_mode.slock, flags); |
212 | if (dev->vbi_mode.isoc_ctl.buf == buf) | 212 | if (dev->vbi_mode.bulk_ctl.buf == buf) |
213 | dev->vbi_mode.isoc_ctl.buf = NULL; | 213 | dev->vbi_mode.bulk_ctl.buf = NULL; |
214 | spin_unlock_irqrestore(&dev->vbi_mode.slock, flags); | 214 | spin_unlock_irqrestore(&dev->vbi_mode.slock, flags); |
215 | 215 | ||
216 | videobuf_vmalloc_free(&buf->vb); | 216 | videobuf_vmalloc_free(&buf->vb); |
@@ -230,7 +230,7 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
230 | 230 | ||
231 | height = ((dev->norm & V4L2_STD_625_50) ? | 231 | height = ((dev->norm & V4L2_STD_625_50) ? |
232 | PAL_VBI_LINES : NTSC_VBI_LINES); | 232 | PAL_VBI_LINES : NTSC_VBI_LINES); |
233 | buf->vb.size = ((dev->width << 1) * height); | 233 | buf->vb.size = ((dev->width << 1) * height * 2); |
234 | 234 | ||
235 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 235 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
236 | return -EINVAL; | 236 | return -EINVAL; |
@@ -246,7 +246,7 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
246 | goto fail; | 246 | goto fail; |
247 | } | 247 | } |
248 | 248 | ||
249 | if (!dev->vbi_mode.isoc_ctl.num_bufs) | 249 | if (!dev->vbi_mode.bulk_ctl.num_bufs) |
250 | urb_init = 1; | 250 | urb_init = 1; |
251 | 251 | ||
252 | if (urb_init) { | 252 | if (urb_init) { |
@@ -328,7 +328,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) | |||
328 | 328 | ||
329 | /* Copy data from URB */ | 329 | /* Copy data from URB */ |
330 | spin_lock(&dev->vbi_mode.slock); | 330 | spin_lock(&dev->vbi_mode.slock); |
331 | rc = dev->vbi_mode.isoc_ctl.isoc_copy(dev, urb); | 331 | rc = dev->vbi_mode.bulk_ctl.bulk_copy(dev, urb); |
332 | spin_unlock(&dev->vbi_mode.slock); | 332 | spin_unlock(&dev->vbi_mode.slock); |
333 | 333 | ||
334 | /* Reset status */ | 334 | /* Reset status */ |
@@ -351,34 +351,34 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) | |||
351 | 351 | ||
352 | cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n"); | 352 | cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n"); |
353 | 353 | ||
354 | dev->vbi_mode.isoc_ctl.nfields = -1; | 354 | dev->vbi_mode.bulk_ctl.nfields = -1; |
355 | for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) { | 355 | for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { |
356 | urb = dev->vbi_mode.isoc_ctl.urb[i]; | 356 | urb = dev->vbi_mode.bulk_ctl.urb[i]; |
357 | if (urb) { | 357 | if (urb) { |
358 | if (!irqs_disabled()) | 358 | if (!irqs_disabled()) |
359 | usb_kill_urb(urb); | 359 | usb_kill_urb(urb); |
360 | else | 360 | else |
361 | usb_unlink_urb(urb); | 361 | usb_unlink_urb(urb); |
362 | 362 | ||
363 | if (dev->vbi_mode.isoc_ctl.transfer_buffer[i]) { | 363 | if (dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { |
364 | 364 | ||
365 | kfree(dev->vbi_mode.isoc_ctl. | 365 | kfree(dev->vbi_mode.bulk_ctl. |
366 | transfer_buffer[i]); | 366 | transfer_buffer[i]); |
367 | dev->vbi_mode.isoc_ctl.transfer_buffer[i] = | 367 | dev->vbi_mode.bulk_ctl.transfer_buffer[i] = |
368 | NULL; | 368 | NULL; |
369 | } | 369 | } |
370 | usb_free_urb(urb); | 370 | usb_free_urb(urb); |
371 | dev->vbi_mode.isoc_ctl.urb[i] = NULL; | 371 | dev->vbi_mode.bulk_ctl.urb[i] = NULL; |
372 | } | 372 | } |
373 | dev->vbi_mode.isoc_ctl.transfer_buffer[i] = NULL; | 373 | dev->vbi_mode.bulk_ctl.transfer_buffer[i] = NULL; |
374 | } | 374 | } |
375 | 375 | ||
376 | kfree(dev->vbi_mode.isoc_ctl.urb); | 376 | kfree(dev->vbi_mode.bulk_ctl.urb); |
377 | kfree(dev->vbi_mode.isoc_ctl.transfer_buffer); | 377 | kfree(dev->vbi_mode.bulk_ctl.transfer_buffer); |
378 | 378 | ||
379 | dev->vbi_mode.isoc_ctl.urb = NULL; | 379 | dev->vbi_mode.bulk_ctl.urb = NULL; |
380 | dev->vbi_mode.isoc_ctl.transfer_buffer = NULL; | 380 | dev->vbi_mode.bulk_ctl.transfer_buffer = NULL; |
381 | dev->vbi_mode.isoc_ctl.num_bufs = 0; | 381 | dev->vbi_mode.bulk_ctl.num_bufs = 0; |
382 | 382 | ||
383 | cx231xx_capture_start(dev, 0, Vbi); | 383 | cx231xx_capture_start(dev, 0, Vbi); |
384 | } | 384 | } |
@@ -389,7 +389,7 @@ EXPORT_SYMBOL_GPL(cx231xx_uninit_vbi_isoc); | |||
389 | */ | 389 | */ |
390 | int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, | 390 | int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, |
391 | int num_bufs, int max_pkt_size, | 391 | int num_bufs, int max_pkt_size, |
392 | int (*isoc_copy) (struct cx231xx *dev, | 392 | int (*bulk_copy) (struct cx231xx *dev, |
393 | struct urb *urb)) | 393 | struct urb *urb)) |
394 | { | 394 | { |
395 | struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq; | 395 | struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq; |
@@ -408,8 +408,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, | |||
408 | usb_rcvbulkpipe(dev->udev, | 408 | usb_rcvbulkpipe(dev->udev, |
409 | dev->vbi_mode.end_point_addr)); | 409 | dev->vbi_mode.end_point_addr)); |
410 | 410 | ||
411 | dev->vbi_mode.isoc_ctl.isoc_copy = isoc_copy; | 411 | dev->vbi_mode.bulk_ctl.bulk_copy = bulk_copy; |
412 | dev->vbi_mode.isoc_ctl.num_bufs = num_bufs; | 412 | dev->vbi_mode.bulk_ctl.num_bufs = num_bufs; |
413 | dma_q->pos = 0; | 413 | dma_q->pos = 0; |
414 | dma_q->is_partial_line = 0; | 414 | dma_q->is_partial_line = 0; |
415 | dma_q->last_sav = 0; | 415 | dma_q->last_sav = 0; |
@@ -421,42 +421,42 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, | |||
421 | for (i = 0; i < 8; i++) | 421 | for (i = 0; i < 8; i++) |
422 | dma_q->partial_buf[i] = 0; | 422 | dma_q->partial_buf[i] = 0; |
423 | 423 | ||
424 | dev->vbi_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs, | 424 | dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, |
425 | GFP_KERNEL); | 425 | GFP_KERNEL); |
426 | if (!dev->vbi_mode.isoc_ctl.urb) { | 426 | if (!dev->vbi_mode.bulk_ctl.urb) { |
427 | cx231xx_errdev("cannot alloc memory for usb buffers\n"); | 427 | cx231xx_errdev("cannot alloc memory for usb buffers\n"); |
428 | return -ENOMEM; | 428 | return -ENOMEM; |
429 | } | 429 | } |
430 | 430 | ||
431 | dev->vbi_mode.isoc_ctl.transfer_buffer = | 431 | dev->vbi_mode.bulk_ctl.transfer_buffer = |
432 | kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); | 432 | kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); |
433 | if (!dev->vbi_mode.isoc_ctl.transfer_buffer) { | 433 | if (!dev->vbi_mode.bulk_ctl.transfer_buffer) { |
434 | cx231xx_errdev("cannot allocate memory for usbtransfer\n"); | 434 | cx231xx_errdev("cannot allocate memory for usbtransfer\n"); |
435 | kfree(dev->vbi_mode.isoc_ctl.urb); | 435 | kfree(dev->vbi_mode.bulk_ctl.urb); |
436 | return -ENOMEM; | 436 | return -ENOMEM; |
437 | } | 437 | } |
438 | 438 | ||
439 | dev->vbi_mode.isoc_ctl.max_pkt_size = max_pkt_size; | 439 | dev->vbi_mode.bulk_ctl.max_pkt_size = max_pkt_size; |
440 | dev->vbi_mode.isoc_ctl.buf = NULL; | 440 | dev->vbi_mode.bulk_ctl.buf = NULL; |
441 | 441 | ||
442 | sb_size = max_packets * dev->vbi_mode.isoc_ctl.max_pkt_size; | 442 | sb_size = max_packets * dev->vbi_mode.bulk_ctl.max_pkt_size; |
443 | 443 | ||
444 | /* allocate urbs and transfer buffers */ | 444 | /* allocate urbs and transfer buffers */ |
445 | for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) { | 445 | for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { |
446 | 446 | ||
447 | urb = usb_alloc_urb(0, GFP_KERNEL); | 447 | urb = usb_alloc_urb(0, GFP_KERNEL); |
448 | if (!urb) { | 448 | if (!urb) { |
449 | cx231xx_err(DRIVER_NAME | 449 | cx231xx_err(DRIVER_NAME |
450 | ": cannot alloc isoc_ctl.urb %i\n", i); | 450 | ": cannot alloc bulk_ctl.urb %i\n", i); |
451 | cx231xx_uninit_vbi_isoc(dev); | 451 | cx231xx_uninit_vbi_isoc(dev); |
452 | return -ENOMEM; | 452 | return -ENOMEM; |
453 | } | 453 | } |
454 | dev->vbi_mode.isoc_ctl.urb[i] = urb; | 454 | dev->vbi_mode.bulk_ctl.urb[i] = urb; |
455 | urb->transfer_flags = 0; | 455 | urb->transfer_flags = 0; |
456 | 456 | ||
457 | dev->vbi_mode.isoc_ctl.transfer_buffer[i] = | 457 | dev->vbi_mode.bulk_ctl.transfer_buffer[i] = |
458 | kzalloc(sb_size, GFP_KERNEL); | 458 | kzalloc(sb_size, GFP_KERNEL); |
459 | if (!dev->vbi_mode.isoc_ctl.transfer_buffer[i]) { | 459 | if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { |
460 | cx231xx_err(DRIVER_NAME | 460 | cx231xx_err(DRIVER_NAME |
461 | ": unable to allocate %i bytes for transfer" | 461 | ": unable to allocate %i bytes for transfer" |
462 | " buffer %i%s\n", sb_size, i, | 462 | " buffer %i%s\n", sb_size, i, |
@@ -467,15 +467,15 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, | |||
467 | 467 | ||
468 | pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr); | 468 | pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr); |
469 | usb_fill_bulk_urb(urb, dev->udev, pipe, | 469 | usb_fill_bulk_urb(urb, dev->udev, pipe, |
470 | dev->vbi_mode.isoc_ctl.transfer_buffer[i], | 470 | dev->vbi_mode.bulk_ctl.transfer_buffer[i], |
471 | sb_size, cx231xx_irq_vbi_callback, dma_q); | 471 | sb_size, cx231xx_irq_vbi_callback, dma_q); |
472 | } | 472 | } |
473 | 473 | ||
474 | init_waitqueue_head(&dma_q->wq); | 474 | init_waitqueue_head(&dma_q->wq); |
475 | 475 | ||
476 | /* submit urbs and enables IRQ */ | 476 | /* submit urbs and enables IRQ */ |
477 | for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) { | 477 | for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { |
478 | rc = usb_submit_urb(dev->vbi_mode.isoc_ctl.urb[i], GFP_ATOMIC); | 478 | rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); |
479 | if (rc) { | 479 | if (rc) { |
480 | cx231xx_err(DRIVER_NAME | 480 | cx231xx_err(DRIVER_NAME |
481 | ": submit of urb %i failed (error=%i)\n", i, | 481 | ": submit of urb %i failed (error=%i)\n", i, |
@@ -536,7 +536,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, | |||
536 | buf->vb.field_count++; | 536 | buf->vb.field_count++; |
537 | do_gettimeofday(&buf->vb.ts); | 537 | do_gettimeofday(&buf->vb.ts); |
538 | 538 | ||
539 | dev->vbi_mode.isoc_ctl.buf = NULL; | 539 | dev->vbi_mode.bulk_ctl.buf = NULL; |
540 | 540 | ||
541 | list_del(&buf->vb.queue); | 541 | list_del(&buf->vb.queue); |
542 | wake_up(&buf->vb.done); | 542 | wake_up(&buf->vb.done); |
@@ -549,11 +549,16 @@ u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, | |||
549 | struct cx231xx_buffer *buf; | 549 | struct cx231xx_buffer *buf; |
550 | u32 _line_size = dev->width * 2; | 550 | u32 _line_size = dev->width * 2; |
551 | 551 | ||
552 | if (dma_q->current_field != field_number) | 552 | if (dma_q->current_field == -1) { |
553 | /* Just starting up */ | ||
553 | cx231xx_reset_vbi_buffer(dev, dma_q); | 554 | cx231xx_reset_vbi_buffer(dev, dma_q); |
555 | } | ||
556 | |||
557 | if (dma_q->current_field != field_number) | ||
558 | dma_q->lines_completed = 0; | ||
554 | 559 | ||
555 | /* get the buffer pointer */ | 560 | /* get the buffer pointer */ |
556 | buf = dev->vbi_mode.isoc_ctl.buf; | 561 | buf = dev->vbi_mode.bulk_ctl.buf; |
557 | 562 | ||
558 | /* Remember the field number for next time */ | 563 | /* Remember the field number for next time */ |
559 | dma_q->current_field = field_number; | 564 | dma_q->current_field = field_number; |
@@ -597,8 +602,8 @@ u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, | |||
597 | vbi_buffer_filled(dev, dma_q, buf); | 602 | vbi_buffer_filled(dev, dma_q, buf); |
598 | 603 | ||
599 | dma_q->pos = 0; | 604 | dma_q->pos = 0; |
600 | buf = NULL; | ||
601 | dma_q->lines_completed = 0; | 605 | dma_q->lines_completed = 0; |
606 | cx231xx_reset_vbi_buffer(dev, dma_q); | ||
602 | } | 607 | } |
603 | } | 608 | } |
604 | 609 | ||
@@ -618,7 +623,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, | |||
618 | 623 | ||
619 | if (list_empty(&dma_q->active)) { | 624 | if (list_empty(&dma_q->active)) { |
620 | cx231xx_err(DRIVER_NAME ": No active queue to serve\n"); | 625 | cx231xx_err(DRIVER_NAME ": No active queue to serve\n"); |
621 | dev->vbi_mode.isoc_ctl.buf = NULL; | 626 | dev->vbi_mode.bulk_ctl.buf = NULL; |
622 | *buf = NULL; | 627 | *buf = NULL; |
623 | return; | 628 | return; |
624 | } | 629 | } |
@@ -630,7 +635,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, | |||
630 | outp = videobuf_to_vmalloc(&(*buf)->vb); | 635 | outp = videobuf_to_vmalloc(&(*buf)->vb); |
631 | memset(outp, 0, (*buf)->vb.size); | 636 | memset(outp, 0, (*buf)->vb.size); |
632 | 637 | ||
633 | dev->vbi_mode.isoc_ctl.buf = *buf; | 638 | dev->vbi_mode.bulk_ctl.buf = *buf; |
634 | 639 | ||
635 | return; | 640 | return; |
636 | } | 641 | } |
@@ -640,7 +645,7 @@ void cx231xx_reset_vbi_buffer(struct cx231xx *dev, | |||
640 | { | 645 | { |
641 | struct cx231xx_buffer *buf; | 646 | struct cx231xx_buffer *buf; |
642 | 647 | ||
643 | buf = dev->vbi_mode.isoc_ctl.buf; | 648 | buf = dev->vbi_mode.bulk_ctl.buf; |
644 | 649 | ||
645 | if (buf == NULL) { | 650 | if (buf == NULL) { |
646 | /* first try to get the buffer */ | 651 | /* first try to get the buffer */ |
@@ -664,7 +669,7 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, | |||
664 | void *startwrite; | 669 | void *startwrite; |
665 | int offset, lencopy; | 670 | int offset, lencopy; |
666 | 671 | ||
667 | buf = dev->vbi_mode.isoc_ctl.buf; | 672 | buf = dev->vbi_mode.bulk_ctl.buf; |
668 | 673 | ||
669 | if (buf == NULL) | 674 | if (buf == NULL) |
670 | return -EINVAL; | 675 | return -EINVAL; |
@@ -679,6 +684,11 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, | |||
679 | offset = (dma_q->lines_completed * _line_size) + | 684 | offset = (dma_q->lines_completed * _line_size) + |
680 | current_line_bytes_copied; | 685 | current_line_bytes_copied; |
681 | 686 | ||
687 | if (dma_q->current_field == 2) { | ||
688 | /* Populate the second half of the frame */ | ||
689 | offset += (dev->width * 2 * dma_q->lines_per_field); | ||
690 | } | ||
691 | |||
682 | /* prepare destination address */ | 692 | /* prepare destination address */ |
683 | startwrite = p_out_buffer + offset; | 693 | startwrite = p_out_buffer + offset; |
684 | 694 | ||
@@ -697,5 +707,8 @@ u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev, | |||
697 | 707 | ||
698 | height = ((dev->norm & V4L2_STD_625_50) ? | 708 | height = ((dev->norm & V4L2_STD_625_50) ? |
699 | PAL_VBI_LINES : NTSC_VBI_LINES); | 709 | PAL_VBI_LINES : NTSC_VBI_LINES); |
700 | return (dma_q->lines_completed == height) ? 1 : 0; | 710 | if (dma_q->lines_completed == height && dma_q->current_field == 2) |
711 | return 1; | ||
712 | else | ||
713 | return 0; | ||
701 | } | 714 | } |
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.h b/drivers/media/video/cx231xx/cx231xx-vbi.h index 89c7fe80b26..16c7d20a22a 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.h +++ b/drivers/media/video/cx231xx/cx231xx-vbi.h | |||
@@ -41,7 +41,7 @@ extern struct videobuf_queue_ops cx231xx_vbi_qops; | |||
41 | /* stream functions */ | 41 | /* stream functions */ |
42 | int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, | 42 | int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, |
43 | int num_bufs, int max_pkt_size, | 43 | int num_bufs, int max_pkt_size, |
44 | int (*isoc_copy) (struct cx231xx *dev, | 44 | int (*bulk_copy) (struct cx231xx *dev, |
45 | struct urb *urb)); | 45 | struct urb *urb)); |
46 | 46 | ||
47 | void cx231xx_uninit_vbi_isoc(struct cx231xx *dev); | 47 | void cx231xx_uninit_vbi_isoc(struct cx231xx *dev); |
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index e76014561aa..b13b69fb2af 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c | |||
@@ -237,7 +237,10 @@ static inline void buffer_filled(struct cx231xx *dev, | |||
237 | buf->vb.field_count++; | 237 | buf->vb.field_count++; |
238 | do_gettimeofday(&buf->vb.ts); | 238 | do_gettimeofday(&buf->vb.ts); |
239 | 239 | ||
240 | dev->video_mode.isoc_ctl.buf = NULL; | 240 | if (dev->USE_ISO) |
241 | dev->video_mode.isoc_ctl.buf = NULL; | ||
242 | else | ||
243 | dev->video_mode.bulk_ctl.buf = NULL; | ||
241 | 244 | ||
242 | list_del(&buf->vb.queue); | 245 | list_del(&buf->vb.queue); |
243 | wake_up(&buf->vb.done); | 246 | wake_up(&buf->vb.done); |
@@ -295,7 +298,10 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q, | |||
295 | 298 | ||
296 | if (list_empty(&dma_q->active)) { | 299 | if (list_empty(&dma_q->active)) { |
297 | cx231xx_isocdbg("No active queue to serve\n"); | 300 | cx231xx_isocdbg("No active queue to serve\n"); |
298 | dev->video_mode.isoc_ctl.buf = NULL; | 301 | if (dev->USE_ISO) |
302 | dev->video_mode.isoc_ctl.buf = NULL; | ||
303 | else | ||
304 | dev->video_mode.bulk_ctl.buf = NULL; | ||
299 | *buf = NULL; | 305 | *buf = NULL; |
300 | return; | 306 | return; |
301 | } | 307 | } |
@@ -307,7 +313,10 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q, | |||
307 | outp = videobuf_to_vmalloc(&(*buf)->vb); | 313 | outp = videobuf_to_vmalloc(&(*buf)->vb); |
308 | memset(outp, 0, (*buf)->vb.size); | 314 | memset(outp, 0, (*buf)->vb.size); |
309 | 315 | ||
310 | dev->video_mode.isoc_ctl.buf = *buf; | 316 | if (dev->USE_ISO) |
317 | dev->video_mode.isoc_ctl.buf = *buf; | ||
318 | else | ||
319 | dev->video_mode.bulk_ctl.buf = *buf; | ||
311 | 320 | ||
312 | return; | 321 | return; |
313 | } | 322 | } |
@@ -418,6 +427,93 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) | |||
418 | return rc; | 427 | return rc; |
419 | } | 428 | } |
420 | 429 | ||
430 | static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) | ||
431 | { | ||
432 | struct cx231xx_buffer *buf; | ||
433 | struct cx231xx_dmaqueue *dma_q = urb->context; | ||
434 | unsigned char *outp = NULL; | ||
435 | int rc = 1; | ||
436 | unsigned char *p_buffer; | ||
437 | u32 bytes_parsed = 0, buffer_size = 0; | ||
438 | u8 sav_eav = 0; | ||
439 | |||
440 | if (!dev) | ||
441 | return 0; | ||
442 | |||
443 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
444 | return 0; | ||
445 | |||
446 | if (urb->status < 0) { | ||
447 | print_err_status(dev, -1, urb->status); | ||
448 | if (urb->status == -ENOENT) | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | buf = dev->video_mode.bulk_ctl.buf; | ||
453 | if (buf != NULL) | ||
454 | outp = videobuf_to_vmalloc(&buf->vb); | ||
455 | |||
456 | if (1) { | ||
457 | |||
458 | /* get buffer pointer and length */ | ||
459 | p_buffer = urb->transfer_buffer; | ||
460 | buffer_size = urb->actual_length; | ||
461 | bytes_parsed = 0; | ||
462 | |||
463 | if (dma_q->is_partial_line) { | ||
464 | /* Handle the case of a partial line */ | ||
465 | sav_eav = dma_q->last_sav; | ||
466 | } else { | ||
467 | /* Check for a SAV/EAV overlapping | ||
468 | the buffer boundary */ | ||
469 | sav_eav = | ||
470 | cx231xx_find_boundary_SAV_EAV(p_buffer, | ||
471 | dma_q->partial_buf, | ||
472 | &bytes_parsed); | ||
473 | } | ||
474 | |||
475 | sav_eav &= 0xF0; | ||
476 | /* Get the first line if we have some portion of an SAV/EAV from | ||
477 | the last buffer or a partial line */ | ||
478 | if (sav_eav) { | ||
479 | bytes_parsed += cx231xx_get_video_line(dev, dma_q, | ||
480 | sav_eav, /* SAV/EAV */ | ||
481 | p_buffer + bytes_parsed, /* p_buffer */ | ||
482 | buffer_size - bytes_parsed);/* buf size */ | ||
483 | } | ||
484 | |||
485 | /* Now parse data that is completely in this buffer */ | ||
486 | /* dma_q->is_partial_line = 0; */ | ||
487 | |||
488 | while (bytes_parsed < buffer_size) { | ||
489 | u32 bytes_used = 0; | ||
490 | |||
491 | sav_eav = cx231xx_find_next_SAV_EAV( | ||
492 | p_buffer + bytes_parsed, /* p_buffer */ | ||
493 | buffer_size - bytes_parsed, /* buf size */ | ||
494 | &bytes_used);/* bytes used to get SAV/EAV */ | ||
495 | |||
496 | bytes_parsed += bytes_used; | ||
497 | |||
498 | sav_eav &= 0xF0; | ||
499 | if (sav_eav && (bytes_parsed < buffer_size)) { | ||
500 | bytes_parsed += cx231xx_get_video_line(dev, | ||
501 | dma_q, sav_eav, /* SAV/EAV */ | ||
502 | p_buffer + bytes_parsed,/* p_buffer */ | ||
503 | buffer_size - bytes_parsed);/*buf size*/ | ||
504 | } | ||
505 | } | ||
506 | |||
507 | /* Save the last four bytes of the buffer so we can check the | ||
508 | buffer boundary condition next time */ | ||
509 | memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4); | ||
510 | bytes_parsed = 0; | ||
511 | |||
512 | } | ||
513 | return rc; | ||
514 | } | ||
515 | |||
516 | |||
421 | u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf, | 517 | u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf, |
422 | u32 *p_bytes_used) | 518 | u32 *p_bytes_used) |
423 | { | 519 | { |
@@ -533,7 +629,10 @@ u32 cx231xx_copy_video_line(struct cx231xx *dev, | |||
533 | cx231xx_reset_video_buffer(dev, dma_q); | 629 | cx231xx_reset_video_buffer(dev, dma_q); |
534 | 630 | ||
535 | /* get the buffer pointer */ | 631 | /* get the buffer pointer */ |
536 | buf = dev->video_mode.isoc_ctl.buf; | 632 | if (dev->USE_ISO) |
633 | buf = dev->video_mode.isoc_ctl.buf; | ||
634 | else | ||
635 | buf = dev->video_mode.bulk_ctl.buf; | ||
537 | 636 | ||
538 | /* Remember the field number for next time */ | 637 | /* Remember the field number for next time */ |
539 | dma_q->current_field = field_number; | 638 | dma_q->current_field = field_number; |
@@ -596,7 +695,10 @@ void cx231xx_reset_video_buffer(struct cx231xx *dev, | |||
596 | dma_q->field1_done = 0; | 695 | dma_q->field1_done = 0; |
597 | } | 696 | } |
598 | 697 | ||
599 | buf = dev->video_mode.isoc_ctl.buf; | 698 | if (dev->USE_ISO) |
699 | buf = dev->video_mode.isoc_ctl.buf; | ||
700 | else | ||
701 | buf = dev->video_mode.bulk_ctl.buf; | ||
600 | 702 | ||
601 | if (buf == NULL) { | 703 | if (buf == NULL) { |
602 | u8 *outp = NULL; | 704 | u8 *outp = NULL; |
@@ -626,7 +728,10 @@ int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, | |||
626 | void *startwrite; | 728 | void *startwrite; |
627 | int offset, lencopy; | 729 | int offset, lencopy; |
628 | 730 | ||
629 | buf = dev->video_mode.isoc_ctl.buf; | 731 | if (dev->USE_ISO) |
732 | buf = dev->video_mode.isoc_ctl.buf; | ||
733 | else | ||
734 | buf = dev->video_mode.bulk_ctl.buf; | ||
630 | 735 | ||
631 | if (buf == NULL) | 736 | if (buf == NULL) |
632 | return -1; | 737 | return -1; |
@@ -691,7 +796,6 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
691 | { | 796 | { |
692 | struct cx231xx_fh *fh = vq->priv_data; | 797 | struct cx231xx_fh *fh = vq->priv_data; |
693 | struct cx231xx *dev = fh->dev; | 798 | struct cx231xx *dev = fh->dev; |
694 | struct v4l2_frequency f; | ||
695 | 799 | ||
696 | *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3; | 800 | *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3; |
697 | if (0 == *count) | 801 | if (0 == *count) |
@@ -700,13 +804,6 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
700 | if (*count < CX231XX_MIN_BUF) | 804 | if (*count < CX231XX_MIN_BUF) |
701 | *count = CX231XX_MIN_BUF; | 805 | *count = CX231XX_MIN_BUF; |
702 | 806 | ||
703 | /* Ask tuner to go to analog mode */ | ||
704 | memset(&f, 0, sizeof(f)); | ||
705 | f.frequency = dev->ctl_freq; | ||
706 | f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
707 | |||
708 | call_all(dev, tuner, s_frequency, &f); | ||
709 | |||
710 | return 0; | 807 | return 0; |
711 | } | 808 | } |
712 | 809 | ||
@@ -730,8 +827,13 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) | |||
730 | VIDEOBUF_ACTIVE, it won't be, though. | 827 | VIDEOBUF_ACTIVE, it won't be, though. |
731 | */ | 828 | */ |
732 | spin_lock_irqsave(&dev->video_mode.slock, flags); | 829 | spin_lock_irqsave(&dev->video_mode.slock, flags); |
733 | if (dev->video_mode.isoc_ctl.buf == buf) | 830 | if (dev->USE_ISO) { |
734 | dev->video_mode.isoc_ctl.buf = NULL; | 831 | if (dev->video_mode.isoc_ctl.buf == buf) |
832 | dev->video_mode.isoc_ctl.buf = NULL; | ||
833 | } else { | ||
834 | if (dev->video_mode.bulk_ctl.buf == buf) | ||
835 | dev->video_mode.bulk_ctl.buf = NULL; | ||
836 | } | ||
735 | spin_unlock_irqrestore(&dev->video_mode.slock, flags); | 837 | spin_unlock_irqrestore(&dev->video_mode.slock, flags); |
736 | 838 | ||
737 | videobuf_vmalloc_free(&buf->vb); | 839 | videobuf_vmalloc_free(&buf->vb); |
@@ -764,14 +866,27 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
764 | goto fail; | 866 | goto fail; |
765 | } | 867 | } |
766 | 868 | ||
767 | if (!dev->video_mode.isoc_ctl.num_bufs) | 869 | if (dev->USE_ISO) { |
768 | urb_init = 1; | 870 | if (!dev->video_mode.isoc_ctl.num_bufs) |
769 | 871 | urb_init = 1; | |
872 | } else { | ||
873 | if (!dev->video_mode.bulk_ctl.num_bufs) | ||
874 | urb_init = 1; | ||
875 | } | ||
876 | /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", | ||
877 | urb_init, dev->video_mode.max_pkt_size);*/ | ||
770 | if (urb_init) { | 878 | if (urb_init) { |
771 | rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, | 879 | dev->mode_tv = 0; |
880 | if (dev->USE_ISO) | ||
881 | rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, | ||
772 | CX231XX_NUM_BUFS, | 882 | CX231XX_NUM_BUFS, |
773 | dev->video_mode.max_pkt_size, | 883 | dev->video_mode.max_pkt_size, |
774 | cx231xx_isoc_copy); | 884 | cx231xx_isoc_copy); |
885 | else | ||
886 | rc = cx231xx_init_bulk(dev, CX231XX_NUM_PACKETS, | ||
887 | CX231XX_NUM_BUFS, | ||
888 | dev->video_mode.max_pkt_size, | ||
889 | cx231xx_bulk_copy); | ||
775 | if (rc < 0) | 890 | if (rc < 0) |
776 | goto fail; | 891 | goto fail; |
777 | } | 892 | } |
@@ -894,22 +1009,6 @@ static int check_dev(struct cx231xx *dev) | |||
894 | return 0; | 1009 | return 0; |
895 | } | 1010 | } |
896 | 1011 | ||
897 | static void get_scale(struct cx231xx *dev, | ||
898 | unsigned int width, unsigned int height, | ||
899 | unsigned int *hscale, unsigned int *vscale) | ||
900 | { | ||
901 | unsigned int maxw = norm_maxw(dev); | ||
902 | unsigned int maxh = norm_maxh(dev); | ||
903 | |||
904 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; | ||
905 | if (*hscale >= 0x4000) | ||
906 | *hscale = 0x3fff; | ||
907 | |||
908 | *vscale = (((unsigned long)maxh) << 12) / height - 4096L; | ||
909 | if (*vscale >= 0x4000) | ||
910 | *vscale = 0x3fff; | ||
911 | } | ||
912 | |||
913 | /* ------------------------------------------------------------------ | 1012 | /* ------------------------------------------------------------------ |
914 | IOCTL vidioc handling | 1013 | IOCTL vidioc handling |
915 | ------------------------------------------------------------------*/ | 1014 | ------------------------------------------------------------------*/ |
@@ -920,8 +1019,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
920 | struct cx231xx_fh *fh = priv; | 1019 | struct cx231xx_fh *fh = priv; |
921 | struct cx231xx *dev = fh->dev; | 1020 | struct cx231xx *dev = fh->dev; |
922 | 1021 | ||
923 | mutex_lock(&dev->lock); | ||
924 | |||
925 | f->fmt.pix.width = dev->width; | 1022 | f->fmt.pix.width = dev->width; |
926 | f->fmt.pix.height = dev->height; | 1023 | f->fmt.pix.height = dev->height; |
927 | f->fmt.pix.pixelformat = dev->format->fourcc; | 1024 | f->fmt.pix.pixelformat = dev->format->fourcc; |
@@ -931,8 +1028,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
931 | 1028 | ||
932 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 1029 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
933 | 1030 | ||
934 | mutex_unlock(&dev->lock); | ||
935 | |||
936 | return 0; | 1031 | return 0; |
937 | } | 1032 | } |
938 | 1033 | ||
@@ -956,7 +1051,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
956 | unsigned int height = f->fmt.pix.height; | 1051 | unsigned int height = f->fmt.pix.height; |
957 | unsigned int maxw = norm_maxw(dev); | 1052 | unsigned int maxw = norm_maxw(dev); |
958 | unsigned int maxh = norm_maxh(dev); | 1053 | unsigned int maxh = norm_maxh(dev); |
959 | unsigned int hscale, vscale; | ||
960 | struct cx231xx_fmt *fmt; | 1054 | struct cx231xx_fmt *fmt; |
961 | 1055 | ||
962 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1056 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
@@ -970,11 +1064,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
970 | height must be even because of interlacing */ | 1064 | height must be even because of interlacing */ |
971 | v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); | 1065 | v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); |
972 | 1066 | ||
973 | get_scale(dev, width, height, &hscale, &vscale); | ||
974 | |||
975 | width = (((unsigned long)maxw) << 12) / (hscale + 4096L); | ||
976 | height = (((unsigned long)maxh) << 12) / (vscale + 4096L); | ||
977 | |||
978 | f->fmt.pix.width = width; | 1067 | f->fmt.pix.width = width; |
979 | f->fmt.pix.height = height; | 1068 | f->fmt.pix.height = height; |
980 | f->fmt.pix.pixelformat = fmt->fourcc; | 1069 | f->fmt.pix.pixelformat = fmt->fourcc; |
@@ -999,47 +1088,35 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
999 | if (rc < 0) | 1088 | if (rc < 0) |
1000 | return rc; | 1089 | return rc; |
1001 | 1090 | ||
1002 | mutex_lock(&dev->lock); | ||
1003 | |||
1004 | vidioc_try_fmt_vid_cap(file, priv, f); | 1091 | vidioc_try_fmt_vid_cap(file, priv, f); |
1005 | 1092 | ||
1006 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1093 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
1007 | if (!fmt) { | 1094 | if (!fmt) |
1008 | rc = -EINVAL; | 1095 | return -EINVAL; |
1009 | goto out; | ||
1010 | } | ||
1011 | 1096 | ||
1012 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | 1097 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { |
1013 | cx231xx_errdev("%s queue busy\n", __func__); | 1098 | cx231xx_errdev("%s queue busy\n", __func__); |
1014 | rc = -EBUSY; | 1099 | return -EBUSY; |
1015 | goto out; | ||
1016 | } | 1100 | } |
1017 | 1101 | ||
1018 | if (dev->stream_on && !fh->stream_on) { | 1102 | if (dev->stream_on && !fh->stream_on) { |
1019 | cx231xx_errdev("%s device in use by another fh\n", __func__); | 1103 | cx231xx_errdev("%s device in use by another fh\n", __func__); |
1020 | rc = -EBUSY; | 1104 | return -EBUSY; |
1021 | goto out; | ||
1022 | } | 1105 | } |
1023 | 1106 | ||
1024 | /* set new image size */ | 1107 | /* set new image size */ |
1025 | dev->width = f->fmt.pix.width; | 1108 | dev->width = f->fmt.pix.width; |
1026 | dev->height = f->fmt.pix.height; | 1109 | dev->height = f->fmt.pix.height; |
1027 | dev->format = fmt; | 1110 | dev->format = fmt; |
1028 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | ||
1029 | 1111 | ||
1030 | v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); | 1112 | v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); |
1031 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); | 1113 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); |
1032 | v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); | 1114 | v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); |
1033 | 1115 | ||
1034 | /* Set the correct alternate setting for this resolution */ | ||
1035 | cx231xx_resolution_set(dev); | ||
1036 | |||
1037 | out: | ||
1038 | mutex_unlock(&dev->lock); | ||
1039 | return rc; | 1116 | return rc; |
1040 | } | 1117 | } |
1041 | 1118 | ||
1042 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id * id) | 1119 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) |
1043 | { | 1120 | { |
1044 | struct cx231xx_fh *fh = priv; | 1121 | struct cx231xx_fh *fh = priv; |
1045 | struct cx231xx *dev = fh->dev; | 1122 | struct cx231xx *dev = fh->dev; |
@@ -1052,6 +1129,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
1052 | { | 1129 | { |
1053 | struct cx231xx_fh *fh = priv; | 1130 | struct cx231xx_fh *fh = priv; |
1054 | struct cx231xx *dev = fh->dev; | 1131 | struct cx231xx *dev = fh->dev; |
1132 | struct v4l2_mbus_framefmt mbus_fmt; | ||
1055 | struct v4l2_format f; | 1133 | struct v4l2_format f; |
1056 | int rc; | 1134 | int rc; |
1057 | 1135 | ||
@@ -1061,7 +1139,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
1061 | 1139 | ||
1062 | cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm); | 1140 | cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm); |
1063 | 1141 | ||
1064 | mutex_lock(&dev->lock); | ||
1065 | dev->norm = *norm; | 1142 | dev->norm = *norm; |
1066 | 1143 | ||
1067 | /* Adjusts width/height, if needed */ | 1144 | /* Adjusts width/height, if needed */ |
@@ -1069,16 +1146,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
1069 | f.fmt.pix.height = dev->height; | 1146 | f.fmt.pix.height = dev->height; |
1070 | vidioc_try_fmt_vid_cap(file, priv, &f); | 1147 | vidioc_try_fmt_vid_cap(file, priv, &f); |
1071 | 1148 | ||
1072 | /* set new image size */ | ||
1073 | dev->width = f.fmt.pix.width; | ||
1074 | dev->height = f.fmt.pix.height; | ||
1075 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | ||
1076 | |||
1077 | call_all(dev, core, s_std, dev->norm); | 1149 | call_all(dev, core, s_std, dev->norm); |
1078 | 1150 | ||
1079 | mutex_unlock(&dev->lock); | 1151 | /* We need to reset basic properties in the decoder related to |
1152 | resolution (since a standard change effects things like the number | ||
1153 | of lines in VACT, etc) */ | ||
1154 | v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED); | ||
1155 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); | ||
1156 | v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt); | ||
1080 | 1157 | ||
1081 | cx231xx_resolution_set(dev); | 1158 | /* set new image size */ |
1159 | dev->width = f.fmt.pix.width; | ||
1160 | dev->height = f.fmt.pix.height; | ||
1082 | 1161 | ||
1083 | /* do mode control overrides */ | 1162 | /* do mode control overrides */ |
1084 | cx231xx_do_mode_ctrl_overrides(dev); | 1163 | cx231xx_do_mode_ctrl_overrides(dev); |
@@ -1138,6 +1217,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1138 | struct cx231xx *dev = fh->dev; | 1217 | struct cx231xx *dev = fh->dev; |
1139 | int rc; | 1218 | int rc; |
1140 | 1219 | ||
1220 | dev->mode_tv = 0; | ||
1141 | rc = check_dev(dev); | 1221 | rc = check_dev(dev); |
1142 | if (rc < 0) | 1222 | if (rc < 0) |
1143 | return rc; | 1223 | return rc; |
@@ -1147,11 +1227,16 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1147 | if (0 == INPUT(i)->type) | 1227 | if (0 == INPUT(i)->type) |
1148 | return -EINVAL; | 1228 | return -EINVAL; |
1149 | 1229 | ||
1150 | mutex_lock(&dev->lock); | ||
1151 | |||
1152 | video_mux(dev, i); | 1230 | video_mux(dev, i); |
1153 | 1231 | ||
1154 | mutex_unlock(&dev->lock); | 1232 | if (INPUT(i)->type == CX231XX_VMUX_TELEVISION || |
1233 | INPUT(i)->type == CX231XX_VMUX_CABLE) { | ||
1234 | /* There's a tuner, so reset the standard and put it on the | ||
1235 | last known frequency (since it was probably powered down | ||
1236 | until now */ | ||
1237 | call_all(dev, core, s_std, dev->norm); | ||
1238 | } | ||
1239 | |||
1155 | return 0; | 1240 | return 0; |
1156 | } | 1241 | } |
1157 | 1242 | ||
@@ -1227,9 +1312,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
1227 | } | 1312 | } |
1228 | *qc = cx231xx_ctls[i].v; | 1313 | *qc = cx231xx_ctls[i].v; |
1229 | 1314 | ||
1230 | mutex_lock(&dev->lock); | ||
1231 | call_all(dev, core, queryctrl, qc); | 1315 | call_all(dev, core, queryctrl, qc); |
1232 | mutex_unlock(&dev->lock); | ||
1233 | 1316 | ||
1234 | if (qc->type) | 1317 | if (qc->type) |
1235 | return 0; | 1318 | return 0; |
@@ -1248,9 +1331,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1248 | if (rc < 0) | 1331 | if (rc < 0) |
1249 | return rc; | 1332 | return rc; |
1250 | 1333 | ||
1251 | mutex_lock(&dev->lock); | ||
1252 | call_all(dev, core, g_ctrl, ctrl); | 1334 | call_all(dev, core, g_ctrl, ctrl); |
1253 | mutex_unlock(&dev->lock); | ||
1254 | return rc; | 1335 | return rc; |
1255 | } | 1336 | } |
1256 | 1337 | ||
@@ -1265,9 +1346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1265 | if (rc < 0) | 1346 | if (rc < 0) |
1266 | return rc; | 1347 | return rc; |
1267 | 1348 | ||
1268 | mutex_lock(&dev->lock); | ||
1269 | call_all(dev, core, s_ctrl, ctrl); | 1349 | call_all(dev, core, s_ctrl, ctrl); |
1270 | mutex_unlock(&dev->lock); | ||
1271 | return rc; | 1350 | return rc; |
1272 | } | 1351 | } |
1273 | 1352 | ||
@@ -1307,9 +1386,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
1307 | if (0 != t->index) | 1386 | if (0 != t->index) |
1308 | return -EINVAL; | 1387 | return -EINVAL; |
1309 | #if 0 | 1388 | #if 0 |
1310 | mutex_lock(&dev->lock); | ||
1311 | call_all(dev, tuner, s_tuner, t); | 1389 | call_all(dev, tuner, s_tuner, t); |
1312 | mutex_unlock(&dev->lock); | ||
1313 | #endif | 1390 | #endif |
1314 | return 0; | 1391 | return 0; |
1315 | } | 1392 | } |
@@ -1320,14 +1397,11 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
1320 | struct cx231xx_fh *fh = priv; | 1397 | struct cx231xx_fh *fh = priv; |
1321 | struct cx231xx *dev = fh->dev; | 1398 | struct cx231xx *dev = fh->dev; |
1322 | 1399 | ||
1323 | mutex_lock(&dev->lock); | ||
1324 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1400 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1325 | f->frequency = dev->ctl_freq; | 1401 | f->frequency = dev->ctl_freq; |
1326 | 1402 | ||
1327 | call_all(dev, tuner, g_frequency, f); | 1403 | call_all(dev, tuner, g_frequency, f); |
1328 | 1404 | ||
1329 | mutex_unlock(&dev->lock); | ||
1330 | |||
1331 | return 0; | 1405 | return 0; |
1332 | } | 1406 | } |
1333 | 1407 | ||
@@ -1337,6 +1411,11 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1337 | struct cx231xx_fh *fh = priv; | 1411 | struct cx231xx_fh *fh = priv; |
1338 | struct cx231xx *dev = fh->dev; | 1412 | struct cx231xx *dev = fh->dev; |
1339 | int rc; | 1413 | int rc; |
1414 | u32 if_frequency = 5400000; | ||
1415 | |||
1416 | cx231xx_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", | ||
1417 | f->frequency, f->type); | ||
1418 | /*cx231xx_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/ | ||
1340 | 1419 | ||
1341 | rc = check_dev(dev); | 1420 | rc = check_dev(dev); |
1342 | if (rc < 0) | 1421 | if (rc < 0) |
@@ -1353,21 +1432,34 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1353 | /* set pre channel change settings in DIF first */ | 1432 | /* set pre channel change settings in DIF first */ |
1354 | rc = cx231xx_tuner_pre_channel_change(dev); | 1433 | rc = cx231xx_tuner_pre_channel_change(dev); |
1355 | 1434 | ||
1356 | mutex_lock(&dev->lock); | ||
1357 | |||
1358 | dev->ctl_freq = f->frequency; | 1435 | dev->ctl_freq = f->frequency; |
1359 | 1436 | call_all(dev, tuner, s_frequency, f); | |
1360 | if (dev->tuner_type == TUNER_XC5000) { | ||
1361 | if (dev->cx231xx_set_analog_freq != NULL) | ||
1362 | dev->cx231xx_set_analog_freq(dev, f->frequency); | ||
1363 | } else | ||
1364 | call_all(dev, tuner, s_frequency, f); | ||
1365 | |||
1366 | mutex_unlock(&dev->lock); | ||
1367 | 1437 | ||
1368 | /* set post channel change settings in DIF first */ | 1438 | /* set post channel change settings in DIF first */ |
1369 | rc = cx231xx_tuner_post_channel_change(dev); | 1439 | rc = cx231xx_tuner_post_channel_change(dev); |
1370 | 1440 | ||
1441 | if (dev->tuner_type == TUNER_NXP_TDA18271) { | ||
1442 | if (dev->norm & (V4L2_STD_MN | V4L2_STD_NTSC_443)) | ||
1443 | if_frequency = 5400000; /*5.4MHz */ | ||
1444 | else if (dev->norm & V4L2_STD_B) | ||
1445 | if_frequency = 6000000; /*6.0MHz */ | ||
1446 | else if (dev->norm & (V4L2_STD_PAL_DK | V4L2_STD_SECAM_DK)) | ||
1447 | if_frequency = 6900000; /*6.9MHz */ | ||
1448 | else if (dev->norm & V4L2_STD_GH) | ||
1449 | if_frequency = 7100000; /*7.1MHz */ | ||
1450 | else if (dev->norm & V4L2_STD_PAL_I) | ||
1451 | if_frequency = 7250000; /*7.25MHz */ | ||
1452 | else if (dev->norm & V4L2_STD_SECAM_L) | ||
1453 | if_frequency = 6900000; /*6.9MHz */ | ||
1454 | else if (dev->norm & V4L2_STD_SECAM_LC) | ||
1455 | if_frequency = 1250000; /*1.25MHz */ | ||
1456 | |||
1457 | cx231xx_info("if_frequency is set to %d\n", if_frequency); | ||
1458 | cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1); | ||
1459 | |||
1460 | update_HH_register_after_set_DIF(dev); | ||
1461 | } | ||
1462 | |||
1371 | cx231xx_info("Set New FREQUENCY to %d\n", f->frequency); | 1463 | cx231xx_info("Set New FREQUENCY to %d\n", f->frequency); |
1372 | 1464 | ||
1373 | return rc; | 1465 | return rc; |
@@ -1445,17 +1537,92 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1445 | case V4L2_CHIP_MATCH_I2C_DRIVER: | 1537 | case V4L2_CHIP_MATCH_I2C_DRIVER: |
1446 | call_all(dev, core, g_register, reg); | 1538 | call_all(dev, core, g_register, reg); |
1447 | return 0; | 1539 | return 0; |
1448 | case V4L2_CHIP_MATCH_I2C_ADDR: | 1540 | case V4L2_CHIP_MATCH_I2C_ADDR:/*for register debug*/ |
1449 | /* Not supported yet */ | 1541 | switch (reg->match.addr) { |
1450 | return -EINVAL; | 1542 | case 0: /* Cx231xx - internal registers */ |
1543 | ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, | ||
1544 | (u16)reg->reg, value, 4); | ||
1545 | reg->val = value[0] | value[1] << 8 | | ||
1546 | value[2] << 16 | value[3] << 24; | ||
1547 | |||
1548 | break; | ||
1549 | case 0x600:/* AFE - read byte */ | ||
1550 | ret = cx231xx_read_i2c_master(dev, AFE_DEVICE_ADDRESS, | ||
1551 | (u16)reg->reg, 2, | ||
1552 | &data, 1 , 0); | ||
1553 | reg->val = le32_to_cpu(data & 0xff); | ||
1554 | break; | ||
1555 | |||
1556 | case 0x880:/* Video Block - read byte */ | ||
1557 | if (reg->reg < 0x0b) { | ||
1558 | ret = cx231xx_read_i2c_master(dev, | ||
1559 | VID_BLK_I2C_ADDRESS, | ||
1560 | (u16)reg->reg, 2, | ||
1561 | &data, 1 , 0); | ||
1562 | reg->val = le32_to_cpu(data & 0xff); | ||
1563 | } else { | ||
1564 | ret = cx231xx_read_i2c_master(dev, | ||
1565 | VID_BLK_I2C_ADDRESS, | ||
1566 | (u16)reg->reg, 2, | ||
1567 | &data, 4 , 0); | ||
1568 | reg->val = le32_to_cpu(data); | ||
1569 | } | ||
1570 | break; | ||
1571 | case 0x980: | ||
1572 | ret = cx231xx_read_i2c_master(dev, | ||
1573 | I2S_BLK_DEVICE_ADDRESS, | ||
1574 | (u16)reg->reg, 1, | ||
1575 | &data, 1 , 0); | ||
1576 | reg->val = le32_to_cpu(data & 0xff); | ||
1577 | break; | ||
1578 | case 0x400: | ||
1579 | ret = | ||
1580 | cx231xx_read_i2c_master(dev, 0x40, | ||
1581 | (u16)reg->reg, 1, | ||
1582 | &data, 1 , 0); | ||
1583 | reg->val = le32_to_cpu(data & 0xff); | ||
1584 | break; | ||
1585 | case 0xc01: | ||
1586 | ret = | ||
1587 | cx231xx_read_i2c_master(dev, 0xc0, | ||
1588 | (u16)reg->reg, 2, | ||
1589 | &data, 38, 1); | ||
1590 | reg->val = le32_to_cpu(data); | ||
1591 | break; | ||
1592 | case 0x022: | ||
1593 | ret = | ||
1594 | cx231xx_read_i2c_master(dev, 0x02, | ||
1595 | (u16)reg->reg, 1, | ||
1596 | &data, 1, 2); | ||
1597 | reg->val = le32_to_cpu(data & 0xff); | ||
1598 | break; | ||
1599 | case 0x322: | ||
1600 | ret = cx231xx_read_i2c_master(dev, | ||
1601 | 0x32, | ||
1602 | (u16)reg->reg, 1, | ||
1603 | &data, 4 , 2); | ||
1604 | reg->val = le32_to_cpu(data); | ||
1605 | break; | ||
1606 | case 0x342: | ||
1607 | ret = cx231xx_read_i2c_master(dev, | ||
1608 | 0x34, | ||
1609 | (u16)reg->reg, 1, | ||
1610 | &data, 4 , 2); | ||
1611 | reg->val = le32_to_cpu(data); | ||
1612 | break; | ||
1613 | |||
1614 | default: | ||
1615 | cx231xx_info("no match device address!!\n"); | ||
1616 | break; | ||
1617 | } | ||
1618 | return ret < 0 ? ret : 0; | ||
1619 | /*return -EINVAL;*/ | ||
1451 | default: | 1620 | default: |
1452 | if (!v4l2_chip_match_host(®->match)) | 1621 | if (!v4l2_chip_match_host(®->match)) |
1453 | return -EINVAL; | 1622 | return -EINVAL; |
1454 | } | 1623 | } |
1455 | 1624 | ||
1456 | mutex_lock(&dev->lock); | ||
1457 | call_all(dev, core, g_register, reg); | 1625 | call_all(dev, core, g_register, reg); |
1458 | mutex_unlock(&dev->lock); | ||
1459 | 1626 | ||
1460 | return ret; | 1627 | return ret; |
1461 | } | 1628 | } |
@@ -1531,14 +1698,96 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1531 | } | 1698 | } |
1532 | } | 1699 | } |
1533 | return ret < 0 ? ret : 0; | 1700 | return ret < 0 ? ret : 0; |
1701 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1702 | { | ||
1703 | value = (u32) buf & 0xffffffff; | ||
1704 | |||
1705 | switch (reg->match.addr) { | ||
1706 | case 0:/*cx231xx internal registers*/ | ||
1707 | data[0] = (u8) value; | ||
1708 | data[1] = (u8) (value >> 8); | ||
1709 | data[2] = (u8) (value >> 16); | ||
1710 | data[3] = (u8) (value >> 24); | ||
1711 | ret = cx231xx_write_ctrl_reg(dev, | ||
1712 | VRT_SET_REGISTER, | ||
1713 | (u16)reg->reg, data, | ||
1714 | 4); | ||
1715 | break; | ||
1716 | case 0x600:/* AFE - read byte */ | ||
1717 | ret = cx231xx_write_i2c_master(dev, | ||
1718 | AFE_DEVICE_ADDRESS, | ||
1719 | (u16)reg->reg, 2, | ||
1720 | value, 1 , 0); | ||
1721 | break; | ||
1534 | 1722 | ||
1723 | case 0x880:/* Video Block - read byte */ | ||
1724 | if (reg->reg < 0x0b) | ||
1725 | cx231xx_write_i2c_master(dev, | ||
1726 | VID_BLK_I2C_ADDRESS, | ||
1727 | (u16)reg->reg, 2, | ||
1728 | value, 1, 0); | ||
1729 | else | ||
1730 | cx231xx_write_i2c_master(dev, | ||
1731 | VID_BLK_I2C_ADDRESS, | ||
1732 | (u16)reg->reg, 2, | ||
1733 | value, 4, 0); | ||
1734 | break; | ||
1735 | case 0x980: | ||
1736 | ret = | ||
1737 | cx231xx_write_i2c_master(dev, | ||
1738 | I2S_BLK_DEVICE_ADDRESS, | ||
1739 | (u16)reg->reg, 1, | ||
1740 | value, 1, 0); | ||
1741 | break; | ||
1742 | case 0x400: | ||
1743 | ret = | ||
1744 | cx231xx_write_i2c_master(dev, | ||
1745 | 0x40, | ||
1746 | (u16)reg->reg, 1, | ||
1747 | value, 1, 0); | ||
1748 | break; | ||
1749 | case 0xc01: | ||
1750 | ret = | ||
1751 | cx231xx_write_i2c_master(dev, | ||
1752 | 0xc0, | ||
1753 | (u16)reg->reg, 1, | ||
1754 | value, 1, 1); | ||
1755 | break; | ||
1756 | |||
1757 | case 0x022: | ||
1758 | ret = | ||
1759 | cx231xx_write_i2c_master(dev, | ||
1760 | 0x02, | ||
1761 | (u16)reg->reg, 1, | ||
1762 | value, 1, 2); | ||
1763 | case 0x322: | ||
1764 | ret = | ||
1765 | cx231xx_write_i2c_master(dev, | ||
1766 | 0x32, | ||
1767 | (u16)reg->reg, 1, | ||
1768 | value, 4, 2); | ||
1769 | break; | ||
1770 | |||
1771 | case 0x342: | ||
1772 | ret = | ||
1773 | cx231xx_write_i2c_master(dev, | ||
1774 | 0x34, | ||
1775 | (u16)reg->reg, 1, | ||
1776 | value, 4, 2); | ||
1777 | break; | ||
1778 | default: | ||
1779 | cx231xx_info("no match device address, " | ||
1780 | "the value is %x\n", reg->match.addr); | ||
1781 | break; | ||
1782 | |||
1783 | } | ||
1784 | |||
1785 | } | ||
1535 | default: | 1786 | default: |
1536 | break; | 1787 | break; |
1537 | } | 1788 | } |
1538 | 1789 | ||
1539 | mutex_lock(&dev->lock); | ||
1540 | call_all(dev, core, s_register, reg); | 1790 | call_all(dev, core, s_register, reg); |
1541 | mutex_unlock(&dev->lock); | ||
1542 | 1791 | ||
1543 | return ret; | 1792 | return ret; |
1544 | } | 1793 | } |
@@ -1575,7 +1824,6 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1575 | if (rc < 0) | 1824 | if (rc < 0) |
1576 | return rc; | 1825 | return rc; |
1577 | 1826 | ||
1578 | mutex_lock(&dev->lock); | ||
1579 | rc = res_get(fh); | 1827 | rc = res_get(fh); |
1580 | 1828 | ||
1581 | if (likely(rc >= 0)) | 1829 | if (likely(rc >= 0)) |
@@ -1583,8 +1831,6 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1583 | 1831 | ||
1584 | call_all(dev, video, s_stream, 1); | 1832 | call_all(dev, video, s_stream, 1); |
1585 | 1833 | ||
1586 | mutex_unlock(&dev->lock); | ||
1587 | |||
1588 | return rc; | 1834 | return rc; |
1589 | } | 1835 | } |
1590 | 1836 | ||
@@ -1605,15 +1851,11 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1605 | if (type != fh->type) | 1851 | if (type != fh->type) |
1606 | return -EINVAL; | 1852 | return -EINVAL; |
1607 | 1853 | ||
1608 | mutex_lock(&dev->lock); | ||
1609 | |||
1610 | cx25840_call(dev, video, s_stream, 0); | 1854 | cx25840_call(dev, video, s_stream, 0); |
1611 | 1855 | ||
1612 | videobuf_streamoff(&fh->vb_vidq); | 1856 | videobuf_streamoff(&fh->vb_vidq); |
1613 | res_free(fh); | 1857 | res_free(fh); |
1614 | 1858 | ||
1615 | mutex_unlock(&dev->lock); | ||
1616 | |||
1617 | return 0; | 1859 | return 0; |
1618 | } | 1860 | } |
1619 | 1861 | ||
@@ -1668,8 +1910,6 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, | |||
1668 | if (rc < 0) | 1910 | if (rc < 0) |
1669 | return rc; | 1911 | return rc; |
1670 | 1912 | ||
1671 | mutex_lock(&dev->lock); | ||
1672 | |||
1673 | f->fmt.sliced.service_set = 0; | 1913 | f->fmt.sliced.service_set = 0; |
1674 | 1914 | ||
1675 | call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); | 1915 | call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); |
@@ -1677,7 +1917,6 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, | |||
1677 | if (f->fmt.sliced.service_set == 0) | 1917 | if (f->fmt.sliced.service_set == 0) |
1678 | rc = -EINVAL; | 1918 | rc = -EINVAL; |
1679 | 1919 | ||
1680 | mutex_unlock(&dev->lock); | ||
1681 | return rc; | 1920 | return rc; |
1682 | } | 1921 | } |
1683 | 1922 | ||
@@ -1692,9 +1931,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, | |||
1692 | if (rc < 0) | 1931 | if (rc < 0) |
1693 | return rc; | 1932 | return rc; |
1694 | 1933 | ||
1695 | mutex_lock(&dev->lock); | ||
1696 | call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); | 1934 | call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); |
1697 | mutex_unlock(&dev->lock); | ||
1698 | 1935 | ||
1699 | if (f->fmt.sliced.service_set == 0) | 1936 | if (f->fmt.sliced.service_set == 0) |
1700 | return -EINVAL; | 1937 | return -EINVAL; |
@@ -1709,12 +1946,10 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | |||
1709 | { | 1946 | { |
1710 | struct cx231xx_fh *fh = priv; | 1947 | struct cx231xx_fh *fh = priv; |
1711 | struct cx231xx *dev = fh->dev; | 1948 | struct cx231xx *dev = fh->dev; |
1712 | 1949 | f->fmt.vbi.sampling_rate = 6750000 * 4; | |
1713 | f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ? | ||
1714 | 35468950 : 28636363; | ||
1715 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; | 1950 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; |
1716 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1951 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
1717 | f->fmt.vbi.offset = 64 * 4; | 1952 | f->fmt.vbi.offset = 0; |
1718 | f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ? | 1953 | f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ? |
1719 | PAL_VBI_START_LINE : NTSC_VBI_START_LINE; | 1954 | PAL_VBI_START_LINE : NTSC_VBI_START_LINE; |
1720 | f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ? | 1955 | f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ? |
@@ -1739,11 +1974,10 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, | |||
1739 | } | 1974 | } |
1740 | 1975 | ||
1741 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1976 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; |
1742 | f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ? | 1977 | f->fmt.vbi.sampling_rate = 6750000 * 4; |
1743 | 35468950 : 28636363; | ||
1744 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; | 1978 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; |
1745 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1979 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
1746 | f->fmt.vbi.offset = 244; | 1980 | f->fmt.vbi.offset = 0; |
1747 | f->fmt.vbi.flags = 0; | 1981 | f->fmt.vbi.flags = 0; |
1748 | f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ? | 1982 | f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ? |
1749 | PAL_VBI_START_LINE : NTSC_VBI_START_LINE; | 1983 | PAL_VBI_START_LINE : NTSC_VBI_START_LINE; |
@@ -1847,9 +2081,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
1847 | strcpy(t->name, "Radio"); | 2081 | strcpy(t->name, "Radio"); |
1848 | t->type = V4L2_TUNER_RADIO; | 2082 | t->type = V4L2_TUNER_RADIO; |
1849 | 2083 | ||
1850 | mutex_lock(&dev->lock); | ||
1851 | call_all(dev, tuner, s_tuner, t); | 2084 | call_all(dev, tuner, s_tuner, t); |
1852 | mutex_unlock(&dev->lock); | ||
1853 | 2085 | ||
1854 | return 0; | 2086 | return 0; |
1855 | } | 2087 | } |
@@ -1880,9 +2112,7 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
1880 | if (0 != t->index) | 2112 | if (0 != t->index) |
1881 | return -EINVAL; | 2113 | return -EINVAL; |
1882 | 2114 | ||
1883 | mutex_lock(&dev->lock); | ||
1884 | call_all(dev, tuner, s_tuner, t); | 2115 | call_all(dev, tuner, s_tuner, t); |
1885 | mutex_unlock(&dev->lock); | ||
1886 | 2116 | ||
1887 | return 0; | 2117 | return 0; |
1888 | } | 2118 | } |
@@ -1941,8 +2171,6 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1941 | break; | 2171 | break; |
1942 | } | 2172 | } |
1943 | 2173 | ||
1944 | mutex_lock(&dev->lock); | ||
1945 | |||
1946 | cx231xx_videodbg("open dev=%s type=%s users=%d\n", | 2174 | cx231xx_videodbg("open dev=%s type=%s users=%d\n", |
1947 | video_device_node_name(vdev), v4l2_type_names[fh_type], | 2175 | video_device_node_name(vdev), v4l2_type_names[fh_type], |
1948 | dev->users); | 2176 | dev->users); |
@@ -1952,7 +2180,6 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1952 | if (errCode < 0) { | 2180 | if (errCode < 0) { |
1953 | cx231xx_errdev | 2181 | cx231xx_errdev |
1954 | ("Device locked on digital mode. Can't open analog\n"); | 2182 | ("Device locked on digital mode. Can't open analog\n"); |
1955 | mutex_unlock(&dev->lock); | ||
1956 | return -EBUSY; | 2183 | return -EBUSY; |
1957 | } | 2184 | } |
1958 | #endif | 2185 | #endif |
@@ -1960,7 +2187,6 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1960 | fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL); | 2187 | fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL); |
1961 | if (!fh) { | 2188 | if (!fh) { |
1962 | cx231xx_errdev("cx231xx-video.c: Out of memory?!\n"); | 2189 | cx231xx_errdev("cx231xx-video.c: Out of memory?!\n"); |
1963 | mutex_unlock(&dev->lock); | ||
1964 | return -ENOMEM; | 2190 | return -ENOMEM; |
1965 | } | 2191 | } |
1966 | fh->dev = dev; | 2192 | fh->dev = dev; |
@@ -1971,16 +2197,18 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1971 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 2197 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
1972 | dev->width = norm_maxw(dev); | 2198 | dev->width = norm_maxw(dev); |
1973 | dev->height = norm_maxh(dev); | 2199 | dev->height = norm_maxh(dev); |
1974 | dev->hscale = 0; | ||
1975 | dev->vscale = 0; | ||
1976 | 2200 | ||
1977 | /* Power up in Analog TV mode */ | 2201 | /* Power up in Analog TV mode */ |
1978 | cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); | 2202 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || |
2203 | dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) | ||
2204 | cx231xx_set_power_mode(dev, | ||
2205 | POLARIS_AVMODE_ENXTERNAL_AV); | ||
2206 | else | ||
2207 | cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); | ||
1979 | 2208 | ||
1980 | #if 0 | 2209 | #if 0 |
1981 | cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); | 2210 | cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); |
1982 | #endif | 2211 | #endif |
1983 | cx231xx_resolution_set(dev); | ||
1984 | 2212 | ||
1985 | /* set video alternate setting */ | 2213 | /* set video alternate setting */ |
1986 | cx231xx_set_video_alternate(dev); | 2214 | cx231xx_set_video_alternate(dev); |
@@ -1991,7 +2219,6 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
1991 | 2219 | ||
1992 | /* device needs to be initialized before isoc transfer */ | 2220 | /* device needs to be initialized before isoc transfer */ |
1993 | dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; | 2221 | dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; |
1994 | video_mux(dev, dev->video_input); | ||
1995 | 2222 | ||
1996 | } | 2223 | } |
1997 | if (fh->radio) { | 2224 | if (fh->radio) { |
@@ -2008,20 +2235,22 @@ static int cx231xx_v4l2_open(struct file *filp) | |||
2008 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops, | 2235 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops, |
2009 | NULL, &dev->video_mode.slock, | 2236 | NULL, &dev->video_mode.slock, |
2010 | fh->type, V4L2_FIELD_INTERLACED, | 2237 | fh->type, V4L2_FIELD_INTERLACED, |
2011 | sizeof(struct cx231xx_buffer), fh); | 2238 | sizeof(struct cx231xx_buffer), |
2239 | fh, &dev->lock); | ||
2012 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 2240 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
2013 | /* Set the required alternate setting VBI interface works in | 2241 | /* Set the required alternate setting VBI interface works in |
2014 | Bulk mode only */ | 2242 | Bulk mode only */ |
2015 | cx231xx_set_alt_setting(dev, INDEX_VANC, 0); | 2243 | if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && |
2244 | dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2) | ||
2245 | cx231xx_set_alt_setting(dev, INDEX_VANC, 0); | ||
2016 | 2246 | ||
2017 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, | 2247 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, |
2018 | NULL, &dev->vbi_mode.slock, | 2248 | NULL, &dev->vbi_mode.slock, |
2019 | fh->type, V4L2_FIELD_SEQ_TB, | 2249 | fh->type, V4L2_FIELD_SEQ_TB, |
2020 | sizeof(struct cx231xx_buffer), fh); | 2250 | sizeof(struct cx231xx_buffer), |
2251 | fh, &dev->lock); | ||
2021 | } | 2252 | } |
2022 | 2253 | ||
2023 | mutex_unlock(&dev->lock); | ||
2024 | |||
2025 | return errCode; | 2254 | return errCode; |
2026 | } | 2255 | } |
2027 | 2256 | ||
@@ -2054,6 +2283,10 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) | |||
2054 | if (dev->vdev) { | 2283 | if (dev->vdev) { |
2055 | cx231xx_info("V4L2 device %s deregistered\n", | 2284 | cx231xx_info("V4L2 device %s deregistered\n", |
2056 | video_device_node_name(dev->vdev)); | 2285 | video_device_node_name(dev->vdev)); |
2286 | |||
2287 | if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) | ||
2288 | cx231xx_417_unregister(dev); | ||
2289 | |||
2057 | if (video_is_registered(dev->vdev)) | 2290 | if (video_is_registered(dev->vdev)) |
2058 | video_unregister_device(dev->vdev); | 2291 | video_unregister_device(dev->vdev); |
2059 | else | 2292 | else |
@@ -2074,39 +2307,44 @@ static int cx231xx_v4l2_close(struct file *filp) | |||
2074 | 2307 | ||
2075 | cx231xx_videodbg("users=%d\n", dev->users); | 2308 | cx231xx_videodbg("users=%d\n", dev->users); |
2076 | 2309 | ||
2077 | mutex_lock(&dev->lock); | 2310 | cx231xx_videodbg("users=%d\n", dev->users); |
2078 | |||
2079 | if (res_check(fh)) | 2311 | if (res_check(fh)) |
2080 | res_free(fh); | 2312 | res_free(fh); |
2081 | 2313 | ||
2082 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 2314 | /*To workaround error number=-71 on EP0 for VideoGrabber, |
2083 | videobuf_stop(&fh->vb_vidq); | 2315 | need exclude following.*/ |
2084 | videobuf_mmap_free(&fh->vb_vidq); | 2316 | if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && |
2085 | 2317 | dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2) | |
2086 | /* the device is already disconnect, | 2318 | if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
2087 | free the remaining resources */ | 2319 | videobuf_stop(&fh->vb_vidq); |
2088 | if (dev->state & DEV_DISCONNECTED) { | 2320 | videobuf_mmap_free(&fh->vb_vidq); |
2089 | cx231xx_release_resources(dev); | 2321 | |
2090 | mutex_unlock(&dev->lock); | 2322 | /* the device is already disconnect, |
2091 | kfree(dev); | 2323 | free the remaining resources */ |
2092 | return 0; | 2324 | if (dev->state & DEV_DISCONNECTED) { |
2093 | } | 2325 | if (atomic_read(&dev->devlist_count) > 0) { |
2326 | cx231xx_release_resources(dev); | ||
2327 | kfree(dev); | ||
2328 | dev = NULL; | ||
2329 | return 0; | ||
2330 | } | ||
2331 | return 0; | ||
2332 | } | ||
2094 | 2333 | ||
2095 | /* do this before setting alternate! */ | 2334 | /* do this before setting alternate! */ |
2096 | cx231xx_uninit_vbi_isoc(dev); | 2335 | cx231xx_uninit_vbi_isoc(dev); |
2097 | 2336 | ||
2098 | /* set alternate 0 */ | 2337 | /* set alternate 0 */ |
2099 | if (!dev->vbi_or_sliced_cc_mode) | 2338 | if (!dev->vbi_or_sliced_cc_mode) |
2100 | cx231xx_set_alt_setting(dev, INDEX_VANC, 0); | 2339 | cx231xx_set_alt_setting(dev, INDEX_VANC, 0); |
2101 | else | 2340 | else |
2102 | cx231xx_set_alt_setting(dev, INDEX_HANC, 0); | 2341 | cx231xx_set_alt_setting(dev, INDEX_HANC, 0); |
2103 | 2342 | ||
2104 | kfree(fh); | 2343 | kfree(fh); |
2105 | dev->users--; | 2344 | dev->users--; |
2106 | wake_up_interruptible_nr(&dev->open, 1); | 2345 | wake_up_interruptible_nr(&dev->open, 1); |
2107 | mutex_unlock(&dev->lock); | 2346 | return 0; |
2108 | return 0; | 2347 | } |
2109 | } | ||
2110 | 2348 | ||
2111 | if (dev->users == 1) { | 2349 | if (dev->users == 1) { |
2112 | videobuf_stop(&fh->vb_vidq); | 2350 | videobuf_stop(&fh->vb_vidq); |
@@ -2116,8 +2354,8 @@ static int cx231xx_v4l2_close(struct file *filp) | |||
2116 | free the remaining resources */ | 2354 | free the remaining resources */ |
2117 | if (dev->state & DEV_DISCONNECTED) { | 2355 | if (dev->state & DEV_DISCONNECTED) { |
2118 | cx231xx_release_resources(dev); | 2356 | cx231xx_release_resources(dev); |
2119 | mutex_unlock(&dev->lock); | ||
2120 | kfree(dev); | 2357 | kfree(dev); |
2358 | dev = NULL; | ||
2121 | return 0; | 2359 | return 0; |
2122 | } | 2360 | } |
2123 | 2361 | ||
@@ -2125,7 +2363,10 @@ static int cx231xx_v4l2_close(struct file *filp) | |||
2125 | call_all(dev, core, s_power, 0); | 2363 | call_all(dev, core, s_power, 0); |
2126 | 2364 | ||
2127 | /* do this before setting alternate! */ | 2365 | /* do this before setting alternate! */ |
2128 | cx231xx_uninit_isoc(dev); | 2366 | if (dev->USE_ISO) |
2367 | cx231xx_uninit_isoc(dev); | ||
2368 | else | ||
2369 | cx231xx_uninit_bulk(dev); | ||
2129 | cx231xx_set_mode(dev, CX231XX_SUSPEND); | 2370 | cx231xx_set_mode(dev, CX231XX_SUSPEND); |
2130 | 2371 | ||
2131 | /* set alternate 0 */ | 2372 | /* set alternate 0 */ |
@@ -2134,7 +2375,6 @@ static int cx231xx_v4l2_close(struct file *filp) | |||
2134 | kfree(fh); | 2375 | kfree(fh); |
2135 | dev->users--; | 2376 | dev->users--; |
2136 | wake_up_interruptible_nr(&dev->open, 1); | 2377 | wake_up_interruptible_nr(&dev->open, 1); |
2137 | mutex_unlock(&dev->lock); | ||
2138 | return 0; | 2378 | return 0; |
2139 | } | 2379 | } |
2140 | 2380 | ||
@@ -2156,9 +2396,7 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
2156 | 2396 | ||
2157 | if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || | 2397 | if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || |
2158 | (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) { | 2398 | (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) { |
2159 | mutex_lock(&dev->lock); | ||
2160 | rc = res_get(fh); | 2399 | rc = res_get(fh); |
2161 | mutex_unlock(&dev->lock); | ||
2162 | 2400 | ||
2163 | if (unlikely(rc < 0)) | 2401 | if (unlikely(rc < 0)) |
2164 | return rc; | 2402 | return rc; |
@@ -2173,7 +2411,7 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
2173 | * cx231xx_v4l2_poll() | 2411 | * cx231xx_v4l2_poll() |
2174 | * will allocate buffers when called for the first time | 2412 | * will allocate buffers when called for the first time |
2175 | */ | 2413 | */ |
2176 | static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait) | 2414 | static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait) |
2177 | { | 2415 | { |
2178 | struct cx231xx_fh *fh = filp->private_data; | 2416 | struct cx231xx_fh *fh = filp->private_data; |
2179 | struct cx231xx *dev = fh->dev; | 2417 | struct cx231xx *dev = fh->dev; |
@@ -2183,9 +2421,7 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait) | |||
2183 | if (rc < 0) | 2421 | if (rc < 0) |
2184 | return rc; | 2422 | return rc; |
2185 | 2423 | ||
2186 | mutex_lock(&dev->lock); | ||
2187 | rc = res_get(fh); | 2424 | rc = res_get(fh); |
2188 | mutex_unlock(&dev->lock); | ||
2189 | 2425 | ||
2190 | if (unlikely(rc < 0)) | 2426 | if (unlikely(rc < 0)) |
2191 | return POLLERR; | 2427 | return POLLERR; |
@@ -2210,9 +2446,7 @@ static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2210 | if (rc < 0) | 2446 | if (rc < 0) |
2211 | return rc; | 2447 | return rc; |
2212 | 2448 | ||
2213 | mutex_lock(&dev->lock); | ||
2214 | rc = res_get(fh); | 2449 | rc = res_get(fh); |
2215 | mutex_unlock(&dev->lock); | ||
2216 | 2450 | ||
2217 | if (unlikely(rc < 0)) | 2451 | if (unlikely(rc < 0)) |
2218 | return rc; | 2452 | return rc; |
@@ -2234,7 +2468,7 @@ static const struct v4l2_file_operations cx231xx_v4l_fops = { | |||
2234 | .read = cx231xx_v4l2_read, | 2468 | .read = cx231xx_v4l2_read, |
2235 | .poll = cx231xx_v4l2_poll, | 2469 | .poll = cx231xx_v4l2_poll, |
2236 | .mmap = cx231xx_v4l2_mmap, | 2470 | .mmap = cx231xx_v4l2_mmap, |
2237 | .ioctl = video_ioctl2, | 2471 | .unlocked_ioctl = video_ioctl2, |
2238 | }; | 2472 | }; |
2239 | 2473 | ||
2240 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 2474 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
@@ -2336,6 +2570,7 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, | |||
2336 | vfd->v4l2_dev = &dev->v4l2_dev; | 2570 | vfd->v4l2_dev = &dev->v4l2_dev; |
2337 | vfd->release = video_device_release; | 2571 | vfd->release = video_device_release; |
2338 | vfd->debug = video_debug; | 2572 | vfd->debug = video_debug; |
2573 | vfd->lock = &dev->lock; | ||
2339 | 2574 | ||
2340 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); | 2575 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); |
2341 | 2576 | ||
@@ -2358,12 +2593,12 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2358 | dev->width = norm_maxw(dev); | 2593 | dev->width = norm_maxw(dev); |
2359 | dev->height = norm_maxh(dev); | 2594 | dev->height = norm_maxh(dev); |
2360 | dev->interlaced = 0; | 2595 | dev->interlaced = 0; |
2361 | dev->hscale = 0; | ||
2362 | dev->vscale = 0; | ||
2363 | 2596 | ||
2364 | /* Analog specific initialization */ | 2597 | /* Analog specific initialization */ |
2365 | dev->format = &format[0]; | 2598 | dev->format = &format[0]; |
2366 | /* video_mux(dev, dev->video_input); */ | 2599 | |
2600 | /* Set the initial input */ | ||
2601 | video_mux(dev, dev->video_input); | ||
2367 | 2602 | ||
2368 | /* Audio defaults */ | 2603 | /* Audio defaults */ |
2369 | dev->mute = 1; | 2604 | dev->mute = 1; |
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index 38d417191a6..d067df9b81e 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h | |||
@@ -27,16 +27,15 @@ | |||
27 | #include <linux/ioctl.h> | 27 | #include <linux/ioctl.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/i2c-algo-bit.h> | 29 | #include <linux/i2c-algo-bit.h> |
30 | #include <linux/workqueue.h> | ||
30 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
31 | 32 | ||
33 | #include <media/cx2341x.h> | ||
32 | 34 | ||
33 | #include <media/videobuf-vmalloc.h> | 35 | #include <media/videobuf-vmalloc.h> |
34 | #include <media/v4l2-device.h> | 36 | #include <media/v4l2-device.h> |
35 | #include <media/ir-core.h> | 37 | #include <media/ir-core.h> |
36 | #if defined(CONFIG_VIDEO_CX231XX_DVB) || \ | ||
37 | defined(CONFIG_VIDEO_CX231XX_DVB_MODULE) | ||
38 | #include <media/videobuf-dvb.h> | 38 | #include <media/videobuf-dvb.h> |
39 | #endif | ||
40 | 39 | ||
41 | #include "cx231xx-reg.h" | 40 | #include "cx231xx-reg.h" |
42 | #include "cx231xx-pcb-cfg.h" | 41 | #include "cx231xx-pcb-cfg.h" |
@@ -49,12 +48,20 @@ | |||
49 | #define AFE_DEVICE_ADDRESS 0x60 | 48 | #define AFE_DEVICE_ADDRESS 0x60 |
50 | #define I2S_BLK_DEVICE_ADDRESS 0x98 | 49 | #define I2S_BLK_DEVICE_ADDRESS 0x98 |
51 | #define VID_BLK_I2C_ADDRESS 0x88 | 50 | #define VID_BLK_I2C_ADDRESS 0x88 |
51 | #define VERVE_I2C_ADDRESS 0x40 | ||
52 | #define DIF_USE_BASEBAND 0xFFFFFFFF | 52 | #define DIF_USE_BASEBAND 0xFFFFFFFF |
53 | 53 | ||
54 | /* Boards supported by driver */ | 54 | /* Boards supported by driver */ |
55 | #define CX231XX_BOARD_UNKNOWN 0 | 55 | #define CX231XX_BOARD_UNKNOWN 0 |
56 | #define CX231XX_BOARD_CNXT_RDE_250 1 | 56 | #define CX231XX_BOARD_CNXT_CARRAERA 1 |
57 | #define CX231XX_BOARD_CNXT_RDU_250 2 | 57 | #define CX231XX_BOARD_CNXT_SHELBY 2 |
58 | #define CX231XX_BOARD_CNXT_RDE_253S 3 | ||
59 | #define CX231XX_BOARD_CNXT_RDU_253S 4 | ||
60 | #define CX231XX_BOARD_CNXT_VIDEO_GRABBER 5 | ||
61 | #define CX231XX_BOARD_CNXT_RDE_250 6 | ||
62 | #define CX231XX_BOARD_CNXT_RDU_250 7 | ||
63 | #define CX231XX_BOARD_HAUPPAUGE_EXETER 8 | ||
64 | #define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 | ||
58 | 65 | ||
59 | /* Limits minimum and default number of buffers */ | 66 | /* Limits minimum and default number of buffers */ |
60 | #define CX231XX_MIN_BUF 4 | 67 | #define CX231XX_MIN_BUF 4 |
@@ -95,6 +102,24 @@ | |||
95 | #define CX231XX_URB_TIMEOUT \ | 102 | #define CX231XX_URB_TIMEOUT \ |
96 | msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS) | 103 | msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS) |
97 | 104 | ||
105 | #define CX231xx_NORMS (\ | ||
106 | V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \ | ||
107 | V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ | ||
108 | V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \ | ||
109 | V4L2_STD_PAL_60 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK) | ||
110 | #define CX231xx_VERSION_CODE KERNEL_VERSION(0, 0, 2) | ||
111 | |||
112 | #define SLEEP_S5H1432 30 | ||
113 | #define CX23417_OSC_EN 8 | ||
114 | #define CX23417_RESET 9 | ||
115 | |||
116 | struct cx23417_fmt { | ||
117 | char *name; | ||
118 | u32 fourcc; /* v4l2 format id */ | ||
119 | int depth; | ||
120 | int flags; | ||
121 | u32 cxformat; | ||
122 | }; | ||
98 | enum cx231xx_mode { | 123 | enum cx231xx_mode { |
99 | CX231XX_SUSPEND, | 124 | CX231XX_SUSPEND, |
100 | CX231XX_ANALOG_MODE, | 125 | CX231XX_ANALOG_MODE, |
@@ -114,7 +139,7 @@ enum cx231xx_stream_state { | |||
114 | 139 | ||
115 | struct cx231xx; | 140 | struct cx231xx; |
116 | 141 | ||
117 | struct cx231xx_usb_isoc_ctl { | 142 | struct cx231xx_isoc_ctl { |
118 | /* max packet size of isoc transaction */ | 143 | /* max packet size of isoc transaction */ |
119 | int max_pkt_size; | 144 | int max_pkt_size; |
120 | 145 | ||
@@ -148,6 +173,40 @@ struct cx231xx_usb_isoc_ctl { | |||
148 | int (*isoc_copy) (struct cx231xx *dev, struct urb *urb); | 173 | int (*isoc_copy) (struct cx231xx *dev, struct urb *urb); |
149 | }; | 174 | }; |
150 | 175 | ||
176 | struct cx231xx_bulk_ctl { | ||
177 | /* max packet size of bulk transaction */ | ||
178 | int max_pkt_size; | ||
179 | |||
180 | /* number of allocated urbs */ | ||
181 | int num_bufs; | ||
182 | |||
183 | /* urb for bulk transfers */ | ||
184 | struct urb **urb; | ||
185 | |||
186 | /* transfer buffers for bulk transfer */ | ||
187 | char **transfer_buffer; | ||
188 | |||
189 | /* Last buffer command and region */ | ||
190 | u8 cmd; | ||
191 | int pos, size, pktsize; | ||
192 | |||
193 | /* Last field: ODD or EVEN? */ | ||
194 | int field; | ||
195 | |||
196 | /* Stores incomplete commands */ | ||
197 | u32 tmp_buf; | ||
198 | int tmp_buf_len; | ||
199 | |||
200 | /* Stores already requested buffers */ | ||
201 | struct cx231xx_buffer *buf; | ||
202 | |||
203 | /* Stores the number of received fields */ | ||
204 | int nfields; | ||
205 | |||
206 | /* bulk urb callback */ | ||
207 | int (*bulk_copy) (struct cx231xx *dev, struct urb *urb); | ||
208 | }; | ||
209 | |||
151 | struct cx231xx_fmt { | 210 | struct cx231xx_fmt { |
152 | char *name; | 211 | char *name; |
153 | u32 fourcc; /* v4l2 format id */ | 212 | u32 fourcc; /* v4l2 format id */ |
@@ -165,6 +224,11 @@ struct cx231xx_buffer { | |||
165 | int receiving; | 224 | int receiving; |
166 | }; | 225 | }; |
167 | 226 | ||
227 | enum ps_package_head { | ||
228 | CX231XX_NEED_ADD_PS_PACKAGE_HEAD = 0, | ||
229 | CX231XX_NONEED_PS_PACKAGE_HEAD | ||
230 | }; | ||
231 | |||
168 | struct cx231xx_dmaqueue { | 232 | struct cx231xx_dmaqueue { |
169 | struct list_head active; | 233 | struct list_head active; |
170 | struct list_head queued; | 234 | struct list_head queued; |
@@ -181,6 +245,14 @@ struct cx231xx_dmaqueue { | |||
181 | u32 lines_completed; | 245 | u32 lines_completed; |
182 | u8 field1_done; | 246 | u8 field1_done; |
183 | u32 lines_per_field; | 247 | u32 lines_per_field; |
248 | |||
249 | /*Mpeg2 control buffer*/ | ||
250 | u8 *p_left_data; | ||
251 | u32 left_data_count; | ||
252 | u8 mpeg_buffer_done; | ||
253 | u32 mpeg_buffer_completed; | ||
254 | enum ps_package_head add_ps_package_head; | ||
255 | char ps_head[10]; | ||
184 | }; | 256 | }; |
185 | 257 | ||
186 | /* inputs */ | 258 | /* inputs */ |
@@ -259,9 +331,10 @@ struct cx231xx_board { | |||
259 | struct cx231xx_reg_seq *dvb_gpio; | 331 | struct cx231xx_reg_seq *dvb_gpio; |
260 | struct cx231xx_reg_seq *suspend_gpio; | 332 | struct cx231xx_reg_seq *suspend_gpio; |
261 | struct cx231xx_reg_seq *tuner_gpio; | 333 | struct cx231xx_reg_seq *tuner_gpio; |
262 | u8 tuner_sif_gpio; | 334 | /* Negative means don't use it */ |
263 | u8 tuner_scl_gpio; | 335 | s8 tuner_sif_gpio; |
264 | u8 tuner_sda_gpio; | 336 | s8 tuner_scl_gpio; |
337 | s8 tuner_sda_gpio; | ||
265 | 338 | ||
266 | /* PIN ctrl */ | 339 | /* PIN ctrl */ |
267 | u32 ctl_pin_status_mask; | 340 | u32 ctl_pin_status_mask; |
@@ -279,6 +352,7 @@ struct cx231xx_board { | |||
279 | unsigned char xclk, i2c_speed; | 352 | unsigned char xclk, i2c_speed; |
280 | 353 | ||
281 | enum cx231xx_decoder decoder; | 354 | enum cx231xx_decoder decoder; |
355 | int output_mode; | ||
282 | 356 | ||
283 | struct cx231xx_input input[MAX_CX231XX_INPUT]; | 357 | struct cx231xx_input input[MAX_CX231XX_INPUT]; |
284 | struct cx231xx_input radio; | 358 | struct cx231xx_input radio; |
@@ -309,10 +383,8 @@ enum AUDIO_INPUT { | |||
309 | }; | 383 | }; |
310 | 384 | ||
311 | #define CX231XX_AUDIO_BUFS 5 | 385 | #define CX231XX_AUDIO_BUFS 5 |
312 | #define CX231XX_NUM_AUDIO_PACKETS 64 | 386 | #define CX231XX_NUM_AUDIO_PACKETS 16 |
313 | #define CX231XX_CAPTURE_STREAM_EN 1 | 387 | #define CX231XX_ISO_NUM_AUDIO_PACKETS 64 |
314 | #define CX231XX_STOP_AUDIO 0 | ||
315 | #define CX231XX_START_AUDIO 1 | ||
316 | 388 | ||
317 | /* cx231xx extensions */ | 389 | /* cx231xx extensions */ |
318 | #define CX231XX_AUDIO 0x10 | 390 | #define CX231XX_AUDIO 0x10 |
@@ -330,7 +402,7 @@ struct cx231xx_audio { | |||
330 | struct snd_card *sndcard; | 402 | struct snd_card *sndcard; |
331 | 403 | ||
332 | int users, shutdown; | 404 | int users, shutdown; |
333 | enum cx231xx_stream_state capture_stream; | 405 | /* locks */ |
334 | spinlock_t slock; | 406 | spinlock_t slock; |
335 | 407 | ||
336 | int alt; /* alternate */ | 408 | int alt; /* alternate */ |
@@ -350,6 +422,28 @@ struct cx231xx_fh { | |||
350 | struct videobuf_queue vb_vidq; | 422 | struct videobuf_queue vb_vidq; |
351 | 423 | ||
352 | enum v4l2_buf_type type; | 424 | enum v4l2_buf_type type; |
425 | |||
426 | |||
427 | |||
428 | /*following is copyed from cx23885.h*/ | ||
429 | u32 resources; | ||
430 | |||
431 | /* video overlay */ | ||
432 | struct v4l2_window win; | ||
433 | struct v4l2_clip *clips; | ||
434 | unsigned int nclips; | ||
435 | |||
436 | /* video capture */ | ||
437 | struct cx23417_fmt *fmt; | ||
438 | unsigned int width, height; | ||
439 | |||
440 | /* vbi capture */ | ||
441 | struct videobuf_queue vidq; | ||
442 | struct videobuf_queue vbiq; | ||
443 | |||
444 | /* MPEG Encoder specifics ONLY */ | ||
445 | |||
446 | atomic_t v4l_reading; | ||
353 | }; | 447 | }; |
354 | 448 | ||
355 | /*****************************************************************/ | 449 | /*****************************************************************/ |
@@ -403,6 +497,13 @@ struct VENDOR_REQUEST_IN { | |||
403 | u8 *pBuff; | 497 | u8 *pBuff; |
404 | }; | 498 | }; |
405 | 499 | ||
500 | struct cx231xx_tvnorm { | ||
501 | char *name; | ||
502 | v4l2_std_id id; | ||
503 | u32 cxiformat; | ||
504 | u32 cxoformat; | ||
505 | }; | ||
506 | |||
406 | struct cx231xx_ctrl { | 507 | struct cx231xx_ctrl { |
407 | struct v4l2_queryctrl v; | 508 | struct v4l2_queryctrl v; |
408 | u32 off; | 509 | u32 off; |
@@ -424,7 +525,9 @@ enum TRANSFER_TYPE { | |||
424 | struct cx231xx_video_mode { | 525 | struct cx231xx_video_mode { |
425 | /* Isoc control struct */ | 526 | /* Isoc control struct */ |
426 | struct cx231xx_dmaqueue vidq; | 527 | struct cx231xx_dmaqueue vidq; |
427 | struct cx231xx_usb_isoc_ctl isoc_ctl; | 528 | struct cx231xx_isoc_ctl isoc_ctl; |
529 | struct cx231xx_bulk_ctl bulk_ctl; | ||
530 | /* locks */ | ||
428 | spinlock_t slock; | 531 | spinlock_t slock; |
429 | 532 | ||
430 | /* usb transfer */ | 533 | /* usb transfer */ |
@@ -434,6 +537,64 @@ struct cx231xx_video_mode { | |||
434 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | 537 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ |
435 | u16 end_point_addr; | 538 | u16 end_point_addr; |
436 | }; | 539 | }; |
540 | /* | ||
541 | struct cx23885_dmaqueue { | ||
542 | struct list_head active; | ||
543 | struct list_head queued; | ||
544 | struct timer_list timeout; | ||
545 | struct btcx_riscmem stopper; | ||
546 | u32 count; | ||
547 | }; | ||
548 | */ | ||
549 | struct cx231xx_tsport { | ||
550 | struct cx231xx *dev; | ||
551 | |||
552 | int nr; | ||
553 | int sram_chno; | ||
554 | |||
555 | struct videobuf_dvb_frontends frontends; | ||
556 | |||
557 | /* dma queues */ | ||
558 | |||
559 | u32 ts_packet_size; | ||
560 | u32 ts_packet_count; | ||
561 | |||
562 | int width; | ||
563 | int height; | ||
564 | |||
565 | /* locks */ | ||
566 | spinlock_t slock; | ||
567 | |||
568 | /* registers */ | ||
569 | u32 reg_gpcnt; | ||
570 | u32 reg_gpcnt_ctl; | ||
571 | u32 reg_dma_ctl; | ||
572 | u32 reg_lngth; | ||
573 | u32 reg_hw_sop_ctrl; | ||
574 | u32 reg_gen_ctrl; | ||
575 | u32 reg_bd_pkt_status; | ||
576 | u32 reg_sop_status; | ||
577 | u32 reg_fifo_ovfl_stat; | ||
578 | u32 reg_vld_misc; | ||
579 | u32 reg_ts_clk_en; | ||
580 | u32 reg_ts_int_msk; | ||
581 | u32 reg_ts_int_stat; | ||
582 | u32 reg_src_sel; | ||
583 | |||
584 | /* Default register vals */ | ||
585 | int pci_irqmask; | ||
586 | u32 dma_ctl_val; | ||
587 | u32 ts_int_msk_val; | ||
588 | u32 gen_ctrl_val; | ||
589 | u32 ts_clk_en_val; | ||
590 | u32 src_sel_val; | ||
591 | u32 vld_misc_val; | ||
592 | u32 hw_sop_ctrl_val; | ||
593 | |||
594 | /* Allow a single tsport to have multiple frontends */ | ||
595 | u32 num_frontends; | ||
596 | void *port_priv; | ||
597 | }; | ||
437 | 598 | ||
438 | /* main device struct */ | 599 | /* main device struct */ |
439 | struct cx231xx { | 600 | struct cx231xx { |
@@ -457,6 +618,9 @@ struct cx231xx { | |||
457 | 618 | ||
458 | struct cx231xx_IR *ir; | 619 | struct cx231xx_IR *ir; |
459 | 620 | ||
621 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ | ||
622 | atomic_t stream_started; /* stream should be running if true */ | ||
623 | |||
460 | struct list_head devlist; | 624 | struct list_head devlist; |
461 | 625 | ||
462 | int tuner_type; /* type of the tuner */ | 626 | int tuner_type; /* type of the tuner */ |
@@ -465,7 +629,9 @@ struct cx231xx { | |||
465 | /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ | 629 | /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ |
466 | struct cx231xx_i2c i2c_bus[3]; | 630 | struct cx231xx_i2c i2c_bus[3]; |
467 | unsigned int xc_fw_load_done:1; | 631 | unsigned int xc_fw_load_done:1; |
632 | /* locks */ | ||
468 | struct mutex gpio_i2c_lock; | 633 | struct mutex gpio_i2c_lock; |
634 | struct mutex i2c_lock; | ||
469 | 635 | ||
470 | /* video for linux */ | 636 | /* video for linux */ |
471 | int users; /* user count for exclusive use */ | 637 | int users; /* user count for exclusive use */ |
@@ -479,8 +645,6 @@ struct cx231xx { | |||
479 | /* frame properties */ | 645 | /* frame properties */ |
480 | int width; /* current frame width */ | 646 | int width; /* current frame width */ |
481 | int height; /* current frame height */ | 647 | int height; /* current frame height */ |
482 | unsigned hscale; /* horizontal scale factor (see datasheet) */ | ||
483 | unsigned vscale; /* vertical scale factor (see datasheet) */ | ||
484 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ | 648 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ |
485 | 649 | ||
486 | struct cx231xx_audio adev; | 650 | struct cx231xx_audio adev; |
@@ -505,6 +669,8 @@ struct cx231xx { | |||
505 | struct cx231xx_video_mode sliced_cc_mode; | 669 | struct cx231xx_video_mode sliced_cc_mode; |
506 | struct cx231xx_video_mode ts1_mode; | 670 | struct cx231xx_video_mode ts1_mode; |
507 | 671 | ||
672 | atomic_t devlist_count; | ||
673 | |||
508 | struct usb_device *udev; /* the usb device */ | 674 | struct usb_device *udev; /* the usb device */ |
509 | char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ | 675 | char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ |
510 | 676 | ||
@@ -550,8 +716,24 @@ struct cx231xx { | |||
550 | u8 vbi_or_sliced_cc_mode; /* 0 - vbi ; 1 - sliced cc mode */ | 716 | u8 vbi_or_sliced_cc_mode; /* 0 - vbi ; 1 - sliced cc mode */ |
551 | enum cx231xx_std_mode std_mode; /* 0 - Air; 1 - cable */ | 717 | enum cx231xx_std_mode std_mode; /* 0 - Air; 1 - cable */ |
552 | 718 | ||
719 | /*mode: digital=1 or analog=0*/ | ||
720 | u8 mode_tv; | ||
721 | |||
722 | u8 USE_ISO; | ||
723 | struct cx231xx_tvnorm encodernorm; | ||
724 | struct cx231xx_tsport ts1, ts2; | ||
725 | struct cx2341x_mpeg_params mpeg_params; | ||
726 | struct video_device *v4l_device; | ||
727 | atomic_t v4l_reader_count; | ||
728 | u32 freq; | ||
729 | unsigned int input; | ||
730 | u32 cx23417_mailbox; | ||
731 | u32 __iomem *lmmio; | ||
732 | u8 __iomem *bmmio; | ||
553 | }; | 733 | }; |
554 | 734 | ||
735 | extern struct list_head cx231xx_devlist; | ||
736 | |||
555 | #define cx25840_call(cx231xx, o, f, args...) \ | 737 | #define cx25840_call(cx231xx, o, f, args...) \ |
556 | v4l2_subdev_call(cx231xx->sd_cx25840, o, f, ##args) | 738 | v4l2_subdev_call(cx231xx->sd_cx25840, o, f, ##args) |
557 | #define tuner_call(cx231xx, o, f, args...) \ | 739 | #define tuner_call(cx231xx, o, f, args...) \ |
@@ -577,6 +759,10 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus); | |||
577 | int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); | 759 | int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); |
578 | 760 | ||
579 | /* Internal block control functions */ | 761 | /* Internal block control functions */ |
762 | int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, | ||
763 | u8 saddr_len, u32 *data, u8 data_len, int master); | ||
764 | int cx231xx_write_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, | ||
765 | u8 saddr_len, u32 data, u8 data_len, int master); | ||
580 | int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, | 766 | int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, |
581 | u16 saddr, u8 saddr_len, u32 *data, u8 data_len); | 767 | u16 saddr, u8 saddr_len, u32 *data, u8 data_len); |
582 | int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, | 768 | int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, |
@@ -588,6 +774,9 @@ int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr, | |||
588 | u16 saddr, u32 mask, u32 value); | 774 | u16 saddr, u32 mask, u32 value); |
589 | u32 cx231xx_set_field(u32 field_mask, u32 data); | 775 | u32 cx231xx_set_field(u32 field_mask, u32 data); |
590 | 776 | ||
777 | /*verve r/w*/ | ||
778 | void initGPIO(struct cx231xx *dev); | ||
779 | void uninitGPIO(struct cx231xx *dev); | ||
591 | /* afe related functions */ | 780 | /* afe related functions */ |
592 | int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count); | 781 | int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count); |
593 | int cx231xx_afe_init_channels(struct cx231xx *dev); | 782 | int cx231xx_afe_init_channels(struct cx231xx *dev); |
@@ -607,6 +796,19 @@ int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input); | |||
607 | /* DIF related functions */ | 796 | /* DIF related functions */ |
608 | int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode, | 797 | int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode, |
609 | u32 function_mode, u32 standard); | 798 | u32 function_mode, u32 standard); |
799 | void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, | ||
800 | u8 spectral_invert, u32 mode); | ||
801 | u32 cx231xx_Get_Colibri_CarrierOffset(u32 mode, u32 standerd); | ||
802 | void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, | ||
803 | u8 spectral_invert, u32 mode); | ||
804 | void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev); | ||
805 | void reset_s5h1432_demod(struct cx231xx *dev); | ||
806 | void cx231xx_dump_HH_reg(struct cx231xx *dev); | ||
807 | void update_HH_register_after_set_DIF(struct cx231xx *dev); | ||
808 | void cx231xx_dump_SC_reg(struct cx231xx *dev); | ||
809 | |||
810 | |||
811 | |||
610 | int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard); | 812 | int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard); |
611 | int cx231xx_tuner_pre_channel_change(struct cx231xx *dev); | 813 | int cx231xx_tuner_pre_channel_change(struct cx231xx *dev); |
612 | int cx231xx_tuner_post_channel_change(struct cx231xx *dev); | 814 | int cx231xx_tuner_post_channel_change(struct cx231xx *dev); |
@@ -672,15 +874,28 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, | |||
672 | enum AUDIO_INPUT audio_input); | 874 | enum AUDIO_INPUT audio_input); |
673 | 875 | ||
674 | int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type); | 876 | int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type); |
675 | int cx231xx_resolution_set(struct cx231xx *dev); | ||
676 | int cx231xx_set_video_alternate(struct cx231xx *dev); | 877 | int cx231xx_set_video_alternate(struct cx231xx *dev); |
677 | int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt); | 878 | int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt); |
879 | int is_fw_load(struct cx231xx *dev); | ||
880 | int cx231xx_check_fw(struct cx231xx *dev); | ||
678 | int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | 881 | int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, |
679 | int num_bufs, int max_pkt_size, | 882 | int num_bufs, int max_pkt_size, |
680 | int (*isoc_copy) (struct cx231xx *dev, | 883 | int (*isoc_copy) (struct cx231xx *dev, |
681 | struct urb *urb)); | 884 | struct urb *urb)); |
885 | int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, | ||
886 | int num_bufs, int max_pkt_size, | ||
887 | int (*bulk_copy) (struct cx231xx *dev, | ||
888 | struct urb *urb)); | ||
889 | void cx231xx_stop_TS1(struct cx231xx *dev); | ||
890 | void cx231xx_start_TS1(struct cx231xx *dev); | ||
682 | void cx231xx_uninit_isoc(struct cx231xx *dev); | 891 | void cx231xx_uninit_isoc(struct cx231xx *dev); |
892 | void cx231xx_uninit_bulk(struct cx231xx *dev); | ||
683 | int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode); | 893 | int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode); |
894 | int cx231xx_unmute_audio(struct cx231xx *dev); | ||
895 | int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size); | ||
896 | void cx231xx_disable656(struct cx231xx *dev); | ||
897 | void cx231xx_enable656(struct cx231xx *dev); | ||
898 | int cx231xx_demod_reset(struct cx231xx *dev); | ||
684 | int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio); | 899 | int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio); |
685 | 900 | ||
686 | /* Device list functions */ | 901 | /* Device list functions */ |
@@ -712,7 +927,7 @@ int cx231xx_power_suspend(struct cx231xx *dev); | |||
712 | int cx231xx_init_ctrl_pin_status(struct cx231xx *dev); | 927 | int cx231xx_init_ctrl_pin_status(struct cx231xx *dev); |
713 | int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, | 928 | int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, |
714 | u8 analog_or_digital); | 929 | u8 analog_or_digital); |
715 | int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex); | 930 | int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3); |
716 | 931 | ||
717 | /* video audio decoder related functions */ | 932 | /* video audio decoder related functions */ |
718 | void video_mux(struct cx231xx *dev, int index); | 933 | void video_mux(struct cx231xx *dev, int index); |
@@ -733,12 +948,11 @@ extern void cx231xx_card_setup(struct cx231xx *dev); | |||
733 | extern struct cx231xx_board cx231xx_boards[]; | 948 | extern struct cx231xx_board cx231xx_boards[]; |
734 | extern struct usb_device_id cx231xx_id_table[]; | 949 | extern struct usb_device_id cx231xx_id_table[]; |
735 | extern const unsigned int cx231xx_bcount; | 950 | extern const unsigned int cx231xx_bcount; |
736 | void cx231xx_register_i2c_ir(struct cx231xx *dev); | ||
737 | int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); | 951 | int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); |
738 | 952 | ||
739 | /* Provided by cx231xx-input.c */ | 953 | /* cx23885-417.c */ |
740 | int cx231xx_ir_init(struct cx231xx *dev); | 954 | extern int cx231xx_417_register(struct cx231xx *dev); |
741 | int cx231xx_ir_fini(struct cx231xx *dev); | 955 | extern void cx231xx_417_unregister(struct cx231xx *dev); |
742 | 956 | ||
743 | /* printk macros */ | 957 | /* printk macros */ |
744 | 958 | ||
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 53a67824071..a6cc12f8736 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -1591,7 +1591,7 @@ static int mpeg_open(struct file *file) | |||
1591 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1591 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1592 | V4L2_FIELD_INTERLACED, | 1592 | V4L2_FIELD_INTERLACED, |
1593 | sizeof(struct cx23885_buffer), | 1593 | sizeof(struct cx23885_buffer), |
1594 | fh); | 1594 | fh, NULL); |
1595 | unlock_kernel(); | 1595 | unlock_kernel(); |
1596 | 1596 | ||
1597 | return 0; | 1597 | return 0; |
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index e76ce8709af..db054004e46 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -1247,7 +1247,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1247 | case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: | 1247 | case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: |
1248 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1248 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1249 | &dev->i2c_bus[2].i2c_adap, | 1249 | &dev->i2c_bus[2].i2c_adap, |
1250 | "cx25840", "cx25840", 0x88 >> 1, NULL); | 1250 | NULL, "cx25840", 0x88 >> 1, NULL); |
1251 | if (dev->sd_cx25840) { | 1251 | if (dev->sd_cx25840) { |
1252 | dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; | 1252 | dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; |
1253 | v4l2_subdev_call(dev->sd_cx25840, core, load_fw); | 1253 | v4l2_subdev_call(dev->sd_cx25840, core, load_fw); |
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index f6b62e7398a..359882419b7 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -815,6 +815,7 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev) | |||
815 | case 0x0e: | 815 | case 0x0e: |
816 | /* CX23887-15Z */ | 816 | /* CX23887-15Z */ |
817 | dev->hwrevision = 0xc0; | 817 | dev->hwrevision = 0xc0; |
818 | break; | ||
818 | case 0x0f: | 819 | case 0x0f: |
819 | /* CX23887-14Z */ | 820 | /* CX23887-14Z */ |
820 | dev->hwrevision = 0xb1; | 821 | dev->hwrevision = 0xb1; |
@@ -1221,7 +1222,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) | |||
1221 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 1222 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
1222 | 1223 | ||
1223 | BUG_ON(in_interrupt()); | 1224 | BUG_ON(in_interrupt()); |
1224 | videobuf_waiton(&buf->vb, 0, 0); | 1225 | videobuf_waiton(q, &buf->vb, 0, 0); |
1225 | videobuf_dma_unmap(q->dev, dma); | 1226 | videobuf_dma_unmap(q->dev, dma); |
1226 | videobuf_dma_free(dma); | 1227 | videobuf_dma_free(dma); |
1227 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); | 1228 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 3d70af28388..5958cb882e9 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -1017,10 +1017,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1017 | /* Read entire EEPROM */ | 1017 | /* Read entire EEPROM */ |
1018 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; | 1018 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; |
1019 | tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); | 1019 | tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); |
1020 | printk(KERN_INFO "TeVii S470 MAC= " | 1020 | printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0); |
1021 | "%02X:%02X:%02X:%02X:%02X:%02X\n", | ||
1022 | eeprom[0xa0], eeprom[0xa1], eeprom[0xa2], | ||
1023 | eeprom[0xa3], eeprom[0xa4], eeprom[0xa5]); | ||
1024 | memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); | 1021 | memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); |
1025 | break; | 1022 | break; |
1026 | } | 1023 | } |
@@ -1074,7 +1071,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) | |||
1074 | videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, | 1071 | videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, |
1075 | &dev->pci->dev, &port->slock, | 1072 | &dev->pci->dev, &port->slock, |
1076 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, | 1073 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, |
1077 | sizeof(struct cx23885_buffer), port); | 1074 | sizeof(struct cx23885_buffer), port, NULL); |
1078 | } | 1075 | } |
1079 | err = dvb_register(port); | 1076 | err = dvb_register(port); |
1080 | if (err != 0) | 1077 | if (err != 0) |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index da66e5f8d91..93af9c65b48 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -758,7 +758,7 @@ static int video_open(struct file *file) | |||
758 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 758 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
759 | V4L2_FIELD_INTERLACED, | 759 | V4L2_FIELD_INTERLACED, |
760 | sizeof(struct cx23885_buffer), | 760 | sizeof(struct cx23885_buffer), |
761 | fh); | 761 | fh, NULL); |
762 | 762 | ||
763 | dprintk(1, "post videobuf_queue_init()\n"); | 763 | dprintk(1, "post videobuf_queue_init()\n"); |
764 | 764 | ||
@@ -1165,9 +1165,10 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) | |||
1165 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1165 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1166 | strcpy(i->name, iname[INPUT(n)->type]); | 1166 | strcpy(i->name, iname[INPUT(n)->type]); |
1167 | if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || | 1167 | if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || |
1168 | (CX23885_VMUX_CABLE == INPUT(n)->type)) | 1168 | (CX23885_VMUX_CABLE == INPUT(n)->type)) { |
1169 | i->type = V4L2_INPUT_TYPE_TUNER; | 1169 | i->type = V4L2_INPUT_TYPE_TUNER; |
1170 | i->std = CX23885_NORMS; | 1170 | i->std = CX23885_NORMS; |
1171 | } | ||
1171 | return 0; | 1172 | return 0; |
1172 | } | 1173 | } |
1173 | 1174 | ||
@@ -1511,11 +1512,11 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1511 | if (dev->tuner_addr) | 1512 | if (dev->tuner_addr) |
1512 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1513 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1513 | &dev->i2c_bus[1].i2c_adap, | 1514 | &dev->i2c_bus[1].i2c_adap, |
1514 | "tuner", "tuner", dev->tuner_addr, NULL); | 1515 | NULL, "tuner", dev->tuner_addr, NULL); |
1515 | else | 1516 | else |
1516 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1517 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1517 | &dev->i2c_bus[1].i2c_adap, | 1518 | &dev->i2c_bus[1].i2c_adap, NULL, |
1518 | "tuner", "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV)); | 1519 | "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV)); |
1519 | if (sd) { | 1520 | if (sd) { |
1520 | struct tuner_setup tun_setup; | 1521 | struct tuner_setup tun_setup; |
1521 | 1522 | ||
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index 2502a0a6709..e78e3e4c811 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c | |||
@@ -704,6 +704,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, | |||
704 | if (v > IR_MAX_DURATION) | 704 | if (v > IR_MAX_DURATION) |
705 | v = IR_MAX_DURATION; | 705 | v = IR_MAX_DURATION; |
706 | 706 | ||
707 | init_ir_raw_event(&p->ir_core_data); | ||
707 | p->ir_core_data.pulse = u; | 708 | p->ir_core_data.pulse = u; |
708 | p->ir_core_data.duration = v; | 709 | p->ir_core_data.duration = v; |
709 | 710 | ||
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 6faad34df3a..34b96c7cfd6 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -437,41 +437,45 @@ void cx25840_audio_set_path(struct i2c_client *client) | |||
437 | { | 437 | { |
438 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | 438 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); |
439 | 439 | ||
440 | /* assert soft reset */ | 440 | if (!is_cx2583x(state)) { |
441 | cx25840_and_or(client, 0x810, ~0x1, 0x01); | 441 | /* assert soft reset */ |
442 | cx25840_and_or(client, 0x810, ~0x1, 0x01); | ||
442 | 443 | ||
443 | /* stop microcontroller */ | 444 | /* stop microcontroller */ |
444 | cx25840_and_or(client, 0x803, ~0x10, 0); | 445 | cx25840_and_or(client, 0x803, ~0x10, 0); |
445 | 446 | ||
446 | /* Mute everything to prevent the PFFT! */ | 447 | /* Mute everything to prevent the PFFT! */ |
447 | cx25840_write(client, 0x8d3, 0x1f); | 448 | cx25840_write(client, 0x8d3, 0x1f); |
448 | 449 | ||
449 | if (state->aud_input == CX25840_AUDIO_SERIAL) { | 450 | if (state->aud_input == CX25840_AUDIO_SERIAL) { |
450 | /* Set Path1 to Serial Audio Input */ | 451 | /* Set Path1 to Serial Audio Input */ |
451 | cx25840_write4(client, 0x8d0, 0x01011012); | 452 | cx25840_write4(client, 0x8d0, 0x01011012); |
452 | 453 | ||
453 | /* The microcontroller should not be started for the | 454 | /* The microcontroller should not be started for the |
454 | * non-tuner inputs: autodetection is specific for | 455 | * non-tuner inputs: autodetection is specific for |
455 | * TV audio. */ | 456 | * TV audio. */ |
456 | } else { | 457 | } else { |
457 | /* Set Path1 to Analog Demod Main Channel */ | 458 | /* Set Path1 to Analog Demod Main Channel */ |
458 | cx25840_write4(client, 0x8d0, 0x1f063870); | 459 | cx25840_write4(client, 0x8d0, 0x1f063870); |
460 | } | ||
459 | } | 461 | } |
460 | 462 | ||
461 | set_audclk_freq(client, state->audclk_freq); | 463 | set_audclk_freq(client, state->audclk_freq); |
462 | 464 | ||
463 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | 465 | if (!is_cx2583x(state)) { |
464 | /* When the microcontroller detects the | 466 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
465 | * audio format, it will unmute the lines */ | 467 | /* When the microcontroller detects the |
466 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 468 | * audio format, it will unmute the lines */ |
467 | } | 469 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
470 | } | ||
468 | 471 | ||
469 | /* deassert soft reset */ | 472 | /* deassert soft reset */ |
470 | cx25840_and_or(client, 0x810, ~0x1, 0x00); | 473 | cx25840_and_or(client, 0x810, ~0x1, 0x00); |
471 | 474 | ||
472 | /* Ensure the controller is running when we exit */ | 475 | /* Ensure the controller is running when we exit */ |
473 | if (is_cx2388x(state) || is_cx231xx(state)) | 476 | if (is_cx2388x(state) || is_cx231xx(state)) |
474 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 477 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
478 | } | ||
475 | } | 479 | } |
476 | 480 | ||
477 | static void set_volume(struct i2c_client *client, int volume) | 481 | static void set_volume(struct i2c_client *client, int volume) |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index f5a3e74c3c7..dfb198d0415 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/delay.h> | 42 | #include <linux/delay.h> |
43 | #include <media/v4l2-common.h> | 43 | #include <media/v4l2-common.h> |
44 | #include <media/v4l2-chip-ident.h> | 44 | #include <media/v4l2-chip-ident.h> |
45 | #include <media/v4l2-i2c-drv.h> | ||
46 | #include <media/cx25840.h> | 45 | #include <media/cx25840.h> |
47 | 46 | ||
48 | #include "cx25840-core.h" | 47 | #include "cx25840-core.h" |
@@ -871,6 +870,11 @@ static void input_change(struct i2c_client *client) | |||
871 | } | 870 | } |
872 | cx25840_and_or(client, 0x401, ~0x60, 0); | 871 | cx25840_and_or(client, 0x401, ~0x60, 0); |
873 | cx25840_and_or(client, 0x401, ~0x60, 0x60); | 872 | cx25840_and_or(client, 0x401, ~0x60, 0x60); |
873 | |||
874 | /* Don't write into audio registers on cx2583x chips */ | ||
875 | if (is_cx2583x(state)) | ||
876 | return; | ||
877 | |||
874 | cx25840_and_or(client, 0x810, ~0x01, 1); | 878 | cx25840_and_or(client, 0x810, ~0x01, 1); |
875 | 879 | ||
876 | if (state->radio) { | 880 | if (state->radio) { |
@@ -1029,10 +1033,8 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp | |||
1029 | 1033 | ||
1030 | state->vid_input = vid_input; | 1034 | state->vid_input = vid_input; |
1031 | state->aud_input = aud_input; | 1035 | state->aud_input = aud_input; |
1032 | if (!is_cx2583x(state)) { | 1036 | cx25840_audio_set_path(client); |
1033 | cx25840_audio_set_path(client); | 1037 | input_change(client); |
1034 | input_change(client); | ||
1035 | } | ||
1036 | 1038 | ||
1037 | if (is_cx2388x(state)) { | 1039 | if (is_cx2388x(state)) { |
1038 | /* Audio channel 1 src : Parallel 1 */ | 1040 | /* Audio channel 1 src : Parallel 1 */ |
@@ -1553,18 +1555,14 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd, | |||
1553 | struct cx25840_state *state = to_state(sd); | 1555 | struct cx25840_state *state = to_state(sd); |
1554 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1556 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1555 | 1557 | ||
1556 | if (is_cx2583x(state)) | ||
1557 | return -EINVAL; | ||
1558 | return set_input(client, state->vid_input, input); | 1558 | return set_input(client, state->vid_input, input); |
1559 | } | 1559 | } |
1560 | 1560 | ||
1561 | static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) | 1561 | static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) |
1562 | { | 1562 | { |
1563 | struct cx25840_state *state = to_state(sd); | ||
1564 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1563 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1565 | 1564 | ||
1566 | if (!is_cx2583x(state)) | 1565 | input_change(client); |
1567 | input_change(client); | ||
1568 | return 0; | 1566 | return 0; |
1569 | } | 1567 | } |
1570 | 1568 | ||
@@ -2043,9 +2041,25 @@ static const struct i2c_device_id cx25840_id[] = { | |||
2043 | }; | 2041 | }; |
2044 | MODULE_DEVICE_TABLE(i2c, cx25840_id); | 2042 | MODULE_DEVICE_TABLE(i2c, cx25840_id); |
2045 | 2043 | ||
2046 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 2044 | static struct i2c_driver cx25840_driver = { |
2047 | .name = "cx25840", | 2045 | .driver = { |
2048 | .probe = cx25840_probe, | 2046 | .owner = THIS_MODULE, |
2049 | .remove = cx25840_remove, | 2047 | .name = "cx25840", |
2050 | .id_table = cx25840_id, | 2048 | }, |
2049 | .probe = cx25840_probe, | ||
2050 | .remove = cx25840_remove, | ||
2051 | .id_table = cx25840_id, | ||
2051 | }; | 2052 | }; |
2053 | |||
2054 | static __init int init_cx25840(void) | ||
2055 | { | ||
2056 | return i2c_add_driver(&cx25840_driver); | ||
2057 | } | ||
2058 | |||
2059 | static __exit void exit_cx25840(void) | ||
2060 | { | ||
2061 | i2c_del_driver(&cx25840_driver); | ||
2062 | } | ||
2063 | |||
2064 | module_init(init_cx25840); | ||
2065 | module_exit(exit_cx25840); | ||
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c index c2b4c14dc9a..97a4e9b25fe 100644 --- a/drivers/media/video/cx25840/cx25840-ir.c +++ b/drivers/media/video/cx25840/cx25840-ir.c | |||
@@ -706,6 +706,7 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, | |||
706 | if (v > IR_MAX_DURATION) | 706 | if (v > IR_MAX_DURATION) |
707 | v = IR_MAX_DURATION; | 707 | v = IR_MAX_DURATION; |
708 | 708 | ||
709 | init_ir_raw_event(&p->ir_core_data); | ||
709 | p->ir_core_data.pulse = u; | 710 | p->ir_core_data.pulse = u; |
710 | p->ir_core_data.duration = v; | 711 | p->ir_core_data.duration = v; |
711 | 712 | ||
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 4f383cdf529..4aaa47c0eab 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <sound/control.h> | 40 | #include <sound/control.h> |
41 | #include <sound/initval.h> | 41 | #include <sound/initval.h> |
42 | #include <sound/tlv.h> | 42 | #include <sound/tlv.h> |
43 | #include <media/wm8775.h> | ||
43 | 44 | ||
44 | #include "cx88.h" | 45 | #include "cx88.h" |
45 | #include "cx88-reg.h" | 46 | #include "cx88-reg.h" |
@@ -94,7 +95,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t; | |||
94 | ****************************************************************************/ | 95 | ****************************************************************************/ |
95 | 96 | ||
96 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 97 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
97 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 98 | static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
98 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; | 99 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; |
99 | 100 | ||
100 | module_param_array(enable, bool, NULL, 0444); | 101 | module_param_array(enable, bool, NULL, 0444); |
@@ -131,7 +132,7 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip) | |||
131 | { | 132 | { |
132 | struct cx88_audio_buffer *buf = chip->buf; | 133 | struct cx88_audio_buffer *buf = chip->buf; |
133 | struct cx88_core *core=chip->core; | 134 | struct cx88_core *core=chip->core; |
134 | struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25]; | 135 | const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25]; |
135 | 136 | ||
136 | /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ | 137 | /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ |
137 | cx_clear(MO_AUD_DMACNTRL, 0x11); | 138 | cx_clear(MO_AUD_DMACNTRL, 0x11); |
@@ -197,7 +198,7 @@ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip) | |||
197 | /* | 198 | /* |
198 | * BOARD Specific: IRQ dma bits | 199 | * BOARD Specific: IRQ dma bits |
199 | */ | 200 | */ |
200 | static char *cx88_aud_irqs[32] = { | 201 | static const char *cx88_aud_irqs[32] = { |
201 | "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ | 202 | "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ |
202 | NULL, /* reserved */ | 203 | NULL, /* reserved */ |
203 | "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ | 204 | "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ |
@@ -308,7 +309,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) | |||
308 | * Digital hardware definition | 309 | * Digital hardware definition |
309 | */ | 310 | */ |
310 | #define DEFAULT_FIFO_SIZE 4096 | 311 | #define DEFAULT_FIFO_SIZE 4096 |
311 | static struct snd_pcm_hardware snd_cx88_digital_hw = { | 312 | static const struct snd_pcm_hardware snd_cx88_digital_hw = { |
312 | .info = SNDRV_PCM_INFO_MMAP | | 313 | .info = SNDRV_PCM_INFO_MMAP | |
313 | SNDRV_PCM_INFO_INTERLEAVED | | 314 | SNDRV_PCM_INFO_INTERLEAVED | |
314 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 315 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -533,7 +534,7 @@ static struct snd_pcm_ops snd_cx88_pcm_ops = { | |||
533 | /* | 534 | /* |
534 | * create a PCM device | 535 | * create a PCM device |
535 | */ | 536 | */ |
536 | static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) | 537 | static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, const char *name) |
537 | { | 538 | { |
538 | int err; | 539 | int err; |
539 | struct snd_pcm *pcm; | 540 | struct snd_pcm *pcm; |
@@ -586,26 +587,47 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, | |||
586 | int left, right, v, b; | 587 | int left, right, v, b; |
587 | int changed = 0; | 588 | int changed = 0; |
588 | u32 old; | 589 | u32 old; |
590 | struct v4l2_control client_ctl; | ||
591 | |||
592 | /* Pass volume & balance onto any WM8775 */ | ||
593 | if (value->value.integer.value[0] >= value->value.integer.value[1]) { | ||
594 | v = value->value.integer.value[0] << 10; | ||
595 | b = value->value.integer.value[0] ? | ||
596 | (0x8000 * value->value.integer.value[1]) / value->value.integer.value[0] : | ||
597 | 0x8000; | ||
598 | } else { | ||
599 | v = value->value.integer.value[1] << 10; | ||
600 | b = value->value.integer.value[1] ? | ||
601 | 0xffff - (0x8000 * value->value.integer.value[0]) / value->value.integer.value[1] : | ||
602 | 0x8000; | ||
603 | } | ||
604 | client_ctl.value = v; | ||
605 | client_ctl.id = V4L2_CID_AUDIO_VOLUME; | ||
606 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
607 | |||
608 | client_ctl.value = b; | ||
609 | client_ctl.id = V4L2_CID_AUDIO_BALANCE; | ||
610 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
589 | 611 | ||
590 | left = value->value.integer.value[0] & 0x3f; | 612 | left = value->value.integer.value[0] & 0x3f; |
591 | right = value->value.integer.value[1] & 0x3f; | 613 | right = value->value.integer.value[1] & 0x3f; |
592 | b = right - left; | 614 | b = right - left; |
593 | if (b < 0) { | 615 | if (b < 0) { |
594 | v = 0x3f - left; | 616 | v = 0x3f - left; |
595 | b = (-b) | 0x40; | 617 | b = (-b) | 0x40; |
596 | } else { | 618 | } else { |
597 | v = 0x3f - right; | 619 | v = 0x3f - right; |
598 | } | 620 | } |
599 | /* Do we really know this will always be called with IRQs on? */ | 621 | /* Do we really know this will always be called with IRQs on? */ |
600 | spin_lock_irq(&chip->reg_lock); | 622 | spin_lock_irq(&chip->reg_lock); |
601 | old = cx_read(AUD_VOL_CTL); | 623 | old = cx_read(AUD_VOL_CTL); |
602 | if (v != (old & 0x3f)) { | 624 | if (v != (old & 0x3f)) { |
603 | cx_write(AUD_VOL_CTL, (old & ~0x3f) | v); | 625 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v); |
604 | changed = 1; | 626 | changed = 1; |
605 | } | 627 | } |
606 | if (cx_read(AUD_BAL_CTL) != b) { | 628 | if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) { |
607 | cx_write(AUD_BAL_CTL, b); | 629 | cx_write(AUD_BAL_CTL, b); |
608 | changed = 1; | 630 | changed = 1; |
609 | } | 631 | } |
610 | spin_unlock_irq(&chip->reg_lock); | 632 | spin_unlock_irq(&chip->reg_lock); |
611 | 633 | ||
@@ -614,11 +636,11 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, | |||
614 | 636 | ||
615 | static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0); | 637 | static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0); |
616 | 638 | ||
617 | static struct snd_kcontrol_new snd_cx88_volume = { | 639 | static const struct snd_kcontrol_new snd_cx88_volume = { |
618 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 640 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
619 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 641 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
620 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | 642 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, |
621 | .name = "Playback Volume", | 643 | .name = "Analog-TV Volume", |
622 | .info = snd_cx88_volume_info, | 644 | .info = snd_cx88_volume_info, |
623 | .get = snd_cx88_volume_get, | 645 | .get = snd_cx88_volume_get, |
624 | .put = snd_cx88_volume_put, | 646 | .put = snd_cx88_volume_put, |
@@ -649,31 +671,74 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, | |||
649 | vol = cx_read(AUD_VOL_CTL); | 671 | vol = cx_read(AUD_VOL_CTL); |
650 | if (value->value.integer.value[0] != !(vol & bit)) { | 672 | if (value->value.integer.value[0] != !(vol & bit)) { |
651 | vol ^= bit; | 673 | vol ^= bit; |
652 | cx_write(AUD_VOL_CTL, vol); | 674 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); |
675 | /* Pass mute onto any WM8775 */ | ||
676 | if ((1<<6) == bit) { | ||
677 | struct v4l2_control client_ctl; | ||
678 | client_ctl.value = 0 != (vol & bit); | ||
679 | client_ctl.id = V4L2_CID_AUDIO_MUTE; | ||
680 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
681 | } | ||
653 | ret = 1; | 682 | ret = 1; |
654 | } | 683 | } |
655 | spin_unlock_irq(&chip->reg_lock); | 684 | spin_unlock_irq(&chip->reg_lock); |
656 | return ret; | 685 | return ret; |
657 | } | 686 | } |
658 | 687 | ||
659 | static struct snd_kcontrol_new snd_cx88_dac_switch = { | 688 | static const struct snd_kcontrol_new snd_cx88_dac_switch = { |
660 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 689 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
661 | .name = "Playback Switch", | 690 | .name = "Audio-Out Switch", |
662 | .info = snd_ctl_boolean_mono_info, | 691 | .info = snd_ctl_boolean_mono_info, |
663 | .get = snd_cx88_switch_get, | 692 | .get = snd_cx88_switch_get, |
664 | .put = snd_cx88_switch_put, | 693 | .put = snd_cx88_switch_put, |
665 | .private_value = (1<<8), | 694 | .private_value = (1<<8), |
666 | }; | 695 | }; |
667 | 696 | ||
668 | static struct snd_kcontrol_new snd_cx88_source_switch = { | 697 | static const struct snd_kcontrol_new snd_cx88_source_switch = { |
669 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 698 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
670 | .name = "Capture Switch", | 699 | .name = "Analog-TV Switch", |
671 | .info = snd_ctl_boolean_mono_info, | 700 | .info = snd_ctl_boolean_mono_info, |
672 | .get = snd_cx88_switch_get, | 701 | .get = snd_cx88_switch_get, |
673 | .put = snd_cx88_switch_put, | 702 | .put = snd_cx88_switch_put, |
674 | .private_value = (1<<6), | 703 | .private_value = (1<<6), |
675 | }; | 704 | }; |
676 | 705 | ||
706 | static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, | ||
707 | struct snd_ctl_elem_value *value) | ||
708 | { | ||
709 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
710 | struct cx88_core *core = chip->core; | ||
711 | struct v4l2_control client_ctl; | ||
712 | |||
713 | client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; | ||
714 | call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl); | ||
715 | value->value.integer.value[0] = client_ctl.value ? 1 : 0; | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol, | ||
721 | struct snd_ctl_elem_value *value) | ||
722 | { | ||
723 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
724 | struct cx88_core *core = chip->core; | ||
725 | struct v4l2_control client_ctl; | ||
726 | |||
727 | client_ctl.value = 0 != value->value.integer.value[0]; | ||
728 | client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; | ||
729 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static struct snd_kcontrol_new snd_cx88_alc_switch = { | ||
735 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
736 | .name = "Line-In ALC Switch", | ||
737 | .info = snd_ctl_boolean_mono_info, | ||
738 | .get = snd_cx88_alc_get, | ||
739 | .put = snd_cx88_alc_put, | ||
740 | }; | ||
741 | |||
677 | /**************************************************************************** | 742 | /**************************************************************************** |
678 | Basic Flow for Sound Devices | 743 | Basic Flow for Sound Devices |
679 | ****************************************************************************/ | 744 | ****************************************************************************/ |
@@ -683,7 +748,7 @@ static struct snd_kcontrol_new snd_cx88_source_switch = { | |||
683 | * Only boards with eeprom and byte 1 at eeprom=1 have it | 748 | * Only boards with eeprom and byte 1 at eeprom=1 have it |
684 | */ | 749 | */ |
685 | 750 | ||
686 | static struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = { | 751 | static const struct pci_device_id const cx88_audio_pci_tbl[] __devinitdata = { |
687 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | 752 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, |
688 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | 753 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, |
689 | {0, } | 754 | {0, } |
@@ -795,6 +860,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
795 | { | 860 | { |
796 | struct snd_card *card; | 861 | struct snd_card *card; |
797 | snd_cx88_card_t *chip; | 862 | snd_cx88_card_t *chip; |
863 | struct v4l2_subdev *sd; | ||
798 | int err; | 864 | int err; |
799 | 865 | ||
800 | if (devno >= SNDRV_CARDS) | 866 | if (devno >= SNDRV_CARDS) |
@@ -830,6 +896,15 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
830 | if (err < 0) | 896 | if (err < 0) |
831 | goto error; | 897 | goto error; |
832 | 898 | ||
899 | /* If there's a wm8775 then add a Line-In ALC switch */ | ||
900 | list_for_each_entry(sd, &chip->core->v4l2_dev.subdevs, list) { | ||
901 | if (WM8775_GID == sd->grp_id) { | ||
902 | snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, | ||
903 | chip)); | ||
904 | break; | ||
905 | } | ||
906 | } | ||
907 | |||
833 | strcpy (card->driver, "CX88x"); | 908 | strcpy (card->driver, "CX88x"); |
834 | sprintf(card->shortname, "Conexant CX%x", pci->device); | 909 | sprintf(card->shortname, "Conexant CX%x", pci->device); |
835 | sprintf(card->longname, "%s at %#llx", | 910 | sprintf(card->longname, "%s at %#llx", |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 660b2a927fe..417d1d5c73c 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -1057,7 +1057,7 @@ static int mpeg_open(struct file *file) | |||
1057 | 1057 | ||
1058 | dprintk( 1, "%s\n", __func__); | 1058 | dprintk( 1, "%s\n", __func__); |
1059 | 1059 | ||
1060 | lock_kernel(); | 1060 | mutex_lock(&dev->core->lock); |
1061 | 1061 | ||
1062 | /* Make sure we can acquire the hardware */ | 1062 | /* Make sure we can acquire the hardware */ |
1063 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | 1063 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); |
@@ -1065,7 +1065,7 @@ static int mpeg_open(struct file *file) | |||
1065 | err = drv->request_acquire(drv); | 1065 | err = drv->request_acquire(drv); |
1066 | if(err != 0) { | 1066 | if(err != 0) { |
1067 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); | 1067 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); |
1068 | unlock_kernel(); | 1068 | mutex_unlock(&dev->core->lock);; |
1069 | return err; | 1069 | return err; |
1070 | } | 1070 | } |
1071 | } | 1071 | } |
@@ -1073,7 +1073,7 @@ static int mpeg_open(struct file *file) | |||
1073 | if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { | 1073 | if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { |
1074 | if (drv) | 1074 | if (drv) |
1075 | drv->request_release(drv); | 1075 | drv->request_release(drv); |
1076 | unlock_kernel(); | 1076 | mutex_unlock(&dev->core->lock); |
1077 | return -EINVAL; | 1077 | return -EINVAL; |
1078 | } | 1078 | } |
1079 | dprintk(1, "open dev=%s\n", video_device_node_name(vdev)); | 1079 | dprintk(1, "open dev=%s\n", video_device_node_name(vdev)); |
@@ -1083,7 +1083,7 @@ static int mpeg_open(struct file *file) | |||
1083 | if (NULL == fh) { | 1083 | if (NULL == fh) { |
1084 | if (drv) | 1084 | if (drv) |
1085 | drv->request_release(drv); | 1085 | drv->request_release(drv); |
1086 | unlock_kernel(); | 1086 | mutex_unlock(&dev->core->lock); |
1087 | return -ENOMEM; | 1087 | return -ENOMEM; |
1088 | } | 1088 | } |
1089 | file->private_data = fh; | 1089 | file->private_data = fh; |
@@ -1094,15 +1094,14 @@ static int mpeg_open(struct file *file) | |||
1094 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1094 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1095 | V4L2_FIELD_INTERLACED, | 1095 | V4L2_FIELD_INTERLACED, |
1096 | sizeof(struct cx88_buffer), | 1096 | sizeof(struct cx88_buffer), |
1097 | fh); | 1097 | fh, NULL); |
1098 | 1098 | ||
1099 | /* FIXME: locking against other video device */ | 1099 | /* FIXME: locking against other video device */ |
1100 | cx88_set_scale(dev->core, dev->width, dev->height, | 1100 | cx88_set_scale(dev->core, dev->width, dev->height, |
1101 | fh->mpegq.field); | 1101 | fh->mpegq.field); |
1102 | unlock_kernel(); | ||
1103 | 1102 | ||
1104 | atomic_inc(&dev->core->mpeg_users); | 1103 | atomic_inc(&dev->core->mpeg_users); |
1105 | 1104 | mutex_unlock(&dev->core->lock); | |
1106 | return 0; | 1105 | return 0; |
1107 | } | 1106 | } |
1108 | 1107 | ||
@@ -1120,8 +1119,11 @@ static int mpeg_release(struct file *file) | |||
1120 | videobuf_stop(&fh->mpegq); | 1119 | videobuf_stop(&fh->mpegq); |
1121 | 1120 | ||
1122 | videobuf_mmap_free(&fh->mpegq); | 1121 | videobuf_mmap_free(&fh->mpegq); |
1122 | |||
1123 | mutex_lock(&dev->core->lock); | ||
1123 | file->private_data = NULL; | 1124 | file->private_data = NULL; |
1124 | kfree(fh); | 1125 | kfree(fh); |
1126 | mutex_unlock(&dev->core->lock); | ||
1125 | 1127 | ||
1126 | /* Make sure we release the hardware */ | 1128 | /* Make sure we release the hardware */ |
1127 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | 1129 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index e8416b76da6..b26fcba8600 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -970,15 +970,22 @@ static const struct cx88_board cx88_boards[] = { | |||
970 | .radio_type = UNSET, | 970 | .radio_type = UNSET, |
971 | .tuner_addr = ADDR_UNSET, | 971 | .tuner_addr = ADDR_UNSET, |
972 | .radio_addr = ADDR_UNSET, | 972 | .radio_addr = ADDR_UNSET, |
973 | .audio_chip = V4L2_IDENT_WM8775, | ||
973 | .input = {{ | 974 | .input = {{ |
974 | .type = CX88_VMUX_DVB, | 975 | .type = CX88_VMUX_DVB, |
975 | .vmux = 0, | 976 | .vmux = 0, |
977 | /* 2: Line-In */ | ||
978 | .audioroute = 2, | ||
976 | },{ | 979 | },{ |
977 | .type = CX88_VMUX_COMPOSITE1, | 980 | .type = CX88_VMUX_COMPOSITE1, |
978 | .vmux = 1, | 981 | .vmux = 1, |
982 | /* 2: Line-In */ | ||
983 | .audioroute = 2, | ||
979 | },{ | 984 | },{ |
980 | .type = CX88_VMUX_SVIDEO, | 985 | .type = CX88_VMUX_SVIDEO, |
981 | .vmux = 2, | 986 | .vmux = 2, |
987 | /* 2: Line-In */ | ||
988 | .audioroute = 2, | ||
982 | }}, | 989 | }}, |
983 | .mpeg = CX88_MPEG_DVB, | 990 | .mpeg = CX88_MPEG_DVB, |
984 | }, | 991 | }, |
@@ -2104,6 +2111,18 @@ static const struct cx88_board cx88_boards[] = { | |||
2104 | } }, | 2111 | } }, |
2105 | .mpeg = CX88_MPEG_DVB, | 2112 | .mpeg = CX88_MPEG_DVB, |
2106 | }, | 2113 | }, |
2114 | [CX88_BOARD_TWINHAN_VP1027_DVBS] = { | ||
2115 | .name = "Twinhan VP-1027 DVB-S", | ||
2116 | .tuner_type = TUNER_ABSENT, | ||
2117 | .radio_type = UNSET, | ||
2118 | .tuner_addr = ADDR_UNSET, | ||
2119 | .radio_addr = ADDR_UNSET, | ||
2120 | .input = {{ | ||
2121 | .type = CX88_VMUX_DVB, | ||
2122 | .vmux = 0, | ||
2123 | } }, | ||
2124 | .mpeg = CX88_MPEG_DVB, | ||
2125 | }, | ||
2107 | }; | 2126 | }; |
2108 | 2127 | ||
2109 | /* ------------------------------------------------------------------ */ | 2128 | /* ------------------------------------------------------------------ */ |
@@ -2576,6 +2595,10 @@ static const struct cx88_subid cx88_subids[] = { | |||
2576 | .subvendor = 0xb034, | 2595 | .subvendor = 0xb034, |
2577 | .subdevice = 0x3034, | 2596 | .subdevice = 0x3034, |
2578 | .card = CX88_BOARD_PROF_7301, | 2597 | .card = CX88_BOARD_PROF_7301, |
2598 | }, { | ||
2599 | .subvendor = 0x1822, | ||
2600 | .subdevice = 0x0023, | ||
2601 | .card = CX88_BOARD_TWINHAN_VP1027_DVBS, | ||
2579 | }, | 2602 | }, |
2580 | }; | 2603 | }; |
2581 | 2604 | ||
@@ -2673,10 +2696,10 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
2673 | /* ----------------------------------------------------------------------- */ | 2696 | /* ----------------------------------------------------------------------- */ |
2674 | /* some GDI (was: Modular Technology) specific stuff */ | 2697 | /* some GDI (was: Modular Technology) specific stuff */ |
2675 | 2698 | ||
2676 | static struct { | 2699 | static const struct { |
2677 | int id; | 2700 | int id; |
2678 | int fm; | 2701 | int fm; |
2679 | char *name; | 2702 | const char *name; |
2680 | } gdi_tuner[] = { | 2703 | } gdi_tuner[] = { |
2681 | [ 0x01 ] = { .id = TUNER_ABSENT, | 2704 | [ 0x01 ] = { .id = TUNER_ABSENT, |
2682 | .name = "NTSC_M" }, | 2705 | .name = "NTSC_M" }, |
@@ -2710,7 +2733,7 @@ static struct { | |||
2710 | 2733 | ||
2711 | static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) | 2734 | static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) |
2712 | { | 2735 | { |
2713 | char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner)) | 2736 | const char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner)) |
2714 | ? gdi_tuner[eeprom_data[0x0d]].name : NULL; | 2737 | ? gdi_tuner[eeprom_data[0x0d]].name : NULL; |
2715 | 2738 | ||
2716 | info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown"); | 2739 | info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown"); |
@@ -3070,6 +3093,13 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) | |||
3070 | cx_set(MO_GP1_IO, 0x10); | 3093 | cx_set(MO_GP1_IO, 0x10); |
3071 | mdelay(50); | 3094 | mdelay(50); |
3072 | break; | 3095 | break; |
3096 | |||
3097 | case CX88_BOARD_TWINHAN_VP1027_DVBS: | ||
3098 | cx_write(MO_GP0_IO, 0x00003230); | ||
3099 | cx_write(MO_GP0_IO, 0x00003210); | ||
3100 | msleep(1); | ||
3101 | cx_write(MO_GP0_IO, 0x00001230); | ||
3102 | break; | ||
3073 | } | 3103 | } |
3074 | } | 3104 | } |
3075 | 3105 | ||
@@ -3485,19 +3515,19 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) | |||
3485 | later code configures a tea5767. | 3515 | later code configures a tea5767. |
3486 | */ | 3516 | */ |
3487 | v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, | 3517 | v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, |
3488 | "tuner", "tuner", | 3518 | NULL, "tuner", |
3489 | 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); | 3519 | 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); |
3490 | if (has_demod) | 3520 | if (has_demod) |
3491 | v4l2_i2c_new_subdev(&core->v4l2_dev, | 3521 | v4l2_i2c_new_subdev(&core->v4l2_dev, |
3492 | &core->i2c_adap, "tuner", "tuner", | 3522 | &core->i2c_adap, NULL, "tuner", |
3493 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | 3523 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); |
3494 | if (core->board.tuner_addr == ADDR_UNSET) { | 3524 | if (core->board.tuner_addr == ADDR_UNSET) { |
3495 | v4l2_i2c_new_subdev(&core->v4l2_dev, | 3525 | v4l2_i2c_new_subdev(&core->v4l2_dev, |
3496 | &core->i2c_adap, "tuner", "tuner", | 3526 | &core->i2c_adap, NULL, "tuner", |
3497 | 0, has_demod ? tv_addrs + 4 : tv_addrs); | 3527 | 0, has_demod ? tv_addrs + 4 : tv_addrs); |
3498 | } else { | 3528 | } else { |
3499 | v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, | 3529 | v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, |
3500 | "tuner", "tuner", core->board.tuner_addr, NULL); | 3530 | NULL, "tuner", core->board.tuner_addr, NULL); |
3501 | } | 3531 | } |
3502 | } | 3532 | } |
3503 | 3533 | ||
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 85eb266fb35..2e145f0a5fd 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -217,7 +217,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
217 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 217 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
218 | 218 | ||
219 | BUG_ON(in_interrupt()); | 219 | BUG_ON(in_interrupt()); |
220 | videobuf_waiton(&buf->vb,0,0); | 220 | videobuf_waiton(q, &buf->vb, 0, 0); |
221 | videobuf_dma_unmap(q->dev, dma); | 221 | videobuf_dma_unmap(q->dev, dma); |
222 | videobuf_dma_free(dma); | 222 | videobuf_dma_free(dma); |
223 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); | 223 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); |
@@ -253,7 +253,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
253 | * 0x0c00 - FIFOs | 253 | * 0x0c00 - FIFOs |
254 | */ | 254 | */ |
255 | 255 | ||
256 | struct sram_channel cx88_sram_channels[] = { | 256 | const struct sram_channel const cx88_sram_channels[] = { |
257 | [SRAM_CH21] = { | 257 | [SRAM_CH21] = { |
258 | .name = "video y / packed", | 258 | .name = "video y / packed", |
259 | .cmds_start = 0x180040, | 259 | .cmds_start = 0x180040, |
@@ -353,7 +353,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
353 | }; | 353 | }; |
354 | 354 | ||
355 | int cx88_sram_channel_setup(struct cx88_core *core, | 355 | int cx88_sram_channel_setup(struct cx88_core *core, |
356 | struct sram_channel *ch, | 356 | const struct sram_channel *ch, |
357 | unsigned int bpl, u32 risc) | 357 | unsigned int bpl, u32 risc) |
358 | { | 358 | { |
359 | unsigned int i,lines; | 359 | unsigned int i,lines; |
@@ -394,7 +394,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, | |||
394 | 394 | ||
395 | static int cx88_risc_decode(u32 risc) | 395 | static int cx88_risc_decode(u32 risc) |
396 | { | 396 | { |
397 | static char *instr[16] = { | 397 | static const char * const instr[16] = { |
398 | [ RISC_SYNC >> 28 ] = "sync", | 398 | [ RISC_SYNC >> 28 ] = "sync", |
399 | [ RISC_WRITE >> 28 ] = "write", | 399 | [ RISC_WRITE >> 28 ] = "write", |
400 | [ RISC_WRITEC >> 28 ] = "writec", | 400 | [ RISC_WRITEC >> 28 ] = "writec", |
@@ -406,14 +406,14 @@ static int cx88_risc_decode(u32 risc) | |||
406 | [ RISC_WRITECM >> 28 ] = "writecm", | 406 | [ RISC_WRITECM >> 28 ] = "writecm", |
407 | [ RISC_WRITECR >> 28 ] = "writecr", | 407 | [ RISC_WRITECR >> 28 ] = "writecr", |
408 | }; | 408 | }; |
409 | static int incr[16] = { | 409 | static int const incr[16] = { |
410 | [ RISC_WRITE >> 28 ] = 2, | 410 | [ RISC_WRITE >> 28 ] = 2, |
411 | [ RISC_JUMP >> 28 ] = 2, | 411 | [ RISC_JUMP >> 28 ] = 2, |
412 | [ RISC_WRITERM >> 28 ] = 3, | 412 | [ RISC_WRITERM >> 28 ] = 3, |
413 | [ RISC_WRITECM >> 28 ] = 3, | 413 | [ RISC_WRITECM >> 28 ] = 3, |
414 | [ RISC_WRITECR >> 28 ] = 4, | 414 | [ RISC_WRITECR >> 28 ] = 4, |
415 | }; | 415 | }; |
416 | static char *bits[] = { | 416 | static const char * const bits[] = { |
417 | "12", "13", "14", "resync", | 417 | "12", "13", "14", "resync", |
418 | "cnt0", "cnt1", "18", "19", | 418 | "cnt0", "cnt1", "18", "19", |
419 | "20", "21", "22", "23", | 419 | "20", "21", "22", "23", |
@@ -432,9 +432,9 @@ static int cx88_risc_decode(u32 risc) | |||
432 | 432 | ||
433 | 433 | ||
434 | void cx88_sram_channel_dump(struct cx88_core *core, | 434 | void cx88_sram_channel_dump(struct cx88_core *core, |
435 | struct sram_channel *ch) | 435 | const struct sram_channel *ch) |
436 | { | 436 | { |
437 | static char *name[] = { | 437 | static const char * const name[] = { |
438 | "initial risc", | 438 | "initial risc", |
439 | "cdt base", | 439 | "cdt base", |
440 | "cdt size", | 440 | "cdt size", |
@@ -489,14 +489,14 @@ void cx88_sram_channel_dump(struct cx88_core *core, | |||
489 | core->name,cx_read(ch->cnt2_reg)); | 489 | core->name,cx_read(ch->cnt2_reg)); |
490 | } | 490 | } |
491 | 491 | ||
492 | static char *cx88_pci_irqs[32] = { | 492 | static const char *cx88_pci_irqs[32] = { |
493 | "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", | 493 | "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", |
494 | "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", | 494 | "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", |
495 | "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", | 495 | "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", |
496 | "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1" | 496 | "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1" |
497 | }; | 497 | }; |
498 | 498 | ||
499 | void cx88_print_irqbits(char *name, char *tag, char **strings, | 499 | void cx88_print_irqbits(const char *name, const char *tag, const char *strings[], |
500 | int len, u32 bits, u32 mask) | 500 | int len, u32 bits, u32 mask) |
501 | { | 501 | { |
502 | unsigned int i; | 502 | unsigned int i; |
@@ -770,7 +770,7 @@ static const u32 xtal = 28636363; | |||
770 | 770 | ||
771 | static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) | 771 | static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) |
772 | { | 772 | { |
773 | static u32 pre[] = { 0, 0, 0, 3, 2, 1 }; | 773 | static const u32 pre[] = { 0, 0, 0, 3, 2, 1 }; |
774 | u64 pll; | 774 | u64 pll; |
775 | u32 reg; | 775 | u32 reg; |
776 | int i; | 776 | int i; |
@@ -879,7 +879,7 @@ static int set_tvaudio(struct cx88_core *core) | |||
879 | } else { | 879 | } else { |
880 | printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n", | 880 | printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n", |
881 | core->name, v4l2_norm_to_name(core->tvnorm)); | 881 | core->name, v4l2_norm_to_name(core->tvnorm)); |
882 | core->tvaudio = 0; | 882 | core->tvaudio = WW_NONE; |
883 | return 0; | 883 | return 0; |
884 | } | 884 | } |
885 | 885 | ||
@@ -1020,15 +1020,15 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) | |||
1020 | 1020 | ||
1021 | struct video_device *cx88_vdev_init(struct cx88_core *core, | 1021 | struct video_device *cx88_vdev_init(struct cx88_core *core, |
1022 | struct pci_dev *pci, | 1022 | struct pci_dev *pci, |
1023 | struct video_device *template, | 1023 | const struct video_device *template_, |
1024 | char *type) | 1024 | const char *type) |
1025 | { | 1025 | { |
1026 | struct video_device *vfd; | 1026 | struct video_device *vfd; |
1027 | 1027 | ||
1028 | vfd = video_device_alloc(); | 1028 | vfd = video_device_alloc(); |
1029 | if (NULL == vfd) | 1029 | if (NULL == vfd) |
1030 | return NULL; | 1030 | return NULL; |
1031 | *vfd = *template; | 1031 | *vfd = *template_; |
1032 | vfd->v4l2_dev = &core->v4l2_dev; | 1032 | vfd->v4l2_dev = &core->v4l2_dev; |
1033 | vfd->parent = &pci->dev; | 1033 | vfd->parent = &pci->dev; |
1034 | vfd->release = video_device_release; | 1034 | vfd->release = video_device_release; |
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c index a94e00a4ac5..a9907265ff6 100644 --- a/drivers/media/video/cx88/cx88-dsp.c +++ b/drivers/media/video/cx88/cx88-dsp.c | |||
@@ -230,7 +230,7 @@ static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N) | |||
230 | 230 | ||
231 | static s16 *read_rds_samples(struct cx88_core *core, u32 *N) | 231 | static s16 *read_rds_samples(struct cx88_core *core, u32 *N) |
232 | { | 232 | { |
233 | struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27]; | 233 | const struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27]; |
234 | s16 *samples; | 234 | s16 *samples; |
235 | 235 | ||
236 | unsigned int i; | 236 | unsigned int i; |
@@ -292,11 +292,20 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core) | |||
292 | switch (core->tvaudio) { | 292 | switch (core->tvaudio) { |
293 | case WW_BG: | 293 | case WW_BG: |
294 | case WW_DK: | 294 | case WW_DK: |
295 | case WW_EIAJ: | ||
296 | case WW_M: | ||
295 | ret = detect_a2_a2m_eiaj(core, samples, N); | 297 | ret = detect_a2_a2m_eiaj(core, samples, N); |
296 | break; | 298 | break; |
297 | case WW_BTSC: | 299 | case WW_BTSC: |
298 | ret = detect_btsc(core, samples, N); | 300 | ret = detect_btsc(core, samples, N); |
299 | break; | 301 | break; |
302 | case WW_NONE: | ||
303 | case WW_I: | ||
304 | case WW_L: | ||
305 | case WW_I2SPT: | ||
306 | case WW_FM: | ||
307 | case WW_I2SADC: | ||
308 | break; | ||
300 | } | 309 | } |
301 | 310 | ||
302 | kfree(samples); | 311 | kfree(samples); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index faa8e8163a4..367a653f4c9 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include "stv0900.h" | 56 | #include "stv0900.h" |
57 | #include "stb6100.h" | 57 | #include "stb6100.h" |
58 | #include "stb6100_proc.h" | 58 | #include "stb6100_proc.h" |
59 | #include "mb86a16.h" | ||
59 | 60 | ||
60 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 61 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
61 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 62 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
@@ -105,7 +106,7 @@ static void dvb_buf_release(struct videobuf_queue *q, | |||
105 | cx88_free_buffer(q, (struct cx88_buffer*)vb); | 106 | cx88_free_buffer(q, (struct cx88_buffer*)vb); |
106 | } | 107 | } |
107 | 108 | ||
108 | static struct videobuf_queue_ops dvb_qops = { | 109 | static const struct videobuf_queue_ops dvb_qops = { |
109 | .buf_setup = dvb_buf_setup, | 110 | .buf_setup = dvb_buf_setup, |
110 | .buf_prepare = dvb_buf_prepare, | 111 | .buf_prepare = dvb_buf_prepare, |
111 | .buf_queue = dvb_buf_queue, | 112 | .buf_queue = dvb_buf_queue, |
@@ -167,12 +168,12 @@ static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) | |||
167 | 168 | ||
168 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | 169 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) |
169 | { | 170 | { |
170 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; | 171 | static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; |
171 | static u8 reset [] = { RESET, 0x80 }; | 172 | static const u8 reset [] = { RESET, 0x80 }; |
172 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | 173 | static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; |
173 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; | 174 | static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; |
174 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | 175 | static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; |
175 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | 176 | static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; |
176 | 177 | ||
177 | mt352_write(fe, clock_config, sizeof(clock_config)); | 178 | mt352_write(fe, clock_config, sizeof(clock_config)); |
178 | udelay(200); | 179 | udelay(200); |
@@ -187,12 +188,12 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | |||
187 | 188 | ||
188 | static int dvico_dual_demod_init(struct dvb_frontend *fe) | 189 | static int dvico_dual_demod_init(struct dvb_frontend *fe) |
189 | { | 190 | { |
190 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | 191 | static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; |
191 | static u8 reset [] = { RESET, 0x80 }; | 192 | static const u8 reset [] = { RESET, 0x80 }; |
192 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | 193 | static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; |
193 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | 194 | static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; |
194 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | 195 | static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; |
195 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | 196 | static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; |
196 | 197 | ||
197 | mt352_write(fe, clock_config, sizeof(clock_config)); | 198 | mt352_write(fe, clock_config, sizeof(clock_config)); |
198 | udelay(200); | 199 | udelay(200); |
@@ -208,13 +209,13 @@ static int dvico_dual_demod_init(struct dvb_frontend *fe) | |||
208 | 209 | ||
209 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | 210 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) |
210 | { | 211 | { |
211 | static u8 clock_config [] = { 0x89, 0x38, 0x39 }; | 212 | static const u8 clock_config [] = { 0x89, 0x38, 0x39 }; |
212 | static u8 reset [] = { 0x50, 0x80 }; | 213 | static const u8 reset [] = { 0x50, 0x80 }; |
213 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | 214 | static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; |
214 | static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, | 215 | static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, |
215 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | 216 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; |
216 | static u8 dntv_extra[] = { 0xB5, 0x7A }; | 217 | static const u8 dntv_extra[] = { 0xB5, 0x7A }; |
217 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | 218 | static const u8 capt_range_cfg[] = { 0x75, 0x32 }; |
218 | 219 | ||
219 | mt352_write(fe, clock_config, sizeof(clock_config)); | 220 | mt352_write(fe, clock_config, sizeof(clock_config)); |
220 | udelay(2000); | 221 | udelay(2000); |
@@ -229,37 +230,41 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | |||
229 | return 0; | 230 | return 0; |
230 | } | 231 | } |
231 | 232 | ||
232 | static struct mt352_config dvico_fusionhdtv = { | 233 | static const struct mt352_config dvico_fusionhdtv = { |
233 | .demod_address = 0x0f, | 234 | .demod_address = 0x0f, |
234 | .demod_init = dvico_fusionhdtv_demod_init, | 235 | .demod_init = dvico_fusionhdtv_demod_init, |
235 | }; | 236 | }; |
236 | 237 | ||
237 | static struct mt352_config dntv_live_dvbt_config = { | 238 | static const struct mt352_config dntv_live_dvbt_config = { |
238 | .demod_address = 0x0f, | 239 | .demod_address = 0x0f, |
239 | .demod_init = dntv_live_dvbt_demod_init, | 240 | .demod_init = dntv_live_dvbt_demod_init, |
240 | }; | 241 | }; |
241 | 242 | ||
242 | static struct mt352_config dvico_fusionhdtv_dual = { | 243 | static const struct mt352_config dvico_fusionhdtv_dual = { |
243 | .demod_address = 0x0f, | 244 | .demod_address = 0x0f, |
244 | .demod_init = dvico_dual_demod_init, | 245 | .demod_init = dvico_dual_demod_init, |
245 | }; | 246 | }; |
246 | 247 | ||
247 | static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = { | 248 | static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = { |
248 | .demod_address = (0x1e >> 1), | 249 | .demod_address = (0x1e >> 1), |
249 | .no_tuner = 1, | 250 | .no_tuner = 1, |
250 | .if2 = 45600, | 251 | .if2 = 45600, |
251 | }; | 252 | }; |
252 | 253 | ||
254 | static struct mb86a16_config twinhan_vp1027 = { | ||
255 | .demod_address = 0x08, | ||
256 | }; | ||
257 | |||
253 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) | 258 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
254 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) | 259 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) |
255 | { | 260 | { |
256 | static u8 clock_config [] = { 0x89, 0x38, 0x38 }; | 261 | static const u8 clock_config [] = { 0x89, 0x38, 0x38 }; |
257 | static u8 reset [] = { 0x50, 0x80 }; | 262 | static const u8 reset [] = { 0x50, 0x80 }; |
258 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | 263 | static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; |
259 | static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, | 264 | static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, |
260 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | 265 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; |
261 | static u8 dntv_extra[] = { 0xB5, 0x7A }; | 266 | static const u8 dntv_extra[] = { 0xB5, 0x7A }; |
262 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | 267 | static const u8 capt_range_cfg[] = { 0x75, 0x32 }; |
263 | 268 | ||
264 | mt352_write(fe, clock_config, sizeof(clock_config)); | 269 | mt352_write(fe, clock_config, sizeof(clock_config)); |
265 | udelay(2000); | 270 | udelay(2000); |
@@ -274,41 +279,41 @@ static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) | |||
274 | return 0; | 279 | return 0; |
275 | } | 280 | } |
276 | 281 | ||
277 | static struct mt352_config dntv_live_dvbt_pro_config = { | 282 | static const struct mt352_config dntv_live_dvbt_pro_config = { |
278 | .demod_address = 0x0f, | 283 | .demod_address = 0x0f, |
279 | .no_tuner = 1, | 284 | .no_tuner = 1, |
280 | .demod_init = dntv_live_dvbt_pro_demod_init, | 285 | .demod_init = dntv_live_dvbt_pro_demod_init, |
281 | }; | 286 | }; |
282 | #endif | 287 | #endif |
283 | 288 | ||
284 | static struct zl10353_config dvico_fusionhdtv_hybrid = { | 289 | static const struct zl10353_config dvico_fusionhdtv_hybrid = { |
285 | .demod_address = 0x0f, | 290 | .demod_address = 0x0f, |
286 | .no_tuner = 1, | 291 | .no_tuner = 1, |
287 | }; | 292 | }; |
288 | 293 | ||
289 | static struct zl10353_config dvico_fusionhdtv_xc3028 = { | 294 | static const struct zl10353_config dvico_fusionhdtv_xc3028 = { |
290 | .demod_address = 0x0f, | 295 | .demod_address = 0x0f, |
291 | .if2 = 45600, | 296 | .if2 = 45600, |
292 | .no_tuner = 1, | 297 | .no_tuner = 1, |
293 | }; | 298 | }; |
294 | 299 | ||
295 | static struct mt352_config dvico_fusionhdtv_mt352_xc3028 = { | 300 | static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = { |
296 | .demod_address = 0x0f, | 301 | .demod_address = 0x0f, |
297 | .if2 = 4560, | 302 | .if2 = 4560, |
298 | .no_tuner = 1, | 303 | .no_tuner = 1, |
299 | .demod_init = dvico_fusionhdtv_demod_init, | 304 | .demod_init = dvico_fusionhdtv_demod_init, |
300 | }; | 305 | }; |
301 | 306 | ||
302 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { | 307 | static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { |
303 | .demod_address = 0x0f, | 308 | .demod_address = 0x0f, |
304 | }; | 309 | }; |
305 | 310 | ||
306 | static struct cx22702_config connexant_refboard_config = { | 311 | static const struct cx22702_config connexant_refboard_config = { |
307 | .demod_address = 0x43, | 312 | .demod_address = 0x43, |
308 | .output_mode = CX22702_SERIAL_OUTPUT, | 313 | .output_mode = CX22702_SERIAL_OUTPUT, |
309 | }; | 314 | }; |
310 | 315 | ||
311 | static struct cx22702_config hauppauge_hvr_config = { | 316 | static const struct cx22702_config hauppauge_hvr_config = { |
312 | .demod_address = 0x63, | 317 | .demod_address = 0x63, |
313 | .output_mode = CX22702_SERIAL_OUTPUT, | 318 | .output_mode = CX22702_SERIAL_OUTPUT, |
314 | }; | 319 | }; |
@@ -320,7 +325,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) | |||
320 | return 0; | 325 | return 0; |
321 | } | 326 | } |
322 | 327 | ||
323 | static struct or51132_config pchdtv_hd3000 = { | 328 | static const struct or51132_config pchdtv_hd3000 = { |
324 | .demod_address = 0x15, | 329 | .demod_address = 0x15, |
325 | .set_ts_params = or51132_set_ts_param, | 330 | .set_ts_params = or51132_set_ts_param, |
326 | }; | 331 | }; |
@@ -355,14 +360,14 @@ static struct lgdt330x_config fusionhdtv_3_gold = { | |||
355 | .set_ts_params = lgdt330x_set_ts_param, | 360 | .set_ts_params = lgdt330x_set_ts_param, |
356 | }; | 361 | }; |
357 | 362 | ||
358 | static struct lgdt330x_config fusionhdtv_5_gold = { | 363 | static const struct lgdt330x_config fusionhdtv_5_gold = { |
359 | .demod_address = 0x0e, | 364 | .demod_address = 0x0e, |
360 | .demod_chip = LGDT3303, | 365 | .demod_chip = LGDT3303, |
361 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | 366 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ |
362 | .set_ts_params = lgdt330x_set_ts_param, | 367 | .set_ts_params = lgdt330x_set_ts_param, |
363 | }; | 368 | }; |
364 | 369 | ||
365 | static struct lgdt330x_config pchdtv_hd5500 = { | 370 | static const struct lgdt330x_config pchdtv_hd5500 = { |
366 | .demod_address = 0x59, | 371 | .demod_address = 0x59, |
367 | .demod_chip = LGDT3303, | 372 | .demod_chip = LGDT3303, |
368 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | 373 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ |
@@ -376,7 +381,7 @@ static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) | |||
376 | return 0; | 381 | return 0; |
377 | } | 382 | } |
378 | 383 | ||
379 | static struct nxt200x_config ati_hdtvwonder = { | 384 | static const struct nxt200x_config ati_hdtvwonder = { |
380 | .demod_address = 0x0a, | 385 | .demod_address = 0x0a, |
381 | .set_ts_params = nxt200x_set_ts_param, | 386 | .set_ts_params = nxt200x_set_ts_param, |
382 | }; | 387 | }; |
@@ -429,15 +434,15 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, | |||
429 | 434 | ||
430 | cx_set(MO_GP0_IO, 0x6040); | 435 | cx_set(MO_GP0_IO, 0x6040); |
431 | switch (voltage) { | 436 | switch (voltage) { |
432 | case SEC_VOLTAGE_13: | 437 | case SEC_VOLTAGE_13: |
433 | cx_clear(MO_GP0_IO, 0x20); | 438 | cx_clear(MO_GP0_IO, 0x20); |
434 | break; | 439 | break; |
435 | case SEC_VOLTAGE_18: | 440 | case SEC_VOLTAGE_18: |
436 | cx_set(MO_GP0_IO, 0x20); | 441 | cx_set(MO_GP0_IO, 0x20); |
437 | break; | 442 | break; |
438 | case SEC_VOLTAGE_OFF: | 443 | case SEC_VOLTAGE_OFF: |
439 | cx_clear(MO_GP0_IO, 0x20); | 444 | cx_clear(MO_GP0_IO, 0x20); |
440 | break; | 445 | break; |
441 | } | 446 | } |
442 | 447 | ||
443 | if (core->prev_set_voltage) | 448 | if (core->prev_set_voltage) |
@@ -445,23 +450,49 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, | |||
445 | return 0; | 450 | return 0; |
446 | } | 451 | } |
447 | 452 | ||
448 | static struct cx24123_config geniatech_dvbs_config = { | 453 | static int vp1027_set_voltage(struct dvb_frontend *fe, |
454 | fe_sec_voltage_t voltage) | ||
455 | { | ||
456 | struct cx8802_dev *dev = fe->dvb->priv; | ||
457 | struct cx88_core *core = dev->core; | ||
458 | |||
459 | switch (voltage) { | ||
460 | case SEC_VOLTAGE_13: | ||
461 | dprintk(1, "LNB SEC Voltage=13\n"); | ||
462 | cx_write(MO_GP0_IO, 0x00001220); | ||
463 | break; | ||
464 | case SEC_VOLTAGE_18: | ||
465 | dprintk(1, "LNB SEC Voltage=18\n"); | ||
466 | cx_write(MO_GP0_IO, 0x00001222); | ||
467 | break; | ||
468 | case SEC_VOLTAGE_OFF: | ||
469 | dprintk(1, "LNB Voltage OFF\n"); | ||
470 | cx_write(MO_GP0_IO, 0x00001230); | ||
471 | break; | ||
472 | } | ||
473 | |||
474 | if (core->prev_set_voltage) | ||
475 | return core->prev_set_voltage(fe, voltage); | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static const struct cx24123_config geniatech_dvbs_config = { | ||
449 | .demod_address = 0x55, | 480 | .demod_address = 0x55, |
450 | .set_ts_params = cx24123_set_ts_param, | 481 | .set_ts_params = cx24123_set_ts_param, |
451 | }; | 482 | }; |
452 | 483 | ||
453 | static struct cx24123_config hauppauge_novas_config = { | 484 | static const struct cx24123_config hauppauge_novas_config = { |
454 | .demod_address = 0x55, | 485 | .demod_address = 0x55, |
455 | .set_ts_params = cx24123_set_ts_param, | 486 | .set_ts_params = cx24123_set_ts_param, |
456 | }; | 487 | }; |
457 | 488 | ||
458 | static struct cx24123_config kworld_dvbs_100_config = { | 489 | static const struct cx24123_config kworld_dvbs_100_config = { |
459 | .demod_address = 0x15, | 490 | .demod_address = 0x15, |
460 | .set_ts_params = cx24123_set_ts_param, | 491 | .set_ts_params = cx24123_set_ts_param, |
461 | .lnb_polarity = 1, | 492 | .lnb_polarity = 1, |
462 | }; | 493 | }; |
463 | 494 | ||
464 | static struct s5h1409_config pinnacle_pctv_hd_800i_config = { | 495 | static const struct s5h1409_config pinnacle_pctv_hd_800i_config = { |
465 | .demod_address = 0x32 >> 1, | 496 | .demod_address = 0x32 >> 1, |
466 | .output_mode = S5H1409_PARALLEL_OUTPUT, | 497 | .output_mode = S5H1409_PARALLEL_OUTPUT, |
467 | .gpio = S5H1409_GPIO_ON, | 498 | .gpio = S5H1409_GPIO_ON, |
@@ -471,7 +502,7 @@ static struct s5h1409_config pinnacle_pctv_hd_800i_config = { | |||
471 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, | 502 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, |
472 | }; | 503 | }; |
473 | 504 | ||
474 | static struct s5h1409_config dvico_hdtv5_pci_nano_config = { | 505 | static const struct s5h1409_config dvico_hdtv5_pci_nano_config = { |
475 | .demod_address = 0x32 >> 1, | 506 | .demod_address = 0x32 >> 1, |
476 | .output_mode = S5H1409_SERIAL_OUTPUT, | 507 | .output_mode = S5H1409_SERIAL_OUTPUT, |
477 | .gpio = S5H1409_GPIO_OFF, | 508 | .gpio = S5H1409_GPIO_OFF, |
@@ -480,7 +511,7 @@ static struct s5h1409_config dvico_hdtv5_pci_nano_config = { | |||
480 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 511 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
481 | }; | 512 | }; |
482 | 513 | ||
483 | static struct s5h1409_config kworld_atsc_120_config = { | 514 | static const struct s5h1409_config kworld_atsc_120_config = { |
484 | .demod_address = 0x32 >> 1, | 515 | .demod_address = 0x32 >> 1, |
485 | .output_mode = S5H1409_SERIAL_OUTPUT, | 516 | .output_mode = S5H1409_SERIAL_OUTPUT, |
486 | .gpio = S5H1409_GPIO_OFF, | 517 | .gpio = S5H1409_GPIO_OFF, |
@@ -489,24 +520,24 @@ static struct s5h1409_config kworld_atsc_120_config = { | |||
489 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 520 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
490 | }; | 521 | }; |
491 | 522 | ||
492 | static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { | 523 | static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { |
493 | .i2c_address = 0x64, | 524 | .i2c_address = 0x64, |
494 | .if_khz = 5380, | 525 | .if_khz = 5380, |
495 | }; | 526 | }; |
496 | 527 | ||
497 | static struct zl10353_config cx88_pinnacle_hybrid_pctv = { | 528 | static const struct zl10353_config cx88_pinnacle_hybrid_pctv = { |
498 | .demod_address = (0x1e >> 1), | 529 | .demod_address = (0x1e >> 1), |
499 | .no_tuner = 1, | 530 | .no_tuner = 1, |
500 | .if2 = 45600, | 531 | .if2 = 45600, |
501 | }; | 532 | }; |
502 | 533 | ||
503 | static struct zl10353_config cx88_geniatech_x8000_mt = { | 534 | static const struct zl10353_config cx88_geniatech_x8000_mt = { |
504 | .demod_address = (0x1e >> 1), | 535 | .demod_address = (0x1e >> 1), |
505 | .no_tuner = 1, | 536 | .no_tuner = 1, |
506 | .disable_i2c_gate_ctrl = 1, | 537 | .disable_i2c_gate_ctrl = 1, |
507 | }; | 538 | }; |
508 | 539 | ||
509 | static struct s5h1411_config dvico_fusionhdtv7_config = { | 540 | static const struct s5h1411_config dvico_fusionhdtv7_config = { |
510 | .output_mode = S5H1411_SERIAL_OUTPUT, | 541 | .output_mode = S5H1411_SERIAL_OUTPUT, |
511 | .gpio = S5H1411_GPIO_ON, | 542 | .gpio = S5H1411_GPIO_ON, |
512 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 543 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
@@ -516,7 +547,7 @@ static struct s5h1411_config dvico_fusionhdtv7_config = { | |||
516 | .status_mode = S5H1411_DEMODLOCKING | 547 | .status_mode = S5H1411_DEMODLOCKING |
517 | }; | 548 | }; |
518 | 549 | ||
519 | static struct xc5000_config dvico_fusionhdtv7_tuner_config = { | 550 | static const struct xc5000_config dvico_fusionhdtv7_tuner_config = { |
520 | .i2c_address = 0xc2 >> 1, | 551 | .i2c_address = 0xc2 >> 1, |
521 | .if_khz = 5380, | 552 | .if_khz = 5380, |
522 | }; | 553 | }; |
@@ -601,19 +632,19 @@ static int cx24116_reset_device(struct dvb_frontend *fe) | |||
601 | return 0; | 632 | return 0; |
602 | } | 633 | } |
603 | 634 | ||
604 | static struct cx24116_config hauppauge_hvr4000_config = { | 635 | static const struct cx24116_config hauppauge_hvr4000_config = { |
605 | .demod_address = 0x05, | 636 | .demod_address = 0x05, |
606 | .set_ts_params = cx24116_set_ts_param, | 637 | .set_ts_params = cx24116_set_ts_param, |
607 | .reset_device = cx24116_reset_device, | 638 | .reset_device = cx24116_reset_device, |
608 | }; | 639 | }; |
609 | 640 | ||
610 | static struct cx24116_config tevii_s460_config = { | 641 | static const struct cx24116_config tevii_s460_config = { |
611 | .demod_address = 0x55, | 642 | .demod_address = 0x55, |
612 | .set_ts_params = cx24116_set_ts_param, | 643 | .set_ts_params = cx24116_set_ts_param, |
613 | .reset_device = cx24116_reset_device, | 644 | .reset_device = cx24116_reset_device, |
614 | }; | 645 | }; |
615 | 646 | ||
616 | static struct stv0900_config prof_7301_stv0900_config = { | 647 | static const struct stv0900_config prof_7301_stv0900_config = { |
617 | .demod_address = 0x6a, | 648 | .demod_address = 0x6a, |
618 | /* demod_mode = 0,*/ | 649 | /* demod_mode = 0,*/ |
619 | .xtal = 27000000, | 650 | .xtal = 27000000, |
@@ -625,12 +656,12 @@ static struct stv0900_config prof_7301_stv0900_config = { | |||
625 | .set_ts_params = stv0900_set_ts_param, | 656 | .set_ts_params = stv0900_set_ts_param, |
626 | }; | 657 | }; |
627 | 658 | ||
628 | static struct stb6100_config prof_7301_stb6100_config = { | 659 | static const struct stb6100_config prof_7301_stb6100_config = { |
629 | .tuner_address = 0x60, | 660 | .tuner_address = 0x60, |
630 | .refclock = 27000000, | 661 | .refclock = 27000000, |
631 | }; | 662 | }; |
632 | 663 | ||
633 | static struct stv0299_config tevii_tuner_sharp_config = { | 664 | static const struct stv0299_config tevii_tuner_sharp_config = { |
634 | .demod_address = 0x68, | 665 | .demod_address = 0x68, |
635 | .inittab = sharp_z0194a_inittab, | 666 | .inittab = sharp_z0194a_inittab, |
636 | .mclk = 88000000UL, | 667 | .mclk = 88000000UL, |
@@ -643,7 +674,7 @@ static struct stv0299_config tevii_tuner_sharp_config = { | |||
643 | .set_ts_params = cx24116_set_ts_param, | 674 | .set_ts_params = cx24116_set_ts_param, |
644 | }; | 675 | }; |
645 | 676 | ||
646 | static struct stv0288_config tevii_tuner_earda_config = { | 677 | static const struct stv0288_config tevii_tuner_earda_config = { |
647 | .demod_address = 0x68, | 678 | .demod_address = 0x68, |
648 | .min_delay_ms = 100, | 679 | .min_delay_ms = 100, |
649 | .set_ts_params = cx24116_set_ts_param, | 680 | .set_ts_params = cx24116_set_ts_param, |
@@ -676,7 +707,7 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev) | |||
676 | 707 | ||
677 | 708 | ||
678 | 709 | ||
679 | static u8 samsung_smt_7020_inittab[] = { | 710 | static const u8 samsung_smt_7020_inittab[] = { |
680 | 0x01, 0x15, | 711 | 0x01, 0x15, |
681 | 0x02, 0x00, | 712 | 0x02, 0x00, |
682 | 0x03, 0x00, | 713 | 0x03, 0x00, |
@@ -850,7 +881,7 @@ static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe, | |||
850 | } | 881 | } |
851 | 882 | ||
852 | 883 | ||
853 | static struct stv0299_config samsung_stv0299_config = { | 884 | static const struct stv0299_config samsung_stv0299_config = { |
854 | .demod_address = 0x68, | 885 | .demod_address = 0x68, |
855 | .inittab = samsung_smt_7020_inittab, | 886 | .inittab = samsung_smt_7020_inittab, |
856 | .mclk = 88000000UL, | 887 | .mclk = 88000000UL, |
@@ -1416,6 +1447,18 @@ static int dvb_register(struct cx8802_dev *dev) | |||
1416 | } | 1447 | } |
1417 | 1448 | ||
1418 | break; | 1449 | break; |
1450 | case CX88_BOARD_TWINHAN_VP1027_DVBS: | ||
1451 | dev->ts_gen_cntrl = 0x00; | ||
1452 | fe0->dvb.frontend = dvb_attach(mb86a16_attach, | ||
1453 | &twinhan_vp1027, | ||
1454 | &core->i2c_adap); | ||
1455 | if (fe0->dvb.frontend) { | ||
1456 | core->prev_set_voltage = | ||
1457 | fe0->dvb.frontend->ops.set_voltage; | ||
1458 | fe0->dvb.frontend->ops.set_voltage = | ||
1459 | vp1027_set_voltage; | ||
1460 | } | ||
1461 | break; | ||
1419 | 1462 | ||
1420 | default: | 1463 | default: |
1421 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", | 1464 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", |
@@ -1576,7 +1619,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) | |||
1576 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1619 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1577 | V4L2_FIELD_TOP, | 1620 | V4L2_FIELD_TOP, |
1578 | sizeof(struct cx88_buffer), | 1621 | sizeof(struct cx88_buffer), |
1579 | dev); | 1622 | dev, NULL); |
1580 | /* init struct videobuf_dvb */ | 1623 | /* init struct videobuf_dvb */ |
1581 | fe->dvb.name = dev->core->name; | 1624 | fe->dvb.name = dev->core->name; |
1582 | } | 1625 | } |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 82db555b22d..f53836bb6a5 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -108,7 +108,7 @@ static const struct i2c_algo_bit_data cx8800_i2c_algo_template = { | |||
108 | 108 | ||
109 | /* ----------------------------------------------------------------------- */ | 109 | /* ----------------------------------------------------------------------- */ |
110 | 110 | ||
111 | static char *i2c_devs[128] = { | 111 | static const char * const i2c_devs[128] = { |
112 | [ 0x1c >> 1 ] = "lgdt330x", | 112 | [ 0x1c >> 1 ] = "lgdt330x", |
113 | [ 0x86 >> 1 ] = "tda9887/cx22702", | 113 | [ 0x86 >> 1 ] = "tda9887/cx22702", |
114 | [ 0xa0 >> 1 ] = "eeprom", | 114 | [ 0xa0 >> 1 ] = "eeprom", |
@@ -117,7 +117,7 @@ static char *i2c_devs[128] = { | |||
117 | [ 0xc8 >> 1 ] = "xc5000", | 117 | [ 0xc8 >> 1 ] = "xc5000", |
118 | }; | 118 | }; |
119 | 119 | ||
120 | static void do_i2c_scan(char *name, struct i2c_client *c) | 120 | static void do_i2c_scan(const char *name, struct i2c_client *c) |
121 | { | 121 | { |
122 | unsigned char buf; | 122 | unsigned char buf; |
123 | int i,rc; | 123 | int i,rc; |
@@ -183,30 +183,3 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
183 | 183 | ||
184 | return core->i2c_rc; | 184 | return core->i2c_rc; |
185 | } | 185 | } |
186 | |||
187 | void cx88_i2c_init_ir(struct cx88_core *core) | ||
188 | { | ||
189 | /* Instantiate the IR receiver device, if present */ | ||
190 | if (0 == core->i2c_rc) { | ||
191 | struct i2c_board_info info; | ||
192 | const unsigned short addr_list[] = { | ||
193 | 0x18, 0x6b, 0x71, | ||
194 | I2C_CLIENT_END | ||
195 | }; | ||
196 | |||
197 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
198 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
199 | /* Use quick read command for probe, some IR chips don't | ||
200 | * support writes */ | ||
201 | i2c_new_probed_device(&core->i2c_adap, &info, addr_list, | ||
202 | i2c_probe_func_quick_read); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /* ----------------------------------------------------------------------- */ | ||
207 | |||
208 | /* | ||
209 | * Local variables: | ||
210 | * c-basic-offset: 8 | ||
211 | * End: | ||
212 | */ | ||
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index eccc5e49a35..fc777bc6e71 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -405,6 +405,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
405 | ir->mask_keycode = 0x7e; | 405 | ir->mask_keycode = 0x7e; |
406 | ir->polling = 100; /* ms */ | 406 | ir->polling = 100; /* ms */ |
407 | break; | 407 | break; |
408 | case CX88_BOARD_TWINHAN_VP1027_DVBS: | ||
409 | ir_codes = RC_MAP_TWINHAN_VP1027_DVBS; | ||
410 | ir_type = IR_TYPE_NEC; | ||
411 | ir->sampling = 0xff00; /* address */ | ||
412 | break; | ||
408 | } | 413 | } |
409 | 414 | ||
410 | if (NULL == ir_codes) { | 415 | if (NULL == ir_codes) { |
@@ -530,6 +535,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
530 | case CX88_BOARD_PROF_7300: | 535 | case CX88_BOARD_PROF_7300: |
531 | case CX88_BOARD_PROF_7301: | 536 | case CX88_BOARD_PROF_7301: |
532 | case CX88_BOARD_PROF_6200: | 537 | case CX88_BOARD_PROF_6200: |
538 | case CX88_BOARD_TWINHAN_VP1027_DVBS: | ||
533 | ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); | 539 | ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); |
534 | 540 | ||
535 | if (ircode == 0xffffffff) { /* decoding error */ | 541 | if (ircode == 0xffffffff) { /* decoding error */ |
@@ -609,13 +615,54 @@ void cx88_ir_irq(struct cx88_core *core) | |||
609 | return; | 615 | return; |
610 | } | 616 | } |
611 | 617 | ||
618 | |||
619 | void cx88_i2c_init_ir(struct cx88_core *core) | ||
620 | { | ||
621 | struct i2c_board_info info; | ||
622 | const unsigned short addr_list[] = { | ||
623 | 0x18, 0x6b, 0x71, | ||
624 | I2C_CLIENT_END | ||
625 | }; | ||
626 | const unsigned short *addrp; | ||
627 | /* Instantiate the IR receiver device, if present */ | ||
628 | if (0 != core->i2c_rc) | ||
629 | return; | ||
630 | |||
631 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
632 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
633 | |||
634 | /* | ||
635 | * We can't call i2c_new_probed_device() because it uses | ||
636 | * quick writes for probing and at least some RC receiver | ||
637 | * devices only reply to reads. | ||
638 | * Also, Hauppauge XVR needs to be specified, as address 0x71 | ||
639 | * conflicts with another remote type used with saa7134 | ||
640 | */ | ||
641 | for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) { | ||
642 | info.platform_data = NULL; | ||
643 | memset(&core->init_data, 0, sizeof(core->init_data)); | ||
644 | |||
645 | if (*addrp == 0x71) { | ||
646 | /* Hauppauge XVR */ | ||
647 | core->init_data.name = "cx88 Hauppauge XVR remote"; | ||
648 | core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; | ||
649 | core->init_data.type = IR_TYPE_RC5; | ||
650 | core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; | ||
651 | |||
652 | info.platform_data = &core->init_data; | ||
653 | } | ||
654 | if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0, | ||
655 | I2C_SMBUS_READ, 0, | ||
656 | I2C_SMBUS_QUICK, NULL) >= 0) { | ||
657 | info.addr = *addrp; | ||
658 | i2c_new_device(&core->i2c_adap, &info); | ||
659 | break; | ||
660 | } | ||
661 | } | ||
662 | } | ||
663 | |||
612 | /* ---------------------------------------------------------------------- */ | 664 | /* ---------------------------------------------------------------------- */ |
613 | 665 | ||
614 | MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe"); | 666 | MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe"); |
615 | MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls"); | 667 | MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls"); |
616 | MODULE_LICENSE("GPL"); | 668 | MODULE_LICENSE("GPL"); |
617 | /* | ||
618 | * Local variables: | ||
619 | * c-basic-offset: 8 | ||
620 | * End: | ||
621 | */ | ||
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 499f8d512ad..f7d71acbb07 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -313,7 +313,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) | |||
313 | 313 | ||
314 | /* ----------------------------------------------------------- */ | 314 | /* ----------------------------------------------------------- */ |
315 | 315 | ||
316 | static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) | 316 | static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart) |
317 | { | 317 | { |
318 | struct cx88_dmaqueue *q = &dev->mpegq; | 318 | struct cx88_dmaqueue *q = &dev->mpegq; |
319 | struct cx88_buffer *buf; | 319 | struct cx88_buffer *buf; |
@@ -358,7 +358,7 @@ static void cx8802_timeout(unsigned long data) | |||
358 | do_cancel_buffers(dev,"timeout",1); | 358 | do_cancel_buffers(dev,"timeout",1); |
359 | } | 359 | } |
360 | 360 | ||
361 | static char *cx88_mpeg_irqs[32] = { | 361 | static const char * cx88_mpeg_irqs[32] = { |
362 | "ts_risci1", NULL, NULL, NULL, | 362 | "ts_risci1", NULL, NULL, NULL, |
363 | "ts_risci2", NULL, NULL, NULL, | 363 | "ts_risci2", NULL, NULL, NULL, |
364 | "ts_oflow", NULL, NULL, NULL, | 364 | "ts_oflow", NULL, NULL, NULL, |
@@ -849,7 +849,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) | |||
849 | kfree(dev); | 849 | kfree(dev); |
850 | } | 850 | } |
851 | 851 | ||
852 | static struct pci_device_id cx8802_pci_tbl[] = { | 852 | static const struct pci_device_id cx8802_pci_tbl[] = { |
853 | { | 853 | { |
854 | .vendor = 0x14f1, | 854 | .vendor = 0x14f1, |
855 | .device = 0x8802, | 855 | .device = 0x8802, |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 239631568f3..08220de3d74 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -70,7 +70,7 @@ MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, " | |||
70 | 70 | ||
71 | /* ----------------------------------------------------------- */ | 71 | /* ----------------------------------------------------------- */ |
72 | 72 | ||
73 | static char *aud_ctl_names[64] = { | 73 | static const char * const aud_ctl_names[64] = { |
74 | [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO", | 74 | [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO", |
75 | [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO", | 75 | [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO", |
76 | [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP", | 76 | [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP", |
@@ -360,7 +360,15 @@ static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode) | |||
360 | set_audio_registers(core, nicam_bgdki_common); | 360 | set_audio_registers(core, nicam_bgdki_common); |
361 | set_audio_registers(core, nicam_i); | 361 | set_audio_registers(core, nicam_i); |
362 | break; | 362 | break; |
363 | default: | 363 | case WW_NONE: |
364 | case WW_BTSC: | ||
365 | case WW_BG: | ||
366 | case WW_DK: | ||
367 | case WW_EIAJ: | ||
368 | case WW_I2SPT: | ||
369 | case WW_FM: | ||
370 | case WW_I2SADC: | ||
371 | case WW_M: | ||
364 | dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __func__); | 372 | dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __func__); |
365 | set_audio_registers(core, nicam_bgdki_common); | 373 | set_audio_registers(core, nicam_bgdki_common); |
366 | set_audio_registers(core, nicam_default); | 374 | set_audio_registers(core, nicam_default); |
@@ -621,7 +629,13 @@ static void set_audio_standard_A2(struct cx88_core *core, u32 mode) | |||
621 | dprintk("%s AM-L (status: devel)\n", __func__); | 629 | dprintk("%s AM-L (status: devel)\n", __func__); |
622 | set_audio_registers(core, am_l); | 630 | set_audio_registers(core, am_l); |
623 | break; | 631 | break; |
624 | default: | 632 | case WW_NONE: |
633 | case WW_BTSC: | ||
634 | case WW_EIAJ: | ||
635 | case WW_I2SPT: | ||
636 | case WW_FM: | ||
637 | case WW_I2SADC: | ||
638 | case WW_M: | ||
625 | dprintk("%s Warning: wrong value\n", __func__); | 639 | dprintk("%s Warning: wrong value\n", __func__); |
626 | return; | 640 | return; |
627 | break; | 641 | break; |
@@ -779,7 +793,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
779 | set_audio_finish(core, EN_I2SIN_ENABLE); | 793 | set_audio_finish(core, EN_I2SIN_ENABLE); |
780 | break; | 794 | break; |
781 | case WW_NONE: | 795 | case WW_NONE: |
782 | default: | 796 | case WW_I2SPT: |
783 | printk("%s/0: unknown tv audio mode [%d]\n", | 797 | printk("%s/0: unknown tv audio mode [%d]\n", |
784 | core->name, core->tvaudio); | 798 | core->name, core->tvaudio); |
785 | break; | 799 | break; |
@@ -795,8 +809,8 @@ void cx88_newstation(struct cx88_core *core) | |||
795 | 809 | ||
796 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | 810 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) |
797 | { | 811 | { |
798 | static char *m[] = { "stereo", "dual mono", "mono", "sap" }; | 812 | static const char * const m[] = { "stereo", "dual mono", "mono", "sap" }; |
799 | static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" }; | 813 | static const char * const p[] = { "no pilot", "pilot c1", "pilot c2", "?" }; |
800 | u32 reg, mode, pilot; | 814 | u32 reg, mode, pilot; |
801 | 815 | ||
802 | reg = cx_read(AUD_STATUS); | 816 | reg = cx_read(AUD_STATUS); |
@@ -840,7 +854,12 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
840 | break; | 854 | break; |
841 | } | 855 | } |
842 | break; | 856 | break; |
843 | default: | 857 | case WW_NONE: |
858 | case WW_I: | ||
859 | case WW_L: | ||
860 | case WW_I2SPT: | ||
861 | case WW_FM: | ||
862 | case WW_I2SADC: | ||
844 | /* nothing */ | 863 | /* nothing */ |
845 | break; | 864 | break; |
846 | } | 865 | } |
@@ -945,6 +964,9 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
945 | } | 964 | } |
946 | break; | 965 | break; |
947 | case WW_I2SADC: | 966 | case WW_I2SADC: |
967 | case WW_NONE: | ||
968 | case WW_EIAJ: | ||
969 | case WW_I2SPT: | ||
948 | /* DO NOTHING */ | 970 | /* DO NOTHING */ |
949 | break; | 971 | break; |
950 | } | 972 | } |
@@ -1000,7 +1022,12 @@ int cx88_audio_thread(void *data) | |||
1000 | /* automatically switch to best available mode */ | 1022 | /* automatically switch to best available mode */ |
1001 | cx88_set_stereo(core, mode, 0); | 1023 | cx88_set_stereo(core, mode, 0); |
1002 | break; | 1024 | break; |
1003 | default: | 1025 | case WW_NONE: |
1026 | case WW_BTSC: | ||
1027 | case WW_EIAJ: | ||
1028 | case WW_I2SPT: | ||
1029 | case WW_FM: | ||
1030 | case WW_I2SADC: | ||
1004 | hw_autodetect: | 1031 | hw_autodetect: |
1005 | /* stereo autodetection is supported by hardware so | 1032 | /* stereo autodetection is supported by hardware so |
1006 | we don't need to do it manually. Do nothing. */ | 1033 | we don't need to do it manually. Do nothing. */ |
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index d9445b0e7ab..f8f8389c036 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c | |||
@@ -230,7 +230,7 @@ static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
230 | cx88_free_buffer(q,buf); | 230 | cx88_free_buffer(q,buf); |
231 | } | 231 | } |
232 | 232 | ||
233 | struct videobuf_queue_ops cx8800_vbi_qops = { | 233 | const struct videobuf_queue_ops cx8800_vbi_qops = { |
234 | .buf_setup = vbi_setup, | 234 | .buf_setup = vbi_setup, |
235 | .buf_prepare = vbi_prepare, | 235 | .buf_prepare = vbi_prepare, |
236 | .buf_queue = vbi_queue, | 236 | .buf_queue = vbi_queue, |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 0fab65c3ab3..d2f159daa8b 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "cx88.h" | 41 | #include "cx88.h" |
42 | #include <media/v4l2-common.h> | 42 | #include <media/v4l2-common.h> |
43 | #include <media/v4l2-ioctl.h> | 43 | #include <media/v4l2-ioctl.h> |
44 | #include <media/wm8775.h> | ||
44 | 45 | ||
45 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); | 46 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); |
46 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 47 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
@@ -78,7 +79,7 @@ MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | |||
78 | /* ------------------------------------------------------------------- */ | 79 | /* ------------------------------------------------------------------- */ |
79 | /* static data */ | 80 | /* static data */ |
80 | 81 | ||
81 | static struct cx8800_fmt formats[] = { | 82 | static const struct cx8800_fmt formats[] = { |
82 | { | 83 | { |
83 | .name = "8 bpp, gray", | 84 | .name = "8 bpp, gray", |
84 | .fourcc = V4L2_PIX_FMT_GREY, | 85 | .fourcc = V4L2_PIX_FMT_GREY, |
@@ -142,7 +143,7 @@ static struct cx8800_fmt formats[] = { | |||
142 | }, | 143 | }, |
143 | }; | 144 | }; |
144 | 145 | ||
145 | static struct cx8800_fmt* format_by_fourcc(unsigned int fourcc) | 146 | static const struct cx8800_fmt* format_by_fourcc(unsigned int fourcc) |
146 | { | 147 | { |
147 | unsigned int i; | 148 | unsigned int i; |
148 | 149 | ||
@@ -159,7 +160,7 @@ static const struct v4l2_queryctrl no_ctl = { | |||
159 | .flags = V4L2_CTRL_FLAG_DISABLED, | 160 | .flags = V4L2_CTRL_FLAG_DISABLED, |
160 | }; | 161 | }; |
161 | 162 | ||
162 | static struct cx88_ctrl cx8800_ctls[] = { | 163 | static const struct cx88_ctrl cx8800_ctls[] = { |
163 | /* --- video --- */ | 164 | /* --- video --- */ |
164 | { | 165 | { |
165 | .v = { | 166 | .v = { |
@@ -288,7 +289,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
288 | .shift = 0, | 289 | .shift = 0, |
289 | } | 290 | } |
290 | }; | 291 | }; |
291 | static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); | 292 | enum { CX8800_CTLS = ARRAY_SIZE(cx8800_ctls) }; |
292 | 293 | ||
293 | /* Must be sorted from low to high control ID! */ | 294 | /* Must be sorted from low to high control ID! */ |
294 | const u32 cx88_user_ctrls[] = { | 295 | const u32 cx88_user_ctrls[] = { |
@@ -306,7 +307,7 @@ const u32 cx88_user_ctrls[] = { | |||
306 | }; | 307 | }; |
307 | EXPORT_SYMBOL(cx88_user_ctrls); | 308 | EXPORT_SYMBOL(cx88_user_ctrls); |
308 | 309 | ||
309 | static const u32 *ctrl_classes[] = { | 310 | static const u32 * const ctrl_classes[] = { |
310 | cx88_user_ctrls, | 311 | cx88_user_ctrls, |
311 | NULL | 312 | NULL |
312 | }; | 313 | }; |
@@ -710,7 +711,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
710 | cx88_free_buffer(q,buf); | 711 | cx88_free_buffer(q,buf); |
711 | } | 712 | } |
712 | 713 | ||
713 | static struct videobuf_queue_ops cx8800_video_qops = { | 714 | static const struct videobuf_queue_ops cx8800_video_qops = { |
714 | .buf_setup = buffer_setup, | 715 | .buf_setup = buffer_setup, |
715 | .buf_prepare = buffer_prepare, | 716 | .buf_prepare = buffer_prepare, |
716 | .buf_queue = buffer_queue, | 717 | .buf_queue = buffer_queue, |
@@ -752,7 +753,7 @@ static int video_open(struct file *file) | |||
752 | { | 753 | { |
753 | struct video_device *vdev = video_devdata(file); | 754 | struct video_device *vdev = video_devdata(file); |
754 | struct cx8800_dev *dev = video_drvdata(file); | 755 | struct cx8800_dev *dev = video_drvdata(file); |
755 | struct cx88_core *core; | 756 | struct cx88_core *core = dev->core; |
756 | struct cx8800_fh *fh; | 757 | struct cx8800_fh *fh; |
757 | enum v4l2_buf_type type = 0; | 758 | enum v4l2_buf_type type = 0; |
758 | int radio = 0; | 759 | int radio = 0; |
@@ -769,19 +770,14 @@ static int video_open(struct file *file) | |||
769 | break; | 770 | break; |
770 | } | 771 | } |
771 | 772 | ||
772 | lock_kernel(); | ||
773 | |||
774 | core = dev->core; | ||
775 | |||
776 | dprintk(1, "open dev=%s radio=%d type=%s\n", | 773 | dprintk(1, "open dev=%s radio=%d type=%s\n", |
777 | video_device_node_name(vdev), radio, v4l2_type_names[type]); | 774 | video_device_node_name(vdev), radio, v4l2_type_names[type]); |
778 | 775 | ||
779 | /* allocate + initialize per filehandle data */ | 776 | /* allocate + initialize per filehandle data */ |
780 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | 777 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); |
781 | if (NULL == fh) { | 778 | if (unlikely(!fh)) |
782 | unlock_kernel(); | ||
783 | return -ENOMEM; | 779 | return -ENOMEM; |
784 | } | 780 | |
785 | file->private_data = fh; | 781 | file->private_data = fh; |
786 | fh->dev = dev; | 782 | fh->dev = dev; |
787 | fh->radio = radio; | 783 | fh->radio = radio; |
@@ -790,18 +786,20 @@ static int video_open(struct file *file) | |||
790 | fh->height = 240; | 786 | fh->height = 240; |
791 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); | 787 | fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); |
792 | 788 | ||
789 | mutex_lock(&core->lock); | ||
790 | |||
793 | videobuf_queue_sg_init(&fh->vidq, &cx8800_video_qops, | 791 | videobuf_queue_sg_init(&fh->vidq, &cx8800_video_qops, |
794 | &dev->pci->dev, &dev->slock, | 792 | &dev->pci->dev, &dev->slock, |
795 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 793 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
796 | V4L2_FIELD_INTERLACED, | 794 | V4L2_FIELD_INTERLACED, |
797 | sizeof(struct cx88_buffer), | 795 | sizeof(struct cx88_buffer), |
798 | fh); | 796 | fh, NULL); |
799 | videobuf_queue_sg_init(&fh->vbiq, &cx8800_vbi_qops, | 797 | videobuf_queue_sg_init(&fh->vbiq, &cx8800_vbi_qops, |
800 | &dev->pci->dev, &dev->slock, | 798 | &dev->pci->dev, &dev->slock, |
801 | V4L2_BUF_TYPE_VBI_CAPTURE, | 799 | V4L2_BUF_TYPE_VBI_CAPTURE, |
802 | V4L2_FIELD_SEQ_TB, | 800 | V4L2_FIELD_SEQ_TB, |
803 | sizeof(struct cx88_buffer), | 801 | sizeof(struct cx88_buffer), |
804 | fh); | 802 | fh, NULL); |
805 | 803 | ||
806 | if (fh->radio) { | 804 | if (fh->radio) { |
807 | dprintk(1,"video_open: setting radio device\n"); | 805 | dprintk(1,"video_open: setting radio device\n"); |
@@ -826,9 +824,9 @@ static int video_open(struct file *file) | |||
826 | } | 824 | } |
827 | call_all(core, tuner, s_radio); | 825 | call_all(core, tuner, s_radio); |
828 | } | 826 | } |
829 | unlock_kernel(); | ||
830 | 827 | ||
831 | atomic_inc(&core->users); | 828 | atomic_inc(&core->users); |
829 | mutex_unlock(&core->lock); | ||
832 | 830 | ||
833 | return 0; | 831 | return 0; |
834 | } | 832 | } |
@@ -920,10 +918,11 @@ static int video_release(struct file *file) | |||
920 | 918 | ||
921 | videobuf_mmap_free(&fh->vidq); | 919 | videobuf_mmap_free(&fh->vidq); |
922 | videobuf_mmap_free(&fh->vbiq); | 920 | videobuf_mmap_free(&fh->vbiq); |
921 | |||
922 | mutex_lock(&dev->core->lock); | ||
923 | file->private_data = NULL; | 923 | file->private_data = NULL; |
924 | kfree(fh); | 924 | kfree(fh); |
925 | 925 | ||
926 | mutex_lock(&dev->core->lock); | ||
927 | if(atomic_dec_and_test(&dev->core->users)) | 926 | if(atomic_dec_and_test(&dev->core->users)) |
928 | call_all(dev->core, core, s_power, 0); | 927 | call_all(dev->core, core, s_power, 0); |
929 | mutex_unlock(&dev->core->lock); | 928 | mutex_unlock(&dev->core->lock); |
@@ -944,7 +943,7 @@ video_mmap(struct file *file, struct vm_area_struct * vma) | |||
944 | 943 | ||
945 | int cx88_get_control (struct cx88_core *core, struct v4l2_control *ctl) | 944 | int cx88_get_control (struct cx88_core *core, struct v4l2_control *ctl) |
946 | { | 945 | { |
947 | struct cx88_ctrl *c = NULL; | 946 | const struct cx88_ctrl *c = NULL; |
948 | u32 value; | 947 | u32 value; |
949 | int i; | 948 | int i; |
950 | 949 | ||
@@ -976,9 +975,10 @@ EXPORT_SYMBOL(cx88_get_control); | |||
976 | 975 | ||
977 | int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) | 976 | int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) |
978 | { | 977 | { |
979 | struct cx88_ctrl *c = NULL; | 978 | const struct cx88_ctrl *c = NULL; |
980 | u32 value,mask; | 979 | u32 value,mask; |
981 | int i; | 980 | int i; |
981 | struct v4l2_control client_ctl; | ||
982 | 982 | ||
983 | for (i = 0; i < CX8800_CTLS; i++) { | 983 | for (i = 0; i < CX8800_CTLS; i++) { |
984 | if (cx8800_ctls[i].v.id == ctl->id) { | 984 | if (cx8800_ctls[i].v.id == ctl->id) { |
@@ -992,6 +992,27 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
992 | ctl->value = c->v.minimum; | 992 | ctl->value = c->v.minimum; |
993 | if (ctl->value > c->v.maximum) | 993 | if (ctl->value > c->v.maximum) |
994 | ctl->value = c->v.maximum; | 994 | ctl->value = c->v.maximum; |
995 | |||
996 | /* Pass changes onto any WM8775 */ | ||
997 | client_ctl.id = ctl->id; | ||
998 | switch (ctl->id) { | ||
999 | case V4L2_CID_AUDIO_MUTE: | ||
1000 | client_ctl.value = ctl->value; | ||
1001 | break; | ||
1002 | case V4L2_CID_AUDIO_VOLUME: | ||
1003 | client_ctl.value = (ctl->value) ? | ||
1004 | (0x90 + ctl->value) << 8 : 0; | ||
1005 | break; | ||
1006 | case V4L2_CID_AUDIO_BALANCE: | ||
1007 | client_ctl.value = ctl->value << 9; | ||
1008 | break; | ||
1009 | default: | ||
1010 | client_ctl.id = 0; | ||
1011 | break; | ||
1012 | } | ||
1013 | if (client_ctl.id) | ||
1014 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
1015 | |||
995 | mask=c->mask; | 1016 | mask=c->mask; |
996 | switch (ctl->id) { | 1017 | switch (ctl->id) { |
997 | case V4L2_CID_AUDIO_BALANCE: | 1018 | case V4L2_CID_AUDIO_BALANCE: |
@@ -1072,7 +1093,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
1072 | struct v4l2_format *f) | 1093 | struct v4l2_format *f) |
1073 | { | 1094 | { |
1074 | struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; | 1095 | struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; |
1075 | struct cx8800_fmt *fmt; | 1096 | const struct cx8800_fmt *fmt; |
1076 | enum v4l2_field field; | 1097 | enum v4l2_field field; |
1077 | unsigned int maxw, maxh; | 1098 | unsigned int maxw, maxh; |
1078 | 1099 | ||
@@ -1247,7 +1268,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *tvnorms) | |||
1247 | /* only one input in this sample driver */ | 1268 | /* only one input in this sample driver */ |
1248 | int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) | 1269 | int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) |
1249 | { | 1270 | { |
1250 | static const char *iname[] = { | 1271 | static const char * const iname[] = { |
1251 | [ CX88_VMUX_COMPOSITE1 ] = "Composite1", | 1272 | [ CX88_VMUX_COMPOSITE1 ] = "Composite1", |
1252 | [ CX88_VMUX_COMPOSITE2 ] = "Composite2", | 1273 | [ CX88_VMUX_COMPOSITE2 ] = "Composite2", |
1253 | [ CX88_VMUX_COMPOSITE3 ] = "Composite3", | 1274 | [ CX88_VMUX_COMPOSITE3 ] = "Composite3", |
@@ -1267,9 +1288,10 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) | |||
1267 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1288 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1268 | strcpy(i->name,iname[INPUT(n).type]); | 1289 | strcpy(i->name,iname[INPUT(n).type]); |
1269 | if ((CX88_VMUX_TELEVISION == INPUT(n).type) || | 1290 | if ((CX88_VMUX_TELEVISION == INPUT(n).type) || |
1270 | (CX88_VMUX_CABLE == INPUT(n).type)) | 1291 | (CX88_VMUX_CABLE == INPUT(n).type)) { |
1271 | i->type = V4L2_INPUT_TYPE_TUNER; | 1292 | i->type = V4L2_INPUT_TYPE_TUNER; |
1272 | i->std = CX88_NORMS; | 1293 | i->std = CX88_NORMS; |
1294 | } | ||
1273 | return 0; | 1295 | return 0; |
1274 | } | 1296 | } |
1275 | EXPORT_SYMBOL(cx88_enum_input); | 1297 | EXPORT_SYMBOL(cx88_enum_input); |
@@ -1537,7 +1559,9 @@ static int radio_queryctrl (struct file *file, void *priv, | |||
1537 | if (c->id < V4L2_CID_BASE || | 1559 | if (c->id < V4L2_CID_BASE || |
1538 | c->id >= V4L2_CID_LASTP1) | 1560 | c->id >= V4L2_CID_LASTP1) |
1539 | return -EINVAL; | 1561 | return -EINVAL; |
1540 | if (c->id == V4L2_CID_AUDIO_MUTE) { | 1562 | if (c->id == V4L2_CID_AUDIO_MUTE || |
1563 | c->id == V4L2_CID_AUDIO_VOLUME || | ||
1564 | c->id == V4L2_CID_AUDIO_BALANCE) { | ||
1541 | for (i = 0; i < CX8800_CTLS; i++) { | 1565 | for (i = 0; i < CX8800_CTLS; i++) { |
1542 | if (cx8800_ctls[i].v.id == c->id) | 1566 | if (cx8800_ctls[i].v.id == c->id) |
1543 | break; | 1567 | break; |
@@ -1578,7 +1602,7 @@ static void cx8800_vid_timeout(unsigned long data) | |||
1578 | spin_unlock_irqrestore(&dev->slock,flags); | 1602 | spin_unlock_irqrestore(&dev->slock,flags); |
1579 | } | 1603 | } |
1580 | 1604 | ||
1581 | static char *cx88_vid_irqs[32] = { | 1605 | static const char *cx88_vid_irqs[32] = { |
1582 | "y_risci1", "u_risci1", "v_risci1", "vbi_risc1", | 1606 | "y_risci1", "u_risci1", "v_risci1", "vbi_risc1", |
1583 | "y_risci2", "u_risci2", "v_risci2", "vbi_risc2", | 1607 | "y_risci2", "u_risci2", "v_risci2", "vbi_risc2", |
1584 | "y_oflow", "u_oflow", "v_oflow", "vbi_oflow", | 1608 | "y_oflow", "u_oflow", "v_oflow", "vbi_oflow", |
@@ -1723,7 +1747,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1723 | 1747 | ||
1724 | static struct video_device cx8800_vbi_template; | 1748 | static struct video_device cx8800_vbi_template; |
1725 | 1749 | ||
1726 | static struct video_device cx8800_video_template = { | 1750 | static const struct video_device cx8800_video_template = { |
1727 | .name = "cx8800-video", | 1751 | .name = "cx8800-video", |
1728 | .fops = &video_fops, | 1752 | .fops = &video_fops, |
1729 | .ioctl_ops = &video_ioctl_ops, | 1753 | .ioctl_ops = &video_ioctl_ops, |
@@ -1758,7 +1782,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
1758 | #endif | 1782 | #endif |
1759 | }; | 1783 | }; |
1760 | 1784 | ||
1761 | static struct video_device cx8800_radio_template = { | 1785 | static const struct video_device cx8800_radio_template = { |
1762 | .name = "cx8800-radio", | 1786 | .name = "cx8800-radio", |
1763 | .fops = &radio_fops, | 1787 | .fops = &radio_fops, |
1764 | .ioctl_ops = &radio_ioctl_ops, | 1788 | .ioctl_ops = &radio_ioctl_ops, |
@@ -1872,20 +1896,20 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1872 | 1896 | ||
1873 | if (core->board.audio_chip == V4L2_IDENT_WM8775) | 1897 | if (core->board.audio_chip == V4L2_IDENT_WM8775) |
1874 | v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, | 1898 | v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, |
1875 | "wm8775", "wm8775", 0x36 >> 1, NULL); | 1899 | NULL, "wm8775", 0x36 >> 1, NULL); |
1876 | 1900 | ||
1877 | if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { | 1901 | if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { |
1878 | /* This probes for a tda9874 as is used on some | 1902 | /* This probes for a tda9874 as is used on some |
1879 | Pixelview Ultra boards. */ | 1903 | Pixelview Ultra boards. */ |
1880 | v4l2_i2c_new_subdev(&core->v4l2_dev, | 1904 | v4l2_i2c_new_subdev(&core->v4l2_dev, |
1881 | &core->i2c_adap, | 1905 | &core->i2c_adap, |
1882 | "tvaudio", "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); | 1906 | NULL, "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); |
1883 | } | 1907 | } |
1884 | 1908 | ||
1885 | switch (core->boardnr) { | 1909 | switch (core->boardnr) { |
1886 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: | 1910 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
1887 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: { | 1911 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: { |
1888 | static struct i2c_board_info rtc_info = { | 1912 | static const struct i2c_board_info rtc_info = { |
1889 | I2C_BOARD_INFO("isl1208", 0x6f) | 1913 | I2C_BOARD_INFO("isl1208", 0x6f) |
1890 | }; | 1914 | }; |
1891 | 1915 | ||
@@ -2082,7 +2106,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) | |||
2082 | 2106 | ||
2083 | /* ----------------------------------------------------------- */ | 2107 | /* ----------------------------------------------------------- */ |
2084 | 2108 | ||
2085 | static struct pci_device_id cx8800_pci_tbl[] = { | 2109 | static const struct pci_device_id cx8800_pci_tbl[] = { |
2086 | { | 2110 | { |
2087 | .vendor = 0x14f1, | 2111 | .vendor = 0x14f1, |
2088 | .device = 0x8800, | 2112 | .device = 0x8800, |
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c index 794f2932b75..ec5476d8b10 100644 --- a/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c | |||
@@ -121,8 +121,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) | |||
121 | memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, | 121 | memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, |
122 | sizeof(vp3054_i2c->algo)); | 122 | sizeof(vp3054_i2c->algo)); |
123 | 123 | ||
124 | vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL; | ||
125 | |||
126 | vp3054_i2c->adap.dev.parent = &dev->pci->dev; | 124 | vp3054_i2c->adap.dev.parent = &dev->pci->dev; |
127 | strlcpy(vp3054_i2c->adap.name, core->name, | 125 | strlcpy(vp3054_i2c->adap.name, core->name, |
128 | sizeof(vp3054_i2c->adap.name)); | 126 | sizeof(vp3054_i2c->adap.name)); |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 33d161a1172..e8c732e7ae4 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -31,9 +31,8 @@ | |||
31 | #include <media/videobuf-dma-sg.h> | 31 | #include <media/videobuf-dma-sg.h> |
32 | #include <media/v4l2-chip-ident.h> | 32 | #include <media/v4l2-chip-ident.h> |
33 | #include <media/cx2341x.h> | 33 | #include <media/cx2341x.h> |
34 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | ||
35 | #include <media/videobuf-dvb.h> | 34 | #include <media/videobuf-dvb.h> |
36 | #endif | 35 | #include <media/ir-kbd-i2c.h> |
37 | 36 | ||
38 | #include "btcx-risc.h" | 37 | #include "btcx-risc.h" |
39 | #include "cx88-reg.h" | 38 | #include "cx88-reg.h" |
@@ -108,7 +107,7 @@ static unsigned int inline norm_maxh(v4l2_std_id norm) | |||
108 | /* static data */ | 107 | /* static data */ |
109 | 108 | ||
110 | struct cx8800_fmt { | 109 | struct cx8800_fmt { |
111 | char *name; | 110 | const char *name; |
112 | u32 fourcc; /* v4l2 format id */ | 111 | u32 fourcc; /* v4l2 format id */ |
113 | int depth; | 112 | int depth; |
114 | int flags; | 113 | int flags; |
@@ -138,7 +137,7 @@ struct cx88_ctrl { | |||
138 | /* more */ | 137 | /* more */ |
139 | 138 | ||
140 | struct sram_channel { | 139 | struct sram_channel { |
141 | char *name; | 140 | const char *name; |
142 | u32 cmds_start; | 141 | u32 cmds_start; |
143 | u32 ctrl_start; | 142 | u32 ctrl_start; |
144 | u32 cdt; | 143 | u32 cdt; |
@@ -149,7 +148,7 @@ struct sram_channel { | |||
149 | u32 cnt1_reg; | 148 | u32 cnt1_reg; |
150 | u32 cnt2_reg; | 149 | u32 cnt2_reg; |
151 | }; | 150 | }; |
152 | extern struct sram_channel cx88_sram_channels[]; | 151 | extern const struct sram_channel const cx88_sram_channels[]; |
153 | 152 | ||
154 | /* ----------------------------------------------------------- */ | 153 | /* ----------------------------------------------------------- */ |
155 | /* card configuration */ | 154 | /* card configuration */ |
@@ -240,6 +239,7 @@ extern struct sram_channel cx88_sram_channels[]; | |||
240 | #define CX88_BOARD_WINFAST_DTV2000H_J 82 | 239 | #define CX88_BOARD_WINFAST_DTV2000H_J 82 |
241 | #define CX88_BOARD_PROF_7301 83 | 240 | #define CX88_BOARD_PROF_7301 83 |
242 | #define CX88_BOARD_SAMSUNG_SMT_7020 84 | 241 | #define CX88_BOARD_SAMSUNG_SMT_7020 84 |
242 | #define CX88_BOARD_TWINHAN_VP1027_DVBS 85 | ||
243 | 243 | ||
244 | enum cx88_itype { | 244 | enum cx88_itype { |
245 | CX88_VMUX_COMPOSITE1 = 1, | 245 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -262,7 +262,7 @@ struct cx88_input { | |||
262 | }; | 262 | }; |
263 | 263 | ||
264 | struct cx88_board { | 264 | struct cx88_board { |
265 | char *name; | 265 | const char *name; |
266 | unsigned int tuner_type; | 266 | unsigned int tuner_type; |
267 | unsigned int radio_type; | 267 | unsigned int radio_type; |
268 | unsigned char tuner_addr; | 268 | unsigned char tuner_addr; |
@@ -281,6 +281,20 @@ struct cx88_subid { | |||
281 | u32 card; | 281 | u32 card; |
282 | }; | 282 | }; |
283 | 283 | ||
284 | enum cx88_tvaudio { | ||
285 | WW_NONE = 1, | ||
286 | WW_BTSC, | ||
287 | WW_BG, | ||
288 | WW_DK, | ||
289 | WW_I, | ||
290 | WW_L, | ||
291 | WW_EIAJ, | ||
292 | WW_I2SPT, | ||
293 | WW_FM, | ||
294 | WW_I2SADC, | ||
295 | WW_M | ||
296 | }; | ||
297 | |||
284 | #define INPUT(nr) (core->board.input[nr]) | 298 | #define INPUT(nr) (core->board.input[nr]) |
285 | 299 | ||
286 | /* ----------------------------------------------------------- */ | 300 | /* ----------------------------------------------------------- */ |
@@ -300,7 +314,7 @@ struct cx88_buffer { | |||
300 | /* cx88 specific */ | 314 | /* cx88 specific */ |
301 | unsigned int bpl; | 315 | unsigned int bpl; |
302 | struct btcx_riscmem risc; | 316 | struct btcx_riscmem risc; |
303 | struct cx8800_fmt *fmt; | 317 | const struct cx8800_fmt *fmt; |
304 | u32 count; | 318 | u32 count; |
305 | }; | 319 | }; |
306 | 320 | ||
@@ -352,7 +366,7 @@ struct cx88_core { | |||
352 | /* state info */ | 366 | /* state info */ |
353 | struct task_struct *kthread; | 367 | struct task_struct *kthread; |
354 | v4l2_std_id tvnorm; | 368 | v4l2_std_id tvnorm; |
355 | u32 tvaudio; | 369 | enum cx88_tvaudio tvaudio; |
356 | u32 audiomode_manual; | 370 | u32 audiomode_manual; |
357 | u32 audiomode_current; | 371 | u32 audiomode_current; |
358 | u32 input; | 372 | u32 input; |
@@ -363,6 +377,9 @@ struct cx88_core { | |||
363 | /* IR remote control state */ | 377 | /* IR remote control state */ |
364 | struct cx88_IR *ir; | 378 | struct cx88_IR *ir; |
365 | 379 | ||
380 | /* I2C remote data */ | ||
381 | struct IR_i2c_init_data init_data; | ||
382 | |||
366 | struct mutex lock; | 383 | struct mutex lock; |
367 | /* various v4l controls */ | 384 | /* various v4l controls */ |
368 | u32 freq; | 385 | u32 freq; |
@@ -381,17 +398,19 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) | |||
381 | return container_of(v4l2_dev, struct cx88_core, v4l2_dev); | 398 | return container_of(v4l2_dev, struct cx88_core, v4l2_dev); |
382 | } | 399 | } |
383 | 400 | ||
384 | #define call_all(core, o, f, args...) \ | 401 | #define call_hw(core, grpid, o, f, args...) \ |
385 | do { \ | 402 | do { \ |
386 | if (!core->i2c_rc) { \ | 403 | if (!core->i2c_rc) { \ |
387 | if (core->gate_ctrl) \ | 404 | if (core->gate_ctrl) \ |
388 | core->gate_ctrl(core, 1); \ | 405 | core->gate_ctrl(core, 1); \ |
389 | v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \ | 406 | v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \ |
390 | if (core->gate_ctrl) \ | 407 | if (core->gate_ctrl) \ |
391 | core->gate_ctrl(core, 0); \ | 408 | core->gate_ctrl(core, 0); \ |
392 | } \ | 409 | } \ |
393 | } while (0) | 410 | } while (0) |
394 | 411 | ||
412 | #define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args) | ||
413 | |||
395 | struct cx8800_dev; | 414 | struct cx8800_dev; |
396 | struct cx8802_dev; | 415 | struct cx8802_dev; |
397 | 416 | ||
@@ -410,7 +429,7 @@ struct cx8800_fh { | |||
410 | unsigned int nclips; | 429 | unsigned int nclips; |
411 | 430 | ||
412 | /* video capture */ | 431 | /* video capture */ |
413 | struct cx8800_fmt *fmt; | 432 | const struct cx8800_fmt *fmt; |
414 | unsigned int width,height; | 433 | unsigned int width,height; |
415 | struct videobuf_queue vidq; | 434 | struct videobuf_queue vidq; |
416 | 435 | ||
@@ -565,7 +584,7 @@ struct cx8802_dev { | |||
565 | /* ----------------------------------------------------------- */ | 584 | /* ----------------------------------------------------------- */ |
566 | /* cx88-core.c */ | 585 | /* cx88-core.c */ |
567 | 586 | ||
568 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, | 587 | extern void cx88_print_irqbits(const char *name, const char *tag, const char *strings[], |
569 | int len, u32 bits, u32 mask); | 588 | int len, u32 bits, u32 mask); |
570 | 589 | ||
571 | extern int cx88_core_irq(struct cx88_core *core, u32 status); | 590 | extern int cx88_core_irq(struct cx88_core *core, u32 status); |
@@ -592,10 +611,10 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf); | |||
592 | extern void cx88_risc_disasm(struct cx88_core *core, | 611 | extern void cx88_risc_disasm(struct cx88_core *core, |
593 | struct btcx_riscmem *risc); | 612 | struct btcx_riscmem *risc); |
594 | extern int cx88_sram_channel_setup(struct cx88_core *core, | 613 | extern int cx88_sram_channel_setup(struct cx88_core *core, |
595 | struct sram_channel *ch, | 614 | const struct sram_channel *ch, |
596 | unsigned int bpl, u32 risc); | 615 | unsigned int bpl, u32 risc); |
597 | extern void cx88_sram_channel_dump(struct cx88_core *core, | 616 | extern void cx88_sram_channel_dump(struct cx88_core *core, |
598 | struct sram_channel *ch); | 617 | const struct sram_channel *ch); |
599 | 618 | ||
600 | extern int cx88_set_scale(struct cx88_core *core, unsigned int width, | 619 | extern int cx88_set_scale(struct cx88_core *core, unsigned int width, |
601 | unsigned int height, enum v4l2_field field); | 620 | unsigned int height, enum v4l2_field field); |
@@ -603,8 +622,8 @@ extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); | |||
603 | 622 | ||
604 | extern struct video_device *cx88_vdev_init(struct cx88_core *core, | 623 | extern struct video_device *cx88_vdev_init(struct cx88_core *core, |
605 | struct pci_dev *pci, | 624 | struct pci_dev *pci, |
606 | struct video_device *template, | 625 | const struct video_device *template_, |
607 | char *type); | 626 | const char *type); |
608 | extern struct cx88_core* cx88_core_get(struct pci_dev *pci); | 627 | extern struct cx88_core* cx88_core_get(struct pci_dev *pci); |
609 | extern void cx88_core_put(struct cx88_core *core, | 628 | extern void cx88_core_put(struct cx88_core *core, |
610 | struct pci_dev *pci); | 629 | struct pci_dev *pci); |
@@ -630,13 +649,12 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev, | |||
630 | struct cx88_dmaqueue *q); | 649 | struct cx88_dmaqueue *q); |
631 | void cx8800_vbi_timeout(unsigned long data); | 650 | void cx8800_vbi_timeout(unsigned long data); |
632 | 651 | ||
633 | extern struct videobuf_queue_ops cx8800_vbi_qops; | 652 | extern const struct videobuf_queue_ops cx8800_vbi_qops; |
634 | 653 | ||
635 | /* ----------------------------------------------------------- */ | 654 | /* ----------------------------------------------------------- */ |
636 | /* cx88-i2c.c */ | 655 | /* cx88-i2c.c */ |
637 | 656 | ||
638 | extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci); | 657 | extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci); |
639 | extern void cx88_i2c_init_ir(struct cx88_core *core); | ||
640 | 658 | ||
641 | 659 | ||
642 | /* ----------------------------------------------------------- */ | 660 | /* ----------------------------------------------------------- */ |
@@ -651,18 +669,6 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); | |||
651 | /* ----------------------------------------------------------- */ | 669 | /* ----------------------------------------------------------- */ |
652 | /* cx88-tvaudio.c */ | 670 | /* cx88-tvaudio.c */ |
653 | 671 | ||
654 | #define WW_NONE 1 | ||
655 | #define WW_BTSC 2 | ||
656 | #define WW_BG 3 | ||
657 | #define WW_DK 4 | ||
658 | #define WW_I 5 | ||
659 | #define WW_L 6 | ||
660 | #define WW_EIAJ 7 | ||
661 | #define WW_I2SPT 8 | ||
662 | #define WW_FM 9 | ||
663 | #define WW_I2SADC 10 | ||
664 | #define WW_M 11 | ||
665 | |||
666 | void cx88_set_tvaudio(struct cx88_core *core); | 672 | void cx88_set_tvaudio(struct cx88_core *core); |
667 | void cx88_newstation(struct cx88_core *core); | 673 | void cx88_newstation(struct cx88_core *core); |
668 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); | 674 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); |
@@ -686,6 +692,7 @@ int cx88_ir_fini(struct cx88_core *core); | |||
686 | void cx88_ir_irq(struct cx88_core *core); | 692 | void cx88_ir_irq(struct cx88_core *core); |
687 | int cx88_ir_start(struct cx88_core *core); | 693 | int cx88_ir_start(struct cx88_core *core); |
688 | void cx88_ir_stop(struct cx88_core *core); | 694 | void cx88_ir_stop(struct cx88_core *core); |
695 | extern void cx88_i2c_init_ir(struct cx88_core *core); | ||
689 | 696 | ||
690 | /* ----------------------------------------------------------- */ | 697 | /* ----------------------------------------------------------- */ |
691 | /* cx88-mpeg.c */ | 698 | /* cx88-mpeg.c */ |
@@ -705,10 +712,3 @@ int cx88_set_freq (struct cx88_core *core,struct v4l2_frequency *f); | |||
705 | int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl); | 712 | int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl); |
706 | int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl); | 713 | int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl); |
707 | int cx88_video_mux(struct cx88_core *core, unsigned int input); | 714 | int cx88_video_mux(struct cx88_core *core, unsigned int input); |
708 | |||
709 | /* | ||
710 | * Local variables: | ||
711 | * c-basic-offset: 8 | ||
712 | * End: | ||
713 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
714 | */ | ||
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 1c258824728..d8e38cc4ec4 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c | |||
@@ -370,7 +370,7 @@ static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev) | |||
370 | * For a given standard, this functions sets up the default | 370 | * For a given standard, this functions sets up the default |
371 | * pix format & crop values in the vpfe device and ccdc. It first | 371 | * pix format & crop values in the vpfe device and ccdc. It first |
372 | * starts with defaults based values from the standard table. | 372 | * starts with defaults based values from the standard table. |
373 | * It then checks if sub device support g_fmt and then override the | 373 | * It then checks if sub device support g_mbus_fmt and then override the |
374 | * values based on that.Sets crop values to match with scan resolution | 374 | * values based on that.Sets crop values to match with scan resolution |
375 | * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the | 375 | * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the |
376 | * values in ccdc | 376 | * values in ccdc |
@@ -379,6 +379,8 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, | |||
379 | const v4l2_std_id *std_id) | 379 | const v4l2_std_id *std_id) |
380 | { | 380 | { |
381 | struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev; | 381 | struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev; |
382 | struct v4l2_mbus_framefmt mbus_fmt; | ||
383 | struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix; | ||
382 | int i, ret = 0; | 384 | int i, ret = 0; |
383 | 385 | ||
384 | for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) { | 386 | for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) { |
@@ -403,29 +405,36 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, | |||
403 | vpfe_dev->crop.left = 0; | 405 | vpfe_dev->crop.left = 0; |
404 | vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels; | 406 | vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels; |
405 | vpfe_dev->crop.height = vpfe_dev->std_info.active_lines; | 407 | vpfe_dev->crop.height = vpfe_dev->std_info.active_lines; |
406 | vpfe_dev->fmt.fmt.pix.width = vpfe_dev->crop.width; | 408 | pix->width = vpfe_dev->crop.width; |
407 | vpfe_dev->fmt.fmt.pix.height = vpfe_dev->crop.height; | 409 | pix->height = vpfe_dev->crop.height; |
408 | 410 | ||
409 | /* first field and frame format based on standard frame format */ | 411 | /* first field and frame format based on standard frame format */ |
410 | if (vpfe_dev->std_info.frame_format) { | 412 | if (vpfe_dev->std_info.frame_format) { |
411 | vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; | 413 | pix->field = V4L2_FIELD_INTERLACED; |
412 | /* assume V4L2_PIX_FMT_UYVY as default */ | 414 | /* assume V4L2_PIX_FMT_UYVY as default */ |
413 | vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; | 415 | pix->pixelformat = V4L2_PIX_FMT_UYVY; |
416 | v4l2_fill_mbus_format(&mbus_fmt, pix, | ||
417 | V4L2_MBUS_FMT_YUYV10_2X10); | ||
414 | } else { | 418 | } else { |
415 | vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE; | 419 | pix->field = V4L2_FIELD_NONE; |
416 | /* assume V4L2_PIX_FMT_SBGGR8 */ | 420 | /* assume V4L2_PIX_FMT_SBGGR8 */ |
417 | vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8; | 421 | pix->pixelformat = V4L2_PIX_FMT_SBGGR8; |
422 | v4l2_fill_mbus_format(&mbus_fmt, pix, | ||
423 | V4L2_MBUS_FMT_SBGGR8_1X8); | ||
418 | } | 424 | } |
419 | 425 | ||
420 | /* if sub device supports g_fmt, override the defaults */ | 426 | /* if sub device supports g_mbus_fmt, override the defaults */ |
421 | ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, | 427 | ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, |
422 | sdinfo->grp_id, video, g_fmt, &vpfe_dev->fmt); | 428 | sdinfo->grp_id, video, g_mbus_fmt, &mbus_fmt); |
423 | 429 | ||
424 | if (ret && ret != -ENOIOCTLCMD) { | 430 | if (ret && ret != -ENOIOCTLCMD) { |
425 | v4l2_err(&vpfe_dev->v4l2_dev, | 431 | v4l2_err(&vpfe_dev->v4l2_dev, |
426 | "error in getting g_fmt from sub device\n"); | 432 | "error in getting g_mbus_fmt from sub device\n"); |
427 | return ret; | 433 | return ret; |
428 | } | 434 | } |
435 | v4l2_fill_pix_format(pix, &mbus_fmt); | ||
436 | pix->bytesperline = pix->width * 2; | ||
437 | pix->sizeimage = pix->bytesperline * pix->height; | ||
429 | 438 | ||
430 | /* Sets the values in CCDC */ | 439 | /* Sets the values in CCDC */ |
431 | ret = vpfe_config_ccdc_image_format(vpfe_dev); | 440 | ret = vpfe_config_ccdc_image_format(vpfe_dev); |
@@ -434,11 +443,8 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, | |||
434 | 443 | ||
435 | /* Update the values of sizeimage and bytesperline */ | 444 | /* Update the values of sizeimage and bytesperline */ |
436 | if (!ret) { | 445 | if (!ret) { |
437 | vpfe_dev->fmt.fmt.pix.bytesperline = | 446 | pix->bytesperline = ccdc_dev->hw_ops.get_line_length(); |
438 | ccdc_dev->hw_ops.get_line_length(); | 447 | pix->sizeimage = pix->bytesperline * pix->height; |
439 | vpfe_dev->fmt.fmt.pix.sizeimage = | ||
440 | vpfe_dev->fmt.fmt.pix.bytesperline * | ||
441 | vpfe_dev->fmt.fmt.pix.height; | ||
442 | } | 448 | } |
443 | return ret; | 449 | return ret; |
444 | } | 450 | } |
@@ -1366,7 +1372,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, | |||
1366 | req_buf->type, | 1372 | req_buf->type, |
1367 | vpfe_dev->fmt.fmt.pix.field, | 1373 | vpfe_dev->fmt.fmt.pix.field, |
1368 | sizeof(struct videobuf_buffer), | 1374 | sizeof(struct videobuf_buffer), |
1369 | fh); | 1375 | fh, NULL); |
1370 | 1376 | ||
1371 | fh->io_allowed = 1; | 1377 | fh->io_allowed = 1; |
1372 | vpfe_dev->io_usrs = 1; | 1378 | vpfe_dev->io_usrs = 1; |
@@ -1980,7 +1986,7 @@ static __init int vpfe_probe(struct platform_device *pdev) | |||
1980 | vpfe_dev->sd[i] = | 1986 | vpfe_dev->sd[i] = |
1981 | v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev, | 1987 | v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev, |
1982 | i2c_adap, | 1988 | i2c_adap, |
1983 | sdinfo->name, | 1989 | NULL, |
1984 | &sdinfo->board_info, | 1990 | &sdinfo->board_info, |
1985 | NULL); | 1991 | NULL); |
1986 | if (vpfe_dev->sd[i]) { | 1992 | if (vpfe_dev->sd[i]) { |
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c index a7f48b53d3f..6ac6acd1635 100644 --- a/drivers/media/video/davinci/vpif_capture.c +++ b/drivers/media/video/davinci/vpif_capture.c | |||
@@ -731,7 +731,6 @@ static int vpif_mmap(struct file *filep, struct vm_area_struct *vma) | |||
731 | */ | 731 | */ |
732 | static unsigned int vpif_poll(struct file *filep, poll_table * wait) | 732 | static unsigned int vpif_poll(struct file *filep, poll_table * wait) |
733 | { | 733 | { |
734 | int err = 0; | ||
735 | struct vpif_fh *fh = filep->private_data; | 734 | struct vpif_fh *fh = filep->private_data; |
736 | struct channel_obj *channel = fh->channel; | 735 | struct channel_obj *channel = fh->channel; |
737 | struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]); | 736 | struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]); |
@@ -739,8 +738,7 @@ static unsigned int vpif_poll(struct file *filep, poll_table * wait) | |||
739 | vpif_dbg(2, debug, "vpif_poll\n"); | 738 | vpif_dbg(2, debug, "vpif_poll\n"); |
740 | 739 | ||
741 | if (common->started) | 740 | if (common->started) |
742 | err = videobuf_poll_stream(filep, &common->buffer_queue, wait); | 741 | return videobuf_poll_stream(filep, &common->buffer_queue, wait); |
743 | |||
744 | return 0; | 742 | return 0; |
745 | } | 743 | } |
746 | 744 | ||
@@ -793,7 +791,7 @@ static int vpif_open(struct file *filep) | |||
793 | } | 791 | } |
794 | 792 | ||
795 | /* Allocate memory for the file handle object */ | 793 | /* Allocate memory for the file handle object */ |
796 | fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL); | 794 | fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); |
797 | if (NULL == fh) { | 795 | if (NULL == fh) { |
798 | vpif_err("unable to allocate memory for file handle object\n"); | 796 | vpif_err("unable to allocate memory for file handle object\n"); |
799 | ret = -ENOMEM; | 797 | ret = -ENOMEM; |
@@ -929,7 +927,8 @@ static int vpif_reqbufs(struct file *file, void *priv, | |||
929 | &common->irqlock, | 927 | &common->irqlock, |
930 | reqbuf->type, | 928 | reqbuf->type, |
931 | common->fmt.fmt.pix.field, | 929 | common->fmt.fmt.pix.field, |
932 | sizeof(struct videobuf_buffer), fh); | 930 | sizeof(struct videobuf_buffer), fh, |
931 | NULL); | ||
933 | 932 | ||
934 | /* Set io allowed member of file handle to TRUE */ | 933 | /* Set io allowed member of file handle to TRUE */ |
935 | fh->io_allowed[index] = 1; | 934 | fh->io_allowed[index] = 1; |
@@ -1030,9 +1029,10 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | |||
1030 | goto qbuf_exit; | 1029 | goto qbuf_exit; |
1031 | 1030 | ||
1032 | if ((VIDEOBUF_NEEDS_INIT != buf1->state) | 1031 | if ((VIDEOBUF_NEEDS_INIT != buf1->state) |
1033 | && (buf1->baddr != tbuf.m.userptr)) | 1032 | && (buf1->baddr != tbuf.m.userptr)) { |
1034 | vpif_buffer_release(&common->buffer_queue, buf1); | 1033 | vpif_buffer_release(&common->buffer_queue, buf1); |
1035 | buf1->baddr = tbuf.m.userptr; | 1034 | buf1->baddr = tbuf.m.userptr; |
1035 | } | ||
1036 | break; | 1036 | break; |
1037 | 1037 | ||
1038 | default: | 1038 | default: |
@@ -1994,7 +1994,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1994 | config = pdev->dev.platform_data; | 1994 | config = pdev->dev.platform_data; |
1995 | 1995 | ||
1996 | subdev_count = config->subdev_count; | 1996 | subdev_count = config->subdev_count; |
1997 | vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count, | 1997 | vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, |
1998 | GFP_KERNEL); | 1998 | GFP_KERNEL); |
1999 | if (vpif_obj.sd == NULL) { | 1999 | if (vpif_obj.sd == NULL) { |
2000 | vpif_err("unable to allocate memory for subdevice pointers\n"); | 2000 | vpif_err("unable to allocate memory for subdevice pointers\n"); |
@@ -2013,7 +2013,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
2013 | vpif_obj.sd[i] = | 2013 | vpif_obj.sd[i] = |
2014 | v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, | 2014 | v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, |
2015 | i2c_adap, | 2015 | i2c_adap, |
2016 | subdevdata->name, | 2016 | NULL, |
2017 | &subdevdata->board_info, | 2017 | &subdevdata->board_info, |
2018 | NULL); | 2018 | NULL); |
2019 | 2019 | ||
@@ -2113,7 +2113,7 @@ static const struct dev_pm_ops vpif_dev_pm_ops = { | |||
2113 | .resume = vpif_resume, | 2113 | .resume = vpif_resume, |
2114 | }; | 2114 | }; |
2115 | 2115 | ||
2116 | static struct platform_driver vpif_driver = { | 2116 | static __refdata struct platform_driver vpif_driver = { |
2117 | .driver = { | 2117 | .driver = { |
2118 | .name = "vpif_capture", | 2118 | .name = "vpif_capture", |
2119 | .owner = THIS_MODULE, | 2119 | .owner = THIS_MODULE, |
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index da07607cbc5..685f6a6ee60 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c | |||
@@ -600,7 +600,7 @@ static int vpif_open(struct file *filep) | |||
600 | 600 | ||
601 | ch = video_get_drvdata(vdev); | 601 | ch = video_get_drvdata(vdev); |
602 | /* Allocate memory for the file handle object */ | 602 | /* Allocate memory for the file handle object */ |
603 | fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL); | 603 | fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); |
604 | if (fh == NULL) { | 604 | if (fh == NULL) { |
605 | vpif_err("unable to allocate memory for file handle object\n"); | 605 | vpif_err("unable to allocate memory for file handle object\n"); |
606 | return -ENOMEM; | 606 | return -ENOMEM; |
@@ -853,7 +853,8 @@ static int vpif_reqbufs(struct file *file, void *priv, | |||
853 | &video_qops, NULL, | 853 | &video_qops, NULL, |
854 | &common->irqlock, | 854 | &common->irqlock, |
855 | reqbuf->type, field, | 855 | reqbuf->type, field, |
856 | sizeof(struct videobuf_buffer), fh); | 856 | sizeof(struct videobuf_buffer), fh, |
857 | NULL); | ||
857 | 858 | ||
858 | /* Set io allowed member of file handle to TRUE */ | 859 | /* Set io allowed member of file handle to TRUE */ |
859 | fh->io_allowed[index] = 1; | 860 | fh->io_allowed[index] = 1; |
@@ -935,9 +936,10 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | |||
935 | goto qbuf_exit; | 936 | goto qbuf_exit; |
936 | 937 | ||
937 | if ((VIDEOBUF_NEEDS_INIT != buf1->state) | 938 | if ((VIDEOBUF_NEEDS_INIT != buf1->state) |
938 | && (buf1->baddr != tbuf.m.userptr)) | 939 | && (buf1->baddr != tbuf.m.userptr)) { |
939 | vpif_buffer_release(&common->buffer_queue, buf1); | 940 | vpif_buffer_release(&common->buffer_queue, buf1); |
940 | buf1->baddr = tbuf.m.userptr; | 941 | buf1->baddr = tbuf.m.userptr; |
942 | } | ||
941 | break; | 943 | break; |
942 | 944 | ||
943 | default: | 945 | default: |
@@ -1395,7 +1397,7 @@ static int initialize_vpif(void) | |||
1395 | /* Allocate memory for six channel objects */ | 1397 | /* Allocate memory for six channel objects */ |
1396 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { | 1398 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { |
1397 | vpif_obj.dev[i] = | 1399 | vpif_obj.dev[i] = |
1398 | kmalloc(sizeof(struct channel_obj), GFP_KERNEL); | 1400 | kzalloc(sizeof(struct channel_obj), GFP_KERNEL); |
1399 | /* If memory allocation fails, return error */ | 1401 | /* If memory allocation fails, return error */ |
1400 | if (!vpif_obj.dev[i]) { | 1402 | if (!vpif_obj.dev[i]) { |
1401 | free_channel_objects_index = i; | 1403 | free_channel_objects_index = i; |
@@ -1541,7 +1543,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1541 | config = pdev->dev.platform_data; | 1543 | config = pdev->dev.platform_data; |
1542 | subdev_count = config->subdev_count; | 1544 | subdev_count = config->subdev_count; |
1543 | subdevdata = config->subdevinfo; | 1545 | subdevdata = config->subdevinfo; |
1544 | vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count, | 1546 | vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, |
1545 | GFP_KERNEL); | 1547 | GFP_KERNEL); |
1546 | if (vpif_obj.sd == NULL) { | 1548 | if (vpif_obj.sd == NULL) { |
1547 | vpif_err("unable to allocate memory for subdevice pointers\n"); | 1549 | vpif_err("unable to allocate memory for subdevice pointers\n"); |
@@ -1551,7 +1553,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1551 | 1553 | ||
1552 | for (i = 0; i < subdev_count; i++) { | 1554 | for (i = 0; i < subdev_count; i++) { |
1553 | vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, | 1555 | vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, |
1554 | i2c_adap, subdevdata[i].name, | 1556 | i2c_adap, NULL, |
1555 | &subdevdata[i].board_info, | 1557 | &subdevdata[i].board_info, |
1556 | NULL); | 1558 | NULL); |
1557 | if (!vpif_obj.sd[i]) { | 1559 | if (!vpif_obj.sd[i]) { |
@@ -1610,7 +1612,7 @@ static int vpif_remove(struct platform_device *device) | |||
1610 | return 0; | 1612 | return 0; |
1611 | } | 1613 | } |
1612 | 1614 | ||
1613 | static struct platform_driver vpif_driver = { | 1615 | static __refdata struct platform_driver vpif_driver = { |
1614 | .driver = { | 1616 | .driver = { |
1615 | .name = "vpif_display", | 1617 | .name = "vpif_display", |
1616 | .owner = THIS_MODULE, | 1618 | .owner = THIS_MODULE, |
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index e182abf476c..3c48a72eb7d 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -102,6 +102,9 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (atomic_read(&dev->stream_started) == 0) | ||
106 | return; | ||
107 | |||
105 | if (dev->adev.capture_pcm_substream) { | 108 | if (dev->adev.capture_pcm_substream) { |
106 | substream = dev->adev.capture_pcm_substream; | 109 | substream = dev->adev.capture_pcm_substream; |
107 | runtime = substream->runtime; | 110 | runtime = substream->runtime; |
@@ -217,31 +220,6 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
217 | return 0; | 220 | return 0; |
218 | } | 221 | } |
219 | 222 | ||
220 | static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) | ||
221 | { | ||
222 | dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ? | ||
223 | "stop" : "start"); | ||
224 | |||
225 | switch (cmd) { | ||
226 | case EM28XX_CAPTURE_STREAM_EN: | ||
227 | if (dev->adev.capture_stream == STREAM_OFF && | ||
228 | arg == EM28XX_START_AUDIO) { | ||
229 | dev->adev.capture_stream = STREAM_ON; | ||
230 | em28xx_init_audio_isoc(dev); | ||
231 | } else if (dev->adev.capture_stream == STREAM_ON && | ||
232 | arg == EM28XX_STOP_AUDIO) { | ||
233 | dev->adev.capture_stream = STREAM_OFF; | ||
234 | em28xx_deinit_isoc_audio(dev); | ||
235 | } else { | ||
236 | em28xx_errdev("An underrun very likely occurred. " | ||
237 | "Ignoring it.\n"); | ||
238 | } | ||
239 | return 0; | ||
240 | default: | ||
241 | return -EINVAL; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, | 223 | static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, |
246 | size_t size) | 224 | size_t size) |
247 | { | 225 | { |
@@ -303,7 +281,6 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | |||
303 | dev->mute = 0; | 281 | dev->mute = 0; |
304 | mutex_lock(&dev->lock); | 282 | mutex_lock(&dev->lock); |
305 | ret = em28xx_audio_analog_set(dev); | 283 | ret = em28xx_audio_analog_set(dev); |
306 | mutex_unlock(&dev->lock); | ||
307 | if (ret < 0) | 284 | if (ret < 0) |
308 | goto err; | 285 | goto err; |
309 | 286 | ||
@@ -311,11 +288,10 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | |||
311 | if (dev->alt == 0 && dev->adev.users == 0) { | 288 | if (dev->alt == 0 && dev->adev.users == 0) { |
312 | int errCode; | 289 | int errCode; |
313 | dev->alt = 7; | 290 | dev->alt = 7; |
314 | errCode = usb_set_interface(dev->udev, 0, 7); | ||
315 | dprintk("changing alternate number to 7\n"); | 291 | dprintk("changing alternate number to 7\n"); |
292 | errCode = usb_set_interface(dev->udev, 0, 7); | ||
316 | } | 293 | } |
317 | 294 | ||
318 | mutex_lock(&dev->lock); | ||
319 | dev->adev.users++; | 295 | dev->adev.users++; |
320 | mutex_unlock(&dev->lock); | 296 | mutex_unlock(&dev->lock); |
321 | 297 | ||
@@ -325,6 +301,8 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | |||
325 | 301 | ||
326 | return 0; | 302 | return 0; |
327 | err: | 303 | err: |
304 | mutex_unlock(&dev->lock); | ||
305 | |||
328 | em28xx_err("Error while configuring em28xx mixer\n"); | 306 | em28xx_err("Error while configuring em28xx mixer\n"); |
329 | return ret; | 307 | return ret; |
330 | } | 308 | } |
@@ -338,6 +316,11 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | |||
338 | dev->mute = 1; | 316 | dev->mute = 1; |
339 | mutex_lock(&dev->lock); | 317 | mutex_lock(&dev->lock); |
340 | dev->adev.users--; | 318 | dev->adev.users--; |
319 | if (atomic_read(&dev->stream_started) > 0) { | ||
320 | atomic_set(&dev->stream_started, 0); | ||
321 | schedule_work(&dev->wq_trigger); | ||
322 | } | ||
323 | |||
341 | em28xx_audio_analog_set(dev); | 324 | em28xx_audio_analog_set(dev); |
342 | if (substream->runtime->dma_area) { | 325 | if (substream->runtime->dma_area) { |
343 | dprintk("freeing\n"); | 326 | dprintk("freeing\n"); |
@@ -375,8 +358,10 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) | |||
375 | 358 | ||
376 | dprintk("Stop capture, if needed\n"); | 359 | dprintk("Stop capture, if needed\n"); |
377 | 360 | ||
378 | if (dev->adev.capture_stream == STREAM_ON) | 361 | if (atomic_read(&dev->stream_started) > 0) { |
379 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO); | 362 | atomic_set(&dev->stream_started, 0); |
363 | schedule_work(&dev->wq_trigger); | ||
364 | } | ||
380 | 365 | ||
381 | return 0; | 366 | return 0; |
382 | } | 367 | } |
@@ -391,31 +376,37 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream) | |||
391 | return 0; | 376 | return 0; |
392 | } | 377 | } |
393 | 378 | ||
379 | static void audio_trigger(struct work_struct *work) | ||
380 | { | ||
381 | struct em28xx *dev = container_of(work, struct em28xx, wq_trigger); | ||
382 | |||
383 | if (atomic_read(&dev->stream_started)) { | ||
384 | dprintk("starting capture"); | ||
385 | em28xx_init_audio_isoc(dev); | ||
386 | } else { | ||
387 | dprintk("stopping capture"); | ||
388 | em28xx_deinit_isoc_audio(dev); | ||
389 | } | ||
390 | } | ||
391 | |||
394 | static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, | 392 | static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, |
395 | int cmd) | 393 | int cmd) |
396 | { | 394 | { |
397 | struct em28xx *dev = snd_pcm_substream_chip(substream); | 395 | struct em28xx *dev = snd_pcm_substream_chip(substream); |
398 | int retval; | 396 | int retval; |
399 | 397 | ||
400 | dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ? | ||
401 | "start" : "stop"); | ||
402 | |||
403 | spin_lock(&dev->adev.slock); | ||
404 | switch (cmd) { | 398 | switch (cmd) { |
405 | case SNDRV_PCM_TRIGGER_START: | 399 | case SNDRV_PCM_TRIGGER_START: |
406 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO); | 400 | atomic_set(&dev->stream_started, 1); |
407 | retval = 0; | ||
408 | break; | 401 | break; |
409 | case SNDRV_PCM_TRIGGER_STOP: | 402 | case SNDRV_PCM_TRIGGER_STOP: |
410 | em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO); | 403 | atomic_set(&dev->stream_started, 1); |
411 | retval = 0; | ||
412 | break; | 404 | break; |
413 | default: | 405 | default: |
414 | retval = -EINVAL; | 406 | retval = -EINVAL; |
415 | } | 407 | } |
416 | 408 | schedule_work(&dev->wq_trigger); | |
417 | spin_unlock(&dev->adev.slock); | 409 | return 0; |
418 | return retval; | ||
419 | } | 410 | } |
420 | 411 | ||
421 | static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream | 412 | static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream |
@@ -495,6 +486,8 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
495 | strcpy(card->shortname, "Em28xx Audio"); | 486 | strcpy(card->shortname, "Em28xx Audio"); |
496 | strcpy(card->longname, "Empia Em28xx Audio"); | 487 | strcpy(card->longname, "Empia Em28xx Audio"); |
497 | 488 | ||
489 | INIT_WORK(&dev->wq_trigger, audio_trigger); | ||
490 | |||
498 | err = snd_card_register(card); | 491 | err = snd_card_register(card); |
499 | if (err < 0) { | 492 | if (err < 0) { |
500 | snd_card_free(card); | 493 | snd_card_free(card); |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index e7efb4bffab..54859233f31 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -187,6 +187,18 @@ static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | |||
187 | { -1, -1, -1, -1}, | 187 | { -1, -1, -1, -1}, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { | ||
191 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
192 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | ||
193 | { -1, -1, -1, -1}, | ||
194 | }; | ||
195 | |||
196 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { | ||
197 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
198 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
199 | { -1, -1, -1, -1}, | ||
200 | }; | ||
201 | |||
190 | /* eb1a:2868 Reddo DVB-C USB TV Box | 202 | /* eb1a:2868 Reddo DVB-C USB TV Box |
191 | GPIO4 - CU1216L NIM | 203 | GPIO4 - CU1216L NIM |
192 | Other GPIOs seems to be don't care. */ | 204 | Other GPIOs seems to be don't care. */ |
@@ -781,22 +793,22 @@ struct em28xx_board em28xx_boards[] = { | |||
781 | .tuner_gpio = default_tuner_gpio, | 793 | .tuner_gpio = default_tuner_gpio, |
782 | .decoder = EM28XX_TVP5150, | 794 | .decoder = EM28XX_TVP5150, |
783 | .has_dvb = 1, | 795 | .has_dvb = 1, |
784 | .dvb_gpio = default_digital, | 796 | .dvb_gpio = terratec_cinergy_USB_XS_FR_digital, |
785 | .input = { { | 797 | .input = { { |
786 | .type = EM28XX_VMUX_TELEVISION, | 798 | .type = EM28XX_VMUX_TELEVISION, |
787 | .vmux = TVP5150_COMPOSITE0, | 799 | .vmux = TVP5150_COMPOSITE0, |
788 | .amux = EM28XX_AMUX_VIDEO, | 800 | .amux = EM28XX_AMUX_VIDEO, |
789 | .gpio = default_analog, | 801 | .gpio = terratec_cinergy_USB_XS_FR_analog, |
790 | }, { | 802 | }, { |
791 | .type = EM28XX_VMUX_COMPOSITE1, | 803 | .type = EM28XX_VMUX_COMPOSITE1, |
792 | .vmux = TVP5150_COMPOSITE1, | 804 | .vmux = TVP5150_COMPOSITE1, |
793 | .amux = EM28XX_AMUX_LINE_IN, | 805 | .amux = EM28XX_AMUX_LINE_IN, |
794 | .gpio = default_analog, | 806 | .gpio = terratec_cinergy_USB_XS_FR_analog, |
795 | }, { | 807 | }, { |
796 | .type = EM28XX_VMUX_SVIDEO, | 808 | .type = EM28XX_VMUX_SVIDEO, |
797 | .vmux = TVP5150_SVIDEO, | 809 | .vmux = TVP5150_SVIDEO, |
798 | .amux = EM28XX_AMUX_LINE_IN, | 810 | .amux = EM28XX_AMUX_LINE_IN, |
799 | .gpio = default_analog, | 811 | .gpio = terratec_cinergy_USB_XS_FR_analog, |
800 | } }, | 812 | } }, |
801 | }, | 813 | }, |
802 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { | 814 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { |
@@ -1648,6 +1660,22 @@ struct em28xx_board em28xx_boards[] = { | |||
1648 | .gpio = terratec_av350_unmute_gpio, | 1660 | .gpio = terratec_av350_unmute_gpio, |
1649 | } }, | 1661 | } }, |
1650 | }, | 1662 | }, |
1663 | |||
1664 | [EM2860_BOARD_ELGATO_VIDEO_CAPTURE] = { | ||
1665 | .name = "Elgato Video Capture", | ||
1666 | .decoder = EM28XX_SAA711X, | ||
1667 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
1668 | .input = { { | ||
1669 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1670 | .vmux = SAA7115_COMPOSITE0, | ||
1671 | .amux = EM28XX_AMUX_LINE_IN, | ||
1672 | }, { | ||
1673 | .type = EM28XX_VMUX_SVIDEO, | ||
1674 | .vmux = SAA7115_SVIDEO3, | ||
1675 | .amux = EM28XX_AMUX_LINE_IN, | ||
1676 | } }, | ||
1677 | }, | ||
1678 | |||
1651 | [EM2882_BOARD_EVGA_INDTUBE] = { | 1679 | [EM2882_BOARD_EVGA_INDTUBE] = { |
1652 | .name = "Evga inDtube", | 1680 | .name = "Evga inDtube", |
1653 | .tuner_type = TUNER_XC2028, | 1681 | .tuner_type = TUNER_XC2028, |
@@ -1772,6 +1800,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
1772 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, | 1800 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, |
1773 | { USB_DEVICE(0x0ccd, 0x0096), | 1801 | { USB_DEVICE(0x0ccd, 0x0096), |
1774 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | 1802 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, |
1803 | { USB_DEVICE(0x0fd9, 0x0033), | ||
1804 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, | ||
1775 | { USB_DEVICE(0x185b, 0x2870), | 1805 | { USB_DEVICE(0x185b, 0x2870), |
1776 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, | 1806 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, |
1777 | { USB_DEVICE(0x185b, 0x2041), | 1807 | { USB_DEVICE(0x185b, 0x2041), |
@@ -2168,6 +2198,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
2168 | ctl->demod = XC3028_FE_ZARLINK456; | 2198 | ctl->demod = XC3028_FE_ZARLINK456; |
2169 | break; | 2199 | break; |
2170 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 2200 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
2201 | case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: | ||
2171 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | 2202 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: |
2172 | ctl->demod = XC3028_FE_ZARLINK456; | 2203 | ctl->demod = XC3028_FE_ZARLINK456; |
2173 | break; | 2204 | break; |
@@ -2523,39 +2554,39 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2523 | /* request some modules */ | 2554 | /* request some modules */ |
2524 | if (dev->board.has_msp34xx) | 2555 | if (dev->board.has_msp34xx) |
2525 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2556 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2526 | "msp3400", "msp3400", 0, msp3400_addrs); | 2557 | NULL, "msp3400", 0, msp3400_addrs); |
2527 | 2558 | ||
2528 | if (dev->board.decoder == EM28XX_SAA711X) | 2559 | if (dev->board.decoder == EM28XX_SAA711X) |
2529 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2560 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2530 | "saa7115", "saa7115_auto", 0, saa711x_addrs); | 2561 | NULL, "saa7115_auto", 0, saa711x_addrs); |
2531 | 2562 | ||
2532 | if (dev->board.decoder == EM28XX_TVP5150) | 2563 | if (dev->board.decoder == EM28XX_TVP5150) |
2533 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2564 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2534 | "tvp5150", "tvp5150", 0, tvp5150_addrs); | 2565 | NULL, "tvp5150", 0, tvp5150_addrs); |
2535 | 2566 | ||
2536 | if (dev->em28xx_sensor == EM28XX_MT9V011) { | 2567 | if (dev->em28xx_sensor == EM28XX_MT9V011) { |
2537 | struct v4l2_subdev *sd; | 2568 | struct v4l2_subdev *sd; |
2538 | 2569 | ||
2539 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 2570 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
2540 | &dev->i2c_adap, "mt9v011", "mt9v011", 0, mt9v011_addrs); | 2571 | &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs); |
2541 | v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); | 2572 | v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); |
2542 | } | 2573 | } |
2543 | 2574 | ||
2544 | 2575 | ||
2545 | if (dev->board.adecoder == EM28XX_TVAUDIO) | 2576 | if (dev->board.adecoder == EM28XX_TVAUDIO) |
2546 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2577 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2547 | "tvaudio", "tvaudio", dev->board.tvaudio_addr, NULL); | 2578 | NULL, "tvaudio", dev->board.tvaudio_addr, NULL); |
2548 | 2579 | ||
2549 | if (dev->board.tuner_type != TUNER_ABSENT) { | 2580 | if (dev->board.tuner_type != TUNER_ABSENT) { |
2550 | int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); | 2581 | int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); |
2551 | 2582 | ||
2552 | if (dev->board.radio.type) | 2583 | if (dev->board.radio.type) |
2553 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2584 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2554 | "tuner", "tuner", dev->board.radio_addr, NULL); | 2585 | NULL, "tuner", dev->board.radio_addr, NULL); |
2555 | 2586 | ||
2556 | if (has_demod) | 2587 | if (has_demod) |
2557 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | 2588 | v4l2_i2c_new_subdev(&dev->v4l2_dev, |
2558 | &dev->i2c_adap, "tuner", "tuner", | 2589 | &dev->i2c_adap, NULL, "tuner", |
2559 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | 2590 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); |
2560 | if (dev->tuner_addr == 0) { | 2591 | if (dev->tuner_addr == 0) { |
2561 | enum v4l2_i2c_tuner_type type = | 2592 | enum v4l2_i2c_tuner_type type = |
@@ -2563,14 +2594,14 @@ void em28xx_card_setup(struct em28xx *dev) | |||
2563 | struct v4l2_subdev *sd; | 2594 | struct v4l2_subdev *sd; |
2564 | 2595 | ||
2565 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 2596 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
2566 | &dev->i2c_adap, "tuner", "tuner", | 2597 | &dev->i2c_adap, NULL, "tuner", |
2567 | 0, v4l2_i2c_tuner_addrs(type)); | 2598 | 0, v4l2_i2c_tuner_addrs(type)); |
2568 | 2599 | ||
2569 | if (sd) | 2600 | if (sd) |
2570 | dev->tuner_addr = v4l2_i2c_subdev_addr(sd); | 2601 | dev->tuner_addr = v4l2_i2c_subdev_addr(sd); |
2571 | } else { | 2602 | } else { |
2572 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2603 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
2573 | "tuner", "tuner", dev->tuner_addr, NULL); | 2604 | NULL, "tuner", dev->tuner_addr, NULL); |
2574 | } | 2605 | } |
2575 | } | 2606 | } |
2576 | 2607 | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 7b9ec6e493e..908e3bc8830 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -277,12 +277,13 @@ static void em28xx_copy_vbi(struct em28xx *dev, | |||
277 | { | 277 | { |
278 | void *startwrite, *startread; | 278 | void *startwrite, *startread; |
279 | int offset; | 279 | int offset; |
280 | int bytesperline = dev->vbi_width; | 280 | int bytesperline; |
281 | 281 | ||
282 | if (dev == NULL) { | 282 | if (dev == NULL) { |
283 | em28xx_isocdbg("dev is null\n"); | 283 | em28xx_isocdbg("dev is null\n"); |
284 | return; | 284 | return; |
285 | } | 285 | } |
286 | bytesperline = dev->vbi_width; | ||
286 | 287 | ||
287 | if (dma_q == NULL) { | 288 | if (dma_q == NULL) { |
288 | em28xx_isocdbg("dma_q is null\n"); | 289 | em28xx_isocdbg("dma_q is null\n"); |
@@ -862,17 +863,14 @@ static int res_get(struct em28xx_fh *fh, unsigned int bit) | |||
862 | return 1; | 863 | return 1; |
863 | 864 | ||
864 | /* is it free? */ | 865 | /* is it free? */ |
865 | mutex_lock(&dev->lock); | ||
866 | if (dev->resources & bit) { | 866 | if (dev->resources & bit) { |
867 | /* no, someone else uses it */ | 867 | /* no, someone else uses it */ |
868 | mutex_unlock(&dev->lock); | ||
869 | return 0; | 868 | return 0; |
870 | } | 869 | } |
871 | /* it's free, grab it */ | 870 | /* it's free, grab it */ |
872 | fh->resources |= bit; | 871 | fh->resources |= bit; |
873 | dev->resources |= bit; | 872 | dev->resources |= bit; |
874 | em28xx_videodbg("res: get %d\n", bit); | 873 | em28xx_videodbg("res: get %d\n", bit); |
875 | mutex_unlock(&dev->lock); | ||
876 | return 1; | 874 | return 1; |
877 | } | 875 | } |
878 | 876 | ||
@@ -892,11 +890,9 @@ static void res_free(struct em28xx_fh *fh, unsigned int bits) | |||
892 | 890 | ||
893 | BUG_ON((fh->resources & bits) != bits); | 891 | BUG_ON((fh->resources & bits) != bits); |
894 | 892 | ||
895 | mutex_lock(&dev->lock); | ||
896 | fh->resources &= ~bits; | 893 | fh->resources &= ~bits; |
897 | dev->resources &= ~bits; | 894 | dev->resources &= ~bits; |
898 | em28xx_videodbg("res: put %d\n", bits); | 895 | em28xx_videodbg("res: put %d\n", bits); |
899 | mutex_unlock(&dev->lock); | ||
900 | } | 896 | } |
901 | 897 | ||
902 | static int get_ressource(struct em28xx_fh *fh) | 898 | static int get_ressource(struct em28xx_fh *fh) |
@@ -1023,8 +1019,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1023 | struct em28xx_fh *fh = priv; | 1019 | struct em28xx_fh *fh = priv; |
1024 | struct em28xx *dev = fh->dev; | 1020 | struct em28xx *dev = fh->dev; |
1025 | 1021 | ||
1026 | mutex_lock(&dev->lock); | ||
1027 | |||
1028 | f->fmt.pix.width = dev->width; | 1022 | f->fmt.pix.width = dev->width; |
1029 | f->fmt.pix.height = dev->height; | 1023 | f->fmt.pix.height = dev->height; |
1030 | f->fmt.pix.pixelformat = dev->format->fourcc; | 1024 | f->fmt.pix.pixelformat = dev->format->fourcc; |
@@ -1038,8 +1032,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1038 | else | 1032 | else |
1039 | f->fmt.pix.field = dev->interlaced ? | 1033 | f->fmt.pix.field = dev->interlaced ? |
1040 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | 1034 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; |
1041 | |||
1042 | mutex_unlock(&dev->lock); | ||
1043 | return 0; | 1035 | return 0; |
1044 | } | 1036 | } |
1045 | 1037 | ||
@@ -1137,22 +1129,15 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1137 | if (rc < 0) | 1129 | if (rc < 0) |
1138 | return rc; | 1130 | return rc; |
1139 | 1131 | ||
1140 | mutex_lock(&dev->lock); | ||
1141 | |||
1142 | vidioc_try_fmt_vid_cap(file, priv, f); | 1132 | vidioc_try_fmt_vid_cap(file, priv, f); |
1143 | 1133 | ||
1144 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | 1134 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { |
1145 | em28xx_errdev("%s queue busy\n", __func__); | 1135 | em28xx_errdev("%s queue busy\n", __func__); |
1146 | rc = -EBUSY; | 1136 | return -EBUSY; |
1147 | goto out; | ||
1148 | } | 1137 | } |
1149 | 1138 | ||
1150 | rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat, | 1139 | return em28xx_set_video_format(dev, f->fmt.pix.pixelformat, |
1151 | f->fmt.pix.width, f->fmt.pix.height); | 1140 | f->fmt.pix.width, f->fmt.pix.height); |
1152 | |||
1153 | out: | ||
1154 | mutex_unlock(&dev->lock); | ||
1155 | return rc; | ||
1156 | } | 1141 | } |
1157 | 1142 | ||
1158 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) | 1143 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) |
@@ -1181,7 +1166,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
1181 | if (rc < 0) | 1166 | if (rc < 0) |
1182 | return rc; | 1167 | return rc; |
1183 | 1168 | ||
1184 | mutex_lock(&dev->lock); | ||
1185 | dev->norm = *norm; | 1169 | dev->norm = *norm; |
1186 | 1170 | ||
1187 | /* Adjusts width/height, if needed */ | 1171 | /* Adjusts width/height, if needed */ |
@@ -1197,7 +1181,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
1197 | em28xx_resolution_set(dev); | 1181 | em28xx_resolution_set(dev); |
1198 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | 1182 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); |
1199 | 1183 | ||
1200 | mutex_unlock(&dev->lock); | ||
1201 | return 0; | 1184 | return 0; |
1202 | } | 1185 | } |
1203 | 1186 | ||
@@ -1302,9 +1285,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1302 | 1285 | ||
1303 | dev->ctl_input = i; | 1286 | dev->ctl_input = i; |
1304 | 1287 | ||
1305 | mutex_lock(&dev->lock); | ||
1306 | video_mux(dev, dev->ctl_input); | 1288 | video_mux(dev, dev->ctl_input); |
1307 | mutex_unlock(&dev->lock); | ||
1308 | return 0; | 1289 | return 0; |
1309 | } | 1290 | } |
1310 | 1291 | ||
@@ -1365,15 +1346,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
1365 | if (0 == INPUT(a->index)->type) | 1346 | if (0 == INPUT(a->index)->type) |
1366 | return -EINVAL; | 1347 | return -EINVAL; |
1367 | 1348 | ||
1368 | mutex_lock(&dev->lock); | ||
1369 | |||
1370 | dev->ctl_ainput = INPUT(a->index)->amux; | 1349 | dev->ctl_ainput = INPUT(a->index)->amux; |
1371 | dev->ctl_aoutput = INPUT(a->index)->aout; | 1350 | dev->ctl_aoutput = INPUT(a->index)->aout; |
1372 | 1351 | ||
1373 | if (!dev->ctl_aoutput) | 1352 | if (!dev->ctl_aoutput) |
1374 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | 1353 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; |
1375 | 1354 | ||
1376 | mutex_unlock(&dev->lock); | ||
1377 | return 0; | 1355 | return 0; |
1378 | } | 1356 | } |
1379 | 1357 | ||
@@ -1393,17 +1371,15 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
1393 | 1371 | ||
1394 | qc->id = id; | 1372 | qc->id = id; |
1395 | 1373 | ||
1396 | /* enumberate AC97 controls */ | 1374 | /* enumerate AC97 controls */ |
1397 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | 1375 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
1398 | rc = ac97_queryctrl(qc); | 1376 | rc = ac97_queryctrl(qc); |
1399 | if (!rc) | 1377 | if (!rc) |
1400 | return 0; | 1378 | return 0; |
1401 | } | 1379 | } |
1402 | 1380 | ||
1403 | /* enumberate V4L2 device controls */ | 1381 | /* enumerate V4L2 device controls */ |
1404 | mutex_lock(&dev->lock); | ||
1405 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); | 1382 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); |
1406 | mutex_unlock(&dev->lock); | ||
1407 | 1383 | ||
1408 | if (qc->type) | 1384 | if (qc->type) |
1409 | return 0; | 1385 | return 0; |
@@ -1423,7 +1399,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1423 | return rc; | 1399 | return rc; |
1424 | rc = 0; | 1400 | rc = 0; |
1425 | 1401 | ||
1426 | mutex_lock(&dev->lock); | ||
1427 | 1402 | ||
1428 | /* Set an AC97 control */ | 1403 | /* Set an AC97 control */ |
1429 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) | 1404 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) |
@@ -1437,7 +1412,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1437 | rc = 0; | 1412 | rc = 0; |
1438 | } | 1413 | } |
1439 | 1414 | ||
1440 | mutex_unlock(&dev->lock); | ||
1441 | return rc; | 1415 | return rc; |
1442 | } | 1416 | } |
1443 | 1417 | ||
@@ -1452,8 +1426,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1452 | if (rc < 0) | 1426 | if (rc < 0) |
1453 | return rc; | 1427 | return rc; |
1454 | 1428 | ||
1455 | mutex_lock(&dev->lock); | ||
1456 | |||
1457 | /* Set an AC97 control */ | 1429 | /* Set an AC97 control */ |
1458 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) | 1430 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) |
1459 | rc = ac97_set_ctrl(dev, ctrl); | 1431 | rc = ac97_set_ctrl(dev, ctrl); |
@@ -1480,8 +1452,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1480 | rc = em28xx_audio_analog_set(dev); | 1452 | rc = em28xx_audio_analog_set(dev); |
1481 | } | 1453 | } |
1482 | } | 1454 | } |
1483 | |||
1484 | mutex_unlock(&dev->lock); | ||
1485 | return rc; | 1455 | return rc; |
1486 | } | 1456 | } |
1487 | 1457 | ||
@@ -1502,10 +1472,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
1502 | strcpy(t->name, "Tuner"); | 1472 | strcpy(t->name, "Tuner"); |
1503 | t->type = V4L2_TUNER_ANALOG_TV; | 1473 | t->type = V4L2_TUNER_ANALOG_TV; |
1504 | 1474 | ||
1505 | mutex_lock(&dev->lock); | ||
1506 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); | 1475 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); |
1507 | mutex_unlock(&dev->lock); | ||
1508 | |||
1509 | return 0; | 1476 | return 0; |
1510 | } | 1477 | } |
1511 | 1478 | ||
@@ -1523,10 +1490,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
1523 | if (0 != t->index) | 1490 | if (0 != t->index) |
1524 | return -EINVAL; | 1491 | return -EINVAL; |
1525 | 1492 | ||
1526 | mutex_lock(&dev->lock); | ||
1527 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); | 1493 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); |
1528 | mutex_unlock(&dev->lock); | ||
1529 | |||
1530 | return 0; | 1494 | return 0; |
1531 | } | 1495 | } |
1532 | 1496 | ||
@@ -1536,11 +1500,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
1536 | struct em28xx_fh *fh = priv; | 1500 | struct em28xx_fh *fh = priv; |
1537 | struct em28xx *dev = fh->dev; | 1501 | struct em28xx *dev = fh->dev; |
1538 | 1502 | ||
1539 | mutex_lock(&dev->lock); | ||
1540 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1503 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1541 | f->frequency = dev->ctl_freq; | 1504 | f->frequency = dev->ctl_freq; |
1542 | mutex_unlock(&dev->lock); | ||
1543 | |||
1544 | return 0; | 1505 | return 0; |
1545 | } | 1506 | } |
1546 | 1507 | ||
@@ -1563,13 +1524,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1563 | if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) | 1524 | if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) |
1564 | return -EINVAL; | 1525 | return -EINVAL; |
1565 | 1526 | ||
1566 | mutex_lock(&dev->lock); | ||
1567 | |||
1568 | dev->ctl_freq = f->frequency; | 1527 | dev->ctl_freq = f->frequency; |
1569 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); | 1528 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); |
1570 | 1529 | ||
1571 | mutex_unlock(&dev->lock); | ||
1572 | |||
1573 | return 0; | 1530 | return 0; |
1574 | } | 1531 | } |
1575 | 1532 | ||
@@ -1610,9 +1567,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1610 | 1567 | ||
1611 | switch (reg->match.type) { | 1568 | switch (reg->match.type) { |
1612 | case V4L2_CHIP_MATCH_AC97: | 1569 | case V4L2_CHIP_MATCH_AC97: |
1613 | mutex_lock(&dev->lock); | ||
1614 | ret = em28xx_read_ac97(dev, reg->reg); | 1570 | ret = em28xx_read_ac97(dev, reg->reg); |
1615 | mutex_unlock(&dev->lock); | ||
1616 | if (ret < 0) | 1571 | if (ret < 0) |
1617 | return ret; | 1572 | return ret; |
1618 | 1573 | ||
@@ -1634,9 +1589,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1634 | /* Match host */ | 1589 | /* Match host */ |
1635 | reg->size = em28xx_reg_len(reg->reg); | 1590 | reg->size = em28xx_reg_len(reg->reg); |
1636 | if (reg->size == 1) { | 1591 | if (reg->size == 1) { |
1637 | mutex_lock(&dev->lock); | ||
1638 | ret = em28xx_read_reg(dev, reg->reg); | 1592 | ret = em28xx_read_reg(dev, reg->reg); |
1639 | mutex_unlock(&dev->lock); | ||
1640 | 1593 | ||
1641 | if (ret < 0) | 1594 | if (ret < 0) |
1642 | return ret; | 1595 | return ret; |
@@ -1644,10 +1597,8 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1644 | reg->val = ret; | 1597 | reg->val = ret; |
1645 | } else { | 1598 | } else { |
1646 | __le16 val = 0; | 1599 | __le16 val = 0; |
1647 | mutex_lock(&dev->lock); | ||
1648 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | 1600 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, |
1649 | reg->reg, (char *)&val, 2); | 1601 | reg->reg, (char *)&val, 2); |
1650 | mutex_unlock(&dev->lock); | ||
1651 | if (ret < 0) | 1602 | if (ret < 0) |
1652 | return ret; | 1603 | return ret; |
1653 | 1604 | ||
@@ -1663,15 +1614,10 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1663 | struct em28xx_fh *fh = priv; | 1614 | struct em28xx_fh *fh = priv; |
1664 | struct em28xx *dev = fh->dev; | 1615 | struct em28xx *dev = fh->dev; |
1665 | __le16 buf; | 1616 | __le16 buf; |
1666 | int rc; | ||
1667 | 1617 | ||
1668 | switch (reg->match.type) { | 1618 | switch (reg->match.type) { |
1669 | case V4L2_CHIP_MATCH_AC97: | 1619 | case V4L2_CHIP_MATCH_AC97: |
1670 | mutex_lock(&dev->lock); | 1620 | return em28xx_write_ac97(dev, reg->reg, reg->val); |
1671 | rc = em28xx_write_ac97(dev, reg->reg, reg->val); | ||
1672 | mutex_unlock(&dev->lock); | ||
1673 | |||
1674 | return rc; | ||
1675 | case V4L2_CHIP_MATCH_I2C_DRIVER: | 1621 | case V4L2_CHIP_MATCH_I2C_DRIVER: |
1676 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); | 1622 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); |
1677 | return 0; | 1623 | return 0; |
@@ -1687,12 +1633,8 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1687 | /* Match host */ | 1633 | /* Match host */ |
1688 | buf = cpu_to_le16(reg->val); | 1634 | buf = cpu_to_le16(reg->val); |
1689 | 1635 | ||
1690 | mutex_lock(&dev->lock); | 1636 | return em28xx_write_regs(dev, reg->reg, (char *)&buf, |
1691 | rc = em28xx_write_regs(dev, reg->reg, (char *)&buf, | ||
1692 | em28xx_reg_len(reg->reg)); | 1637 | em28xx_reg_len(reg->reg)); |
1693 | mutex_unlock(&dev->lock); | ||
1694 | |||
1695 | return rc; | ||
1696 | } | 1638 | } |
1697 | #endif | 1639 | #endif |
1698 | 1640 | ||
@@ -1829,16 +1771,12 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, | |||
1829 | if (rc < 0) | 1771 | if (rc < 0) |
1830 | return rc; | 1772 | return rc; |
1831 | 1773 | ||
1832 | mutex_lock(&dev->lock); | ||
1833 | |||
1834 | f->fmt.sliced.service_set = 0; | 1774 | f->fmt.sliced.service_set = 0; |
1835 | v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced); | 1775 | v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced); |
1836 | 1776 | ||
1837 | if (f->fmt.sliced.service_set == 0) | 1777 | if (f->fmt.sliced.service_set == 0) |
1838 | rc = -EINVAL; | 1778 | rc = -EINVAL; |
1839 | 1779 | ||
1840 | mutex_unlock(&dev->lock); | ||
1841 | |||
1842 | return rc; | 1780 | return rc; |
1843 | } | 1781 | } |
1844 | 1782 | ||
@@ -1853,9 +1791,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, | |||
1853 | if (rc < 0) | 1791 | if (rc < 0) |
1854 | return rc; | 1792 | return rc; |
1855 | 1793 | ||
1856 | mutex_lock(&dev->lock); | ||
1857 | v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced); | 1794 | v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced); |
1858 | mutex_unlock(&dev->lock); | ||
1859 | 1795 | ||
1860 | if (f->fmt.sliced.service_set == 0) | 1796 | if (f->fmt.sliced.service_set == 0) |
1861 | return -EINVAL; | 1797 | return -EINVAL; |
@@ -2040,9 +1976,7 @@ static int radio_g_tuner(struct file *file, void *priv, | |||
2040 | strcpy(t->name, "Radio"); | 1976 | strcpy(t->name, "Radio"); |
2041 | t->type = V4L2_TUNER_RADIO; | 1977 | t->type = V4L2_TUNER_RADIO; |
2042 | 1978 | ||
2043 | mutex_lock(&dev->lock); | ||
2044 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); | 1979 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); |
2045 | mutex_unlock(&dev->lock); | ||
2046 | 1980 | ||
2047 | return 0; | 1981 | return 0; |
2048 | } | 1982 | } |
@@ -2075,9 +2009,7 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
2075 | if (0 != t->index) | 2009 | if (0 != t->index) |
2076 | return -EINVAL; | 2010 | return -EINVAL; |
2077 | 2011 | ||
2078 | mutex_lock(&dev->lock); | ||
2079 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); | 2012 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); |
2080 | mutex_unlock(&dev->lock); | ||
2081 | 2013 | ||
2082 | return 0; | 2014 | return 0; |
2083 | } | 2015 | } |
@@ -2137,8 +2069,6 @@ static int em28xx_v4l2_open(struct file *filp) | |||
2137 | break; | 2069 | break; |
2138 | } | 2070 | } |
2139 | 2071 | ||
2140 | mutex_lock(&dev->lock); | ||
2141 | |||
2142 | em28xx_videodbg("open dev=%s type=%s users=%d\n", | 2072 | em28xx_videodbg("open dev=%s type=%s users=%d\n", |
2143 | video_device_node_name(vdev), v4l2_type_names[fh_type], | 2073 | video_device_node_name(vdev), v4l2_type_names[fh_type], |
2144 | dev->users); | 2074 | dev->users); |
@@ -2147,7 +2077,6 @@ static int em28xx_v4l2_open(struct file *filp) | |||
2147 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | 2077 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); |
2148 | if (!fh) { | 2078 | if (!fh) { |
2149 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); | 2079 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); |
2150 | mutex_unlock(&dev->lock); | ||
2151 | return -ENOMEM; | 2080 | return -ENOMEM; |
2152 | } | 2081 | } |
2153 | fh->dev = dev; | 2082 | fh->dev = dev; |
@@ -2181,15 +2110,13 @@ static int em28xx_v4l2_open(struct file *filp) | |||
2181 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, | 2110 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, |
2182 | NULL, &dev->slock, | 2111 | NULL, &dev->slock, |
2183 | V4L2_BUF_TYPE_VIDEO_CAPTURE, field, | 2112 | V4L2_BUF_TYPE_VIDEO_CAPTURE, field, |
2184 | sizeof(struct em28xx_buffer), fh); | 2113 | sizeof(struct em28xx_buffer), fh, &dev->lock); |
2185 | 2114 | ||
2186 | videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops, | 2115 | videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops, |
2187 | NULL, &dev->slock, | 2116 | NULL, &dev->slock, |
2188 | V4L2_BUF_TYPE_VBI_CAPTURE, | 2117 | V4L2_BUF_TYPE_VBI_CAPTURE, |
2189 | V4L2_FIELD_SEQ_TB, | 2118 | V4L2_FIELD_SEQ_TB, |
2190 | sizeof(struct em28xx_buffer), fh); | 2119 | sizeof(struct em28xx_buffer), fh, &dev->lock); |
2191 | |||
2192 | mutex_unlock(&dev->lock); | ||
2193 | 2120 | ||
2194 | return errCode; | 2121 | return errCode; |
2195 | } | 2122 | } |
@@ -2388,7 +2315,7 @@ static const struct v4l2_file_operations em28xx_v4l_fops = { | |||
2388 | .read = em28xx_v4l2_read, | 2315 | .read = em28xx_v4l2_read, |
2389 | .poll = em28xx_v4l2_poll, | 2316 | .poll = em28xx_v4l2_poll, |
2390 | .mmap = em28xx_v4l2_mmap, | 2317 | .mmap = em28xx_v4l2_mmap, |
2391 | .ioctl = video_ioctl2, | 2318 | .unlocked_ioctl = video_ioctl2, |
2392 | }; | 2319 | }; |
2393 | 2320 | ||
2394 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 2321 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
@@ -2496,6 +2423,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
2496 | vfd->v4l2_dev = &dev->v4l2_dev; | 2423 | vfd->v4l2_dev = &dev->v4l2_dev; |
2497 | vfd->release = video_device_release; | 2424 | vfd->release = video_device_release; |
2498 | vfd->debug = video_debug; | 2425 | vfd->debug = video_debug; |
2426 | vfd->lock = &dev->lock; | ||
2499 | 2427 | ||
2500 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", | 2428 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", |
2501 | dev->name, type_name); | 2429 | dev->name, type_name); |
@@ -2516,6 +2444,7 @@ int em28xx_register_analog_devices(struct em28xx *dev) | |||
2516 | 2444 | ||
2517 | /* set default norm */ | 2445 | /* set default norm */ |
2518 | dev->norm = em28xx_video_template.current_norm; | 2446 | dev->norm = em28xx_video_template.current_norm; |
2447 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | ||
2519 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | 2448 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; |
2520 | dev->ctl_input = 0; | 2449 | dev->ctl_input = 0; |
2521 | 2450 | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 1c61a6b65d2..6a75e6a4fc2 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -25,12 +25,13 @@ | |||
25 | #ifndef _EM28XX_H | 25 | #ifndef _EM28XX_H |
26 | #define _EM28XX_H | 26 | #define _EM28XX_H |
27 | 27 | ||
28 | #include <linux/workqueue.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/mutex.h> | ||
28 | #include <linux/videodev2.h> | 31 | #include <linux/videodev2.h> |
32 | |||
29 | #include <media/videobuf-vmalloc.h> | 33 | #include <media/videobuf-vmalloc.h> |
30 | #include <media/v4l2-device.h> | 34 | #include <media/v4l2-device.h> |
31 | |||
32 | #include <linux/i2c.h> | ||
33 | #include <linux/mutex.h> | ||
34 | #include <media/ir-kbd-i2c.h> | 35 | #include <media/ir-kbd-i2c.h> |
35 | #include <media/ir-core.h> | 36 | #include <media/ir-core.h> |
36 | #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) | 37 | #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) |
@@ -73,6 +74,7 @@ | |||
73 | #define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 | 74 | #define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 |
74 | #define EM2821_BOARD_USBGEAR_VD204 31 | 75 | #define EM2821_BOARD_USBGEAR_VD204 31 |
75 | #define EM2821_BOARD_SUPERCOMP_USB_2 32 | 76 | #define EM2821_BOARD_SUPERCOMP_USB_2 32 |
77 | #define EM2860_BOARD_ELGATO_VIDEO_CAPTURE 33 | ||
76 | #define EM2860_BOARD_TERRATEC_HYBRID_XS 34 | 78 | #define EM2860_BOARD_TERRATEC_HYBRID_XS 34 |
77 | #define EM2860_BOARD_TYPHOON_DVD_MAKER 35 | 79 | #define EM2860_BOARD_TYPHOON_DVD_MAKER 35 |
78 | #define EM2860_BOARD_NETGMBH_CAM 36 | 80 | #define EM2860_BOARD_NETGMBH_CAM 36 |
@@ -184,11 +186,6 @@ enum em28xx_mode { | |||
184 | EM28XX_DIGITAL_MODE, | 186 | EM28XX_DIGITAL_MODE, |
185 | }; | 187 | }; |
186 | 188 | ||
187 | enum em28xx_stream_state { | ||
188 | STREAM_OFF, | ||
189 | STREAM_INTERRUPT, | ||
190 | STREAM_ON, | ||
191 | }; | ||
192 | 189 | ||
193 | struct em28xx; | 190 | struct em28xx; |
194 | 191 | ||
@@ -463,7 +460,6 @@ struct em28xx_audio { | |||
463 | struct snd_card *sndcard; | 460 | struct snd_card *sndcard; |
464 | 461 | ||
465 | int users; | 462 | int users; |
466 | enum em28xx_stream_state capture_stream; | ||
467 | spinlock_t slock; | 463 | spinlock_t slock; |
468 | }; | 464 | }; |
469 | 465 | ||
@@ -505,6 +501,10 @@ struct em28xx { | |||
505 | unsigned int has_audio_class:1; | 501 | unsigned int has_audio_class:1; |
506 | unsigned int has_alsa_audio:1; | 502 | unsigned int has_alsa_audio:1; |
507 | 503 | ||
504 | /* Controls audio streaming */ | ||
505 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ | ||
506 | atomic_t stream_started; /* stream should be running if true */ | ||
507 | |||
508 | struct em28xx_fmt *format; | 508 | struct em28xx_fmt *format; |
509 | 509 | ||
510 | struct em28xx_IR *ir; | 510 | struct em28xx_IR *ir; |
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c index 43d208f1f58..9a075d83dd1 100644 --- a/drivers/media/video/fsl-viu.c +++ b/drivers/media/video/fsl-viu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
25 | #include <linux/slab.h> | ||
25 | #include <linux/version.h> | 26 | #include <linux/version.h> |
26 | #include <media/v4l2-common.h> | 27 | #include <media/v4l2-common.h> |
27 | #include <media/v4l2-device.h> | 28 | #include <media/v4l2-device.h> |
@@ -425,7 +426,7 @@ static void free_buffer(struct videobuf_queue *vq, struct viu_buf *buf) | |||
425 | 426 | ||
426 | BUG_ON(in_interrupt()); | 427 | BUG_ON(in_interrupt()); |
427 | 428 | ||
428 | videobuf_waiton(&buf->vb, 0, 0); | 429 | videobuf_waiton(vq, &buf->vb, 0, 0); |
429 | 430 | ||
430 | if (vq->int_ops && vq->int_ops->vaddr) | 431 | if (vq->int_ops && vq->int_ops->vaddr) |
431 | vaddr = vq->int_ops->vaddr(vb); | 432 | vaddr = vq->int_ops->vaddr(vb); |
@@ -1287,7 +1288,7 @@ static int viu_open(struct file *file) | |||
1287 | videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops, | 1288 | videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops, |
1288 | dev->dev, &fh->vbq_lock, | 1289 | dev->dev, &fh->vbq_lock, |
1289 | fh->type, V4L2_FIELD_INTERLACED, | 1290 | fh->type, V4L2_FIELD_INTERLACED, |
1290 | sizeof(struct viu_buf), fh); | 1291 | sizeof(struct viu_buf), fh, NULL); |
1291 | return 0; | 1292 | return 0; |
1292 | } | 1293 | } |
1293 | 1294 | ||
@@ -1485,7 +1486,7 @@ static int __devinit viu_of_probe(struct platform_device *op, | |||
1485 | 1486 | ||
1486 | ad = i2c_get_adapter(0); | 1487 | ad = i2c_get_adapter(0); |
1487 | viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad, | 1488 | viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad, |
1488 | "saa7115", "saa7113", VIU_VIDEO_DECODER_ADDR, NULL); | 1489 | NULL, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL); |
1489 | 1490 | ||
1490 | viu_dev->vidq.timeout.function = viu_vid_timeout; | 1491 | viu_dev->vidq.timeout.function = viu_vid_timeout; |
1491 | viu_dev->vidq.timeout.data = (unsigned long)viu_dev; | 1492 | viu_dev->vidq.timeout.data = (unsigned long)viu_dev; |
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 23db0c29f68..dda56ff834f 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
@@ -77,6 +77,15 @@ config USB_GSPCA_JEILINJ | |||
77 | To compile this driver as a module, choose M here: the | 77 | To compile this driver as a module, choose M here: the |
78 | module will be called gspca_jeilinj. | 78 | module will be called gspca_jeilinj. |
79 | 79 | ||
80 | config USB_GSPCA_KONICA | ||
81 | tristate "Konica USB Camera V4L2 driver" | ||
82 | depends on VIDEO_V4L2 && USB_GSPCA | ||
83 | help | ||
84 | Say Y here if you want support for cameras based on the Konica chip. | ||
85 | |||
86 | To compile this driver as a module, choose M here: the | ||
87 | module will be called gspca_konica. | ||
88 | |||
80 | config USB_GSPCA_MARS | 89 | config USB_GSPCA_MARS |
81 | tristate "Mars USB Camera Driver" | 90 | tristate "Mars USB Camera Driver" |
82 | depends on VIDEO_V4L2 && USB_GSPCA | 91 | depends on VIDEO_V4L2 && USB_GSPCA |
@@ -337,6 +346,15 @@ config USB_GSPCA_VC032X | |||
337 | To compile this driver as a module, choose M here: the | 346 | To compile this driver as a module, choose M here: the |
338 | module will be called gspca_vc032x. | 347 | module will be called gspca_vc032x. |
339 | 348 | ||
349 | config USB_GSPCA_XIRLINK_CIT | ||
350 | tristate "Xirlink C-It USB Camera Driver" | ||
351 | depends on VIDEO_V4L2 && USB_GSPCA | ||
352 | help | ||
353 | Say Y here if you want support for Xirlink C-It bases cameras. | ||
354 | |||
355 | To compile this driver as a module, choose M here: the | ||
356 | module will be called gspca_xirlink_cit. | ||
357 | |||
340 | config USB_GSPCA_ZC3XX | 358 | config USB_GSPCA_ZC3XX |
341 | tristate "ZC3XX USB Camera Driver" | 359 | tristate "ZC3XX USB Camera Driver" |
342 | depends on VIDEO_V4L2 && USB_GSPCA | 360 | depends on VIDEO_V4L2 && USB_GSPCA |
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index f6616db0b7f..24e695b8b07 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile | |||
@@ -5,6 +5,7 @@ obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o | |||
5 | obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o | 5 | obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o |
6 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o | 6 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o |
7 | obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o | 7 | obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o |
8 | obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o | ||
8 | obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o | 9 | obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o |
9 | obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o | 10 | obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o |
10 | obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o | 11 | obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o |
@@ -33,6 +34,7 @@ obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o | |||
33 | obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o | 34 | obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o |
34 | obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o | 35 | obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o |
35 | obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o | 36 | obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o |
37 | obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o | ||
36 | obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o | 38 | obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o |
37 | 39 | ||
38 | gspca_main-objs := gspca.o | 40 | gspca_main-objs := gspca.o |
@@ -42,6 +44,7 @@ gspca_cpia1-objs := cpia1.o | |||
42 | gspca_etoms-objs := etoms.o | 44 | gspca_etoms-objs := etoms.o |
43 | gspca_finepix-objs := finepix.o | 45 | gspca_finepix-objs := finepix.o |
44 | gspca_jeilinj-objs := jeilinj.o | 46 | gspca_jeilinj-objs := jeilinj.o |
47 | gspca_konica-objs := konica.o | ||
45 | gspca_mars-objs := mars.o | 48 | gspca_mars-objs := mars.o |
46 | gspca_mr97310a-objs := mr97310a.o | 49 | gspca_mr97310a-objs := mr97310a.o |
47 | gspca_ov519-objs := ov519.o | 50 | gspca_ov519-objs := ov519.o |
@@ -70,6 +73,7 @@ gspca_sunplus-objs := sunplus.o | |||
70 | gspca_t613-objs := t613.o | 73 | gspca_t613-objs := t613.o |
71 | gspca_tv8532-objs := tv8532.o | 74 | gspca_tv8532-objs := tv8532.o |
72 | gspca_vc032x-objs := vc032x.o | 75 | gspca_vc032x-objs := vc032x.o |
76 | gspca_xirlink_cit-objs := xirlink_cit.o | ||
73 | gspca_zc3xx-objs := zc3xx.o | 77 | gspca_zc3xx-objs := zc3xx.o |
74 | 78 | ||
75 | obj-$(CONFIG_USB_M5602) += m5602/ | 79 | obj-$(CONFIG_USB_M5602) += m5602/ |
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c index fce8d949264..62904393350 100644 --- a/drivers/media/video/gspca/benq.c +++ b/drivers/media/video/gspca/benq.c | |||
@@ -62,7 +62,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
62 | 0, | 62 | 0, |
63 | 500); | 63 | 500); |
64 | if (ret < 0) { | 64 | if (ret < 0) { |
65 | PDEBUG(D_ERR, "reg_w err %d", ret); | 65 | err("reg_w err %d", ret); |
66 | gspca_dev->usb_err = ret; | 66 | gspca_dev->usb_err = ret; |
67 | } | 67 | } |
68 | } | 68 | } |
@@ -152,7 +152,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
152 | reg_w(gspca_dev, 0x003c, 0x0005); | 152 | reg_w(gspca_dev, 0x003c, 0x0005); |
153 | reg_w(gspca_dev, 0x003c, 0x0006); | 153 | reg_w(gspca_dev, 0x003c, 0x0006); |
154 | reg_w(gspca_dev, 0x003c, 0x0007); | 154 | reg_w(gspca_dev, 0x003c, 0x0007); |
155 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->nbalt - 1); | 155 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, |
156 | gspca_dev->nbalt - 1); | ||
156 | } | 157 | } |
157 | 158 | ||
158 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 159 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
@@ -180,7 +181,7 @@ static void sd_isoc_irq(struct urb *urb) | |||
180 | if (gspca_dev->frozen) | 181 | if (gspca_dev->frozen) |
181 | return; | 182 | return; |
182 | #endif | 183 | #endif |
183 | PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); | 184 | err("urb status: %d", urb->status); |
184 | return; | 185 | return; |
185 | } | 186 | } |
186 | 187 | ||
@@ -208,8 +209,7 @@ static void sd_isoc_irq(struct urb *urb) | |||
208 | if (st == 0) | 209 | if (st == 0) |
209 | st = urb->iso_frame_desc[i].status; | 210 | st = urb->iso_frame_desc[i].status; |
210 | if (st) { | 211 | if (st) { |
211 | PDEBUG(D_ERR, | 212 | err("ISOC data error: [%d] status=%d", |
212 | "ISOC data error: [%d] status=%d", | ||
213 | i, st); | 213 | i, st); |
214 | gspca_dev->last_packet_type = DISCARD_PACKET; | 214 | gspca_dev->last_packet_type = DISCARD_PACKET; |
215 | continue; | 215 | continue; |
@@ -256,10 +256,10 @@ static void sd_isoc_irq(struct urb *urb) | |||
256 | /* resubmit the URBs */ | 256 | /* resubmit the URBs */ |
257 | st = usb_submit_urb(urb0, GFP_ATOMIC); | 257 | st = usb_submit_urb(urb0, GFP_ATOMIC); |
258 | if (st < 0) | 258 | if (st < 0) |
259 | PDEBUG(D_ERR|D_PACK, "usb_submit_urb(0) ret %d", st); | 259 | err("usb_submit_urb(0) ret %d", st); |
260 | st = usb_submit_urb(urb, GFP_ATOMIC); | 260 | st = usb_submit_urb(urb, GFP_ATOMIC); |
261 | if (st < 0) | 261 | if (st < 0) |
262 | PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); | 262 | err("usb_submit_urb() ret %d", st); |
263 | } | 263 | } |
264 | 264 | ||
265 | /* sub-driver description */ | 265 | /* sub-driver description */ |
@@ -304,18 +304,11 @@ static struct usb_driver sd_driver = { | |||
304 | /* -- module insert / remove -- */ | 304 | /* -- module insert / remove -- */ |
305 | static int __init sd_mod_init(void) | 305 | static int __init sd_mod_init(void) |
306 | { | 306 | { |
307 | int ret; | 307 | return usb_register(&sd_driver); |
308 | |||
309 | ret = usb_register(&sd_driver); | ||
310 | if (ret < 0) | ||
311 | return ret; | ||
312 | info("registered"); | ||
313 | return 0; | ||
314 | } | 308 | } |
315 | static void __exit sd_mod_exit(void) | 309 | static void __exit sd_mod_exit(void) |
316 | { | 310 | { |
317 | usb_deregister(&sd_driver); | 311 | usb_deregister(&sd_driver); |
318 | info("deregistered"); | ||
319 | } | 312 | } |
320 | 313 | ||
321 | module_init(sd_mod_init); | 314 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index d6a75772f3f..1eacb6c7926 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
@@ -687,7 +687,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) | |||
687 | reg_w_val(gspca_dev, 0x00c0, 0x00); | 687 | reg_w_val(gspca_dev, 0x00c0, 0x00); |
688 | reg_r(gspca_dev, 0x0001, 1); | 688 | reg_r(gspca_dev, 0x0001, 1); |
689 | length = 8; | 689 | length = 8; |
690 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | 690 | switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) { |
691 | case 0: | 691 | case 0: |
692 | for (i = 0; i < 27; i++) { | 692 | for (i = 0; i < 27; i++) { |
693 | if (i == 26) | 693 | if (i == 26) |
@@ -901,7 +901,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
901 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 901 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
902 | } | 902 | } |
903 | 903 | ||
904 | static void setbrightness(struct gspca_dev*gspca_dev) | 904 | static void setbrightness(struct gspca_dev *gspca_dev) |
905 | { | 905 | { |
906 | struct sd *sd = (struct sd *) gspca_dev; | 906 | struct sd *sd = (struct sd *) gspca_dev; |
907 | __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; | 907 | __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; |
@@ -924,7 +924,7 @@ static void setbrightness(struct gspca_dev*gspca_dev) | |||
924 | reg_w_val(gspca_dev, 0x0070, reg70); | 924 | reg_w_val(gspca_dev, 0x0070, reg70); |
925 | } | 925 | } |
926 | 926 | ||
927 | static void setcontrast(struct gspca_dev*gspca_dev) | 927 | static void setcontrast(struct gspca_dev *gspca_dev) |
928 | { | 928 | { |
929 | struct sd *sd = (struct sd *) gspca_dev; | 929 | struct sd *sd = (struct sd *) gspca_dev; |
930 | __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ | 930 | __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ |
@@ -1068,17 +1068,11 @@ static struct usb_driver sd_driver = { | |||
1068 | /* -- module insert / remove -- */ | 1068 | /* -- module insert / remove -- */ |
1069 | static int __init sd_mod_init(void) | 1069 | static int __init sd_mod_init(void) |
1070 | { | 1070 | { |
1071 | int ret; | 1071 | return usb_register(&sd_driver); |
1072 | ret = usb_register(&sd_driver); | ||
1073 | if (ret < 0) | ||
1074 | return ret; | ||
1075 | PDEBUG(D_PROBE, "registered"); | ||
1076 | return 0; | ||
1077 | } | 1072 | } |
1078 | static void __exit sd_mod_exit(void) | 1073 | static void __exit sd_mod_exit(void) |
1079 | { | 1074 | { |
1080 | usb_deregister(&sd_driver); | 1075 | usb_deregister(&sd_driver); |
1081 | PDEBUG(D_PROBE, "deregistered"); | ||
1082 | } | 1076 | } |
1083 | 1077 | ||
1084 | module_init(sd_mod_init); | 1078 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c index 3747a1dcff5..9b121681d13 100644 --- a/drivers/media/video/gspca/cpia1.c +++ b/drivers/media/video/gspca/cpia1.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cpia CPiA (1) gspca driver | 2 | * cpia CPiA (1) gspca driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Hans de Goede <hdgoede@redhat.com> | 4 | * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> |
5 | * | 5 | * |
6 | * This module is adapted from the in kernel v4l1 cpia driver which is : | 6 | * This module is adapted from the in kernel v4l1 cpia driver which is : |
7 | * | 7 | * |
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #include "gspca.h" | 31 | #include "gspca.h" |
32 | 32 | ||
33 | MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>"); | 33 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
34 | MODULE_DESCRIPTION("Vision CPiA"); | 34 | MODULE_DESCRIPTION("Vision CPiA"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
@@ -373,9 +373,14 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | |||
373 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 373 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
374 | static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val); | 374 | static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val); |
375 | static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val); | 375 | static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val); |
376 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val); | ||
377 | static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val); | ||
378 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val); | ||
379 | static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val); | ||
376 | 380 | ||
377 | static const struct ctrl sd_ctrls[] = { | 381 | static const struct ctrl sd_ctrls[] = { |
378 | { | 382 | { |
383 | #define BRIGHTNESS_IDX 0 | ||
379 | { | 384 | { |
380 | .id = V4L2_CID_BRIGHTNESS, | 385 | .id = V4L2_CID_BRIGHTNESS, |
381 | .type = V4L2_CTRL_TYPE_INTEGER, | 386 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -390,6 +395,7 @@ static const struct ctrl sd_ctrls[] = { | |||
390 | .set = sd_setbrightness, | 395 | .set = sd_setbrightness, |
391 | .get = sd_getbrightness, | 396 | .get = sd_getbrightness, |
392 | }, | 397 | }, |
398 | #define CONTRAST_IDX 1 | ||
393 | { | 399 | { |
394 | { | 400 | { |
395 | .id = V4L2_CID_CONTRAST, | 401 | .id = V4L2_CID_CONTRAST, |
@@ -404,6 +410,7 @@ static const struct ctrl sd_ctrls[] = { | |||
404 | .set = sd_setcontrast, | 410 | .set = sd_setcontrast, |
405 | .get = sd_getcontrast, | 411 | .get = sd_getcontrast, |
406 | }, | 412 | }, |
413 | #define SATURATION_IDX 2 | ||
407 | { | 414 | { |
408 | { | 415 | { |
409 | .id = V4L2_CID_SATURATION, | 416 | .id = V4L2_CID_SATURATION, |
@@ -418,6 +425,7 @@ static const struct ctrl sd_ctrls[] = { | |||
418 | .set = sd_setsaturation, | 425 | .set = sd_setsaturation, |
419 | .get = sd_getsaturation, | 426 | .get = sd_getsaturation, |
420 | }, | 427 | }, |
428 | #define POWER_LINE_FREQUENCY_IDX 3 | ||
421 | { | 429 | { |
422 | { | 430 | { |
423 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 431 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
@@ -432,6 +440,37 @@ static const struct ctrl sd_ctrls[] = { | |||
432 | .set = sd_setfreq, | 440 | .set = sd_setfreq, |
433 | .get = sd_getfreq, | 441 | .get = sd_getfreq, |
434 | }, | 442 | }, |
443 | #define ILLUMINATORS_1_IDX 4 | ||
444 | { | ||
445 | { | ||
446 | .id = V4L2_CID_ILLUMINATORS_1, | ||
447 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
448 | .name = "Illuminator 1", | ||
449 | .minimum = 0, | ||
450 | .maximum = 1, | ||
451 | .step = 1, | ||
452 | #define ILLUMINATORS_1_DEF 0 | ||
453 | .default_value = ILLUMINATORS_1_DEF, | ||
454 | }, | ||
455 | .set = sd_setilluminator1, | ||
456 | .get = sd_getilluminator1, | ||
457 | }, | ||
458 | #define ILLUMINATORS_2_IDX 5 | ||
459 | { | ||
460 | { | ||
461 | .id = V4L2_CID_ILLUMINATORS_2, | ||
462 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
463 | .name = "Illuminator 2", | ||
464 | .minimum = 0, | ||
465 | .maximum = 1, | ||
466 | .step = 1, | ||
467 | #define ILLUMINATORS_2_DEF 0 | ||
468 | .default_value = ILLUMINATORS_2_DEF, | ||
469 | }, | ||
470 | .set = sd_setilluminator2, | ||
471 | .get = sd_getilluminator2, | ||
472 | }, | ||
473 | #define COMP_TARGET_IDX 6 | ||
435 | { | 474 | { |
436 | { | 475 | { |
437 | #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE | 476 | #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE |
@@ -510,7 +549,7 @@ retry: | |||
510 | gspca_dev->usb_buf, databytes, 1000); | 549 | gspca_dev->usb_buf, databytes, 1000); |
511 | 550 | ||
512 | if (ret < 0) | 551 | if (ret < 0) |
513 | PDEBUG(D_ERR, "usb_control_msg %02x, error %d", command[1], | 552 | err("usb_control_msg %02x, error %d", command[1], |
514 | ret); | 553 | ret); |
515 | 554 | ||
516 | if (ret == -EPIPE && retries > 0) { | 555 | if (ret == -EPIPE && retries > 0) { |
@@ -1059,7 +1098,6 @@ static int command_resume(struct gspca_dev *gspca_dev) | |||
1059 | 0, sd->params.streamStartLine, 0, 0); | 1098 | 0, sd->params.streamStartLine, 0, 0); |
1060 | } | 1099 | } |
1061 | 1100 | ||
1062 | #if 0 /* Currently unused */ | ||
1063 | static int command_setlights(struct gspca_dev *gspca_dev) | 1101 | static int command_setlights(struct gspca_dev *gspca_dev) |
1064 | { | 1102 | { |
1065 | struct sd *sd = (struct sd *) gspca_dev; | 1103 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -1079,7 +1117,6 @@ static int command_setlights(struct gspca_dev *gspca_dev) | |||
1079 | return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0, | 1117 | return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0, |
1080 | p1 | p2 | 0xE0, 0); | 1118 | p1 | p2 | 0xE0, 0); |
1081 | } | 1119 | } |
1082 | #endif | ||
1083 | 1120 | ||
1084 | static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) | 1121 | static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) |
1085 | { | 1122 | { |
@@ -1236,7 +1273,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev) | |||
1236 | cmd[7] = 0; | 1273 | cmd[7] = 0; |
1237 | ret = cpia_usb_transferCmd(gspca_dev, cmd); | 1274 | ret = cpia_usb_transferCmd(gspca_dev, cmd); |
1238 | if (ret) { | 1275 | if (ret) { |
1239 | PDEBUG(D_ERR, "ReadVPRegs(30,4,9,8) - failed: %d", ret); | 1276 | err("ReadVPRegs(30,4,9,8) - failed: %d", ret); |
1240 | return; | 1277 | return; |
1241 | } | 1278 | } |
1242 | exp_acc = gspca_dev->usb_buf[0]; | 1279 | exp_acc = gspca_dev->usb_buf[0]; |
@@ -1716,7 +1753,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1716 | /* this function is called at probe and resume time */ | 1753 | /* this function is called at probe and resume time */ |
1717 | static int sd_init(struct gspca_dev *gspca_dev) | 1754 | static int sd_init(struct gspca_dev *gspca_dev) |
1718 | { | 1755 | { |
1756 | #ifdef GSPCA_DEBUG | ||
1719 | struct sd *sd = (struct sd *) gspca_dev; | 1757 | struct sd *sd = (struct sd *) gspca_dev; |
1758 | #endif | ||
1720 | int ret; | 1759 | int ret; |
1721 | 1760 | ||
1722 | /* Start / Stop the camera to make sure we are talking to | 1761 | /* Start / Stop the camera to make sure we are talking to |
@@ -1726,6 +1765,14 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1726 | if (ret) | 1765 | if (ret) |
1727 | return ret; | 1766 | return ret; |
1728 | 1767 | ||
1768 | /* Ensure the QX3 illuminators' states are restored upon resume, | ||
1769 | or disable the illuminator controls, if this isn't a QX3 */ | ||
1770 | if (sd->params.qx3.qx3_detected) | ||
1771 | command_setlights(gspca_dev); | ||
1772 | else | ||
1773 | gspca_dev->ctrl_dis |= | ||
1774 | ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX)); | ||
1775 | |||
1729 | sd_stopN(gspca_dev); | 1776 | sd_stopN(gspca_dev); |
1730 | 1777 | ||
1731 | PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)", | 1778 | PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)", |
@@ -1929,6 +1976,72 @@ static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val) | |||
1929 | return 0; | 1976 | return 0; |
1930 | } | 1977 | } |
1931 | 1978 | ||
1979 | static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n) | ||
1980 | { | ||
1981 | struct sd *sd = (struct sd *) gspca_dev; | ||
1982 | int ret; | ||
1983 | |||
1984 | if (!sd->params.qx3.qx3_detected) | ||
1985 | return -EINVAL; | ||
1986 | |||
1987 | switch (n) { | ||
1988 | case 1: | ||
1989 | sd->params.qx3.bottomlight = val ? 1 : 0; | ||
1990 | break; | ||
1991 | case 2: | ||
1992 | sd->params.qx3.toplight = val ? 1 : 0; | ||
1993 | break; | ||
1994 | default: | ||
1995 | return -EINVAL; | ||
1996 | } | ||
1997 | |||
1998 | ret = command_setlights(gspca_dev); | ||
1999 | if (ret && ret != -EINVAL) | ||
2000 | ret = -EBUSY; | ||
2001 | |||
2002 | return ret; | ||
2003 | } | ||
2004 | |||
2005 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val) | ||
2006 | { | ||
2007 | return sd_setilluminator(gspca_dev, val, 1); | ||
2008 | } | ||
2009 | |||
2010 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val) | ||
2011 | { | ||
2012 | return sd_setilluminator(gspca_dev, val, 2); | ||
2013 | } | ||
2014 | |||
2015 | static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n) | ||
2016 | { | ||
2017 | struct sd *sd = (struct sd *) gspca_dev; | ||
2018 | |||
2019 | if (!sd->params.qx3.qx3_detected) | ||
2020 | return -EINVAL; | ||
2021 | |||
2022 | switch (n) { | ||
2023 | case 1: | ||
2024 | *val = sd->params.qx3.bottomlight; | ||
2025 | break; | ||
2026 | case 2: | ||
2027 | *val = sd->params.qx3.toplight; | ||
2028 | break; | ||
2029 | default: | ||
2030 | return -EINVAL; | ||
2031 | } | ||
2032 | return 0; | ||
2033 | } | ||
2034 | |||
2035 | static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val) | ||
2036 | { | ||
2037 | return sd_getilluminator(gspca_dev, val, 1); | ||
2038 | } | ||
2039 | |||
2040 | static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val) | ||
2041 | { | ||
2042 | return sd_getilluminator(gspca_dev, val, 2); | ||
2043 | } | ||
2044 | |||
1932 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 2045 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
1933 | struct v4l2_querymenu *menu) | 2046 | struct v4l2_querymenu *menu) |
1934 | { | 2047 | { |
@@ -2004,17 +2117,11 @@ static struct usb_driver sd_driver = { | |||
2004 | /* -- module insert / remove -- */ | 2117 | /* -- module insert / remove -- */ |
2005 | static int __init sd_mod_init(void) | 2118 | static int __init sd_mod_init(void) |
2006 | { | 2119 | { |
2007 | int ret; | 2120 | return usb_register(&sd_driver); |
2008 | ret = usb_register(&sd_driver); | ||
2009 | if (ret < 0) | ||
2010 | return ret; | ||
2011 | PDEBUG(D_PROBE, "registered"); | ||
2012 | return 0; | ||
2013 | } | 2121 | } |
2014 | static void __exit sd_mod_exit(void) | 2122 | static void __exit sd_mod_exit(void) |
2015 | { | 2123 | { |
2016 | usb_deregister(&sd_driver); | 2124 | usb_deregister(&sd_driver); |
2017 | PDEBUG(D_PROBE, "deregistered"); | ||
2018 | } | 2125 | } |
2019 | 2126 | ||
2020 | module_init(sd_mod_init); | 2127 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index ecd4d743d2b..a594b36d619 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -710,9 +710,9 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) | |||
710 | } | 710 | } |
711 | 711 | ||
712 | #define BLIMIT(bright) \ | 712 | #define BLIMIT(bright) \ |
713 | (__u8)((bright > 0x1f)?0x1f:((bright < 4)?3:bright)) | 713 | (u8)((bright > 0x1f) ? 0x1f : ((bright < 4) ? 3 : bright)) |
714 | #define LIMIT(color) \ | 714 | #define LIMIT(color) \ |
715 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) | 715 | (u8)((color > 0xff) ? 0xff : ((color < 0) ? 0 : color)) |
716 | 716 | ||
717 | static void do_autogain(struct gspca_dev *gspca_dev) | 717 | static void do_autogain(struct gspca_dev *gspca_dev) |
718 | { | 718 | { |
@@ -896,18 +896,12 @@ static struct usb_driver sd_driver = { | |||
896 | /* -- module insert / remove -- */ | 896 | /* -- module insert / remove -- */ |
897 | static int __init sd_mod_init(void) | 897 | static int __init sd_mod_init(void) |
898 | { | 898 | { |
899 | int ret; | 899 | return usb_register(&sd_driver); |
900 | ret = usb_register(&sd_driver); | ||
901 | if (ret < 0) | ||
902 | return ret; | ||
903 | PDEBUG(D_PROBE, "registered"); | ||
904 | return 0; | ||
905 | } | 900 | } |
906 | 901 | ||
907 | static void __exit sd_mod_exit(void) | 902 | static void __exit sd_mod_exit(void) |
908 | { | 903 | { |
909 | usb_deregister(&sd_driver); | 904 | usb_deregister(&sd_driver); |
910 | PDEBUG(D_PROBE, "deregistered"); | ||
911 | } | 905 | } |
912 | 906 | ||
913 | module_init(sd_mod_init); | 907 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 5d90e744857..d78226455d1 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c | |||
@@ -182,7 +182,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
182 | /* Init the device */ | 182 | /* Init the device */ |
183 | ret = command(gspca_dev, 0); | 183 | ret = command(gspca_dev, 0); |
184 | if (ret < 0) { | 184 | if (ret < 0) { |
185 | PDEBUG(D_STREAM, "init failed %d", ret); | 185 | err("init failed %d", ret); |
186 | return ret; | 186 | return ret; |
187 | } | 187 | } |
188 | 188 | ||
@@ -194,14 +194,14 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
194 | FPIX_MAX_TRANSFER, &len, | 194 | FPIX_MAX_TRANSFER, &len, |
195 | FPIX_TIMEOUT); | 195 | FPIX_TIMEOUT); |
196 | if (ret < 0) { | 196 | if (ret < 0) { |
197 | PDEBUG(D_STREAM, "usb_bulk_msg failed %d", ret); | 197 | err("usb_bulk_msg failed %d", ret); |
198 | return ret; | 198 | return ret; |
199 | } | 199 | } |
200 | 200 | ||
201 | /* Request a frame, but don't read it */ | 201 | /* Request a frame, but don't read it */ |
202 | ret = command(gspca_dev, 1); | 202 | ret = command(gspca_dev, 1); |
203 | if (ret < 0) { | 203 | if (ret < 0) { |
204 | PDEBUG(D_STREAM, "frame request failed %d", ret); | 204 | err("frame request failed %d", ret); |
205 | return ret; | 205 | return ret; |
206 | } | 206 | } |
207 | 207 | ||
@@ -291,19 +291,12 @@ static struct usb_driver sd_driver = { | |||
291 | /* -- module insert / remove -- */ | 291 | /* -- module insert / remove -- */ |
292 | static int __init sd_mod_init(void) | 292 | static int __init sd_mod_init(void) |
293 | { | 293 | { |
294 | int ret; | 294 | return usb_register(&sd_driver); |
295 | |||
296 | ret = usb_register(&sd_driver); | ||
297 | if (ret < 0) | ||
298 | return ret; | ||
299 | PDEBUG(D_PROBE, "registered"); | ||
300 | return 0; | ||
301 | } | 295 | } |
302 | 296 | ||
303 | static void __exit sd_mod_exit(void) | 297 | static void __exit sd_mod_exit(void) |
304 | { | 298 | { |
305 | usb_deregister(&sd_driver); | 299 | usb_deregister(&sd_driver); |
306 | PDEBUG(D_PROBE, "deregistered"); | ||
307 | } | 300 | } |
308 | 301 | ||
309 | module_init(sd_mod_init); | 302 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c index 57782e011c9..2edda6b7d65 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi2020.c +++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c | |||
@@ -69,15 +69,15 @@ static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 }; | |||
69 | static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; | 69 | static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; |
70 | 70 | ||
71 | static struct validx tbl_init_at_startup[] = { | 71 | static struct validx tbl_init_at_startup[] = { |
72 | {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001,0x00c1}, | 72 | {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, |
73 | {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, | 73 | {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, |
74 | {53, 0xffff}, | 74 | {53, 0xffff}, |
75 | {0x0040, 0x0000}, {0x0063, 0x0006}, | 75 | {0x0040, 0x0000}, {0x0063, 0x0006}, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct validx tbl_common_0B[] = { | 78 | static struct validx tbl_common_0B[] = { |
79 | {0x0002, 0x0004}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a,0x000d}, | 79 | {0x0002, 0x0004}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, |
80 | {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042,0x00c2}, | 80 | {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, |
81 | {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, | 81 | {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, |
82 | }; | 82 | }; |
83 | 83 | ||
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index e86eb8b4aed..b05bec7321b 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c | |||
@@ -540,15 +540,12 @@ static int __init sd_mod_init(void) | |||
540 | 540 | ||
541 | if (usb_register(&sd_driver) < 0) | 541 | if (usb_register(&sd_driver) < 0) |
542 | return -1; | 542 | return -1; |
543 | PDEBUG(D_PROBE, "driver registered"); | ||
544 | |||
545 | return 0; | 543 | return 0; |
546 | } | 544 | } |
547 | 545 | ||
548 | static void __exit sd_mod_exit(void) | 546 | static void __exit sd_mod_exit(void) |
549 | { | 547 | { |
550 | usb_deregister(&sd_driver); | 548 | usb_deregister(&sd_driver); |
551 | PDEBUG(D_PROBE, "driver deregistered"); | ||
552 | } | 549 | } |
553 | 550 | ||
554 | module_init(sd_mod_init); | 551 | module_init(sd_mod_init); |
@@ -588,8 +585,7 @@ int gl860_RTx(struct gspca_dev *gspca_dev, | |||
588 | } | 585 | } |
589 | 586 | ||
590 | if (r < 0) | 587 | if (r < 0) |
591 | PDEBUG(D_ERR, | 588 | err("ctrl transfer failed %4d " |
592 | "ctrl transfer failed %4d " | ||
593 | "[p%02x r%d v%04x i%04x len%d]", | 589 | "[p%02x r%d v%04x i%04x len%d]", |
594 | r, pref, req, val, index, len); | 590 | r, pref, req, val, index, len); |
595 | else if (len > 1 && r < len) | 591 | else if (len > 1 && r < len) |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 78abc1c1f9d..8fe8fb486d6 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -148,7 +148,7 @@ static void int_irq(struct urb *urb) | |||
148 | if (ret == 0) { | 148 | if (ret == 0) { |
149 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 149 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
150 | if (ret < 0) | 150 | if (ret < 0) |
151 | PDEBUG(D_ERR, "Resubmit URB failed with error %i", ret); | 151 | err("Resubmit URB failed with error %i", ret); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
@@ -177,8 +177,8 @@ static int gspca_input_connect(struct gspca_dev *dev) | |||
177 | 177 | ||
178 | err = input_register_device(input_dev); | 178 | err = input_register_device(input_dev); |
179 | if (err) { | 179 | if (err) { |
180 | PDEBUG(D_ERR, "Input device registration failed " | 180 | err("Input device registration failed with error %i", |
181 | "with error %i", err); | 181 | err); |
182 | input_dev->dev.parent = NULL; | 182 | input_dev->dev.parent = NULL; |
183 | input_free_device(input_dev); | 183 | input_free_device(input_dev); |
184 | } else { | 184 | } else { |
@@ -328,8 +328,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
328 | } | 328 | } |
329 | st = urb->iso_frame_desc[i].status; | 329 | st = urb->iso_frame_desc[i].status; |
330 | if (st) { | 330 | if (st) { |
331 | PDEBUG(D_ERR, | 331 | err("ISOC data error: [%d] len=%d, status=%d", |
332 | "ISOC data error: [%d] len=%d, status=%d", | ||
333 | i, len, st); | 332 | i, len, st); |
334 | gspca_dev->last_packet_type = DISCARD_PACKET; | 333 | gspca_dev->last_packet_type = DISCARD_PACKET; |
335 | continue; | 334 | continue; |
@@ -347,7 +346,7 @@ resubmit: | |||
347 | /* resubmit the URB */ | 346 | /* resubmit the URB */ |
348 | st = usb_submit_urb(urb, GFP_ATOMIC); | 347 | st = usb_submit_urb(urb, GFP_ATOMIC); |
349 | if (st < 0) | 348 | if (st < 0) |
350 | PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); | 349 | err("usb_submit_urb() ret %d", st); |
351 | } | 350 | } |
352 | 351 | ||
353 | /* | 352 | /* |
@@ -401,7 +400,7 @@ resubmit: | |||
401 | if (gspca_dev->cam.bulk_nurbs != 0) { | 400 | if (gspca_dev->cam.bulk_nurbs != 0) { |
402 | st = usb_submit_urb(urb, GFP_ATOMIC); | 401 | st = usb_submit_urb(urb, GFP_ATOMIC); |
403 | if (st < 0) | 402 | if (st < 0) |
404 | PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); | 403 | err("usb_submit_urb() ret %d", st); |
405 | } | 404 | } |
406 | } | 405 | } |
407 | 406 | ||
@@ -433,12 +432,13 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, | |||
433 | /* if there are no queued buffer, discard the whole frame */ | 432 | /* if there are no queued buffer, discard the whole frame */ |
434 | if (i == atomic_read(&gspca_dev->fr_q)) { | 433 | if (i == atomic_read(&gspca_dev->fr_q)) { |
435 | gspca_dev->last_packet_type = DISCARD_PACKET; | 434 | gspca_dev->last_packet_type = DISCARD_PACKET; |
435 | gspca_dev->sequence++; | ||
436 | return; | 436 | return; |
437 | } | 437 | } |
438 | j = gspca_dev->fr_queue[i]; | 438 | j = gspca_dev->fr_queue[i]; |
439 | frame = &gspca_dev->frame[j]; | 439 | frame = &gspca_dev->frame[j]; |
440 | frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); | 440 | frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); |
441 | frame->v4l2_buf.sequence = ++gspca_dev->sequence; | 441 | frame->v4l2_buf.sequence = gspca_dev->sequence++; |
442 | gspca_dev->image = frame->data; | 442 | gspca_dev->image = frame->data; |
443 | gspca_dev->image_len = 0; | 443 | gspca_dev->image_len = 0; |
444 | } else { | 444 | } else { |
@@ -590,7 +590,7 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) | |||
590 | return 0; | 590 | return 0; |
591 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | 591 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); |
592 | if (ret < 0) | 592 | if (ret < 0) |
593 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | 593 | err("set alt 0 err %d", ret); |
594 | return ret; | 594 | return ret; |
595 | } | 595 | } |
596 | 596 | ||
@@ -652,7 +652,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
652 | : USB_ENDPOINT_XFER_ISOC; | 652 | : USB_ENDPOINT_XFER_ISOC; |
653 | i = gspca_dev->alt; /* previous alt setting */ | 653 | i = gspca_dev->alt; /* previous alt setting */ |
654 | if (gspca_dev->cam.reverse_alts) { | 654 | if (gspca_dev->cam.reverse_alts) { |
655 | if (gspca_dev->audio) | 655 | if (gspca_dev->audio && i < gspca_dev->nbalt - 2) |
656 | i++; | 656 | i++; |
657 | while (++i < gspca_dev->nbalt) { | 657 | while (++i < gspca_dev->nbalt) { |
658 | ep = alt_xfer(&intf->altsetting[i], xfer); | 658 | ep = alt_xfer(&intf->altsetting[i], xfer); |
@@ -660,7 +660,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
660 | break; | 660 | break; |
661 | } | 661 | } |
662 | } else { | 662 | } else { |
663 | if (gspca_dev->audio) | 663 | if (gspca_dev->audio && i > 1) |
664 | i--; | 664 | i--; |
665 | while (--i >= 0) { | 665 | while (--i >= 0) { |
666 | ep = alt_xfer(&intf->altsetting[i], xfer); | 666 | ep = alt_xfer(&intf->altsetting[i], xfer); |
@@ -850,8 +850,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
850 | break; | 850 | break; |
851 | gspca_stream_off(gspca_dev); | 851 | gspca_stream_off(gspca_dev); |
852 | if (ret != -ENOSPC) { | 852 | if (ret != -ENOSPC) { |
853 | PDEBUG(D_ERR|D_STREAM, | 853 | err("usb_submit_urb alt %d err %d", |
854 | "usb_submit_urb alt %d err %d", | ||
855 | gspca_dev->alt, ret); | 854 | gspca_dev->alt, ret); |
856 | goto out; | 855 | goto out; |
857 | } | 856 | } |
@@ -880,6 +879,7 @@ out: | |||
880 | 879 | ||
881 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | 880 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) |
882 | { | 881 | { |
882 | struct gspca_ctrl *ctrl; | ||
883 | int i; | 883 | int i; |
884 | 884 | ||
885 | i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ | 885 | i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ |
@@ -887,6 +887,16 @@ static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | |||
887 | gspca_dev->width = gspca_dev->cam.cam_mode[i].width; | 887 | gspca_dev->width = gspca_dev->cam.cam_mode[i].width; |
888 | gspca_dev->height = gspca_dev->cam.cam_mode[i].height; | 888 | gspca_dev->height = gspca_dev->cam.cam_mode[i].height; |
889 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; | 889 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; |
890 | |||
891 | /* set the current control values to their default values | ||
892 | * which may have changed in sd_init() */ | ||
893 | ctrl = gspca_dev->cam.ctrls; | ||
894 | if (ctrl != NULL) { | ||
895 | for (i = 0; | ||
896 | i < gspca_dev->sd_desc->nctrls; | ||
897 | i++, ctrl++) | ||
898 | ctrl->val = ctrl->def; | ||
899 | } | ||
890 | } | 900 | } |
891 | 901 | ||
892 | static int wxh_to_mode(struct gspca_dev *gspca_dev, | 902 | static int wxh_to_mode(struct gspca_dev *gspca_dev, |
@@ -1310,7 +1320,7 @@ out: | |||
1310 | return ret; | 1320 | return ret; |
1311 | } | 1321 | } |
1312 | 1322 | ||
1313 | static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev, | 1323 | static int get_ctrl(struct gspca_dev *gspca_dev, |
1314 | int id) | 1324 | int id) |
1315 | { | 1325 | { |
1316 | const struct ctrl *ctrls; | 1326 | const struct ctrl *ctrls; |
@@ -1322,9 +1332,9 @@ static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev, | |||
1322 | if (gspca_dev->ctrl_dis & (1 << i)) | 1332 | if (gspca_dev->ctrl_dis & (1 << i)) |
1323 | continue; | 1333 | continue; |
1324 | if (id == ctrls->qctrl.id) | 1334 | if (id == ctrls->qctrl.id) |
1325 | return ctrls; | 1335 | return i; |
1326 | } | 1336 | } |
1327 | return NULL; | 1337 | return -1; |
1328 | } | 1338 | } |
1329 | 1339 | ||
1330 | static int vidioc_queryctrl(struct file *file, void *priv, | 1340 | static int vidioc_queryctrl(struct file *file, void *priv, |
@@ -1332,34 +1342,40 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
1332 | { | 1342 | { |
1333 | struct gspca_dev *gspca_dev = priv; | 1343 | struct gspca_dev *gspca_dev = priv; |
1334 | const struct ctrl *ctrls; | 1344 | const struct ctrl *ctrls; |
1335 | int i; | 1345 | struct gspca_ctrl *gspca_ctrl; |
1346 | int i, idx; | ||
1336 | u32 id; | 1347 | u32 id; |
1337 | 1348 | ||
1338 | ctrls = NULL; | ||
1339 | id = q_ctrl->id; | 1349 | id = q_ctrl->id; |
1340 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | 1350 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { |
1341 | id &= V4L2_CTRL_ID_MASK; | 1351 | id &= V4L2_CTRL_ID_MASK; |
1342 | id++; | 1352 | id++; |
1353 | idx = -1; | ||
1343 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 1354 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
1344 | if (gspca_dev->ctrl_dis & (1 << i)) | 1355 | if (gspca_dev->ctrl_dis & (1 << i)) |
1345 | continue; | 1356 | continue; |
1346 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) | 1357 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) |
1347 | continue; | 1358 | continue; |
1348 | if (ctrls && gspca_dev->sd_desc->ctrls[i].qctrl.id | 1359 | if (idx >= 0 |
1349 | > ctrls->qctrl.id) | 1360 | && gspca_dev->sd_desc->ctrls[i].qctrl.id |
1361 | > gspca_dev->sd_desc->ctrls[idx].qctrl.id) | ||
1350 | continue; | 1362 | continue; |
1351 | ctrls = &gspca_dev->sd_desc->ctrls[i]; | 1363 | idx = i; |
1352 | } | 1364 | } |
1353 | if (ctrls == NULL) | ||
1354 | return -EINVAL; | ||
1355 | } else { | 1365 | } else { |
1356 | ctrls = get_ctrl(gspca_dev, id); | 1366 | idx = get_ctrl(gspca_dev, id); |
1357 | if (ctrls == NULL) | ||
1358 | return -EINVAL; | ||
1359 | i = ctrls - gspca_dev->sd_desc->ctrls; | ||
1360 | } | 1367 | } |
1361 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); | 1368 | if (idx < 0) |
1362 | if (gspca_dev->ctrl_inac & (1 << i)) | 1369 | return -EINVAL; |
1370 | ctrls = &gspca_dev->sd_desc->ctrls[idx]; | ||
1371 | memcpy(q_ctrl, &ctrls->qctrl, sizeof *q_ctrl); | ||
1372 | if (gspca_dev->cam.ctrls != NULL) { | ||
1373 | gspca_ctrl = &gspca_dev->cam.ctrls[idx]; | ||
1374 | q_ctrl->default_value = gspca_ctrl->def; | ||
1375 | q_ctrl->minimum = gspca_ctrl->min; | ||
1376 | q_ctrl->maximum = gspca_ctrl->max; | ||
1377 | } | ||
1378 | if (gspca_dev->ctrl_inac & (1 << idx)) | ||
1363 | q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | 1379 | q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; |
1364 | return 0; | 1380 | return 0; |
1365 | } | 1381 | } |
@@ -1369,23 +1385,46 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1369 | { | 1385 | { |
1370 | struct gspca_dev *gspca_dev = priv; | 1386 | struct gspca_dev *gspca_dev = priv; |
1371 | const struct ctrl *ctrls; | 1387 | const struct ctrl *ctrls; |
1372 | int ret; | 1388 | struct gspca_ctrl *gspca_ctrl; |
1389 | int idx, ret; | ||
1373 | 1390 | ||
1374 | ctrls = get_ctrl(gspca_dev, ctrl->id); | 1391 | idx = get_ctrl(gspca_dev, ctrl->id); |
1375 | if (ctrls == NULL) | 1392 | if (idx < 0) |
1376 | return -EINVAL; | 1393 | return -EINVAL; |
1377 | 1394 | if (gspca_dev->ctrl_inac & (1 << idx)) | |
1378 | if (ctrl->value < ctrls->qctrl.minimum | 1395 | return -EINVAL; |
1379 | || ctrl->value > ctrls->qctrl.maximum) | 1396 | ctrls = &gspca_dev->sd_desc->ctrls[idx]; |
1380 | return -ERANGE; | 1397 | if (gspca_dev->cam.ctrls != NULL) { |
1398 | gspca_ctrl = &gspca_dev->cam.ctrls[idx]; | ||
1399 | if (ctrl->value < gspca_ctrl->min | ||
1400 | || ctrl->value > gspca_ctrl->max) | ||
1401 | return -ERANGE; | ||
1402 | } else { | ||
1403 | gspca_ctrl = NULL; | ||
1404 | if (ctrl->value < ctrls->qctrl.minimum | ||
1405 | || ctrl->value > ctrls->qctrl.maximum) | ||
1406 | return -ERANGE; | ||
1407 | } | ||
1381 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 1408 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
1382 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1409 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1383 | return -ERESTARTSYS; | 1410 | return -ERESTARTSYS; |
1411 | if (!gspca_dev->present) { | ||
1412 | ret = -ENODEV; | ||
1413 | goto out; | ||
1414 | } | ||
1384 | gspca_dev->usb_err = 0; | 1415 | gspca_dev->usb_err = 0; |
1385 | if (gspca_dev->present) | 1416 | if (ctrls->set != NULL) { |
1386 | ret = ctrls->set(gspca_dev, ctrl->value); | 1417 | ret = ctrls->set(gspca_dev, ctrl->value); |
1387 | else | 1418 | goto out; |
1388 | ret = -ENODEV; | 1419 | } |
1420 | if (gspca_ctrl != NULL) { | ||
1421 | gspca_ctrl->val = ctrl->value; | ||
1422 | if (ctrls->set_control != NULL | ||
1423 | && gspca_dev->streaming) | ||
1424 | ctrls->set_control(gspca_dev); | ||
1425 | } | ||
1426 | ret = gspca_dev->usb_err; | ||
1427 | out: | ||
1389 | mutex_unlock(&gspca_dev->usb_lock); | 1428 | mutex_unlock(&gspca_dev->usb_lock); |
1390 | return ret; | 1429 | return ret; |
1391 | } | 1430 | } |
@@ -1395,19 +1434,28 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1395 | { | 1434 | { |
1396 | struct gspca_dev *gspca_dev = priv; | 1435 | struct gspca_dev *gspca_dev = priv; |
1397 | const struct ctrl *ctrls; | 1436 | const struct ctrl *ctrls; |
1398 | int ret; | 1437 | int idx, ret; |
1399 | 1438 | ||
1400 | ctrls = get_ctrl(gspca_dev, ctrl->id); | 1439 | idx = get_ctrl(gspca_dev, ctrl->id); |
1401 | if (ctrls == NULL) | 1440 | if (idx < 0) |
1402 | return -EINVAL; | 1441 | return -EINVAL; |
1442 | ctrls = &gspca_dev->sd_desc->ctrls[idx]; | ||
1403 | 1443 | ||
1404 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1444 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1405 | return -ERESTARTSYS; | 1445 | return -ERESTARTSYS; |
1446 | if (!gspca_dev->present) { | ||
1447 | ret = -ENODEV; | ||
1448 | goto out; | ||
1449 | } | ||
1406 | gspca_dev->usb_err = 0; | 1450 | gspca_dev->usb_err = 0; |
1407 | if (gspca_dev->present) | 1451 | if (ctrls->get != NULL) { |
1408 | ret = ctrls->get(gspca_dev, &ctrl->value); | 1452 | ret = ctrls->get(gspca_dev, &ctrl->value); |
1409 | else | 1453 | goto out; |
1410 | ret = -ENODEV; | 1454 | } |
1455 | if (gspca_dev->cam.ctrls != NULL) | ||
1456 | ctrl->value = gspca_dev->cam.ctrls[idx].val; | ||
1457 | ret = 0; | ||
1458 | out: | ||
1411 | mutex_unlock(&gspca_dev->usb_lock); | 1459 | mutex_unlock(&gspca_dev->usb_lock); |
1412 | return ret; | 1460 | return ret; |
1413 | } | 1461 | } |
@@ -2127,6 +2175,22 @@ static struct video_device gspca_template = { | |||
2127 | .release = gspca_release, | 2175 | .release = gspca_release, |
2128 | }; | 2176 | }; |
2129 | 2177 | ||
2178 | /* initialize the controls */ | ||
2179 | static void ctrls_init(struct gspca_dev *gspca_dev) | ||
2180 | { | ||
2181 | struct gspca_ctrl *ctrl; | ||
2182 | int i; | ||
2183 | |||
2184 | for (i = 0, ctrl = gspca_dev->cam.ctrls; | ||
2185 | i < gspca_dev->sd_desc->nctrls; | ||
2186 | i++, ctrl++) { | ||
2187 | ctrl->def = gspca_dev->sd_desc->ctrls[i].qctrl.default_value; | ||
2188 | ctrl->val = ctrl->def; | ||
2189 | ctrl->min = gspca_dev->sd_desc->ctrls[i].qctrl.minimum; | ||
2190 | ctrl->max = gspca_dev->sd_desc->ctrls[i].qctrl.maximum; | ||
2191 | } | ||
2192 | } | ||
2193 | |||
2130 | /* | 2194 | /* |
2131 | * probe and create a new gspca device | 2195 | * probe and create a new gspca device |
2132 | * | 2196 | * |
@@ -2188,6 +2252,8 @@ int gspca_dev_probe2(struct usb_interface *intf, | |||
2188 | ret = sd_desc->config(gspca_dev, id); | 2252 | ret = sd_desc->config(gspca_dev, id); |
2189 | if (ret < 0) | 2253 | if (ret < 0) |
2190 | goto out; | 2254 | goto out; |
2255 | if (gspca_dev->cam.ctrls != NULL) | ||
2256 | ctrls_init(gspca_dev); | ||
2191 | ret = sd_desc->init(gspca_dev); | 2257 | ret = sd_desc->init(gspca_dev); |
2192 | if (ret < 0) | 2258 | if (ret < 0) |
2193 | goto out; | 2259 | goto out; |
@@ -2243,7 +2309,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2243 | 2309 | ||
2244 | /* we don't handle multi-config cameras */ | 2310 | /* we don't handle multi-config cameras */ |
2245 | if (dev->descriptor.bNumConfigurations != 1) { | 2311 | if (dev->descriptor.bNumConfigurations != 1) { |
2246 | PDEBUG(D_ERR, "%04x:%04x too many config", | 2312 | err("%04x:%04x too many config", |
2247 | id->idVendor, id->idProduct); | 2313 | id->idVendor, id->idProduct); |
2248 | return -ENODEV; | 2314 | return -ENODEV; |
2249 | } | 2315 | } |
@@ -2428,7 +2494,7 @@ EXPORT_SYMBOL(gspca_auto_gain_n_exposure); | |||
2428 | /* -- module insert / remove -- */ | 2494 | /* -- module insert / remove -- */ |
2429 | static int __init gspca_init(void) | 2495 | static int __init gspca_init(void) |
2430 | { | 2496 | { |
2431 | info("main v%d.%d.%d registered", | 2497 | info("v%d.%d.%d registered", |
2432 | (DRIVER_VERSION_NUMBER >> 16) & 0xff, | 2498 | (DRIVER_VERSION_NUMBER >> 16) & 0xff, |
2433 | (DRIVER_VERSION_NUMBER >> 8) & 0xff, | 2499 | (DRIVER_VERSION_NUMBER >> 8) & 0xff, |
2434 | DRIVER_VERSION_NUMBER & 0xff); | 2500 | DRIVER_VERSION_NUMBER & 0xff); |
@@ -2436,7 +2502,6 @@ static int __init gspca_init(void) | |||
2436 | } | 2502 | } |
2437 | static void __exit gspca_exit(void) | 2503 | static void __exit gspca_exit(void) |
2438 | { | 2504 | { |
2439 | info("main deregistered"); | ||
2440 | } | 2505 | } |
2441 | 2506 | ||
2442 | module_init(gspca_init); | 2507 | module_init(gspca_init); |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index b749c36d9f7..d4d210b56b4 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -52,11 +52,20 @@ struct framerates { | |||
52 | int nrates; | 52 | int nrates; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | /* control definition */ | ||
56 | struct gspca_ctrl { | ||
57 | s16 val; /* current value */ | ||
58 | s16 def; /* default value */ | ||
59 | s16 min, max; /* minimum and maximum values */ | ||
60 | }; | ||
61 | |||
55 | /* device information - set at probe time */ | 62 | /* device information - set at probe time */ |
56 | struct cam { | 63 | struct cam { |
57 | const struct v4l2_pix_format *cam_mode; /* size nmodes */ | 64 | const struct v4l2_pix_format *cam_mode; /* size nmodes */ |
58 | const struct framerates *mode_framerates; /* must have size nmode, | 65 | const struct framerates *mode_framerates; /* must have size nmode, |
59 | * just like cam_mode */ | 66 | * just like cam_mode */ |
67 | struct gspca_ctrl *ctrls; /* control table - size nctrls */ | ||
68 | /* may be NULL */ | ||
60 | u32 bulk_size; /* buffer size when image transfer by bulk */ | 69 | u32 bulk_size; /* buffer size when image transfer by bulk */ |
61 | u32 input_flags; /* value for ENUM_INPUT status flags */ | 70 | u32 input_flags; /* value for ENUM_INPUT status flags */ |
62 | u8 nmodes; /* size of cam_mode */ | 71 | u8 nmodes; /* size of cam_mode */ |
@@ -99,6 +108,7 @@ struct ctrl { | |||
99 | struct v4l2_queryctrl qctrl; | 108 | struct v4l2_queryctrl qctrl; |
100 | int (*set)(struct gspca_dev *, __s32); | 109 | int (*set)(struct gspca_dev *, __s32); |
101 | int (*get)(struct gspca_dev *, __s32 *); | 110 | int (*get)(struct gspca_dev *, __s32 *); |
111 | cam_v_op set_control; | ||
102 | }; | 112 | }; |
103 | 113 | ||
104 | /* subdriver description */ | 114 | /* subdriver description */ |
@@ -106,7 +116,7 @@ struct sd_desc { | |||
106 | /* information */ | 116 | /* information */ |
107 | const char *name; /* sub-driver name */ | 117 | const char *name; /* sub-driver name */ |
108 | /* controls */ | 118 | /* controls */ |
109 | const struct ctrl *ctrls; | 119 | const struct ctrl *ctrls; /* static control definition */ |
110 | int nctrls; | 120 | int nctrls; |
111 | /* mandatory operations */ | 121 | /* mandatory operations */ |
112 | cam_cf_op config; /* called on probe */ | 122 | cam_cf_op config; /* called on probe */ |
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index 12d9cf4caba..a35e87bb038 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c | |||
@@ -82,7 +82,7 @@ static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command) | |||
82 | usb_sndbulkpipe(gspca_dev->dev, 3), | 82 | usb_sndbulkpipe(gspca_dev->dev, 3), |
83 | gspca_dev->usb_buf, 2, NULL, 500); | 83 | gspca_dev->usb_buf, 2, NULL, 500); |
84 | if (retval < 0) | 84 | if (retval < 0) |
85 | PDEBUG(D_ERR, "command write [%02x] error %d", | 85 | err("command write [%02x] error %d", |
86 | gspca_dev->usb_buf[0], retval); | 86 | gspca_dev->usb_buf[0], retval); |
87 | return retval; | 87 | return retval; |
88 | } | 88 | } |
@@ -97,7 +97,7 @@ static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response) | |||
97 | gspca_dev->usb_buf, 1, NULL, 500); | 97 | gspca_dev->usb_buf, 1, NULL, 500); |
98 | response = gspca_dev->usb_buf[0]; | 98 | response = gspca_dev->usb_buf[0]; |
99 | if (retval < 0) | 99 | if (retval < 0) |
100 | PDEBUG(D_ERR, "read command [%02x] error %d", | 100 | err("read command [%02x] error %d", |
101 | gspca_dev->usb_buf[0], retval); | 101 | gspca_dev->usb_buf[0], retval); |
102 | return retval; | 102 | return retval; |
103 | } | 103 | } |
@@ -191,7 +191,7 @@ static void jlj_dostream(struct work_struct *work) | |||
191 | 191 | ||
192 | buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); | 192 | buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); |
193 | if (!buffer) { | 193 | if (!buffer) { |
194 | PDEBUG(D_ERR, "Couldn't allocate USB buffer"); | 194 | err("Couldn't allocate USB buffer"); |
195 | goto quit_stream; | 195 | goto quit_stream; |
196 | } | 196 | } |
197 | while (gspca_dev->present && gspca_dev->streaming) { | 197 | while (gspca_dev->present && gspca_dev->streaming) { |
@@ -354,19 +354,12 @@ static struct usb_driver sd_driver = { | |||
354 | /* -- module insert / remove -- */ | 354 | /* -- module insert / remove -- */ |
355 | static int __init sd_mod_init(void) | 355 | static int __init sd_mod_init(void) |
356 | { | 356 | { |
357 | int ret; | 357 | return usb_register(&sd_driver); |
358 | |||
359 | ret = usb_register(&sd_driver); | ||
360 | if (ret < 0) | ||
361 | return ret; | ||
362 | PDEBUG(D_PROBE, "registered"); | ||
363 | return 0; | ||
364 | } | 358 | } |
365 | 359 | ||
366 | static void __exit sd_mod_exit(void) | 360 | static void __exit sd_mod_exit(void) |
367 | { | 361 | { |
368 | usb_deregister(&sd_driver); | 362 | usb_deregister(&sd_driver); |
369 | PDEBUG(D_PROBE, "deregistered"); | ||
370 | } | 363 | } |
371 | 364 | ||
372 | module_init(sd_mod_init); | 365 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c new file mode 100644 index 00000000000..d2ce65dcbfd --- /dev/null +++ b/drivers/media/video/gspca/konica.c | |||
@@ -0,0 +1,646 @@ | |||
1 | /* | ||
2 | * Driver for USB webcams based on Konica chipset. This | ||
3 | * chipset is used in Intel YC76 camera. | ||
4 | * | ||
5 | * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> | ||
6 | * | ||
7 | * Based on the usbvideo v4l1 konicawc driver which is: | ||
8 | * | ||
9 | * Copyright (C) 2002 Simon Evans <spse@secret.org.uk> | ||
10 | * | ||
11 | * The code for making gspca work with a webcam with 2 isoc endpoints was | ||
12 | * taken from the benq gspca subdriver which is: | ||
13 | * | ||
14 | * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr) | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
29 | */ | ||
30 | |||
31 | #define MODULE_NAME "konica" | ||
32 | |||
33 | #include <linux/input.h> | ||
34 | #include "gspca.h" | ||
35 | |||
36 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
37 | MODULE_DESCRIPTION("Konica chipset USB Camera Driver"); | ||
38 | MODULE_LICENSE("GPL"); | ||
39 | |||
40 | #define WHITEBAL_REG 0x01 | ||
41 | #define BRIGHTNESS_REG 0x02 | ||
42 | #define SHARPNESS_REG 0x03 | ||
43 | #define CONTRAST_REG 0x04 | ||
44 | #define SATURATION_REG 0x05 | ||
45 | |||
46 | /* specific webcam descriptor */ | ||
47 | struct sd { | ||
48 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
49 | struct urb *last_data_urb; | ||
50 | u8 snapshot_pressed; | ||
51 | u8 brightness; | ||
52 | u8 contrast; | ||
53 | u8 saturation; | ||
54 | u8 whitebal; | ||
55 | u8 sharpness; | ||
56 | }; | ||
57 | |||
58 | /* V4L2 controls supported by the driver */ | ||
59 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
60 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
61 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
63 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); | ||
65 | static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | |||
70 | static const struct ctrl sd_ctrls[] = { | ||
71 | #define SD_BRIGHTNESS 0 | ||
72 | { | ||
73 | { | ||
74 | .id = V4L2_CID_BRIGHTNESS, | ||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
76 | .name = "Brightness", | ||
77 | .minimum = 0, | ||
78 | .maximum = 9, | ||
79 | .step = 1, | ||
80 | #define BRIGHTNESS_DEFAULT 4 | ||
81 | .default_value = BRIGHTNESS_DEFAULT, | ||
82 | .flags = 0, | ||
83 | }, | ||
84 | .set = sd_setbrightness, | ||
85 | .get = sd_getbrightness, | ||
86 | }, | ||
87 | #define SD_CONTRAST 1 | ||
88 | { | ||
89 | { | ||
90 | .id = V4L2_CID_CONTRAST, | ||
91 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
92 | .name = "Contrast", | ||
93 | .minimum = 0, | ||
94 | .maximum = 9, | ||
95 | .step = 4, | ||
96 | #define CONTRAST_DEFAULT 10 | ||
97 | .default_value = CONTRAST_DEFAULT, | ||
98 | .flags = 0, | ||
99 | }, | ||
100 | .set = sd_setcontrast, | ||
101 | .get = sd_getcontrast, | ||
102 | }, | ||
103 | #define SD_SATURATION 2 | ||
104 | { | ||
105 | { | ||
106 | .id = V4L2_CID_SATURATION, | ||
107 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
108 | .name = "Saturation", | ||
109 | .minimum = 0, | ||
110 | .maximum = 9, | ||
111 | .step = 1, | ||
112 | #define SATURATION_DEFAULT 4 | ||
113 | .default_value = SATURATION_DEFAULT, | ||
114 | .flags = 0, | ||
115 | }, | ||
116 | .set = sd_setsaturation, | ||
117 | .get = sd_getsaturation, | ||
118 | }, | ||
119 | #define SD_WHITEBAL 3 | ||
120 | { | ||
121 | { | ||
122 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
123 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
124 | .name = "White Balance", | ||
125 | .minimum = 0, | ||
126 | .maximum = 33, | ||
127 | .step = 1, | ||
128 | #define WHITEBAL_DEFAULT 25 | ||
129 | .default_value = WHITEBAL_DEFAULT, | ||
130 | .flags = 0, | ||
131 | }, | ||
132 | .set = sd_setwhitebal, | ||
133 | .get = sd_getwhitebal, | ||
134 | }, | ||
135 | #define SD_SHARPNESS 4 | ||
136 | { | ||
137 | { | ||
138 | .id = V4L2_CID_SHARPNESS, | ||
139 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
140 | .name = "Sharpness", | ||
141 | .minimum = 0, | ||
142 | .maximum = 9, | ||
143 | .step = 1, | ||
144 | #define SHARPNESS_DEFAULT 4 | ||
145 | .default_value = SHARPNESS_DEFAULT, | ||
146 | .flags = 0, | ||
147 | }, | ||
148 | .set = sd_setsharpness, | ||
149 | .get = sd_getsharpness, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | /* .priv is what goes to register 8 for this mode, known working values: | ||
154 | 0x00 -> 176x144, cropped | ||
155 | 0x01 -> 176x144, cropped | ||
156 | 0x02 -> 176x144, cropped | ||
157 | 0x03 -> 176x144, cropped | ||
158 | 0x04 -> 176x144, binned | ||
159 | 0x05 -> 320x240 | ||
160 | 0x06 -> 320x240 | ||
161 | 0x07 -> 160x120, cropped | ||
162 | 0x08 -> 160x120, cropped | ||
163 | 0x09 -> 160x120, binned (note has 136 lines) | ||
164 | 0x0a -> 160x120, binned (note has 136 lines) | ||
165 | 0x0b -> 160x120, cropped | ||
166 | */ | ||
167 | static const struct v4l2_pix_format vga_mode[] = { | ||
168 | {160, 120, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE, | ||
169 | .bytesperline = 160, | ||
170 | .sizeimage = 160 * 136 * 3 / 2 + 960, | ||
171 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
172 | .priv = 0x0a}, | ||
173 | {176, 144, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE, | ||
174 | .bytesperline = 176, | ||
175 | .sizeimage = 176 * 144 * 3 / 2 + 960, | ||
176 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
177 | .priv = 0x04}, | ||
178 | {320, 240, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE, | ||
179 | .bytesperline = 320, | ||
180 | .sizeimage = 320 * 240 * 3 / 2 + 960, | ||
181 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
182 | .priv = 0x05}, | ||
183 | }; | ||
184 | |||
185 | static void sd_isoc_irq(struct urb *urb); | ||
186 | |||
187 | static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) | ||
188 | { | ||
189 | struct usb_device *dev = gspca_dev->dev; | ||
190 | int ret; | ||
191 | |||
192 | if (gspca_dev->usb_err < 0) | ||
193 | return; | ||
194 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
195 | 0x02, | ||
196 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
197 | value, | ||
198 | index, | ||
199 | NULL, | ||
200 | 0, | ||
201 | 1000); | ||
202 | if (ret < 0) { | ||
203 | err("reg_w err %d", ret); | ||
204 | gspca_dev->usb_err = ret; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index) | ||
209 | { | ||
210 | struct usb_device *dev = gspca_dev->dev; | ||
211 | int ret; | ||
212 | |||
213 | if (gspca_dev->usb_err < 0) | ||
214 | return; | ||
215 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
216 | 0x03, | ||
217 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
218 | value, | ||
219 | index, | ||
220 | gspca_dev->usb_buf, | ||
221 | 2, | ||
222 | 1000); | ||
223 | if (ret < 0) { | ||
224 | err("reg_w err %d", ret); | ||
225 | gspca_dev->usb_err = ret; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static void konica_stream_on(struct gspca_dev *gspca_dev) | ||
230 | { | ||
231 | reg_w(gspca_dev, 1, 0x0b); | ||
232 | } | ||
233 | |||
234 | static void konica_stream_off(struct gspca_dev *gspca_dev) | ||
235 | { | ||
236 | reg_w(gspca_dev, 0, 0x0b); | ||
237 | } | ||
238 | |||
239 | /* this function is called at probe time */ | ||
240 | static int sd_config(struct gspca_dev *gspca_dev, | ||
241 | const struct usb_device_id *id) | ||
242 | { | ||
243 | struct sd *sd = (struct sd *) gspca_dev; | ||
244 | |||
245 | gspca_dev->cam.cam_mode = vga_mode; | ||
246 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | ||
247 | gspca_dev->cam.no_urb_create = 1; | ||
248 | /* The highest alt setting has an isoc packetsize of 0, so we | ||
249 | don't want to use it */ | ||
250 | gspca_dev->nbalt--; | ||
251 | |||
252 | sd->brightness = BRIGHTNESS_DEFAULT; | ||
253 | sd->contrast = CONTRAST_DEFAULT; | ||
254 | sd->saturation = SATURATION_DEFAULT; | ||
255 | sd->whitebal = WHITEBAL_DEFAULT; | ||
256 | sd->sharpness = SHARPNESS_DEFAULT; | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | /* this function is called at probe and resume time */ | ||
262 | static int sd_init(struct gspca_dev *gspca_dev) | ||
263 | { | ||
264 | /* HDG not sure if these 2 reads are needed */ | ||
265 | reg_r(gspca_dev, 0, 0x10); | ||
266 | PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x", | ||
267 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); | ||
268 | reg_r(gspca_dev, 0, 0x10); | ||
269 | PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x", | ||
270 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); | ||
271 | reg_w(gspca_dev, 0, 0x0d); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int sd_start(struct gspca_dev *gspca_dev) | ||
277 | { | ||
278 | struct sd *sd = (struct sd *) gspca_dev; | ||
279 | struct urb *urb; | ||
280 | int i, n, packet_size; | ||
281 | struct usb_host_interface *alt; | ||
282 | struct usb_interface *intf; | ||
283 | |||
284 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | ||
285 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | ||
286 | if (!alt) { | ||
287 | err("Couldn't get altsetting"); | ||
288 | return -EIO; | ||
289 | } | ||
290 | |||
291 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
292 | |||
293 | reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG); | ||
294 | reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG); | ||
295 | reg_w(gspca_dev, sd->contrast, CONTRAST_REG); | ||
296 | reg_w(gspca_dev, sd->saturation, SATURATION_REG); | ||
297 | reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG); | ||
298 | |||
299 | n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | ||
300 | reg_w(gspca_dev, n, 0x08); | ||
301 | |||
302 | konica_stream_on(gspca_dev); | ||
303 | |||
304 | if (gspca_dev->usb_err) | ||
305 | return gspca_dev->usb_err; | ||
306 | |||
307 | /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */ | ||
308 | #if MAX_NURBS < 4 | ||
309 | #error "Not enough URBs in the gspca table" | ||
310 | #endif | ||
311 | #define SD_NPKT 32 | ||
312 | for (n = 0; n < 4; n++) { | ||
313 | i = n & 1 ? 0 : 1; | ||
314 | packet_size = | ||
315 | le16_to_cpu(alt->endpoint[i].desc.wMaxPacketSize); | ||
316 | urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); | ||
317 | if (!urb) { | ||
318 | err("usb_alloc_urb failed"); | ||
319 | return -ENOMEM; | ||
320 | } | ||
321 | gspca_dev->urb[n] = urb; | ||
322 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, | ||
323 | packet_size * SD_NPKT, | ||
324 | GFP_KERNEL, | ||
325 | &urb->transfer_dma); | ||
326 | if (urb->transfer_buffer == NULL) { | ||
327 | err("usb_buffer_alloc failed"); | ||
328 | return -ENOMEM; | ||
329 | } | ||
330 | |||
331 | urb->dev = gspca_dev->dev; | ||
332 | urb->context = gspca_dev; | ||
333 | urb->transfer_buffer_length = packet_size * SD_NPKT; | ||
334 | urb->pipe = usb_rcvisocpipe(gspca_dev->dev, | ||
335 | n & 1 ? 0x81 : 0x82); | ||
336 | urb->transfer_flags = URB_ISO_ASAP | ||
337 | | URB_NO_TRANSFER_DMA_MAP; | ||
338 | urb->interval = 1; | ||
339 | urb->complete = sd_isoc_irq; | ||
340 | urb->number_of_packets = SD_NPKT; | ||
341 | for (i = 0; i < SD_NPKT; i++) { | ||
342 | urb->iso_frame_desc[i].length = packet_size; | ||
343 | urb->iso_frame_desc[i].offset = packet_size * i; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
351 | { | ||
352 | struct sd *sd = (struct sd *) gspca_dev; | ||
353 | |||
354 | konica_stream_off(gspca_dev); | ||
355 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
356 | /* Don't keep the button in the pressed state "forever" if it was | ||
357 | pressed when streaming is stopped */ | ||
358 | if (sd->snapshot_pressed) { | ||
359 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | ||
360 | input_sync(gspca_dev->input_dev); | ||
361 | sd->snapshot_pressed = 0; | ||
362 | } | ||
363 | #endif | ||
364 | } | ||
365 | |||
366 | /* reception of an URB */ | ||
367 | static void sd_isoc_irq(struct urb *urb) | ||
368 | { | ||
369 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | ||
370 | struct sd *sd = (struct sd *) gspca_dev; | ||
371 | struct urb *data_urb, *status_urb; | ||
372 | u8 *data; | ||
373 | int i, st; | ||
374 | |||
375 | PDEBUG(D_PACK, "sd isoc irq"); | ||
376 | if (!gspca_dev->streaming) | ||
377 | return; | ||
378 | |||
379 | if (urb->status != 0) { | ||
380 | if (urb->status == -ESHUTDOWN) | ||
381 | return; /* disconnection */ | ||
382 | #ifdef CONFIG_PM | ||
383 | if (gspca_dev->frozen) | ||
384 | return; | ||
385 | #endif | ||
386 | PDEBUG(D_ERR, "urb status: %d", urb->status); | ||
387 | st = usb_submit_urb(urb, GFP_ATOMIC); | ||
388 | if (st < 0) | ||
389 | err("resubmit urb error %d", st); | ||
390 | return; | ||
391 | } | ||
392 | |||
393 | /* if this is a data URB (ep 0x82), wait */ | ||
394 | if (urb->transfer_buffer_length > 32) { | ||
395 | sd->last_data_urb = urb; | ||
396 | return; | ||
397 | } | ||
398 | |||
399 | status_urb = urb; | ||
400 | data_urb = sd->last_data_urb; | ||
401 | sd->last_data_urb = NULL; | ||
402 | |||
403 | if (!data_urb || data_urb->start_frame != status_urb->start_frame) { | ||
404 | PDEBUG(D_ERR|D_PACK, "lost sync on frames"); | ||
405 | goto resubmit; | ||
406 | } | ||
407 | |||
408 | if (data_urb->number_of_packets != status_urb->number_of_packets) { | ||
409 | PDEBUG(D_ERR|D_PACK, | ||
410 | "no packets does not match, data: %d, status: %d", | ||
411 | data_urb->number_of_packets, | ||
412 | status_urb->number_of_packets); | ||
413 | goto resubmit; | ||
414 | } | ||
415 | |||
416 | for (i = 0; i < status_urb->number_of_packets; i++) { | ||
417 | if (data_urb->iso_frame_desc[i].status || | ||
418 | status_urb->iso_frame_desc[i].status) { | ||
419 | PDEBUG(D_ERR|D_PACK, | ||
420 | "pkt %d data-status %d, status-status %d", i, | ||
421 | data_urb->iso_frame_desc[i].status, | ||
422 | status_urb->iso_frame_desc[i].status); | ||
423 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
424 | continue; | ||
425 | } | ||
426 | |||
427 | if (status_urb->iso_frame_desc[i].actual_length != 1) { | ||
428 | PDEBUG(D_ERR|D_PACK, | ||
429 | "bad status packet length %d", | ||
430 | status_urb->iso_frame_desc[i].actual_length); | ||
431 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
432 | continue; | ||
433 | } | ||
434 | |||
435 | st = *((u8 *)status_urb->transfer_buffer | ||
436 | + status_urb->iso_frame_desc[i].offset); | ||
437 | |||
438 | data = (u8 *)data_urb->transfer_buffer | ||
439 | + data_urb->iso_frame_desc[i].offset; | ||
440 | |||
441 | /* st: 0x80-0xff: frame start with frame number (ie 0-7f) | ||
442 | * otherwise: | ||
443 | * bit 0 0: keep packet | ||
444 | * 1: drop packet (padding data) | ||
445 | * | ||
446 | * bit 4 0 button not clicked | ||
447 | * 1 button clicked | ||
448 | * button is used to `take a picture' (in software) | ||
449 | */ | ||
450 | if (st & 0x80) { | ||
451 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | ||
452 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); | ||
453 | } else { | ||
454 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
455 | u8 button_state = st & 0x40 ? 1 : 0; | ||
456 | if (sd->snapshot_pressed != button_state) { | ||
457 | input_report_key(gspca_dev->input_dev, | ||
458 | KEY_CAMERA, | ||
459 | button_state); | ||
460 | input_sync(gspca_dev->input_dev); | ||
461 | sd->snapshot_pressed = button_state; | ||
462 | } | ||
463 | #endif | ||
464 | if (st & 0x01) | ||
465 | continue; | ||
466 | } | ||
467 | gspca_frame_add(gspca_dev, INTER_PACKET, data, | ||
468 | data_urb->iso_frame_desc[i].actual_length); | ||
469 | } | ||
470 | |||
471 | resubmit: | ||
472 | if (data_urb) { | ||
473 | st = usb_submit_urb(data_urb, GFP_ATOMIC); | ||
474 | if (st < 0) | ||
475 | PDEBUG(D_ERR|D_PACK, | ||
476 | "usb_submit_urb(data_urb) ret %d", st); | ||
477 | } | ||
478 | st = usb_submit_urb(status_urb, GFP_ATOMIC); | ||
479 | if (st < 0) | ||
480 | err("usb_submit_urb(status_urb) ret %d", st); | ||
481 | } | ||
482 | |||
483 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
484 | { | ||
485 | struct sd *sd = (struct sd *) gspca_dev; | ||
486 | |||
487 | sd->brightness = val; | ||
488 | if (gspca_dev->streaming) { | ||
489 | konica_stream_off(gspca_dev); | ||
490 | reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG); | ||
491 | konica_stream_on(gspca_dev); | ||
492 | } | ||
493 | |||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
498 | { | ||
499 | struct sd *sd = (struct sd *) gspca_dev; | ||
500 | |||
501 | *val = sd->brightness; | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
507 | { | ||
508 | struct sd *sd = (struct sd *) gspca_dev; | ||
509 | |||
510 | sd->contrast = val; | ||
511 | if (gspca_dev->streaming) { | ||
512 | konica_stream_off(gspca_dev); | ||
513 | reg_w(gspca_dev, sd->contrast, CONTRAST_REG); | ||
514 | konica_stream_on(gspca_dev); | ||
515 | } | ||
516 | |||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
521 | { | ||
522 | struct sd *sd = (struct sd *) gspca_dev; | ||
523 | |||
524 | *val = sd->contrast; | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) | ||
530 | { | ||
531 | struct sd *sd = (struct sd *) gspca_dev; | ||
532 | |||
533 | sd->saturation = val; | ||
534 | if (gspca_dev->streaming) { | ||
535 | konica_stream_off(gspca_dev); | ||
536 | reg_w(gspca_dev, sd->saturation, SATURATION_REG); | ||
537 | konica_stream_on(gspca_dev); | ||
538 | } | ||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) | ||
543 | { | ||
544 | struct sd *sd = (struct sd *) gspca_dev; | ||
545 | |||
546 | *val = sd->saturation; | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val) | ||
552 | { | ||
553 | struct sd *sd = (struct sd *) gspca_dev; | ||
554 | |||
555 | sd->whitebal = val; | ||
556 | if (gspca_dev->streaming) { | ||
557 | konica_stream_off(gspca_dev); | ||
558 | reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG); | ||
559 | konica_stream_on(gspca_dev); | ||
560 | } | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val) | ||
565 | { | ||
566 | struct sd *sd = (struct sd *) gspca_dev; | ||
567 | |||
568 | *val = sd->whitebal; | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
574 | { | ||
575 | struct sd *sd = (struct sd *) gspca_dev; | ||
576 | |||
577 | sd->sharpness = val; | ||
578 | if (gspca_dev->streaming) { | ||
579 | konica_stream_off(gspca_dev); | ||
580 | reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG); | ||
581 | konica_stream_on(gspca_dev); | ||
582 | } | ||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
587 | { | ||
588 | struct sd *sd = (struct sd *) gspca_dev; | ||
589 | |||
590 | *val = sd->sharpness; | ||
591 | |||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | /* sub-driver description */ | ||
596 | static const struct sd_desc sd_desc = { | ||
597 | .name = MODULE_NAME, | ||
598 | .ctrls = sd_ctrls, | ||
599 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
600 | .config = sd_config, | ||
601 | .init = sd_init, | ||
602 | .start = sd_start, | ||
603 | .stopN = sd_stopN, | ||
604 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
605 | .other_input = 1, | ||
606 | #endif | ||
607 | }; | ||
608 | |||
609 | /* -- module initialisation -- */ | ||
610 | static const __devinitdata struct usb_device_id device_table[] = { | ||
611 | {USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */ | ||
612 | {} | ||
613 | }; | ||
614 | MODULE_DEVICE_TABLE(usb, device_table); | ||
615 | |||
616 | /* -- device connect -- */ | ||
617 | static int sd_probe(struct usb_interface *intf, | ||
618 | const struct usb_device_id *id) | ||
619 | { | ||
620 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
621 | THIS_MODULE); | ||
622 | } | ||
623 | |||
624 | static struct usb_driver sd_driver = { | ||
625 | .name = MODULE_NAME, | ||
626 | .id_table = device_table, | ||
627 | .probe = sd_probe, | ||
628 | .disconnect = gspca_disconnect, | ||
629 | #ifdef CONFIG_PM | ||
630 | .suspend = gspca_suspend, | ||
631 | .resume = gspca_resume, | ||
632 | #endif | ||
633 | }; | ||
634 | |||
635 | /* -- module insert / remove -- */ | ||
636 | static int __init sd_mod_init(void) | ||
637 | { | ||
638 | return usb_register(&sd_driver); | ||
639 | } | ||
640 | static void __exit sd_mod_exit(void) | ||
641 | { | ||
642 | usb_deregister(&sd_driver); | ||
643 | } | ||
644 | |||
645 | module_init(sd_mod_init); | ||
646 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index b073d66acd0..c872b93a335 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c | |||
@@ -406,18 +406,12 @@ static struct usb_driver sd_driver = { | |||
406 | /* -- module insert / remove -- */ | 406 | /* -- module insert / remove -- */ |
407 | static int __init mod_m5602_init(void) | 407 | static int __init mod_m5602_init(void) |
408 | { | 408 | { |
409 | int ret; | 409 | return usb_register(&sd_driver); |
410 | ret = usb_register(&sd_driver); | ||
411 | if (ret < 0) | ||
412 | return ret; | ||
413 | PDEBUG(D_PROBE, "registered"); | ||
414 | return 0; | ||
415 | } | 410 | } |
416 | 411 | ||
417 | static void __exit mod_m5602_exit(void) | 412 | static void __exit mod_m5602_exit(void) |
418 | { | 413 | { |
419 | usb_deregister(&sd_driver); | 414 | usb_deregister(&sd_driver); |
420 | PDEBUG(D_PROBE, "deregistered"); | ||
421 | } | 415 | } |
422 | 416 | ||
423 | module_init(mod_m5602_init); | 417 | module_init(mod_m5602_init); |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index c0722fa6460..0d605a52b92 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c | |||
@@ -109,14 +109,14 @@ static const struct ctrl mt9m111_ctrls[] = { | |||
109 | #define GREEN_BALANCE_IDX 4 | 109 | #define GREEN_BALANCE_IDX 4 |
110 | { | 110 | { |
111 | { | 111 | { |
112 | .id = M5602_V4L2_CID_GREEN_BALANCE, | 112 | .id = M5602_V4L2_CID_GREEN_BALANCE, |
113 | .type = V4L2_CTRL_TYPE_INTEGER, | 113 | .type = V4L2_CTRL_TYPE_INTEGER, |
114 | .name = "green balance", | 114 | .name = "green balance", |
115 | .minimum = 0x00, | 115 | .minimum = 0x00, |
116 | .maximum = 0x7ff, | 116 | .maximum = 0x7ff, |
117 | .step = 0x1, | 117 | .step = 0x1, |
118 | .default_value = MT9M111_GREEN_GAIN_DEFAULT, | 118 | .default_value = MT9M111_GREEN_GAIN_DEFAULT, |
119 | .flags = V4L2_CTRL_FLAG_SLIDER | 119 | .flags = V4L2_CTRL_FLAG_SLIDER |
120 | }, | 120 | }, |
121 | .set = mt9m111_set_green_balance, | 121 | .set = mt9m111_set_green_balance, |
122 | .get = mt9m111_get_green_balance | 122 | .get = mt9m111_get_green_balance |
@@ -124,14 +124,14 @@ static const struct ctrl mt9m111_ctrls[] = { | |||
124 | #define BLUE_BALANCE_IDX 5 | 124 | #define BLUE_BALANCE_IDX 5 |
125 | { | 125 | { |
126 | { | 126 | { |
127 | .id = V4L2_CID_BLUE_BALANCE, | 127 | .id = V4L2_CID_BLUE_BALANCE, |
128 | .type = V4L2_CTRL_TYPE_INTEGER, | 128 | .type = V4L2_CTRL_TYPE_INTEGER, |
129 | .name = "blue balance", | 129 | .name = "blue balance", |
130 | .minimum = 0x00, | 130 | .minimum = 0x00, |
131 | .maximum = 0x7ff, | 131 | .maximum = 0x7ff, |
132 | .step = 0x1, | 132 | .step = 0x1, |
133 | .default_value = MT9M111_BLUE_GAIN_DEFAULT, | 133 | .default_value = MT9M111_BLUE_GAIN_DEFAULT, |
134 | .flags = V4L2_CTRL_FLAG_SLIDER | 134 | .flags = V4L2_CTRL_FLAG_SLIDER |
135 | }, | 135 | }, |
136 | .set = mt9m111_set_blue_balance, | 136 | .set = mt9m111_set_blue_balance, |
137 | .get = mt9m111_get_blue_balance | 137 | .get = mt9m111_get_blue_balance |
@@ -139,14 +139,14 @@ static const struct ctrl mt9m111_ctrls[] = { | |||
139 | #define RED_BALANCE_IDX 5 | 139 | #define RED_BALANCE_IDX 5 |
140 | { | 140 | { |
141 | { | 141 | { |
142 | .id = V4L2_CID_RED_BALANCE, | 142 | .id = V4L2_CID_RED_BALANCE, |
143 | .type = V4L2_CTRL_TYPE_INTEGER, | 143 | .type = V4L2_CTRL_TYPE_INTEGER, |
144 | .name = "red balance", | 144 | .name = "red balance", |
145 | .minimum = 0x00, | 145 | .minimum = 0x00, |
146 | .maximum = 0x7ff, | 146 | .maximum = 0x7ff, |
147 | .step = 0x1, | 147 | .step = 0x1, |
148 | .default_value = MT9M111_RED_GAIN_DEFAULT, | 148 | .default_value = MT9M111_RED_GAIN_DEFAULT, |
149 | .flags = V4L2_CTRL_FLAG_SLIDER | 149 | .flags = V4L2_CTRL_FLAG_SLIDER |
150 | }, | 150 | }, |
151 | .set = mt9m111_set_red_balance, | 151 | .set = mt9m111_set_red_balance, |
152 | .get = mt9m111_get_red_balance | 152 | .get = mt9m111_get_red_balance |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index b3de7782309..b1f0c492036 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h | |||
@@ -70,7 +70,7 @@ | |||
70 | #define MT9M111_COLORPIPE 0x01 | 70 | #define MT9M111_COLORPIPE 0x01 |
71 | #define MT9M111_CAMERA_CONTROL 0x02 | 71 | #define MT9M111_CAMERA_CONTROL 0x02 |
72 | 72 | ||
73 | #define MT9M111_RESET (1 << 0) | 73 | #define MT9M111_RESET (1 << 0) |
74 | #define MT9M111_RESTART (1 << 1) | 74 | #define MT9M111_RESTART (1 << 1) |
75 | #define MT9M111_ANALOG_STANDBY (1 << 2) | 75 | #define MT9M111_ANALOG_STANDBY (1 << 2) |
76 | #define MT9M111_CHIP_ENABLE (1 << 3) | 76 | #define MT9M111_CHIP_ENABLE (1 << 3) |
@@ -97,7 +97,7 @@ | |||
97 | #define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0) | 97 | #define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0) |
98 | 98 | ||
99 | #define INITIAL_MAX_GAIN 64 | 99 | #define INITIAL_MAX_GAIN 64 |
100 | #define MT9M111_DEFAULT_GAIN 283 | 100 | #define MT9M111_DEFAULT_GAIN 283 |
101 | #define MT9M111_GREEN_GAIN_DEFAULT 0x20 | 101 | #define MT9M111_GREEN_GAIN_DEFAULT 0x20 |
102 | #define MT9M111_BLUE_GAIN_DEFAULT 0x20 | 102 | #define MT9M111_BLUE_GAIN_DEFAULT 0x20 |
103 | #define MT9M111_RED_GAIN_DEFAULT 0x20 | 103 | #define MT9M111_RED_GAIN_DEFAULT 0x20 |
@@ -125,8 +125,7 @@ static const struct m5602_sensor mt9m111 = { | |||
125 | .start = mt9m111_start, | 125 | .start = mt9m111_start, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static const unsigned char preinit_mt9m111[][4] = | 128 | static const unsigned char preinit_mt9m111[][4] = { |
129 | { | ||
130 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 129 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
131 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | 130 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, |
132 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
@@ -165,8 +164,7 @@ static const unsigned char preinit_mt9m111[][4] = | |||
165 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00} | 164 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00} |
166 | }; | 165 | }; |
167 | 166 | ||
168 | static const unsigned char init_mt9m111[][4] = | 167 | static const unsigned char init_mt9m111[][4] = { |
169 | { | ||
170 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 168 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
171 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | 169 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, |
172 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 170 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
@@ -257,8 +255,7 @@ static const unsigned char init_mt9m111[][4] = | |||
257 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | 255 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, |
258 | }; | 256 | }; |
259 | 257 | ||
260 | static const unsigned char start_mt9m111[][4] = | 258 | static const unsigned char start_mt9m111[][4] = { |
261 | { | ||
262 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 259 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
263 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 260 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
264 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 261 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -271,5 +268,4 @@ static const unsigned char start_mt9m111[][4] = | |||
271 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 268 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
272 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 269 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
273 | }; | 270 | }; |
274 | |||
275 | #endif | 271 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c index 62c1cbf0666..b12f60464b3 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov7660.c +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c | |||
@@ -54,13 +54,13 @@ static const struct ctrl ov7660_ctrls[] = { | |||
54 | #define AUTO_WHITE_BALANCE_IDX 4 | 54 | #define AUTO_WHITE_BALANCE_IDX 4 |
55 | { | 55 | { |
56 | { | 56 | { |
57 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | 57 | .id = V4L2_CID_AUTO_WHITE_BALANCE, |
58 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 58 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
59 | .name = "auto white balance", | 59 | .name = "auto white balance", |
60 | .minimum = 0, | 60 | .minimum = 0, |
61 | .maximum = 1, | 61 | .maximum = 1, |
62 | .step = 1, | 62 | .step = 1, |
63 | .default_value = 1 | 63 | .default_value = 1 |
64 | }, | 64 | }, |
65 | .set = ov7660_set_auto_white_balance, | 65 | .set = ov7660_set_auto_white_balance, |
66 | .get = ov7660_get_auto_white_balance | 66 | .get = ov7660_get_auto_white_balance |
@@ -68,13 +68,13 @@ static const struct ctrl ov7660_ctrls[] = { | |||
68 | #define AUTO_GAIN_CTRL_IDX 5 | 68 | #define AUTO_GAIN_CTRL_IDX 5 |
69 | { | 69 | { |
70 | { | 70 | { |
71 | .id = V4L2_CID_AUTOGAIN, | 71 | .id = V4L2_CID_AUTOGAIN, |
72 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 72 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
73 | .name = "auto gain control", | 73 | .name = "auto gain control", |
74 | .minimum = 0, | 74 | .minimum = 0, |
75 | .maximum = 1, | 75 | .maximum = 1, |
76 | .step = 1, | 76 | .step = 1, |
77 | .default_value = 1 | 77 | .default_value = 1 |
78 | }, | 78 | }, |
79 | .set = ov7660_set_auto_gain, | 79 | .set = ov7660_set_auto_gain, |
80 | .get = ov7660_get_auto_gain | 80 | .get = ov7660_get_auto_gain |
@@ -82,13 +82,13 @@ static const struct ctrl ov7660_ctrls[] = { | |||
82 | #define AUTO_EXPOSURE_IDX 6 | 82 | #define AUTO_EXPOSURE_IDX 6 |
83 | { | 83 | { |
84 | { | 84 | { |
85 | .id = V4L2_CID_EXPOSURE_AUTO, | 85 | .id = V4L2_CID_EXPOSURE_AUTO, |
86 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 86 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
87 | .name = "auto exposure", | 87 | .name = "auto exposure", |
88 | .minimum = 0, | 88 | .minimum = 0, |
89 | .maximum = 1, | 89 | .maximum = 1, |
90 | .step = 1, | 90 | .step = 1, |
91 | .default_value = 1 | 91 | .default_value = 1 |
92 | }, | 92 | }, |
93 | .set = ov7660_set_auto_exposure, | 93 | .set = ov7660_set_auto_exposure, |
94 | .get = ov7660_get_auto_exposure | 94 | .get = ov7660_get_auto_exposure |
@@ -96,13 +96,13 @@ static const struct ctrl ov7660_ctrls[] = { | |||
96 | #define HFLIP_IDX 7 | 96 | #define HFLIP_IDX 7 |
97 | { | 97 | { |
98 | { | 98 | { |
99 | .id = V4L2_CID_HFLIP, | 99 | .id = V4L2_CID_HFLIP, |
100 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 100 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
101 | .name = "horizontal flip", | 101 | .name = "horizontal flip", |
102 | .minimum = 0, | 102 | .minimum = 0, |
103 | .maximum = 1, | 103 | .maximum = 1, |
104 | .step = 1, | 104 | .step = 1, |
105 | .default_value = 0 | 105 | .default_value = 0 |
106 | }, | 106 | }, |
107 | .set = ov7660_set_hflip, | 107 | .set = ov7660_set_hflip, |
108 | .get = ov7660_get_hflip | 108 | .get = ov7660_get_hflip |
@@ -110,13 +110,13 @@ static const struct ctrl ov7660_ctrls[] = { | |||
110 | #define VFLIP_IDX 8 | 110 | #define VFLIP_IDX 8 |
111 | { | 111 | { |
112 | { | 112 | { |
113 | .id = V4L2_CID_VFLIP, | 113 | .id = V4L2_CID_VFLIP, |
114 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 114 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
115 | .name = "vertical flip", | 115 | .name = "vertical flip", |
116 | .minimum = 0, | 116 | .minimum = 0, |
117 | .maximum = 1, | 117 | .maximum = 1, |
118 | .step = 1, | 118 | .step = 1, |
119 | .default_value = 0 | 119 | .default_value = 0 |
120 | }, | 120 | }, |
121 | .set = ov7660_set_vflip, | 121 | .set = ov7660_set_vflip, |
122 | .get = ov7660_get_vflip | 122 | .get = ov7660_get_vflip |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h index 4d9dcf29da2..2efd607987e 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov7660.h +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h | |||
@@ -80,7 +80,7 @@ | |||
80 | 80 | ||
81 | #define OV7660_DEFAULT_GAIN 0x0e | 81 | #define OV7660_DEFAULT_GAIN 0x0e |
82 | #define OV7660_DEFAULT_RED_GAIN 0x80 | 82 | #define OV7660_DEFAULT_RED_GAIN 0x80 |
83 | #define OV7660_DEFAULT_BLUE_GAIN 0x80 | 83 | #define OV7660_DEFAULT_BLUE_GAIN 0x80 |
84 | #define OV7660_DEFAULT_SATURATION 0x00 | 84 | #define OV7660_DEFAULT_SATURATION 0x00 |
85 | #define OV7660_DEFAULT_EXPOSURE 0x20 | 85 | #define OV7660_DEFAULT_EXPOSURE 0x20 |
86 | 86 | ||
@@ -105,8 +105,7 @@ static const struct m5602_sensor ov7660 = { | |||
105 | .disconnect = ov7660_disconnect, | 105 | .disconnect = ov7660_disconnect, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static const unsigned char preinit_ov7660[][4] = | 108 | static const unsigned char preinit_ov7660[][4] = { |
109 | { | ||
110 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 109 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
111 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 110 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
112 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 111 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
@@ -140,8 +139,7 @@ static const unsigned char preinit_ov7660[][4] = | |||
140 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} | 139 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} |
141 | }; | 140 | }; |
142 | 141 | ||
143 | static const unsigned char init_ov7660[][4] = | 142 | static const unsigned char init_ov7660[][4] = { |
144 | { | ||
145 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 143 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
146 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 144 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
147 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 145 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
@@ -259,5 +257,4 @@ static const unsigned char init_ov7660[][4] = | |||
259 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 257 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
260 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 258 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
261 | }; | 259 | }; |
262 | |||
263 | #endif | 260 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 069ba0044f8..8ded8b10057 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -121,8 +121,8 @@ static const struct ctrl ov9650_ctrls[] = { | |||
121 | .minimum = 0x00, | 121 | .minimum = 0x00, |
122 | .maximum = 0x1ff, | 122 | .maximum = 0x1ff, |
123 | .step = 0x4, | 123 | .step = 0x4, |
124 | .default_value = EXPOSURE_DEFAULT, | 124 | .default_value = EXPOSURE_DEFAULT, |
125 | .flags = V4L2_CTRL_FLAG_SLIDER | 125 | .flags = V4L2_CTRL_FLAG_SLIDER |
126 | }, | 126 | }, |
127 | .set = ov9650_set_exposure, | 127 | .set = ov9650_set_exposure, |
128 | .get = ov9650_get_exposure | 128 | .get = ov9650_get_exposure |
@@ -146,13 +146,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
146 | { | 146 | { |
147 | { | 147 | { |
148 | .id = V4L2_CID_RED_BALANCE, | 148 | .id = V4L2_CID_RED_BALANCE, |
149 | .type = V4L2_CTRL_TYPE_INTEGER, | 149 | .type = V4L2_CTRL_TYPE_INTEGER, |
150 | .name = "red balance", | 150 | .name = "red balance", |
151 | .minimum = 0x00, | 151 | .minimum = 0x00, |
152 | .maximum = 0xff, | 152 | .maximum = 0xff, |
153 | .step = 0x1, | 153 | .step = 0x1, |
154 | .default_value = RED_GAIN_DEFAULT, | 154 | .default_value = RED_GAIN_DEFAULT, |
155 | .flags = V4L2_CTRL_FLAG_SLIDER | 155 | .flags = V4L2_CTRL_FLAG_SLIDER |
156 | }, | 156 | }, |
157 | .set = ov9650_set_red_balance, | 157 | .set = ov9650_set_red_balance, |
158 | .get = ov9650_get_red_balance | 158 | .get = ov9650_get_red_balance |
@@ -161,13 +161,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
161 | { | 161 | { |
162 | { | 162 | { |
163 | .id = V4L2_CID_BLUE_BALANCE, | 163 | .id = V4L2_CID_BLUE_BALANCE, |
164 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
165 | .name = "blue balance", | 165 | .name = "blue balance", |
166 | .minimum = 0x00, | 166 | .minimum = 0x00, |
167 | .maximum = 0xff, | 167 | .maximum = 0xff, |
168 | .step = 0x1, | 168 | .step = 0x1, |
169 | .default_value = BLUE_GAIN_DEFAULT, | 169 | .default_value = BLUE_GAIN_DEFAULT, |
170 | .flags = V4L2_CTRL_FLAG_SLIDER | 170 | .flags = V4L2_CTRL_FLAG_SLIDER |
171 | }, | 171 | }, |
172 | .set = ov9650_set_blue_balance, | 172 | .set = ov9650_set_blue_balance, |
173 | .get = ov9650_get_blue_balance | 173 | .get = ov9650_get_blue_balance |
@@ -175,13 +175,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
175 | #define HFLIP_IDX 4 | 175 | #define HFLIP_IDX 4 |
176 | { | 176 | { |
177 | { | 177 | { |
178 | .id = V4L2_CID_HFLIP, | 178 | .id = V4L2_CID_HFLIP, |
179 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 179 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
180 | .name = "horizontal flip", | 180 | .name = "horizontal flip", |
181 | .minimum = 0, | 181 | .minimum = 0, |
182 | .maximum = 1, | 182 | .maximum = 1, |
183 | .step = 1, | 183 | .step = 1, |
184 | .default_value = 0 | 184 | .default_value = 0 |
185 | }, | 185 | }, |
186 | .set = ov9650_set_hflip, | 186 | .set = ov9650_set_hflip, |
187 | .get = ov9650_get_hflip | 187 | .get = ov9650_get_hflip |
@@ -189,13 +189,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
189 | #define VFLIP_IDX 5 | 189 | #define VFLIP_IDX 5 |
190 | { | 190 | { |
191 | { | 191 | { |
192 | .id = V4L2_CID_VFLIP, | 192 | .id = V4L2_CID_VFLIP, |
193 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 193 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
194 | .name = "vertical flip", | 194 | .name = "vertical flip", |
195 | .minimum = 0, | 195 | .minimum = 0, |
196 | .maximum = 1, | 196 | .maximum = 1, |
197 | .step = 1, | 197 | .step = 1, |
198 | .default_value = 0 | 198 | .default_value = 0 |
199 | }, | 199 | }, |
200 | .set = ov9650_set_vflip, | 200 | .set = ov9650_set_vflip, |
201 | .get = ov9650_get_vflip | 201 | .get = ov9650_get_vflip |
@@ -203,13 +203,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
203 | #define AUTO_WHITE_BALANCE_IDX 6 | 203 | #define AUTO_WHITE_BALANCE_IDX 6 |
204 | { | 204 | { |
205 | { | 205 | { |
206 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | 206 | .id = V4L2_CID_AUTO_WHITE_BALANCE, |
207 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 207 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
208 | .name = "auto white balance", | 208 | .name = "auto white balance", |
209 | .minimum = 0, | 209 | .minimum = 0, |
210 | .maximum = 1, | 210 | .maximum = 1, |
211 | .step = 1, | 211 | .step = 1, |
212 | .default_value = 1 | 212 | .default_value = 1 |
213 | }, | 213 | }, |
214 | .set = ov9650_set_auto_white_balance, | 214 | .set = ov9650_set_auto_white_balance, |
215 | .get = ov9650_get_auto_white_balance | 215 | .get = ov9650_get_auto_white_balance |
@@ -217,13 +217,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
217 | #define AUTO_GAIN_CTRL_IDX 7 | 217 | #define AUTO_GAIN_CTRL_IDX 7 |
218 | { | 218 | { |
219 | { | 219 | { |
220 | .id = V4L2_CID_AUTOGAIN, | 220 | .id = V4L2_CID_AUTOGAIN, |
221 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 221 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
222 | .name = "auto gain control", | 222 | .name = "auto gain control", |
223 | .minimum = 0, | 223 | .minimum = 0, |
224 | .maximum = 1, | 224 | .maximum = 1, |
225 | .step = 1, | 225 | .step = 1, |
226 | .default_value = 1 | 226 | .default_value = 1 |
227 | }, | 227 | }, |
228 | .set = ov9650_set_auto_gain, | 228 | .set = ov9650_set_auto_gain, |
229 | .get = ov9650_get_auto_gain | 229 | .get = ov9650_get_auto_gain |
@@ -231,13 +231,13 @@ static const struct ctrl ov9650_ctrls[] = { | |||
231 | #define AUTO_EXPOSURE_IDX 8 | 231 | #define AUTO_EXPOSURE_IDX 8 |
232 | { | 232 | { |
233 | { | 233 | { |
234 | .id = V4L2_CID_EXPOSURE_AUTO, | 234 | .id = V4L2_CID_EXPOSURE_AUTO, |
235 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 235 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
236 | .name = "auto exposure", | 236 | .name = "auto exposure", |
237 | .minimum = 0, | 237 | .minimum = 0, |
238 | .maximum = 1, | 238 | .maximum = 1, |
239 | .step = 1, | 239 | .step = 1, |
240 | .default_value = 1 | 240 | .default_value = 1 |
241 | }, | 241 | }, |
242 | .set = ov9650_set_auto_exposure, | 242 | .set = ov9650_set_auto_exposure, |
243 | .get = ov9650_get_auto_exposure | 243 | .get = ov9650_get_auto_exposure |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index c98c40d69e0..da9a129b739 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h | |||
@@ -110,7 +110,7 @@ | |||
110 | 110 | ||
111 | #define OV9650_VARIOPIXEL (1 << 2) | 111 | #define OV9650_VARIOPIXEL (1 << 2) |
112 | #define OV9650_SYSTEM_CLK_SEL (1 << 7) | 112 | #define OV9650_SYSTEM_CLK_SEL (1 << 7) |
113 | #define OV9650_SLAM_MODE (1 << 4) | 113 | #define OV9650_SLAM_MODE (1 << 4) |
114 | 114 | ||
115 | #define OV9650_QVGA_VARIOPIXEL (1 << 7) | 115 | #define OV9650_QVGA_VARIOPIXEL (1 << 7) |
116 | 116 | ||
@@ -154,8 +154,7 @@ static const struct m5602_sensor ov9650 = { | |||
154 | .disconnect = ov9650_disconnect, | 154 | .disconnect = ov9650_disconnect, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static const unsigned char preinit_ov9650[][3] = | 157 | static const unsigned char preinit_ov9650[][3] = { |
158 | { | ||
159 | /* [INITCAM] */ | 158 | /* [INITCAM] */ |
160 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 159 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
161 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 160 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
@@ -180,8 +179,7 @@ static const unsigned char preinit_ov9650[][3] = | |||
180 | {SENSOR, OV9650_OFON, 0x40} | 179 | {SENSOR, OV9650_OFON, 0x40} |
181 | }; | 180 | }; |
182 | 181 | ||
183 | static const unsigned char init_ov9650[][3] = | 182 | static const unsigned char init_ov9650[][3] = { |
184 | { | ||
185 | /* [INITCAM] */ | 183 | /* [INITCAM] */ |
186 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 184 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
187 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 185 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
@@ -297,8 +295,7 @@ static const unsigned char init_ov9650[][3] = | |||
297 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, | 295 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, |
298 | }; | 296 | }; |
299 | 297 | ||
300 | static const unsigned char res_init_ov9650[][3] = | 298 | static const unsigned char res_init_ov9650[][3] = { |
301 | { | ||
302 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, | 299 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, |
303 | 300 | ||
304 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82}, | 301 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82}, |
@@ -307,5 +304,4 @@ static const unsigned char res_init_ov9650[][3] = | |||
307 | {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00}, | 304 | {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00}, |
308 | {BRIDGE, M5602_XB_SIG_INI, 0x01} | 305 | {BRIDGE, M5602_XB_SIG_INI, 0x01} |
309 | }; | 306 | }; |
310 | |||
311 | #endif | 307 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index 925b87d66f4..1febd34c2f0 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/drivers/media/video/gspca/m5602/m5602_po1030.c | |||
@@ -58,14 +58,14 @@ static const struct ctrl po1030_ctrls[] = { | |||
58 | #define GAIN_IDX 0 | 58 | #define GAIN_IDX 0 |
59 | { | 59 | { |
60 | { | 60 | { |
61 | .id = V4L2_CID_GAIN, | 61 | .id = V4L2_CID_GAIN, |
62 | .type = V4L2_CTRL_TYPE_INTEGER, | 62 | .type = V4L2_CTRL_TYPE_INTEGER, |
63 | .name = "gain", | 63 | .name = "gain", |
64 | .minimum = 0x00, | 64 | .minimum = 0x00, |
65 | .maximum = 0x4f, | 65 | .maximum = 0x4f, |
66 | .step = 0x1, | 66 | .step = 0x1, |
67 | .default_value = PO1030_GLOBAL_GAIN_DEFAULT, | 67 | .default_value = PO1030_GLOBAL_GAIN_DEFAULT, |
68 | .flags = V4L2_CTRL_FLAG_SLIDER | 68 | .flags = V4L2_CTRL_FLAG_SLIDER |
69 | }, | 69 | }, |
70 | .set = po1030_set_gain, | 70 | .set = po1030_set_gain, |
71 | .get = po1030_get_gain | 71 | .get = po1030_get_gain |
@@ -73,14 +73,14 @@ static const struct ctrl po1030_ctrls[] = { | |||
73 | #define EXPOSURE_IDX 1 | 73 | #define EXPOSURE_IDX 1 |
74 | { | 74 | { |
75 | { | 75 | { |
76 | .id = V4L2_CID_EXPOSURE, | 76 | .id = V4L2_CID_EXPOSURE, |
77 | .type = V4L2_CTRL_TYPE_INTEGER, | 77 | .type = V4L2_CTRL_TYPE_INTEGER, |
78 | .name = "exposure", | 78 | .name = "exposure", |
79 | .minimum = 0x00, | 79 | .minimum = 0x00, |
80 | .maximum = 0x02ff, | 80 | .maximum = 0x02ff, |
81 | .step = 0x1, | 81 | .step = 0x1, |
82 | .default_value = PO1030_EXPOSURE_DEFAULT, | 82 | .default_value = PO1030_EXPOSURE_DEFAULT, |
83 | .flags = V4L2_CTRL_FLAG_SLIDER | 83 | .flags = V4L2_CTRL_FLAG_SLIDER |
84 | }, | 84 | }, |
85 | .set = po1030_set_exposure, | 85 | .set = po1030_set_exposure, |
86 | .get = po1030_get_exposure | 86 | .get = po1030_get_exposure |
@@ -88,14 +88,14 @@ static const struct ctrl po1030_ctrls[] = { | |||
88 | #define RED_BALANCE_IDX 2 | 88 | #define RED_BALANCE_IDX 2 |
89 | { | 89 | { |
90 | { | 90 | { |
91 | .id = V4L2_CID_RED_BALANCE, | 91 | .id = V4L2_CID_RED_BALANCE, |
92 | .type = V4L2_CTRL_TYPE_INTEGER, | 92 | .type = V4L2_CTRL_TYPE_INTEGER, |
93 | .name = "red balance", | 93 | .name = "red balance", |
94 | .minimum = 0x00, | 94 | .minimum = 0x00, |
95 | .maximum = 0xff, | 95 | .maximum = 0xff, |
96 | .step = 0x1, | 96 | .step = 0x1, |
97 | .default_value = PO1030_RED_GAIN_DEFAULT, | 97 | .default_value = PO1030_RED_GAIN_DEFAULT, |
98 | .flags = V4L2_CTRL_FLAG_SLIDER | 98 | .flags = V4L2_CTRL_FLAG_SLIDER |
99 | }, | 99 | }, |
100 | .set = po1030_set_red_balance, | 100 | .set = po1030_set_red_balance, |
101 | .get = po1030_get_red_balance | 101 | .get = po1030_get_red_balance |
@@ -103,14 +103,14 @@ static const struct ctrl po1030_ctrls[] = { | |||
103 | #define BLUE_BALANCE_IDX 3 | 103 | #define BLUE_BALANCE_IDX 3 |
104 | { | 104 | { |
105 | { | 105 | { |
106 | .id = V4L2_CID_BLUE_BALANCE, | 106 | .id = V4L2_CID_BLUE_BALANCE, |
107 | .type = V4L2_CTRL_TYPE_INTEGER, | 107 | .type = V4L2_CTRL_TYPE_INTEGER, |
108 | .name = "blue balance", | 108 | .name = "blue balance", |
109 | .minimum = 0x00, | 109 | .minimum = 0x00, |
110 | .maximum = 0xff, | 110 | .maximum = 0xff, |
111 | .step = 0x1, | 111 | .step = 0x1, |
112 | .default_value = PO1030_BLUE_GAIN_DEFAULT, | 112 | .default_value = PO1030_BLUE_GAIN_DEFAULT, |
113 | .flags = V4L2_CTRL_FLAG_SLIDER | 113 | .flags = V4L2_CTRL_FLAG_SLIDER |
114 | }, | 114 | }, |
115 | .set = po1030_set_blue_balance, | 115 | .set = po1030_set_blue_balance, |
116 | .get = po1030_get_blue_balance | 116 | .get = po1030_get_blue_balance |
@@ -118,13 +118,13 @@ static const struct ctrl po1030_ctrls[] = { | |||
118 | #define HFLIP_IDX 4 | 118 | #define HFLIP_IDX 4 |
119 | { | 119 | { |
120 | { | 120 | { |
121 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
122 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
123 | .name = "horizontal flip", | 123 | .name = "horizontal flip", |
124 | .minimum = 0, | 124 | .minimum = 0, |
125 | .maximum = 1, | 125 | .maximum = 1, |
126 | .step = 1, | 126 | .step = 1, |
127 | .default_value = 0, | 127 | .default_value = 0, |
128 | }, | 128 | }, |
129 | .set = po1030_set_hflip, | 129 | .set = po1030_set_hflip, |
130 | .get = po1030_get_hflip | 130 | .get = po1030_get_hflip |
@@ -132,13 +132,13 @@ static const struct ctrl po1030_ctrls[] = { | |||
132 | #define VFLIP_IDX 5 | 132 | #define VFLIP_IDX 5 |
133 | { | 133 | { |
134 | { | 134 | { |
135 | .id = V4L2_CID_VFLIP, | 135 | .id = V4L2_CID_VFLIP, |
136 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 136 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
137 | .name = "vertical flip", | 137 | .name = "vertical flip", |
138 | .minimum = 0, | 138 | .minimum = 0, |
139 | .maximum = 1, | 139 | .maximum = 1, |
140 | .step = 1, | 140 | .step = 1, |
141 | .default_value = 0, | 141 | .default_value = 0, |
142 | }, | 142 | }, |
143 | .set = po1030_set_vflip, | 143 | .set = po1030_set_vflip, |
144 | .get = po1030_get_vflip | 144 | .get = po1030_get_vflip |
@@ -146,13 +146,13 @@ static const struct ctrl po1030_ctrls[] = { | |||
146 | #define AUTO_WHITE_BALANCE_IDX 6 | 146 | #define AUTO_WHITE_BALANCE_IDX 6 |
147 | { | 147 | { |
148 | { | 148 | { |
149 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | 149 | .id = V4L2_CID_AUTO_WHITE_BALANCE, |
150 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 150 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
151 | .name = "auto white balance", | 151 | .name = "auto white balance", |
152 | .minimum = 0, | 152 | .minimum = 0, |
153 | .maximum = 1, | 153 | .maximum = 1, |
154 | .step = 1, | 154 | .step = 1, |
155 | .default_value = 0, | 155 | .default_value = 0, |
156 | }, | 156 | }, |
157 | .set = po1030_set_auto_white_balance, | 157 | .set = po1030_set_auto_white_balance, |
158 | .get = po1030_get_auto_white_balance | 158 | .get = po1030_get_auto_white_balance |
@@ -160,13 +160,13 @@ static const struct ctrl po1030_ctrls[] = { | |||
160 | #define AUTO_EXPOSURE_IDX 7 | 160 | #define AUTO_EXPOSURE_IDX 7 |
161 | { | 161 | { |
162 | { | 162 | { |
163 | .id = V4L2_CID_EXPOSURE_AUTO, | 163 | .id = V4L2_CID_EXPOSURE_AUTO, |
164 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 164 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
165 | .name = "auto exposure", | 165 | .name = "auto exposure", |
166 | .minimum = 0, | 166 | .minimum = 0, |
167 | .maximum = 1, | 167 | .maximum = 1, |
168 | .step = 1, | 168 | .step = 1, |
169 | .default_value = 0, | 169 | .default_value = 0, |
170 | }, | 170 | }, |
171 | .set = po1030_set_auto_exposure, | 171 | .set = po1030_set_auto_exposure, |
172 | .get = po1030_get_auto_exposure | 172 | .get = po1030_get_auto_exposure |
@@ -174,14 +174,14 @@ static const struct ctrl po1030_ctrls[] = { | |||
174 | #define GREEN_BALANCE_IDX 8 | 174 | #define GREEN_BALANCE_IDX 8 |
175 | { | 175 | { |
176 | { | 176 | { |
177 | .id = M5602_V4L2_CID_GREEN_BALANCE, | 177 | .id = M5602_V4L2_CID_GREEN_BALANCE, |
178 | .type = V4L2_CTRL_TYPE_INTEGER, | 178 | .type = V4L2_CTRL_TYPE_INTEGER, |
179 | .name = "green balance", | 179 | .name = "green balance", |
180 | .minimum = 0x00, | 180 | .minimum = 0x00, |
181 | .maximum = 0xff, | 181 | .maximum = 0xff, |
182 | .step = 0x1, | 182 | .step = 0x1, |
183 | .default_value = PO1030_GREEN_GAIN_DEFAULT, | 183 | .default_value = PO1030_GREEN_GAIN_DEFAULT, |
184 | .flags = V4L2_CTRL_FLAG_SLIDER | 184 | .flags = V4L2_CTRL_FLAG_SLIDER |
185 | }, | 185 | }, |
186 | .set = po1030_set_green_balance, | 186 | .set = po1030_set_green_balance, |
187 | .get = po1030_get_green_balance | 187 | .get = po1030_get_green_balance |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index 1ea380b2bbe..33835959639 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h | |||
@@ -139,9 +139,9 @@ | |||
139 | 139 | ||
140 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 | 140 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 |
141 | #define PO1030_EXPOSURE_DEFAULT 0x0085 | 141 | #define PO1030_EXPOSURE_DEFAULT 0x0085 |
142 | #define PO1030_BLUE_GAIN_DEFAULT 0x36 | 142 | #define PO1030_BLUE_GAIN_DEFAULT 0x36 |
143 | #define PO1030_RED_GAIN_DEFAULT 0x36 | 143 | #define PO1030_RED_GAIN_DEFAULT 0x36 |
144 | #define PO1030_GREEN_GAIN_DEFAULT 0x40 | 144 | #define PO1030_GREEN_GAIN_DEFAULT 0x40 |
145 | 145 | ||
146 | /*****************************************************************************/ | 146 | /*****************************************************************************/ |
147 | 147 | ||
@@ -166,8 +166,7 @@ static const struct m5602_sensor po1030 = { | |||
166 | .disconnect = po1030_disconnect, | 166 | .disconnect = po1030_disconnect, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static const unsigned char preinit_po1030[][3] = | 169 | static const unsigned char preinit_po1030[][3] = { |
170 | { | ||
171 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 170 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
172 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 171 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
173 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
@@ -193,8 +192,7 @@ static const unsigned char preinit_po1030[][3] = | |||
193 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} | 192 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} |
194 | }; | 193 | }; |
195 | 194 | ||
196 | static const unsigned char init_po1030[][3] = | 195 | static const unsigned char init_po1030[][3] = { |
197 | { | ||
198 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 196 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
199 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 197 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
200 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 198 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
@@ -271,5 +269,4 @@ static const unsigned char init_po1030[][3] = | |||
271 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 269 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
272 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | 270 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, |
273 | }; | 271 | }; |
274 | |||
275 | #endif | 272 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index da0a38c7870..d27280be985 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -143,13 +143,13 @@ static const struct ctrl s5k4aa_ctrls[] = { | |||
143 | #define VFLIP_IDX 0 | 143 | #define VFLIP_IDX 0 |
144 | { | 144 | { |
145 | { | 145 | { |
146 | .id = V4L2_CID_VFLIP, | 146 | .id = V4L2_CID_VFLIP, |
147 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 147 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
148 | .name = "vertical flip", | 148 | .name = "vertical flip", |
149 | .minimum = 0, | 149 | .minimum = 0, |
150 | .maximum = 1, | 150 | .maximum = 1, |
151 | .step = 1, | 151 | .step = 1, |
152 | .default_value = 0 | 152 | .default_value = 0 |
153 | }, | 153 | }, |
154 | .set = s5k4aa_set_vflip, | 154 | .set = s5k4aa_set_vflip, |
155 | .get = s5k4aa_get_vflip | 155 | .get = s5k4aa_get_vflip |
@@ -157,13 +157,13 @@ static const struct ctrl s5k4aa_ctrls[] = { | |||
157 | #define HFLIP_IDX 1 | 157 | #define HFLIP_IDX 1 |
158 | { | 158 | { |
159 | { | 159 | { |
160 | .id = V4L2_CID_HFLIP, | 160 | .id = V4L2_CID_HFLIP, |
161 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 161 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
162 | .name = "horizontal flip", | 162 | .name = "horizontal flip", |
163 | .minimum = 0, | 163 | .minimum = 0, |
164 | .maximum = 1, | 164 | .maximum = 1, |
165 | .step = 1, | 165 | .step = 1, |
166 | .default_value = 0 | 166 | .default_value = 0 |
167 | }, | 167 | }, |
168 | .set = s5k4aa_set_hflip, | 168 | .set = s5k4aa_set_hflip, |
169 | .get = s5k4aa_get_hflip | 169 | .get = s5k4aa_get_hflip |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index 4440da4e7f0..8cc7a3f6da7 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h | |||
@@ -83,8 +83,7 @@ static const struct m5602_sensor s5k4aa = { | |||
83 | .disconnect = s5k4aa_disconnect, | 83 | .disconnect = s5k4aa_disconnect, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static const unsigned char preinit_s5k4aa[][4] = | 86 | static const unsigned char preinit_s5k4aa[][4] = { |
87 | { | ||
88 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 87 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
89 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | 88 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, |
90 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 89 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
@@ -127,8 +126,7 @@ static const unsigned char preinit_s5k4aa[][4] = | |||
127 | {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00} | 126 | {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00} |
128 | }; | 127 | }; |
129 | 128 | ||
130 | static const unsigned char init_s5k4aa[][4] = | 129 | static const unsigned char init_s5k4aa[][4] = { |
131 | { | ||
132 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 130 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
133 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | 131 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, |
134 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 132 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
@@ -179,8 +177,7 @@ static const unsigned char init_s5k4aa[][4] = | |||
179 | {SENSOR, 0x37, 0x00, 0x00}, | 177 | {SENSOR, 0x37, 0x00, 0x00}, |
180 | }; | 178 | }; |
181 | 179 | ||
182 | static const unsigned char VGA_s5k4aa[][4] = | 180 | static const unsigned char VGA_s5k4aa[][4] = { |
183 | { | ||
184 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 181 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
185 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 182 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
186 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 183 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -235,8 +232,7 @@ static const unsigned char VGA_s5k4aa[][4] = | |||
235 | {SENSOR, 0x02, 0x0e, 0x00}, | 232 | {SENSOR, 0x02, 0x0e, 0x00}, |
236 | }; | 233 | }; |
237 | 234 | ||
238 | static const unsigned char SXGA_s5k4aa[][4] = | 235 | static const unsigned char SXGA_s5k4aa[][4] = { |
239 | { | ||
240 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 236 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
241 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 237 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
242 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 238 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -284,6 +280,4 @@ static const unsigned char SXGA_s5k4aa[][4] = | |||
284 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 280 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
285 | {SENSOR, 0x02, 0x0e, 0x00}, | 281 | {SENSOR, 0x02, 0x0e, 0x00}, |
286 | }; | 282 | }; |
287 | |||
288 | |||
289 | #endif | 283 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 7814b078acd..80a63a236e2 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #define S5K83A_MAXIMUM_EXPOSURE 0x3c | 35 | #define S5K83A_MAXIMUM_EXPOSURE 0x3c |
36 | #define S5K83A_FLIP_MASK 0x10 | 36 | #define S5K83A_FLIP_MASK 0x10 |
37 | #define S5K83A_GPIO_LED_MASK 0x10 | 37 | #define S5K83A_GPIO_LED_MASK 0x10 |
38 | #define S5K83A_GPIO_ROTATION_MASK 0x40 | 38 | #define S5K83A_GPIO_ROTATION_MASK 0x40 |
39 | 39 | ||
40 | /*****************************************************************************/ | 40 | /*****************************************************************************/ |
41 | 41 | ||
@@ -67,8 +67,7 @@ struct s5k83a_priv { | |||
67 | s32 *settings; | 67 | s32 *settings; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static const unsigned char preinit_s5k83a[][4] = | 70 | static const unsigned char preinit_s5k83a[][4] = { |
71 | { | ||
72 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 71 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
73 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | 72 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, |
74 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 73 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
@@ -108,8 +107,7 @@ static const unsigned char preinit_s5k83a[][4] = | |||
108 | /* This could probably be considerably shortened. | 107 | /* This could probably be considerably shortened. |
109 | I don't have the hardware to experiment with it, patches welcome | 108 | I don't have the hardware to experiment with it, patches welcome |
110 | */ | 109 | */ |
111 | static const unsigned char init_s5k83a[][4] = | 110 | static const unsigned char init_s5k83a[][4] = { |
112 | { | ||
113 | /* The following sequence is useless after a clean boot | 111 | /* The following sequence is useless after a clean boot |
114 | but is necessary after resume from suspend */ | 112 | but is necessary after resume from suspend */ |
115 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 113 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
@@ -166,8 +164,7 @@ static const unsigned char init_s5k83a[][4] = | |||
166 | {SENSOR, 0x00, 0x06, 0x00}, | 164 | {SENSOR, 0x00, 0x06, 0x00}, |
167 | }; | 165 | }; |
168 | 166 | ||
169 | static const unsigned char start_s5k83a[][4] = | 167 | static const unsigned char start_s5k83a[][4] = { |
170 | { | ||
171 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 168 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
172 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 169 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
173 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 170 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -193,5 +190,4 @@ static const unsigned char start_s5k83a[][4] = | |||
193 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 190 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
194 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 191 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
195 | }; | 192 | }; |
196 | |||
197 | #endif | 193 | #endif |
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 031f7195ce0..a81536e7869 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
@@ -28,14 +28,23 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
28 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); | 28 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); |
29 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
30 | 30 | ||
31 | /* controls */ | ||
32 | enum e_ctrl { | ||
33 | BRIGHTNESS, | ||
34 | COLORS, | ||
35 | GAMMA, | ||
36 | SHARPNESS, | ||
37 | ILLUM_TOP, | ||
38 | ILLUM_BOT, | ||
39 | NCTRLS /* number of controls */ | ||
40 | }; | ||
41 | |||
31 | /* specific webcam descriptor */ | 42 | /* specific webcam descriptor */ |
32 | struct sd { | 43 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 44 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 45 | ||
35 | u8 brightness; | 46 | struct gspca_ctrl ctrls[NCTRLS]; |
36 | u8 colors; | 47 | |
37 | u8 gamma; | ||
38 | u8 sharpness; | ||
39 | u8 quality; | 48 | u8 quality; |
40 | #define QUALITY_MIN 40 | 49 | #define QUALITY_MIN 40 |
41 | #define QUALITY_MAX 70 | 50 | #define QUALITY_MAX 70 |
@@ -45,17 +54,15 @@ struct sd { | |||
45 | }; | 54 | }; |
46 | 55 | ||
47 | /* V4L2 controls supported by the driver */ | 56 | /* V4L2 controls supported by the driver */ |
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 57 | static void setbrightness(struct gspca_dev *gspca_dev); |
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 58 | static void setcolors(struct gspca_dev *gspca_dev); |
50 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 59 | static void setgamma(struct gspca_dev *gspca_dev); |
51 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 60 | static void setsharpness(struct gspca_dev *gspca_dev); |
52 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | 61 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val); |
53 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | 62 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val); |
54 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | 63 | |
55 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | 64 | static const struct ctrl sd_ctrls[NCTRLS] = { |
56 | 65 | [BRIGHTNESS] = { | |
57 | static const struct ctrl sd_ctrls[] = { | ||
58 | { | ||
59 | { | 66 | { |
60 | .id = V4L2_CID_BRIGHTNESS, | 67 | .id = V4L2_CID_BRIGHTNESS, |
61 | .type = V4L2_CTRL_TYPE_INTEGER, | 68 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -63,13 +70,11 @@ static const struct ctrl sd_ctrls[] = { | |||
63 | .minimum = 0, | 70 | .minimum = 0, |
64 | .maximum = 30, | 71 | .maximum = 30, |
65 | .step = 1, | 72 | .step = 1, |
66 | #define BRIGHTNESS_DEF 15 | 73 | .default_value = 15, |
67 | .default_value = BRIGHTNESS_DEF, | ||
68 | }, | 74 | }, |
69 | .set = sd_setbrightness, | 75 | .set_control = setbrightness |
70 | .get = sd_getbrightness, | ||
71 | }, | 76 | }, |
72 | { | 77 | [COLORS] = { |
73 | { | 78 | { |
74 | .id = V4L2_CID_SATURATION, | 79 | .id = V4L2_CID_SATURATION, |
75 | .type = V4L2_CTRL_TYPE_INTEGER, | 80 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -77,13 +82,11 @@ static const struct ctrl sd_ctrls[] = { | |||
77 | .minimum = 1, | 82 | .minimum = 1, |
78 | .maximum = 255, | 83 | .maximum = 255, |
79 | .step = 1, | 84 | .step = 1, |
80 | #define COLOR_DEF 200 | 85 | .default_value = 200, |
81 | .default_value = COLOR_DEF, | ||
82 | }, | 86 | }, |
83 | .set = sd_setcolors, | 87 | .set_control = setcolors |
84 | .get = sd_getcolors, | ||
85 | }, | 88 | }, |
86 | { | 89 | [GAMMA] = { |
87 | { | 90 | { |
88 | .id = V4L2_CID_GAMMA, | 91 | .id = V4L2_CID_GAMMA, |
89 | .type = V4L2_CTRL_TYPE_INTEGER, | 92 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -91,13 +94,11 @@ static const struct ctrl sd_ctrls[] = { | |||
91 | .minimum = 0, | 94 | .minimum = 0, |
92 | .maximum = 3, | 95 | .maximum = 3, |
93 | .step = 1, | 96 | .step = 1, |
94 | #define GAMMA_DEF 1 | 97 | .default_value = 1, |
95 | .default_value = GAMMA_DEF, | ||
96 | }, | 98 | }, |
97 | .set = sd_setgamma, | 99 | .set_control = setgamma |
98 | .get = sd_getgamma, | ||
99 | }, | 100 | }, |
100 | { | 101 | [SHARPNESS] = { |
101 | { | 102 | { |
102 | .id = V4L2_CID_SHARPNESS, | 103 | .id = V4L2_CID_SHARPNESS, |
103 | .type = V4L2_CTRL_TYPE_INTEGER, | 104 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -105,11 +106,35 @@ static const struct ctrl sd_ctrls[] = { | |||
105 | .minimum = 0, | 106 | .minimum = 0, |
106 | .maximum = 2, | 107 | .maximum = 2, |
107 | .step = 1, | 108 | .step = 1, |
108 | #define SHARPNESS_DEF 1 | 109 | .default_value = 1, |
109 | .default_value = SHARPNESS_DEF, | 110 | }, |
111 | .set_control = setsharpness | ||
112 | }, | ||
113 | [ILLUM_TOP] = { | ||
114 | { | ||
115 | .id = V4L2_CID_ILLUMINATORS_1, | ||
116 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
117 | .name = "Top illuminator", | ||
118 | .minimum = 0, | ||
119 | .maximum = 1, | ||
120 | .step = 1, | ||
121 | .default_value = 0, | ||
122 | .flags = V4L2_CTRL_FLAG_UPDATE, | ||
123 | }, | ||
124 | .set = sd_setilluminator1 | ||
125 | }, | ||
126 | [ILLUM_BOT] = { | ||
127 | { | ||
128 | .id = V4L2_CID_ILLUMINATORS_2, | ||
129 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
130 | .name = "Bottom illuminator", | ||
131 | .minimum = 0, | ||
132 | .maximum = 1, | ||
133 | .step = 1, | ||
134 | .default_value = 0, | ||
135 | .flags = V4L2_CTRL_FLAG_UPDATE, | ||
110 | }, | 136 | }, |
111 | .set = sd_setsharpness, | 137 | .set = sd_setilluminator2 |
112 | .get = sd_getsharpness, | ||
113 | }, | 138 | }, |
114 | }; | 139 | }; |
115 | 140 | ||
@@ -138,21 +163,25 @@ static const __u8 mi_data[0x20] = { | |||
138 | }; | 163 | }; |
139 | 164 | ||
140 | /* write <len> bytes from gspca_dev->usb_buf */ | 165 | /* write <len> bytes from gspca_dev->usb_buf */ |
141 | static int reg_w(struct gspca_dev *gspca_dev, | 166 | static void reg_w(struct gspca_dev *gspca_dev, |
142 | int len) | 167 | int len) |
143 | { | 168 | { |
144 | int alen, ret; | 169 | int alen, ret; |
145 | 170 | ||
171 | if (gspca_dev->usb_err < 0) | ||
172 | return; | ||
173 | |||
146 | ret = usb_bulk_msg(gspca_dev->dev, | 174 | ret = usb_bulk_msg(gspca_dev->dev, |
147 | usb_sndbulkpipe(gspca_dev->dev, 4), | 175 | usb_sndbulkpipe(gspca_dev->dev, 4), |
148 | gspca_dev->usb_buf, | 176 | gspca_dev->usb_buf, |
149 | len, | 177 | len, |
150 | &alen, | 178 | &alen, |
151 | 500); /* timeout in milliseconds */ | 179 | 500); /* timeout in milliseconds */ |
152 | if (ret < 0) | 180 | if (ret < 0) { |
153 | PDEBUG(D_ERR, "reg write [%02x] error %d", | 181 | err("reg write [%02x] error %d", |
154 | gspca_dev->usb_buf[0], ret); | 182 | gspca_dev->usb_buf[0], ret); |
155 | return ret; | 183 | gspca_dev->usb_err = ret; |
184 | } | ||
156 | } | 185 | } |
157 | 186 | ||
158 | static void mi_w(struct gspca_dev *gspca_dev, | 187 | static void mi_w(struct gspca_dev *gspca_dev, |
@@ -167,6 +196,59 @@ static void mi_w(struct gspca_dev *gspca_dev, | |||
167 | reg_w(gspca_dev, 4); | 196 | reg_w(gspca_dev, 4); |
168 | } | 197 | } |
169 | 198 | ||
199 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
200 | { | ||
201 | struct sd *sd = (struct sd *) gspca_dev; | ||
202 | |||
203 | gspca_dev->usb_buf[0] = 0x61; | ||
204 | gspca_dev->usb_buf[1] = sd->ctrls[BRIGHTNESS].val; | ||
205 | reg_w(gspca_dev, 2); | ||
206 | } | ||
207 | |||
208 | static void setcolors(struct gspca_dev *gspca_dev) | ||
209 | { | ||
210 | struct sd *sd = (struct sd *) gspca_dev; | ||
211 | s16 val; | ||
212 | |||
213 | val = sd->ctrls[COLORS].val; | ||
214 | gspca_dev->usb_buf[0] = 0x5f; | ||
215 | gspca_dev->usb_buf[1] = val << 3; | ||
216 | gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04; | ||
217 | reg_w(gspca_dev, 3); | ||
218 | } | ||
219 | |||
220 | static void setgamma(struct gspca_dev *gspca_dev) | ||
221 | { | ||
222 | struct sd *sd = (struct sd *) gspca_dev; | ||
223 | |||
224 | gspca_dev->usb_buf[0] = 0x06; | ||
225 | gspca_dev->usb_buf[1] = sd->ctrls[GAMMA].val * 0x40; | ||
226 | reg_w(gspca_dev, 2); | ||
227 | } | ||
228 | |||
229 | static void setsharpness(struct gspca_dev *gspca_dev) | ||
230 | { | ||
231 | struct sd *sd = (struct sd *) gspca_dev; | ||
232 | |||
233 | gspca_dev->usb_buf[0] = 0x67; | ||
234 | gspca_dev->usb_buf[1] = sd->ctrls[SHARPNESS].val * 4 + 3; | ||
235 | reg_w(gspca_dev, 2); | ||
236 | } | ||
237 | |||
238 | static void setilluminators(struct gspca_dev *gspca_dev) | ||
239 | { | ||
240 | struct sd *sd = (struct sd *) gspca_dev; | ||
241 | |||
242 | gspca_dev->usb_buf[0] = 0x22; | ||
243 | if (sd->ctrls[ILLUM_TOP].val) | ||
244 | gspca_dev->usb_buf[1] = 0x76; | ||
245 | else if (sd->ctrls[ILLUM_BOT].val) | ||
246 | gspca_dev->usb_buf[1] = 0x7a; | ||
247 | else | ||
248 | gspca_dev->usb_buf[1] = 0x7e; | ||
249 | reg_w(gspca_dev, 2); | ||
250 | } | ||
251 | |||
170 | /* this function is called at probe time */ | 252 | /* this function is called at probe time */ |
171 | static int sd_config(struct gspca_dev *gspca_dev, | 253 | static int sd_config(struct gspca_dev *gspca_dev, |
172 | const struct usb_device_id *id) | 254 | const struct usb_device_id *id) |
@@ -177,10 +259,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
177 | cam = &gspca_dev->cam; | 259 | cam = &gspca_dev->cam; |
178 | cam->cam_mode = vga_mode; | 260 | cam->cam_mode = vga_mode; |
179 | cam->nmodes = ARRAY_SIZE(vga_mode); | 261 | cam->nmodes = ARRAY_SIZE(vga_mode); |
180 | sd->brightness = BRIGHTNESS_DEF; | 262 | cam->ctrls = sd->ctrls; |
181 | sd->colors = COLOR_DEF; | ||
182 | sd->gamma = GAMMA_DEF; | ||
183 | sd->sharpness = SHARPNESS_DEF; | ||
184 | sd->quality = QUALITY_DEF; | 263 | sd->quality = QUALITY_DEF; |
185 | gspca_dev->nbalt = 9; /* use the altsetting 08 */ | 264 | gspca_dev->nbalt = 9; /* use the altsetting 08 */ |
186 | return 0; | 265 | return 0; |
@@ -189,13 +268,13 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
189 | /* this function is called at probe and resume time */ | 268 | /* this function is called at probe and resume time */ |
190 | static int sd_init(struct gspca_dev *gspca_dev) | 269 | static int sd_init(struct gspca_dev *gspca_dev) |
191 | { | 270 | { |
271 | gspca_dev->ctrl_inac = (1 << ILLUM_TOP) | (1 << ILLUM_BOT); | ||
192 | return 0; | 272 | return 0; |
193 | } | 273 | } |
194 | 274 | ||
195 | static int sd_start(struct gspca_dev *gspca_dev) | 275 | static int sd_start(struct gspca_dev *gspca_dev) |
196 | { | 276 | { |
197 | struct sd *sd = (struct sd *) gspca_dev; | 277 | struct sd *sd = (struct sd *) gspca_dev; |
198 | int err_code; | ||
199 | u8 *data; | 278 | u8 *data; |
200 | int i; | 279 | int i; |
201 | 280 | ||
@@ -208,9 +287,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
208 | 287 | ||
209 | data[0] = 0x01; /* address */ | 288 | data[0] = 0x01; /* address */ |
210 | data[1] = 0x01; | 289 | data[1] = 0x01; |
211 | err_code = reg_w(gspca_dev, 2); | 290 | reg_w(gspca_dev, 2); |
212 | if (err_code < 0) | ||
213 | return err_code; | ||
214 | 291 | ||
215 | /* | 292 | /* |
216 | Initialize the MR97113 chip register | 293 | Initialize the MR97113 chip register |
@@ -223,7 +300,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
223 | data[5] = 0x30; /* reg 4, MI, PAS5101 : | 300 | data[5] = 0x30; /* reg 4, MI, PAS5101 : |
224 | * 0x30 for 24mhz , 0x28 for 12mhz */ | 301 | * 0x30 for 24mhz , 0x28 for 12mhz */ |
225 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ | 302 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ |
226 | data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */ | 303 | data[7] = sd->ctrls[GAMMA].val * 0x40; /* reg 0x06: gamma */ |
227 | data[8] = 0x01; /* reg 7, V start - was 0x03 */ | 304 | data[8] = 0x01; /* reg 7, V start - was 0x03 */ |
228 | /* if (h_size == 320 ) */ | 305 | /* if (h_size == 320 ) */ |
229 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ | 306 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ |
@@ -232,16 +309,12 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
232 | /*jfm: from win trace*/ | 309 | /*jfm: from win trace*/ |
233 | data[10] = 0x18; | 310 | data[10] = 0x18; |
234 | 311 | ||
235 | err_code = reg_w(gspca_dev, 11); | 312 | reg_w(gspca_dev, 11); |
236 | if (err_code < 0) | ||
237 | return err_code; | ||
238 | 313 | ||
239 | data[0] = 0x23; /* address */ | 314 | data[0] = 0x23; /* address */ |
240 | data[1] = 0x09; /* reg 35, append frame header */ | 315 | data[1] = 0x09; /* reg 35, append frame header */ |
241 | 316 | ||
242 | err_code = reg_w(gspca_dev, 2); | 317 | reg_w(gspca_dev, 2); |
243 | if (err_code < 0) | ||
244 | return err_code; | ||
245 | 318 | ||
246 | data[0] = 0x3c; /* address */ | 319 | data[0] = 0x3c; /* address */ |
247 | /* if (gspca_dev->width == 1280) */ | 320 | /* if (gspca_dev->width == 1280) */ |
@@ -250,9 +323,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
250 | /* else */ | 323 | /* else */ |
251 | data[1] = 50; /* 50 reg 60, pc-cam frame size | 324 | data[1] = 50; /* 50 reg 60, pc-cam frame size |
252 | * (unit: 4KB) 200KB */ | 325 | * (unit: 4KB) 200KB */ |
253 | err_code = reg_w(gspca_dev, 2); | 326 | reg_w(gspca_dev, 2); |
254 | if (err_code < 0) | ||
255 | return err_code; | ||
256 | 327 | ||
257 | /* auto dark-gain */ | 328 | /* auto dark-gain */ |
258 | data[0] = 0x5e; /* address */ | 329 | data[0] = 0x5e; /* address */ |
@@ -261,37 +332,29 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
261 | /* reg 0x5f/0x60 (LE) = saturation */ | 332 | /* reg 0x5f/0x60 (LE) = saturation */ |
262 | /* h (60): xxxx x100 | 333 | /* h (60): xxxx x100 |
263 | * l (5f): xxxx x000 */ | 334 | * l (5f): xxxx x000 */ |
264 | data[2] = sd->colors << 3; | 335 | data[2] = sd->ctrls[COLORS].val << 3; |
265 | data[3] = ((sd->colors >> 2) & 0xf8) | 0x04; | 336 | data[3] = ((sd->ctrls[COLORS].val >> 2) & 0xf8) | 0x04; |
266 | data[4] = sd->brightness; /* reg 0x61 = brightness */ | 337 | data[4] = sd->ctrls[BRIGHTNESS].val; /* reg 0x61 = brightness */ |
267 | data[5] = 0x00; | 338 | data[5] = 0x00; |
268 | 339 | ||
269 | err_code = reg_w(gspca_dev, 6); | 340 | reg_w(gspca_dev, 6); |
270 | if (err_code < 0) | ||
271 | return err_code; | ||
272 | 341 | ||
273 | data[0] = 0x67; | 342 | data[0] = 0x67; |
274 | /*jfm: from win trace*/ | 343 | /*jfm: from win trace*/ |
275 | data[1] = sd->sharpness * 4 + 3; | 344 | data[1] = sd->ctrls[SHARPNESS].val * 4 + 3; |
276 | data[2] = 0x14; | 345 | data[2] = 0x14; |
277 | err_code = reg_w(gspca_dev, 3); | 346 | reg_w(gspca_dev, 3); |
278 | if (err_code < 0) | ||
279 | return err_code; | ||
280 | 347 | ||
281 | data[0] = 0x69; | 348 | data[0] = 0x69; |
282 | data[1] = 0x2f; | 349 | data[1] = 0x2f; |
283 | data[2] = 0x28; | 350 | data[2] = 0x28; |
284 | data[3] = 0x42; | 351 | data[3] = 0x42; |
285 | err_code = reg_w(gspca_dev, 4); | 352 | reg_w(gspca_dev, 4); |
286 | if (err_code < 0) | ||
287 | return err_code; | ||
288 | 353 | ||
289 | data[0] = 0x63; | 354 | data[0] = 0x63; |
290 | data[1] = 0x07; | 355 | data[1] = 0x07; |
291 | err_code = reg_w(gspca_dev, 2); | 356 | reg_w(gspca_dev, 2); |
292 | /*jfm: win trace - many writes here to reg 0x64*/ | 357 | /*jfm: win trace - many writes here to reg 0x64*/ |
293 | if (err_code < 0) | ||
294 | return err_code; | ||
295 | 358 | ||
296 | /* initialize the MI sensor */ | 359 | /* initialize the MI sensor */ |
297 | for (i = 0; i < sizeof mi_data; i++) | 360 | for (i = 0; i < sizeof mi_data; i++) |
@@ -300,18 +363,26 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
300 | data[0] = 0x00; | 363 | data[0] = 0x00; |
301 | data[1] = 0x4d; /* ISOC transfering enable... */ | 364 | data[1] = 0x4d; /* ISOC transfering enable... */ |
302 | reg_w(gspca_dev, 2); | 365 | reg_w(gspca_dev, 2); |
303 | return 0; | 366 | |
367 | gspca_dev->ctrl_inac = 0; /* activate the illuminator controls */ | ||
368 | return gspca_dev->usb_err; | ||
304 | } | 369 | } |
305 | 370 | ||
306 | static void sd_stopN(struct gspca_dev *gspca_dev) | 371 | static void sd_stopN(struct gspca_dev *gspca_dev) |
307 | { | 372 | { |
308 | int result; | 373 | struct sd *sd = (struct sd *) gspca_dev; |
374 | |||
375 | gspca_dev->ctrl_inac = (1 << ILLUM_TOP) | (1 << ILLUM_BOT); | ||
376 | if (sd->ctrls[ILLUM_TOP].val || sd->ctrls[ILLUM_BOT].val) { | ||
377 | sd->ctrls[ILLUM_TOP].val = 0; | ||
378 | sd->ctrls[ILLUM_BOT].val = 0; | ||
379 | setilluminators(gspca_dev); | ||
380 | msleep(20); | ||
381 | } | ||
309 | 382 | ||
310 | gspca_dev->usb_buf[0] = 1; | 383 | gspca_dev->usb_buf[0] = 1; |
311 | gspca_dev->usb_buf[1] = 0; | 384 | gspca_dev->usb_buf[1] = 0; |
312 | result = reg_w(gspca_dev, 2); | 385 | reg_w(gspca_dev, 2); |
313 | if (result < 0) | ||
314 | PDEBUG(D_ERR, "Camera Stop failed"); | ||
315 | } | 386 | } |
316 | 387 | ||
317 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 388 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
@@ -352,91 +423,28 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
352 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 423 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
353 | } | 424 | } |
354 | 425 | ||
355 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 426 | static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val) |
356 | { | ||
357 | struct sd *sd = (struct sd *) gspca_dev; | ||
358 | |||
359 | sd->brightness = val; | ||
360 | if (gspca_dev->streaming) { | ||
361 | gspca_dev->usb_buf[0] = 0x61; | ||
362 | gspca_dev->usb_buf[1] = val; | ||
363 | reg_w(gspca_dev, 2); | ||
364 | } | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
369 | { | 427 | { |
370 | struct sd *sd = (struct sd *) gspca_dev; | 428 | struct sd *sd = (struct sd *) gspca_dev; |
371 | 429 | ||
372 | *val = sd->brightness; | 430 | /* only one illuminator may be on */ |
373 | return 0; | 431 | sd->ctrls[ILLUM_TOP].val = val; |
432 | if (val) | ||
433 | sd->ctrls[ILLUM_BOT].val = 0; | ||
434 | setilluminators(gspca_dev); | ||
435 | return gspca_dev->usb_err; | ||
374 | } | 436 | } |
375 | 437 | ||
376 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | 438 | static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val) |
377 | { | 439 | { |
378 | struct sd *sd = (struct sd *) gspca_dev; | 440 | struct sd *sd = (struct sd *) gspca_dev; |
379 | 441 | ||
380 | sd->colors = val; | 442 | /* only one illuminator may be on */ |
381 | if (gspca_dev->streaming) { | 443 | sd->ctrls[ILLUM_BOT].val = val; |
382 | 444 | if (val) | |
383 | /* see sd_start */ | 445 | sd->ctrls[ILLUM_TOP].val = 0; |
384 | gspca_dev->usb_buf[0] = 0x5f; | 446 | setilluminators(gspca_dev); |
385 | gspca_dev->usb_buf[1] = sd->colors << 3; | 447 | return gspca_dev->usb_err; |
386 | gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04; | ||
387 | reg_w(gspca_dev, 3); | ||
388 | } | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
393 | { | ||
394 | struct sd *sd = (struct sd *) gspca_dev; | ||
395 | |||
396 | *val = sd->colors; | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
401 | { | ||
402 | struct sd *sd = (struct sd *) gspca_dev; | ||
403 | |||
404 | sd->gamma = val; | ||
405 | if (gspca_dev->streaming) { | ||
406 | gspca_dev->usb_buf[0] = 0x06; | ||
407 | gspca_dev->usb_buf[1] = val * 0x40; | ||
408 | reg_w(gspca_dev, 2); | ||
409 | } | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
414 | { | ||
415 | struct sd *sd = (struct sd *) gspca_dev; | ||
416 | |||
417 | *val = sd->gamma; | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
422 | { | ||
423 | struct sd *sd = (struct sd *) gspca_dev; | ||
424 | |||
425 | sd->sharpness = val; | ||
426 | if (gspca_dev->streaming) { | ||
427 | gspca_dev->usb_buf[0] = 0x67; | ||
428 | gspca_dev->usb_buf[1] = val * 4 + 3; | ||
429 | reg_w(gspca_dev, 2); | ||
430 | } | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
435 | { | ||
436 | struct sd *sd = (struct sd *) gspca_dev; | ||
437 | |||
438 | *val = sd->sharpness; | ||
439 | return 0; | ||
440 | } | 448 | } |
441 | 449 | ||
442 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 450 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, |
@@ -471,7 +479,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
471 | static const struct sd_desc sd_desc = { | 479 | static const struct sd_desc sd_desc = { |
472 | .name = MODULE_NAME, | 480 | .name = MODULE_NAME, |
473 | .ctrls = sd_ctrls, | 481 | .ctrls = sd_ctrls, |
474 | .nctrls = ARRAY_SIZE(sd_ctrls), | 482 | .nctrls = NCTRLS, |
475 | .config = sd_config, | 483 | .config = sd_config, |
476 | .init = sd_init, | 484 | .init = sd_init, |
477 | .start = sd_start, | 485 | .start = sd_start, |
@@ -510,18 +518,11 @@ static struct usb_driver sd_driver = { | |||
510 | /* -- module insert / remove -- */ | 518 | /* -- module insert / remove -- */ |
511 | static int __init sd_mod_init(void) | 519 | static int __init sd_mod_init(void) |
512 | { | 520 | { |
513 | int ret; | 521 | return usb_register(&sd_driver); |
514 | |||
515 | ret = usb_register(&sd_driver); | ||
516 | if (ret < 0) | ||
517 | return ret; | ||
518 | PDEBUG(D_PROBE, "registered"); | ||
519 | return 0; | ||
520 | } | 522 | } |
521 | static void __exit sd_mod_exit(void) | 523 | static void __exit sd_mod_exit(void) |
522 | { | 524 | { |
523 | usb_deregister(&sd_driver); | 525 | usb_deregister(&sd_driver); |
524 | PDEBUG(D_PROBE, "deregistered"); | ||
525 | } | 526 | } |
526 | 527 | ||
527 | module_init(sd_mod_init); | 528 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 33744e724ea..7607a288b51 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -9,14 +9,14 @@ | |||
9 | * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> | 9 | * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> |
10 | * | 10 | * |
11 | * Support for the control settings for the CIF cameras is | 11 | * Support for the control settings for the CIF cameras is |
12 | * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and | 12 | * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and |
13 | * Thomas Kaiser <thomas@kaiser-linux.li> | 13 | * Thomas Kaiser <thomas@kaiser-linux.li> |
14 | * | 14 | * |
15 | * Support for the control settings for the VGA cameras is | 15 | * Support for the control settings for the VGA cameras is |
16 | * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> | 16 | * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> |
17 | * | 17 | * |
18 | * Several previously unsupported cameras are owned and have been tested by | 18 | * Several previously unsupported cameras are owned and have been tested by |
19 | * Hans de Goede <hdgoede@redhat.com> and | 19 | * Hans de Goede <hdegoede@redhat.com> and |
20 | * Thomas Kaiser <thomas@kaiser-linux.li> and | 20 | * Thomas Kaiser <thomas@kaiser-linux.li> and |
21 | * Theodore Kilgore <kilgota@auburn.edu> and | 21 | * Theodore Kilgore <kilgota@auburn.edu> and |
22 | * Edmond Rodriguez <erodrig_97@yahoo.com> and | 22 | * Edmond Rodriguez <erodrig_97@yahoo.com> and |
@@ -267,7 +267,7 @@ static int mr_write(struct gspca_dev *gspca_dev, int len) | |||
267 | usb_sndbulkpipe(gspca_dev->dev, 4), | 267 | usb_sndbulkpipe(gspca_dev->dev, 4), |
268 | gspca_dev->usb_buf, len, NULL, 500); | 268 | gspca_dev->usb_buf, len, NULL, 500); |
269 | if (rc < 0) | 269 | if (rc < 0) |
270 | PDEBUG(D_ERR, "reg write [%02x] error %d", | 270 | err("reg write [%02x] error %d", |
271 | gspca_dev->usb_buf[0], rc); | 271 | gspca_dev->usb_buf[0], rc); |
272 | return rc; | 272 | return rc; |
273 | } | 273 | } |
@@ -281,7 +281,7 @@ static int mr_read(struct gspca_dev *gspca_dev, int len) | |||
281 | usb_rcvbulkpipe(gspca_dev->dev, 3), | 281 | usb_rcvbulkpipe(gspca_dev->dev, 3), |
282 | gspca_dev->usb_buf, len, NULL, 500); | 282 | gspca_dev->usb_buf, len, NULL, 500); |
283 | if (rc < 0) | 283 | if (rc < 0) |
284 | PDEBUG(D_ERR, "reg read [%02x] error %d", | 284 | err("reg read [%02x] error %d", |
285 | gspca_dev->usb_buf[0], rc); | 285 | gspca_dev->usb_buf[0], rc); |
286 | return rc; | 286 | return rc; |
287 | } | 287 | } |
@@ -540,7 +540,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
540 | sd->sensor_type = 1; | 540 | sd->sensor_type = 1; |
541 | break; | 541 | break; |
542 | default: | 542 | default: |
543 | PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x", | 543 | err("Unknown CIF Sensor id : %02x", |
544 | gspca_dev->usb_buf[1]); | 544 | gspca_dev->usb_buf[1]); |
545 | return -ENODEV; | 545 | return -ENODEV; |
546 | } | 546 | } |
@@ -575,10 +575,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
575 | sd->sensor_type = 2; | 575 | sd->sensor_type = 2; |
576 | } else if ((gspca_dev->usb_buf[0] != 0x03) && | 576 | } else if ((gspca_dev->usb_buf[0] != 0x03) && |
577 | (gspca_dev->usb_buf[0] != 0x04)) { | 577 | (gspca_dev->usb_buf[0] != 0x04)) { |
578 | PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", | 578 | err("Unknown VGA Sensor id Byte 0: %02x", |
579 | gspca_dev->usb_buf[0]); | 579 | gspca_dev->usb_buf[0]); |
580 | PDEBUG(D_ERR, "Defaults assumed, may not work"); | 580 | err("Defaults assumed, may not work"); |
581 | PDEBUG(D_ERR, "Please report this"); | 581 | err("Please report this"); |
582 | } | 582 | } |
583 | /* Sakar Digital color needs to be adjusted. */ | 583 | /* Sakar Digital color needs to be adjusted. */ |
584 | if ((gspca_dev->usb_buf[0] == 0x03) && | 584 | if ((gspca_dev->usb_buf[0] == 0x03) && |
@@ -595,12 +595,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
595 | /* Nothing to do here. */ | 595 | /* Nothing to do here. */ |
596 | break; | 596 | break; |
597 | default: | 597 | default: |
598 | PDEBUG(D_ERR, | 598 | err("Unknown VGA Sensor id Byte 1: %02x", |
599 | "Unknown VGA Sensor id Byte 1: %02x", | ||
600 | gspca_dev->usb_buf[1]); | 599 | gspca_dev->usb_buf[1]); |
601 | PDEBUG(D_ERR, | 600 | err("Defaults assumed, may not work"); |
602 | "Defaults assumed, may not work"); | 601 | err("Please report this"); |
603 | PDEBUG(D_ERR, "Please report this"); | ||
604 | } | 602 | } |
605 | } | 603 | } |
606 | PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", | 604 | PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", |
@@ -675,7 +673,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
675 | struct sd *sd = (struct sd *) gspca_dev; | 673 | struct sd *sd = (struct sd *) gspca_dev; |
676 | __u8 *data = gspca_dev->usb_buf; | 674 | __u8 *data = gspca_dev->usb_buf; |
677 | int err_code; | 675 | int err_code; |
678 | const __u8 startup_string[] = { | 676 | static const __u8 startup_string[] = { |
679 | 0x00, | 677 | 0x00, |
680 | 0x0d, | 678 | 0x0d, |
681 | 0x01, | 679 | 0x01, |
@@ -721,7 +719,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
721 | return err_code; | 719 | return err_code; |
722 | 720 | ||
723 | if (!sd->sensor_type) { | 721 | if (!sd->sensor_type) { |
724 | const struct sensor_w_data cif_sensor0_init_data[] = { | 722 | static const struct sensor_w_data cif_sensor0_init_data[] = { |
725 | {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01, | 723 | {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01, |
726 | 0x0f, 0x14, 0x0f, 0x10}, 8}, | 724 | 0x0f, 0x14, 0x0f, 0x10}, 8}, |
727 | {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5}, | 725 | {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5}, |
@@ -742,7 +740,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
742 | err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data, | 740 | err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data, |
743 | ARRAY_SIZE(cif_sensor0_init_data)); | 741 | ARRAY_SIZE(cif_sensor0_init_data)); |
744 | } else { /* sd->sensor_type = 1 */ | 742 | } else { /* sd->sensor_type = 1 */ |
745 | const struct sensor_w_data cif_sensor1_init_data[] = { | 743 | static const struct sensor_w_data cif_sensor1_init_data[] = { |
746 | /* Reg 3,4, 7,8 get set by the controls */ | 744 | /* Reg 3,4, 7,8 get set by the controls */ |
747 | {0x02, 0x00, {0x10}, 1}, | 745 | {0x02, 0x00, {0x10}, 1}, |
748 | {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */ | 746 | {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */ |
@@ -777,8 +775,9 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
777 | struct sd *sd = (struct sd *) gspca_dev; | 775 | struct sd *sd = (struct sd *) gspca_dev; |
778 | __u8 *data = gspca_dev->usb_buf; | 776 | __u8 *data = gspca_dev->usb_buf; |
779 | int err_code; | 777 | int err_code; |
780 | const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, | 778 | static const __u8 startup_string[] = |
781 | 0x00, 0x00, 0x00, 0x50, 0xc0}; | 779 | {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, |
780 | 0x00, 0x50, 0xc0}; | ||
782 | /* What some of these mean is explained in start_cif_cam(), above */ | 781 | /* What some of these mean is explained in start_cif_cam(), above */ |
783 | 782 | ||
784 | memcpy(data, startup_string, 11); | 783 | memcpy(data, startup_string, 11); |
@@ -830,7 +829,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
830 | return err_code; | 829 | return err_code; |
831 | 830 | ||
832 | if (!sd->sensor_type) { | 831 | if (!sd->sensor_type) { |
833 | const struct sensor_w_data vga_sensor0_init_data[] = { | 832 | static const struct sensor_w_data vga_sensor0_init_data[] = { |
834 | {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, | 833 | {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, |
835 | {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, | 834 | {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, |
836 | {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4}, | 835 | {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4}, |
@@ -841,20 +840,20 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
841 | err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, | 840 | err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, |
842 | ARRAY_SIZE(vga_sensor0_init_data)); | 841 | ARRAY_SIZE(vga_sensor0_init_data)); |
843 | } else if (sd->sensor_type == 1) { | 842 | } else if (sd->sensor_type == 1) { |
844 | const struct sensor_w_data color_adj[] = { | 843 | static const struct sensor_w_data color_adj[] = { |
845 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, | 844 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, |
846 | /* adjusted blue, green, red gain correct | 845 | /* adjusted blue, green, red gain correct |
847 | too much blue from the Sakar Digital */ | 846 | too much blue from the Sakar Digital */ |
848 | 0x05, 0x01, 0x04}, 8} | 847 | 0x05, 0x01, 0x04}, 8} |
849 | }; | 848 | }; |
850 | 849 | ||
851 | const struct sensor_w_data color_no_adj[] = { | 850 | static const struct sensor_w_data color_no_adj[] = { |
852 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, | 851 | {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, |
853 | /* default blue, green, red gain settings */ | 852 | /* default blue, green, red gain settings */ |
854 | 0x07, 0x00, 0x01}, 8} | 853 | 0x07, 0x00, 0x01}, 8} |
855 | }; | 854 | }; |
856 | 855 | ||
857 | const struct sensor_w_data vga_sensor1_init_data[] = { | 856 | static const struct sensor_w_data vga_sensor1_init_data[] = { |
858 | {0x11, 0x04, {0x01}, 1}, | 857 | {0x11, 0x04, {0x01}, 1}, |
859 | {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, | 858 | {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, |
860 | /* These settings may be better for some cameras */ | 859 | /* These settings may be better for some cameras */ |
@@ -879,7 +878,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
879 | err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, | 878 | err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, |
880 | ARRAY_SIZE(vga_sensor1_init_data)); | 879 | ARRAY_SIZE(vga_sensor1_init_data)); |
881 | } else { /* sensor type == 2 */ | 880 | } else { /* sensor type == 2 */ |
882 | const struct sensor_w_data vga_sensor2_init_data[] = { | 881 | static const struct sensor_w_data vga_sensor2_init_data[] = { |
883 | 882 | ||
884 | {0x01, 0x00, {0x48}, 1}, | 883 | {0x01, 0x00, {0x48}, 1}, |
885 | {0x02, 0x00, {0x22}, 1}, | 884 | {0x02, 0x00, {0x22}, 1}, |
@@ -976,7 +975,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
976 | u8 val; | 975 | u8 val; |
977 | u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ | 976 | u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ |
978 | u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ | 977 | u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ |
979 | const u8 quick_clix_table[] = | 978 | static const u8 quick_clix_table[] = |
980 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ | 979 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ |
981 | { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; | 980 | { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; |
982 | /* | 981 | /* |
@@ -1261,18 +1260,11 @@ static struct usb_driver sd_driver = { | |||
1261 | /* -- module insert / remove -- */ | 1260 | /* -- module insert / remove -- */ |
1262 | static int __init sd_mod_init(void) | 1261 | static int __init sd_mod_init(void) |
1263 | { | 1262 | { |
1264 | int ret; | 1263 | return usb_register(&sd_driver); |
1265 | |||
1266 | ret = usb_register(&sd_driver); | ||
1267 | if (ret < 0) | ||
1268 | return ret; | ||
1269 | PDEBUG(D_PROBE, "registered"); | ||
1270 | return 0; | ||
1271 | } | 1264 | } |
1272 | static void __exit sd_mod_exit(void) | 1265 | static void __exit sd_mod_exit(void) |
1273 | { | 1266 | { |
1274 | usb_deregister(&sd_driver); | 1267 | usb_deregister(&sd_driver); |
1275 | PDEBUG(D_PROBE, "deregistered"); | ||
1276 | } | 1268 | } |
1277 | 1269 | ||
1278 | module_init(sd_mod_init); | 1270 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 2b2cbdbf03f..6cf6855aa50 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -57,10 +57,24 @@ static int frame_rate; | |||
57 | * are getting "Failed to read sensor ID..." */ | 57 | * are getting "Failed to read sensor ID..." */ |
58 | static int i2c_detect_tries = 10; | 58 | static int i2c_detect_tries = 10; |
59 | 59 | ||
60 | /* controls */ | ||
61 | enum e_ctrl { | ||
62 | BRIGHTNESS, | ||
63 | CONTRAST, | ||
64 | COLORS, | ||
65 | HFLIP, | ||
66 | VFLIP, | ||
67 | AUTOBRIGHT, | ||
68 | FREQ, | ||
69 | NCTRL /* number of controls */ | ||
70 | }; | ||
71 | |||
60 | /* ov519 device descriptor */ | 72 | /* ov519 device descriptor */ |
61 | struct sd { | 73 | struct sd { |
62 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 74 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
63 | 75 | ||
76 | struct gspca_ctrl ctrls[NCTRL]; | ||
77 | |||
64 | __u8 packet_nr; | 78 | __u8 packet_nr; |
65 | 79 | ||
66 | char bridge; | 80 | char bridge; |
@@ -82,13 +96,6 @@ struct sd { | |||
82 | /* Determined by sensor type */ | 96 | /* Determined by sensor type */ |
83 | __u8 sif; | 97 | __u8 sif; |
84 | 98 | ||
85 | __u8 brightness; | ||
86 | __u8 contrast; | ||
87 | __u8 colors; | ||
88 | __u8 hflip; | ||
89 | __u8 vflip; | ||
90 | __u8 autobrightness; | ||
91 | __u8 freq; | ||
92 | __u8 quality; | 99 | __u8 quality; |
93 | #define QUALITY_MIN 50 | 100 | #define QUALITY_MIN 50 |
94 | #define QUALITY_MAX 70 | 101 | #define QUALITY_MAX 70 |
@@ -130,29 +137,16 @@ struct sd { | |||
130 | #include "w996Xcf.c" | 137 | #include "w996Xcf.c" |
131 | 138 | ||
132 | /* V4L2 controls supported by the driver */ | 139 | /* V4L2 controls supported by the driver */ |
133 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
134 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
135 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
136 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
137 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
138 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
139 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
140 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
141 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
142 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
143 | static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
144 | static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
145 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
146 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
147 | static void setbrightness(struct gspca_dev *gspca_dev); | 140 | static void setbrightness(struct gspca_dev *gspca_dev); |
148 | static void setcontrast(struct gspca_dev *gspca_dev); | 141 | static void setcontrast(struct gspca_dev *gspca_dev); |
149 | static void setcolors(struct gspca_dev *gspca_dev); | 142 | static void setcolors(struct gspca_dev *gspca_dev); |
150 | static void setautobrightness(struct sd *sd); | 143 | static void sethvflip(struct gspca_dev *gspca_dev); |
151 | static void setfreq(struct sd *sd); | 144 | static void setautobright(struct gspca_dev *gspca_dev); |
145 | static void setfreq(struct gspca_dev *gspca_dev); | ||
146 | static void setfreq_i(struct sd *sd); | ||
152 | 147 | ||
153 | static const struct ctrl sd_ctrls[] = { | 148 | static const struct ctrl sd_ctrls[] = { |
154 | #define BRIGHTNESS_IDX 0 | 149 | [BRIGHTNESS] = { |
155 | { | ||
156 | { | 150 | { |
157 | .id = V4L2_CID_BRIGHTNESS, | 151 | .id = V4L2_CID_BRIGHTNESS, |
158 | .type = V4L2_CTRL_TYPE_INTEGER, | 152 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -160,14 +154,11 @@ static const struct ctrl sd_ctrls[] = { | |||
160 | .minimum = 0, | 154 | .minimum = 0, |
161 | .maximum = 255, | 155 | .maximum = 255, |
162 | .step = 1, | 156 | .step = 1, |
163 | #define BRIGHTNESS_DEF 127 | 157 | .default_value = 127, |
164 | .default_value = BRIGHTNESS_DEF, | ||
165 | }, | 158 | }, |
166 | .set = sd_setbrightness, | 159 | .set_control = setbrightness, |
167 | .get = sd_getbrightness, | ||
168 | }, | 160 | }, |
169 | #define CONTRAST_IDX 1 | 161 | [CONTRAST] = { |
170 | { | ||
171 | { | 162 | { |
172 | .id = V4L2_CID_CONTRAST, | 163 | .id = V4L2_CID_CONTRAST, |
173 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -175,14 +166,11 @@ static const struct ctrl sd_ctrls[] = { | |||
175 | .minimum = 0, | 166 | .minimum = 0, |
176 | .maximum = 255, | 167 | .maximum = 255, |
177 | .step = 1, | 168 | .step = 1, |
178 | #define CONTRAST_DEF 127 | 169 | .default_value = 127, |
179 | .default_value = CONTRAST_DEF, | ||
180 | }, | 170 | }, |
181 | .set = sd_setcontrast, | 171 | .set_control = setcontrast, |
182 | .get = sd_getcontrast, | ||
183 | }, | 172 | }, |
184 | #define COLOR_IDX 2 | 173 | [COLORS] = { |
185 | { | ||
186 | { | 174 | { |
187 | .id = V4L2_CID_SATURATION, | 175 | .id = V4L2_CID_SATURATION, |
188 | .type = V4L2_CTRL_TYPE_INTEGER, | 176 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -190,15 +178,12 @@ static const struct ctrl sd_ctrls[] = { | |||
190 | .minimum = 0, | 178 | .minimum = 0, |
191 | .maximum = 255, | 179 | .maximum = 255, |
192 | .step = 1, | 180 | .step = 1, |
193 | #define COLOR_DEF 127 | 181 | .default_value = 127, |
194 | .default_value = COLOR_DEF, | ||
195 | }, | 182 | }, |
196 | .set = sd_setcolors, | 183 | .set_control = setcolors, |
197 | .get = sd_getcolors, | ||
198 | }, | 184 | }, |
199 | /* The flip controls work with ov7670 only */ | 185 | /* The flip controls work with ov7670 only */ |
200 | #define HFLIP_IDX 3 | 186 | [HFLIP] = { |
201 | { | ||
202 | { | 187 | { |
203 | .id = V4L2_CID_HFLIP, | 188 | .id = V4L2_CID_HFLIP, |
204 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 189 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -206,14 +191,11 @@ static const struct ctrl sd_ctrls[] = { | |||
206 | .minimum = 0, | 191 | .minimum = 0, |
207 | .maximum = 1, | 192 | .maximum = 1, |
208 | .step = 1, | 193 | .step = 1, |
209 | #define HFLIP_DEF 0 | 194 | .default_value = 0, |
210 | .default_value = HFLIP_DEF, | ||
211 | }, | 195 | }, |
212 | .set = sd_sethflip, | 196 | .set_control = sethvflip, |
213 | .get = sd_gethflip, | ||
214 | }, | 197 | }, |
215 | #define VFLIP_IDX 4 | 198 | [VFLIP] = { |
216 | { | ||
217 | { | 199 | { |
218 | .id = V4L2_CID_VFLIP, | 200 | .id = V4L2_CID_VFLIP, |
219 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 201 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -221,14 +203,11 @@ static const struct ctrl sd_ctrls[] = { | |||
221 | .minimum = 0, | 203 | .minimum = 0, |
222 | .maximum = 1, | 204 | .maximum = 1, |
223 | .step = 1, | 205 | .step = 1, |
224 | #define VFLIP_DEF 0 | 206 | .default_value = 0, |
225 | .default_value = VFLIP_DEF, | ||
226 | }, | 207 | }, |
227 | .set = sd_setvflip, | 208 | .set_control = sethvflip, |
228 | .get = sd_getvflip, | ||
229 | }, | 209 | }, |
230 | #define AUTOBRIGHT_IDX 5 | 210 | [AUTOBRIGHT] = { |
231 | { | ||
232 | { | 211 | { |
233 | .id = V4L2_CID_AUTOBRIGHTNESS, | 212 | .id = V4L2_CID_AUTOBRIGHTNESS, |
234 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 213 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -236,14 +215,11 @@ static const struct ctrl sd_ctrls[] = { | |||
236 | .minimum = 0, | 215 | .minimum = 0, |
237 | .maximum = 1, | 216 | .maximum = 1, |
238 | .step = 1, | 217 | .step = 1, |
239 | #define AUTOBRIGHT_DEF 1 | 218 | .default_value = 1, |
240 | .default_value = AUTOBRIGHT_DEF, | ||
241 | }, | 219 | }, |
242 | .set = sd_setautobrightness, | 220 | .set_control = setautobright, |
243 | .get = sd_getautobrightness, | ||
244 | }, | 221 | }, |
245 | #define FREQ_IDX 6 | 222 | [FREQ] = { |
246 | { | ||
247 | { | 223 | { |
248 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 224 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
249 | .type = V4L2_CTRL_TYPE_MENU, | 225 | .type = V4L2_CTRL_TYPE_MENU, |
@@ -251,26 +227,9 @@ static const struct ctrl sd_ctrls[] = { | |||
251 | .minimum = 0, | 227 | .minimum = 0, |
252 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | 228 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ |
253 | .step = 1, | 229 | .step = 1, |
254 | #define FREQ_DEF 0 | 230 | .default_value = 0, |
255 | .default_value = FREQ_DEF, | ||
256 | }, | ||
257 | .set = sd_setfreq, | ||
258 | .get = sd_getfreq, | ||
259 | }, | ||
260 | #define OV7670_FREQ_IDX 7 | ||
261 | { | ||
262 | { | ||
263 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
264 | .type = V4L2_CTRL_TYPE_MENU, | ||
265 | .name = "Light frequency filter", | ||
266 | .minimum = 0, | ||
267 | .maximum = 3, /* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */ | ||
268 | .step = 1, | ||
269 | #define OV7670_FREQ_DEF 3 | ||
270 | .default_value = OV7670_FREQ_DEF, | ||
271 | }, | 231 | }, |
272 | .set = sd_setfreq, | 232 | .set_control = setfreq, |
273 | .get = sd_getfreq, | ||
274 | }, | 233 | }, |
275 | }; | 234 | }; |
276 | 235 | ||
@@ -456,10 +415,10 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
456 | 415 | ||
457 | /* Registers common to OV511 / OV518 */ | 416 | /* Registers common to OV511 / OV518 */ |
458 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ | 417 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ |
459 | #define R51x_SYS_RESET 0x50 | 418 | #define R51x_SYS_RESET 0x50 |
460 | /* Reset type flags */ | 419 | /* Reset type flags */ |
461 | #define OV511_RESET_OMNICE 0x08 | 420 | #define OV511_RESET_OMNICE 0x08 |
462 | #define R51x_SYS_INIT 0x53 | 421 | #define R51x_SYS_INIT 0x53 |
463 | #define R51x_SYS_SNAP 0x52 | 422 | #define R51x_SYS_SNAP 0x52 |
464 | #define R51x_SYS_CUST_ID 0x5F | 423 | #define R51x_SYS_CUST_ID 0x5F |
465 | #define R51x_COMP_LUT_BEGIN 0x80 | 424 | #define R51x_COMP_LUT_BEGIN 0x80 |
@@ -644,13 +603,11 @@ struct ov_i2c_regvals { | |||
644 | }; | 603 | }; |
645 | 604 | ||
646 | /* Settings for OV2610 camera chip */ | 605 | /* Settings for OV2610 camera chip */ |
647 | static const struct ov_i2c_regvals norm_2610[] = | 606 | static const struct ov_i2c_regvals norm_2610[] = { |
648 | { | ||
649 | { 0x12, 0x80 }, /* reset */ | 607 | { 0x12, 0x80 }, /* reset */ |
650 | }; | 608 | }; |
651 | 609 | ||
652 | static const struct ov_i2c_regvals norm_3620b[] = | 610 | static const struct ov_i2c_regvals norm_3620b[] = { |
653 | { | ||
654 | /* | 611 | /* |
655 | * From the datasheet: "Note that after writing to register COMH | 612 | * From the datasheet: "Note that after writing to register COMH |
656 | * (0x12) to change the sensor mode, registers related to the | 613 | * (0x12) to change the sensor mode, registers related to the |
@@ -1900,7 +1857,7 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1900 | sd->gspca_dev.usb_buf, 1, 500); | 1857 | sd->gspca_dev.usb_buf, 1, 500); |
1901 | leave: | 1858 | leave: |
1902 | if (ret < 0) { | 1859 | if (ret < 0) { |
1903 | PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed", | 1860 | err("Write reg 0x%04x -> [0x%02x] failed", |
1904 | value, index); | 1861 | value, index); |
1905 | return ret; | 1862 | return ret; |
1906 | } | 1863 | } |
@@ -1938,7 +1895,7 @@ static int reg_r(struct sd *sd, __u16 index) | |||
1938 | ret = sd->gspca_dev.usb_buf[0]; | 1895 | ret = sd->gspca_dev.usb_buf[0]; |
1939 | PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret); | 1896 | PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret); |
1940 | } else | 1897 | } else |
1941 | PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); | 1898 | err("Read reg [0x%02x] failed", index); |
1942 | 1899 | ||
1943 | return ret; | 1900 | return ret; |
1944 | } | 1901 | } |
@@ -1958,7 +1915,7 @@ static int reg_r8(struct sd *sd, | |||
1958 | if (ret >= 0) | 1915 | if (ret >= 0) |
1959 | ret = sd->gspca_dev.usb_buf[0]; | 1916 | ret = sd->gspca_dev.usb_buf[0]; |
1960 | else | 1917 | else |
1961 | PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); | 1918 | err("Read reg 8 [0x%02x] failed", index); |
1962 | 1919 | ||
1963 | return ret; | 1920 | return ret; |
1964 | } | 1921 | } |
@@ -2006,7 +1963,7 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | |||
2006 | 0, index, | 1963 | 0, index, |
2007 | sd->gspca_dev.usb_buf, n, 500); | 1964 | sd->gspca_dev.usb_buf, n, 500); |
2008 | if (ret < 0) { | 1965 | if (ret < 0) { |
2009 | PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); | 1966 | err("Write reg32 [%02x] %08x failed", index, value); |
2010 | return ret; | 1967 | return ret; |
2011 | } | 1968 | } |
2012 | 1969 | ||
@@ -2203,7 +2160,7 @@ static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value) | |||
2203 | (__u16)value, (__u16)reg, NULL, 0, 500); | 2160 | (__u16)value, (__u16)reg, NULL, 0, 500); |
2204 | 2161 | ||
2205 | if (ret < 0) { | 2162 | if (ret < 0) { |
2206 | PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); | 2163 | err("i2c 0x%02x -> [0x%02x] failed", value, reg); |
2207 | return ret; | 2164 | return ret; |
2208 | } | 2165 | } |
2209 | 2166 | ||
@@ -2225,7 +2182,7 @@ static int ovfx2_i2c_r(struct sd *sd, __u8 reg) | |||
2225 | ret = sd->gspca_dev.usb_buf[0]; | 2182 | ret = sd->gspca_dev.usb_buf[0]; |
2226 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret); | 2183 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret); |
2227 | } else | 2184 | } else |
2228 | PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg); | 2185 | err("i2c read [0x%02x] failed", reg); |
2229 | 2186 | ||
2230 | return ret; | 2187 | return ret; |
2231 | } | 2188 | } |
@@ -2481,7 +2438,7 @@ static int ov_hires_configure(struct sd *sd) | |||
2481 | int high, low; | 2438 | int high, low; |
2482 | 2439 | ||
2483 | if (sd->bridge != BRIDGE_OVFX2) { | 2440 | if (sd->bridge != BRIDGE_OVFX2) { |
2484 | PDEBUG(D_ERR, "error hires sensors only supported with ovfx2"); | 2441 | err("error hires sensors only supported with ovfx2"); |
2485 | return -1; | 2442 | return -1; |
2486 | } | 2443 | } |
2487 | 2444 | ||
@@ -2498,7 +2455,7 @@ static int ov_hires_configure(struct sd *sd) | |||
2498 | PDEBUG(D_PROBE, "Sensor is an OV3610"); | 2455 | PDEBUG(D_PROBE, "Sensor is an OV3610"); |
2499 | sd->sensor = SEN_OV3610; | 2456 | sd->sensor = SEN_OV3610; |
2500 | } else { | 2457 | } else { |
2501 | PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x", | 2458 | err("Error unknown sensor type: 0x%02x%02x", |
2502 | high, low); | 2459 | high, low); |
2503 | return -1; | 2460 | return -1; |
2504 | } | 2461 | } |
@@ -2526,7 +2483,7 @@ static int ov8xx0_configure(struct sd *sd) | |||
2526 | if ((rc & 3) == 1) { | 2483 | if ((rc & 3) == 1) { |
2527 | sd->sensor = SEN_OV8610; | 2484 | sd->sensor = SEN_OV8610; |
2528 | } else { | 2485 | } else { |
2529 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | 2486 | err("Unknown image sensor version: %d", rc & 3); |
2530 | return -1; | 2487 | return -1; |
2531 | } | 2488 | } |
2532 | 2489 | ||
@@ -2589,9 +2546,8 @@ static int ov7xx0_configure(struct sd *sd) | |||
2589 | if (high == 0x76) { | 2546 | if (high == 0x76) { |
2590 | switch (low) { | 2547 | switch (low) { |
2591 | case 0x30: | 2548 | case 0x30: |
2592 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); | 2549 | err("Sensor is an OV7630/OV7635"); |
2593 | PDEBUG(D_ERR, | 2550 | err("7630 is not supported by this driver"); |
2594 | "7630 is not supported by this driver"); | ||
2595 | return -1; | 2551 | return -1; |
2596 | case 0x40: | 2552 | case 0x40: |
2597 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | 2553 | PDEBUG(D_PROBE, "Sensor is an OV7645"); |
@@ -2614,7 +2570,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
2614 | sd->sensor = SEN_OV7620; | 2570 | sd->sensor = SEN_OV7620; |
2615 | } | 2571 | } |
2616 | } else { | 2572 | } else { |
2617 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | 2573 | err("Unknown image sensor version: %d", rc & 3); |
2618 | return -1; | 2574 | return -1; |
2619 | } | 2575 | } |
2620 | 2576 | ||
@@ -2641,9 +2597,8 @@ static int ov6xx0_configure(struct sd *sd) | |||
2641 | switch (rc) { | 2597 | switch (rc) { |
2642 | case 0x00: | 2598 | case 0x00: |
2643 | sd->sensor = SEN_OV6630; | 2599 | sd->sensor = SEN_OV6630; |
2644 | PDEBUG(D_ERR, | 2600 | warn("WARNING: Sensor is an OV66308. Your camera may have"); |
2645 | "WARNING: Sensor is an OV66308. Your camera may have"); | 2601 | warn("been misdetected in previous driver versions."); |
2646 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | ||
2647 | break; | 2602 | break; |
2648 | case 0x01: | 2603 | case 0x01: |
2649 | sd->sensor = SEN_OV6620; | 2604 | sd->sensor = SEN_OV6620; |
@@ -2659,12 +2614,11 @@ static int ov6xx0_configure(struct sd *sd) | |||
2659 | break; | 2614 | break; |
2660 | case 0x90: | 2615 | case 0x90: |
2661 | sd->sensor = SEN_OV6630; | 2616 | sd->sensor = SEN_OV6630; |
2662 | PDEBUG(D_ERR, | 2617 | warn("WARNING: Sensor is an OV66307. Your camera may have"); |
2663 | "WARNING: Sensor is an OV66307. Your camera may have"); | 2618 | warn("been misdetected in previous driver versions."); |
2664 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | ||
2665 | break; | 2619 | break; |
2666 | default: | 2620 | default: |
2667 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); | 2621 | err("FATAL: Unknown sensor version: 0x%02x", rc); |
2668 | return -1; | 2622 | return -1; |
2669 | } | 2623 | } |
2670 | 2624 | ||
@@ -2823,7 +2777,7 @@ static int ov511_configure(struct gspca_dev *gspca_dev) | |||
2823 | }; | 2777 | }; |
2824 | 2778 | ||
2825 | const struct ov_regvals norm_511[] = { | 2779 | const struct ov_regvals norm_511[] = { |
2826 | { R511_DRAM_FLOW_CTL, 0x01 }, | 2780 | { R511_DRAM_FLOW_CTL, 0x01 }, |
2827 | { R51x_SYS_SNAP, 0x00 }, | 2781 | { R51x_SYS_SNAP, 0x00 }, |
2828 | { R51x_SYS_SNAP, 0x02 }, | 2782 | { R51x_SYS_SNAP, 0x02 }, |
2829 | { R51x_SYS_SNAP, 0x00 }, | 2783 | { R51x_SYS_SNAP, 0x00 }, |
@@ -2907,7 +2861,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev) | |||
2907 | const struct ov_regvals norm_518[] = { | 2861 | const struct ov_regvals norm_518[] = { |
2908 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | 2862 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ |
2909 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | 2863 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ |
2910 | { 0x31, 0x0f }, | 2864 | { 0x31, 0x0f }, |
2911 | { 0x5d, 0x03 }, | 2865 | { 0x5d, 0x03 }, |
2912 | { 0x24, 0x9f }, | 2866 | { 0x24, 0x9f }, |
2913 | { 0x25, 0x90 }, | 2867 | { 0x25, 0x90 }, |
@@ -2920,7 +2874,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev) | |||
2920 | const struct ov_regvals norm_518_p[] = { | 2874 | const struct ov_regvals norm_518_p[] = { |
2921 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | 2875 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ |
2922 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | 2876 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ |
2923 | { 0x31, 0x0f }, | 2877 | { 0x31, 0x0f }, |
2924 | { 0x5d, 0x03 }, | 2878 | { 0x5d, 0x03 }, |
2925 | { 0x24, 0x9f }, | 2879 | { 0x24, 0x9f }, |
2926 | { 0x25, 0x90 }, | 2880 | { 0x25, 0x90 }, |
@@ -3082,7 +3036,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3082 | goto error; | 3036 | goto error; |
3083 | } | 3037 | } |
3084 | } else { | 3038 | } else { |
3085 | PDEBUG(D_ERR, "Can't determine sensor slave IDs"); | 3039 | err("Can't determine sensor slave IDs"); |
3086 | goto error; | 3040 | goto error; |
3087 | } | 3041 | } |
3088 | 3042 | ||
@@ -3142,36 +3096,23 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3142 | goto error; | 3096 | goto error; |
3143 | break; | 3097 | break; |
3144 | } | 3098 | } |
3145 | sd->brightness = BRIGHTNESS_DEF; | 3099 | gspca_dev->cam.ctrls = sd->ctrls; |
3146 | if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) | 3100 | if (sd->sensor == SEN_OV7670) |
3147 | sd->contrast = 200; /* The default is too low for the ov6630 */ | 3101 | gspca_dev->ctrl_dis = 1 << COLORS; |
3148 | else | 3102 | else |
3149 | sd->contrast = CONTRAST_DEF; | 3103 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); |
3150 | sd->colors = COLOR_DEF; | ||
3151 | sd->hflip = HFLIP_DEF; | ||
3152 | sd->vflip = VFLIP_DEF; | ||
3153 | sd->autobrightness = AUTOBRIGHT_DEF; | ||
3154 | if (sd->sensor == SEN_OV7670) { | ||
3155 | sd->freq = OV7670_FREQ_DEF; | ||
3156 | gspca_dev->ctrl_dis = (1 << FREQ_IDX) | (1 << COLOR_IDX); | ||
3157 | } else { | ||
3158 | sd->freq = FREQ_DEF; | ||
3159 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | | ||
3160 | (1 << OV7670_FREQ_IDX); | ||
3161 | } | ||
3162 | sd->quality = QUALITY_DEF; | 3104 | sd->quality = QUALITY_DEF; |
3163 | if (sd->sensor == SEN_OV7640 || | 3105 | if (sd->sensor == SEN_OV7640 || |
3164 | sd->sensor == SEN_OV7648) | 3106 | sd->sensor == SEN_OV7648) |
3165 | gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) | | 3107 | gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST); |
3166 | (1 << CONTRAST_IDX); | ||
3167 | if (sd->sensor == SEN_OV7670) | 3108 | if (sd->sensor == SEN_OV7670) |
3168 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; | 3109 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT; |
3169 | /* OV8610 Frequency filter control should work but needs testing */ | 3110 | /* OV8610 Frequency filter control should work but needs testing */ |
3170 | if (sd->sensor == SEN_OV8610) | 3111 | if (sd->sensor == SEN_OV8610) |
3171 | gspca_dev->ctrl_dis |= 1 << FREQ_IDX; | 3112 | gspca_dev->ctrl_dis |= 1 << FREQ; |
3172 | /* No controls for the OV2610/OV3610 */ | 3113 | /* No controls for the OV2610/OV3610 */ |
3173 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 3114 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) |
3174 | gspca_dev->ctrl_dis |= 0xFF; | 3115 | gspca_dev->ctrl_dis |= (1 << NCTRL) - 1; |
3175 | 3116 | ||
3176 | return 0; | 3117 | return 0; |
3177 | error: | 3118 | error: |
@@ -3206,6 +3147,8 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3206 | break; | 3147 | break; |
3207 | case SEN_OV6630: | 3148 | case SEN_OV6630: |
3208 | case SEN_OV66308AF: | 3149 | case SEN_OV66308AF: |
3150 | sd->ctrls[CONTRAST].def = 200; | ||
3151 | /* The default is too low for the ov6630 */ | ||
3209 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) | 3152 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) |
3210 | return -EIO; | 3153 | return -EIO; |
3211 | break; | 3154 | break; |
@@ -3228,6 +3171,8 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3228 | return -EIO; | 3171 | return -EIO; |
3229 | break; | 3172 | break; |
3230 | case SEN_OV7670: | 3173 | case SEN_OV7670: |
3174 | sd->ctrls[FREQ].max = 3; /* auto */ | ||
3175 | sd->ctrls[FREQ].def = 3; | ||
3231 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) | 3176 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) |
3232 | return -EIO; | 3177 | return -EIO; |
3233 | break; | 3178 | break; |
@@ -3253,7 +3198,7 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3253 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | 3198 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); |
3254 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 3199 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
3255 | if (!alt) { | 3200 | if (!alt) { |
3256 | PDEBUG(D_ERR, "Couldn't get altsetting"); | 3201 | err("Couldn't get altsetting"); |
3257 | return -EIO; | 3202 | return -EIO; |
3258 | } | 3203 | } |
3259 | 3204 | ||
@@ -3377,7 +3322,7 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3377 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | 3322 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); |
3378 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 3323 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
3379 | if (!alt) { | 3324 | if (!alt) { |
3380 | PDEBUG(D_ERR, "Couldn't get altsetting"); | 3325 | err("Couldn't get altsetting"); |
3381 | return -EIO; | 3326 | return -EIO; |
3382 | } | 3327 | } |
3383 | 3328 | ||
@@ -3706,7 +3651,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3706 | break; | 3651 | break; |
3707 | case SEN_OV7610: | 3652 | case SEN_OV7610: |
3708 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3653 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
3709 | i2c_w(sd, 0x35, qvga?0x1e:0x9e); | 3654 | i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); |
3710 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | 3655 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ |
3711 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | 3656 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ |
3712 | break; | 3657 | break; |
@@ -3798,15 +3743,17 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3798 | return 0; | 3743 | return 0; |
3799 | } | 3744 | } |
3800 | 3745 | ||
3801 | static void sethvflip(struct sd *sd) | 3746 | static void sethvflip(struct gspca_dev *gspca_dev) |
3802 | { | 3747 | { |
3748 | struct sd *sd = (struct sd *) gspca_dev; | ||
3749 | |||
3803 | if (sd->sensor != SEN_OV7670) | 3750 | if (sd->sensor != SEN_OV7670) |
3804 | return; | 3751 | return; |
3805 | if (sd->gspca_dev.streaming) | 3752 | if (sd->gspca_dev.streaming) |
3806 | ov51x_stop(sd); | 3753 | ov51x_stop(sd); |
3807 | i2c_w_mask(sd, OV7670_REG_MVFP, | 3754 | i2c_w_mask(sd, OV7670_REG_MVFP, |
3808 | OV7670_MVFP_MIRROR * sd->hflip | 3755 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val |
3809 | | OV7670_MVFP_VFLIP * sd->vflip, | 3756 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, |
3810 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | 3757 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); |
3811 | if (sd->gspca_dev.streaming) | 3758 | if (sd->gspca_dev.streaming) |
3812 | ov51x_restart(sd); | 3759 | ov51x_restart(sd); |
@@ -3957,9 +3904,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3957 | setcontrast(gspca_dev); | 3904 | setcontrast(gspca_dev); |
3958 | setbrightness(gspca_dev); | 3905 | setbrightness(gspca_dev); |
3959 | setcolors(gspca_dev); | 3906 | setcolors(gspca_dev); |
3960 | sethvflip(sd); | 3907 | sethvflip(gspca_dev); |
3961 | setautobrightness(sd); | 3908 | setautobright(gspca_dev); |
3962 | setfreq(sd); | 3909 | setfreq_i(sd); |
3963 | 3910 | ||
3964 | /* Force clear snapshot state in case the snapshot button was | 3911 | /* Force clear snapshot state in case the snapshot button was |
3965 | pressed while we weren't streaming */ | 3912 | pressed while we weren't streaming */ |
@@ -4000,7 +3947,7 @@ static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) | |||
4000 | struct sd *sd = (struct sd *) gspca_dev; | 3947 | struct sd *sd = (struct sd *) gspca_dev; |
4001 | 3948 | ||
4002 | if (sd->snapshot_pressed != state) { | 3949 | if (sd->snapshot_pressed != state) { |
4003 | #ifdef CONFIG_INPUT | 3950 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
4004 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, state); | 3951 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, state); |
4005 | input_sync(gspca_dev->input_dev); | 3952 | input_sync(gspca_dev->input_dev); |
4006 | #endif | 3953 | #endif |
@@ -4214,7 +4161,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4214 | struct sd *sd = (struct sd *) gspca_dev; | 4161 | struct sd *sd = (struct sd *) gspca_dev; |
4215 | int val; | 4162 | int val; |
4216 | 4163 | ||
4217 | val = sd->brightness; | 4164 | val = sd->ctrls[BRIGHTNESS].val; |
4218 | switch (sd->sensor) { | 4165 | switch (sd->sensor) { |
4219 | case SEN_OV8610: | 4166 | case SEN_OV8610: |
4220 | case SEN_OV7610: | 4167 | case SEN_OV7610: |
@@ -4229,7 +4176,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4229 | case SEN_OV7620: | 4176 | case SEN_OV7620: |
4230 | case SEN_OV7620AE: | 4177 | case SEN_OV7620AE: |
4231 | /* 7620 doesn't like manual changes when in auto mode */ | 4178 | /* 7620 doesn't like manual changes when in auto mode */ |
4232 | if (!sd->autobrightness) | 4179 | if (!sd->ctrls[AUTOBRIGHT].val) |
4233 | i2c_w(sd, OV7610_REG_BRT, val); | 4180 | i2c_w(sd, OV7610_REG_BRT, val); |
4234 | break; | 4181 | break; |
4235 | case SEN_OV7670: | 4182 | case SEN_OV7670: |
@@ -4245,7 +4192,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4245 | struct sd *sd = (struct sd *) gspca_dev; | 4192 | struct sd *sd = (struct sd *) gspca_dev; |
4246 | int val; | 4193 | int val; |
4247 | 4194 | ||
4248 | val = sd->contrast; | 4195 | val = sd->ctrls[CONTRAST].val; |
4249 | switch (sd->sensor) { | 4196 | switch (sd->sensor) { |
4250 | case SEN_OV7610: | 4197 | case SEN_OV7610: |
4251 | case SEN_OV6620: | 4198 | case SEN_OV6620: |
@@ -4287,7 +4234,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4287 | struct sd *sd = (struct sd *) gspca_dev; | 4234 | struct sd *sd = (struct sd *) gspca_dev; |
4288 | int val; | 4235 | int val; |
4289 | 4236 | ||
4290 | val = sd->colors; | 4237 | val = sd->ctrls[COLORS].val; |
4291 | switch (sd->sensor) { | 4238 | switch (sd->sensor) { |
4292 | case SEN_OV8610: | 4239 | case SEN_OV8610: |
4293 | case SEN_OV7610: | 4240 | case SEN_OV7610: |
@@ -4317,23 +4264,25 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4317 | } | 4264 | } |
4318 | } | 4265 | } |
4319 | 4266 | ||
4320 | static void setautobrightness(struct sd *sd) | 4267 | static void setautobright(struct gspca_dev *gspca_dev) |
4321 | { | 4268 | { |
4269 | struct sd *sd = (struct sd *) gspca_dev; | ||
4270 | |||
4322 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 || | 4271 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 || |
4323 | sd->sensor == SEN_OV7670 || | 4272 | sd->sensor == SEN_OV7670 || |
4324 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 4273 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) |
4325 | return; | 4274 | return; |
4326 | 4275 | ||
4327 | i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); | 4276 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); |
4328 | } | 4277 | } |
4329 | 4278 | ||
4330 | static void setfreq(struct sd *sd) | 4279 | static void setfreq_i(struct sd *sd) |
4331 | { | 4280 | { |
4332 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 4281 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) |
4333 | return; | 4282 | return; |
4334 | 4283 | ||
4335 | if (sd->sensor == SEN_OV7670) { | 4284 | if (sd->sensor == SEN_OV7670) { |
4336 | switch (sd->freq) { | 4285 | switch (sd->ctrls[FREQ].val) { |
4337 | case 0: /* Banding filter disabled */ | 4286 | case 0: /* Banding filter disabled */ |
4338 | i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT); | 4287 | i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT); |
4339 | break; | 4288 | break; |
@@ -4355,7 +4304,7 @@ static void setfreq(struct sd *sd) | |||
4355 | break; | 4304 | break; |
4356 | } | 4305 | } |
4357 | } else { | 4306 | } else { |
4358 | switch (sd->freq) { | 4307 | switch (sd->ctrls[FREQ].val) { |
4359 | case 0: /* Banding filter disabled */ | 4308 | case 0: /* Banding filter disabled */ |
4360 | i2c_w_mask(sd, 0x2d, 0x00, 0x04); | 4309 | i2c_w_mask(sd, 0x2d, 0x00, 0x04); |
4361 | i2c_w_mask(sd, 0x2a, 0x00, 0x80); | 4310 | i2c_w_mask(sd, 0x2a, 0x00, 0x80); |
@@ -4387,135 +4336,15 @@ static void setfreq(struct sd *sd) | |||
4387 | } | 4336 | } |
4388 | } | 4337 | } |
4389 | } | 4338 | } |
4390 | 4339 | static void setfreq(struct gspca_dev *gspca_dev) | |
4391 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
4392 | { | ||
4393 | struct sd *sd = (struct sd *) gspca_dev; | ||
4394 | |||
4395 | sd->brightness = val; | ||
4396 | if (gspca_dev->streaming) | ||
4397 | setbrightness(gspca_dev); | ||
4398 | return 0; | ||
4399 | } | ||
4400 | |||
4401 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
4402 | { | ||
4403 | struct sd *sd = (struct sd *) gspca_dev; | ||
4404 | |||
4405 | *val = sd->brightness; | ||
4406 | return 0; | ||
4407 | } | ||
4408 | |||
4409 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
4410 | { | ||
4411 | struct sd *sd = (struct sd *) gspca_dev; | ||
4412 | |||
4413 | sd->contrast = val; | ||
4414 | if (gspca_dev->streaming) | ||
4415 | setcontrast(gspca_dev); | ||
4416 | return 0; | ||
4417 | } | ||
4418 | |||
4419 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
4420 | { | ||
4421 | struct sd *sd = (struct sd *) gspca_dev; | ||
4422 | |||
4423 | *val = sd->contrast; | ||
4424 | return 0; | ||
4425 | } | ||
4426 | |||
4427 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
4428 | { | ||
4429 | struct sd *sd = (struct sd *) gspca_dev; | ||
4430 | |||
4431 | sd->colors = val; | ||
4432 | if (gspca_dev->streaming) | ||
4433 | setcolors(gspca_dev); | ||
4434 | return 0; | ||
4435 | } | ||
4436 | |||
4437 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
4438 | { | ||
4439 | struct sd *sd = (struct sd *) gspca_dev; | ||
4440 | |||
4441 | *val = sd->colors; | ||
4442 | return 0; | ||
4443 | } | ||
4444 | |||
4445 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
4446 | { | ||
4447 | struct sd *sd = (struct sd *) gspca_dev; | ||
4448 | |||
4449 | sd->hflip = val; | ||
4450 | if (gspca_dev->streaming) | ||
4451 | sethvflip(sd); | ||
4452 | return 0; | ||
4453 | } | ||
4454 | |||
4455 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
4456 | { | ||
4457 | struct sd *sd = (struct sd *) gspca_dev; | ||
4458 | |||
4459 | *val = sd->hflip; | ||
4460 | return 0; | ||
4461 | } | ||
4462 | |||
4463 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
4464 | { | ||
4465 | struct sd *sd = (struct sd *) gspca_dev; | ||
4466 | |||
4467 | sd->vflip = val; | ||
4468 | if (gspca_dev->streaming) | ||
4469 | sethvflip(sd); | ||
4470 | return 0; | ||
4471 | } | ||
4472 | |||
4473 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
4474 | { | ||
4475 | struct sd *sd = (struct sd *) gspca_dev; | ||
4476 | |||
4477 | *val = sd->vflip; | ||
4478 | return 0; | ||
4479 | } | ||
4480 | |||
4481 | static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
4482 | { | ||
4483 | struct sd *sd = (struct sd *) gspca_dev; | ||
4484 | |||
4485 | sd->autobrightness = val; | ||
4486 | if (gspca_dev->streaming) | ||
4487 | setautobrightness(sd); | ||
4488 | return 0; | ||
4489 | } | ||
4490 | |||
4491 | static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
4492 | { | ||
4493 | struct sd *sd = (struct sd *) gspca_dev; | ||
4494 | |||
4495 | *val = sd->autobrightness; | ||
4496 | return 0; | ||
4497 | } | ||
4498 | |||
4499 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
4500 | { | 4340 | { |
4501 | struct sd *sd = (struct sd *) gspca_dev; | 4341 | struct sd *sd = (struct sd *) gspca_dev; |
4502 | 4342 | ||
4503 | sd->freq = val; | 4343 | setfreq_i(sd); |
4504 | if (gspca_dev->streaming) { | ||
4505 | setfreq(sd); | ||
4506 | /* Ugly but necessary */ | ||
4507 | if (sd->bridge == BRIDGE_W9968CF) | ||
4508 | w9968cf_set_crop_window(sd); | ||
4509 | } | ||
4510 | return 0; | ||
4511 | } | ||
4512 | |||
4513 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
4514 | { | ||
4515 | struct sd *sd = (struct sd *) gspca_dev; | ||
4516 | 4344 | ||
4517 | *val = sd->freq; | 4345 | /* Ugly but necessary */ |
4518 | return 0; | 4346 | if (sd->bridge == BRIDGE_W9968CF) |
4347 | w9968cf_set_crop_window(sd); | ||
4519 | } | 4348 | } |
4520 | 4349 | ||
4521 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 4350 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
@@ -4601,7 +4430,7 @@ static const struct sd_desc sd_desc = { | |||
4601 | .querymenu = sd_querymenu, | 4430 | .querymenu = sd_querymenu, |
4602 | .get_jcomp = sd_get_jcomp, | 4431 | .get_jcomp = sd_get_jcomp, |
4603 | .set_jcomp = sd_set_jcomp, | 4432 | .set_jcomp = sd_set_jcomp, |
4604 | #ifdef CONFIG_INPUT | 4433 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
4605 | .other_input = 1, | 4434 | .other_input = 1, |
4606 | #endif | 4435 | #endif |
4607 | }; | 4436 | }; |
@@ -4663,17 +4492,11 @@ static struct usb_driver sd_driver = { | |||
4663 | /* -- module insert / remove -- */ | 4492 | /* -- module insert / remove -- */ |
4664 | static int __init sd_mod_init(void) | 4493 | static int __init sd_mod_init(void) |
4665 | { | 4494 | { |
4666 | int ret; | 4495 | return usb_register(&sd_driver); |
4667 | ret = usb_register(&sd_driver); | ||
4668 | if (ret < 0) | ||
4669 | return ret; | ||
4670 | PDEBUG(D_PROBE, "registered"); | ||
4671 | return 0; | ||
4672 | } | 4496 | } |
4673 | static void __exit sd_mod_exit(void) | 4497 | static void __exit sd_mod_exit(void) |
4674 | { | 4498 | { |
4675 | usb_deregister(&sd_driver); | 4499 | usb_deregister(&sd_driver); |
4676 | PDEBUG(D_PROBE, "deregistered"); | ||
4677 | } | 4500 | } |
4678 | 4501 | ||
4679 | module_init(sd_mod_init); | 4502 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 96cb3a97658..88ef03f6235 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -487,7 +487,7 @@ static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) | |||
487 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 487 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
488 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); | 488 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); |
489 | if (ret < 0) | 489 | if (ret < 0) |
490 | PDEBUG(D_ERR, "write failed"); | 490 | err("write failed %d", ret); |
491 | } | 491 | } |
492 | 492 | ||
493 | static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) | 493 | static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) |
@@ -502,7 +502,7 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) | |||
502 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); | 502 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); |
503 | PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); | 503 | PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); |
504 | if (ret < 0) | 504 | if (ret < 0) |
505 | PDEBUG(D_ERR, "read failed"); | 505 | err("read failed %d", ret); |
506 | return gspca_dev->usb_buf[0]; | 506 | return gspca_dev->usb_buf[0]; |
507 | } | 507 | } |
508 | 508 | ||
@@ -564,7 +564,7 @@ static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
564 | ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); | 564 | ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); |
565 | 565 | ||
566 | if (!sccb_check_status(gspca_dev)) | 566 | if (!sccb_check_status(gspca_dev)) |
567 | PDEBUG(D_ERR, "sccb_reg_write failed"); | 567 | err("sccb_reg_write failed"); |
568 | } | 568 | } |
569 | 569 | ||
570 | static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) | 570 | static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) |
@@ -572,11 +572,11 @@ static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) | |||
572 | ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); | 572 | ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); |
573 | ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); | 573 | ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); |
574 | if (!sccb_check_status(gspca_dev)) | 574 | if (!sccb_check_status(gspca_dev)) |
575 | PDEBUG(D_ERR, "sccb_reg_read failed 1"); | 575 | err("sccb_reg_read failed 1"); |
576 | 576 | ||
577 | ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); | 577 | ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); |
578 | if (!sccb_check_status(gspca_dev)) | 578 | if (!sccb_check_status(gspca_dev)) |
579 | PDEBUG(D_ERR, "sccb_reg_read failed 2"); | 579 | err("sccb_reg_read failed 2"); |
580 | 580 | ||
581 | return ov534_reg_read(gspca_dev, OV534_REG_READ); | 581 | return ov534_reg_read(gspca_dev, OV534_REG_READ); |
582 | } | 582 | } |
@@ -1327,19 +1327,12 @@ static struct usb_driver sd_driver = { | |||
1327 | /* -- module insert / remove -- */ | 1327 | /* -- module insert / remove -- */ |
1328 | static int __init sd_mod_init(void) | 1328 | static int __init sd_mod_init(void) |
1329 | { | 1329 | { |
1330 | int ret; | 1330 | return usb_register(&sd_driver); |
1331 | |||
1332 | ret = usb_register(&sd_driver); | ||
1333 | if (ret < 0) | ||
1334 | return ret; | ||
1335 | PDEBUG(D_PROBE, "registered"); | ||
1336 | return 0; | ||
1337 | } | 1331 | } |
1338 | 1332 | ||
1339 | static void __exit sd_mod_exit(void) | 1333 | static void __exit sd_mod_exit(void) |
1340 | { | 1334 | { |
1341 | usb_deregister(&sd_driver); | 1335 | usb_deregister(&sd_driver); |
1342 | PDEBUG(D_PROBE, "deregistered"); | ||
1343 | } | 1336 | } |
1344 | 1337 | ||
1345 | module_init(sd_mod_init); | 1338 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index bbe5a030e3b..e831f0d280e 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c | |||
@@ -785,7 +785,7 @@ static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val) | |||
785 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 785 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
786 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); | 786 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); |
787 | if (ret < 0) { | 787 | if (ret < 0) { |
788 | PDEBUG(D_ERR, "reg_w failed %d", ret); | 788 | err("reg_w failed %d", ret); |
789 | gspca_dev->usb_err = ret; | 789 | gspca_dev->usb_err = ret; |
790 | } | 790 | } |
791 | } | 791 | } |
@@ -810,7 +810,7 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg) | |||
810 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); | 810 | 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); |
811 | PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]); | 811 | PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]); |
812 | if (ret < 0) { | 812 | if (ret < 0) { |
813 | PDEBUG(D_ERR, "reg_r err %d", ret); | 813 | err("reg_r err %d", ret); |
814 | gspca_dev->usb_err = ret; | 814 | gspca_dev->usb_err = ret; |
815 | } | 815 | } |
816 | return gspca_dev->usb_buf[0]; | 816 | return gspca_dev->usb_buf[0]; |
@@ -848,7 +848,7 @@ static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
848 | reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); | 848 | reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); |
849 | 849 | ||
850 | if (!sccb_check_status(gspca_dev)) | 850 | if (!sccb_check_status(gspca_dev)) |
851 | PDEBUG(D_ERR, "sccb_write failed"); | 851 | err("sccb_write failed"); |
852 | } | 852 | } |
853 | 853 | ||
854 | static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) | 854 | static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) |
@@ -856,11 +856,11 @@ static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) | |||
856 | reg_w(gspca_dev, OV534_REG_SUBADDR, reg); | 856 | reg_w(gspca_dev, OV534_REG_SUBADDR, reg); |
857 | reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); | 857 | reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); |
858 | if (!sccb_check_status(gspca_dev)) | 858 | if (!sccb_check_status(gspca_dev)) |
859 | PDEBUG(D_ERR, "sccb_read failed 1"); | 859 | err("sccb_read failed 1"); |
860 | 860 | ||
861 | reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); | 861 | reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); |
862 | if (!sccb_check_status(gspca_dev)) | 862 | if (!sccb_check_status(gspca_dev)) |
863 | PDEBUG(D_ERR, "sccb_read failed 2"); | 863 | err("sccb_read failed 2"); |
864 | 864 | ||
865 | return reg_r(gspca_dev, OV534_REG_READ); | 865 | return reg_r(gspca_dev, OV534_REG_READ); |
866 | } | 866 | } |
@@ -1458,19 +1458,12 @@ static struct usb_driver sd_driver = { | |||
1458 | /* -- module insert / remove -- */ | 1458 | /* -- module insert / remove -- */ |
1459 | static int __init sd_mod_init(void) | 1459 | static int __init sd_mod_init(void) |
1460 | { | 1460 | { |
1461 | int ret; | 1461 | return usb_register(&sd_driver); |
1462 | |||
1463 | ret = usb_register(&sd_driver); | ||
1464 | if (ret < 0) | ||
1465 | return ret; | ||
1466 | PDEBUG(D_PROBE, "registered"); | ||
1467 | return 0; | ||
1468 | } | 1462 | } |
1469 | 1463 | ||
1470 | static void __exit sd_mod_exit(void) | 1464 | static void __exit sd_mod_exit(void) |
1471 | { | 1465 | { |
1472 | usb_deregister(&sd_driver); | 1466 | usb_deregister(&sd_driver); |
1473 | PDEBUG(D_PROBE, "deregistered"); | ||
1474 | } | 1467 | } |
1475 | 1468 | ||
1476 | module_init(sd_mod_init); | 1469 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index a40f8893310..15e97fa4c33 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Pixart PAC207BCA library | 2 | * Pixart PAC207BCA library |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Hans de Goede <hdgoede@redhat.com> | 4 | * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com> |
5 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li | 5 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li |
6 | * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr | 6 | * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr |
7 | * | 7 | * |
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include "gspca.h" | 29 | #include "gspca.h" |
30 | 30 | ||
31 | MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>"); | 31 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
32 | MODULE_DESCRIPTION("Pixart PAC207"); | 32 | MODULE_DESCRIPTION("Pixart PAC207"); |
33 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
34 | 34 | ||
@@ -45,7 +45,7 @@ MODULE_LICENSE("GPL"); | |||
45 | 45 | ||
46 | #define PAC207_GAIN_MIN 0 | 46 | #define PAC207_GAIN_MIN 0 |
47 | #define PAC207_GAIN_MAX 31 | 47 | #define PAC207_GAIN_MAX 31 |
48 | #define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */ | 48 | #define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */ |
49 | #define PAC207_GAIN_KNEE 31 | 49 | #define PAC207_GAIN_KNEE 31 |
50 | 50 | ||
51 | #define PAC207_AUTOGAIN_DEADZONE 30 | 51 | #define PAC207_AUTOGAIN_DEADZONE 30 |
@@ -178,8 +178,7 @@ static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, | |||
178 | 0x00, index, | 178 | 0x00, index, |
179 | gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT); | 179 | gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT); |
180 | if (err < 0) | 180 | if (err < 0) |
181 | PDEBUG(D_ERR, | 181 | err("Failed to write registers to index 0x%04X, error %d)", |
182 | "Failed to write registers to index 0x%04X, error %d)", | ||
183 | index, err); | 182 | index, err); |
184 | 183 | ||
185 | return err; | 184 | return err; |
@@ -195,7 +194,7 @@ static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) | |||
195 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 194 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
196 | value, index, NULL, 0, PAC207_CTRL_TIMEOUT); | 195 | value, index, NULL, 0, PAC207_CTRL_TIMEOUT); |
197 | if (err) | 196 | if (err) |
198 | PDEBUG(D_ERR, "Failed to write a register (index 0x%04X," | 197 | err("Failed to write a register (index 0x%04X," |
199 | " value 0x%02X, error %d)", index, value, err); | 198 | " value 0x%02X, error %d)", index, value, err); |
200 | 199 | ||
201 | return err; | 200 | return err; |
@@ -211,8 +210,7 @@ static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) | |||
211 | 0x00, index, | 210 | 0x00, index, |
212 | gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT); | 211 | gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT); |
213 | if (res < 0) { | 212 | if (res < 0) { |
214 | PDEBUG(D_ERR, | 213 | err("Failed to read a register (index 0x%04X, error %d)", |
215 | "Failed to read a register (index 0x%04X, error %d)", | ||
216 | index, res); | 214 | index, res); |
217 | return res; | 215 | return res; |
218 | } | 216 | } |
@@ -496,7 +494,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | |||
496 | return 0; | 494 | return 0; |
497 | } | 495 | } |
498 | 496 | ||
499 | #ifdef CONFIG_INPUT | 497 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
500 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 498 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
501 | u8 *data, /* interrupt packet data */ | 499 | u8 *data, /* interrupt packet data */ |
502 | int len) /* interrput packet length */ | 500 | int len) /* interrput packet length */ |
@@ -526,7 +524,7 @@ static const struct sd_desc sd_desc = { | |||
526 | .stopN = sd_stopN, | 524 | .stopN = sd_stopN, |
527 | .dq_callback = pac207_do_auto_gain, | 525 | .dq_callback = pac207_do_auto_gain, |
528 | .pkt_scan = sd_pkt_scan, | 526 | .pkt_scan = sd_pkt_scan, |
529 | #ifdef CONFIG_INPUT | 527 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
530 | .int_pkt_scan = sd_int_pkt_scan, | 528 | .int_pkt_scan = sd_int_pkt_scan, |
531 | #endif | 529 | #endif |
532 | }; | 530 | }; |
@@ -572,17 +570,11 @@ static struct usb_driver sd_driver = { | |||
572 | /* -- module insert / remove -- */ | 570 | /* -- module insert / remove -- */ |
573 | static int __init sd_mod_init(void) | 571 | static int __init sd_mod_init(void) |
574 | { | 572 | { |
575 | int ret; | 573 | return usb_register(&sd_driver); |
576 | ret = usb_register(&sd_driver); | ||
577 | if (ret < 0) | ||
578 | return ret; | ||
579 | PDEBUG(D_PROBE, "registered"); | ||
580 | return 0; | ||
581 | } | 574 | } |
582 | static void __exit sd_mod_exit(void) | 575 | static void __exit sd_mod_exit(void) |
583 | { | 576 | { |
584 | usb_deregister(&sd_driver); | 577 | usb_deregister(&sd_driver); |
585 | PDEBUG(D_PROBE, "deregistered"); | ||
586 | } | 578 | } |
587 | 579 | ||
588 | module_init(sd_mod_init); | 580 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index a66df07d762..55fbea7381b 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c | |||
@@ -408,9 +408,8 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
408 | index, gspca_dev->usb_buf, len, | 408 | index, gspca_dev->usb_buf, len, |
409 | 500); | 409 | 500); |
410 | if (ret < 0) { | 410 | if (ret < 0) { |
411 | PDEBUG(D_ERR, "reg_w_buf(): " | 411 | err("reg_w_buf failed index 0x%02x, error %d", |
412 | "Failed to write registers to index 0x%x, error %i", | 412 | index, ret); |
413 | index, ret); | ||
414 | gspca_dev->usb_err = ret; | 413 | gspca_dev->usb_err = ret; |
415 | } | 414 | } |
416 | } | 415 | } |
@@ -432,9 +431,8 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
432 | 0, index, gspca_dev->usb_buf, 1, | 431 | 0, index, gspca_dev->usb_buf, 1, |
433 | 500); | 432 | 500); |
434 | if (ret < 0) { | 433 | if (ret < 0) { |
435 | PDEBUG(D_ERR, "reg_w(): " | 434 | err("reg_w() failed index 0x%02x, value 0x%02x, error %d", |
436 | "Failed to write register to index 0x%x, value 0x%x, error %i", | 435 | index, value, ret); |
437 | index, value, ret); | ||
438 | gspca_dev->usb_err = ret; | 436 | gspca_dev->usb_err = ret; |
439 | } | 437 | } |
440 | } | 438 | } |
@@ -468,10 +466,9 @@ static void reg_w_page(struct gspca_dev *gspca_dev, | |||
468 | 0, index, gspca_dev->usb_buf, 1, | 466 | 0, index, gspca_dev->usb_buf, 1, |
469 | 500); | 467 | 500); |
470 | if (ret < 0) { | 468 | if (ret < 0) { |
471 | PDEBUG(D_ERR, "reg_w_page(): " | 469 | err("reg_w_page() failed index 0x%02x, " |
472 | "Failed to write register to index 0x%x, " | 470 | "value 0x%02x, error %d", |
473 | "value 0x%x, error %i", | 471 | index, page[index], ret); |
474 | index, page[index], ret); | ||
475 | gspca_dev->usb_err = ret; | 472 | gspca_dev->usb_err = ret; |
476 | break; | 473 | break; |
477 | } | 474 | } |
@@ -900,9 +897,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | |||
900 | struct sd *sd = (struct sd *) gspca_dev; | 897 | struct sd *sd = (struct sd *) gspca_dev; |
901 | 898 | ||
902 | sd->contrast = val; | 899 | sd->contrast = val; |
903 | if (gspca_dev->streaming) { | 900 | if (gspca_dev->streaming) |
904 | setbrightcont(gspca_dev); | 901 | setbrightcont(gspca_dev); |
905 | } | ||
906 | return gspca_dev->usb_err; | 902 | return gspca_dev->usb_err; |
907 | } | 903 | } |
908 | 904 | ||
@@ -1135,7 +1131,7 @@ static int sd_chip_ident(struct gspca_dev *gspca_dev, | |||
1135 | } | 1131 | } |
1136 | #endif | 1132 | #endif |
1137 | 1133 | ||
1138 | #ifdef CONFIG_INPUT | 1134 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1139 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 1135 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
1140 | u8 *data, /* interrupt packet data */ | 1136 | u8 *data, /* interrupt packet data */ |
1141 | int len) /* interrput packet length */ | 1137 | int len) /* interrput packet length */ |
@@ -1182,7 +1178,7 @@ static const struct sd_desc sd_desc = { | |||
1182 | .set_register = sd_dbg_s_register, | 1178 | .set_register = sd_dbg_s_register, |
1183 | .get_chip_ident = sd_chip_ident, | 1179 | .get_chip_ident = sd_chip_ident, |
1184 | #endif | 1180 | #endif |
1185 | #ifdef CONFIG_INPUT | 1181 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1186 | .int_pkt_scan = sd_int_pkt_scan, | 1182 | .int_pkt_scan = sd_int_pkt_scan, |
1187 | #endif | 1183 | #endif |
1188 | }; | 1184 | }; |
@@ -1226,17 +1222,11 @@ static struct usb_driver sd_driver = { | |||
1226 | /* -- module insert / remove -- */ | 1222 | /* -- module insert / remove -- */ |
1227 | static int __init sd_mod_init(void) | 1223 | static int __init sd_mod_init(void) |
1228 | { | 1224 | { |
1229 | int ret; | 1225 | return usb_register(&sd_driver); |
1230 | ret = usb_register(&sd_driver); | ||
1231 | if (ret < 0) | ||
1232 | return ret; | ||
1233 | PDEBUG(D_PROBE, "registered"); | ||
1234 | return 0; | ||
1235 | } | 1226 | } |
1236 | static void __exit sd_mod_exit(void) | 1227 | static void __exit sd_mod_exit(void) |
1237 | { | 1228 | { |
1238 | usb_deregister(&sd_driver); | 1229 | usb_deregister(&sd_driver); |
1239 | PDEBUG(D_PROBE, "deregistered"); | ||
1240 | } | 1230 | } |
1241 | 1231 | ||
1242 | module_init(sd_mod_init); | 1232 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 1cb7e99e92b..7657b43b320 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -276,9 +276,8 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
276 | index, gspca_dev->usb_buf, len, | 276 | index, gspca_dev->usb_buf, len, |
277 | 500); | 277 | 500); |
278 | if (ret < 0) { | 278 | if (ret < 0) { |
279 | PDEBUG(D_ERR, "reg_w_buf(): " | 279 | err("reg_w_buf() failed index 0x%02x, error %d", |
280 | "Failed to write registers to index 0x%x, error %i", | 280 | index, ret); |
281 | index, ret); | ||
282 | gspca_dev->usb_err = ret; | 281 | gspca_dev->usb_err = ret; |
283 | } | 282 | } |
284 | } | 283 | } |
@@ -300,9 +299,8 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
300 | 0, index, gspca_dev->usb_buf, 1, | 299 | 0, index, gspca_dev->usb_buf, 1, |
301 | 500); | 300 | 500); |
302 | if (ret < 0) { | 301 | if (ret < 0) { |
303 | PDEBUG(D_ERR, "reg_w(): " | 302 | err("reg_w() failed index 0x%02x, value 0x%02x, error %d", |
304 | "Failed to write register to index 0x%x, value 0x%x, error %i", | 303 | index, value, ret); |
305 | index, value, ret); | ||
306 | gspca_dev->usb_err = ret; | 304 | gspca_dev->usb_err = ret; |
307 | } | 305 | } |
308 | } | 306 | } |
@@ -336,10 +334,9 @@ static void reg_w_page(struct gspca_dev *gspca_dev, | |||
336 | 0, index, gspca_dev->usb_buf, 1, | 334 | 0, index, gspca_dev->usb_buf, 1, |
337 | 500); | 335 | 500); |
338 | if (ret < 0) { | 336 | if (ret < 0) { |
339 | PDEBUG(D_ERR, "reg_w_page(): " | 337 | err("reg_w_page() failed index 0x%02x, " |
340 | "Failed to write register to index 0x%x, " | 338 | "value 0x%02x, error %d", |
341 | "value 0x%x, error %i", | 339 | index, page[index], ret); |
342 | index, page[index], ret); | ||
343 | gspca_dev->usb_err = ret; | 340 | gspca_dev->usb_err = ret; |
344 | break; | 341 | break; |
345 | } | 342 | } |
@@ -675,9 +672,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | |||
675 | struct sd *sd = (struct sd *) gspca_dev; | 672 | struct sd *sd = (struct sd *) gspca_dev; |
676 | 673 | ||
677 | sd->contrast = val; | 674 | sd->contrast = val; |
678 | if (gspca_dev->streaming) { | 675 | if (gspca_dev->streaming) |
679 | setcontrast(gspca_dev); | 676 | setcontrast(gspca_dev); |
680 | } | ||
681 | return gspca_dev->usb_err; | 677 | return gspca_dev->usb_err; |
682 | } | 678 | } |
683 | 679 | ||
@@ -792,7 +788,7 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
792 | return 0; | 788 | return 0; |
793 | } | 789 | } |
794 | 790 | ||
795 | #ifdef CONFIG_INPUT | 791 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
796 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 792 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
797 | u8 *data, /* interrupt packet data */ | 793 | u8 *data, /* interrupt packet data */ |
798 | int len) /* interrupt packet length */ | 794 | int len) /* interrupt packet length */ |
@@ -835,7 +831,7 @@ static const struct sd_desc sd_desc = { | |||
835 | .stop0 = sd_stop0, | 831 | .stop0 = sd_stop0, |
836 | .pkt_scan = sd_pkt_scan, | 832 | .pkt_scan = sd_pkt_scan, |
837 | .dq_callback = do_autogain, | 833 | .dq_callback = do_autogain, |
838 | #ifdef CONFIG_INPUT | 834 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
839 | .int_pkt_scan = sd_int_pkt_scan, | 835 | .int_pkt_scan = sd_int_pkt_scan, |
840 | #endif | 836 | #endif |
841 | }; | 837 | }; |
@@ -874,17 +870,11 @@ static struct usb_driver sd_driver = { | |||
874 | /* -- module insert / remove -- */ | 870 | /* -- module insert / remove -- */ |
875 | static int __init sd_mod_init(void) | 871 | static int __init sd_mod_init(void) |
876 | { | 872 | { |
877 | int ret; | 873 | return usb_register(&sd_driver); |
878 | ret = usb_register(&sd_driver); | ||
879 | if (ret < 0) | ||
880 | return ret; | ||
881 | PDEBUG(D_PROBE, "registered"); | ||
882 | return 0; | ||
883 | } | 874 | } |
884 | static void __exit sd_mod_exit(void) | 875 | static void __exit sd_mod_exit(void) |
885 | { | 876 | { |
886 | usb_deregister(&sd_driver); | 877 | usb_deregister(&sd_driver); |
887 | PDEBUG(D_PROBE, "deregistered"); | ||
888 | } | 878 | } |
889 | 879 | ||
890 | module_init(sd_mod_init); | 880 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c index 71d9447a798..40a06680502 100644 --- a/drivers/media/video/gspca/sn9c2028.c +++ b/drivers/media/video/gspca/sn9c2028.c | |||
@@ -75,7 +75,7 @@ static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command) | |||
75 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 75 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
76 | 2, 0, gspca_dev->usb_buf, 6, 500); | 76 | 2, 0, gspca_dev->usb_buf, 6, 500); |
77 | if (rc < 0) { | 77 | if (rc < 0) { |
78 | PDEBUG(D_ERR, "command write [%02x] error %d", | 78 | err("command write [%02x] error %d", |
79 | gspca_dev->usb_buf[0], rc); | 79 | gspca_dev->usb_buf[0], rc); |
80 | return rc; | 80 | return rc; |
81 | } | 81 | } |
@@ -93,7 +93,7 @@ static int sn9c2028_read1(struct gspca_dev *gspca_dev) | |||
93 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 93 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
94 | 1, 0, gspca_dev->usb_buf, 1, 500); | 94 | 1, 0, gspca_dev->usb_buf, 1, 500); |
95 | if (rc != 1) { | 95 | if (rc != 1) { |
96 | PDEBUG(D_ERR, "read1 error %d", rc); | 96 | err("read1 error %d", rc); |
97 | return (rc < 0) ? rc : -EIO; | 97 | return (rc < 0) ? rc : -EIO; |
98 | } | 98 | } |
99 | PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]); | 99 | PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]); |
@@ -109,7 +109,7 @@ static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading) | |||
109 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 109 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
110 | 4, 0, gspca_dev->usb_buf, 4, 500); | 110 | 4, 0, gspca_dev->usb_buf, 4, 500); |
111 | if (rc != 4) { | 111 | if (rc != 4) { |
112 | PDEBUG(D_ERR, "read4 error %d", rc); | 112 | err("read4 error %d", rc); |
113 | return (rc < 0) ? rc : -EIO; | 113 | return (rc < 0) ? rc : -EIO; |
114 | } | 114 | } |
115 | memcpy(reading, gspca_dev->usb_buf, 4); | 115 | memcpy(reading, gspca_dev->usb_buf, 4); |
@@ -131,7 +131,7 @@ static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command) | |||
131 | for (i = 0; i < 256 && status < 2; i++) | 131 | for (i = 0; i < 256 && status < 2; i++) |
132 | status = sn9c2028_read1(gspca_dev); | 132 | status = sn9c2028_read1(gspca_dev); |
133 | if (status != 2) { | 133 | if (status != 2) { |
134 | PDEBUG(D_ERR, "long command status read error %d", status); | 134 | err("long command status read error %d", status); |
135 | return (status < 0) ? status : -EIO; | 135 | return (status < 0) ? status : -EIO; |
136 | } | 136 | } |
137 | 137 | ||
@@ -638,7 +638,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
638 | err_code = start_vivitar_cam(gspca_dev); | 638 | err_code = start_vivitar_cam(gspca_dev); |
639 | break; | 639 | break; |
640 | default: | 640 | default: |
641 | PDEBUG(D_ERR, "Starting unknown camera, please report this"); | 641 | err("Starting unknown camera, please report this"); |
642 | return -ENXIO; | 642 | return -ENXIO; |
643 | } | 643 | } |
644 | 644 | ||
@@ -738,19 +738,12 @@ static struct usb_driver sd_driver = { | |||
738 | /* -- module insert / remove -- */ | 738 | /* -- module insert / remove -- */ |
739 | static int __init sd_mod_init(void) | 739 | static int __init sd_mod_init(void) |
740 | { | 740 | { |
741 | int ret; | 741 | return usb_register(&sd_driver); |
742 | |||
743 | ret = usb_register(&sd_driver); | ||
744 | if (ret < 0) | ||
745 | return ret; | ||
746 | PDEBUG(D_PROBE, "registered"); | ||
747 | return 0; | ||
748 | } | 742 | } |
749 | 743 | ||
750 | static void __exit sd_mod_exit(void) | 744 | static void __exit sd_mod_exit(void) |
751 | { | 745 | { |
752 | usb_deregister(&sd_driver); | 746 | usb_deregister(&sd_driver); |
753 | PDEBUG(D_PROBE, "deregistered"); | ||
754 | } | 747 | } |
755 | 748 | ||
756 | module_init(sd_mod_init); | 749 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 9052d570255..6b155ae3a74 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -18,9 +18,7 @@ | |||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #ifdef CONFIG_INPUT | ||
22 | #include <linux/input.h> | 21 | #include <linux/input.h> |
23 | #endif | ||
24 | 22 | ||
25 | #include "gspca.h" | 23 | #include "gspca.h" |
26 | #include "jpeg.h" | 24 | #include "jpeg.h" |
@@ -347,8 +345,8 @@ static const struct ctrl sd_ctrls[] = { | |||
347 | 345 | ||
348 | static const struct v4l2_pix_format vga_mode[] = { | 346 | static const struct v4l2_pix_format vga_mode[] = { |
349 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 347 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
350 | .bytesperline = 240, | 348 | .bytesperline = 160, |
351 | .sizeimage = 240 * 120, | 349 | .sizeimage = 160 * 120 * 4 / 8 + 590, |
352 | .colorspace = V4L2_COLORSPACE_JPEG, | 350 | .colorspace = V4L2_COLORSPACE_JPEG, |
353 | .priv = 0 | MODE_JPEG}, | 351 | .priv = 0 | MODE_JPEG}, |
354 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 352 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
@@ -357,13 +355,13 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
357 | .colorspace = V4L2_COLORSPACE_SRGB, | 355 | .colorspace = V4L2_COLORSPACE_SRGB, |
358 | .priv = 0 | MODE_RAW}, | 356 | .priv = 0 | MODE_RAW}, |
359 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 357 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
360 | .bytesperline = 240, | 358 | .bytesperline = 160, |
361 | .sizeimage = 240 * 120, | 359 | .sizeimage = 240 * 120, |
362 | .colorspace = V4L2_COLORSPACE_SRGB, | 360 | .colorspace = V4L2_COLORSPACE_SRGB, |
363 | .priv = 0}, | 361 | .priv = 0}, |
364 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 362 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
365 | .bytesperline = 480, | 363 | .bytesperline = 320, |
366 | .sizeimage = 480 * 240 , | 364 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
367 | .colorspace = V4L2_COLORSPACE_JPEG, | 365 | .colorspace = V4L2_COLORSPACE_JPEG, |
368 | .priv = 1 | MODE_JPEG}, | 366 | .priv = 1 | MODE_JPEG}, |
369 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 367 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
@@ -372,13 +370,13 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
372 | .colorspace = V4L2_COLORSPACE_SRGB, | 370 | .colorspace = V4L2_COLORSPACE_SRGB, |
373 | .priv = 1 | MODE_RAW}, | 371 | .priv = 1 | MODE_RAW}, |
374 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 372 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
375 | .bytesperline = 480, | 373 | .bytesperline = 320, |
376 | .sizeimage = 480 * 240 , | 374 | .sizeimage = 480 * 240 , |
377 | .colorspace = V4L2_COLORSPACE_SRGB, | 375 | .colorspace = V4L2_COLORSPACE_SRGB, |
378 | .priv = 1}, | 376 | .priv = 1}, |
379 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 377 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
380 | .bytesperline = 960, | 378 | .bytesperline = 640, |
381 | .sizeimage = 960 * 480, | 379 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
382 | .colorspace = V4L2_COLORSPACE_JPEG, | 380 | .colorspace = V4L2_COLORSPACE_JPEG, |
383 | .priv = 2 | MODE_JPEG}, | 381 | .priv = 2 | MODE_JPEG}, |
384 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 382 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
@@ -387,7 +385,7 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
387 | .colorspace = V4L2_COLORSPACE_SRGB, | 385 | .colorspace = V4L2_COLORSPACE_SRGB, |
388 | .priv = 2 | MODE_RAW}, | 386 | .priv = 2 | MODE_RAW}, |
389 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 387 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
390 | .bytesperline = 960, | 388 | .bytesperline = 640, |
391 | .sizeimage = 960 * 480, | 389 | .sizeimage = 960 * 480, |
392 | .colorspace = V4L2_COLORSPACE_SRGB, | 390 | .colorspace = V4L2_COLORSPACE_SRGB, |
393 | .priv = 2}, | 391 | .priv = 2}, |
@@ -395,8 +393,8 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
395 | 393 | ||
396 | static const struct v4l2_pix_format sxga_mode[] = { | 394 | static const struct v4l2_pix_format sxga_mode[] = { |
397 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 395 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
398 | .bytesperline = 240, | 396 | .bytesperline = 160, |
399 | .sizeimage = 240 * 120, | 397 | .sizeimage = 160 * 120 * 4 / 8 + 590, |
400 | .colorspace = V4L2_COLORSPACE_JPEG, | 398 | .colorspace = V4L2_COLORSPACE_JPEG, |
401 | .priv = 0 | MODE_JPEG}, | 399 | .priv = 0 | MODE_JPEG}, |
402 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 400 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
@@ -405,13 +403,13 @@ static const struct v4l2_pix_format sxga_mode[] = { | |||
405 | .colorspace = V4L2_COLORSPACE_SRGB, | 403 | .colorspace = V4L2_COLORSPACE_SRGB, |
406 | .priv = 0 | MODE_RAW}, | 404 | .priv = 0 | MODE_RAW}, |
407 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 405 | {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
408 | .bytesperline = 240, | 406 | .bytesperline = 160, |
409 | .sizeimage = 240 * 120, | 407 | .sizeimage = 240 * 120, |
410 | .colorspace = V4L2_COLORSPACE_SRGB, | 408 | .colorspace = V4L2_COLORSPACE_SRGB, |
411 | .priv = 0}, | 409 | .priv = 0}, |
412 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 410 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
413 | .bytesperline = 480, | 411 | .bytesperline = 320, |
414 | .sizeimage = 480 * 240 , | 412 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
415 | .colorspace = V4L2_COLORSPACE_JPEG, | 413 | .colorspace = V4L2_COLORSPACE_JPEG, |
416 | .priv = 1 | MODE_JPEG}, | 414 | .priv = 1 | MODE_JPEG}, |
417 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 415 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
@@ -420,13 +418,13 @@ static const struct v4l2_pix_format sxga_mode[] = { | |||
420 | .colorspace = V4L2_COLORSPACE_SRGB, | 418 | .colorspace = V4L2_COLORSPACE_SRGB, |
421 | .priv = 1 | MODE_RAW}, | 419 | .priv = 1 | MODE_RAW}, |
422 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 420 | {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
423 | .bytesperline = 480, | 421 | .bytesperline = 320, |
424 | .sizeimage = 480 * 240 , | 422 | .sizeimage = 480 * 240 , |
425 | .colorspace = V4L2_COLORSPACE_SRGB, | 423 | .colorspace = V4L2_COLORSPACE_SRGB, |
426 | .priv = 1}, | 424 | .priv = 1}, |
427 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 425 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
428 | .bytesperline = 960, | 426 | .bytesperline = 640, |
429 | .sizeimage = 960 * 480, | 427 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
430 | .colorspace = V4L2_COLORSPACE_JPEG, | 428 | .colorspace = V4L2_COLORSPACE_JPEG, |
431 | .priv = 2 | MODE_JPEG}, | 429 | .priv = 2 | MODE_JPEG}, |
432 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 430 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
@@ -435,13 +433,13 @@ static const struct v4l2_pix_format sxga_mode[] = { | |||
435 | .colorspace = V4L2_COLORSPACE_SRGB, | 433 | .colorspace = V4L2_COLORSPACE_SRGB, |
436 | .priv = 2 | MODE_RAW}, | 434 | .priv = 2 | MODE_RAW}, |
437 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, | 435 | {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, |
438 | .bytesperline = 960, | 436 | .bytesperline = 640, |
439 | .sizeimage = 960 * 480, | 437 | .sizeimage = 960 * 480, |
440 | .colorspace = V4L2_COLORSPACE_SRGB, | 438 | .colorspace = V4L2_COLORSPACE_SRGB, |
441 | .priv = 2}, | 439 | .priv = 2}, |
442 | {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 440 | {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
443 | .bytesperline = 1280, | 441 | .bytesperline = 1280, |
444 | .sizeimage = (1280 * 1024) + 64, | 442 | .sizeimage = 1280 * 1024, |
445 | .colorspace = V4L2_COLORSPACE_SRGB, | 443 | .colorspace = V4L2_COLORSPACE_SRGB, |
446 | .priv = 3 | MODE_RAW | MODE_SXGA}, | 444 | .priv = 3 | MODE_RAW | MODE_SXGA}, |
447 | }; | 445 | }; |
@@ -1272,7 +1270,8 @@ static int soi968_init_sensor(struct gspca_dev *gspca_dev) | |||
1272 | } | 1270 | } |
1273 | } | 1271 | } |
1274 | /* disable hflip and vflip */ | 1272 | /* disable hflip and vflip */ |
1275 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX); | 1273 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
1274 | | (1 << EXPOSURE_IDX); | ||
1276 | sd->hstart = 60; | 1275 | sd->hstart = 60; |
1277 | sd->vstart = 11; | 1276 | sd->vstart = 11; |
1278 | return 0; | 1277 | return 0; |
@@ -1351,7 +1350,9 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev) | |||
1351 | return -ENODEV; | 1350 | return -ENODEV; |
1352 | } | 1351 | } |
1353 | } | 1352 | } |
1354 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX); | 1353 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) |
1354 | | (1 << AUTOGAIN_IDX) | ||
1355 | | (1 << GAIN_IDX); | ||
1355 | sd->hstart = 2; | 1356 | sd->hstart = 2; |
1356 | sd->vstart = 2; | 1357 | sd->vstart = 2; |
1357 | sd->sensor = SENSOR_MT9V111; | 1358 | sd->sensor = SENSOR_MT9V111; |
@@ -1395,7 +1396,8 @@ static int mt9m112_init_sensor(struct gspca_dev *gspca_dev) | |||
1395 | return -ENODEV; | 1396 | return -ENODEV; |
1396 | } | 1397 | } |
1397 | } | 1398 | } |
1398 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX); | 1399 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) |
1400 | | (1 << GAIN_IDX); | ||
1399 | sd->hstart = 0; | 1401 | sd->hstart = 0; |
1400 | sd->vstart = 2; | 1402 | sd->vstart = 2; |
1401 | return 0; | 1403 | return 0; |
@@ -1412,7 +1414,8 @@ static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) | |||
1412 | return -ENODEV; | 1414 | return -ENODEV; |
1413 | } | 1415 | } |
1414 | } | 1416 | } |
1415 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX); | 1417 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) |
1418 | | (1 << GAIN_IDX); | ||
1416 | sd->hstart = 0; | 1419 | sd->hstart = 0; |
1417 | sd->vstart = 2; | 1420 | sd->vstart = 2; |
1418 | return 0; | 1421 | return 0; |
@@ -2304,7 +2307,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) | |||
2304 | do_autoexposure(gspca_dev, avg_lum); | 2307 | do_autoexposure(gspca_dev, avg_lum); |
2305 | } | 2308 | } |
2306 | 2309 | ||
2307 | #ifdef CONFIG_INPUT | 2310 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2308 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 2311 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
2309 | u8 *data, /* interrupt packet */ | 2312 | u8 *data, /* interrupt packet */ |
2310 | int len) /* interrupt packet length */ | 2313 | int len) /* interrupt packet length */ |
@@ -2386,7 +2389,7 @@ static const struct sd_desc sd_desc = { | |||
2386 | .start = sd_start, | 2389 | .start = sd_start, |
2387 | .stopN = sd_stopN, | 2390 | .stopN = sd_stopN, |
2388 | .pkt_scan = sd_pkt_scan, | 2391 | .pkt_scan = sd_pkt_scan, |
2389 | #ifdef CONFIG_INPUT | 2392 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2390 | .int_pkt_scan = sd_int_pkt_scan, | 2393 | .int_pkt_scan = sd_int_pkt_scan, |
2391 | #endif | 2394 | #endif |
2392 | .dq_callback = sd_dqcallback, | 2395 | .dq_callback = sd_dqcallback, |
@@ -2467,17 +2470,11 @@ static struct usb_driver sd_driver = { | |||
2467 | /* -- module insert / remove -- */ | 2470 | /* -- module insert / remove -- */ |
2468 | static int __init sd_mod_init(void) | 2471 | static int __init sd_mod_init(void) |
2469 | { | 2472 | { |
2470 | int ret; | 2473 | return usb_register(&sd_driver); |
2471 | ret = usb_register(&sd_driver); | ||
2472 | if (ret < 0) | ||
2473 | return ret; | ||
2474 | info("registered"); | ||
2475 | return 0; | ||
2476 | } | 2474 | } |
2477 | static void __exit sd_mod_exit(void) | 2475 | static void __exit sd_mod_exit(void) |
2478 | { | 2476 | { |
2479 | usb_deregister(&sd_driver); | 2477 | usb_deregister(&sd_driver); |
2480 | info("deregistered"); | ||
2481 | } | 2478 | } |
2482 | 2479 | ||
2483 | module_init(sd_mod_init); | 2480 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 204bb3af455..706f96f9265 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -323,10 +323,9 @@ static const __u8 initOv6650[] = { | |||
323 | 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, | 323 | 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, |
324 | 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 | 324 | 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 |
325 | }; | 325 | }; |
326 | static const __u8 ov6650_sensor_init[][8] = | 326 | static const __u8 ov6650_sensor_init[][8] = { |
327 | { | ||
328 | /* Bright, contrast, etc are set through SCBB interface. | 327 | /* Bright, contrast, etc are set through SCBB interface. |
329 | * AVCAP on win2 do not send any data on this controls. */ | 328 | * AVCAP on win2 do not send any data on this controls. */ |
330 | /* Anyway, some registers appears to alter bright and constrat */ | 329 | /* Anyway, some registers appears to alter bright and constrat */ |
331 | 330 | ||
332 | /* Reset sensor */ | 331 | /* Reset sensor */ |
@@ -544,7 +543,7 @@ static const __u8 initTas5130[] = { | |||
544 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | 543 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c |
545 | }; | 544 | }; |
546 | static const __u8 tas5130_sensor_init[][8] = { | 545 | static const __u8 tas5130_sensor_init[][8] = { |
547 | /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, | 546 | /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, |
548 | * shutter 0x47 short exposure? */ | 547 | * shutter 0x47 short exposure? */ |
549 | {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10}, | 548 | {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10}, |
550 | /* shutter 0x01 long exposure */ | 549 | /* shutter 0x01 long exposure */ |
@@ -861,7 +860,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
861 | i2c[4] |= reg11 - 1; | 860 | i2c[4] |= reg11 - 1; |
862 | 861 | ||
863 | /* If register 11 didn't change, don't change it */ | 862 | /* If register 11 didn't change, don't change it */ |
864 | if (sd->reg11 == reg11 ) | 863 | if (sd->reg11 == reg11) |
865 | i2c[0] = 0xa0; | 864 | i2c[0] = 0xa0; |
866 | 865 | ||
867 | if (i2c_w(gspca_dev, i2c) == 0) | 866 | if (i2c_w(gspca_dev, i2c) == 0) |
@@ -1388,7 +1387,7 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, | |||
1388 | return -EINVAL; | 1387 | return -EINVAL; |
1389 | } | 1388 | } |
1390 | 1389 | ||
1391 | #ifdef CONFIG_INPUT | 1390 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1392 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 1391 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
1393 | u8 *data, /* interrupt packet data */ | 1392 | u8 *data, /* interrupt packet data */ |
1394 | int len) /* interrupt packet length */ | 1393 | int len) /* interrupt packet length */ |
@@ -1419,7 +1418,7 @@ static const struct sd_desc sd_desc = { | |||
1419 | .pkt_scan = sd_pkt_scan, | 1418 | .pkt_scan = sd_pkt_scan, |
1420 | .querymenu = sd_querymenu, | 1419 | .querymenu = sd_querymenu, |
1421 | .dq_callback = do_autogain, | 1420 | .dq_callback = do_autogain, |
1422 | #ifdef CONFIG_INPUT | 1421 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1423 | .int_pkt_scan = sd_int_pkt_scan, | 1422 | .int_pkt_scan = sd_int_pkt_scan, |
1424 | #endif | 1423 | #endif |
1425 | }; | 1424 | }; |
@@ -1479,17 +1478,11 @@ static struct usb_driver sd_driver = { | |||
1479 | /* -- module insert / remove -- */ | 1478 | /* -- module insert / remove -- */ |
1480 | static int __init sd_mod_init(void) | 1479 | static int __init sd_mod_init(void) |
1481 | { | 1480 | { |
1482 | int ret; | 1481 | return usb_register(&sd_driver); |
1483 | ret = usb_register(&sd_driver); | ||
1484 | if (ret < 0) | ||
1485 | return ret; | ||
1486 | PDEBUG(D_PROBE, "registered"); | ||
1487 | return 0; | ||
1488 | } | 1482 | } |
1489 | static void __exit sd_mod_exit(void) | 1483 | static void __exit sd_mod_exit(void) |
1490 | { | 1484 | { |
1491 | usb_deregister(&sd_driver); | 1485 | usb_deregister(&sd_driver); |
1492 | PDEBUG(D_PROBE, "deregistered"); | ||
1493 | } | 1486 | } |
1494 | 1487 | ||
1495 | module_init(sd_mod_init); | 1488 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 370544361be..330dadc0010 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -31,24 +31,32 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); | |||
31 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); | 31 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); |
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | 33 | ||
34 | /* controls */ | ||
35 | enum e_ctrl { | ||
36 | BRIGHTNESS, | ||
37 | CONTRAST, | ||
38 | COLORS, | ||
39 | BLUE, | ||
40 | RED, | ||
41 | GAMMA, | ||
42 | AUTOGAIN, | ||
43 | HFLIP, | ||
44 | VFLIP, | ||
45 | SHARPNESS, | ||
46 | INFRARED, | ||
47 | FREQ, | ||
48 | NCTRLS /* number of controls */ | ||
49 | }; | ||
50 | |||
34 | /* specific webcam descriptor */ | 51 | /* specific webcam descriptor */ |
35 | struct sd { | 52 | struct sd { |
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 53 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
37 | 54 | ||
55 | struct gspca_ctrl ctrls[NCTRLS]; | ||
56 | |||
38 | atomic_t avg_lum; | 57 | atomic_t avg_lum; |
39 | u32 exposure; | 58 | u32 exposure; |
40 | 59 | ||
41 | u16 brightness; | ||
42 | u8 contrast; | ||
43 | u8 colors; | ||
44 | u8 autogain; | ||
45 | u8 blue; | ||
46 | u8 red; | ||
47 | u8 gamma; | ||
48 | u8 vflip; /* ov7630/ov7648 only */ | ||
49 | u8 sharpness; | ||
50 | u8 infrared; /* mt9v111 only */ | ||
51 | u8 freq; /* ov76xx only */ | ||
52 | u8 quality; /* image quality */ | 60 | u8 quality; /* image quality */ |
53 | #define QUALITY_MIN 60 | 61 | #define QUALITY_MIN 60 |
54 | #define QUALITY_MAX 95 | 62 | #define QUALITY_MAX 95 |
@@ -75,6 +83,7 @@ enum sensors { | |||
75 | SENSOR_GC0307, | 83 | SENSOR_GC0307, |
76 | SENSOR_HV7131R, | 84 | SENSOR_HV7131R, |
77 | SENSOR_MI0360, | 85 | SENSOR_MI0360, |
86 | SENSOR_MI0360B, | ||
78 | SENSOR_MO4000, | 87 | SENSOR_MO4000, |
79 | SENSOR_MT9V111, | 88 | SENSOR_MT9V111, |
80 | SENSOR_OM6802, | 89 | SENSOR_OM6802, |
@@ -88,48 +97,31 @@ enum sensors { | |||
88 | }; | 97 | }; |
89 | 98 | ||
90 | /* V4L2 controls supported by the driver */ | 99 | /* V4L2 controls supported by the driver */ |
91 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 100 | static void setbrightness(struct gspca_dev *gspca_dev); |
92 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 101 | static void setcontrast(struct gspca_dev *gspca_dev); |
93 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 102 | static void setcolors(struct gspca_dev *gspca_dev); |
94 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 103 | static void setredblue(struct gspca_dev *gspca_dev); |
95 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 104 | static void setgamma(struct gspca_dev *gspca_dev); |
96 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 105 | static void setautogain(struct gspca_dev *gspca_dev); |
97 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | 106 | static void sethvflip(struct gspca_dev *gspca_dev); |
98 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | 107 | static void setsharpness(struct gspca_dev *gspca_dev); |
99 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | 108 | static void setinfrared(struct gspca_dev *gspca_dev); |
100 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | 109 | static void setfreq(struct gspca_dev *gspca_dev); |
101 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | 110 | |
102 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | 111 | static const struct ctrl sd_ctrls[NCTRLS] = { |
103 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 112 | [BRIGHTNESS] = { |
104 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
105 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
106 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
107 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
108 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
109 | static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); | ||
110 | static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); | ||
111 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
112 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
113 | |||
114 | static const struct ctrl sd_ctrls[] = { | ||
115 | #define BRIGHTNESS_IDX 0 | ||
116 | { | ||
117 | { | 113 | { |
118 | .id = V4L2_CID_BRIGHTNESS, | 114 | .id = V4L2_CID_BRIGHTNESS, |
119 | .type = V4L2_CTRL_TYPE_INTEGER, | 115 | .type = V4L2_CTRL_TYPE_INTEGER, |
120 | .name = "Brightness", | 116 | .name = "Brightness", |
121 | .minimum = 0, | 117 | .minimum = 0, |
122 | #define BRIGHTNESS_MAX 0xffff | 118 | .maximum = 0xff, |
123 | .maximum = BRIGHTNESS_MAX, | ||
124 | .step = 1, | 119 | .step = 1, |
125 | #define BRIGHTNESS_DEF 0x8000 | 120 | .default_value = 0x80, |
126 | .default_value = BRIGHTNESS_DEF, | ||
127 | }, | 121 | }, |
128 | .set = sd_setbrightness, | 122 | .set_control = setbrightness |
129 | .get = sd_getbrightness, | ||
130 | }, | 123 | }, |
131 | #define CONTRAST_IDX 1 | 124 | [CONTRAST] = { |
132 | { | ||
133 | { | 125 | { |
134 | .id = V4L2_CID_CONTRAST, | 126 | .id = V4L2_CID_CONTRAST, |
135 | .type = V4L2_CTRL_TYPE_INTEGER, | 127 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -138,14 +130,11 @@ static const struct ctrl sd_ctrls[] = { | |||
138 | #define CONTRAST_MAX 127 | 130 | #define CONTRAST_MAX 127 |
139 | .maximum = CONTRAST_MAX, | 131 | .maximum = CONTRAST_MAX, |
140 | .step = 1, | 132 | .step = 1, |
141 | #define CONTRAST_DEF 63 | 133 | .default_value = 63, |
142 | .default_value = CONTRAST_DEF, | ||
143 | }, | 134 | }, |
144 | .set = sd_setcontrast, | 135 | .set_control = setcontrast |
145 | .get = sd_getcontrast, | ||
146 | }, | 136 | }, |
147 | #define COLOR_IDX 2 | 137 | [COLORS] = { |
148 | { | ||
149 | { | 138 | { |
150 | .id = V4L2_CID_SATURATION, | 139 | .id = V4L2_CID_SATURATION, |
151 | .type = V4L2_CTRL_TYPE_INTEGER, | 140 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -153,14 +142,12 @@ static const struct ctrl sd_ctrls[] = { | |||
153 | .minimum = 0, | 142 | .minimum = 0, |
154 | .maximum = 40, | 143 | .maximum = 40, |
155 | .step = 1, | 144 | .step = 1, |
156 | #define COLOR_DEF 25 | 145 | #define COLORS_DEF 25 |
157 | .default_value = COLOR_DEF, | 146 | .default_value = COLORS_DEF, |
158 | }, | 147 | }, |
159 | .set = sd_setcolors, | 148 | .set_control = setcolors |
160 | .get = sd_getcolors, | ||
161 | }, | 149 | }, |
162 | #define BLUE_BALANCE_IDX 3 | 150 | [BLUE] = { |
163 | { | ||
164 | { | 151 | { |
165 | .id = V4L2_CID_BLUE_BALANCE, | 152 | .id = V4L2_CID_BLUE_BALANCE, |
166 | .type = V4L2_CTRL_TYPE_INTEGER, | 153 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -168,14 +155,11 @@ static const struct ctrl sd_ctrls[] = { | |||
168 | .minimum = 24, | 155 | .minimum = 24, |
169 | .maximum = 40, | 156 | .maximum = 40, |
170 | .step = 1, | 157 | .step = 1, |
171 | #define BLUE_BALANCE_DEF 32 | 158 | .default_value = 32, |
172 | .default_value = BLUE_BALANCE_DEF, | ||
173 | }, | 159 | }, |
174 | .set = sd_setblue_balance, | 160 | .set_control = setredblue |
175 | .get = sd_getblue_balance, | ||
176 | }, | 161 | }, |
177 | #define RED_BALANCE_IDX 4 | 162 | [RED] = { |
178 | { | ||
179 | { | 163 | { |
180 | .id = V4L2_CID_RED_BALANCE, | 164 | .id = V4L2_CID_RED_BALANCE, |
181 | .type = V4L2_CTRL_TYPE_INTEGER, | 165 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -183,14 +167,11 @@ static const struct ctrl sd_ctrls[] = { | |||
183 | .minimum = 24, | 167 | .minimum = 24, |
184 | .maximum = 40, | 168 | .maximum = 40, |
185 | .step = 1, | 169 | .step = 1, |
186 | #define RED_BALANCE_DEF 32 | 170 | .default_value = 32, |
187 | .default_value = RED_BALANCE_DEF, | ||
188 | }, | 171 | }, |
189 | .set = sd_setred_balance, | 172 | .set_control = setredblue |
190 | .get = sd_getred_balance, | ||
191 | }, | 173 | }, |
192 | #define GAMMA_IDX 5 | 174 | [GAMMA] = { |
193 | { | ||
194 | { | 175 | { |
195 | .id = V4L2_CID_GAMMA, | 176 | .id = V4L2_CID_GAMMA, |
196 | .type = V4L2_CTRL_TYPE_INTEGER, | 177 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -201,11 +182,9 @@ static const struct ctrl sd_ctrls[] = { | |||
201 | #define GAMMA_DEF 20 | 182 | #define GAMMA_DEF 20 |
202 | .default_value = GAMMA_DEF, | 183 | .default_value = GAMMA_DEF, |
203 | }, | 184 | }, |
204 | .set = sd_setgamma, | 185 | .set_control = setgamma |
205 | .get = sd_getgamma, | ||
206 | }, | 186 | }, |
207 | #define AUTOGAIN_IDX 6 | 187 | [AUTOGAIN] = { |
208 | { | ||
209 | { | 188 | { |
210 | .id = V4L2_CID_AUTOGAIN, | 189 | .id = V4L2_CID_AUTOGAIN, |
211 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 190 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -213,15 +192,23 @@ static const struct ctrl sd_ctrls[] = { | |||
213 | .minimum = 0, | 192 | .minimum = 0, |
214 | .maximum = 1, | 193 | .maximum = 1, |
215 | .step = 1, | 194 | .step = 1, |
216 | #define AUTOGAIN_DEF 1 | 195 | .default_value = 1 |
217 | .default_value = AUTOGAIN_DEF, | 196 | }, |
197 | .set_control = setautogain | ||
198 | }, | ||
199 | [HFLIP] = { | ||
200 | { | ||
201 | .id = V4L2_CID_HFLIP, | ||
202 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
203 | .name = "Mirror", | ||
204 | .minimum = 0, | ||
205 | .maximum = 1, | ||
206 | .step = 1, | ||
207 | .default_value = 0, | ||
218 | }, | 208 | }, |
219 | .set = sd_setautogain, | 209 | .set_control = sethvflip |
220 | .get = sd_getautogain, | ||
221 | }, | 210 | }, |
222 | /* ov7630/ov7648 only */ | 211 | [VFLIP] = { |
223 | #define VFLIP_IDX 7 | ||
224 | { | ||
225 | { | 212 | { |
226 | .id = V4L2_CID_VFLIP, | 213 | .id = V4L2_CID_VFLIP, |
227 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 214 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -229,14 +216,11 @@ static const struct ctrl sd_ctrls[] = { | |||
229 | .minimum = 0, | 216 | .minimum = 0, |
230 | .maximum = 1, | 217 | .maximum = 1, |
231 | .step = 1, | 218 | .step = 1, |
232 | #define VFLIP_DEF 0 | 219 | .default_value = 0, |
233 | .default_value = VFLIP_DEF, | ||
234 | }, | 220 | }, |
235 | .set = sd_setvflip, | 221 | .set_control = sethvflip |
236 | .get = sd_getvflip, | ||
237 | }, | 222 | }, |
238 | #define SHARPNESS_IDX 8 | 223 | [SHARPNESS] = { |
239 | { | ||
240 | { | 224 | { |
241 | .id = V4L2_CID_SHARPNESS, | 225 | .id = V4L2_CID_SHARPNESS, |
242 | .type = V4L2_CTRL_TYPE_INTEGER, | 226 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -244,15 +228,12 @@ static const struct ctrl sd_ctrls[] = { | |||
244 | .minimum = 0, | 228 | .minimum = 0, |
245 | .maximum = 255, | 229 | .maximum = 255, |
246 | .step = 1, | 230 | .step = 1, |
247 | #define SHARPNESS_DEF 90 | 231 | .default_value = 90, |
248 | .default_value = SHARPNESS_DEF, | ||
249 | }, | 232 | }, |
250 | .set = sd_setsharpness, | 233 | .set_control = setsharpness |
251 | .get = sd_getsharpness, | ||
252 | }, | 234 | }, |
253 | /* mt9v111 only */ | 235 | /* mt9v111 only */ |
254 | #define INFRARED_IDX 9 | 236 | [INFRARED] = { |
255 | { | ||
256 | { | 237 | { |
257 | .id = V4L2_CID_INFRARED, | 238 | .id = V4L2_CID_INFRARED, |
258 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 239 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -260,15 +241,12 @@ static const struct ctrl sd_ctrls[] = { | |||
260 | .minimum = 0, | 241 | .minimum = 0, |
261 | .maximum = 1, | 242 | .maximum = 1, |
262 | .step = 1, | 243 | .step = 1, |
263 | #define INFRARED_DEF 0 | 244 | .default_value = 0, |
264 | .default_value = INFRARED_DEF, | ||
265 | }, | 245 | }, |
266 | .set = sd_setinfrared, | 246 | .set_control = setinfrared |
267 | .get = sd_getinfrared, | ||
268 | }, | 247 | }, |
269 | /* ov7630/ov7648/ov7660 only */ | 248 | /* ov7630/ov7648/ov7660 only */ |
270 | #define FREQ_IDX 10 | 249 | [FREQ] = { |
271 | { | ||
272 | { | 250 | { |
273 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 251 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
274 | .type = V4L2_CTRL_TYPE_MENU, | 252 | .type = V4L2_CTRL_TYPE_MENU, |
@@ -276,69 +254,85 @@ static const struct ctrl sd_ctrls[] = { | |||
276 | .minimum = 0, | 254 | .minimum = 0, |
277 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | 255 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ |
278 | .step = 1, | 256 | .step = 1, |
279 | #define FREQ_DEF 1 | 257 | .default_value = 1, |
280 | .default_value = FREQ_DEF, | ||
281 | }, | 258 | }, |
282 | .set = sd_setfreq, | 259 | .set_control = setfreq |
283 | .get = sd_getfreq, | ||
284 | }, | 260 | }, |
285 | }; | 261 | }; |
286 | 262 | ||
287 | /* table of the disabled controls */ | 263 | /* table of the disabled controls */ |
288 | static const __u32 ctrl_dis[] = { | 264 | static const __u32 ctrl_dis[] = { |
289 | [SENSOR_ADCM1700] = (1 << AUTOGAIN_IDX) | | 265 | [SENSOR_ADCM1700] = (1 << AUTOGAIN) | |
290 | (1 << INFRARED_IDX) | | 266 | (1 << INFRARED) | |
291 | (1 << VFLIP_IDX) | | 267 | (1 << HFLIP) | |
292 | (1 << FREQ_IDX), | 268 | (1 << VFLIP) | |
293 | 269 | (1 << FREQ), | |
294 | [SENSOR_GC0307] = (1 << INFRARED_IDX) | | 270 | |
295 | (1 << VFLIP_IDX) | | 271 | [SENSOR_GC0307] = (1 << INFRARED) | |
296 | (1 << FREQ_IDX), | 272 | (1 << HFLIP) | |
297 | 273 | (1 << VFLIP) | | |
298 | [SENSOR_HV7131R] = (1 << INFRARED_IDX) | | 274 | (1 << FREQ), |
299 | (1 << FREQ_IDX), | 275 | |
300 | 276 | [SENSOR_HV7131R] = (1 << INFRARED) | | |
301 | [SENSOR_MI0360] = (1 << INFRARED_IDX) | | 277 | (1 << HFLIP) | |
302 | (1 << VFLIP_IDX) | | 278 | (1 << FREQ), |
303 | (1 << FREQ_IDX), | 279 | |
304 | 280 | [SENSOR_MI0360] = (1 << INFRARED) | | |
305 | [SENSOR_MO4000] = (1 << INFRARED_IDX) | | 281 | (1 << HFLIP) | |
306 | (1 << VFLIP_IDX) | | 282 | (1 << VFLIP) | |
307 | (1 << FREQ_IDX), | 283 | (1 << FREQ), |
308 | 284 | ||
309 | [SENSOR_MT9V111] = (1 << VFLIP_IDX) | | 285 | [SENSOR_MI0360B] = (1 << INFRARED) | |
310 | (1 << FREQ_IDX), | 286 | (1 << HFLIP) | |
311 | 287 | (1 << VFLIP) | | |
312 | [SENSOR_OM6802] = (1 << INFRARED_IDX) | | 288 | (1 << FREQ), |
313 | (1 << VFLIP_IDX) | | 289 | |
314 | (1 << FREQ_IDX), | 290 | [SENSOR_MO4000] = (1 << INFRARED) | |
315 | 291 | (1 << HFLIP) | | |
316 | [SENSOR_OV7630] = (1 << INFRARED_IDX), | 292 | (1 << VFLIP) | |
317 | 293 | (1 << FREQ), | |
318 | [SENSOR_OV7648] = (1 << INFRARED_IDX), | 294 | |
319 | 295 | [SENSOR_MT9V111] = (1 << HFLIP) | | |
320 | [SENSOR_OV7660] = (1 << AUTOGAIN_IDX) | | 296 | (1 << VFLIP) | |
321 | (1 << INFRARED_IDX) | | 297 | (1 << FREQ), |
322 | (1 << VFLIP_IDX), | 298 | |
323 | 299 | [SENSOR_OM6802] = (1 << INFRARED) | | |
324 | [SENSOR_PO1030] = (1 << AUTOGAIN_IDX) | | 300 | (1 << HFLIP) | |
325 | (1 << INFRARED_IDX) | | 301 | (1 << VFLIP) | |
326 | (1 << VFLIP_IDX) | | 302 | (1 << FREQ), |
327 | (1 << FREQ_IDX), | 303 | |
328 | 304 | [SENSOR_OV7630] = (1 << INFRARED) | | |
329 | [SENSOR_PO2030N] = (1 << AUTOGAIN_IDX) | | 305 | (1 << HFLIP), |
330 | (1 << INFRARED_IDX) | | 306 | |
331 | (1 << VFLIP_IDX) | | 307 | [SENSOR_OV7648] = (1 << INFRARED) | |
332 | (1 << FREQ_IDX), | 308 | (1 << HFLIP), |
333 | [SENSOR_SOI768] = (1 << AUTOGAIN_IDX) | | 309 | |
334 | (1 << INFRARED_IDX) | | 310 | [SENSOR_OV7660] = (1 << AUTOGAIN) | |
335 | (1 << VFLIP_IDX) | | 311 | (1 << INFRARED) | |
336 | (1 << FREQ_IDX), | 312 | (1 << HFLIP) | |
337 | 313 | (1 << VFLIP), | |
338 | [SENSOR_SP80708] = (1 << AUTOGAIN_IDX) | | 314 | |
339 | (1 << INFRARED_IDX) | | 315 | [SENSOR_PO1030] = (1 << AUTOGAIN) | |
340 | (1 << VFLIP_IDX) | | 316 | (1 << INFRARED) | |
341 | (1 << FREQ_IDX), | 317 | (1 << HFLIP) | |
318 | (1 << VFLIP) | | ||
319 | (1 << FREQ), | ||
320 | |||
321 | [SENSOR_PO2030N] = (1 << AUTOGAIN) | | ||
322 | (1 << INFRARED) | | ||
323 | (1 << FREQ), | ||
324 | |||
325 | [SENSOR_SOI768] = (1 << AUTOGAIN) | | ||
326 | (1 << INFRARED) | | ||
327 | (1 << HFLIP) | | ||
328 | (1 << VFLIP) | | ||
329 | (1 << FREQ), | ||
330 | |||
331 | [SENSOR_SP80708] = (1 << AUTOGAIN) | | ||
332 | (1 << INFRARED) | | ||
333 | (1 << HFLIP) | | ||
334 | (1 << VFLIP) | | ||
335 | (1 << FREQ), | ||
342 | }; | 336 | }; |
343 | 337 | ||
344 | static const struct v4l2_pix_format cif_mode[] = { | 338 | static const struct v4l2_pix_format cif_mode[] = { |
@@ -411,6 +405,17 @@ static const u8 sn_mi0360[0x1c] = { | |||
411 | 0x06, 0x00, 0x00, 0x00 | 405 | 0x06, 0x00, 0x00, 0x00 |
412 | }; | 406 | }; |
413 | 407 | ||
408 | static const u8 sn_mi0360b[0x1c] = { | ||
409 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | ||
410 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, | ||
411 | /* reg8 reg9 rega regb regc regd rege regf */ | ||
412 | 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
413 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
414 | 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40, | ||
415 | /* reg18 reg19 reg1a reg1b */ | ||
416 | 0x06, 0x00, 0x00, 0x00 | ||
417 | }; | ||
418 | |||
414 | static const u8 sn_mo4000[0x1c] = { | 419 | static const u8 sn_mo4000[0x1c] = { |
415 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 420 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
416 | 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, | 421 | 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, |
@@ -527,6 +532,7 @@ static const u8 *sn_tb[] = { | |||
527 | [SENSOR_GC0307] = sn_gc0307, | 532 | [SENSOR_GC0307] = sn_gc0307, |
528 | [SENSOR_HV7131R] = sn_hv7131, | 533 | [SENSOR_HV7131R] = sn_hv7131, |
529 | [SENSOR_MI0360] = sn_mi0360, | 534 | [SENSOR_MI0360] = sn_mi0360, |
535 | [SENSOR_MI0360B] = sn_mi0360b, | ||
530 | [SENSOR_MO4000] = sn_mo4000, | 536 | [SENSOR_MO4000] = sn_mo4000, |
531 | [SENSOR_MT9V111] = sn_mt9v111, | 537 | [SENSOR_MT9V111] = sn_mt9v111, |
532 | [SENSOR_OM6802] = sn_om6802, | 538 | [SENSOR_OM6802] = sn_om6802, |
@@ -572,20 +578,23 @@ static const u8 reg84[] = { | |||
572 | 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ | 578 | 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ |
573 | 0x00, 0x00, 0x00 /* YUV offsets */ | 579 | 0x00, 0x00, 0x00 /* YUV offsets */ |
574 | }; | 580 | }; |
581 | |||
582 | #define DELAY 0xdd | ||
583 | |||
575 | static const u8 adcm1700_sensor_init[][8] = { | 584 | static const u8 adcm1700_sensor_init[][8] = { |
576 | {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10}, | 585 | {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10}, |
577 | {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */ | 586 | {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */ |
578 | {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | 587 | {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
579 | {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, | 588 | {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, |
580 | {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | 589 | {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
581 | {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10}, | 590 | {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10}, |
582 | {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10}, | 591 | {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10}, |
583 | {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10}, | 592 | {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10}, |
584 | {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10}, | 593 | {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10}, |
585 | {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10}, | 594 | {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10}, |
586 | {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | 595 | {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
587 | {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10}, | 596 | {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10}, |
588 | {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | 597 | {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
589 | {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10}, | 598 | {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10}, |
590 | {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, | 599 | {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, |
591 | {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10}, | 600 | {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10}, |
@@ -629,7 +638,7 @@ static const u8 gc0307_sensor_init[][8] = { | |||
629 | {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10}, | 638 | {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10}, |
630 | {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10}, | 639 | {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10}, |
631 | {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10}, | 640 | {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10}, |
632 | {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/ | 641 | {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/ |
633 | {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10}, | 642 | {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10}, |
634 | {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10}, | 643 | {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10}, |
635 | {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10}, | 644 | {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10}, |
@@ -747,6 +756,62 @@ static const u8 mi0360_sensor_init[][8] = { | |||
747 | {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ | 756 | {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ |
748 | {} | 757 | {} |
749 | }; | 758 | }; |
759 | static const u8 mi0360b_sensor_init[][8] = { | ||
760 | {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
761 | {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, | ||
762 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/ | ||
763 | {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
764 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/ | ||
765 | {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, | ||
766 | {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, | ||
767 | {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
768 | {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
769 | {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
770 | {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
771 | {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
772 | {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
773 | {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
774 | {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
775 | {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
776 | {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
777 | {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
778 | {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
779 | {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
780 | {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, | ||
781 | {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
782 | {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
783 | {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, | ||
784 | {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10}, | ||
785 | {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
786 | {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, | ||
787 | {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10}, | ||
788 | {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10}, | ||
789 | {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, | ||
790 | {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, | ||
791 | {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
792 | {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
793 | {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10}, | ||
794 | {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, | ||
795 | |||
796 | {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, | ||
797 | {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, | ||
798 | {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, | ||
799 | {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, | ||
800 | {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, | ||
801 | {} | ||
802 | }; | ||
803 | static const u8 mi0360b_sensor_param1[][8] = { | ||
804 | {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
805 | {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10}, | ||
806 | {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, | ||
807 | {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ | ||
808 | |||
809 | {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10}, | ||
810 | {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10}, | ||
811 | {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ | ||
812 | {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ | ||
813 | {} | ||
814 | }; | ||
750 | static const u8 mo4000_sensor_init[][8] = { | 815 | static const u8 mo4000_sensor_init[][8] = { |
751 | {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, | 816 | {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, |
752 | {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, | 817 | {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, |
@@ -772,7 +837,7 @@ static const u8 mo4000_sensor_init[][8] = { | |||
772 | }; | 837 | }; |
773 | static const u8 mt9v111_sensor_init[][8] = { | 838 | static const u8 mt9v111_sensor_init[][8] = { |
774 | {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ | 839 | {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ |
775 | {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ | 840 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ |
776 | {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, | 841 | {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, |
777 | {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ | 842 | {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ |
778 | {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ | 843 | {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ |
@@ -860,10 +925,10 @@ static const u8 om6802_sensor_param1[][8] = { | |||
860 | static const u8 ov7630_sensor_init[][8] = { | 925 | static const u8 ov7630_sensor_init[][8] = { |
861 | {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, | 926 | {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, |
862 | {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, | 927 | {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, |
863 | {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ | 928 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ |
864 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, | 929 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, |
865 | {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, | 930 | {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, |
866 | {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ | 931 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ |
867 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, | 932 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, |
868 | /* win: i2c_r from 00 to 80 */ | 933 | /* win: i2c_r from 00 to 80 */ |
869 | {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, | 934 | {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, |
@@ -917,7 +982,7 @@ static const u8 ov7630_sensor_param1[][8] = { | |||
917 | static const u8 ov7648_sensor_init[][8] = { | 982 | static const u8 ov7648_sensor_init[][8] = { |
918 | {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, | 983 | {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, |
919 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ | 984 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ |
920 | {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ | 985 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ |
921 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | 986 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, |
922 | {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10}, | 987 | {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10}, |
923 | {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10}, | 988 | {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10}, |
@@ -966,7 +1031,7 @@ static const u8 ov7648_sensor_param1[][8] = { | |||
966 | 1031 | ||
967 | static const u8 ov7660_sensor_init[][8] = { | 1032 | static const u8 ov7660_sensor_init[][8] = { |
968 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | 1033 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ |
969 | {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ | 1034 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ |
970 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, | 1035 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, |
971 | /* Outformat = rawRGB */ | 1036 | /* Outformat = rawRGB */ |
972 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ | 1037 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ |
@@ -1062,7 +1127,7 @@ static const u8 ov7660_sensor_param1[][8] = { | |||
1062 | static const u8 po1030_sensor_init[][8] = { | 1127 | static const u8 po1030_sensor_init[][8] = { |
1063 | /* the sensor registers are described in m5602/m5602_po1030.h */ | 1128 | /* the sensor registers are described in m5602/m5602_po1030.h */ |
1064 | {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */ | 1129 | {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */ |
1065 | {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ | 1130 | {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ |
1066 | {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10}, | 1131 | {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10}, |
1067 | {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10}, | 1132 | {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10}, |
1068 | {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10}, | 1133 | {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10}, |
@@ -1116,10 +1181,10 @@ static const u8 po1030_sensor_param1[][8] = { | |||
1116 | static const u8 po2030n_sensor_init[][8] = { | 1181 | static const u8 po2030n_sensor_init[][8] = { |
1117 | {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10}, | 1182 | {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10}, |
1118 | {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10}, | 1183 | {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10}, |
1119 | {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ | 1184 | {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ |
1120 | {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 1185 | {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10}, |
1121 | {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10}, | 1186 | {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10}, |
1122 | {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ | 1187 | {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ |
1123 | {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10}, | 1188 | {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10}, |
1124 | {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, | 1189 | {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, |
1125 | {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10}, | 1190 | {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10}, |
@@ -1168,7 +1233,7 @@ static const u8 po2030n_sensor_init[][8] = { | |||
1168 | }; | 1233 | }; |
1169 | static const u8 po2030n_sensor_param1[][8] = { | 1234 | static const u8 po2030n_sensor_param1[][8] = { |
1170 | {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10}, | 1235 | {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10}, |
1171 | {0xdd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ | 1236 | {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ |
1172 | {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, | 1237 | {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, |
1173 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, | 1238 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, |
1174 | {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10}, | 1239 | {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10}, |
@@ -1182,16 +1247,16 @@ static const u8 po2030n_sensor_param1[][8] = { | |||
1182 | {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10}, | 1247 | {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10}, |
1183 | /*after start*/ | 1248 | /*after start*/ |
1184 | {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10}, | 1249 | {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10}, |
1185 | {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ | 1250 | {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ |
1186 | {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10}, | 1251 | {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10}, |
1187 | {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ | 1252 | {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ |
1188 | {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10}, | 1253 | {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10}, |
1189 | {} | 1254 | {} |
1190 | }; | 1255 | }; |
1191 | 1256 | ||
1192 | static const u8 soi768_sensor_init[][8] = { | 1257 | static const u8 soi768_sensor_init[][8] = { |
1193 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ | 1258 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ |
1194 | {0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */ | 1259 | {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */ |
1195 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | 1260 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, |
1196 | {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, | 1261 | {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, |
1197 | {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10}, | 1262 | {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10}, |
@@ -1310,6 +1375,7 @@ static const u8 (*sensor_init[])[8] = { | |||
1310 | [SENSOR_GC0307] = gc0307_sensor_init, | 1375 | [SENSOR_GC0307] = gc0307_sensor_init, |
1311 | [SENSOR_HV7131R] = hv7131r_sensor_init, | 1376 | [SENSOR_HV7131R] = hv7131r_sensor_init, |
1312 | [SENSOR_MI0360] = mi0360_sensor_init, | 1377 | [SENSOR_MI0360] = mi0360_sensor_init, |
1378 | [SENSOR_MI0360B] = mi0360b_sensor_init, | ||
1313 | [SENSOR_MO4000] = mo4000_sensor_init, | 1379 | [SENSOR_MO4000] = mo4000_sensor_init, |
1314 | [SENSOR_MT9V111] = mt9v111_sensor_init, | 1380 | [SENSOR_MT9V111] = mt9v111_sensor_init, |
1315 | [SENSOR_OM6802] = om6802_sensor_init, | 1381 | [SENSOR_OM6802] = om6802_sensor_init, |
@@ -1326,13 +1392,17 @@ static const u8 (*sensor_init[])[8] = { | |||
1326 | static void reg_r(struct gspca_dev *gspca_dev, | 1392 | static void reg_r(struct gspca_dev *gspca_dev, |
1327 | u16 value, int len) | 1393 | u16 value, int len) |
1328 | { | 1394 | { |
1395 | int ret; | ||
1396 | |||
1397 | if (gspca_dev->usb_err < 0) | ||
1398 | return; | ||
1329 | #ifdef GSPCA_DEBUG | 1399 | #ifdef GSPCA_DEBUG |
1330 | if (len > USB_BUF_SZ) { | 1400 | if (len > USB_BUF_SZ) { |
1331 | err("reg_r: buffer overflow"); | 1401 | err("reg_r: buffer overflow"); |
1332 | return; | 1402 | return; |
1333 | } | 1403 | } |
1334 | #endif | 1404 | #endif |
1335 | usb_control_msg(gspca_dev->dev, | 1405 | ret = usb_control_msg(gspca_dev->dev, |
1336 | usb_rcvctrlpipe(gspca_dev->dev, 0), | 1406 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
1337 | 0, | 1407 | 0, |
1338 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 1408 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -1340,15 +1410,23 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
1340 | gspca_dev->usb_buf, len, | 1410 | gspca_dev->usb_buf, len, |
1341 | 500); | 1411 | 500); |
1342 | PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]); | 1412 | PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]); |
1413 | if (ret < 0) { | ||
1414 | err("reg_r err %d", ret); | ||
1415 | gspca_dev->usb_err = ret; | ||
1416 | } | ||
1343 | } | 1417 | } |
1344 | 1418 | ||
1345 | static void reg_w1(struct gspca_dev *gspca_dev, | 1419 | static void reg_w1(struct gspca_dev *gspca_dev, |
1346 | u16 value, | 1420 | u16 value, |
1347 | u8 data) | 1421 | u8 data) |
1348 | { | 1422 | { |
1423 | int ret; | ||
1424 | |||
1425 | if (gspca_dev->usb_err < 0) | ||
1426 | return; | ||
1349 | PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data); | 1427 | PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data); |
1350 | gspca_dev->usb_buf[0] = data; | 1428 | gspca_dev->usb_buf[0] = data; |
1351 | usb_control_msg(gspca_dev->dev, | 1429 | ret = usb_control_msg(gspca_dev->dev, |
1352 | usb_sndctrlpipe(gspca_dev->dev, 0), | 1430 | usb_sndctrlpipe(gspca_dev->dev, 0), |
1353 | 0x08, | 1431 | 0x08, |
1354 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 1432 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -1356,12 +1434,20 @@ static void reg_w1(struct gspca_dev *gspca_dev, | |||
1356 | 0, | 1434 | 0, |
1357 | gspca_dev->usb_buf, 1, | 1435 | gspca_dev->usb_buf, 1, |
1358 | 500); | 1436 | 500); |
1437 | if (ret < 0) { | ||
1438 | err("reg_w1 err %d", ret); | ||
1439 | gspca_dev->usb_err = ret; | ||
1440 | } | ||
1359 | } | 1441 | } |
1360 | static void reg_w(struct gspca_dev *gspca_dev, | 1442 | static void reg_w(struct gspca_dev *gspca_dev, |
1361 | u16 value, | 1443 | u16 value, |
1362 | const u8 *buffer, | 1444 | const u8 *buffer, |
1363 | int len) | 1445 | int len) |
1364 | { | 1446 | { |
1447 | int ret; | ||
1448 | |||
1449 | if (gspca_dev->usb_err < 0) | ||
1450 | return; | ||
1365 | PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", | 1451 | PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", |
1366 | value, buffer[0], buffer[1]); | 1452 | value, buffer[0], buffer[1]); |
1367 | #ifdef GSPCA_DEBUG | 1453 | #ifdef GSPCA_DEBUG |
@@ -1371,20 +1457,27 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
1371 | } | 1457 | } |
1372 | #endif | 1458 | #endif |
1373 | memcpy(gspca_dev->usb_buf, buffer, len); | 1459 | memcpy(gspca_dev->usb_buf, buffer, len); |
1374 | usb_control_msg(gspca_dev->dev, | 1460 | ret = usb_control_msg(gspca_dev->dev, |
1375 | usb_sndctrlpipe(gspca_dev->dev, 0), | 1461 | usb_sndctrlpipe(gspca_dev->dev, 0), |
1376 | 0x08, | 1462 | 0x08, |
1377 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 1463 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
1378 | value, 0, | 1464 | value, 0, |
1379 | gspca_dev->usb_buf, len, | 1465 | gspca_dev->usb_buf, len, |
1380 | 500); | 1466 | 500); |
1467 | if (ret < 0) { | ||
1468 | err("reg_w err %d", ret); | ||
1469 | gspca_dev->usb_err = ret; | ||
1470 | } | ||
1381 | } | 1471 | } |
1382 | 1472 | ||
1383 | /* I2C write 1 byte */ | 1473 | /* I2C write 1 byte */ |
1384 | static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | 1474 | static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) |
1385 | { | 1475 | { |
1386 | struct sd *sd = (struct sd *) gspca_dev; | 1476 | struct sd *sd = (struct sd *) gspca_dev; |
1477 | int ret; | ||
1387 | 1478 | ||
1479 | if (gspca_dev->usb_err < 0) | ||
1480 | return; | ||
1388 | PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val); | 1481 | PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val); |
1389 | switch (sd->sensor) { | 1482 | switch (sd->sensor) { |
1390 | case SENSOR_ADCM1700: | 1483 | case SENSOR_ADCM1700: |
@@ -1403,7 +1496,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
1403 | gspca_dev->usb_buf[5] = 0; | 1496 | gspca_dev->usb_buf[5] = 0; |
1404 | gspca_dev->usb_buf[6] = 0; | 1497 | gspca_dev->usb_buf[6] = 0; |
1405 | gspca_dev->usb_buf[7] = 0x10; | 1498 | gspca_dev->usb_buf[7] = 0x10; |
1406 | usb_control_msg(gspca_dev->dev, | 1499 | ret = usb_control_msg(gspca_dev->dev, |
1407 | usb_sndctrlpipe(gspca_dev->dev, 0), | 1500 | usb_sndctrlpipe(gspca_dev->dev, 0), |
1408 | 0x08, | 1501 | 0x08, |
1409 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 1502 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -1411,16 +1504,24 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
1411 | 0, | 1504 | 0, |
1412 | gspca_dev->usb_buf, 8, | 1505 | gspca_dev->usb_buf, 8, |
1413 | 500); | 1506 | 500); |
1507 | if (ret < 0) { | ||
1508 | err("i2c_w1 err %d", ret); | ||
1509 | gspca_dev->usb_err = ret; | ||
1510 | } | ||
1414 | } | 1511 | } |
1415 | 1512 | ||
1416 | /* I2C write 8 bytes */ | 1513 | /* I2C write 8 bytes */ |
1417 | static void i2c_w8(struct gspca_dev *gspca_dev, | 1514 | static void i2c_w8(struct gspca_dev *gspca_dev, |
1418 | const u8 *buffer) | 1515 | const u8 *buffer) |
1419 | { | 1516 | { |
1517 | int ret; | ||
1518 | |||
1519 | if (gspca_dev->usb_err < 0) | ||
1520 | return; | ||
1420 | PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..", | 1521 | PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..", |
1421 | buffer[2], buffer[3]); | 1522 | buffer[2], buffer[3]); |
1422 | memcpy(gspca_dev->usb_buf, buffer, 8); | 1523 | memcpy(gspca_dev->usb_buf, buffer, 8); |
1423 | usb_control_msg(gspca_dev->dev, | 1524 | ret = usb_control_msg(gspca_dev->dev, |
1424 | usb_sndctrlpipe(gspca_dev->dev, 0), | 1525 | usb_sndctrlpipe(gspca_dev->dev, 0), |
1425 | 0x08, | 1526 | 0x08, |
1426 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 1527 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -1428,6 +1529,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev, | |||
1428 | gspca_dev->usb_buf, 8, | 1529 | gspca_dev->usb_buf, 8, |
1429 | 500); | 1530 | 500); |
1430 | msleep(2); | 1531 | msleep(2); |
1532 | if (ret < 0) { | ||
1533 | err("i2c_w8 err %d", ret); | ||
1534 | gspca_dev->usb_err = ret; | ||
1535 | } | ||
1431 | } | 1536 | } |
1432 | 1537 | ||
1433 | /* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */ | 1538 | /* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */ |
@@ -1466,7 +1571,7 @@ static void i2c_w_seq(struct gspca_dev *gspca_dev, | |||
1466 | const u8 (*data)[8]) | 1571 | const u8 (*data)[8]) |
1467 | { | 1572 | { |
1468 | while ((*data)[0] != 0) { | 1573 | while ((*data)[0] != 0) { |
1469 | if ((*data)[0] != 0xdd) | 1574 | if ((*data)[0] != DELAY) |
1470 | i2c_w8(gspca_dev, *data); | 1575 | i2c_w8(gspca_dev, *data); |
1471 | else | 1576 | else |
1472 | msleep((*data)[1]); | 1577 | msleep((*data)[1]); |
@@ -1529,7 +1634,13 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) | |||
1529 | if (val != 0xffff) | 1634 | if (val != 0xffff) |
1530 | break; | 1635 | break; |
1531 | } | 1636 | } |
1637 | if (gspca_dev->usb_err < 0) | ||
1638 | return; | ||
1532 | switch (val) { | 1639 | switch (val) { |
1640 | case 0x8221: | ||
1641 | PDEBUG(D_PROBE, "Sensor mi0360b"); | ||
1642 | sd->sensor = SENSOR_MI0360B; | ||
1643 | break; | ||
1533 | case 0x823a: | 1644 | case 0x823a: |
1534 | PDEBUG(D_PROBE, "Sensor mt9v111"); | 1645 | PDEBUG(D_PROBE, "Sensor mt9v111"); |
1535 | sd->sensor = SENSOR_MT9V111; | 1646 | sd->sensor = SENSOR_MT9V111; |
@@ -1556,6 +1667,8 @@ static void ov7630_probe(struct gspca_dev *gspca_dev) | |||
1556 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | 1667 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; |
1557 | reg_w1(gspca_dev, 0x01, 0x29); | 1668 | reg_w1(gspca_dev, 0x01, 0x29); |
1558 | reg_w1(gspca_dev, 0x17, 0x42); | 1669 | reg_w1(gspca_dev, 0x17, 0x42); |
1670 | if (gspca_dev->usb_err < 0) | ||
1671 | return; | ||
1559 | if (val == 0x7628) { /* soi768 */ | 1672 | if (val == 0x7628) { /* soi768 */ |
1560 | sd->sensor = SENSOR_SOI768; | 1673 | sd->sensor = SENSOR_SOI768; |
1561 | /*fixme: only valid for 0c45:613e?*/ | 1674 | /*fixme: only valid for 0c45:613e?*/ |
@@ -1593,13 +1706,14 @@ static void ov7648_probe(struct gspca_dev *gspca_dev) | |||
1593 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | 1706 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; |
1594 | reg_w1(gspca_dev, 0x01, 0x29); | 1707 | reg_w1(gspca_dev, 0x01, 0x29); |
1595 | reg_w1(gspca_dev, 0x17, 0x42); | 1708 | reg_w1(gspca_dev, 0x17, 0x42); |
1709 | if (gspca_dev->usb_err < 0) | ||
1710 | return; | ||
1596 | if (val == 0x1030) { /* po1030 */ | 1711 | if (val == 0x1030) { /* po1030 */ |
1597 | PDEBUG(D_PROBE, "Sensor po1030"); | 1712 | PDEBUG(D_PROBE, "Sensor po1030"); |
1598 | sd->sensor = SENSOR_PO1030; | 1713 | sd->sensor = SENSOR_PO1030; |
1599 | return; | 1714 | return; |
1600 | } | 1715 | } |
1601 | 1716 | err("Unknown sensor %04x", val); | |
1602 | PDEBUG(D_PROBE, "Unknown sensor %04x", val); | ||
1603 | } | 1717 | } |
1604 | 1718 | ||
1605 | /* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */ | 1719 | /* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */ |
@@ -1631,11 +1745,13 @@ static void po2030n_probe(struct gspca_dev *gspca_dev) | |||
1631 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | 1745 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; |
1632 | reg_w1(gspca_dev, 0x01, 0x29); | 1746 | reg_w1(gspca_dev, 0x01, 0x29); |
1633 | reg_w1(gspca_dev, 0x17, 0x42); | 1747 | reg_w1(gspca_dev, 0x17, 0x42); |
1748 | if (gspca_dev->usb_err < 0) | ||
1749 | return; | ||
1634 | if (val == 0x2030) { | 1750 | if (val == 0x2030) { |
1635 | PDEBUG(D_PROBE, "Sensor po2030n"); | 1751 | PDEBUG(D_PROBE, "Sensor po2030n"); |
1636 | /* sd->sensor = SENSOR_PO2030N; */ | 1752 | /* sd->sensor = SENSOR_PO2030N; */ |
1637 | } else { | 1753 | } else { |
1638 | PDEBUG(D_PROBE, "Unknown sensor ID %04x", val); | 1754 | err("Unknown sensor ID %04x", val); |
1639 | } | 1755 | } |
1640 | } | 1756 | } |
1641 | 1757 | ||
@@ -1697,6 +1813,12 @@ static void bridge_init(struct gspca_dev *gspca_dev, | |||
1697 | reg_w1(gspca_dev, 0x01, 0x40); | 1813 | reg_w1(gspca_dev, 0x01, 0x40); |
1698 | msleep(50); | 1814 | msleep(50); |
1699 | break; | 1815 | break; |
1816 | case SENSOR_MI0360B: | ||
1817 | reg_w1(gspca_dev, 0x01, 0x61); | ||
1818 | reg_w1(gspca_dev, 0x17, 0x60); | ||
1819 | reg_w1(gspca_dev, 0x01, 0x60); | ||
1820 | reg_w1(gspca_dev, 0x01, 0x40); | ||
1821 | break; | ||
1700 | case SENSOR_MT9V111: | 1822 | case SENSOR_MT9V111: |
1701 | reg_w1(gspca_dev, 0x01, 0x61); | 1823 | reg_w1(gspca_dev, 0x01, 0x61); |
1702 | reg_w1(gspca_dev, 0x17, 0x61); | 1824 | reg_w1(gspca_dev, 0x17, 0x61); |
@@ -1762,8 +1884,7 @@ static void bridge_init(struct gspca_dev *gspca_dev, | |||
1762 | reg_w1(gspca_dev, 0x01, 0x43); | 1884 | reg_w1(gspca_dev, 0x01, 0x43); |
1763 | reg_w1(gspca_dev, 0x17, 0x61); | 1885 | reg_w1(gspca_dev, 0x17, 0x61); |
1764 | reg_w1(gspca_dev, 0x01, 0x42); | 1886 | reg_w1(gspca_dev, 0x01, 0x42); |
1765 | if (sd->sensor == SENSOR_HV7131R | 1887 | if (sd->sensor == SENSOR_HV7131R) |
1766 | && sd->bridge == BRIDGE_SN9C102P) | ||
1767 | hv7131r_probe(gspca_dev); | 1888 | hv7131r_probe(gspca_dev); |
1768 | break; | 1889 | break; |
1769 | } | 1890 | } |
@@ -1788,26 +1909,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1788 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1909 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1789 | } | 1910 | } |
1790 | cam->npkt = 24; /* 24 packets per ISOC message */ | 1911 | cam->npkt = 24; /* 24 packets per ISOC message */ |
1912 | cam->ctrls = sd->ctrls; | ||
1791 | 1913 | ||
1792 | sd->brightness = BRIGHTNESS_DEF; | ||
1793 | sd->contrast = CONTRAST_DEF; | ||
1794 | sd->colors = COLOR_DEF; | ||
1795 | sd->blue = BLUE_BALANCE_DEF; | ||
1796 | sd->red = RED_BALANCE_DEF; | ||
1797 | sd->gamma = GAMMA_DEF; | ||
1798 | sd->autogain = AUTOGAIN_DEF; | ||
1799 | sd->ag_cnt = -1; | 1914 | sd->ag_cnt = -1; |
1800 | sd->vflip = VFLIP_DEF; | ||
1801 | switch (sd->sensor) { | ||
1802 | case SENSOR_OM6802: | ||
1803 | sd->sharpness = 0x10; | ||
1804 | break; | ||
1805 | default: | ||
1806 | sd->sharpness = SHARPNESS_DEF; | ||
1807 | break; | ||
1808 | } | ||
1809 | sd->infrared = INFRARED_DEF; | ||
1810 | sd->freq = FREQ_DEF; | ||
1811 | sd->quality = QUALITY_DEF; | 1915 | sd->quality = QUALITY_DEF; |
1812 | sd->jpegqual = 80; | 1916 | sd->jpegqual = 80; |
1813 | 1917 | ||
@@ -1828,6 +1932,8 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1828 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | 1932 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); |
1829 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ | 1933 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ |
1830 | regF1 = gspca_dev->usb_buf[0]; | 1934 | regF1 = gspca_dev->usb_buf[0]; |
1935 | if (gspca_dev->usb_err < 0) | ||
1936 | return gspca_dev->usb_err; | ||
1831 | PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); | 1937 | PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); |
1832 | switch (sd->bridge) { | 1938 | switch (sd->bridge) { |
1833 | case BRIDGE_SN9C102P: | 1939 | case BRIDGE_SN9C102P: |
@@ -1871,6 +1977,9 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1871 | break; | 1977 | break; |
1872 | } | 1978 | } |
1873 | 1979 | ||
1980 | if (sd->sensor == SENSOR_OM6802) | ||
1981 | sd->ctrls[SHARPNESS].def = 0x10; | ||
1982 | |||
1874 | /* Note we do not disable the sensor clock here (power saving mode), | 1983 | /* Note we do not disable the sensor clock here (power saving mode), |
1875 | as that also disables the button on the cam. */ | 1984 | as that also disables the button on the cam. */ |
1876 | reg_w1(gspca_dev, 0xf1, 0x00); | 1985 | reg_w1(gspca_dev, 0xf1, 0x00); |
@@ -1881,7 +1990,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1881 | 1990 | ||
1882 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | 1991 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; |
1883 | 1992 | ||
1884 | return 0; | 1993 | return gspca_dev->usb_err; |
1885 | } | 1994 | } |
1886 | 1995 | ||
1887 | static u32 setexposure(struct gspca_dev *gspca_dev, | 1996 | static u32 setexposure(struct gspca_dev *gspca_dev, |
@@ -1912,7 +2021,8 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | |||
1912 | i2c_w8(gspca_dev, Expodoit); | 2021 | i2c_w8(gspca_dev, Expodoit); |
1913 | break; | 2022 | break; |
1914 | } | 2023 | } |
1915 | case SENSOR_MI0360: { | 2024 | case SENSOR_MI0360: |
2025 | case SENSOR_MI0360B: { | ||
1916 | u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ | 2026 | u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ |
1917 | { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 }; | 2027 | { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 }; |
1918 | static const u8 doit[] = /* update sensor */ | 2028 | static const u8 doit[] = /* update sensor */ |
@@ -1991,16 +2101,18 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1991 | { | 2101 | { |
1992 | struct sd *sd = (struct sd *) gspca_dev; | 2102 | struct sd *sd = (struct sd *) gspca_dev; |
1993 | unsigned int expo; | 2103 | unsigned int expo; |
2104 | int brightness; | ||
1994 | u8 k2; | 2105 | u8 k2; |
1995 | 2106 | ||
1996 | k2 = ((int) sd->brightness - 0x8000) >> 10; | 2107 | brightness = sd->ctrls[BRIGHTNESS].val; |
2108 | k2 = (brightness - 0x80) >> 2; | ||
1997 | switch (sd->sensor) { | 2109 | switch (sd->sensor) { |
1998 | case SENSOR_ADCM1700: | 2110 | case SENSOR_ADCM1700: |
1999 | if (k2 > 0x1f) | 2111 | if (k2 > 0x1f) |
2000 | k2 = 0; /* only positive Y offset */ | 2112 | k2 = 0; /* only positive Y offset */ |
2001 | break; | 2113 | break; |
2002 | case SENSOR_HV7131R: | 2114 | case SENSOR_HV7131R: |
2003 | expo = sd->brightness << 4; | 2115 | expo = brightness << 12; |
2004 | if (expo > 0x002dc6c0) | 2116 | if (expo > 0x002dc6c0) |
2005 | expo = 0x002dc6c0; | 2117 | expo = 0x002dc6c0; |
2006 | else if (expo < 0x02a0) | 2118 | else if (expo < 0x02a0) |
@@ -2009,18 +2121,22 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
2009 | break; | 2121 | break; |
2010 | case SENSOR_MI0360: | 2122 | case SENSOR_MI0360: |
2011 | case SENSOR_MO4000: | 2123 | case SENSOR_MO4000: |
2012 | expo = sd->brightness >> 4; | 2124 | expo = brightness << 4; |
2125 | sd->exposure = setexposure(gspca_dev, expo); | ||
2126 | break; | ||
2127 | case SENSOR_MI0360B: | ||
2128 | expo = brightness << 2; | ||
2013 | sd->exposure = setexposure(gspca_dev, expo); | 2129 | sd->exposure = setexposure(gspca_dev, expo); |
2014 | break; | 2130 | break; |
2015 | case SENSOR_GC0307: | 2131 | case SENSOR_GC0307: |
2016 | case SENSOR_MT9V111: | 2132 | case SENSOR_MT9V111: |
2017 | expo = sd->brightness >> 8; | 2133 | expo = brightness; |
2018 | sd->exposure = setexposure(gspca_dev, expo); | 2134 | sd->exposure = setexposure(gspca_dev, expo); |
2019 | return; /* don't set the Y offset */ | 2135 | return; /* don't set the Y offset */ |
2020 | case SENSOR_OM6802: | 2136 | case SENSOR_OM6802: |
2021 | expo = sd->brightness >> 6; | 2137 | expo = brightness << 2; |
2022 | sd->exposure = setexposure(gspca_dev, expo); | 2138 | sd->exposure = setexposure(gspca_dev, expo); |
2023 | k2 = sd->brightness >> 11; | 2139 | k2 = brightness >> 3; |
2024 | break; | 2140 | break; |
2025 | } | 2141 | } |
2026 | 2142 | ||
@@ -2033,7 +2149,8 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
2033 | u8 k2; | 2149 | u8 k2; |
2034 | u8 contrast[6]; | 2150 | u8 contrast[6]; |
2035 | 2151 | ||
2036 | k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */ | 2152 | k2 = sd->ctrls[CONTRAST].val * 0x30 / (CONTRAST_MAX + 1) |
2153 | + 0x10; /* 10..40 */ | ||
2037 | contrast[0] = (k2 + 1) / 2; /* red */ | 2154 | contrast[0] = (k2 + 1) / 2; /* red */ |
2038 | contrast[1] = 0; | 2155 | contrast[1] = 0; |
2039 | contrast[2] = k2; /* green */ | 2156 | contrast[2] = k2; /* green */ |
@@ -2046,15 +2163,25 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
2046 | static void setcolors(struct gspca_dev *gspca_dev) | 2163 | static void setcolors(struct gspca_dev *gspca_dev) |
2047 | { | 2164 | { |
2048 | struct sd *sd = (struct sd *) gspca_dev; | 2165 | struct sd *sd = (struct sd *) gspca_dev; |
2049 | int i, v; | 2166 | int i, v, colors; |
2167 | const s16 *uv; | ||
2050 | u8 reg8a[12]; /* U & V gains */ | 2168 | u8 reg8a[12]; /* U & V gains */ |
2051 | static const s16 uv[6] = { /* same as reg84 in signed decimal */ | 2169 | static const s16 uv_com[6] = { /* same as reg84 in signed decimal */ |
2052 | -24, -38, 64, /* UR UG UB */ | 2170 | -24, -38, 64, /* UR UG UB */ |
2053 | 62, -51, -9 /* VR VG VB */ | 2171 | 62, -51, -9 /* VR VG VB */ |
2054 | }; | 2172 | }; |
2173 | static const s16 uv_mi0360b[6] = { | ||
2174 | -20, -38, 64, /* UR UG UB */ | ||
2175 | 60, -51, -9 /* VR VG VB */ | ||
2176 | }; | ||
2055 | 2177 | ||
2178 | colors = sd->ctrls[COLORS].val; | ||
2179 | if (sd->sensor == SENSOR_MI0360B) | ||
2180 | uv = uv_mi0360b; | ||
2181 | else | ||
2182 | uv = uv_com; | ||
2056 | for (i = 0; i < 6; i++) { | 2183 | for (i = 0; i < 6; i++) { |
2057 | v = uv[i] * sd->colors / COLOR_DEF; | 2184 | v = uv[i] * colors / COLORS_DEF; |
2058 | reg8a[i * 2] = v; | 2185 | reg8a[i * 2] = v; |
2059 | reg8a[i * 2 + 1] = (v >> 8) & 0x0f; | 2186 | reg8a[i * 2 + 1] = (v >> 8) & 0x0f; |
2060 | } | 2187 | } |
@@ -2065,15 +2192,15 @@ static void setredblue(struct gspca_dev *gspca_dev) | |||
2065 | { | 2192 | { |
2066 | struct sd *sd = (struct sd *) gspca_dev; | 2193 | struct sd *sd = (struct sd *) gspca_dev; |
2067 | 2194 | ||
2068 | reg_w1(gspca_dev, 0x05, sd->red); | 2195 | reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); |
2069 | /* reg_w1(gspca_dev, 0x07, 32); */ | 2196 | /* reg_w1(gspca_dev, 0x07, 32); */ |
2070 | reg_w1(gspca_dev, 0x06, sd->blue); | 2197 | reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); |
2071 | } | 2198 | } |
2072 | 2199 | ||
2073 | static void setgamma(struct gspca_dev *gspca_dev) | 2200 | static void setgamma(struct gspca_dev *gspca_dev) |
2074 | { | 2201 | { |
2075 | struct sd *sd = (struct sd *) gspca_dev; | 2202 | struct sd *sd = (struct sd *) gspca_dev; |
2076 | int i; | 2203 | int i, val; |
2077 | u8 gamma[17]; | 2204 | u8 gamma[17]; |
2078 | const u8 *gamma_base; | 2205 | const u8 *gamma_base; |
2079 | static const u8 delta[17] = { | 2206 | static const u8 delta[17] = { |
@@ -2086,6 +2213,7 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
2086 | gamma_base = gamma_spec_0; | 2213 | gamma_base = gamma_spec_0; |
2087 | break; | 2214 | break; |
2088 | case SENSOR_HV7131R: | 2215 | case SENSOR_HV7131R: |
2216 | case SENSOR_MI0360B: | ||
2089 | case SENSOR_MT9V111: | 2217 | case SENSOR_MT9V111: |
2090 | gamma_base = gamma_spec_1; | 2218 | gamma_base = gamma_spec_1; |
2091 | break; | 2219 | break; |
@@ -2100,9 +2228,10 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
2100 | break; | 2228 | break; |
2101 | } | 2229 | } |
2102 | 2230 | ||
2231 | val = sd->ctrls[GAMMA].val; | ||
2103 | for (i = 0; i < sizeof gamma; i++) | 2232 | for (i = 0; i < sizeof gamma; i++) |
2104 | gamma[i] = gamma_base[i] | 2233 | gamma[i] = gamma_base[i] |
2105 | + delta[i] * (sd->gamma - GAMMA_DEF) / 32; | 2234 | + delta[i] * (val - GAMMA_DEF) / 32; |
2106 | reg_w(gspca_dev, 0x20, gamma, sizeof gamma); | 2235 | reg_w(gspca_dev, 0x20, gamma, sizeof gamma); |
2107 | } | 2236 | } |
2108 | 2237 | ||
@@ -2110,7 +2239,7 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
2110 | { | 2239 | { |
2111 | struct sd *sd = (struct sd *) gspca_dev; | 2240 | struct sd *sd = (struct sd *) gspca_dev; |
2112 | 2241 | ||
2113 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) | 2242 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) |
2114 | return; | 2243 | return; |
2115 | switch (sd->sensor) { | 2244 | switch (sd->sensor) { |
2116 | case SENSOR_OV7630: | 2245 | case SENSOR_OV7630: |
@@ -2121,74 +2250,91 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
2121 | comb = 0xc0; | 2250 | comb = 0xc0; |
2122 | else | 2251 | else |
2123 | comb = 0xa0; | 2252 | comb = 0xa0; |
2124 | if (sd->autogain) | 2253 | if (sd->ctrls[AUTOGAIN].val) |
2125 | comb |= 0x03; | 2254 | comb |= 0x03; |
2126 | i2c_w1(&sd->gspca_dev, 0x13, comb); | 2255 | i2c_w1(&sd->gspca_dev, 0x13, comb); |
2127 | return; | 2256 | return; |
2128 | } | 2257 | } |
2129 | } | 2258 | } |
2130 | if (sd->autogain) | 2259 | if (sd->ctrls[AUTOGAIN].val) |
2131 | sd->ag_cnt = AG_CNT_START; | 2260 | sd->ag_cnt = AG_CNT_START; |
2132 | else | 2261 | else |
2133 | sd->ag_cnt = -1; | 2262 | sd->ag_cnt = -1; |
2134 | } | 2263 | } |
2135 | 2264 | ||
2136 | /* hv7131r/ov7630/ov7648 only */ | 2265 | static void sethvflip(struct gspca_dev *gspca_dev) |
2137 | static void setvflip(struct sd *sd) | ||
2138 | { | 2266 | { |
2267 | struct sd *sd = (struct sd *) gspca_dev; | ||
2139 | u8 comn; | 2268 | u8 comn; |
2140 | 2269 | ||
2141 | if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX)) | ||
2142 | return; | ||
2143 | switch (sd->sensor) { | 2270 | switch (sd->sensor) { |
2144 | case SENSOR_HV7131R: | 2271 | case SENSOR_HV7131R: |
2145 | comn = 0x18; /* clkdiv = 1, ablcen = 1 */ | 2272 | comn = 0x18; /* clkdiv = 1, ablcen = 1 */ |
2146 | if (sd->vflip) | 2273 | if (sd->ctrls[VFLIP].val) |
2147 | comn |= 0x01; | 2274 | comn |= 0x01; |
2148 | i2c_w1(&sd->gspca_dev, 0x01, comn); /* sctra */ | 2275 | i2c_w1(gspca_dev, 0x01, comn); /* sctra */ |
2149 | break; | 2276 | break; |
2150 | case SENSOR_OV7630: | 2277 | case SENSOR_OV7630: |
2151 | comn = 0x02; | 2278 | comn = 0x02; |
2152 | if (!sd->vflip) | 2279 | if (!sd->ctrls[VFLIP].val) |
2153 | comn |= 0x80; | 2280 | comn |= 0x80; |
2154 | i2c_w1(&sd->gspca_dev, 0x75, comn); | 2281 | i2c_w1(gspca_dev, 0x75, comn); |
2155 | break; | 2282 | break; |
2156 | default: | 2283 | case SENSOR_OV7648: |
2157 | /* case SENSOR_OV7648: */ | ||
2158 | comn = 0x06; | 2284 | comn = 0x06; |
2159 | if (sd->vflip) | 2285 | if (sd->ctrls[VFLIP].val) |
2286 | comn |= 0x80; | ||
2287 | i2c_w1(gspca_dev, 0x75, comn); | ||
2288 | break; | ||
2289 | case SENSOR_PO2030N: | ||
2290 | /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2) | ||
2291 | * (reset value: 0x0A) | ||
2292 | * bit7: HM: Horizontal Mirror: 0: disable, 1: enable | ||
2293 | * bit6: VM: Vertical Mirror: 0: disable, 1: enable | ||
2294 | * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical | ||
2295 | * bit4: FT: Single Frame Transfer: 0: disable, 1: enable | ||
2296 | * bit3-0: X | ||
2297 | */ | ||
2298 | comn = 0x0a; | ||
2299 | if (sd->ctrls[HFLIP].val) | ||
2160 | comn |= 0x80; | 2300 | comn |= 0x80; |
2161 | i2c_w1(&sd->gspca_dev, 0x75, comn); | 2301 | if (sd->ctrls[VFLIP].val) |
2302 | comn |= 0x40; | ||
2303 | i2c_w1(&sd->gspca_dev, 0x1e, comn); | ||
2162 | break; | 2304 | break; |
2163 | } | 2305 | } |
2164 | } | 2306 | } |
2165 | 2307 | ||
2166 | static void setsharpness(struct sd *sd) | 2308 | static void setsharpness(struct gspca_dev *gspca_dev) |
2167 | { | 2309 | { |
2168 | reg_w1(&sd->gspca_dev, 0x99, sd->sharpness); | 2310 | struct sd *sd = (struct sd *) gspca_dev; |
2311 | |||
2312 | reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); | ||
2169 | } | 2313 | } |
2170 | 2314 | ||
2171 | static void setinfrared(struct sd *sd) | 2315 | static void setinfrared(struct gspca_dev *gspca_dev) |
2172 | { | 2316 | { |
2173 | if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX)) | 2317 | struct sd *sd = (struct sd *) gspca_dev; |
2318 | |||
2319 | if (gspca_dev->ctrl_dis & (1 << INFRARED)) | ||
2174 | return; | 2320 | return; |
2175 | /*fixme: different sequence for StarCam Clip and StarCam 370i */ | 2321 | /*fixme: different sequence for StarCam Clip and StarCam 370i */ |
2176 | /* Clip */ | 2322 | /* Clip */ |
2177 | i2c_w1(&sd->gspca_dev, 0x02, /* gpio */ | 2323 | i2c_w1(gspca_dev, 0x02, /* gpio */ |
2178 | sd->infrared ? 0x66 : 0x64); | 2324 | sd->ctrls[INFRARED].val ? 0x66 : 0x64); |
2179 | } | 2325 | } |
2180 | 2326 | ||
2181 | static void setfreq(struct gspca_dev *gspca_dev) | 2327 | static void setfreq(struct gspca_dev *gspca_dev) |
2182 | { | 2328 | { |
2183 | struct sd *sd = (struct sd *) gspca_dev; | 2329 | struct sd *sd = (struct sd *) gspca_dev; |
2184 | 2330 | ||
2185 | if (gspca_dev->ctrl_dis & (1 << FREQ_IDX)) | 2331 | if (gspca_dev->ctrl_dis & (1 << FREQ)) |
2186 | return; | 2332 | return; |
2187 | if (sd->sensor == SENSOR_OV7660) { | 2333 | if (sd->sensor == SENSOR_OV7660) { |
2188 | u8 com8; | 2334 | u8 com8; |
2189 | 2335 | ||
2190 | com8 = 0xdf; /* auto gain/wb/expo */ | 2336 | com8 = 0xdf; /* auto gain/wb/expo */ |
2191 | switch (sd->freq) { | 2337 | switch (sd->ctrls[FREQ].val) { |
2192 | case 0: /* Banding filter disabled */ | 2338 | case 0: /* Banding filter disabled */ |
2193 | i2c_w1(gspca_dev, 0x13, com8 | 0x20); | 2339 | i2c_w1(gspca_dev, 0x13, com8 | 0x20); |
2194 | break; | 2340 | break; |
@@ -2216,7 +2362,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
2216 | break; | 2362 | break; |
2217 | } | 2363 | } |
2218 | 2364 | ||
2219 | switch (sd->freq) { | 2365 | switch (sd->ctrls[FREQ].val) { |
2220 | case 0: /* Banding filter disabled */ | 2366 | case 0: /* Banding filter disabled */ |
2221 | break; | 2367 | break; |
2222 | case 1: /* 50 hz (filter on and framerate adj) */ | 2368 | case 1: /* 50 hz (filter on and framerate adj) */ |
@@ -2334,6 +2480,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2334 | reg17 = 0xa2; | 2480 | reg17 = 0xa2; |
2335 | break; | 2481 | break; |
2336 | case SENSOR_MT9V111: | 2482 | case SENSOR_MT9V111: |
2483 | case SENSOR_MI0360B: | ||
2337 | reg17 = 0xe0; | 2484 | reg17 = 0xe0; |
2338 | break; | 2485 | break; |
2339 | case SENSOR_ADCM1700: | 2486 | case SENSOR_ADCM1700: |
@@ -2375,6 +2522,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2375 | break; | 2522 | break; |
2376 | case SENSOR_GC0307: | 2523 | case SENSOR_GC0307: |
2377 | case SENSOR_MT9V111: | 2524 | case SENSOR_MT9V111: |
2525 | case SENSOR_MI0360B: | ||
2378 | reg_w1(gspca_dev, 0x9a, 0x07); | 2526 | reg_w1(gspca_dev, 0x9a, 0x07); |
2379 | break; | 2527 | break; |
2380 | case SENSOR_OV7630: | 2528 | case SENSOR_OV7630: |
@@ -2389,7 +2537,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2389 | reg_w1(gspca_dev, 0x9a, 0x08); | 2537 | reg_w1(gspca_dev, 0x9a, 0x08); |
2390 | break; | 2538 | break; |
2391 | } | 2539 | } |
2392 | setsharpness(sd); | 2540 | setsharpness(gspca_dev); |
2393 | 2541 | ||
2394 | reg_w(gspca_dev, 0x84, reg84, sizeof reg84); | 2542 | reg_w(gspca_dev, 0x84, reg84, sizeof reg84); |
2395 | reg_w1(gspca_dev, 0x05, 0x20); /* red */ | 2543 | reg_w1(gspca_dev, 0x05, 0x20); /* red */ |
@@ -2414,6 +2562,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2414 | reg17 = 0xa2; | 2562 | reg17 = 0xa2; |
2415 | reg1 = 0x44; | 2563 | reg1 = 0x44; |
2416 | break; | 2564 | break; |
2565 | case SENSOR_MI0360B: | ||
2566 | init = mi0360b_sensor_param1; | ||
2567 | reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */ | ||
2568 | reg17 = 0xe2; | ||
2569 | break; | ||
2417 | case SENSOR_MO4000: | 2570 | case SENSOR_MO4000: |
2418 | if (mode) { | 2571 | if (mode) { |
2419 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ | 2572 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ |
@@ -2474,8 +2627,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2474 | reg1 = 0x44; | 2627 | reg1 = 0x44; |
2475 | reg17 = 0xa2; | 2628 | reg17 = 0xa2; |
2476 | break; | 2629 | break; |
2477 | default: | 2630 | case SENSOR_SP80708: |
2478 | /* case SENSOR_SP80708: */ | ||
2479 | init = sp80708_sensor_param1; | 2631 | init = sp80708_sensor_param1; |
2480 | if (mode) { | 2632 | if (mode) { |
2481 | /*?? reg1 = 0x04; * 320 clk 48Mhz */ | 2633 | /*?? reg1 = 0x04; * 320 clk 48Mhz */ |
@@ -2526,7 +2678,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2526 | break; | 2678 | break; |
2527 | } | 2679 | } |
2528 | 2680 | ||
2529 | |||
2530 | /* here change size mode 0 -> VGA; 1 -> CIF */ | 2681 | /* here change size mode 0 -> VGA; 1 -> CIF */ |
2531 | sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; | 2682 | sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; |
2532 | reg_w1(gspca_dev, 0x18, sd->reg18); | 2683 | reg_w1(gspca_dev, 0x18, sd->reg18); |
@@ -2535,13 +2686,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2535 | reg_w1(gspca_dev, 0x17, reg17); | 2686 | reg_w1(gspca_dev, 0x17, reg17); |
2536 | reg_w1(gspca_dev, 0x01, reg1); | 2687 | reg_w1(gspca_dev, 0x01, reg1); |
2537 | 2688 | ||
2538 | setvflip(sd); | 2689 | sethvflip(gspca_dev); |
2539 | setbrightness(gspca_dev); | 2690 | setbrightness(gspca_dev); |
2540 | setcontrast(gspca_dev); | 2691 | setcontrast(gspca_dev); |
2541 | setcolors(gspca_dev); | 2692 | setcolors(gspca_dev); |
2542 | setautogain(gspca_dev); | 2693 | setautogain(gspca_dev); |
2543 | setfreq(gspca_dev); | 2694 | setfreq(gspca_dev); |
2544 | return 0; | 2695 | return gspca_dev->usb_err; |
2545 | } | 2696 | } |
2546 | 2697 | ||
2547 | static void sd_stopN(struct gspca_dev *gspca_dev) | 2698 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -2568,6 +2719,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
2568 | data = 0x2b; | 2719 | data = 0x2b; |
2569 | break; | 2720 | break; |
2570 | case SENSOR_MI0360: | 2721 | case SENSOR_MI0360: |
2722 | case SENSOR_MI0360B: | ||
2571 | i2c_w8(gspca_dev, stopmi0360); | 2723 | i2c_w8(gspca_dev, stopmi0360); |
2572 | data = 0x29; | 2724 | data = 0x29; |
2573 | break; | 2725 | break; |
@@ -2641,6 +2793,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2641 | default: | 2793 | default: |
2642 | /* case SENSOR_MO4000: */ | 2794 | /* case SENSOR_MO4000: */ |
2643 | /* case SENSOR_MI0360: */ | 2795 | /* case SENSOR_MI0360: */ |
2796 | /* case SENSOR_MI0360B: */ | ||
2644 | /* case SENSOR_MT9V111: */ | 2797 | /* case SENSOR_MT9V111: */ |
2645 | expotimes = sd->exposure; | 2798 | expotimes = sd->exposure; |
2646 | expotimes += (luma_mean - delta) >> 6; | 2799 | expotimes += (luma_mean - delta) >> 6; |
@@ -2663,236 +2816,52 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
2663 | struct sd *sd = (struct sd *) gspca_dev; | 2816 | struct sd *sd = (struct sd *) gspca_dev; |
2664 | int sof, avg_lum; | 2817 | int sof, avg_lum; |
2665 | 2818 | ||
2666 | sof = len - 64; | 2819 | /* the image ends on a 64 bytes block starting with |
2667 | if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) { | 2820 | * ff d9 ff ff 00 c4 c4 96 |
2821 | * and followed by various information including luminosity */ | ||
2822 | /* this block may be splitted between two packets */ | ||
2823 | /* a new image always starts in a new packet */ | ||
2824 | switch (gspca_dev->last_packet_type) { | ||
2825 | case DISCARD_PACKET: /* restart image building */ | ||
2826 | sof = len - 64; | ||
2827 | if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) | ||
2828 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | ||
2829 | return; | ||
2830 | case LAST_PACKET: /* put the JPEG 422 header */ | ||
2831 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
2832 | sd->jpeg_hdr, JPEG_HDR_SZ); | ||
2833 | break; | ||
2834 | } | ||
2835 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | ||
2836 | |||
2837 | data = gspca_dev->image; | ||
2838 | if (data == NULL) | ||
2839 | return; | ||
2840 | sof = gspca_dev->image_len - 64; | ||
2841 | if (data[sof] != 0xff | ||
2842 | || data[sof + 1] != 0xd9) | ||
2843 | return; | ||
2668 | 2844 | ||
2669 | /* end of frame */ | 2845 | /* end of image found - remove the trailing data */ |
2670 | gspca_frame_add(gspca_dev, LAST_PACKET, | 2846 | gspca_dev->image_len = sof + 2; |
2671 | data, sof + 2); | 2847 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
2672 | if (sd->ag_cnt < 0) | 2848 | if (sd->ag_cnt < 0) |
2673 | return; | 2849 | return; |
2674 | /* w1 w2 w3 */ | 2850 | /* w1 w2 w3 */ |
2675 | /* w4 w5 w6 */ | 2851 | /* w4 w5 w6 */ |
2676 | /* w7 w8 */ | 2852 | /* w7 w8 */ |
2677 | /* w4 */ | 2853 | /* w4 */ |
2678 | avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6; | 2854 | avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6; |
2679 | /* w6 */ | 2855 | /* w6 */ |
2680 | avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6; | 2856 | avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6; |
2681 | /* w2 */ | 2857 | /* w2 */ |
2682 | avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6; | 2858 | avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6; |
2683 | /* w8 */ | 2859 | /* w8 */ |
2684 | avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6; | 2860 | avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6; |
2685 | /* w5 */ | 2861 | /* w5 */ |
2686 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | 2862 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; |
2687 | avg_lum >>= 4; | 2863 | avg_lum >>= 4; |
2688 | atomic_set(&sd->avg_lum, avg_lum); | 2864 | atomic_set(&sd->avg_lum, avg_lum); |
2689 | return; | ||
2690 | } | ||
2691 | if (gspca_dev->last_packet_type == LAST_PACKET) { | ||
2692 | |||
2693 | /* put the JPEG 422 header */ | ||
2694 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
2695 | sd->jpeg_hdr, JPEG_HDR_SZ); | ||
2696 | } | ||
2697 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | ||
2698 | } | ||
2699 | |||
2700 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
2701 | { | ||
2702 | struct sd *sd = (struct sd *) gspca_dev; | ||
2703 | |||
2704 | sd->brightness = val; | ||
2705 | if (gspca_dev->streaming) | ||
2706 | setbrightness(gspca_dev); | ||
2707 | return 0; | ||
2708 | } | ||
2709 | |||
2710 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2711 | { | ||
2712 | struct sd *sd = (struct sd *) gspca_dev; | ||
2713 | |||
2714 | *val = sd->brightness; | ||
2715 | return 0; | ||
2716 | } | ||
2717 | |||
2718 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2719 | { | ||
2720 | struct sd *sd = (struct sd *) gspca_dev; | ||
2721 | |||
2722 | sd->contrast = val; | ||
2723 | if (gspca_dev->streaming) | ||
2724 | setcontrast(gspca_dev); | ||
2725 | return 0; | ||
2726 | } | ||
2727 | |||
2728 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2729 | { | ||
2730 | struct sd *sd = (struct sd *) gspca_dev; | ||
2731 | |||
2732 | *val = sd->contrast; | ||
2733 | return 0; | ||
2734 | } | ||
2735 | |||
2736 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
2737 | { | ||
2738 | struct sd *sd = (struct sd *) gspca_dev; | ||
2739 | |||
2740 | sd->colors = val; | ||
2741 | if (gspca_dev->streaming) | ||
2742 | setcolors(gspca_dev); | ||
2743 | return 0; | ||
2744 | } | ||
2745 | |||
2746 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
2747 | { | ||
2748 | struct sd *sd = (struct sd *) gspca_dev; | ||
2749 | |||
2750 | *val = sd->colors; | ||
2751 | return 0; | ||
2752 | } | ||
2753 | |||
2754 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
2755 | { | ||
2756 | struct sd *sd = (struct sd *) gspca_dev; | ||
2757 | |||
2758 | sd->blue = val; | ||
2759 | if (gspca_dev->streaming) | ||
2760 | setredblue(gspca_dev); | ||
2761 | return 0; | ||
2762 | } | ||
2763 | |||
2764 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
2765 | { | ||
2766 | struct sd *sd = (struct sd *) gspca_dev; | ||
2767 | |||
2768 | *val = sd->blue; | ||
2769 | return 0; | ||
2770 | } | ||
2771 | |||
2772 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
2773 | { | ||
2774 | struct sd *sd = (struct sd *) gspca_dev; | ||
2775 | |||
2776 | sd->red = val; | ||
2777 | if (gspca_dev->streaming) | ||
2778 | setredblue(gspca_dev); | ||
2779 | return 0; | ||
2780 | } | ||
2781 | |||
2782 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
2783 | { | ||
2784 | struct sd *sd = (struct sd *) gspca_dev; | ||
2785 | |||
2786 | *val = sd->red; | ||
2787 | return 0; | ||
2788 | } | ||
2789 | |||
2790 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
2791 | { | ||
2792 | struct sd *sd = (struct sd *) gspca_dev; | ||
2793 | |||
2794 | sd->gamma = val; | ||
2795 | if (gspca_dev->streaming) | ||
2796 | setgamma(gspca_dev); | ||
2797 | return 0; | ||
2798 | } | ||
2799 | |||
2800 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
2801 | { | ||
2802 | struct sd *sd = (struct sd *) gspca_dev; | ||
2803 | |||
2804 | *val = sd->gamma; | ||
2805 | return 0; | ||
2806 | } | ||
2807 | |||
2808 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
2809 | { | ||
2810 | struct sd *sd = (struct sd *) gspca_dev; | ||
2811 | |||
2812 | sd->autogain = val; | ||
2813 | if (gspca_dev->streaming) | ||
2814 | setautogain(gspca_dev); | ||
2815 | return 0; | ||
2816 | } | ||
2817 | |||
2818 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
2819 | { | ||
2820 | struct sd *sd = (struct sd *) gspca_dev; | ||
2821 | |||
2822 | *val = sd->autogain; | ||
2823 | return 0; | ||
2824 | } | ||
2825 | |||
2826 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
2827 | { | ||
2828 | struct sd *sd = (struct sd *) gspca_dev; | ||
2829 | |||
2830 | sd->sharpness = val; | ||
2831 | if (gspca_dev->streaming) | ||
2832 | setsharpness(sd); | ||
2833 | return 0; | ||
2834 | } | ||
2835 | |||
2836 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2837 | { | ||
2838 | struct sd *sd = (struct sd *) gspca_dev; | ||
2839 | |||
2840 | *val = sd->sharpness; | ||
2841 | return 0; | ||
2842 | } | ||
2843 | |||
2844 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2845 | { | ||
2846 | struct sd *sd = (struct sd *) gspca_dev; | ||
2847 | |||
2848 | sd->vflip = val; | ||
2849 | if (gspca_dev->streaming) | ||
2850 | setvflip(sd); | ||
2851 | return 0; | ||
2852 | } | ||
2853 | |||
2854 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2855 | { | ||
2856 | struct sd *sd = (struct sd *) gspca_dev; | ||
2857 | |||
2858 | *val = sd->vflip; | ||
2859 | return 0; | ||
2860 | } | ||
2861 | |||
2862 | static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val) | ||
2863 | { | ||
2864 | struct sd *sd = (struct sd *) gspca_dev; | ||
2865 | |||
2866 | sd->infrared = val; | ||
2867 | if (gspca_dev->streaming) | ||
2868 | setinfrared(sd); | ||
2869 | return 0; | ||
2870 | } | ||
2871 | |||
2872 | static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val) | ||
2873 | { | ||
2874 | struct sd *sd = (struct sd *) gspca_dev; | ||
2875 | |||
2876 | *val = sd->infrared; | ||
2877 | return 0; | ||
2878 | } | ||
2879 | |||
2880 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
2881 | { | ||
2882 | struct sd *sd = (struct sd *) gspca_dev; | ||
2883 | |||
2884 | sd->freq = val; | ||
2885 | if (gspca_dev->streaming) | ||
2886 | setfreq(gspca_dev); | ||
2887 | return 0; | ||
2888 | } | ||
2889 | |||
2890 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
2891 | { | ||
2892 | struct sd *sd = (struct sd *) gspca_dev; | ||
2893 | |||
2894 | *val = sd->freq; | ||
2895 | return 0; | ||
2896 | } | 2865 | } |
2897 | 2866 | ||
2898 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 2867 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, |
@@ -2944,7 +2913,7 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, | |||
2944 | return -EINVAL; | 2913 | return -EINVAL; |
2945 | } | 2914 | } |
2946 | 2915 | ||
2947 | #ifdef CONFIG_INPUT | 2916 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2948 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 2917 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
2949 | u8 *data, /* interrupt packet data */ | 2918 | u8 *data, /* interrupt packet data */ |
2950 | int len) /* interrupt packet length */ | 2919 | int len) /* interrupt packet length */ |
@@ -2967,7 +2936,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | |||
2967 | static const struct sd_desc sd_desc = { | 2936 | static const struct sd_desc sd_desc = { |
2968 | .name = MODULE_NAME, | 2937 | .name = MODULE_NAME, |
2969 | .ctrls = sd_ctrls, | 2938 | .ctrls = sd_ctrls, |
2970 | .nctrls = ARRAY_SIZE(sd_ctrls), | 2939 | .nctrls = NCTRLS, |
2971 | .config = sd_config, | 2940 | .config = sd_config, |
2972 | .init = sd_init, | 2941 | .init = sd_init, |
2973 | .start = sd_start, | 2942 | .start = sd_start, |
@@ -2977,7 +2946,7 @@ static const struct sd_desc sd_desc = { | |||
2977 | .get_jcomp = sd_get_jcomp, | 2946 | .get_jcomp = sd_get_jcomp, |
2978 | .set_jcomp = sd_set_jcomp, | 2947 | .set_jcomp = sd_set_jcomp, |
2979 | .querymenu = sd_querymenu, | 2948 | .querymenu = sd_querymenu, |
2980 | #ifdef CONFIG_INPUT | 2949 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2981 | .int_pkt_scan = sd_int_pkt_scan, | 2950 | .int_pkt_scan = sd_int_pkt_scan, |
2982 | #endif | 2951 | #endif |
2983 | }; | 2952 | }; |
@@ -3005,6 +2974,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
3005 | {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)}, | 2974 | {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)}, |
3006 | /* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */ | 2975 | /* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */ |
3007 | {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)}, | 2976 | {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)}, |
2977 | /* or MT9V111 */ | ||
3008 | /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ | 2978 | /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ |
3009 | /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ | 2979 | /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ |
3010 | /* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ | 2980 | /* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ |
@@ -3019,7 +2989,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
3019 | {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, | 2989 | {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, |
3020 | #endif | 2990 | #endif |
3021 | {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ | 2991 | {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ |
3022 | /* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/ | 2992 | {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/ |
3023 | /* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ | 2993 | /* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ |
3024 | {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ | 2994 | {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ |
3025 | {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ | 2995 | {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ |
@@ -3031,12 +3001,12 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
3031 | {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/ | 3001 | {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/ |
3032 | /*bw600.inf:*/ | 3002 | /*bw600.inf:*/ |
3033 | {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/ | 3003 | {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/ |
3004 | {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)}, | ||
3034 | {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)}, | 3005 | {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)}, |
3035 | {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)}, | 3006 | {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)}, |
3036 | /* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */ | 3007 | /* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */ |
3037 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | ||
3038 | {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)}, | 3008 | {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)}, |
3039 | #endif | 3009 | /* or MT9V111 / MI0360B */ |
3040 | /* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */ | 3010 | /* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */ |
3041 | {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)}, | 3011 | {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)}, |
3042 | {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)}, | 3012 | {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)}, |
@@ -3076,17 +3046,11 @@ static struct usb_driver sd_driver = { | |||
3076 | /* -- module insert / remove -- */ | 3046 | /* -- module insert / remove -- */ |
3077 | static int __init sd_mod_init(void) | 3047 | static int __init sd_mod_init(void) |
3078 | { | 3048 | { |
3079 | int ret; | 3049 | return usb_register(&sd_driver); |
3080 | ret = usb_register(&sd_driver); | ||
3081 | if (ret < 0) | ||
3082 | return ret; | ||
3083 | info("registered"); | ||
3084 | return 0; | ||
3085 | } | 3050 | } |
3086 | static void __exit sd_mod_exit(void) | 3051 | static void __exit sd_mod_exit(void) |
3087 | { | 3052 | { |
3088 | usb_deregister(&sd_driver); | 3053 | usb_deregister(&sd_driver); |
3089 | info("deregistered"); | ||
3090 | } | 3054 | } |
3091 | 3055 | ||
3092 | module_init(sd_mod_init); | 3056 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/video/gspca/spca1528.c index 3f514eb1d99..e6433866441 100644 --- a/drivers/media/video/gspca/spca1528.c +++ b/drivers/media/video/gspca/spca1528.c | |||
@@ -171,7 +171,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
171 | PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index, | 171 | PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index, |
172 | gspca_dev->usb_buf[0]); | 172 | gspca_dev->usb_buf[0]); |
173 | if (ret < 0) { | 173 | if (ret < 0) { |
174 | PDEBUG(D_ERR, "reg_r err %d", ret); | 174 | err("reg_r err %d", ret); |
175 | gspca_dev->usb_err = ret; | 175 | gspca_dev->usb_err = ret; |
176 | } | 176 | } |
177 | } | 177 | } |
@@ -193,7 +193,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
193 | value, index, | 193 | value, index, |
194 | NULL, 0, 500); | 194 | NULL, 0, 500); |
195 | if (ret < 0) { | 195 | if (ret < 0) { |
196 | PDEBUG(D_ERR, "reg_w err %d", ret); | 196 | err("reg_w err %d", ret); |
197 | gspca_dev->usb_err = ret; | 197 | gspca_dev->usb_err = ret; |
198 | } | 198 | } |
199 | } | 199 | } |
@@ -217,7 +217,7 @@ static void reg_wb(struct gspca_dev *gspca_dev, | |||
217 | value, index, | 217 | value, index, |
218 | gspca_dev->usb_buf, 1, 500); | 218 | gspca_dev->usb_buf, 1, 500); |
219 | if (ret < 0) { | 219 | if (ret < 0) { |
220 | PDEBUG(D_ERR, "reg_w err %d", ret); | 220 | err("reg_w err %d", ret); |
221 | gspca_dev->usb_err = ret; | 221 | gspca_dev->usb_err = ret; |
222 | } | 222 | } |
223 | } | 223 | } |
@@ -587,18 +587,11 @@ static struct usb_driver sd_driver = { | |||
587 | /* -- module insert / remove -- */ | 587 | /* -- module insert / remove -- */ |
588 | static int __init sd_mod_init(void) | 588 | static int __init sd_mod_init(void) |
589 | { | 589 | { |
590 | int ret; | 590 | return usb_register(&sd_driver); |
591 | |||
592 | ret = usb_register(&sd_driver); | ||
593 | if (ret < 0) | ||
594 | return ret; | ||
595 | info("registered"); | ||
596 | return 0; | ||
597 | } | 591 | } |
598 | static void __exit sd_mod_exit(void) | 592 | static void __exit sd_mod_exit(void) |
599 | { | 593 | { |
600 | usb_deregister(&sd_driver); | 594 | usb_deregister(&sd_driver); |
601 | info("deregistered"); | ||
602 | } | 595 | } |
603 | 596 | ||
604 | module_init(sd_mod_init); | 597 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index c02beb6c1e9..8e202b9039f 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -396,7 +396,7 @@ static int reg_w(struct gspca_dev *gspca_dev, | |||
396 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 396 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
397 | value, index, NULL, 0, 500); | 397 | value, index, NULL, 0, 500); |
398 | if (ret < 0) | 398 | if (ret < 0) |
399 | PDEBUG(D_ERR, "reg write: error %d", ret); | 399 | err("reg write: error %d", ret); |
400 | return ret; | 400 | return ret; |
401 | } | 401 | } |
402 | 402 | ||
@@ -418,8 +418,8 @@ static int reg_r_12(struct gspca_dev *gspca_dev, | |||
418 | gspca_dev->usb_buf, length, | 418 | gspca_dev->usb_buf, length, |
419 | 500); /* timeout */ | 419 | 500); /* timeout */ |
420 | if (ret < 0) { | 420 | if (ret < 0) { |
421 | PDEBUG(D_ERR, "reg_r_12 err %d", ret); | 421 | err("reg_r_12 err %d", ret); |
422 | return -1; | 422 | return ret; |
423 | } | 423 | } |
424 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | 424 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; |
425 | } | 425 | } |
@@ -1093,17 +1093,11 @@ static struct usb_driver sd_driver = { | |||
1093 | /* -- module insert / remove -- */ | 1093 | /* -- module insert / remove -- */ |
1094 | static int __init sd_mod_init(void) | 1094 | static int __init sd_mod_init(void) |
1095 | { | 1095 | { |
1096 | int ret; | 1096 | return usb_register(&sd_driver); |
1097 | ret = usb_register(&sd_driver); | ||
1098 | if (ret < 0) | ||
1099 | return ret; | ||
1100 | PDEBUG(D_PROBE, "registered"); | ||
1101 | return 0; | ||
1102 | } | 1097 | } |
1103 | static void __exit sd_mod_exit(void) | 1098 | static void __exit sd_mod_exit(void) |
1104 | { | 1099 | { |
1105 | usb_deregister(&sd_driver); | 1100 | usb_deregister(&sd_driver); |
1106 | PDEBUG(D_PROBE, "deregistered"); | ||
1107 | } | 1101 | } |
1108 | 1102 | ||
1109 | module_init(sd_mod_init); | 1103 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index c99333933e3..642839a11e8 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c | |||
@@ -1724,7 +1724,7 @@ static const __u16 spca501c_mysterious_init_data[][3] = { | |||
1724 | {0x00, 0x0000, 0x0048}, | 1724 | {0x00, 0x0000, 0x0048}, |
1725 | {0x00, 0x0000, 0x0049}, | 1725 | {0x00, 0x0000, 0x0049}, |
1726 | {0x00, 0x0008, 0x004a}, | 1726 | {0x00, 0x0008, 0x004a}, |
1727 | /* DSP Registers */ | 1727 | /* DSP Registers */ |
1728 | {0x01, 0x00a6, 0x0000}, | 1728 | {0x01, 0x00a6, 0x0000}, |
1729 | {0x01, 0x0028, 0x0001}, | 1729 | {0x01, 0x0028, 0x0001}, |
1730 | {0x01, 0x0000, 0x0002}, | 1730 | {0x01, 0x0000, 0x0002}, |
@@ -1788,7 +1788,7 @@ static const __u16 spca501c_mysterious_init_data[][3] = { | |||
1788 | {0x05, 0x0022, 0x0004}, | 1788 | {0x05, 0x0022, 0x0004}, |
1789 | {0x05, 0x0025, 0x0001}, | 1789 | {0x05, 0x0025, 0x0001}, |
1790 | {0x05, 0x0000, 0x0000}, | 1790 | {0x05, 0x0000, 0x0000}, |
1791 | /* Part 4 */ | 1791 | /* Part 4 */ |
1792 | {0x05, 0x0026, 0x0001}, | 1792 | {0x05, 0x0026, 0x0001}, |
1793 | {0x05, 0x0001, 0x0000}, | 1793 | {0x05, 0x0001, 0x0000}, |
1794 | {0x05, 0x0027, 0x0001}, | 1794 | {0x05, 0x0027, 0x0001}, |
@@ -1806,7 +1806,7 @@ static const __u16 spca501c_mysterious_init_data[][3] = { | |||
1806 | {0x05, 0x0001, 0x0000}, | 1806 | {0x05, 0x0001, 0x0000}, |
1807 | {0x05, 0x0027, 0x0001}, | 1807 | {0x05, 0x0027, 0x0001}, |
1808 | {0x05, 0x004e, 0x0000}, | 1808 | {0x05, 0x004e, 0x0000}, |
1809 | /* Part 5 */ | 1809 | /* Part 5 */ |
1810 | {0x01, 0x0003, 0x003f}, | 1810 | {0x01, 0x0003, 0x003f}, |
1811 | {0x01, 0x0001, 0x0056}, | 1811 | {0x01, 0x0001, 0x0056}, |
1812 | {0x01, 0x000f, 0x0008}, | 1812 | {0x01, 0x000f, 0x0008}, |
@@ -1852,7 +1852,7 @@ static int reg_write(struct usb_device *dev, | |||
1852 | PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x", | 1852 | PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x", |
1853 | req, index, value); | 1853 | req, index, value); |
1854 | if (ret < 0) | 1854 | if (ret < 0) |
1855 | PDEBUG(D_ERR, "reg write: error %d", ret); | 1855 | err("reg write: error %d", ret); |
1856 | return ret; | 1856 | return ret; |
1857 | } | 1857 | } |
1858 | 1858 | ||
@@ -2189,17 +2189,11 @@ static struct usb_driver sd_driver = { | |||
2189 | /* -- module insert / remove -- */ | 2189 | /* -- module insert / remove -- */ |
2190 | static int __init sd_mod_init(void) | 2190 | static int __init sd_mod_init(void) |
2191 | { | 2191 | { |
2192 | int ret; | 2192 | return usb_register(&sd_driver); |
2193 | ret = usb_register(&sd_driver); | ||
2194 | if (ret < 0) | ||
2195 | return ret; | ||
2196 | PDEBUG(D_PROBE, "registered"); | ||
2197 | return 0; | ||
2198 | } | 2193 | } |
2199 | static void __exit sd_mod_exit(void) | 2194 | static void __exit sd_mod_exit(void) |
2200 | { | 2195 | { |
2201 | usb_deregister(&sd_driver); | 2196 | usb_deregister(&sd_driver); |
2202 | PDEBUG(D_PROBE, "deregistered"); | ||
2203 | } | 2197 | } |
2204 | 2198 | ||
2205 | module_init(sd_mod_init); | 2199 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index c576eed73ab..bc9dd9034ab 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -368,10 +368,6 @@ static const u8 spca505b_init_data[][3] = { | |||
368 | {0x08, 0x00, 0x00}, | 368 | {0x08, 0x00, 0x00}, |
369 | {0x08, 0x00, 0x01}, | 369 | {0x08, 0x00, 0x01}, |
370 | {0x08, 0x00, 0x02}, | 370 | {0x08, 0x00, 0x02}, |
371 | {0x00, 0x01, 0x00}, | ||
372 | {0x00, 0x01, 0x01}, | ||
373 | {0x00, 0x01, 0x34}, | ||
374 | {0x00, 0x01, 0x35}, | ||
375 | {0x06, 0x18, 0x08}, | 371 | {0x06, 0x18, 0x08}, |
376 | {0x06, 0xfc, 0x09}, | 372 | {0x06, 0xfc, 0x09}, |
377 | {0x06, 0xfc, 0x0a}, | 373 | {0x06, 0xfc, 0x0a}, |
@@ -582,7 +578,7 @@ static int reg_write(struct usb_device *dev, | |||
582 | PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", | 578 | PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", |
583 | req, index, value, ret); | 579 | req, index, value, ret); |
584 | if (ret < 0) | 580 | if (ret < 0) |
585 | PDEBUG(D_ERR, "reg write: error %d", ret); | 581 | err("reg write: error %d", ret); |
586 | return ret; | 582 | return ret; |
587 | } | 583 | } |
588 | 584 | ||
@@ -689,8 +685,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
689 | return ret; | 685 | return ret; |
690 | } | 686 | } |
691 | if (ret != 0x0101) { | 687 | if (ret != 0x0101) { |
692 | PDEBUG(D_ERR|D_CONF, | 688 | err("After vector read returns 0x%04x should be 0x0101", |
693 | "After vector read returns 0x%04x should be 0x0101", | ||
694 | ret); | 689 | ret); |
695 | } | 690 | } |
696 | 691 | ||
@@ -821,18 +816,11 @@ static struct usb_driver sd_driver = { | |||
821 | /* -- module insert / remove -- */ | 816 | /* -- module insert / remove -- */ |
822 | static int __init sd_mod_init(void) | 817 | static int __init sd_mod_init(void) |
823 | { | 818 | { |
824 | int ret; | 819 | return usb_register(&sd_driver); |
825 | |||
826 | ret = usb_register(&sd_driver); | ||
827 | if (ret < 0) | ||
828 | return ret; | ||
829 | PDEBUG(D_PROBE, "registered"); | ||
830 | return 0; | ||
831 | } | 820 | } |
832 | static void __exit sd_mod_exit(void) | 821 | static void __exit sd_mod_exit(void) |
833 | { | 822 | { |
834 | usb_deregister(&sd_driver); | 823 | usb_deregister(&sd_driver); |
835 | PDEBUG(D_PROBE, "deregistered"); | ||
836 | } | 824 | } |
837 | 825 | ||
838 | module_init(sd_mod_init); | 826 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index edf0fe15750..7307638ac91 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -92,8 +92,7 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
92 | * Initialization data: this is the first set-up data written to the | 92 | * Initialization data: this is the first set-up data written to the |
93 | * device (before the open data). | 93 | * device (before the open data). |
94 | */ | 94 | */ |
95 | static const u16 spca508_init_data[][2] = | 95 | static const u16 spca508_init_data[][2] = { |
96 | { | ||
97 | {0x0000, 0x870b}, | 96 | {0x0000, 0x870b}, |
98 | 97 | ||
99 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ | 98 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
@@ -1276,7 +1275,7 @@ static int reg_write(struct usb_device *dev, | |||
1276 | PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x", | 1275 | PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x", |
1277 | index, value); | 1276 | index, value); |
1278 | if (ret < 0) | 1277 | if (ret < 0) |
1279 | PDEBUG(D_ERR|D_USBO, "reg write: error %d", ret); | 1278 | err("reg write: error %d", ret); |
1280 | return ret; | 1279 | return ret; |
1281 | } | 1280 | } |
1282 | 1281 | ||
@@ -1298,7 +1297,7 @@ static int reg_read(struct gspca_dev *gspca_dev, | |||
1298 | PDEBUG(D_USBI, "reg read i:%04x --> %02x", | 1297 | PDEBUG(D_USBI, "reg read i:%04x --> %02x", |
1299 | index, gspca_dev->usb_buf[0]); | 1298 | index, gspca_dev->usb_buf[0]); |
1300 | if (ret < 0) { | 1299 | if (ret < 0) { |
1301 | PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret); | 1300 | err("reg_read err %d", ret); |
1302 | return ret; | 1301 | return ret; |
1303 | } | 1302 | } |
1304 | return gspca_dev->usb_buf[0]; | 1303 | return gspca_dev->usb_buf[0]; |
@@ -1543,18 +1542,11 @@ static struct usb_driver sd_driver = { | |||
1543 | /* -- module insert / remove -- */ | 1542 | /* -- module insert / remove -- */ |
1544 | static int __init sd_mod_init(void) | 1543 | static int __init sd_mod_init(void) |
1545 | { | 1544 | { |
1546 | int ret; | 1545 | return usb_register(&sd_driver); |
1547 | |||
1548 | ret = usb_register(&sd_driver); | ||
1549 | if (ret < 0) | ||
1550 | return ret; | ||
1551 | PDEBUG(D_PROBE, "registered"); | ||
1552 | return 0; | ||
1553 | } | 1546 | } |
1554 | static void __exit sd_mod_exit(void) | 1547 | static void __exit sd_mod_exit(void) |
1555 | { | 1548 | { |
1556 | usb_deregister(&sd_driver); | 1549 | usb_deregister(&sd_driver); |
1557 | PDEBUG(D_PROBE, "deregistered"); | ||
1558 | } | 1550 | } |
1559 | 1551 | ||
1560 | module_init(sd_mod_init); | 1552 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 7bb2355005d..ad73f4812c0 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -315,7 +315,7 @@ static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) | |||
315 | value, index, NULL, 0, 500); | 315 | value, index, NULL, 0, 500); |
316 | PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); | 316 | PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); |
317 | if (ret < 0) | 317 | if (ret < 0) |
318 | PDEBUG(D_ERR, "reg write: error %d", ret); | 318 | err("reg write: error %d", ret); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void write_vector(struct gspca_dev *gspca_dev, | 321 | static void write_vector(struct gspca_dev *gspca_dev, |
@@ -787,7 +787,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
787 | return; | 787 | return; |
788 | } | 788 | } |
789 | 789 | ||
790 | #ifdef CONFIG_INPUT | 790 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
791 | if (data[0] & 0x20) { | 791 | if (data[0] & 0x20) { |
792 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); | 792 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); |
793 | input_sync(gspca_dev->input_dev); | 793 | input_sync(gspca_dev->input_dev); |
@@ -1037,7 +1037,7 @@ static const struct sd_desc sd_desc_12a = { | |||
1037 | .start = sd_start_12a, | 1037 | .start = sd_start_12a, |
1038 | .stopN = sd_stopN, | 1038 | .stopN = sd_stopN, |
1039 | .pkt_scan = sd_pkt_scan, | 1039 | .pkt_scan = sd_pkt_scan, |
1040 | #ifdef CONFIG_INPUT | 1040 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1041 | .other_input = 1, | 1041 | .other_input = 1, |
1042 | #endif | 1042 | #endif |
1043 | }; | 1043 | }; |
@@ -1051,7 +1051,7 @@ static const struct sd_desc sd_desc_72a = { | |||
1051 | .stopN = sd_stopN, | 1051 | .stopN = sd_stopN, |
1052 | .pkt_scan = sd_pkt_scan, | 1052 | .pkt_scan = sd_pkt_scan, |
1053 | .dq_callback = do_autogain, | 1053 | .dq_callback = do_autogain, |
1054 | #ifdef CONFIG_INPUT | 1054 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
1055 | .other_input = 1, | 1055 | .other_input = 1, |
1056 | #endif | 1056 | #endif |
1057 | }; | 1057 | }; |
@@ -1107,17 +1107,11 @@ static struct usb_driver sd_driver = { | |||
1107 | /* -- module insert / remove -- */ | 1107 | /* -- module insert / remove -- */ |
1108 | static int __init sd_mod_init(void) | 1108 | static int __init sd_mod_init(void) |
1109 | { | 1109 | { |
1110 | int ret; | 1110 | return usb_register(&sd_driver); |
1111 | ret = usb_register(&sd_driver); | ||
1112 | if (ret < 0) | ||
1113 | return ret; | ||
1114 | PDEBUG(D_PROBE, "registered"); | ||
1115 | return 0; | ||
1116 | } | 1111 | } |
1117 | static void __exit sd_mod_exit(void) | 1112 | static void __exit sd_mod_exit(void) |
1118 | { | 1113 | { |
1119 | usb_deregister(&sd_driver); | 1114 | usb_deregister(&sd_driver); |
1120 | PDEBUG(D_PROBE, "deregistered"); | ||
1121 | } | 1115 | } |
1122 | 1116 | ||
1123 | module_init(sd_mod_init); | 1117 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 09b3f93fa4d..40406774577 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c | |||
@@ -123,7 +123,7 @@ static int sq905_command(struct gspca_dev *gspca_dev, u16 index) | |||
123 | SQ905_COMMAND, index, gspca_dev->usb_buf, 1, | 123 | SQ905_COMMAND, index, gspca_dev->usb_buf, 1, |
124 | SQ905_CMD_TIMEOUT); | 124 | SQ905_CMD_TIMEOUT); |
125 | if (ret < 0) { | 125 | if (ret < 0) { |
126 | PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", | 126 | err("%s: usb_control_msg failed (%d)", |
127 | __func__, ret); | 127 | __func__, ret); |
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
@@ -135,7 +135,7 @@ static int sq905_command(struct gspca_dev *gspca_dev, u16 index) | |||
135 | SQ905_PING, 0, gspca_dev->usb_buf, 1, | 135 | SQ905_PING, 0, gspca_dev->usb_buf, 1, |
136 | SQ905_CMD_TIMEOUT); | 136 | SQ905_CMD_TIMEOUT); |
137 | if (ret < 0) { | 137 | if (ret < 0) { |
138 | PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)", | 138 | err("%s: usb_control_msg failed 2 (%d)", |
139 | __func__, ret); | 139 | __func__, ret); |
140 | return ret; | 140 | return ret; |
141 | } | 141 | } |
@@ -158,7 +158,7 @@ static int sq905_ack_frame(struct gspca_dev *gspca_dev) | |||
158 | SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1, | 158 | SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1, |
159 | SQ905_CMD_TIMEOUT); | 159 | SQ905_CMD_TIMEOUT); |
160 | if (ret < 0) { | 160 | if (ret < 0) { |
161 | PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); | 161 | err("%s: usb_control_msg failed (%d)", __func__, ret); |
162 | return ret; | 162 | return ret; |
163 | } | 163 | } |
164 | 164 | ||
@@ -186,7 +186,7 @@ sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) | |||
186 | if (need_lock) | 186 | if (need_lock) |
187 | mutex_unlock(&gspca_dev->usb_lock); | 187 | mutex_unlock(&gspca_dev->usb_lock); |
188 | if (ret < 0) { | 188 | if (ret < 0) { |
189 | PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); | 189 | err("%s: usb_control_msg failed (%d)", __func__, ret); |
190 | return ret; | 190 | return ret; |
191 | } | 191 | } |
192 | ret = usb_bulk_msg(gspca_dev->dev, | 192 | ret = usb_bulk_msg(gspca_dev->dev, |
@@ -195,7 +195,7 @@ sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) | |||
195 | 195 | ||
196 | /* successful, it returns 0, otherwise negative */ | 196 | /* successful, it returns 0, otherwise negative */ |
197 | if (ret < 0 || act_len != size) { | 197 | if (ret < 0 || act_len != size) { |
198 | PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d", | 198 | err("bulk read fail (%d) len %d/%d", |
199 | ret, act_len, size); | 199 | ret, act_len, size); |
200 | return -EIO; | 200 | return -EIO; |
201 | } | 201 | } |
@@ -226,7 +226,7 @@ static void sq905_dostream(struct work_struct *work) | |||
226 | 226 | ||
227 | buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); | 227 | buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); |
228 | if (!buffer) { | 228 | if (!buffer) { |
229 | PDEBUG(D_ERR, "Couldn't allocate USB buffer"); | 229 | err("Couldn't allocate USB buffer"); |
230 | goto quit_stream; | 230 | goto quit_stream; |
231 | } | 231 | } |
232 | 232 | ||
@@ -436,19 +436,12 @@ static struct usb_driver sd_driver = { | |||
436 | /* -- module insert / remove -- */ | 436 | /* -- module insert / remove -- */ |
437 | static int __init sd_mod_init(void) | 437 | static int __init sd_mod_init(void) |
438 | { | 438 | { |
439 | int ret; | 439 | return usb_register(&sd_driver); |
440 | |||
441 | ret = usb_register(&sd_driver); | ||
442 | if (ret < 0) | ||
443 | return ret; | ||
444 | PDEBUG(D_PROBE, "registered"); | ||
445 | return 0; | ||
446 | } | 440 | } |
447 | 441 | ||
448 | static void __exit sd_mod_exit(void) | 442 | static void __exit sd_mod_exit(void) |
449 | { | 443 | { |
450 | usb_deregister(&sd_driver); | 444 | usb_deregister(&sd_driver); |
451 | PDEBUG(D_PROBE, "deregistered"); | ||
452 | } | 445 | } |
453 | 446 | ||
454 | module_init(sd_mod_init); | 447 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 4c70628ca61..c2e88b5303c 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -95,7 +95,7 @@ static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index) | |||
95 | command, index, NULL, 0, | 95 | command, index, NULL, 0, |
96 | SQ905C_CMD_TIMEOUT); | 96 | SQ905C_CMD_TIMEOUT); |
97 | if (ret < 0) { | 97 | if (ret < 0) { |
98 | PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", | 98 | err("%s: usb_control_msg failed (%d)", |
99 | __func__, ret); | 99 | __func__, ret); |
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
@@ -115,7 +115,7 @@ static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index, | |||
115 | command, index, gspca_dev->usb_buf, size, | 115 | command, index, gspca_dev->usb_buf, size, |
116 | SQ905C_CMD_TIMEOUT); | 116 | SQ905C_CMD_TIMEOUT); |
117 | if (ret < 0) { | 117 | if (ret < 0) { |
118 | PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", | 118 | err("%s: usb_control_msg failed (%d)", |
119 | __func__, ret); | 119 | __func__, ret); |
120 | return ret; | 120 | return ret; |
121 | } | 121 | } |
@@ -146,7 +146,7 @@ static void sq905c_dostream(struct work_struct *work) | |||
146 | 146 | ||
147 | buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); | 147 | buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); |
148 | if (!buffer) { | 148 | if (!buffer) { |
149 | PDEBUG(D_ERR, "Couldn't allocate USB buffer"); | 149 | err("Couldn't allocate USB buffer"); |
150 | goto quit_stream; | 150 | goto quit_stream; |
151 | } | 151 | } |
152 | 152 | ||
@@ -341,19 +341,12 @@ static struct usb_driver sd_driver = { | |||
341 | /* -- module insert / remove -- */ | 341 | /* -- module insert / remove -- */ |
342 | static int __init sd_mod_init(void) | 342 | static int __init sd_mod_init(void) |
343 | { | 343 | { |
344 | int ret; | 344 | return usb_register(&sd_driver); |
345 | |||
346 | ret = usb_register(&sd_driver); | ||
347 | if (ret < 0) | ||
348 | return ret; | ||
349 | PDEBUG(D_PROBE, "registered"); | ||
350 | return 0; | ||
351 | } | 345 | } |
352 | 346 | ||
353 | static void __exit sd_mod_exit(void) | 347 | static void __exit sd_mod_exit(void) |
354 | { | 348 | { |
355 | usb_deregister(&sd_driver); | 349 | usb_deregister(&sd_driver); |
356 | PDEBUG(D_PROBE, "deregistered"); | ||
357 | } | 350 | } |
358 | 351 | ||
359 | module_init(sd_mod_init); | 352 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c index 7ae6522d4ed..3e4b0b94c70 100644 --- a/drivers/media/video/gspca/sq930x.c +++ b/drivers/media/video/gspca/sq930x.c | |||
@@ -468,7 +468,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
468 | value, 0, gspca_dev->usb_buf, len, | 468 | value, 0, gspca_dev->usb_buf, len, |
469 | 500); | 469 | 500); |
470 | if (ret < 0) { | 470 | if (ret < 0) { |
471 | PDEBUG(D_ERR, "reg_r %04x failed %d", value, ret); | 471 | err("reg_r %04x failed %d", value, ret); |
472 | gspca_dev->usb_err = ret; | 472 | gspca_dev->usb_err = ret; |
473 | } | 473 | } |
474 | } | 474 | } |
@@ -488,7 +488,7 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) | |||
488 | 500); | 488 | 500); |
489 | msleep(30); | 489 | msleep(30); |
490 | if (ret < 0) { | 490 | if (ret < 0) { |
491 | PDEBUG(D_ERR, "reg_w %04x %04x failed %d", value, index, ret); | 491 | err("reg_w %04x %04x failed %d", value, index, ret); |
492 | gspca_dev->usb_err = ret; | 492 | gspca_dev->usb_err = ret; |
493 | } | 493 | } |
494 | } | 494 | } |
@@ -511,7 +511,7 @@ static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index, | |||
511 | 1000); | 511 | 1000); |
512 | msleep(30); | 512 | msleep(30); |
513 | if (ret < 0) { | 513 | if (ret < 0) { |
514 | PDEBUG(D_ERR, "reg_wb %04x %04x failed %d", value, index, ret); | 514 | err("reg_wb %04x %04x failed %d", value, index, ret); |
515 | gspca_dev->usb_err = ret; | 515 | gspca_dev->usb_err = ret; |
516 | } | 516 | } |
517 | } | 517 | } |
@@ -556,7 +556,7 @@ static void i2c_write(struct sd *sd, | |||
556 | gspca_dev->usb_buf, buf - gspca_dev->usb_buf, | 556 | gspca_dev->usb_buf, buf - gspca_dev->usb_buf, |
557 | 500); | 557 | 500); |
558 | if (ret < 0) { | 558 | if (ret < 0) { |
559 | PDEBUG(D_ERR, "i2c_write failed %d", ret); | 559 | err("i2c_write failed %d", ret); |
560 | gspca_dev->usb_err = ret; | 560 | gspca_dev->usb_err = ret; |
561 | } | 561 | } |
562 | } | 562 | } |
@@ -612,7 +612,7 @@ static void ucbus_write(struct gspca_dev *gspca_dev, | |||
612 | gspca_dev->usb_buf, buf - gspca_dev->usb_buf, | 612 | gspca_dev->usb_buf, buf - gspca_dev->usb_buf, |
613 | 500); | 613 | 500); |
614 | if (ret < 0) { | 614 | if (ret < 0) { |
615 | PDEBUG(D_ERR, "ucbus_write failed %d", ret); | 615 | err("ucbus_write failed %d", ret); |
616 | gspca_dev->usb_err = ret; | 616 | gspca_dev->usb_err = ret; |
617 | return; | 617 | return; |
618 | } | 618 | } |
@@ -688,7 +688,7 @@ static void cmos_probe(struct gspca_dev *gspca_dev) | |||
688 | break; | 688 | break; |
689 | } | 689 | } |
690 | if (i >= ARRAY_SIZE(probe_order)) | 690 | if (i >= ARRAY_SIZE(probe_order)) |
691 | PDEBUG(D_PROBE, "Unknown sensor"); | 691 | err("Unknown sensor"); |
692 | else | 692 | else |
693 | sd->sensor = probe_order[i]; | 693 | sd->sensor = probe_order[i]; |
694 | } | 694 | } |
@@ -1079,7 +1079,7 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) | |||
1079 | gspca_dev->cam.bulk_nurbs = 1; | 1079 | gspca_dev->cam.bulk_nurbs = 1; |
1080 | ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC); | 1080 | ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC); |
1081 | if (ret < 0) | 1081 | if (ret < 0) |
1082 | PDEBUG(D_ERR|D_PACK, "sd_dq_callback() err %d", ret); | 1082 | err("sd_dq_callback() err %d", ret); |
1083 | 1083 | ||
1084 | /* wait a little time, otherwise the webcam crashes */ | 1084 | /* wait a little time, otherwise the webcam crashes */ |
1085 | msleep(100); | 1085 | msleep(100); |
@@ -1185,18 +1185,11 @@ static struct usb_driver sd_driver = { | |||
1185 | /* -- module insert / remove -- */ | 1185 | /* -- module insert / remove -- */ |
1186 | static int __init sd_mod_init(void) | 1186 | static int __init sd_mod_init(void) |
1187 | { | 1187 | { |
1188 | int ret; | 1188 | return usb_register(&sd_driver); |
1189 | |||
1190 | ret = usb_register(&sd_driver); | ||
1191 | if (ret < 0) | ||
1192 | return ret; | ||
1193 | info("registered"); | ||
1194 | return 0; | ||
1195 | } | 1189 | } |
1196 | static void __exit sd_mod_exit(void) | 1190 | static void __exit sd_mod_exit(void) |
1197 | { | 1191 | { |
1198 | usb_deregister(&sd_driver); | 1192 | usb_deregister(&sd_driver); |
1199 | info("deregistered"); | ||
1200 | } | 1193 | } |
1201 | 1194 | ||
1202 | module_init(sd_mod_init); | 1195 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 2aedf4b1bfa..11a192b95ed 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c | |||
@@ -27,14 +27,21 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | |||
27 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); | 27 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); |
28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
29 | 29 | ||
30 | /* controls */ | ||
31 | enum e_ctrl { | ||
32 | BRIGHTNESS, | ||
33 | CONTRAST, | ||
34 | COLORS, | ||
35 | LIGHTFREQ, | ||
36 | NCTRLS /* number of controls */ | ||
37 | }; | ||
38 | |||
30 | /* specific webcam descriptor */ | 39 | /* specific webcam descriptor */ |
31 | struct sd { | 40 | struct sd { |
32 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 41 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
33 | 42 | ||
34 | unsigned char brightness; | 43 | struct gspca_ctrl ctrls[NCTRLS]; |
35 | unsigned char contrast; | 44 | |
36 | unsigned char colors; | ||
37 | unsigned char lightfreq; | ||
38 | u8 quality; | 45 | u8 quality; |
39 | #define QUALITY_MIN 70 | 46 | #define QUALITY_MIN 70 |
40 | #define QUALITY_MAX 95 | 47 | #define QUALITY_MAX 95 |
@@ -44,17 +51,13 @@ struct sd { | |||
44 | }; | 51 | }; |
45 | 52 | ||
46 | /* V4L2 controls supported by the driver */ | 53 | /* V4L2 controls supported by the driver */ |
47 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 54 | static void setbrightness(struct gspca_dev *gspca_dev); |
48 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 55 | static void setcontrast(struct gspca_dev *gspca_dev); |
49 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 56 | static void setcolors(struct gspca_dev *gspca_dev); |
50 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 57 | static void setlightfreq(struct gspca_dev *gspca_dev); |
51 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 58 | |
52 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 59 | static const struct ctrl sd_ctrls[NCTRLS] = { |
53 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | 60 | [BRIGHTNESS] = { |
54 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | |||
56 | static const struct ctrl sd_ctrls[] = { | ||
57 | { | ||
58 | { | 61 | { |
59 | .id = V4L2_CID_BRIGHTNESS, | 62 | .id = V4L2_CID_BRIGHTNESS, |
60 | .type = V4L2_CTRL_TYPE_INTEGER, | 63 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -62,13 +65,11 @@ static const struct ctrl sd_ctrls[] = { | |||
62 | .minimum = 0, | 65 | .minimum = 0, |
63 | .maximum = 255, | 66 | .maximum = 255, |
64 | .step = 1, | 67 | .step = 1, |
65 | #define BRIGHTNESS_DEF 127 | 68 | .default_value = 127, |
66 | .default_value = BRIGHTNESS_DEF, | ||
67 | }, | 69 | }, |
68 | .set = sd_setbrightness, | 70 | .set_control = setbrightness |
69 | .get = sd_getbrightness, | ||
70 | }, | 71 | }, |
71 | { | 72 | [CONTRAST] = { |
72 | { | 73 | { |
73 | .id = V4L2_CID_CONTRAST, | 74 | .id = V4L2_CID_CONTRAST, |
74 | .type = V4L2_CTRL_TYPE_INTEGER, | 75 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -76,13 +77,11 @@ static const struct ctrl sd_ctrls[] = { | |||
76 | .minimum = 0, | 77 | .minimum = 0, |
77 | .maximum = 255, | 78 | .maximum = 255, |
78 | .step = 1, | 79 | .step = 1, |
79 | #define CONTRAST_DEF 127 | 80 | .default_value = 127, |
80 | .default_value = CONTRAST_DEF, | ||
81 | }, | 81 | }, |
82 | .set = sd_setcontrast, | 82 | .set_control = setcontrast |
83 | .get = sd_getcontrast, | ||
84 | }, | 83 | }, |
85 | { | 84 | [COLORS] = { |
86 | { | 85 | { |
87 | .id = V4L2_CID_SATURATION, | 86 | .id = V4L2_CID_SATURATION, |
88 | .type = V4L2_CTRL_TYPE_INTEGER, | 87 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -90,13 +89,11 @@ static const struct ctrl sd_ctrls[] = { | |||
90 | .minimum = 0, | 89 | .minimum = 0, |
91 | .maximum = 255, | 90 | .maximum = 255, |
92 | .step = 1, | 91 | .step = 1, |
93 | #define COLOR_DEF 127 | 92 | .default_value = 127, |
94 | .default_value = COLOR_DEF, | ||
95 | }, | 93 | }, |
96 | .set = sd_setcolors, | 94 | .set_control = setcolors |
97 | .get = sd_getcolors, | ||
98 | }, | 95 | }, |
99 | { | 96 | [LIGHTFREQ] = { |
100 | { | 97 | { |
101 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 98 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
102 | .type = V4L2_CTRL_TYPE_MENU, | 99 | .type = V4L2_CTRL_TYPE_MENU, |
@@ -104,11 +101,9 @@ static const struct ctrl sd_ctrls[] = { | |||
104 | .minimum = 1, | 101 | .minimum = 1, |
105 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | 102 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ |
106 | .step = 1, | 103 | .step = 1, |
107 | #define FREQ_DEF 1 | 104 | .default_value = 1, |
108 | .default_value = FREQ_DEF, | ||
109 | }, | 105 | }, |
110 | .set = sd_setfreq, | 106 | .set_control = setlightfreq |
111 | .get = sd_getfreq, | ||
112 | }, | 107 | }, |
113 | }; | 108 | }; |
114 | 109 | ||
@@ -142,7 +137,7 @@ static u8 reg_r(struct gspca_dev *gspca_dev, | |||
142 | gspca_dev->usb_buf, 1, | 137 | gspca_dev->usb_buf, 1, |
143 | 500); | 138 | 500); |
144 | if (ret < 0) { | 139 | if (ret < 0) { |
145 | PDEBUG(D_ERR, "reg_r err %d", ret); | 140 | err("reg_r err %d", ret); |
146 | gspca_dev->usb_err = ret; | 141 | gspca_dev->usb_err = ret; |
147 | return 0; | 142 | return 0; |
148 | } | 143 | } |
@@ -167,7 +162,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
167 | 0, | 162 | 0, |
168 | 500); | 163 | 500); |
169 | if (ret < 0) { | 164 | if (ret < 0) { |
170 | PDEBUG(D_ERR, "reg_w err %d", ret); | 165 | err("reg_w err %d", ret); |
171 | gspca_dev->usb_err = ret; | 166 | gspca_dev->usb_err = ret; |
172 | } | 167 | } |
173 | } | 168 | } |
@@ -197,7 +192,7 @@ static void rcv_val(struct gspca_dev *gspca_dev, | |||
197 | &alen, | 192 | &alen, |
198 | 500); /* timeout in milliseconds */ | 193 | 500); /* timeout in milliseconds */ |
199 | if (ret < 0) { | 194 | if (ret < 0) { |
200 | PDEBUG(D_ERR, "rcv_val err %d", ret); | 195 | err("rcv_val err %d", ret); |
201 | gspca_dev->usb_err = ret; | 196 | gspca_dev->usb_err = ret; |
202 | } | 197 | } |
203 | } | 198 | } |
@@ -240,7 +235,7 @@ static void snd_val(struct gspca_dev *gspca_dev, | |||
240 | &alen, | 235 | &alen, |
241 | 500); /* timeout in milliseconds */ | 236 | 500); /* timeout in milliseconds */ |
242 | if (ret < 0) { | 237 | if (ret < 0) { |
243 | PDEBUG(D_ERR, "snd_val err %d", ret); | 238 | err("snd_val err %d", ret); |
244 | gspca_dev->usb_err = ret; | 239 | gspca_dev->usb_err = ret; |
245 | } else { | 240 | } else { |
246 | if (ads == 0x003f08) { | 241 | if (ads == 0x003f08) { |
@@ -264,7 +259,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
264 | int parval; | 259 | int parval; |
265 | 260 | ||
266 | parval = 0x06000000 /* whiteness */ | 261 | parval = 0x06000000 /* whiteness */ |
267 | + (sd->brightness << 16); | 262 | + (sd->ctrls[BRIGHTNESS].val << 16); |
268 | set_par(gspca_dev, parval); | 263 | set_par(gspca_dev, parval); |
269 | } | 264 | } |
270 | 265 | ||
@@ -274,7 +269,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
274 | int parval; | 269 | int parval; |
275 | 270 | ||
276 | parval = 0x07000000 /* contrast */ | 271 | parval = 0x07000000 /* contrast */ |
277 | + (sd->contrast << 16); | 272 | + (sd->ctrls[CONTRAST].val << 16); |
278 | set_par(gspca_dev, parval); | 273 | set_par(gspca_dev, parval); |
279 | } | 274 | } |
280 | 275 | ||
@@ -284,15 +279,15 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
284 | int parval; | 279 | int parval; |
285 | 280 | ||
286 | parval = 0x08000000 /* saturation */ | 281 | parval = 0x08000000 /* saturation */ |
287 | + (sd->colors << 16); | 282 | + (sd->ctrls[COLORS].val << 16); |
288 | set_par(gspca_dev, parval); | 283 | set_par(gspca_dev, parval); |
289 | } | 284 | } |
290 | 285 | ||
291 | static void setfreq(struct gspca_dev *gspca_dev) | 286 | static void setlightfreq(struct gspca_dev *gspca_dev) |
292 | { | 287 | { |
293 | struct sd *sd = (struct sd *) gspca_dev; | 288 | struct sd *sd = (struct sd *) gspca_dev; |
294 | 289 | ||
295 | set_par(gspca_dev, sd->lightfreq == 1 | 290 | set_par(gspca_dev, sd->ctrls[LIGHTFREQ].val == 1 |
296 | ? 0x33640000 /* 50 Hz */ | 291 | ? 0x33640000 /* 50 Hz */ |
297 | : 0x33780000); /* 60 Hz */ | 292 | : 0x33780000); /* 60 Hz */ |
298 | } | 293 | } |
@@ -305,10 +300,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
305 | 300 | ||
306 | gspca_dev->cam.cam_mode = vga_mode; | 301 | gspca_dev->cam.cam_mode = vga_mode; |
307 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | 302 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); |
308 | sd->brightness = BRIGHTNESS_DEF; | 303 | gspca_dev->cam.ctrls = sd->ctrls; |
309 | sd->contrast = CONTRAST_DEF; | ||
310 | sd->colors = COLOR_DEF; | ||
311 | sd->lightfreq = FREQ_DEF; | ||
312 | sd->quality = QUALITY_DEF; | 304 | sd->quality = QUALITY_DEF; |
313 | return 0; | 305 | return 0; |
314 | } | 306 | } |
@@ -323,7 +315,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
323 | ret = reg_r(gspca_dev, 0x0740); | 315 | ret = reg_r(gspca_dev, 0x0740); |
324 | if (gspca_dev->usb_err >= 0) { | 316 | if (gspca_dev->usb_err >= 0) { |
325 | if (ret != 0xff) { | 317 | if (ret != 0xff) { |
326 | PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); | 318 | err("init reg: 0x%02x", ret); |
327 | gspca_dev->usb_err = -EIO; | 319 | gspca_dev->usb_err = -EIO; |
328 | } | 320 | } |
329 | } | 321 | } |
@@ -357,7 +349,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
357 | gspca_dev->iface, | 349 | gspca_dev->iface, |
358 | gspca_dev->alt); | 350 | gspca_dev->alt); |
359 | if (ret < 0) { | 351 | if (ret < 0) { |
360 | PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", | 352 | err("set intf %d %d failed", |
361 | gspca_dev->iface, gspca_dev->alt); | 353 | gspca_dev->iface, gspca_dev->alt); |
362 | gspca_dev->usb_err = ret; | 354 | gspca_dev->usb_err = ret; |
363 | goto out; | 355 | goto out; |
@@ -378,7 +370,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
378 | set_par(gspca_dev, 0x0a800000); /* Green ? */ | 370 | set_par(gspca_dev, 0x0a800000); /* Green ? */ |
379 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ | 371 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ |
380 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ | 372 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ |
381 | setfreq(gspca_dev); /* light frequency */ | 373 | setlightfreq(gspca_dev); |
382 | 374 | ||
383 | /* start the video flow */ | 375 | /* start the video flow */ |
384 | set_par(gspca_dev, 0x01000000); | 376 | set_par(gspca_dev, 0x01000000); |
@@ -441,78 +433,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
441 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 433 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
442 | } | 434 | } |
443 | 435 | ||
444 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
445 | { | ||
446 | struct sd *sd = (struct sd *) gspca_dev; | ||
447 | |||
448 | sd->brightness = val; | ||
449 | if (gspca_dev->streaming) | ||
450 | setbrightness(gspca_dev); | ||
451 | return gspca_dev->usb_err; | ||
452 | } | ||
453 | |||
454 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
455 | { | ||
456 | struct sd *sd = (struct sd *) gspca_dev; | ||
457 | |||
458 | *val = sd->brightness; | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
463 | { | ||
464 | struct sd *sd = (struct sd *) gspca_dev; | ||
465 | |||
466 | sd->contrast = val; | ||
467 | if (gspca_dev->streaming) | ||
468 | setcontrast(gspca_dev); | ||
469 | return gspca_dev->usb_err; | ||
470 | } | ||
471 | |||
472 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
473 | { | ||
474 | struct sd *sd = (struct sd *) gspca_dev; | ||
475 | |||
476 | *val = sd->contrast; | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
481 | { | ||
482 | struct sd *sd = (struct sd *) gspca_dev; | ||
483 | |||
484 | sd->colors = val; | ||
485 | if (gspca_dev->streaming) | ||
486 | setcolors(gspca_dev); | ||
487 | return gspca_dev->usb_err; | ||
488 | } | ||
489 | |||
490 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
491 | { | ||
492 | struct sd *sd = (struct sd *) gspca_dev; | ||
493 | |||
494 | *val = sd->colors; | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
499 | { | ||
500 | struct sd *sd = (struct sd *) gspca_dev; | ||
501 | |||
502 | sd->lightfreq = val; | ||
503 | if (gspca_dev->streaming) | ||
504 | setfreq(gspca_dev); | ||
505 | return gspca_dev->usb_err; | ||
506 | } | ||
507 | |||
508 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
509 | { | ||
510 | struct sd *sd = (struct sd *) gspca_dev; | ||
511 | |||
512 | *val = sd->lightfreq; | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 436 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
517 | struct v4l2_querymenu *menu) | 437 | struct v4l2_querymenu *menu) |
518 | { | 438 | { |
@@ -563,7 +483,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
563 | static const struct sd_desc sd_desc = { | 483 | static const struct sd_desc sd_desc = { |
564 | .name = MODULE_NAME, | 484 | .name = MODULE_NAME, |
565 | .ctrls = sd_ctrls, | 485 | .ctrls = sd_ctrls, |
566 | .nctrls = ARRAY_SIZE(sd_ctrls), | 486 | .nctrls = NCTRLS, |
567 | .config = sd_config, | 487 | .config = sd_config, |
568 | .init = sd_init, | 488 | .init = sd_init, |
569 | .start = sd_start, | 489 | .start = sd_start, |
@@ -603,17 +523,11 @@ static struct usb_driver sd_driver = { | |||
603 | /* -- module insert / remove -- */ | 523 | /* -- module insert / remove -- */ |
604 | static int __init sd_mod_init(void) | 524 | static int __init sd_mod_init(void) |
605 | { | 525 | { |
606 | int ret; | 526 | return usb_register(&sd_driver); |
607 | ret = usb_register(&sd_driver); | ||
608 | if (ret < 0) | ||
609 | return ret; | ||
610 | info("registered"); | ||
611 | return 0; | ||
612 | } | 527 | } |
613 | static void __exit sd_mod_exit(void) | 528 | static void __exit sd_mod_exit(void) |
614 | { | 529 | { |
615 | usb_deregister(&sd_driver); | 530 | usb_deregister(&sd_driver); |
616 | info("deregistered"); | ||
617 | } | 531 | } |
618 | 532 | ||
619 | module_init(sd_mod_init); | 533 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c index e50dd7693f7..b199ad4666b 100644 --- a/drivers/media/video/gspca/stv0680.c +++ b/drivers/media/video/gspca/stv0680.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * STV0680 USB Camera Driver | 2 | * STV0680 USB Camera Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> | 4 | * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> |
5 | * | 5 | * |
6 | * This module is adapted from the in kernel v4l1 stv680 driver: | 6 | * This module is adapted from the in kernel v4l1 stv680 driver: |
7 | * | 7 | * |
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | #include "gspca.h" | 32 | #include "gspca.h" |
33 | 33 | ||
34 | MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>"); | 34 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
35 | MODULE_DESCRIPTION("STV0680 USB Camera Driver"); | 35 | MODULE_DESCRIPTION("STV0680 USB Camera Driver"); |
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | 37 | ||
@@ -79,8 +79,7 @@ static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, | |||
79 | val, 0, gspca_dev->usb_buf, size, 500); | 79 | val, 0, gspca_dev->usb_buf, size, 500); |
80 | 80 | ||
81 | if ((ret < 0) && (req != 0x0a)) | 81 | if ((ret < 0) && (req != 0x0a)) |
82 | PDEBUG(D_ERR, | 82 | err("usb_control_msg error %i, request = 0x%x, error = %i", |
83 | "usb_control_msg error %i, request = 0x%x, error = %i", | ||
84 | set, req, ret); | 83 | set, req, ret); |
85 | 84 | ||
86 | return ret; | 85 | return ret; |
@@ -237,7 +236,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
237 | 236 | ||
238 | if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 || | 237 | if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 || |
239 | gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) { | 238 | gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) { |
240 | PDEBUG(D_ERR, "Could not get descriptor 0100."); | 239 | err("Could not get descriptor 0100."); |
241 | return stv0680_handle_error(gspca_dev, -EIO); | 240 | return stv0680_handle_error(gspca_dev, -EIO); |
242 | } | 241 | } |
243 | 242 | ||
@@ -357,17 +356,11 @@ static struct usb_driver sd_driver = { | |||
357 | /* -- module insert / remove -- */ | 356 | /* -- module insert / remove -- */ |
358 | static int __init sd_mod_init(void) | 357 | static int __init sd_mod_init(void) |
359 | { | 358 | { |
360 | int ret; | 359 | return usb_register(&sd_driver); |
361 | ret = usb_register(&sd_driver); | ||
362 | if (ret < 0) | ||
363 | return ret; | ||
364 | PDEBUG(D_PROBE, "registered"); | ||
365 | return 0; | ||
366 | } | 360 | } |
367 | static void __exit sd_mod_exit(void) | 361 | static void __exit sd_mod_exit(void) |
368 | { | 362 | { |
369 | usb_deregister(&sd_driver); | 363 | usb_deregister(&sd_driver); |
370 | PDEBUG(D_PROBE, "deregistered"); | ||
371 | } | 364 | } |
372 | 365 | ||
373 | module_init(sd_mod_init); | 366 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 14f179a1948..086de44a6e5 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c | |||
@@ -189,7 +189,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value) | |||
189 | 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, | 189 | 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, |
190 | STV06XX_URB_MSG_TIMEOUT); | 190 | STV06XX_URB_MSG_TIMEOUT); |
191 | if (err < 0) { | 191 | if (err < 0) { |
192 | PDEBUG(D_ERR, "I2C: Read error writing address: %d", err); | 192 | err("I2C: Read error writing address: %d", err); |
193 | return err; | 193 | return err; |
194 | } | 194 | } |
195 | 195 | ||
@@ -428,7 +428,7 @@ frame_data: | |||
428 | } | 428 | } |
429 | } | 429 | } |
430 | 430 | ||
431 | #ifdef CONFIG_INPUT | 431 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
432 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 432 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
433 | u8 *data, /* interrupt packet data */ | 433 | u8 *data, /* interrupt packet data */ |
434 | int len) /* interrupt packet length */ | 434 | int len) /* interrupt packet length */ |
@@ -462,7 +462,7 @@ static const struct sd_desc sd_desc = { | |||
462 | .start = stv06xx_start, | 462 | .start = stv06xx_start, |
463 | .stopN = stv06xx_stopN, | 463 | .stopN = stv06xx_stopN, |
464 | .pkt_scan = stv06xx_pkt_scan, | 464 | .pkt_scan = stv06xx_pkt_scan, |
465 | #ifdef CONFIG_INPUT | 465 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
466 | .int_pkt_scan = sd_int_pkt_scan, | 466 | .int_pkt_scan = sd_int_pkt_scan, |
467 | #endif | 467 | #endif |
468 | }; | 468 | }; |
@@ -562,17 +562,11 @@ static struct usb_driver sd_driver = { | |||
562 | /* -- module insert / remove -- */ | 562 | /* -- module insert / remove -- */ |
563 | static int __init sd_mod_init(void) | 563 | static int __init sd_mod_init(void) |
564 | { | 564 | { |
565 | int ret; | 565 | return usb_register(&sd_driver); |
566 | ret = usb_register(&sd_driver); | ||
567 | if (ret < 0) | ||
568 | return ret; | ||
569 | PDEBUG(D_PROBE, "registered"); | ||
570 | return 0; | ||
571 | } | 566 | } |
572 | static void __exit sd_mod_exit(void) | 567 | static void __exit sd_mod_exit(void) |
573 | { | 568 | { |
574 | usb_deregister(&sd_driver); | 569 | usb_deregister(&sd_driver); |
575 | PDEBUG(D_PROBE, "deregistered"); | ||
576 | } | 570 | } |
577 | 571 | ||
578 | module_init(sd_mod_init); | 572 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h index 053a27e3a40..e0f63c51f40 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx.h | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #define STV_ISOC_ENDPOINT_ADDR 0x81 | 38 | #define STV_ISOC_ENDPOINT_ADDR 0x81 |
39 | 39 | ||
40 | #define STV_REG23 0x0423 | 40 | #define STV_REG23 0x0423 |
41 | 41 | ||
42 | /* Control registers of the STV0600 ASIC */ | 42 | /* Control registers of the STV0600 ASIC */ |
43 | #define STV_I2C_PARTNER 0x1420 | 43 | #define STV_I2C_PARTNER 0x1420 |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index 706e08dc525..17531b41a07 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c | |||
@@ -39,8 +39,8 @@ static const struct ctrl hdcs1x00_ctrl[] = { | |||
39 | .minimum = 0x00, | 39 | .minimum = 0x00, |
40 | .maximum = 0xff, | 40 | .maximum = 0xff, |
41 | .step = 0x1, | 41 | .step = 0x1, |
42 | .default_value = HDCS_DEFAULT_EXPOSURE, | 42 | .default_value = HDCS_DEFAULT_EXPOSURE, |
43 | .flags = V4L2_CTRL_FLAG_SLIDER | 43 | .flags = V4L2_CTRL_FLAG_SLIDER |
44 | }, | 44 | }, |
45 | .set = hdcs_set_exposure, | 45 | .set = hdcs_set_exposure, |
46 | .get = hdcs_get_exposure | 46 | .get = hdcs_get_exposure |
@@ -52,8 +52,8 @@ static const struct ctrl hdcs1x00_ctrl[] = { | |||
52 | .minimum = 0x00, | 52 | .minimum = 0x00, |
53 | .maximum = 0xff, | 53 | .maximum = 0xff, |
54 | .step = 0x1, | 54 | .step = 0x1, |
55 | .default_value = HDCS_DEFAULT_GAIN, | 55 | .default_value = HDCS_DEFAULT_GAIN, |
56 | .flags = V4L2_CTRL_FLAG_SLIDER | 56 | .flags = V4L2_CTRL_FLAG_SLIDER |
57 | }, | 57 | }, |
58 | .set = hdcs_set_gain, | 58 | .set = hdcs_set_gain, |
59 | .get = hdcs_get_gain | 59 | .get = hdcs_get_gain |
@@ -83,8 +83,8 @@ static const struct ctrl hdcs1020_ctrl[] = { | |||
83 | .minimum = 0x00, | 83 | .minimum = 0x00, |
84 | .maximum = 0xffff, | 84 | .maximum = 0xffff, |
85 | .step = 0x1, | 85 | .step = 0x1, |
86 | .default_value = HDCS_DEFAULT_EXPOSURE, | 86 | .default_value = HDCS_DEFAULT_EXPOSURE, |
87 | .flags = V4L2_CTRL_FLAG_SLIDER | 87 | .flags = V4L2_CTRL_FLAG_SLIDER |
88 | }, | 88 | }, |
89 | .set = hdcs_set_exposure, | 89 | .set = hdcs_set_exposure, |
90 | .get = hdcs_get_exposure | 90 | .get = hdcs_get_exposure |
@@ -96,8 +96,8 @@ static const struct ctrl hdcs1020_ctrl[] = { | |||
96 | .minimum = 0x00, | 96 | .minimum = 0x00, |
97 | .maximum = 0xff, | 97 | .maximum = 0xff, |
98 | .step = 0x1, | 98 | .step = 0x1, |
99 | .default_value = HDCS_DEFAULT_GAIN, | 99 | .default_value = HDCS_DEFAULT_GAIN, |
100 | .flags = V4L2_CTRL_FLAG_SLIDER | 100 | .flags = V4L2_CTRL_FLAG_SLIDER |
101 | }, | 101 | }, |
102 | .set = hdcs_set_gain, | 102 | .set = hdcs_set_gain, |
103 | .get = hdcs_get_gain | 103 | .get = hdcs_get_gain |
@@ -163,7 +163,8 @@ static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) | |||
163 | for (i = 0; i < len; i++) { | 163 | for (i = 0; i < len; i++) { |
164 | regs[2 * i] = reg; | 164 | regs[2 * i] = reg; |
165 | regs[2 * i + 1] = vals[i]; | 165 | regs[2 * i + 1] = vals[i]; |
166 | /* All addresses are shifted left one bit as bit 0 toggles r/w */ | 166 | /* All addresses are shifted left one bit |
167 | * as bit 0 toggles r/w */ | ||
167 | reg += 2; | 168 | reg += 2; |
168 | } | 169 | } |
169 | 170 | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h index 37b31c99d95..cf3d0ccc112 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h | |||
@@ -37,7 +37,7 @@ | |||
37 | #define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL) | 37 | #define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL) |
38 | 38 | ||
39 | #define HDCS_1X00_DEF_WIDTH 360 | 39 | #define HDCS_1X00_DEF_WIDTH 360 |
40 | #define HDCS_1X00_DEF_HEIGHT 296 | 40 | #define HDCS_1X00_DEF_HEIGHT 296 |
41 | 41 | ||
42 | #define HDCS_1020_DEF_WIDTH 352 | 42 | #define HDCS_1020_DEF_WIDTH 352 |
43 | #define HDCS_1020_DEF_HEIGHT 292 | 43 | #define HDCS_1020_DEF_HEIGHT 292 |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c index c11f06e4ae7..3af53264a36 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c | |||
@@ -246,7 +246,7 @@ static int st6422_start(struct sd *sd) | |||
246 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | 246 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); |
247 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 247 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
248 | if (!alt) { | 248 | if (!alt) { |
249 | PDEBUG(D_ERR, "Couldn't get altsetting"); | 249 | err("Couldn't get altsetting"); |
250 | return -EIO; | 250 | return -EIO; |
251 | } | 251 | } |
252 | 252 | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index 11a0c002f5d..f8398434c32 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | |||
@@ -66,7 +66,7 @@ static const struct ctrl vv6410_ctrl[] = { | |||
66 | .minimum = 0, | 66 | .minimum = 0, |
67 | .maximum = 1, | 67 | .maximum = 1, |
68 | .step = 1, | 68 | .step = 1, |
69 | .default_value = 0 | 69 | .default_value = 0 |
70 | }, | 70 | }, |
71 | .set = vv6410_set_vflip, | 71 | .set = vv6410_set_vflip, |
72 | .get = vv6410_get_vflip | 72 | .get = vv6410_get_vflip |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 96c61926d37..b3b5508473b 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -157,8 +157,8 @@ | |||
157 | /* Audio Amplifier Setup Register */ | 157 | /* Audio Amplifier Setup Register */ |
158 | #define VV6410_AT1 0x79 | 158 | #define VV6410_AT1 0x79 |
159 | 159 | ||
160 | #define VV6410_HFLIP (1 << 3) | 160 | #define VV6410_HFLIP (1 << 3) |
161 | #define VV6410_VFLIP (1 << 4) | 161 | #define VV6410_VFLIP (1 << 4) |
162 | 162 | ||
163 | #define VV6410_LOW_POWER_MODE (1 << 0) | 163 | #define VV6410_LOW_POWER_MODE (1 << 0) |
164 | #define VV6410_SOFT_RESET (1 << 2) | 164 | #define VV6410_SOFT_RESET (1 << 2) |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 9494f86b9a8..a9cbcd6011d 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -343,7 +343,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
343 | len ? gspca_dev->usb_buf : NULL, len, | 343 | len ? gspca_dev->usb_buf : NULL, len, |
344 | 500); | 344 | 500); |
345 | if (ret < 0) { | 345 | if (ret < 0) { |
346 | PDEBUG(D_ERR, "reg_r err %d", ret); | 346 | err("reg_r err %d", ret); |
347 | gspca_dev->usb_err = ret; | 347 | gspca_dev->usb_err = ret; |
348 | } | 348 | } |
349 | } | 349 | } |
@@ -368,7 +368,7 @@ static void reg_w_1(struct gspca_dev *gspca_dev, | |||
368 | gspca_dev->usb_buf, 1, | 368 | gspca_dev->usb_buf, 1, |
369 | 500); | 369 | 500); |
370 | if (ret < 0) { | 370 | if (ret < 0) { |
371 | PDEBUG(D_ERR, "reg_w_1 err %d", ret); | 371 | err("reg_w_1 err %d", ret); |
372 | gspca_dev->usb_err = ret; | 372 | gspca_dev->usb_err = ret; |
373 | } | 373 | } |
374 | } | 374 | } |
@@ -388,7 +388,7 @@ static void reg_w_riv(struct gspca_dev *gspca_dev, | |||
388 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 388 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
389 | value, index, NULL, 0, 500); | 389 | value, index, NULL, 0, 500); |
390 | if (ret < 0) { | 390 | if (ret < 0) { |
391 | PDEBUG(D_ERR, "reg_w_riv err %d", ret); | 391 | err("reg_w_riv err %d", ret); |
392 | gspca_dev->usb_err = ret; | 392 | gspca_dev->usb_err = ret; |
393 | return; | 393 | return; |
394 | } | 394 | } |
@@ -413,7 +413,7 @@ static u8 reg_r_1(struct gspca_dev *gspca_dev, | |||
413 | gspca_dev->usb_buf, 1, | 413 | gspca_dev->usb_buf, 1, |
414 | 500); /* timeout */ | 414 | 500); /* timeout */ |
415 | if (ret < 0) { | 415 | if (ret < 0) { |
416 | PDEBUG(D_ERR, "reg_r_1 err %d", ret); | 416 | err("reg_r_1 err %d", ret); |
417 | gspca_dev->usb_err = ret; | 417 | gspca_dev->usb_err = ret; |
418 | return 0; | 418 | return 0; |
419 | } | 419 | } |
@@ -440,7 +440,7 @@ static u16 reg_r_12(struct gspca_dev *gspca_dev, | |||
440 | gspca_dev->usb_buf, length, | 440 | gspca_dev->usb_buf, length, |
441 | 500); | 441 | 500); |
442 | if (ret < 0) { | 442 | if (ret < 0) { |
443 | PDEBUG(D_ERR, "reg_r_12 err %d", ret); | 443 | err("reg_r_12 err %d", ret); |
444 | gspca_dev->usb_err = ret; | 444 | gspca_dev->usb_err = ret; |
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
@@ -463,7 +463,7 @@ static void setup_qtable(struct gspca_dev *gspca_dev, | |||
463 | 463 | ||
464 | /* loop over y components */ | 464 | /* loop over y components */ |
465 | for (i = 0; i < 64; i++) | 465 | for (i = 0; i < 64; i++) |
466 | reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]); | 466 | reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]); |
467 | 467 | ||
468 | /* loop over c components */ | 468 | /* loop over c components */ |
469 | for (i = 0; i < 64; i++) | 469 | for (i = 0; i < 64; i++) |
@@ -712,8 +712,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
712 | sd->subtype = id->driver_info; | 712 | sd->subtype = id->driver_info; |
713 | 713 | ||
714 | if (sd->subtype == AiptekMiniPenCam13) { | 714 | if (sd->subtype == AiptekMiniPenCam13) { |
715 | /* try to get the firmware as some cam answer 2.0.1.2.2 | 715 | |
716 | * and should be a spca504b then overwrite that setting */ | 716 | /* try to get the firmware as some cam answer 2.0.1.2.2 |
717 | * and should be a spca504b then overwrite that setting */ | ||
717 | reg_r(gspca_dev, 0x20, 0, 1); | 718 | reg_r(gspca_dev, 0x20, 0, 1); |
718 | switch (gspca_dev->usb_buf[0]) { | 719 | switch (gspca_dev->usb_buf[0]) { |
719 | case 1: | 720 | case 1: |
@@ -733,7 +734,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
733 | /* case BRIDGE_SPCA504: */ | 734 | /* case BRIDGE_SPCA504: */ |
734 | /* case BRIDGE_SPCA536: */ | 735 | /* case BRIDGE_SPCA536: */ |
735 | cam->cam_mode = vga_mode; | 736 | cam->cam_mode = vga_mode; |
736 | cam->nmodes =ARRAY_SIZE(vga_mode); | 737 | cam->nmodes = ARRAY_SIZE(vga_mode); |
737 | break; | 738 | break; |
738 | case BRIDGE_SPCA533: | 739 | case BRIDGE_SPCA533: |
739 | cam->cam_mode = custom_mode; | 740 | cam->cam_mode = custom_mode; |
@@ -1247,17 +1248,11 @@ static struct usb_driver sd_driver = { | |||
1247 | /* -- module insert / remove -- */ | 1248 | /* -- module insert / remove -- */ |
1248 | static int __init sd_mod_init(void) | 1249 | static int __init sd_mod_init(void) |
1249 | { | 1250 | { |
1250 | int ret; | 1251 | return usb_register(&sd_driver); |
1251 | ret = usb_register(&sd_driver); | ||
1252 | if (ret < 0) | ||
1253 | return ret; | ||
1254 | PDEBUG(D_PROBE, "registered"); | ||
1255 | return 0; | ||
1256 | } | 1252 | } |
1257 | static void __exit sd_mod_exit(void) | 1253 | static void __exit sd_mod_exit(void) |
1258 | { | 1254 | { |
1259 | usb_deregister(&sd_driver); | 1255 | usb_deregister(&sd_driver); |
1260 | PDEBUG(D_PROBE, "deregistered"); | ||
1261 | } | 1256 | } |
1262 | 1257 | ||
1263 | module_init(sd_mod_init); | 1258 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 3b3b983f2b9..b45f4d0f399 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -892,7 +892,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
892 | sd->sensor = SENSOR_OM6802; | 892 | sd->sensor = SENSOR_OM6802; |
893 | break; | 893 | break; |
894 | default: | 894 | default: |
895 | PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id); | 895 | err("unknown sensor %04x", sensor_id); |
896 | return -EINVAL; | 896 | return -EINVAL; |
897 | } | 897 | } |
898 | 898 | ||
@@ -1444,17 +1444,11 @@ static struct usb_driver sd_driver = { | |||
1444 | /* -- module insert / remove -- */ | 1444 | /* -- module insert / remove -- */ |
1445 | static int __init sd_mod_init(void) | 1445 | static int __init sd_mod_init(void) |
1446 | { | 1446 | { |
1447 | int ret; | 1447 | return usb_register(&sd_driver); |
1448 | ret = usb_register(&sd_driver); | ||
1449 | if (ret < 0) | ||
1450 | return ret; | ||
1451 | PDEBUG(D_PROBE, "registered"); | ||
1452 | return 0; | ||
1453 | } | 1448 | } |
1454 | static void __exit sd_mod_exit(void) | 1449 | static void __exit sd_mod_exit(void) |
1455 | { | 1450 | { |
1456 | usb_deregister(&sd_driver); | 1451 | usb_deregister(&sd_driver); |
1457 | PDEBUG(D_PROBE, "deregistered"); | ||
1458 | } | 1452 | } |
1459 | 1453 | ||
1460 | module_init(sd_mod_init); | 1454 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index d9c5bf3449d..d9e3c605078 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -421,18 +421,12 @@ static struct usb_driver sd_driver = { | |||
421 | /* -- module insert / remove -- */ | 421 | /* -- module insert / remove -- */ |
422 | static int __init sd_mod_init(void) | 422 | static int __init sd_mod_init(void) |
423 | { | 423 | { |
424 | int ret; | 424 | return usb_register(&sd_driver); |
425 | ret = usb_register(&sd_driver); | ||
426 | if (ret < 0) | ||
427 | return ret; | ||
428 | PDEBUG(D_PROBE, "registered"); | ||
429 | return 0; | ||
430 | } | 425 | } |
431 | 426 | ||
432 | static void __exit sd_mod_exit(void) | 427 | static void __exit sd_mod_exit(void) |
433 | { | 428 | { |
434 | usb_deregister(&sd_driver); | 429 | usb_deregister(&sd_driver); |
435 | PDEBUG(D_PROBE, "deregistered"); | ||
436 | } | 430 | } |
437 | 431 | ||
438 | module_init(sd_mod_init); | 432 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index b16fd47e8ce..38a6efe1a5f 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -3164,7 +3164,7 @@ static void reg_r_i(struct gspca_dev *gspca_dev, | |||
3164 | index, gspca_dev->usb_buf, len, | 3164 | index, gspca_dev->usb_buf, len, |
3165 | 500); | 3165 | 500); |
3166 | if (ret < 0) { | 3166 | if (ret < 0) { |
3167 | PDEBUG(D_ERR, "reg_r err %d", ret); | 3167 | err("reg_r err %d", ret); |
3168 | gspca_dev->usb_err = ret; | 3168 | gspca_dev->usb_err = ret; |
3169 | } | 3169 | } |
3170 | } | 3170 | } |
@@ -3205,7 +3205,7 @@ static void reg_w_i(struct gspca_dev *gspca_dev, | |||
3205 | value, index, NULL, 0, | 3205 | value, index, NULL, 0, |
3206 | 500); | 3206 | 500); |
3207 | if (ret < 0) { | 3207 | if (ret < 0) { |
3208 | PDEBUG(D_ERR, "reg_w err %d", ret); | 3208 | err("reg_w err %d", ret); |
3209 | gspca_dev->usb_err = ret; | 3209 | gspca_dev->usb_err = ret; |
3210 | } | 3210 | } |
3211 | } | 3211 | } |
@@ -3230,7 +3230,7 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev, | |||
3230 | 3230 | ||
3231 | reg_r(gspca_dev, 0xa1, 0xb33f, 1); | 3231 | reg_r(gspca_dev, 0xa1, 0xb33f, 1); |
3232 | if (!(gspca_dev->usb_buf[0] & 0x02)) { | 3232 | if (!(gspca_dev->usb_buf[0] & 0x02)) { |
3233 | PDEBUG(D_ERR, "I2c Bus Busy Wait %02x", | 3233 | err("I2c Bus Busy Wait %02x", |
3234 | gspca_dev->usb_buf[0]); | 3234 | gspca_dev->usb_buf[0]); |
3235 | return 0; | 3235 | return 0; |
3236 | } | 3236 | } |
@@ -3344,7 +3344,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, | |||
3344 | msleep(20); | 3344 | msleep(20); |
3345 | } while (--retry > 0); | 3345 | } while (--retry > 0); |
3346 | if (retry <= 0) | 3346 | if (retry <= 0) |
3347 | PDEBUG(D_ERR, "i2c_write timeout"); | 3347 | err("i2c_write timeout"); |
3348 | } | 3348 | } |
3349 | 3349 | ||
3350 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, | 3350 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, |
@@ -3440,7 +3440,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3440 | 3440 | ||
3441 | switch (sensor) { | 3441 | switch (sensor) { |
3442 | case -1: | 3442 | case -1: |
3443 | PDEBUG(D_PROBE, "Unknown sensor..."); | 3443 | err("Unknown sensor..."); |
3444 | return -EINVAL; | 3444 | return -EINVAL; |
3445 | case SENSOR_HV7131R: | 3445 | case SENSOR_HV7131R: |
3446 | PDEBUG(D_PROBE, "Find Sensor HV7131R"); | 3446 | PDEBUG(D_PROBE, "Find Sensor HV7131R"); |
@@ -4226,18 +4226,11 @@ static struct usb_driver sd_driver = { | |||
4226 | /* -- module insert / remove -- */ | 4226 | /* -- module insert / remove -- */ |
4227 | static int __init sd_mod_init(void) | 4227 | static int __init sd_mod_init(void) |
4228 | { | 4228 | { |
4229 | int ret; | 4229 | return usb_register(&sd_driver); |
4230 | |||
4231 | ret = usb_register(&sd_driver); | ||
4232 | if (ret < 0) | ||
4233 | return ret; | ||
4234 | PDEBUG(D_PROBE, "registered"); | ||
4235 | return 0; | ||
4236 | } | 4230 | } |
4237 | static void __exit sd_mod_exit(void) | 4231 | static void __exit sd_mod_exit(void) |
4238 | { | 4232 | { |
4239 | usb_deregister(&sd_driver); | 4233 | usb_deregister(&sd_driver); |
4240 | PDEBUG(D_PROBE, "deregistered"); | ||
4241 | } | 4234 | } |
4242 | 4235 | ||
4243 | module_init(sd_mod_init); | 4236 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 38a68591ce4..4066ac8c45a 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c | |||
@@ -67,7 +67,7 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value); | |||
67 | --------------------------------------------------------------------------*/ | 67 | --------------------------------------------------------------------------*/ |
68 | static int w9968cf_write_fsb(struct sd *sd, u16* data) | 68 | static int w9968cf_write_fsb(struct sd *sd, u16* data) |
69 | { | 69 | { |
70 | struct usb_device* udev = sd->gspca_dev.dev; | 70 | struct usb_device *udev = sd->gspca_dev.dev; |
71 | u16 value; | 71 | u16 value; |
72 | int ret; | 72 | int ret; |
73 | 73 | ||
@@ -78,7 +78,7 @@ static int w9968cf_write_fsb(struct sd *sd, u16* data) | |||
78 | USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, | 78 | USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, |
79 | value, 0x06, sd->gspca_dev.usb_buf, 6, 500); | 79 | value, 0x06, sd->gspca_dev.usb_buf, 6, 500); |
80 | if (ret < 0) { | 80 | if (ret < 0) { |
81 | PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret); | 81 | err("Write FSB registers failed (%d)", ret); |
82 | return ret; | 82 | return ret; |
83 | } | 83 | } |
84 | 84 | ||
@@ -104,7 +104,7 @@ static int w9968cf_write_sb(struct sd *sd, u16 value) | |||
104 | udelay(W9968CF_I2C_BUS_DELAY); | 104 | udelay(W9968CF_I2C_BUS_DELAY); |
105 | 105 | ||
106 | if (ret < 0) { | 106 | if (ret < 0) { |
107 | PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value); | 107 | err("Write SB reg [01] %04x failed", value); |
108 | return ret; | 108 | return ret; |
109 | } | 109 | } |
110 | 110 | ||
@@ -130,7 +130,7 @@ static int w9968cf_read_sb(struct sd *sd) | |||
130 | ret = sd->gspca_dev.usb_buf[0] | | 130 | ret = sd->gspca_dev.usb_buf[0] | |
131 | (sd->gspca_dev.usb_buf[1] << 8); | 131 | (sd->gspca_dev.usb_buf[1] << 8); |
132 | else | 132 | else |
133 | PDEBUG(D_ERR, "Read SB reg [01] failed"); | 133 | err("Read SB reg [01] failed"); |
134 | 134 | ||
135 | udelay(W9968CF_I2C_BUS_DELAY); | 135 | udelay(W9968CF_I2C_BUS_DELAY); |
136 | 136 | ||
@@ -437,7 +437,7 @@ static int w9968cf_set_crop_window(struct sd *sd) | |||
437 | if (sd->sensor == SEN_OV7620) { | 437 | if (sd->sensor == SEN_OV7620) { |
438 | /* Sigh, this is dependend on the clock / framerate changes | 438 | /* Sigh, this is dependend on the clock / framerate changes |
439 | made by the frequency control, sick. */ | 439 | made by the frequency control, sick. */ |
440 | if (sd->freq == 1) { | 440 | if (sd->ctrls[FREQ].val == 1) { |
441 | start_cropx = 277; | 441 | start_cropx = 277; |
442 | start_cropy = 37; | 442 | start_cropy = 37; |
443 | } else { | 443 | } else { |
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c new file mode 100644 index 00000000000..8715577bc2d --- /dev/null +++ b/drivers/media/video/gspca/xirlink_cit.c | |||
@@ -0,0 +1,3253 @@ | |||
1 | /* | ||
2 | * USB IBM C-It Video Camera driver | ||
3 | * | ||
4 | * Supports Xirlink C-It Video Camera, IBM PC Camera, | ||
5 | * IBM NetCamera and Veo Stingray. | ||
6 | * | ||
7 | * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> | ||
8 | * | ||
9 | * This driver is based on earlier work of: | ||
10 | * | ||
11 | * (C) Copyright 1999 Johannes Erdfelt | ||
12 | * (C) Copyright 1999 Randy Dunlap | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #define MODULE_NAME "xirlink-cit" | ||
31 | |||
32 | #include "gspca.h" | ||
33 | |||
34 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
35 | MODULE_DESCRIPTION("Xirlink C-IT"); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | |||
38 | /* FIXME we should autodetect this */ | ||
39 | static int ibm_netcam_pro; | ||
40 | module_param(ibm_netcam_pro, int, 0); | ||
41 | MODULE_PARM_DESC(ibm_netcam_pro, | ||
42 | "Use IBM Netcamera Pro init sequences for Model 3 cams"); | ||
43 | |||
44 | /* FIXME this should be handled through the V4L2 input selection API */ | ||
45 | static int rca_input; | ||
46 | module_param(rca_input, int, 0644); | ||
47 | MODULE_PARM_DESC(rca_input, | ||
48 | "Use rca input instead of ccd sensor on Model 3 cams"); | ||
49 | |||
50 | /* specific webcam descriptor */ | ||
51 | struct sd { | ||
52 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
53 | u8 model; | ||
54 | #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */ | ||
55 | #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */ | ||
56 | #define CIT_MODEL2 2 /* ibmcam driver */ | ||
57 | #define CIT_MODEL3 3 | ||
58 | #define CIT_MODEL4 4 | ||
59 | #define CIT_IBM_NETCAM_PRO 5 | ||
60 | u8 input_index; | ||
61 | u8 stop_on_control_change; | ||
62 | u8 sof_read; | ||
63 | u8 sof_len; | ||
64 | u8 contrast; | ||
65 | u8 brightness; | ||
66 | u8 hue; | ||
67 | u8 sharpness; | ||
68 | u8 lighting; | ||
69 | u8 hflip; | ||
70 | }; | ||
71 | |||
72 | /* V4L2 controls supported by the driver */ | ||
73 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
74 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
75 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
76 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
77 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | static void sd_stop0(struct gspca_dev *gspca_dev); | ||
86 | |||
87 | static const struct ctrl sd_ctrls[] = { | ||
88 | #define SD_BRIGHTNESS 0 | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_BRIGHTNESS, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "Brightness", | ||
94 | .minimum = 0, | ||
95 | .maximum = 63, | ||
96 | .step = 1, | ||
97 | #define BRIGHTNESS_DEFAULT 32 | ||
98 | .default_value = BRIGHTNESS_DEFAULT, | ||
99 | .flags = 0, | ||
100 | }, | ||
101 | .set = sd_setbrightness, | ||
102 | .get = sd_getbrightness, | ||
103 | }, | ||
104 | #define SD_CONTRAST 1 | ||
105 | { | ||
106 | { | ||
107 | .id = V4L2_CID_CONTRAST, | ||
108 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
109 | .name = "contrast", | ||
110 | .minimum = 0, | ||
111 | .maximum = 20, | ||
112 | .step = 1, | ||
113 | #define CONTRAST_DEFAULT 10 | ||
114 | .default_value = CONTRAST_DEFAULT, | ||
115 | .flags = 0, | ||
116 | }, | ||
117 | .set = sd_setcontrast, | ||
118 | .get = sd_getcontrast, | ||
119 | }, | ||
120 | #define SD_HUE 2 | ||
121 | { | ||
122 | { | ||
123 | .id = V4L2_CID_HUE, | ||
124 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
125 | .name = "Hue", | ||
126 | .minimum = 0, | ||
127 | .maximum = 127, | ||
128 | .step = 1, | ||
129 | #define HUE_DEFAULT 63 | ||
130 | .default_value = HUE_DEFAULT, | ||
131 | .flags = 0, | ||
132 | }, | ||
133 | .set = sd_sethue, | ||
134 | .get = sd_gethue, | ||
135 | }, | ||
136 | #define SD_SHARPNESS 3 | ||
137 | { | ||
138 | { | ||
139 | .id = V4L2_CID_SHARPNESS, | ||
140 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
141 | .name = "Sharpness", | ||
142 | .minimum = 0, | ||
143 | .maximum = 6, | ||
144 | .step = 1, | ||
145 | #define SHARPNESS_DEFAULT 3 | ||
146 | .default_value = SHARPNESS_DEFAULT, | ||
147 | .flags = 0, | ||
148 | }, | ||
149 | .set = sd_setsharpness, | ||
150 | .get = sd_getsharpness, | ||
151 | }, | ||
152 | #define SD_LIGHTING 4 | ||
153 | { | ||
154 | { | ||
155 | .id = V4L2_CID_BACKLIGHT_COMPENSATION, | ||
156 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
157 | .name = "Lighting", | ||
158 | .minimum = 0, | ||
159 | .maximum = 2, | ||
160 | .step = 1, | ||
161 | #define LIGHTING_DEFAULT 1 | ||
162 | .default_value = LIGHTING_DEFAULT, | ||
163 | .flags = 0, | ||
164 | }, | ||
165 | .set = sd_setlighting, | ||
166 | .get = sd_getlighting, | ||
167 | }, | ||
168 | #define SD_HFLIP 5 | ||
169 | { | ||
170 | { | ||
171 | .id = V4L2_CID_HFLIP, | ||
172 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
173 | .name = "Mirror", | ||
174 | .minimum = 0, | ||
175 | .maximum = 1, | ||
176 | .step = 1, | ||
177 | #define HFLIP_DEFAULT 0 | ||
178 | .default_value = HFLIP_DEFAULT, | ||
179 | }, | ||
180 | .set = sd_sethflip, | ||
181 | .get = sd_gethflip, | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | static const struct v4l2_pix_format cif_yuv_mode[] = { | ||
186 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
187 | .bytesperline = 176, | ||
188 | .sizeimage = 176 * 144 * 3 / 2, | ||
189 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
190 | {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
191 | .bytesperline = 352, | ||
192 | .sizeimage = 352 * 288 * 3 / 2, | ||
193 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
194 | }; | ||
195 | |||
196 | static const struct v4l2_pix_format vga_yuv_mode[] = { | ||
197 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
198 | .bytesperline = 160, | ||
199 | .sizeimage = 160 * 120 * 3 / 2, | ||
200 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
201 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
202 | .bytesperline = 320, | ||
203 | .sizeimage = 320 * 240 * 3 / 2, | ||
204 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
205 | {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
206 | .bytesperline = 640, | ||
207 | .sizeimage = 640 * 480 * 3 / 2, | ||
208 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
209 | }; | ||
210 | |||
211 | static const struct v4l2_pix_format model0_mode[] = { | ||
212 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
213 | .bytesperline = 160, | ||
214 | .sizeimage = 160 * 120 * 3 / 2, | ||
215 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
216 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
217 | .bytesperline = 176, | ||
218 | .sizeimage = 176 * 144 * 3 / 2, | ||
219 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
220 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
221 | .bytesperline = 320, | ||
222 | .sizeimage = 320 * 240 * 3 / 2, | ||
223 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
224 | }; | ||
225 | |||
226 | static const struct v4l2_pix_format model2_mode[] = { | ||
227 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
228 | .bytesperline = 160, | ||
229 | .sizeimage = 160 * 120 * 3 / 2, | ||
230 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
231 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
232 | .bytesperline = 176, | ||
233 | .sizeimage = 176 * 144 * 3 / 2, | ||
234 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
235 | {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, | ||
236 | .bytesperline = 320, | ||
237 | .sizeimage = 320 * 240, | ||
238 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
239 | {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, | ||
240 | .bytesperline = 352, | ||
241 | .sizeimage = 352 * 288, | ||
242 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
243 | }; | ||
244 | |||
245 | /* | ||
246 | * 01.01.08 - Added for RCA video in support -LO | ||
247 | * This struct is used to init the Model3 cam to use the RCA video in port | ||
248 | * instead of the CCD sensor. | ||
249 | */ | ||
250 | static const u16 rca_initdata[][3] = { | ||
251 | {0, 0x0000, 0x010c}, | ||
252 | {0, 0x0006, 0x012c}, | ||
253 | {0, 0x0078, 0x012d}, | ||
254 | {0, 0x0046, 0x012f}, | ||
255 | {0, 0xd141, 0x0124}, | ||
256 | {0, 0x0000, 0x0127}, | ||
257 | {0, 0xfea8, 0x0124}, | ||
258 | {1, 0x0000, 0x0116}, | ||
259 | {0, 0x0064, 0x0116}, | ||
260 | {1, 0x0000, 0x0115}, | ||
261 | {0, 0x0003, 0x0115}, | ||
262 | {0, 0x0008, 0x0123}, | ||
263 | {0, 0x0000, 0x0117}, | ||
264 | {0, 0x0000, 0x0112}, | ||
265 | {0, 0x0080, 0x0100}, | ||
266 | {0, 0x0000, 0x0100}, | ||
267 | {1, 0x0000, 0x0116}, | ||
268 | {0, 0x0060, 0x0116}, | ||
269 | {0, 0x0002, 0x0112}, | ||
270 | {0, 0x0000, 0x0123}, | ||
271 | {0, 0x0001, 0x0117}, | ||
272 | {0, 0x0040, 0x0108}, | ||
273 | {0, 0x0019, 0x012c}, | ||
274 | {0, 0x0040, 0x0116}, | ||
275 | {0, 0x000a, 0x0115}, | ||
276 | {0, 0x000b, 0x0115}, | ||
277 | {0, 0x0078, 0x012d}, | ||
278 | {0, 0x0046, 0x012f}, | ||
279 | {0, 0xd141, 0x0124}, | ||
280 | {0, 0x0000, 0x0127}, | ||
281 | {0, 0xfea8, 0x0124}, | ||
282 | {0, 0x0064, 0x0116}, | ||
283 | {0, 0x0000, 0x0115}, | ||
284 | {0, 0x0001, 0x0115}, | ||
285 | {0, 0xffff, 0x0124}, | ||
286 | {0, 0xfff9, 0x0124}, | ||
287 | {0, 0x0086, 0x0127}, | ||
288 | {0, 0xfff8, 0x0124}, | ||
289 | {0, 0xfffd, 0x0124}, | ||
290 | {0, 0x00aa, 0x0127}, | ||
291 | {0, 0xfff8, 0x0124}, | ||
292 | {0, 0xfffd, 0x0124}, | ||
293 | {0, 0x0000, 0x0127}, | ||
294 | {0, 0xfff8, 0x0124}, | ||
295 | {0, 0xfffd, 0x0124}, | ||
296 | {0, 0xfffa, 0x0124}, | ||
297 | {0, 0xffff, 0x0124}, | ||
298 | {0, 0xfff9, 0x0124}, | ||
299 | {0, 0x0086, 0x0127}, | ||
300 | {0, 0xfff8, 0x0124}, | ||
301 | {0, 0xfffd, 0x0124}, | ||
302 | {0, 0x00f2, 0x0127}, | ||
303 | {0, 0xfff8, 0x0124}, | ||
304 | {0, 0xfffd, 0x0124}, | ||
305 | {0, 0x000f, 0x0127}, | ||
306 | {0, 0xfff8, 0x0124}, | ||
307 | {0, 0xfffd, 0x0124}, | ||
308 | {0, 0xfffa, 0x0124}, | ||
309 | {0, 0xffff, 0x0124}, | ||
310 | {0, 0xfff9, 0x0124}, | ||
311 | {0, 0x0086, 0x0127}, | ||
312 | {0, 0xfff8, 0x0124}, | ||
313 | {0, 0xfffd, 0x0124}, | ||
314 | {0, 0x00f8, 0x0127}, | ||
315 | {0, 0xfff8, 0x0124}, | ||
316 | {0, 0xfffd, 0x0124}, | ||
317 | {0, 0x00fc, 0x0127}, | ||
318 | {0, 0xfff8, 0x0124}, | ||
319 | {0, 0xfffd, 0x0124}, | ||
320 | {0, 0xfffa, 0x0124}, | ||
321 | {0, 0xffff, 0x0124}, | ||
322 | {0, 0xfff9, 0x0124}, | ||
323 | {0, 0x0086, 0x0127}, | ||
324 | {0, 0xfff8, 0x0124}, | ||
325 | {0, 0xfffd, 0x0124}, | ||
326 | {0, 0x00f9, 0x0127}, | ||
327 | {0, 0xfff8, 0x0124}, | ||
328 | {0, 0xfffd, 0x0124}, | ||
329 | {0, 0x003c, 0x0127}, | ||
330 | {0, 0xfff8, 0x0124}, | ||
331 | {0, 0xfffd, 0x0124}, | ||
332 | {0, 0xfffa, 0x0124}, | ||
333 | {0, 0xffff, 0x0124}, | ||
334 | {0, 0xfff9, 0x0124}, | ||
335 | {0, 0x0086, 0x0127}, | ||
336 | {0, 0xfff8, 0x0124}, | ||
337 | {0, 0xfffd, 0x0124}, | ||
338 | {0, 0x0027, 0x0127}, | ||
339 | {0, 0xfff8, 0x0124}, | ||
340 | {0, 0xfffd, 0x0124}, | ||
341 | {0, 0x0019, 0x0127}, | ||
342 | {0, 0xfff8, 0x0124}, | ||
343 | {0, 0xfffd, 0x0124}, | ||
344 | {0, 0xfffa, 0x0124}, | ||
345 | {0, 0xfff9, 0x0124}, | ||
346 | {0, 0x0086, 0x0127}, | ||
347 | {0, 0xfff8, 0x0124}, | ||
348 | {0, 0xfffd, 0x0124}, | ||
349 | {0, 0x0037, 0x0127}, | ||
350 | {0, 0xfff8, 0x0124}, | ||
351 | {0, 0xfffd, 0x0124}, | ||
352 | {0, 0x0000, 0x0127}, | ||
353 | {0, 0xfff8, 0x0124}, | ||
354 | {0, 0xfffd, 0x0124}, | ||
355 | {0, 0x0021, 0x0127}, | ||
356 | {0, 0xfff8, 0x0124}, | ||
357 | {0, 0xfffd, 0x0124}, | ||
358 | {0, 0xfffa, 0x0124}, | ||
359 | {0, 0xfff9, 0x0124}, | ||
360 | {0, 0x0086, 0x0127}, | ||
361 | {0, 0xfff8, 0x0124}, | ||
362 | {0, 0xfffd, 0x0124}, | ||
363 | {0, 0x0038, 0x0127}, | ||
364 | {0, 0xfff8, 0x0124}, | ||
365 | {0, 0xfffd, 0x0124}, | ||
366 | {0, 0x0006, 0x0127}, | ||
367 | {0, 0xfff8, 0x0124}, | ||
368 | {0, 0xfffd, 0x0124}, | ||
369 | {0, 0x0045, 0x0127}, | ||
370 | {0, 0xfff8, 0x0124}, | ||
371 | {0, 0xfffd, 0x0124}, | ||
372 | {0, 0xfffa, 0x0124}, | ||
373 | {0, 0xfff9, 0x0124}, | ||
374 | {0, 0x0086, 0x0127}, | ||
375 | {0, 0xfff8, 0x0124}, | ||
376 | {0, 0xfffd, 0x0124}, | ||
377 | {0, 0x0037, 0x0127}, | ||
378 | {0, 0xfff8, 0x0124}, | ||
379 | {0, 0xfffd, 0x0124}, | ||
380 | {0, 0x0001, 0x0127}, | ||
381 | {0, 0xfff8, 0x0124}, | ||
382 | {0, 0xfffd, 0x0124}, | ||
383 | {0, 0x002a, 0x0127}, | ||
384 | {0, 0xfff8, 0x0124}, | ||
385 | {0, 0xfffd, 0x0124}, | ||
386 | {0, 0xfffa, 0x0124}, | ||
387 | {0, 0xfff9, 0x0124}, | ||
388 | {0, 0x0086, 0x0127}, | ||
389 | {0, 0xfff8, 0x0124}, | ||
390 | {0, 0xfffd, 0x0124}, | ||
391 | {0, 0x0038, 0x0127}, | ||
392 | {0, 0xfff8, 0x0124}, | ||
393 | {0, 0xfffd, 0x0124}, | ||
394 | {0, 0x0000, 0x0127}, | ||
395 | {0, 0xfff8, 0x0124}, | ||
396 | {0, 0xfffd, 0x0124}, | ||
397 | {0, 0x000e, 0x0127}, | ||
398 | {0, 0xfff8, 0x0124}, | ||
399 | {0, 0xfffd, 0x0124}, | ||
400 | {0, 0xfffa, 0x0124}, | ||
401 | {0, 0xfff9, 0x0124}, | ||
402 | {0, 0x0086, 0x0127}, | ||
403 | {0, 0xfff8, 0x0124}, | ||
404 | {0, 0xfffd, 0x0124}, | ||
405 | {0, 0x0037, 0x0127}, | ||
406 | {0, 0xfff8, 0x0124}, | ||
407 | {0, 0xfffd, 0x0124}, | ||
408 | {0, 0x0001, 0x0127}, | ||
409 | {0, 0xfff8, 0x0124}, | ||
410 | {0, 0xfffd, 0x0124}, | ||
411 | {0, 0x002b, 0x0127}, | ||
412 | {0, 0xfff8, 0x0124}, | ||
413 | {0, 0xfffd, 0x0124}, | ||
414 | {0, 0xfffa, 0x0124}, | ||
415 | {0, 0xfff9, 0x0124}, | ||
416 | {0, 0x0086, 0x0127}, | ||
417 | {0, 0xfff8, 0x0124}, | ||
418 | {0, 0xfffd, 0x0124}, | ||
419 | {0, 0x0038, 0x0127}, | ||
420 | {0, 0xfff8, 0x0124}, | ||
421 | {0, 0xfffd, 0x0124}, | ||
422 | {0, 0x0001, 0x0127}, | ||
423 | {0, 0xfff8, 0x0124}, | ||
424 | {0, 0xfffd, 0x0124}, | ||
425 | {0, 0x00f4, 0x0127}, | ||
426 | {0, 0xfff8, 0x0124}, | ||
427 | {0, 0xfffd, 0x0124}, | ||
428 | {0, 0xfffa, 0x0124}, | ||
429 | {0, 0xfff9, 0x0124}, | ||
430 | {0, 0x0086, 0x0127}, | ||
431 | {0, 0xfff8, 0x0124}, | ||
432 | {0, 0xfffd, 0x0124}, | ||
433 | {0, 0x0037, 0x0127}, | ||
434 | {0, 0xfff8, 0x0124}, | ||
435 | {0, 0xfffd, 0x0124}, | ||
436 | {0, 0x0001, 0x0127}, | ||
437 | {0, 0xfff8, 0x0124}, | ||
438 | {0, 0xfffd, 0x0124}, | ||
439 | {0, 0x002c, 0x0127}, | ||
440 | {0, 0xfff8, 0x0124}, | ||
441 | {0, 0xfffd, 0x0124}, | ||
442 | {0, 0xfffa, 0x0124}, | ||
443 | {0, 0xfff9, 0x0124}, | ||
444 | {0, 0x0086, 0x0127}, | ||
445 | {0, 0xfff8, 0x0124}, | ||
446 | {0, 0xfffd, 0x0124}, | ||
447 | {0, 0x0038, 0x0127}, | ||
448 | {0, 0xfff8, 0x0124}, | ||
449 | {0, 0xfffd, 0x0124}, | ||
450 | {0, 0x0001, 0x0127}, | ||
451 | {0, 0xfff8, 0x0124}, | ||
452 | {0, 0xfffd, 0x0124}, | ||
453 | {0, 0x0004, 0x0127}, | ||
454 | {0, 0xfff8, 0x0124}, | ||
455 | {0, 0xfffd, 0x0124}, | ||
456 | {0, 0xfffa, 0x0124}, | ||
457 | {0, 0xfff9, 0x0124}, | ||
458 | {0, 0x0086, 0x0127}, | ||
459 | {0, 0xfff8, 0x0124}, | ||
460 | {0, 0xfffd, 0x0124}, | ||
461 | {0, 0x0037, 0x0127}, | ||
462 | {0, 0xfff8, 0x0124}, | ||
463 | {0, 0xfffd, 0x0124}, | ||
464 | {0, 0x0001, 0x0127}, | ||
465 | {0, 0xfff8, 0x0124}, | ||
466 | {0, 0xfffd, 0x0124}, | ||
467 | {0, 0x002d, 0x0127}, | ||
468 | {0, 0xfff8, 0x0124}, | ||
469 | {0, 0xfffd, 0x0124}, | ||
470 | {0, 0xfffa, 0x0124}, | ||
471 | {0, 0xfff9, 0x0124}, | ||
472 | {0, 0x0086, 0x0127}, | ||
473 | {0, 0xfff8, 0x0124}, | ||
474 | {0, 0xfffd, 0x0124}, | ||
475 | {0, 0x0038, 0x0127}, | ||
476 | {0, 0xfff8, 0x0124}, | ||
477 | {0, 0xfffd, 0x0124}, | ||
478 | {0, 0x0000, 0x0127}, | ||
479 | {0, 0xfff8, 0x0124}, | ||
480 | {0, 0xfffd, 0x0124}, | ||
481 | {0, 0x0014, 0x0127}, | ||
482 | {0, 0xfff8, 0x0124}, | ||
483 | {0, 0xfffd, 0x0124}, | ||
484 | {0, 0xfffa, 0x0124}, | ||
485 | {0, 0xfff9, 0x0124}, | ||
486 | {0, 0x0086, 0x0127}, | ||
487 | {0, 0xfff8, 0x0124}, | ||
488 | {0, 0xfffd, 0x0124}, | ||
489 | {0, 0x0037, 0x0127}, | ||
490 | {0, 0xfff8, 0x0124}, | ||
491 | {0, 0xfffd, 0x0124}, | ||
492 | {0, 0x0001, 0x0127}, | ||
493 | {0, 0xfff8, 0x0124}, | ||
494 | {0, 0xfffd, 0x0124}, | ||
495 | {0, 0x002e, 0x0127}, | ||
496 | {0, 0xfff8, 0x0124}, | ||
497 | {0, 0xfffd, 0x0124}, | ||
498 | {0, 0xfffa, 0x0124}, | ||
499 | {0, 0xfff9, 0x0124}, | ||
500 | {0, 0x0086, 0x0127}, | ||
501 | {0, 0xfff8, 0x0124}, | ||
502 | {0, 0xfffd, 0x0124}, | ||
503 | {0, 0x0038, 0x0127}, | ||
504 | {0, 0xfff8, 0x0124}, | ||
505 | {0, 0xfffd, 0x0124}, | ||
506 | {0, 0x0003, 0x0127}, | ||
507 | {0, 0xfff8, 0x0124}, | ||
508 | {0, 0xfffd, 0x0124}, | ||
509 | {0, 0x0000, 0x0127}, | ||
510 | {0, 0xfff8, 0x0124}, | ||
511 | {0, 0xfffd, 0x0124}, | ||
512 | {0, 0xfffa, 0x0124}, | ||
513 | {0, 0xfff9, 0x0124}, | ||
514 | {0, 0x0086, 0x0127}, | ||
515 | {0, 0xfff8, 0x0124}, | ||
516 | {0, 0xfffd, 0x0124}, | ||
517 | {0, 0x0037, 0x0127}, | ||
518 | {0, 0xfff8, 0x0124}, | ||
519 | {0, 0xfffd, 0x0124}, | ||
520 | {0, 0x0001, 0x0127}, | ||
521 | {0, 0xfff8, 0x0124}, | ||
522 | {0, 0xfffd, 0x0124}, | ||
523 | {0, 0x002f, 0x0127}, | ||
524 | {0, 0xfff8, 0x0124}, | ||
525 | {0, 0xfffd, 0x0124}, | ||
526 | {0, 0xfffa, 0x0124}, | ||
527 | {0, 0xfff9, 0x0124}, | ||
528 | {0, 0x0086, 0x0127}, | ||
529 | {0, 0xfff8, 0x0124}, | ||
530 | {0, 0xfffd, 0x0124}, | ||
531 | {0, 0x0038, 0x0127}, | ||
532 | {0, 0xfff8, 0x0124}, | ||
533 | {0, 0xfffd, 0x0124}, | ||
534 | {0, 0x0003, 0x0127}, | ||
535 | {0, 0xfff8, 0x0124}, | ||
536 | {0, 0xfffd, 0x0124}, | ||
537 | {0, 0x0014, 0x0127}, | ||
538 | {0, 0xfff8, 0x0124}, | ||
539 | {0, 0xfffd, 0x0124}, | ||
540 | {0, 0xfffa, 0x0124}, | ||
541 | {0, 0xfff9, 0x0124}, | ||
542 | {0, 0x0086, 0x0127}, | ||
543 | {0, 0xfff8, 0x0124}, | ||
544 | {0, 0xfffd, 0x0124}, | ||
545 | {0, 0x0037, 0x0127}, | ||
546 | {0, 0xfff8, 0x0124}, | ||
547 | {0, 0xfffd, 0x0124}, | ||
548 | {0, 0x0001, 0x0127}, | ||
549 | {0, 0xfff8, 0x0124}, | ||
550 | {0, 0xfffd, 0x0124}, | ||
551 | {0, 0x0040, 0x0127}, | ||
552 | {0, 0xfff8, 0x0124}, | ||
553 | {0, 0xfffd, 0x0124}, | ||
554 | {0, 0xfffa, 0x0124}, | ||
555 | {0, 0xfff9, 0x0124}, | ||
556 | {0, 0x0086, 0x0127}, | ||
557 | {0, 0xfff8, 0x0124}, | ||
558 | {0, 0xfffd, 0x0124}, | ||
559 | {0, 0x0038, 0x0127}, | ||
560 | {0, 0xfff8, 0x0124}, | ||
561 | {0, 0xfffd, 0x0124}, | ||
562 | {0, 0x0000, 0x0127}, | ||
563 | {0, 0xfff8, 0x0124}, | ||
564 | {0, 0xfffd, 0x0124}, | ||
565 | {0, 0x0040, 0x0127}, | ||
566 | {0, 0xfff8, 0x0124}, | ||
567 | {0, 0xfffd, 0x0124}, | ||
568 | {0, 0xfffa, 0x0124}, | ||
569 | {0, 0xfff9, 0x0124}, | ||
570 | {0, 0x0086, 0x0127}, | ||
571 | {0, 0xfff8, 0x0124}, | ||
572 | {0, 0xfffd, 0x0124}, | ||
573 | {0, 0x0037, 0x0127}, | ||
574 | {0, 0xfff8, 0x0124}, | ||
575 | {0, 0xfffd, 0x0124}, | ||
576 | {0, 0x0001, 0x0127}, | ||
577 | {0, 0xfff8, 0x0124}, | ||
578 | {0, 0xfffd, 0x0124}, | ||
579 | {0, 0x0053, 0x0127}, | ||
580 | {0, 0xfff8, 0x0124}, | ||
581 | {0, 0xfffd, 0x0124}, | ||
582 | {0, 0xfffa, 0x0124}, | ||
583 | {0, 0xfff9, 0x0124}, | ||
584 | {0, 0x0086, 0x0127}, | ||
585 | {0, 0xfff8, 0x0124}, | ||
586 | {0, 0xfffd, 0x0124}, | ||
587 | {0, 0x0038, 0x0127}, | ||
588 | {0, 0xfff8, 0x0124}, | ||
589 | {0, 0xfffd, 0x0124}, | ||
590 | {0, 0x0000, 0x0127}, | ||
591 | {0, 0xfff8, 0x0124}, | ||
592 | {0, 0xfffd, 0x0124}, | ||
593 | {0, 0x0038, 0x0127}, | ||
594 | {0, 0xfff8, 0x0124}, | ||
595 | {0, 0xfffd, 0x0124}, | ||
596 | {0, 0xfffa, 0x0124}, | ||
597 | {0, 0x0000, 0x0101}, | ||
598 | {0, 0x00a0, 0x0103}, | ||
599 | {0, 0x0078, 0x0105}, | ||
600 | {0, 0x0000, 0x010a}, | ||
601 | {0, 0x0024, 0x010b}, | ||
602 | {0, 0x0028, 0x0119}, | ||
603 | {0, 0x0088, 0x011b}, | ||
604 | {0, 0x0002, 0x011d}, | ||
605 | {0, 0x0003, 0x011e}, | ||
606 | {0, 0x0000, 0x0129}, | ||
607 | {0, 0x00fc, 0x012b}, | ||
608 | {0, 0x0008, 0x0102}, | ||
609 | {0, 0x0000, 0x0104}, | ||
610 | {0, 0x0008, 0x011a}, | ||
611 | {0, 0x0028, 0x011c}, | ||
612 | {0, 0x0021, 0x012a}, | ||
613 | {0, 0x0000, 0x0118}, | ||
614 | {0, 0x0000, 0x0132}, | ||
615 | {0, 0x0000, 0x0109}, | ||
616 | {0, 0xfff9, 0x0124}, | ||
617 | {0, 0x0086, 0x0127}, | ||
618 | {0, 0xfff8, 0x0124}, | ||
619 | {0, 0xfffd, 0x0124}, | ||
620 | {0, 0x0037, 0x0127}, | ||
621 | {0, 0xfff8, 0x0124}, | ||
622 | {0, 0xfffd, 0x0124}, | ||
623 | {0, 0x0001, 0x0127}, | ||
624 | {0, 0xfff8, 0x0124}, | ||
625 | {0, 0xfffd, 0x0124}, | ||
626 | {0, 0x0031, 0x0127}, | ||
627 | {0, 0xfff8, 0x0124}, | ||
628 | {0, 0xfffd, 0x0124}, | ||
629 | {0, 0xfffa, 0x0124}, | ||
630 | {0, 0xfff9, 0x0124}, | ||
631 | {0, 0x0086, 0x0127}, | ||
632 | {0, 0xfff8, 0x0124}, | ||
633 | {0, 0xfffd, 0x0124}, | ||
634 | {0, 0x0038, 0x0127}, | ||
635 | {0, 0xfff8, 0x0124}, | ||
636 | {0, 0xfffd, 0x0124}, | ||
637 | {0, 0x0000, 0x0127}, | ||
638 | {0, 0xfff8, 0x0124}, | ||
639 | {0, 0xfffd, 0x0124}, | ||
640 | {0, 0x0000, 0x0127}, | ||
641 | {0, 0xfff8, 0x0124}, | ||
642 | {0, 0xfffd, 0x0124}, | ||
643 | {0, 0xfffa, 0x0124}, | ||
644 | {0, 0xfff9, 0x0124}, | ||
645 | {0, 0x0086, 0x0127}, | ||
646 | {0, 0xfff8, 0x0124}, | ||
647 | {0, 0xfffd, 0x0124}, | ||
648 | {0, 0x0037, 0x0127}, | ||
649 | {0, 0xfff8, 0x0124}, | ||
650 | {0, 0xfffd, 0x0124}, | ||
651 | {0, 0x0001, 0x0127}, | ||
652 | {0, 0xfff8, 0x0124}, | ||
653 | {0, 0xfffd, 0x0124}, | ||
654 | {0, 0x0040, 0x0127}, | ||
655 | {0, 0xfff8, 0x0124}, | ||
656 | {0, 0xfffd, 0x0124}, | ||
657 | {0, 0xfffa, 0x0124}, | ||
658 | {0, 0xfff9, 0x0124}, | ||
659 | {0, 0x0086, 0x0127}, | ||
660 | {0, 0xfff8, 0x0124}, | ||
661 | {0, 0xfffd, 0x0124}, | ||
662 | {0, 0x0038, 0x0127}, | ||
663 | {0, 0xfff8, 0x0124}, | ||
664 | {0, 0xfffd, 0x0124}, | ||
665 | {0, 0x0000, 0x0127}, | ||
666 | {0, 0xfff8, 0x0124}, | ||
667 | {0, 0xfffd, 0x0124}, | ||
668 | {0, 0x0040, 0x0127}, | ||
669 | {0, 0xfff8, 0x0124}, | ||
670 | {0, 0xfffd, 0x0124}, | ||
671 | {0, 0xfffa, 0x0124}, | ||
672 | {0, 0xfff9, 0x0124}, | ||
673 | {0, 0x0086, 0x0127}, | ||
674 | {0, 0xfff8, 0x0124}, | ||
675 | {0, 0xfffd, 0x0124}, | ||
676 | {0, 0x0037, 0x0127}, | ||
677 | {0, 0xfff8, 0x0124}, | ||
678 | {0, 0xfffd, 0x0124}, | ||
679 | {0, 0x0000, 0x0127}, | ||
680 | {0, 0xfff8, 0x0124}, | ||
681 | {0, 0xfffd, 0x0124}, | ||
682 | {0, 0x00dc, 0x0127}, | ||
683 | {0, 0xfff8, 0x0124}, | ||
684 | {0, 0xfffd, 0x0124}, | ||
685 | {0, 0xfffa, 0x0124}, | ||
686 | {0, 0xfff9, 0x0124}, | ||
687 | {0, 0x0086, 0x0127}, | ||
688 | {0, 0xfff8, 0x0124}, | ||
689 | {0, 0xfffd, 0x0124}, | ||
690 | {0, 0x0038, 0x0127}, | ||
691 | {0, 0xfff8, 0x0124}, | ||
692 | {0, 0xfffd, 0x0124}, | ||
693 | {0, 0x0000, 0x0127}, | ||
694 | {0, 0xfff8, 0x0124}, | ||
695 | {0, 0xfffd, 0x0124}, | ||
696 | {0, 0x0000, 0x0127}, | ||
697 | {0, 0xfff8, 0x0124}, | ||
698 | {0, 0xfffd, 0x0124}, | ||
699 | {0, 0xfffa, 0x0124}, | ||
700 | {0, 0xfff9, 0x0124}, | ||
701 | {0, 0x0086, 0x0127}, | ||
702 | {0, 0xfff8, 0x0124}, | ||
703 | {0, 0xfffd, 0x0124}, | ||
704 | {0, 0x0037, 0x0127}, | ||
705 | {0, 0xfff8, 0x0124}, | ||
706 | {0, 0xfffd, 0x0124}, | ||
707 | {0, 0x0001, 0x0127}, | ||
708 | {0, 0xfff8, 0x0124}, | ||
709 | {0, 0xfffd, 0x0124}, | ||
710 | {0, 0x0032, 0x0127}, | ||
711 | {0, 0xfff8, 0x0124}, | ||
712 | {0, 0xfffd, 0x0124}, | ||
713 | {0, 0xfffa, 0x0124}, | ||
714 | {0, 0xfff9, 0x0124}, | ||
715 | {0, 0x0086, 0x0127}, | ||
716 | {0, 0xfff8, 0x0124}, | ||
717 | {0, 0xfffd, 0x0124}, | ||
718 | {0, 0x0038, 0x0127}, | ||
719 | {0, 0xfff8, 0x0124}, | ||
720 | {0, 0xfffd, 0x0124}, | ||
721 | {0, 0x0001, 0x0127}, | ||
722 | {0, 0xfff8, 0x0124}, | ||
723 | {0, 0xfffd, 0x0124}, | ||
724 | {0, 0x0020, 0x0127}, | ||
725 | {0, 0xfff8, 0x0124}, | ||
726 | {0, 0xfffd, 0x0124}, | ||
727 | {0, 0xfffa, 0x0124}, | ||
728 | {0, 0xfff9, 0x0124}, | ||
729 | {0, 0x0086, 0x0127}, | ||
730 | {0, 0xfff8, 0x0124}, | ||
731 | {0, 0xfffd, 0x0124}, | ||
732 | {0, 0x0037, 0x0127}, | ||
733 | {0, 0xfff8, 0x0124}, | ||
734 | {0, 0xfffd, 0x0124}, | ||
735 | {0, 0x0001, 0x0127}, | ||
736 | {0, 0xfff8, 0x0124}, | ||
737 | {0, 0xfffd, 0x0124}, | ||
738 | {0, 0x0040, 0x0127}, | ||
739 | {0, 0xfff8, 0x0124}, | ||
740 | {0, 0xfffd, 0x0124}, | ||
741 | {0, 0xfffa, 0x0124}, | ||
742 | {0, 0xfff9, 0x0124}, | ||
743 | {0, 0x0086, 0x0127}, | ||
744 | {0, 0xfff8, 0x0124}, | ||
745 | {0, 0xfffd, 0x0124}, | ||
746 | {0, 0x0038, 0x0127}, | ||
747 | {0, 0xfff8, 0x0124}, | ||
748 | {0, 0xfffd, 0x0124}, | ||
749 | {0, 0x0000, 0x0127}, | ||
750 | {0, 0xfff8, 0x0124}, | ||
751 | {0, 0xfffd, 0x0124}, | ||
752 | {0, 0x0040, 0x0127}, | ||
753 | {0, 0xfff8, 0x0124}, | ||
754 | {0, 0xfffd, 0x0124}, | ||
755 | {0, 0xfffa, 0x0124}, | ||
756 | {0, 0xfff9, 0x0124}, | ||
757 | {0, 0x0086, 0x0127}, | ||
758 | {0, 0xfff8, 0x0124}, | ||
759 | {0, 0xfffd, 0x0124}, | ||
760 | {0, 0x0037, 0x0127}, | ||
761 | {0, 0xfff8, 0x0124}, | ||
762 | {0, 0xfffd, 0x0124}, | ||
763 | {0, 0x0000, 0x0127}, | ||
764 | {0, 0xfff8, 0x0124}, | ||
765 | {0, 0xfffd, 0x0124}, | ||
766 | {0, 0x0030, 0x0127}, | ||
767 | {0, 0xfff8, 0x0124}, | ||
768 | {0, 0xfffd, 0x0124}, | ||
769 | {0, 0xfffa, 0x0124}, | ||
770 | {0, 0xfff9, 0x0124}, | ||
771 | {0, 0x0086, 0x0127}, | ||
772 | {0, 0xfff8, 0x0124}, | ||
773 | {0, 0xfffd, 0x0124}, | ||
774 | {0, 0x0038, 0x0127}, | ||
775 | {0, 0xfff8, 0x0124}, | ||
776 | {0, 0xfffd, 0x0124}, | ||
777 | {0, 0x0008, 0x0127}, | ||
778 | {0, 0xfff8, 0x0124}, | ||
779 | {0, 0xfffd, 0x0124}, | ||
780 | {0, 0x0000, 0x0127}, | ||
781 | {0, 0xfff8, 0x0124}, | ||
782 | {0, 0xfffd, 0x0124}, | ||
783 | {0, 0xfffa, 0x0124}, | ||
784 | {0, 0x0003, 0x0111}, | ||
785 | }; | ||
786 | |||
787 | /* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we | ||
788 | do the same for now (testing needed to see if this is really necessary) */ | ||
789 | static const int cit_model1_ntries = 5; | ||
790 | static const int cit_model1_ntries2 = 2; | ||
791 | |||
792 | static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index) | ||
793 | { | ||
794 | struct usb_device *udev = gspca_dev->dev; | ||
795 | int err; | ||
796 | |||
797 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, | ||
798 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, | ||
799 | value, index, NULL, 0, 1000); | ||
800 | if (err < 0) | ||
801 | err("Failed to write a register (index 0x%04X," | ||
802 | " value 0x%02X, error %d)", index, value, err); | ||
803 | |||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index) | ||
808 | { | ||
809 | struct usb_device *udev = gspca_dev->dev; | ||
810 | __u8 *buf = gspca_dev->usb_buf; | ||
811 | int res; | ||
812 | |||
813 | res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01, | ||
814 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, | ||
815 | 0x00, index, buf, 8, 1000); | ||
816 | if (res < 0) { | ||
817 | err("Failed to read a register (index 0x%04X, error %d)", | ||
818 | index, res); | ||
819 | return res; | ||
820 | } | ||
821 | |||
822 | PDEBUG(D_PROBE, | ||
823 | "Register %04x value: %02x %02x %02x %02x %02x %02x %02x %02x", | ||
824 | index, | ||
825 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); | ||
826 | |||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | /* | ||
831 | * cit_send_FF_04_02() | ||
832 | * | ||
833 | * This procedure sends magic 3-command prefix to the camera. | ||
834 | * The purpose of this prefix is not known. | ||
835 | * | ||
836 | * History: | ||
837 | * 1/2/00 Created. | ||
838 | */ | ||
839 | static void cit_send_FF_04_02(struct gspca_dev *gspca_dev) | ||
840 | { | ||
841 | cit_write_reg(gspca_dev, 0x00FF, 0x0127); | ||
842 | cit_write_reg(gspca_dev, 0x0004, 0x0124); | ||
843 | cit_write_reg(gspca_dev, 0x0002, 0x0124); | ||
844 | } | ||
845 | |||
846 | static void cit_send_00_04_06(struct gspca_dev *gspca_dev) | ||
847 | { | ||
848 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
849 | cit_write_reg(gspca_dev, 0x0004, 0x0124); | ||
850 | cit_write_reg(gspca_dev, 0x0006, 0x0124); | ||
851 | } | ||
852 | |||
853 | static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x) | ||
854 | { | ||
855 | cit_write_reg(gspca_dev, x, 0x0127); | ||
856 | cit_write_reg(gspca_dev, 0x0000, 0x0124); | ||
857 | } | ||
858 | |||
859 | static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x) | ||
860 | { | ||
861 | cit_send_x_00(gspca_dev, x); | ||
862 | cit_write_reg(gspca_dev, 0x0005, 0x0124); | ||
863 | } | ||
864 | |||
865 | static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x) | ||
866 | { | ||
867 | cit_write_reg(gspca_dev, x, 0x0127); | ||
868 | cit_write_reg(gspca_dev, 0x0000, 0x0124); | ||
869 | cit_write_reg(gspca_dev, 0x0005, 0x0124); | ||
870 | cit_write_reg(gspca_dev, 0x0002, 0x0124); | ||
871 | } | ||
872 | |||
873 | static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x) | ||
874 | { | ||
875 | cit_write_reg(gspca_dev, x, 0x0127); | ||
876 | cit_write_reg(gspca_dev, 0x0001, 0x0124); | ||
877 | cit_write_reg(gspca_dev, 0x0000, 0x0124); | ||
878 | cit_write_reg(gspca_dev, 0x0005, 0x0124); | ||
879 | } | ||
880 | |||
881 | static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x) | ||
882 | { | ||
883 | cit_write_reg(gspca_dev, x, 0x0127); | ||
884 | cit_write_reg(gspca_dev, 0x0000, 0x0124); | ||
885 | cit_write_reg(gspca_dev, 0x0005, 0x0124); | ||
886 | cit_write_reg(gspca_dev, 0x0002, 0x0124); | ||
887 | cit_write_reg(gspca_dev, 0x0001, 0x0124); | ||
888 | } | ||
889 | |||
890 | static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x) | ||
891 | { | ||
892 | cit_write_reg(gspca_dev, x, 0x0127); | ||
893 | cit_write_reg(gspca_dev, 0x0000, 0x0124); | ||
894 | cit_write_reg(gspca_dev, 0x0005, 0x0124); | ||
895 | cit_write_reg(gspca_dev, 0x0002, 0x0124); | ||
896 | cit_write_reg(gspca_dev, 0x0008, 0x0124); | ||
897 | cit_write_reg(gspca_dev, 0x0001, 0x0124); | ||
898 | } | ||
899 | |||
900 | static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val) | ||
901 | { | ||
902 | cit_send_x_01_00_05(gspca_dev, 0x0088); | ||
903 | cit_send_x_00_05(gspca_dev, fkey); | ||
904 | cit_send_x_00_05_02_08_01(gspca_dev, val); | ||
905 | cit_send_x_00_05(gspca_dev, 0x0088); | ||
906 | cit_send_x_00_05_02_01(gspca_dev, fkey); | ||
907 | cit_send_x_00_05(gspca_dev, 0x0089); | ||
908 | cit_send_x_00(gspca_dev, fkey); | ||
909 | cit_send_00_04_06(gspca_dev); | ||
910 | cit_read_reg(gspca_dev, 0x0126); | ||
911 | cit_send_FF_04_02(gspca_dev); | ||
912 | } | ||
913 | |||
914 | static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val) | ||
915 | { | ||
916 | cit_send_x_01_00_05(gspca_dev, 0x0088); | ||
917 | cit_send_x_00_05(gspca_dev, fkey); | ||
918 | cit_send_x_00_05_02(gspca_dev, val); | ||
919 | } | ||
920 | |||
921 | static void cit_model2_Packet2(struct gspca_dev *gspca_dev) | ||
922 | { | ||
923 | cit_write_reg(gspca_dev, 0x00ff, 0x012d); | ||
924 | cit_write_reg(gspca_dev, 0xfea3, 0x0124); | ||
925 | } | ||
926 | |||
927 | static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2) | ||
928 | { | ||
929 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
930 | cit_write_reg(gspca_dev, 0x00ff, 0x012e); | ||
931 | cit_write_reg(gspca_dev, v1, 0x012f); | ||
932 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); | ||
933 | cit_write_reg(gspca_dev, 0xc719, 0x0124); | ||
934 | cit_write_reg(gspca_dev, v2, 0x0127); | ||
935 | |||
936 | cit_model2_Packet2(gspca_dev); | ||
937 | } | ||
938 | |||
939 | /* | ||
940 | * cit_model3_Packet1() | ||
941 | * | ||
942 | * 00_0078_012d | ||
943 | * 00_0097_012f | ||
944 | * 00_d141_0124 | ||
945 | * 00_0096_0127 | ||
946 | * 00_fea8_0124 | ||
947 | */ | ||
948 | static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2) | ||
949 | { | ||
950 | cit_write_reg(gspca_dev, 0x0078, 0x012d); | ||
951 | cit_write_reg(gspca_dev, v1, 0x012f); | ||
952 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
953 | cit_write_reg(gspca_dev, v2, 0x0127); | ||
954 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
955 | } | ||
956 | |||
957 | static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2) | ||
958 | { | ||
959 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
960 | cit_write_reg(gspca_dev, v1, 0x012f); | ||
961 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
962 | cit_write_reg(gspca_dev, v2, 0x0127); | ||
963 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
964 | } | ||
965 | |||
966 | static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val) | ||
967 | { | ||
968 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
969 | cit_write_reg(gspca_dev, 0x0026, 0x012f); | ||
970 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
971 | cit_write_reg(gspca_dev, val, 0x0127); | ||
972 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
973 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
974 | cit_write_reg(gspca_dev, 0x0038, 0x012d); | ||
975 | cit_write_reg(gspca_dev, 0x0004, 0x012f); | ||
976 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
977 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
978 | } | ||
979 | |||
980 | /* this function is called at probe time */ | ||
981 | static int sd_config(struct gspca_dev *gspca_dev, | ||
982 | const struct usb_device_id *id) | ||
983 | { | ||
984 | struct sd *sd = (struct sd *) gspca_dev; | ||
985 | struct cam *cam; | ||
986 | |||
987 | sd->model = id->driver_info; | ||
988 | if (sd->model == CIT_MODEL3 && ibm_netcam_pro) | ||
989 | sd->model = CIT_IBM_NETCAM_PRO; | ||
990 | |||
991 | cam = &gspca_dev->cam; | ||
992 | switch (sd->model) { | ||
993 | case CIT_MODEL0: | ||
994 | cam->cam_mode = model0_mode; | ||
995 | cam->nmodes = ARRAY_SIZE(model0_mode); | ||
996 | cam->reverse_alts = 1; | ||
997 | gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP)); | ||
998 | sd->sof_len = 4; | ||
999 | break; | ||
1000 | case CIT_MODEL1: | ||
1001 | cam->cam_mode = cif_yuv_mode; | ||
1002 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); | ||
1003 | cam->reverse_alts = 1; | ||
1004 | gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP); | ||
1005 | sd->sof_len = 4; | ||
1006 | break; | ||
1007 | case CIT_MODEL2: | ||
1008 | cam->cam_mode = model2_mode + 1; /* no 160x120 */ | ||
1009 | cam->nmodes = 3; | ||
1010 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | | ||
1011 | (1 << SD_SHARPNESS) | | ||
1012 | (1 << SD_HFLIP); | ||
1013 | break; | ||
1014 | case CIT_MODEL3: | ||
1015 | cam->cam_mode = vga_yuv_mode; | ||
1016 | cam->nmodes = ARRAY_SIZE(vga_yuv_mode); | ||
1017 | gspca_dev->ctrl_dis = (1 << SD_HUE) | | ||
1018 | (1 << SD_LIGHTING) | | ||
1019 | (1 << SD_HFLIP); | ||
1020 | sd->stop_on_control_change = 1; | ||
1021 | sd->sof_len = 4; | ||
1022 | break; | ||
1023 | case CIT_MODEL4: | ||
1024 | cam->cam_mode = model2_mode; | ||
1025 | cam->nmodes = ARRAY_SIZE(model2_mode); | ||
1026 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | | ||
1027 | (1 << SD_SHARPNESS) | | ||
1028 | (1 << SD_LIGHTING) | | ||
1029 | (1 << SD_HFLIP); | ||
1030 | break; | ||
1031 | case CIT_IBM_NETCAM_PRO: | ||
1032 | cam->cam_mode = vga_yuv_mode; | ||
1033 | cam->nmodes = 2; /* no 640 x 480 */ | ||
1034 | cam->input_flags = V4L2_IN_ST_VFLIP; | ||
1035 | gspca_dev->ctrl_dis = ~(1 << SD_CONTRAST); | ||
1036 | sd->stop_on_control_change = 1; | ||
1037 | sd->sof_len = 4; | ||
1038 | break; | ||
1039 | } | ||
1040 | |||
1041 | sd->brightness = BRIGHTNESS_DEFAULT; | ||
1042 | sd->contrast = CONTRAST_DEFAULT; | ||
1043 | sd->hue = HUE_DEFAULT; | ||
1044 | sd->sharpness = SHARPNESS_DEFAULT; | ||
1045 | sd->lighting = LIGHTING_DEFAULT; | ||
1046 | sd->hflip = HFLIP_DEFAULT; | ||
1047 | |||
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | static int cit_init_model0(struct gspca_dev *gspca_dev) | ||
1052 | { | ||
1053 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */ | ||
1054 | cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */ | ||
1055 | cit_write_reg(gspca_dev, 0x0000, 0x0400); | ||
1056 | cit_write_reg(gspca_dev, 0x0001, 0x0400); | ||
1057 | cit_write_reg(gspca_dev, 0x0000, 0x0420); | ||
1058 | cit_write_reg(gspca_dev, 0x0001, 0x0420); | ||
1059 | cit_write_reg(gspca_dev, 0x000d, 0x0409); | ||
1060 | cit_write_reg(gspca_dev, 0x0002, 0x040a); | ||
1061 | cit_write_reg(gspca_dev, 0x0018, 0x0405); | ||
1062 | cit_write_reg(gspca_dev, 0x0008, 0x0435); | ||
1063 | cit_write_reg(gspca_dev, 0x0026, 0x040b); | ||
1064 | cit_write_reg(gspca_dev, 0x0007, 0x0437); | ||
1065 | cit_write_reg(gspca_dev, 0x0015, 0x042f); | ||
1066 | cit_write_reg(gspca_dev, 0x002b, 0x0439); | ||
1067 | cit_write_reg(gspca_dev, 0x0026, 0x043a); | ||
1068 | cit_write_reg(gspca_dev, 0x0008, 0x0438); | ||
1069 | cit_write_reg(gspca_dev, 0x001e, 0x042b); | ||
1070 | cit_write_reg(gspca_dev, 0x0041, 0x042c); | ||
1071 | |||
1072 | return 0; | ||
1073 | } | ||
1074 | |||
1075 | static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev) | ||
1076 | { | ||
1077 | cit_read_reg(gspca_dev, 0x128); | ||
1078 | cit_write_reg(gspca_dev, 0x0003, 0x0133); | ||
1079 | cit_write_reg(gspca_dev, 0x0000, 0x0117); | ||
1080 | cit_write_reg(gspca_dev, 0x0008, 0x0123); | ||
1081 | cit_write_reg(gspca_dev, 0x0000, 0x0100); | ||
1082 | cit_read_reg(gspca_dev, 0x0116); | ||
1083 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
1084 | cit_write_reg(gspca_dev, 0x0002, 0x0112); | ||
1085 | cit_write_reg(gspca_dev, 0x0000, 0x0133); | ||
1086 | cit_write_reg(gspca_dev, 0x0000, 0x0123); | ||
1087 | cit_write_reg(gspca_dev, 0x0001, 0x0117); | ||
1088 | cit_write_reg(gspca_dev, 0x0040, 0x0108); | ||
1089 | cit_write_reg(gspca_dev, 0x0019, 0x012c); | ||
1090 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
1091 | cit_write_reg(gspca_dev, 0x0002, 0x0115); | ||
1092 | cit_write_reg(gspca_dev, 0x000b, 0x0115); | ||
1093 | |||
1094 | cit_write_reg(gspca_dev, 0x0078, 0x012d); | ||
1095 | cit_write_reg(gspca_dev, 0x0001, 0x012f); | ||
1096 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
1097 | cit_write_reg(gspca_dev, 0x0079, 0x012d); | ||
1098 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); | ||
1099 | cit_write_reg(gspca_dev, 0xcd41, 0x0124); | ||
1100 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
1101 | cit_read_reg(gspca_dev, 0x0126); | ||
1102 | |||
1103 | cit_model3_Packet1(gspca_dev, 0x0000, 0x0000); | ||
1104 | cit_model3_Packet1(gspca_dev, 0x0000, 0x0001); | ||
1105 | cit_model3_Packet1(gspca_dev, 0x000b, 0x0000); | ||
1106 | cit_model3_Packet1(gspca_dev, 0x000c, 0x0008); | ||
1107 | cit_model3_Packet1(gspca_dev, 0x000d, 0x003a); | ||
1108 | cit_model3_Packet1(gspca_dev, 0x000e, 0x0060); | ||
1109 | cit_model3_Packet1(gspca_dev, 0x000f, 0x0060); | ||
1110 | cit_model3_Packet1(gspca_dev, 0x0010, 0x0008); | ||
1111 | cit_model3_Packet1(gspca_dev, 0x0011, 0x0004); | ||
1112 | cit_model3_Packet1(gspca_dev, 0x0012, 0x0028); | ||
1113 | cit_model3_Packet1(gspca_dev, 0x0013, 0x0002); | ||
1114 | cit_model3_Packet1(gspca_dev, 0x0014, 0x0000); | ||
1115 | cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb); | ||
1116 | cit_model3_Packet1(gspca_dev, 0x0016, 0x0002); | ||
1117 | cit_model3_Packet1(gspca_dev, 0x0017, 0x0037); | ||
1118 | cit_model3_Packet1(gspca_dev, 0x0018, 0x0036); | ||
1119 | cit_model3_Packet1(gspca_dev, 0x001e, 0x0000); | ||
1120 | cit_model3_Packet1(gspca_dev, 0x001f, 0x0008); | ||
1121 | cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1); | ||
1122 | cit_model3_Packet1(gspca_dev, 0x0021, 0x0034); | ||
1123 | cit_model3_Packet1(gspca_dev, 0x0022, 0x0034); | ||
1124 | cit_model3_Packet1(gspca_dev, 0x0025, 0x0002); | ||
1125 | cit_model3_Packet1(gspca_dev, 0x0028, 0x0022); | ||
1126 | cit_model3_Packet1(gspca_dev, 0x0029, 0x000a); | ||
1127 | cit_model3_Packet1(gspca_dev, 0x002b, 0x0000); | ||
1128 | cit_model3_Packet1(gspca_dev, 0x002c, 0x0000); | ||
1129 | cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff); | ||
1130 | cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff); | ||
1131 | cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff); | ||
1132 | cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff); | ||
1133 | cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff); | ||
1134 | cit_model3_Packet1(gspca_dev, 0x0032, 0x0007); | ||
1135 | cit_model3_Packet1(gspca_dev, 0x0033, 0x0005); | ||
1136 | cit_model3_Packet1(gspca_dev, 0x0037, 0x0040); | ||
1137 | cit_model3_Packet1(gspca_dev, 0x0039, 0x0000); | ||
1138 | cit_model3_Packet1(gspca_dev, 0x003a, 0x0000); | ||
1139 | cit_model3_Packet1(gspca_dev, 0x003b, 0x0001); | ||
1140 | cit_model3_Packet1(gspca_dev, 0x003c, 0x0000); | ||
1141 | cit_model3_Packet1(gspca_dev, 0x0040, 0x000c); | ||
1142 | cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb); | ||
1143 | cit_model3_Packet1(gspca_dev, 0x0042, 0x0002); | ||
1144 | cit_model3_Packet1(gspca_dev, 0x0043, 0x0000); | ||
1145 | cit_model3_Packet1(gspca_dev, 0x0045, 0x0000); | ||
1146 | cit_model3_Packet1(gspca_dev, 0x0046, 0x0000); | ||
1147 | cit_model3_Packet1(gspca_dev, 0x0047, 0x0000); | ||
1148 | cit_model3_Packet1(gspca_dev, 0x0048, 0x0000); | ||
1149 | cit_model3_Packet1(gspca_dev, 0x0049, 0x0000); | ||
1150 | cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff); | ||
1151 | cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff); | ||
1152 | cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff); | ||
1153 | cit_model3_Packet1(gspca_dev, 0x004f, 0x0000); | ||
1154 | cit_model3_Packet1(gspca_dev, 0x0050, 0x0000); | ||
1155 | cit_model3_Packet1(gspca_dev, 0x0051, 0x0002); | ||
1156 | cit_model3_Packet1(gspca_dev, 0x0055, 0x0000); | ||
1157 | cit_model3_Packet1(gspca_dev, 0x0056, 0x0000); | ||
1158 | cit_model3_Packet1(gspca_dev, 0x0057, 0x0000); | ||
1159 | cit_model3_Packet1(gspca_dev, 0x0058, 0x0002); | ||
1160 | cit_model3_Packet1(gspca_dev, 0x0059, 0x0000); | ||
1161 | cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); | ||
1162 | cit_model3_Packet1(gspca_dev, 0x005d, 0x0022); | ||
1163 | cit_model3_Packet1(gspca_dev, 0x005e, 0x003c); | ||
1164 | cit_model3_Packet1(gspca_dev, 0x005f, 0x0050); | ||
1165 | cit_model3_Packet1(gspca_dev, 0x0060, 0x0044); | ||
1166 | cit_model3_Packet1(gspca_dev, 0x0061, 0x0005); | ||
1167 | cit_model3_Packet1(gspca_dev, 0x006a, 0x007e); | ||
1168 | cit_model3_Packet1(gspca_dev, 0x006f, 0x0000); | ||
1169 | cit_model3_Packet1(gspca_dev, 0x0072, 0x001b); | ||
1170 | cit_model3_Packet1(gspca_dev, 0x0073, 0x0005); | ||
1171 | cit_model3_Packet1(gspca_dev, 0x0074, 0x000a); | ||
1172 | cit_model3_Packet1(gspca_dev, 0x0075, 0x001b); | ||
1173 | cit_model3_Packet1(gspca_dev, 0x0076, 0x002a); | ||
1174 | cit_model3_Packet1(gspca_dev, 0x0077, 0x003c); | ||
1175 | cit_model3_Packet1(gspca_dev, 0x0078, 0x0050); | ||
1176 | cit_model3_Packet1(gspca_dev, 0x007b, 0x0000); | ||
1177 | cit_model3_Packet1(gspca_dev, 0x007c, 0x0011); | ||
1178 | cit_model3_Packet1(gspca_dev, 0x007d, 0x0024); | ||
1179 | cit_model3_Packet1(gspca_dev, 0x007e, 0x0043); | ||
1180 | cit_model3_Packet1(gspca_dev, 0x007f, 0x005a); | ||
1181 | cit_model3_Packet1(gspca_dev, 0x0084, 0x0020); | ||
1182 | cit_model3_Packet1(gspca_dev, 0x0085, 0x0033); | ||
1183 | cit_model3_Packet1(gspca_dev, 0x0086, 0x000a); | ||
1184 | cit_model3_Packet1(gspca_dev, 0x0087, 0x0030); | ||
1185 | cit_model3_Packet1(gspca_dev, 0x0088, 0x0070); | ||
1186 | cit_model3_Packet1(gspca_dev, 0x008b, 0x0008); | ||
1187 | cit_model3_Packet1(gspca_dev, 0x008f, 0x0000); | ||
1188 | cit_model3_Packet1(gspca_dev, 0x0090, 0x0006); | ||
1189 | cit_model3_Packet1(gspca_dev, 0x0091, 0x0028); | ||
1190 | cit_model3_Packet1(gspca_dev, 0x0092, 0x005a); | ||
1191 | cit_model3_Packet1(gspca_dev, 0x0093, 0x0082); | ||
1192 | cit_model3_Packet1(gspca_dev, 0x0096, 0x0014); | ||
1193 | cit_model3_Packet1(gspca_dev, 0x0097, 0x0020); | ||
1194 | cit_model3_Packet1(gspca_dev, 0x0098, 0x0000); | ||
1195 | cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046); | ||
1196 | cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000); | ||
1197 | cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000); | ||
1198 | cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004); | ||
1199 | cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007); | ||
1200 | cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002); | ||
1201 | cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004); | ||
1202 | cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000); | ||
1203 | cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001); | ||
1204 | cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000); | ||
1205 | cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000); | ||
1206 | cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8); | ||
1207 | cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014); | ||
1208 | cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001); | ||
1209 | cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000); | ||
1210 | cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004); | ||
1211 | cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf); | ||
1212 | cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf); | ||
1213 | cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf); | ||
1214 | cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000); | ||
1215 | cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020); | ||
1216 | cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040); | ||
1217 | cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf); | ||
1218 | cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf); | ||
1219 | cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf); | ||
1220 | cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf); | ||
1221 | cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008); | ||
1222 | cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000); | ||
1223 | cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8); | ||
1224 | cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001); | ||
1225 | cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022); | ||
1226 | cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000); | ||
1227 | cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028); | ||
1228 | cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002); | ||
1229 | cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000); | ||
1230 | cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000); | ||
1231 | cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001); | ||
1232 | cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000); | ||
1233 | cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000); | ||
1234 | cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000); | ||
1235 | cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000); | ||
1236 | |||
1237 | cit_model3_Packet1(gspca_dev, 0x00be, 0x0003); | ||
1238 | cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000); | ||
1239 | cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020); | ||
1240 | cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040); | ||
1241 | cit_model3_Packet1(gspca_dev, 0x0053, 0x0001); | ||
1242 | cit_model3_Packet1(gspca_dev, 0x0082, 0x000e); | ||
1243 | cit_model3_Packet1(gspca_dev, 0x0083, 0x0020); | ||
1244 | cit_model3_Packet1(gspca_dev, 0x0034, 0x003c); | ||
1245 | cit_model3_Packet1(gspca_dev, 0x006e, 0x0055); | ||
1246 | cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); | ||
1247 | cit_model3_Packet1(gspca_dev, 0x0063, 0x0008); | ||
1248 | cit_model3_Packet1(gspca_dev, 0x0066, 0x000a); | ||
1249 | cit_model3_Packet1(gspca_dev, 0x0067, 0x0006); | ||
1250 | cit_model3_Packet1(gspca_dev, 0x006b, 0x0010); | ||
1251 | cit_model3_Packet1(gspca_dev, 0x005a, 0x0001); | ||
1252 | cit_model3_Packet1(gspca_dev, 0x005b, 0x000a); | ||
1253 | cit_model3_Packet1(gspca_dev, 0x0023, 0x0006); | ||
1254 | cit_model3_Packet1(gspca_dev, 0x0026, 0x0004); | ||
1255 | cit_model3_Packet1(gspca_dev, 0x0036, 0x0069); | ||
1256 | cit_model3_Packet1(gspca_dev, 0x0038, 0x0064); | ||
1257 | cit_model3_Packet1(gspca_dev, 0x003d, 0x0003); | ||
1258 | cit_model3_Packet1(gspca_dev, 0x003e, 0x0001); | ||
1259 | cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014); | ||
1260 | cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014); | ||
1261 | cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004); | ||
1262 | cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001); | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1267 | /* this function is called at probe and resume time */ | ||
1268 | static int sd_init(struct gspca_dev *gspca_dev) | ||
1269 | { | ||
1270 | struct sd *sd = (struct sd *) gspca_dev; | ||
1271 | |||
1272 | switch (sd->model) { | ||
1273 | case CIT_MODEL0: | ||
1274 | cit_init_model0(gspca_dev); | ||
1275 | sd_stop0(gspca_dev); | ||
1276 | break; | ||
1277 | case CIT_MODEL1: | ||
1278 | case CIT_MODEL2: | ||
1279 | case CIT_MODEL3: | ||
1280 | case CIT_MODEL4: | ||
1281 | break; /* All is done in sd_start */ | ||
1282 | case CIT_IBM_NETCAM_PRO: | ||
1283 | cit_init_ibm_netcam_pro(gspca_dev); | ||
1284 | sd_stop0(gspca_dev); | ||
1285 | break; | ||
1286 | } | ||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | static int cit_set_brightness(struct gspca_dev *gspca_dev) | ||
1291 | { | ||
1292 | struct sd *sd = (struct sd *) gspca_dev; | ||
1293 | int i; | ||
1294 | |||
1295 | switch (sd->model) { | ||
1296 | case CIT_MODEL0: | ||
1297 | case CIT_IBM_NETCAM_PRO: | ||
1298 | /* No (known) brightness control for these */ | ||
1299 | break; | ||
1300 | case CIT_MODEL1: | ||
1301 | /* Model 1: Brightness range 0 - 63 */ | ||
1302 | cit_Packet_Format1(gspca_dev, 0x0031, sd->brightness); | ||
1303 | cit_Packet_Format1(gspca_dev, 0x0032, sd->brightness); | ||
1304 | cit_Packet_Format1(gspca_dev, 0x0033, sd->brightness); | ||
1305 | break; | ||
1306 | case CIT_MODEL2: | ||
1307 | /* Model 2: Brightness range 0x60 - 0xee */ | ||
1308 | /* Scale 0 - 63 to 0x60 - 0xee */ | ||
1309 | i = 0x60 + sd->brightness * 2254 / 1000; | ||
1310 | cit_model2_Packet1(gspca_dev, 0x001a, i); | ||
1311 | break; | ||
1312 | case CIT_MODEL3: | ||
1313 | /* Model 3: Brightness range 'i' in [0x0C..0x3F] */ | ||
1314 | i = sd->brightness; | ||
1315 | if (i < 0x0c) | ||
1316 | i = 0x0c; | ||
1317 | cit_model3_Packet1(gspca_dev, 0x0036, i); | ||
1318 | break; | ||
1319 | case CIT_MODEL4: | ||
1320 | /* Model 4: Brightness range 'i' in [0x04..0xb4] */ | ||
1321 | /* Scale 0 - 63 to 0x04 - 0xb4 */ | ||
1322 | i = 0x04 + sd->brightness * 2794 / 1000; | ||
1323 | cit_model4_BrightnessPacket(gspca_dev, i); | ||
1324 | break; | ||
1325 | } | ||
1326 | |||
1327 | return 0; | ||
1328 | } | ||
1329 | |||
1330 | static int cit_set_contrast(struct gspca_dev *gspca_dev) | ||
1331 | { | ||
1332 | struct sd *sd = (struct sd *) gspca_dev; | ||
1333 | |||
1334 | switch (sd->model) { | ||
1335 | case CIT_MODEL0: { | ||
1336 | int i; | ||
1337 | /* gain 0-15, 0-20 -> 0-15 */ | ||
1338 | i = sd->contrast * 1000 / 1333; | ||
1339 | cit_write_reg(gspca_dev, i, 0x0422); | ||
1340 | /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */ | ||
1341 | i = sd->contrast * 2000 / 1333; | ||
1342 | cit_write_reg(gspca_dev, i, 0x0423); | ||
1343 | /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */ | ||
1344 | i = sd->contrast * 4000 / 1333; | ||
1345 | cit_write_reg(gspca_dev, i, 0x0424); | ||
1346 | /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */ | ||
1347 | i = sd->contrast * 8000 / 1333; | ||
1348 | cit_write_reg(gspca_dev, i, 0x0425); | ||
1349 | break; | ||
1350 | } | ||
1351 | case CIT_MODEL2: | ||
1352 | case CIT_MODEL4: | ||
1353 | /* These models do not have this control. */ | ||
1354 | break; | ||
1355 | case CIT_MODEL1: | ||
1356 | { | ||
1357 | /* Scale 0 - 20 to 15 - 0 */ | ||
1358 | int i, new_contrast = (20 - sd->contrast) * 1000 / 1333; | ||
1359 | for (i = 0; i < cit_model1_ntries; i++) { | ||
1360 | cit_Packet_Format1(gspca_dev, 0x0014, new_contrast); | ||
1361 | cit_send_FF_04_02(gspca_dev); | ||
1362 | } | ||
1363 | break; | ||
1364 | } | ||
1365 | case CIT_MODEL3: | ||
1366 | { /* Preset hardware values */ | ||
1367 | static const struct { | ||
1368 | unsigned short cv1; | ||
1369 | unsigned short cv2; | ||
1370 | unsigned short cv3; | ||
1371 | } cv[7] = { | ||
1372 | { 0x05, 0x05, 0x0f }, /* Minimum */ | ||
1373 | { 0x04, 0x04, 0x16 }, | ||
1374 | { 0x02, 0x03, 0x16 }, | ||
1375 | { 0x02, 0x08, 0x16 }, | ||
1376 | { 0x01, 0x0c, 0x16 }, | ||
1377 | { 0x01, 0x0e, 0x16 }, | ||
1378 | { 0x01, 0x10, 0x16 } /* Maximum */ | ||
1379 | }; | ||
1380 | int i = sd->contrast / 3; | ||
1381 | cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1); | ||
1382 | cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2); | ||
1383 | cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3); | ||
1384 | break; | ||
1385 | } | ||
1386 | case CIT_IBM_NETCAM_PRO: | ||
1387 | cit_model3_Packet1(gspca_dev, 0x005b, sd->contrast + 1); | ||
1388 | break; | ||
1389 | } | ||
1390 | return 0; | ||
1391 | } | ||
1392 | |||
1393 | static int cit_set_hue(struct gspca_dev *gspca_dev) | ||
1394 | { | ||
1395 | struct sd *sd = (struct sd *) gspca_dev; | ||
1396 | |||
1397 | switch (sd->model) { | ||
1398 | case CIT_MODEL0: | ||
1399 | case CIT_MODEL1: | ||
1400 | case CIT_IBM_NETCAM_PRO: | ||
1401 | /* No hue control for these models */ | ||
1402 | break; | ||
1403 | case CIT_MODEL2: | ||
1404 | cit_model2_Packet1(gspca_dev, 0x0024, sd->hue); | ||
1405 | /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */ | ||
1406 | break; | ||
1407 | case CIT_MODEL3: { | ||
1408 | /* Model 3: Brightness range 'i' in [0x05..0x37] */ | ||
1409 | /* TESTME according to the ibmcam driver this does not work */ | ||
1410 | if (0) { | ||
1411 | /* Scale 0 - 127 to 0x05 - 0x37 */ | ||
1412 | int i = 0x05 + sd->hue * 1000 / 2540; | ||
1413 | cit_model3_Packet1(gspca_dev, 0x007e, i); | ||
1414 | } | ||
1415 | break; | ||
1416 | } | ||
1417 | case CIT_MODEL4: | ||
1418 | /* HDG: taken from ibmcam, setting the color gains does not | ||
1419 | * really belong here. | ||
1420 | * | ||
1421 | * I am not sure r/g/b_gain variables exactly control gain | ||
1422 | * of those channels. Most likely they subtly change some | ||
1423 | * very internal image processing settings in the camera. | ||
1424 | * In any case, here is what they do, and feel free to tweak: | ||
1425 | * | ||
1426 | * r_gain: seriously affects red gain | ||
1427 | * g_gain: seriously affects green gain | ||
1428 | * b_gain: seriously affects blue gain | ||
1429 | * hue: changes average color from violet (0) to red (0xFF) | ||
1430 | */ | ||
1431 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
1432 | cit_write_reg(gspca_dev, 0x001e, 0x012f); | ||
1433 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
1434 | cit_write_reg(gspca_dev, 160, 0x0127); /* Green gain */ | ||
1435 | cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */ | ||
1436 | cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */ | ||
1437 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
1438 | cit_write_reg(gspca_dev, sd->hue, 0x012d); /* Hue */ | ||
1439 | cit_write_reg(gspca_dev, 0xf545, 0x0124); | ||
1440 | break; | ||
1441 | } | ||
1442 | return 0; | ||
1443 | } | ||
1444 | |||
1445 | static int cit_set_sharpness(struct gspca_dev *gspca_dev) | ||
1446 | { | ||
1447 | struct sd *sd = (struct sd *) gspca_dev; | ||
1448 | |||
1449 | switch (sd->model) { | ||
1450 | case CIT_MODEL0: | ||
1451 | case CIT_MODEL2: | ||
1452 | case CIT_MODEL4: | ||
1453 | case CIT_IBM_NETCAM_PRO: | ||
1454 | /* These models do not have this control */ | ||
1455 | break; | ||
1456 | case CIT_MODEL1: { | ||
1457 | int i; | ||
1458 | const unsigned short sa[] = { | ||
1459 | 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; | ||
1460 | |||
1461 | for (i = 0; i < cit_model1_ntries; i++) | ||
1462 | cit_PacketFormat2(gspca_dev, 0x0013, sa[sd->sharpness]); | ||
1463 | break; | ||
1464 | } | ||
1465 | case CIT_MODEL3: | ||
1466 | { /* | ||
1467 | * "Use a table of magic numbers. | ||
1468 | * This setting doesn't really change much. | ||
1469 | * But that's how Windows does it." | ||
1470 | */ | ||
1471 | static const struct { | ||
1472 | unsigned short sv1; | ||
1473 | unsigned short sv2; | ||
1474 | unsigned short sv3; | ||
1475 | unsigned short sv4; | ||
1476 | } sv[7] = { | ||
1477 | { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */ | ||
1478 | { 0x01, 0x04, 0x05, 0x14 }, | ||
1479 | { 0x02, 0x04, 0x05, 0x14 }, | ||
1480 | { 0x03, 0x04, 0x05, 0x14 }, | ||
1481 | { 0x03, 0x05, 0x05, 0x14 }, | ||
1482 | { 0x03, 0x06, 0x05, 0x14 }, | ||
1483 | { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */ | ||
1484 | }; | ||
1485 | cit_model3_Packet1(gspca_dev, 0x0060, sv[sd->sharpness].sv1); | ||
1486 | cit_model3_Packet1(gspca_dev, 0x0061, sv[sd->sharpness].sv2); | ||
1487 | cit_model3_Packet1(gspca_dev, 0x0062, sv[sd->sharpness].sv3); | ||
1488 | cit_model3_Packet1(gspca_dev, 0x0063, sv[sd->sharpness].sv4); | ||
1489 | break; | ||
1490 | } | ||
1491 | } | ||
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1495 | /* | ||
1496 | * cit_set_lighting() | ||
1497 | * | ||
1498 | * Camera model 1: | ||
1499 | * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low. | ||
1500 | * | ||
1501 | * Camera model 2: | ||
1502 | * We have 16 levels of lighting, 0 for bright light and up to 15 for | ||
1503 | * low light. But values above 5 or so are useless because camera is | ||
1504 | * not really capable to produce anything worth viewing at such light. | ||
1505 | * This setting may be altered only in certain camera state. | ||
1506 | * | ||
1507 | * Low lighting forces slower FPS. | ||
1508 | * | ||
1509 | * History: | ||
1510 | * 1/5/00 Created. | ||
1511 | * 2/20/00 Added support for Model 2 cameras. | ||
1512 | */ | ||
1513 | static void cit_set_lighting(struct gspca_dev *gspca_dev) | ||
1514 | { | ||
1515 | struct sd *sd = (struct sd *) gspca_dev; | ||
1516 | |||
1517 | switch (sd->model) { | ||
1518 | case CIT_MODEL0: | ||
1519 | case CIT_MODEL2: | ||
1520 | case CIT_MODEL3: | ||
1521 | case CIT_MODEL4: | ||
1522 | case CIT_IBM_NETCAM_PRO: | ||
1523 | break; | ||
1524 | case CIT_MODEL1: { | ||
1525 | int i; | ||
1526 | for (i = 0; i < cit_model1_ntries; i++) | ||
1527 | cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting); | ||
1528 | break; | ||
1529 | } | ||
1530 | } | ||
1531 | } | ||
1532 | |||
1533 | static void cit_set_hflip(struct gspca_dev *gspca_dev) | ||
1534 | { | ||
1535 | struct sd *sd = (struct sd *) gspca_dev; | ||
1536 | |||
1537 | switch (sd->model) { | ||
1538 | case CIT_MODEL0: | ||
1539 | if (sd->hflip) | ||
1540 | cit_write_reg(gspca_dev, 0x0020, 0x0115); | ||
1541 | else | ||
1542 | cit_write_reg(gspca_dev, 0x0040, 0x0115); | ||
1543 | break; | ||
1544 | case CIT_MODEL1: | ||
1545 | case CIT_MODEL2: | ||
1546 | case CIT_MODEL3: | ||
1547 | case CIT_MODEL4: | ||
1548 | case CIT_IBM_NETCAM_PRO: | ||
1549 | break; | ||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | static int cit_restart_stream(struct gspca_dev *gspca_dev) | ||
1554 | { | ||
1555 | struct sd *sd = (struct sd *) gspca_dev; | ||
1556 | |||
1557 | switch (sd->model) { | ||
1558 | case CIT_MODEL0: | ||
1559 | case CIT_MODEL1: | ||
1560 | case CIT_MODEL3: | ||
1561 | case CIT_IBM_NETCAM_PRO: | ||
1562 | cit_write_reg(gspca_dev, 0x0001, 0x0114); | ||
1563 | /* Fall through */ | ||
1564 | case CIT_MODEL2: | ||
1565 | case CIT_MODEL4: | ||
1566 | cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */ | ||
1567 | usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); | ||
1568 | /* This happens repeatedly while streaming with the ibm netcam | ||
1569 | pro and the ibmcam driver did it for model3 after changing | ||
1570 | settings, but it does not seem to have any effect. */ | ||
1571 | /* cit_write_reg(gspca_dev, 0x0001, 0x0113); */ | ||
1572 | break; | ||
1573 | } | ||
1574 | |||
1575 | sd->sof_read = 0; | ||
1576 | |||
1577 | return 0; | ||
1578 | } | ||
1579 | |||
1580 | static int cit_get_packet_size(struct gspca_dev *gspca_dev) | ||
1581 | { | ||
1582 | struct usb_host_interface *alt; | ||
1583 | struct usb_interface *intf; | ||
1584 | |||
1585 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | ||
1586 | alt = usb_altnum_to_altsetting(intf, gspca_dev->alt); | ||
1587 | if (!alt) { | ||
1588 | err("Couldn't get altsetting"); | ||
1589 | return -EIO; | ||
1590 | } | ||
1591 | |||
1592 | return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
1593 | } | ||
1594 | |||
1595 | /* Calculate the clockdiv giving us max fps given the available bandwidth */ | ||
1596 | static int cit_get_clock_div(struct gspca_dev *gspca_dev) | ||
1597 | { | ||
1598 | int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */ | ||
1599 | int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 }; | ||
1600 | int packet_size; | ||
1601 | |||
1602 | packet_size = cit_get_packet_size(gspca_dev); | ||
1603 | if (packet_size < 0) | ||
1604 | return packet_size; | ||
1605 | |||
1606 | while (clock_div > 3 && | ||
1607 | 1000 * packet_size > | ||
1608 | gspca_dev->width * gspca_dev->height * | ||
1609 | fps[clock_div - 1] * 3 / 2) | ||
1610 | clock_div--; | ||
1611 | |||
1612 | PDEBUG(D_PROBE, | ||
1613 | "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)", | ||
1614 | packet_size, gspca_dev->width, gspca_dev->height, clock_div, | ||
1615 | fps[clock_div]); | ||
1616 | |||
1617 | return clock_div; | ||
1618 | } | ||
1619 | |||
1620 | static int cit_start_model0(struct gspca_dev *gspca_dev) | ||
1621 | { | ||
1622 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ | ||
1623 | int clock_div; | ||
1624 | |||
1625 | clock_div = cit_get_clock_div(gspca_dev); | ||
1626 | if (clock_div < 0) | ||
1627 | return clock_div; | ||
1628 | |||
1629 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */ | ||
1630 | cit_write_reg(gspca_dev, 0x0003, 0x0438); | ||
1631 | cit_write_reg(gspca_dev, 0x001e, 0x042b); | ||
1632 | cit_write_reg(gspca_dev, 0x0041, 0x042c); | ||
1633 | cit_write_reg(gspca_dev, 0x0008, 0x0436); | ||
1634 | cit_write_reg(gspca_dev, 0x0024, 0x0403); | ||
1635 | cit_write_reg(gspca_dev, 0x002c, 0x0404); | ||
1636 | cit_write_reg(gspca_dev, 0x0002, 0x0426); | ||
1637 | cit_write_reg(gspca_dev, 0x0014, 0x0427); | ||
1638 | |||
1639 | switch (gspca_dev->width) { | ||
1640 | case 160: /* 160x120 */ | ||
1641 | cit_write_reg(gspca_dev, 0x0004, 0x010b); | ||
1642 | cit_write_reg(gspca_dev, 0x0001, 0x010a); | ||
1643 | cit_write_reg(gspca_dev, 0x0010, 0x0102); | ||
1644 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); | ||
1645 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
1646 | cit_write_reg(gspca_dev, 0x0078, 0x0105); | ||
1647 | break; | ||
1648 | |||
1649 | case 176: /* 176x144 */ | ||
1650 | cit_write_reg(gspca_dev, 0x0006, 0x010b); | ||
1651 | cit_write_reg(gspca_dev, 0x0000, 0x010a); | ||
1652 | cit_write_reg(gspca_dev, 0x0005, 0x0102); | ||
1653 | cit_write_reg(gspca_dev, 0x00b0, 0x0103); | ||
1654 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
1655 | cit_write_reg(gspca_dev, 0x0090, 0x0105); | ||
1656 | break; | ||
1657 | |||
1658 | case 320: /* 320x240 */ | ||
1659 | cit_write_reg(gspca_dev, 0x0008, 0x010b); | ||
1660 | cit_write_reg(gspca_dev, 0x0004, 0x010a); | ||
1661 | cit_write_reg(gspca_dev, 0x0005, 0x0102); | ||
1662 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); | ||
1663 | cit_write_reg(gspca_dev, 0x0010, 0x0104); | ||
1664 | cit_write_reg(gspca_dev, 0x0078, 0x0105); | ||
1665 | break; | ||
1666 | } | ||
1667 | |||
1668 | cit_write_reg(gspca_dev, compression, 0x0109); | ||
1669 | cit_write_reg(gspca_dev, clock_div, 0x0111); | ||
1670 | |||
1671 | return 0; | ||
1672 | } | ||
1673 | |||
1674 | static int cit_start_model1(struct gspca_dev *gspca_dev) | ||
1675 | { | ||
1676 | struct sd *sd = (struct sd *) gspca_dev; | ||
1677 | int i, clock_div; | ||
1678 | |||
1679 | clock_div = cit_get_clock_div(gspca_dev); | ||
1680 | if (clock_div < 0) | ||
1681 | return clock_div; | ||
1682 | |||
1683 | cit_read_reg(gspca_dev, 0x0128); | ||
1684 | cit_read_reg(gspca_dev, 0x0100); | ||
1685 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ | ||
1686 | cit_read_reg(gspca_dev, 0x0100); | ||
1687 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ | ||
1688 | cit_read_reg(gspca_dev, 0x0100); | ||
1689 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ | ||
1690 | cit_write_reg(gspca_dev, 0x01, 0x0108); | ||
1691 | |||
1692 | cit_write_reg(gspca_dev, 0x03, 0x0112); | ||
1693 | cit_read_reg(gspca_dev, 0x0115); | ||
1694 | cit_write_reg(gspca_dev, 0x06, 0x0115); | ||
1695 | cit_read_reg(gspca_dev, 0x0116); | ||
1696 | cit_write_reg(gspca_dev, 0x44, 0x0116); | ||
1697 | cit_read_reg(gspca_dev, 0x0116); | ||
1698 | cit_write_reg(gspca_dev, 0x40, 0x0116); | ||
1699 | cit_read_reg(gspca_dev, 0x0115); | ||
1700 | cit_write_reg(gspca_dev, 0x0e, 0x0115); | ||
1701 | cit_write_reg(gspca_dev, 0x19, 0x012c); | ||
1702 | |||
1703 | cit_Packet_Format1(gspca_dev, 0x00, 0x1e); | ||
1704 | cit_Packet_Format1(gspca_dev, 0x39, 0x0d); | ||
1705 | cit_Packet_Format1(gspca_dev, 0x39, 0x09); | ||
1706 | cit_Packet_Format1(gspca_dev, 0x3b, 0x00); | ||
1707 | cit_Packet_Format1(gspca_dev, 0x28, 0x22); | ||
1708 | cit_Packet_Format1(gspca_dev, 0x27, 0x00); | ||
1709 | cit_Packet_Format1(gspca_dev, 0x2b, 0x1f); | ||
1710 | cit_Packet_Format1(gspca_dev, 0x39, 0x08); | ||
1711 | |||
1712 | for (i = 0; i < cit_model1_ntries; i++) | ||
1713 | cit_Packet_Format1(gspca_dev, 0x2c, 0x00); | ||
1714 | |||
1715 | for (i = 0; i < cit_model1_ntries; i++) | ||
1716 | cit_Packet_Format1(gspca_dev, 0x30, 0x14); | ||
1717 | |||
1718 | cit_PacketFormat2(gspca_dev, 0x39, 0x02); | ||
1719 | cit_PacketFormat2(gspca_dev, 0x01, 0xe1); | ||
1720 | cit_PacketFormat2(gspca_dev, 0x02, 0xcd); | ||
1721 | cit_PacketFormat2(gspca_dev, 0x03, 0xcd); | ||
1722 | cit_PacketFormat2(gspca_dev, 0x04, 0xfa); | ||
1723 | cit_PacketFormat2(gspca_dev, 0x3f, 0xff); | ||
1724 | cit_PacketFormat2(gspca_dev, 0x39, 0x00); | ||
1725 | |||
1726 | cit_PacketFormat2(gspca_dev, 0x39, 0x02); | ||
1727 | cit_PacketFormat2(gspca_dev, 0x0a, 0x37); | ||
1728 | cit_PacketFormat2(gspca_dev, 0x0b, 0xb8); | ||
1729 | cit_PacketFormat2(gspca_dev, 0x0c, 0xf3); | ||
1730 | cit_PacketFormat2(gspca_dev, 0x0d, 0xe3); | ||
1731 | cit_PacketFormat2(gspca_dev, 0x0e, 0x0d); | ||
1732 | cit_PacketFormat2(gspca_dev, 0x0f, 0xf2); | ||
1733 | cit_PacketFormat2(gspca_dev, 0x10, 0xd5); | ||
1734 | cit_PacketFormat2(gspca_dev, 0x11, 0xba); | ||
1735 | cit_PacketFormat2(gspca_dev, 0x12, 0x53); | ||
1736 | cit_PacketFormat2(gspca_dev, 0x3f, 0xff); | ||
1737 | cit_PacketFormat2(gspca_dev, 0x39, 0x00); | ||
1738 | |||
1739 | cit_PacketFormat2(gspca_dev, 0x39, 0x02); | ||
1740 | cit_PacketFormat2(gspca_dev, 0x16, 0x00); | ||
1741 | cit_PacketFormat2(gspca_dev, 0x17, 0x28); | ||
1742 | cit_PacketFormat2(gspca_dev, 0x18, 0x7d); | ||
1743 | cit_PacketFormat2(gspca_dev, 0x19, 0xbe); | ||
1744 | cit_PacketFormat2(gspca_dev, 0x3f, 0xff); | ||
1745 | cit_PacketFormat2(gspca_dev, 0x39, 0x00); | ||
1746 | |||
1747 | for (i = 0; i < cit_model1_ntries; i++) | ||
1748 | cit_Packet_Format1(gspca_dev, 0x00, 0x18); | ||
1749 | for (i = 0; i < cit_model1_ntries; i++) | ||
1750 | cit_Packet_Format1(gspca_dev, 0x13, 0x18); | ||
1751 | for (i = 0; i < cit_model1_ntries; i++) | ||
1752 | cit_Packet_Format1(gspca_dev, 0x14, 0x06); | ||
1753 | |||
1754 | /* TESTME These are handled through controls | ||
1755 | KEEP until someone can test leaving this out is ok */ | ||
1756 | if (0) { | ||
1757 | /* This is default brightness */ | ||
1758 | for (i = 0; i < cit_model1_ntries; i++) | ||
1759 | cit_Packet_Format1(gspca_dev, 0x31, 0x37); | ||
1760 | for (i = 0; i < cit_model1_ntries; i++) | ||
1761 | cit_Packet_Format1(gspca_dev, 0x32, 0x46); | ||
1762 | for (i = 0; i < cit_model1_ntries; i++) | ||
1763 | cit_Packet_Format1(gspca_dev, 0x33, 0x55); | ||
1764 | } | ||
1765 | |||
1766 | cit_Packet_Format1(gspca_dev, 0x2e, 0x04); | ||
1767 | for (i = 0; i < cit_model1_ntries; i++) | ||
1768 | cit_Packet_Format1(gspca_dev, 0x2d, 0x04); | ||
1769 | for (i = 0; i < cit_model1_ntries; i++) | ||
1770 | cit_Packet_Format1(gspca_dev, 0x29, 0x80); | ||
1771 | cit_Packet_Format1(gspca_dev, 0x2c, 0x01); | ||
1772 | cit_Packet_Format1(gspca_dev, 0x30, 0x17); | ||
1773 | cit_Packet_Format1(gspca_dev, 0x39, 0x08); | ||
1774 | for (i = 0; i < cit_model1_ntries; i++) | ||
1775 | cit_Packet_Format1(gspca_dev, 0x34, 0x00); | ||
1776 | |||
1777 | cit_write_reg(gspca_dev, 0x00, 0x0101); | ||
1778 | cit_write_reg(gspca_dev, 0x00, 0x010a); | ||
1779 | |||
1780 | switch (gspca_dev->width) { | ||
1781 | case 128: /* 128x96 */ | ||
1782 | cit_write_reg(gspca_dev, 0x80, 0x0103); | ||
1783 | cit_write_reg(gspca_dev, 0x60, 0x0105); | ||
1784 | cit_write_reg(gspca_dev, 0x0c, 0x010b); | ||
1785 | cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */ | ||
1786 | cit_write_reg(gspca_dev, 0x0b, 0x011d); | ||
1787 | cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */ | ||
1788 | cit_write_reg(gspca_dev, 0x00, 0x0129); | ||
1789 | break; | ||
1790 | case 176: /* 176x144 */ | ||
1791 | cit_write_reg(gspca_dev, 0xb0, 0x0103); | ||
1792 | cit_write_reg(gspca_dev, 0x8f, 0x0105); | ||
1793 | cit_write_reg(gspca_dev, 0x06, 0x010b); | ||
1794 | cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */ | ||
1795 | cit_write_reg(gspca_dev, 0x0d, 0x011d); | ||
1796 | cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */ | ||
1797 | cit_write_reg(gspca_dev, 0x03, 0x0129); | ||
1798 | break; | ||
1799 | case 352: /* 352x288 */ | ||
1800 | cit_write_reg(gspca_dev, 0xb0, 0x0103); | ||
1801 | cit_write_reg(gspca_dev, 0x90, 0x0105); | ||
1802 | cit_write_reg(gspca_dev, 0x02, 0x010b); | ||
1803 | cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */ | ||
1804 | cit_write_reg(gspca_dev, 0x05, 0x011d); | ||
1805 | cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */ | ||
1806 | cit_write_reg(gspca_dev, 0x00, 0x0129); | ||
1807 | break; | ||
1808 | } | ||
1809 | |||
1810 | cit_write_reg(gspca_dev, 0xff, 0x012b); | ||
1811 | |||
1812 | /* TESTME These are handled through controls | ||
1813 | KEEP until someone can test leaving this out is ok */ | ||
1814 | if (0) { | ||
1815 | /* This is another brightness - don't know why */ | ||
1816 | for (i = 0; i < cit_model1_ntries; i++) | ||
1817 | cit_Packet_Format1(gspca_dev, 0x31, 0xc3); | ||
1818 | for (i = 0; i < cit_model1_ntries; i++) | ||
1819 | cit_Packet_Format1(gspca_dev, 0x32, 0xd2); | ||
1820 | for (i = 0; i < cit_model1_ntries; i++) | ||
1821 | cit_Packet_Format1(gspca_dev, 0x33, 0xe1); | ||
1822 | |||
1823 | /* Default contrast */ | ||
1824 | for (i = 0; i < cit_model1_ntries; i++) | ||
1825 | cit_Packet_Format1(gspca_dev, 0x14, 0x0a); | ||
1826 | |||
1827 | /* Default sharpness */ | ||
1828 | for (i = 0; i < cit_model1_ntries2; i++) | ||
1829 | cit_PacketFormat2(gspca_dev, 0x13, 0x1a); | ||
1830 | |||
1831 | /* Default lighting conditions */ | ||
1832 | cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting); | ||
1833 | } | ||
1834 | |||
1835 | /* Assorted init */ | ||
1836 | switch (gspca_dev->width) { | ||
1837 | case 128: /* 128x96 */ | ||
1838 | cit_Packet_Format1(gspca_dev, 0x2b, 0x1e); | ||
1839 | cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ | ||
1840 | cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */ | ||
1841 | cit_write_reg(gspca_dev, 0x36, 0x0102); | ||
1842 | cit_write_reg(gspca_dev, 0x1a, 0x0104); | ||
1843 | cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */ | ||
1844 | cit_write_reg(gspca_dev, 0x2b, 0x011c); | ||
1845 | cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */ | ||
1846 | break; | ||
1847 | case 176: /* 176x144 */ | ||
1848 | cit_Packet_Format1(gspca_dev, 0x2b, 0x1e); | ||
1849 | cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ | ||
1850 | cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */ | ||
1851 | cit_write_reg(gspca_dev, 0x04, 0x0102); | ||
1852 | cit_write_reg(gspca_dev, 0x02, 0x0104); | ||
1853 | cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */ | ||
1854 | cit_write_reg(gspca_dev, 0x2b, 0x011c); | ||
1855 | cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */ | ||
1856 | break; | ||
1857 | case 352: /* 352x288 */ | ||
1858 | cit_Packet_Format1(gspca_dev, 0x2b, 0x1f); | ||
1859 | cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ | ||
1860 | cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */ | ||
1861 | cit_write_reg(gspca_dev, 0x08, 0x0102); | ||
1862 | cit_write_reg(gspca_dev, 0x01, 0x0104); | ||
1863 | cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */ | ||
1864 | cit_write_reg(gspca_dev, 0x2f, 0x011c); | ||
1865 | cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */ | ||
1866 | break; | ||
1867 | } | ||
1868 | |||
1869 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ | ||
1870 | cit_write_reg(gspca_dev, clock_div, 0x0111); | ||
1871 | |||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | static int cit_start_model2(struct gspca_dev *gspca_dev) | ||
1876 | { | ||
1877 | struct sd *sd = (struct sd *) gspca_dev; | ||
1878 | int clock_div = 0; | ||
1879 | |||
1880 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ | ||
1881 | cit_read_reg(gspca_dev, 0x0116); | ||
1882 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
1883 | cit_write_reg(gspca_dev, 0x0002, 0x0112); | ||
1884 | cit_write_reg(gspca_dev, 0x00bc, 0x012c); | ||
1885 | cit_write_reg(gspca_dev, 0x0008, 0x012b); | ||
1886 | cit_write_reg(gspca_dev, 0x0000, 0x0108); | ||
1887 | cit_write_reg(gspca_dev, 0x0001, 0x0133); | ||
1888 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | ||
1889 | switch (gspca_dev->width) { | ||
1890 | case 176: /* 176x144 */ | ||
1891 | cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ | ||
1892 | cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ | ||
1893 | cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */ | ||
1894 | cit_write_reg(gspca_dev, 0x00b9, 0x010a); /* Unique to this mode */ | ||
1895 | cit_write_reg(gspca_dev, 0x0038, 0x0119); /* Unique to this mode */ | ||
1896 | /* TESTME HDG: this does not seem right | ||
1897 | (it is 2 for all other resolutions) */ | ||
1898 | sd->sof_len = 10; | ||
1899 | break; | ||
1900 | case 320: /* 320x240 */ | ||
1901 | cit_write_reg(gspca_dev, 0x0028, 0x0103); /* Unique to this mode */ | ||
1902 | cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ | ||
1903 | cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */ | ||
1904 | cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */ | ||
1905 | cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ | ||
1906 | sd->sof_len = 2; | ||
1907 | break; | ||
1908 | /* case VIDEOSIZE_352x240: */ | ||
1909 | cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ | ||
1910 | cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ | ||
1911 | cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */ | ||
1912 | cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */ | ||
1913 | cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ | ||
1914 | sd->sof_len = 2; | ||
1915 | break; | ||
1916 | case 352: /* 352x288 */ | ||
1917 | cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ | ||
1918 | cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ | ||
1919 | cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */ | ||
1920 | cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */ | ||
1921 | cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ | ||
1922 | sd->sof_len = 2; | ||
1923 | break; | ||
1924 | } | ||
1925 | |||
1926 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ | ||
1927 | |||
1928 | switch (gspca_dev->width) { | ||
1929 | case 176: /* 176x144 */ | ||
1930 | cit_write_reg(gspca_dev, 0x0050, 0x0111); | ||
1931 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | ||
1932 | break; | ||
1933 | case 320: /* 320x240 */ | ||
1934 | case 352: /* 352x288 */ | ||
1935 | cit_write_reg(gspca_dev, 0x0040, 0x0111); | ||
1936 | cit_write_reg(gspca_dev, 0x00c0, 0x0111); | ||
1937 | break; | ||
1938 | } | ||
1939 | cit_write_reg(gspca_dev, 0x009b, 0x010f); | ||
1940 | cit_write_reg(gspca_dev, 0x00bb, 0x010f); | ||
1941 | |||
1942 | /* | ||
1943 | * Hardware settings, may affect CMOS sensor; not user controls! | ||
1944 | * ------------------------------------------------------------- | ||
1945 | * 0x0004: no effect | ||
1946 | * 0x0006: hardware effect | ||
1947 | * 0x0008: no effect | ||
1948 | * 0x000a: stops video stream, probably important h/w setting | ||
1949 | * 0x000c: changes color in hardware manner (not user setting) | ||
1950 | * 0x0012: changes number of colors (does not affect speed) | ||
1951 | * 0x002a: no effect | ||
1952 | * 0x002c: hardware setting (related to scan lines) | ||
1953 | * 0x002e: stops video stream, probably important h/w setting | ||
1954 | */ | ||
1955 | cit_model2_Packet1(gspca_dev, 0x000a, 0x005c); | ||
1956 | cit_model2_Packet1(gspca_dev, 0x0004, 0x0000); | ||
1957 | cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb); | ||
1958 | cit_model2_Packet1(gspca_dev, 0x0008, 0x0000); | ||
1959 | cit_model2_Packet1(gspca_dev, 0x000c, 0x0009); | ||
1960 | cit_model2_Packet1(gspca_dev, 0x0012, 0x000a); | ||
1961 | cit_model2_Packet1(gspca_dev, 0x002a, 0x0000); | ||
1962 | cit_model2_Packet1(gspca_dev, 0x002c, 0x0000); | ||
1963 | cit_model2_Packet1(gspca_dev, 0x002e, 0x0008); | ||
1964 | |||
1965 | /* | ||
1966 | * Function 0x0030 pops up all over the place. Apparently | ||
1967 | * it is a hardware control register, with every bit assigned to | ||
1968 | * do something. | ||
1969 | */ | ||
1970 | cit_model2_Packet1(gspca_dev, 0x0030, 0x0000); | ||
1971 | |||
1972 | /* | ||
1973 | * Magic control of CMOS sensor. Only lower values like | ||
1974 | * 0-3 work, and picture shifts left or right. Don't change. | ||
1975 | */ | ||
1976 | switch (gspca_dev->width) { | ||
1977 | case 176: /* 176x144 */ | ||
1978 | cit_model2_Packet1(gspca_dev, 0x0014, 0x0002); | ||
1979 | cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ | ||
1980 | cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */ | ||
1981 | clock_div = 6; | ||
1982 | break; | ||
1983 | case 320: /* 320x240 */ | ||
1984 | cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); | ||
1985 | cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */ | ||
1986 | cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */ | ||
1987 | clock_div = 8; | ||
1988 | break; | ||
1989 | /* case VIDEOSIZE_352x240: */ | ||
1990 | /* This mode doesn't work as Windows programs it; changed to work */ | ||
1991 | cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */ | ||
1992 | cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */ | ||
1993 | cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */ | ||
1994 | clock_div = 10; | ||
1995 | break; | ||
1996 | case 352: /* 352x288 */ | ||
1997 | cit_model2_Packet1(gspca_dev, 0x0014, 0x0003); | ||
1998 | cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ | ||
1999 | cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */ | ||
2000 | clock_div = 16; | ||
2001 | break; | ||
2002 | } | ||
2003 | |||
2004 | /* TESTME These are handled through controls | ||
2005 | KEEP until someone can test leaving this out is ok */ | ||
2006 | if (0) | ||
2007 | cit_model2_Packet1(gspca_dev, 0x001a, 0x005a); | ||
2008 | |||
2009 | /* | ||
2010 | * We have our own frame rate setting varying from 0 (slowest) to 6 | ||
2011 | * (fastest). The camera model 2 allows frame rate in range [0..0x1F] | ||
2012 | # where 0 is also the slowest setting. However for all practical | ||
2013 | # reasons high settings make no sense because USB is not fast enough | ||
2014 | # to support high FPS. Be aware that the picture datastream will be | ||
2015 | # severely disrupted if you ask for frame rate faster than allowed | ||
2016 | # for the video size - see below: | ||
2017 | * | ||
2018 | * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz): | ||
2019 | * ----------------------------------------------------------------- | ||
2020 | * 176x144: [6..31] | ||
2021 | * 320x240: [8..31] | ||
2022 | * 352x240: [10..31] | ||
2023 | * 352x288: [16..31] I have to raise lower threshold for stability... | ||
2024 | * | ||
2025 | * As usual, slower FPS provides better sensitivity. | ||
2026 | */ | ||
2027 | cit_model2_Packet1(gspca_dev, 0x001c, clock_div); | ||
2028 | |||
2029 | /* | ||
2030 | * This setting does not visibly affect pictures; left it here | ||
2031 | * because it was present in Windows USB data stream. This function | ||
2032 | * does not allow arbitrary values and apparently is a bit mask, to | ||
2033 | * be activated only at appropriate time. Don't change it randomly! | ||
2034 | */ | ||
2035 | switch (gspca_dev->width) { | ||
2036 | case 176: /* 176x144 */ | ||
2037 | cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2); | ||
2038 | break; | ||
2039 | case 320: /* 320x240 */ | ||
2040 | cit_model2_Packet1(gspca_dev, 0x0026, 0x0044); | ||
2041 | break; | ||
2042 | /* case VIDEOSIZE_352x240: */ | ||
2043 | cit_model2_Packet1(gspca_dev, 0x0026, 0x0046); | ||
2044 | break; | ||
2045 | case 352: /* 352x288 */ | ||
2046 | cit_model2_Packet1(gspca_dev, 0x0026, 0x0048); | ||
2047 | break; | ||
2048 | } | ||
2049 | |||
2050 | /* FIXME this cannot be changed while streaming, so we | ||
2051 | should report a grabbed flag for this control. */ | ||
2052 | cit_model2_Packet1(gspca_dev, 0x0028, sd->lighting); | ||
2053 | /* color balance rg2 */ | ||
2054 | cit_model2_Packet1(gspca_dev, 0x001e, 0x002f); | ||
2055 | /* saturation */ | ||
2056 | cit_model2_Packet1(gspca_dev, 0x0020, 0x0034); | ||
2057 | /* color balance yb */ | ||
2058 | cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0); | ||
2059 | |||
2060 | /* Hardware control command */ | ||
2061 | cit_model2_Packet1(gspca_dev, 0x0030, 0x0004); | ||
2062 | |||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
2066 | static int cit_start_model3(struct gspca_dev *gspca_dev) | ||
2067 | { | ||
2068 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ | ||
2069 | int i, clock_div = 0; | ||
2070 | |||
2071 | /* HDG not in ibmcam driver, added to see if it helps with | ||
2072 | auto-detecting between model3 and ibm netcamera pro */ | ||
2073 | cit_read_reg(gspca_dev, 0x128); | ||
2074 | |||
2075 | cit_write_reg(gspca_dev, 0x0000, 0x0100); | ||
2076 | cit_read_reg(gspca_dev, 0x0116); | ||
2077 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
2078 | cit_write_reg(gspca_dev, 0x0002, 0x0112); | ||
2079 | cit_write_reg(gspca_dev, 0x0000, 0x0123); | ||
2080 | cit_write_reg(gspca_dev, 0x0001, 0x0117); | ||
2081 | cit_write_reg(gspca_dev, 0x0040, 0x0108); | ||
2082 | cit_write_reg(gspca_dev, 0x0019, 0x012c); | ||
2083 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
2084 | cit_write_reg(gspca_dev, 0x0002, 0x0115); | ||
2085 | cit_write_reg(gspca_dev, 0x0003, 0x0115); | ||
2086 | cit_read_reg(gspca_dev, 0x0115); | ||
2087 | cit_write_reg(gspca_dev, 0x000b, 0x0115); | ||
2088 | |||
2089 | /* TESTME HDG not in ibmcam driver, added to see if it helps with | ||
2090 | auto-detecting between model3 and ibm netcamera pro */ | ||
2091 | if (0) { | ||
2092 | cit_write_reg(gspca_dev, 0x0078, 0x012d); | ||
2093 | cit_write_reg(gspca_dev, 0x0001, 0x012f); | ||
2094 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2095 | cit_write_reg(gspca_dev, 0x0079, 0x012d); | ||
2096 | cit_write_reg(gspca_dev, 0x00ff, 0x0130); | ||
2097 | cit_write_reg(gspca_dev, 0xcd41, 0x0124); | ||
2098 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2099 | cit_read_reg(gspca_dev, 0x0126); | ||
2100 | } | ||
2101 | |||
2102 | cit_model3_Packet1(gspca_dev, 0x000a, 0x0040); | ||
2103 | cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6); | ||
2104 | cit_model3_Packet1(gspca_dev, 0x000c, 0x0002); | ||
2105 | cit_model3_Packet1(gspca_dev, 0x000d, 0x0020); | ||
2106 | cit_model3_Packet1(gspca_dev, 0x000e, 0x0033); | ||
2107 | cit_model3_Packet1(gspca_dev, 0x000f, 0x0007); | ||
2108 | cit_model3_Packet1(gspca_dev, 0x0010, 0x0000); | ||
2109 | cit_model3_Packet1(gspca_dev, 0x0011, 0x0070); | ||
2110 | cit_model3_Packet1(gspca_dev, 0x0012, 0x0030); | ||
2111 | cit_model3_Packet1(gspca_dev, 0x0013, 0x0000); | ||
2112 | cit_model3_Packet1(gspca_dev, 0x0014, 0x0001); | ||
2113 | cit_model3_Packet1(gspca_dev, 0x0015, 0x0001); | ||
2114 | cit_model3_Packet1(gspca_dev, 0x0016, 0x0001); | ||
2115 | cit_model3_Packet1(gspca_dev, 0x0017, 0x0001); | ||
2116 | cit_model3_Packet1(gspca_dev, 0x0018, 0x0000); | ||
2117 | cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3); | ||
2118 | cit_model3_Packet1(gspca_dev, 0x0020, 0x0000); | ||
2119 | cit_model3_Packet1(gspca_dev, 0x0028, 0x0010); | ||
2120 | cit_model3_Packet1(gspca_dev, 0x0029, 0x0054); | ||
2121 | cit_model3_Packet1(gspca_dev, 0x002a, 0x0013); | ||
2122 | cit_model3_Packet1(gspca_dev, 0x002b, 0x0007); | ||
2123 | cit_model3_Packet1(gspca_dev, 0x002d, 0x0028); | ||
2124 | cit_model3_Packet1(gspca_dev, 0x002e, 0x0000); | ||
2125 | cit_model3_Packet1(gspca_dev, 0x0031, 0x0000); | ||
2126 | cit_model3_Packet1(gspca_dev, 0x0032, 0x0000); | ||
2127 | cit_model3_Packet1(gspca_dev, 0x0033, 0x0000); | ||
2128 | cit_model3_Packet1(gspca_dev, 0x0034, 0x0000); | ||
2129 | cit_model3_Packet1(gspca_dev, 0x0035, 0x0038); | ||
2130 | cit_model3_Packet1(gspca_dev, 0x003a, 0x0001); | ||
2131 | cit_model3_Packet1(gspca_dev, 0x003c, 0x001e); | ||
2132 | cit_model3_Packet1(gspca_dev, 0x003f, 0x000a); | ||
2133 | cit_model3_Packet1(gspca_dev, 0x0041, 0x0000); | ||
2134 | cit_model3_Packet1(gspca_dev, 0x0046, 0x003f); | ||
2135 | cit_model3_Packet1(gspca_dev, 0x0047, 0x0000); | ||
2136 | cit_model3_Packet1(gspca_dev, 0x0050, 0x0005); | ||
2137 | cit_model3_Packet1(gspca_dev, 0x0052, 0x001a); | ||
2138 | cit_model3_Packet1(gspca_dev, 0x0053, 0x0003); | ||
2139 | cit_model3_Packet1(gspca_dev, 0x005a, 0x006b); | ||
2140 | cit_model3_Packet1(gspca_dev, 0x005d, 0x001e); | ||
2141 | cit_model3_Packet1(gspca_dev, 0x005e, 0x0030); | ||
2142 | cit_model3_Packet1(gspca_dev, 0x005f, 0x0041); | ||
2143 | cit_model3_Packet1(gspca_dev, 0x0064, 0x0008); | ||
2144 | cit_model3_Packet1(gspca_dev, 0x0065, 0x0015); | ||
2145 | cit_model3_Packet1(gspca_dev, 0x0068, 0x000f); | ||
2146 | cit_model3_Packet1(gspca_dev, 0x0079, 0x0000); | ||
2147 | cit_model3_Packet1(gspca_dev, 0x007a, 0x0000); | ||
2148 | cit_model3_Packet1(gspca_dev, 0x007c, 0x003f); | ||
2149 | cit_model3_Packet1(gspca_dev, 0x0082, 0x000f); | ||
2150 | cit_model3_Packet1(gspca_dev, 0x0085, 0x0000); | ||
2151 | cit_model3_Packet1(gspca_dev, 0x0099, 0x0000); | ||
2152 | cit_model3_Packet1(gspca_dev, 0x009b, 0x0023); | ||
2153 | cit_model3_Packet1(gspca_dev, 0x009c, 0x0022); | ||
2154 | cit_model3_Packet1(gspca_dev, 0x009d, 0x0096); | ||
2155 | cit_model3_Packet1(gspca_dev, 0x009e, 0x0096); | ||
2156 | cit_model3_Packet1(gspca_dev, 0x009f, 0x000a); | ||
2157 | |||
2158 | switch (gspca_dev->width) { | ||
2159 | case 160: | ||
2160 | cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ | ||
2161 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ | ||
2162 | cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */ | ||
2163 | cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ | ||
2164 | cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */ | ||
2165 | cit_write_reg(gspca_dev, 0x00a9, 0x0119); | ||
2166 | cit_write_reg(gspca_dev, 0x0016, 0x011b); | ||
2167 | cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */ | ||
2168 | cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */ | ||
2169 | cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ | ||
2170 | cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ | ||
2171 | cit_write_reg(gspca_dev, 0x0018, 0x0102); | ||
2172 | cit_write_reg(gspca_dev, 0x0004, 0x0104); | ||
2173 | cit_write_reg(gspca_dev, 0x0004, 0x011a); | ||
2174 | cit_write_reg(gspca_dev, 0x0028, 0x011c); | ||
2175 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ | ||
2176 | cit_write_reg(gspca_dev, 0x0000, 0x0118); | ||
2177 | cit_write_reg(gspca_dev, 0x0000, 0x0132); | ||
2178 | cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */ | ||
2179 | cit_write_reg(gspca_dev, compression, 0x0109); | ||
2180 | clock_div = 3; | ||
2181 | break; | ||
2182 | case 320: | ||
2183 | cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ | ||
2184 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ | ||
2185 | cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */ | ||
2186 | cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ | ||
2187 | cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */ | ||
2188 | cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */ | ||
2189 | cit_write_reg(gspca_dev, 0x0000, 0x011e); | ||
2190 | cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ | ||
2191 | cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ | ||
2192 | /* 4 commands from 160x120 skipped */ | ||
2193 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ | ||
2194 | cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */ | ||
2195 | cit_write_reg(gspca_dev, compression, 0x0109); | ||
2196 | cit_write_reg(gspca_dev, 0x00d9, 0x0119); | ||
2197 | cit_write_reg(gspca_dev, 0x0006, 0x011b); | ||
2198 | cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */ | ||
2199 | cit_write_reg(gspca_dev, 0x0010, 0x0104); | ||
2200 | cit_write_reg(gspca_dev, 0x0004, 0x011a); | ||
2201 | cit_write_reg(gspca_dev, 0x003f, 0x011c); | ||
2202 | cit_write_reg(gspca_dev, 0x001c, 0x0118); | ||
2203 | cit_write_reg(gspca_dev, 0x0000, 0x0132); | ||
2204 | clock_div = 5; | ||
2205 | break; | ||
2206 | case 640: | ||
2207 | cit_write_reg(gspca_dev, 0x00f0, 0x0105); | ||
2208 | cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ | ||
2209 | cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */ | ||
2210 | cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */ | ||
2211 | cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */ | ||
2212 | cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */ | ||
2213 | cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */ | ||
2214 | cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ | ||
2215 | cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ | ||
2216 | cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */ | ||
2217 | cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */ | ||
2218 | cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */ | ||
2219 | cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */ | ||
2220 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ | ||
2221 | cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */ | ||
2222 | cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */ | ||
2223 | cit_write_reg(gspca_dev, compression, 0x0109); | ||
2224 | cit_write_reg(gspca_dev, 0x0040, 0x0101); | ||
2225 | cit_write_reg(gspca_dev, 0x0040, 0x0103); | ||
2226 | cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */ | ||
2227 | clock_div = 7; | ||
2228 | break; | ||
2229 | } | ||
2230 | |||
2231 | cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); /* Hue */ | ||
2232 | cit_model3_Packet1(gspca_dev, 0x0036, 0x0011); /* Brightness */ | ||
2233 | cit_model3_Packet1(gspca_dev, 0x0060, 0x0002); /* Sharpness */ | ||
2234 | cit_model3_Packet1(gspca_dev, 0x0061, 0x0004); /* Sharpness */ | ||
2235 | cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); /* Sharpness */ | ||
2236 | cit_model3_Packet1(gspca_dev, 0x0063, 0x0014); /* Sharpness */ | ||
2237 | cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */ | ||
2238 | cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */ | ||
2239 | cit_model3_Packet1(gspca_dev, 0x0067, 0x0001); /* Contrast */ | ||
2240 | cit_model3_Packet1(gspca_dev, 0x005b, 0x000c); /* Contrast */ | ||
2241 | cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); /* Contrast */ | ||
2242 | cit_model3_Packet1(gspca_dev, 0x0098, 0x000b); | ||
2243 | cit_model3_Packet1(gspca_dev, 0x002c, 0x0003); /* Was 1, broke 640x480 */ | ||
2244 | cit_model3_Packet1(gspca_dev, 0x002f, 0x002a); | ||
2245 | cit_model3_Packet1(gspca_dev, 0x0030, 0x0029); | ||
2246 | cit_model3_Packet1(gspca_dev, 0x0037, 0x0002); | ||
2247 | cit_model3_Packet1(gspca_dev, 0x0038, 0x0059); | ||
2248 | cit_model3_Packet1(gspca_dev, 0x003d, 0x002e); | ||
2249 | cit_model3_Packet1(gspca_dev, 0x003e, 0x0028); | ||
2250 | cit_model3_Packet1(gspca_dev, 0x0078, 0x0005); | ||
2251 | cit_model3_Packet1(gspca_dev, 0x007b, 0x0011); | ||
2252 | cit_model3_Packet1(gspca_dev, 0x007d, 0x004b); | ||
2253 | cit_model3_Packet1(gspca_dev, 0x007f, 0x0022); | ||
2254 | cit_model3_Packet1(gspca_dev, 0x0080, 0x000c); | ||
2255 | cit_model3_Packet1(gspca_dev, 0x0081, 0x000b); | ||
2256 | cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd); | ||
2257 | cit_model3_Packet1(gspca_dev, 0x0086, 0x000b); | ||
2258 | cit_model3_Packet1(gspca_dev, 0x0087, 0x000b); | ||
2259 | cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); | ||
2260 | cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */ | ||
2261 | cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */ | ||
2262 | cit_model3_Packet1(gspca_dev, 0x0098, 0x000b); | ||
2263 | |||
2264 | /* FIXME we should probably use cit_get_clock_div() here (in | ||
2265 | combination with isoc negotiation using the programmable isoc size) | ||
2266 | like with the IBM netcam pro). */ | ||
2267 | cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */ | ||
2268 | |||
2269 | switch (gspca_dev->width) { | ||
2270 | case 160: | ||
2271 | cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */ | ||
2272 | cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */ | ||
2273 | cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */ | ||
2274 | cit_model3_Packet1(gspca_dev, 0x0040, 0x000a); | ||
2275 | cit_model3_Packet1(gspca_dev, 0x0051, 0x000a); | ||
2276 | break; | ||
2277 | case 320: | ||
2278 | cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */ | ||
2279 | cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */ | ||
2280 | cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */ | ||
2281 | cit_model3_Packet1(gspca_dev, 0x0040, 0x0008); | ||
2282 | cit_model3_Packet1(gspca_dev, 0x0051, 0x000b); | ||
2283 | break; | ||
2284 | case 640: | ||
2285 | cit_model3_Packet1(gspca_dev, 0x001f, 0x0002); /* !Same */ | ||
2286 | cit_model3_Packet1(gspca_dev, 0x0039, 0x003e); /* !Same */ | ||
2287 | cit_model3_Packet1(gspca_dev, 0x0040, 0x0008); | ||
2288 | cit_model3_Packet1(gspca_dev, 0x0051, 0x000a); | ||
2289 | break; | ||
2290 | } | ||
2291 | |||
2292 | /* if (sd->input_index) { */ | ||
2293 | if (rca_input) { | ||
2294 | for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { | ||
2295 | if (rca_initdata[i][0]) | ||
2296 | cit_read_reg(gspca_dev, rca_initdata[i][2]); | ||
2297 | else | ||
2298 | cit_write_reg(gspca_dev, rca_initdata[i][1], | ||
2299 | rca_initdata[i][2]); | ||
2300 | } | ||
2301 | } | ||
2302 | |||
2303 | return 0; | ||
2304 | } | ||
2305 | |||
2306 | static int cit_start_model4(struct gspca_dev *gspca_dev) | ||
2307 | { | ||
2308 | struct sd *sd = (struct sd *) gspca_dev; | ||
2309 | |||
2310 | cit_write_reg(gspca_dev, 0x0000, 0x0100); | ||
2311 | cit_write_reg(gspca_dev, 0x00c0, 0x0111); | ||
2312 | cit_write_reg(gspca_dev, 0x00bc, 0x012c); | ||
2313 | cit_write_reg(gspca_dev, 0x0080, 0x012b); | ||
2314 | cit_write_reg(gspca_dev, 0x0000, 0x0108); | ||
2315 | cit_write_reg(gspca_dev, 0x0001, 0x0133); | ||
2316 | cit_write_reg(gspca_dev, 0x009b, 0x010f); | ||
2317 | cit_write_reg(gspca_dev, 0x00bb, 0x010f); | ||
2318 | cit_model4_Packet1(gspca_dev, 0x0038, 0x0000); | ||
2319 | cit_model4_Packet1(gspca_dev, 0x000a, 0x005c); | ||
2320 | |||
2321 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2322 | cit_write_reg(gspca_dev, 0x0004, 0x012f); | ||
2323 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2324 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2325 | cit_write_reg(gspca_dev, 0x00fb, 0x012e); | ||
2326 | cit_write_reg(gspca_dev, 0x0000, 0x0130); | ||
2327 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2328 | cit_write_reg(gspca_dev, 0x00aa, 0x012f); | ||
2329 | cit_write_reg(gspca_dev, 0xd055, 0x0124); | ||
2330 | cit_write_reg(gspca_dev, 0x000c, 0x0127); | ||
2331 | cit_write_reg(gspca_dev, 0x0009, 0x012e); | ||
2332 | cit_write_reg(gspca_dev, 0xaa28, 0x0124); | ||
2333 | |||
2334 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2335 | cit_write_reg(gspca_dev, 0x0012, 0x012f); | ||
2336 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2337 | cit_write_reg(gspca_dev, 0x0008, 0x0127); | ||
2338 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2339 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2340 | cit_write_reg(gspca_dev, 0x002a, 0x012d); | ||
2341 | cit_write_reg(gspca_dev, 0x0000, 0x012f); | ||
2342 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2343 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2344 | cit_model4_Packet1(gspca_dev, 0x0034, 0x0000); | ||
2345 | |||
2346 | switch (gspca_dev->width) { | ||
2347 | case 128: /* 128x96 */ | ||
2348 | cit_write_reg(gspca_dev, 0x0070, 0x0119); | ||
2349 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | ||
2350 | cit_write_reg(gspca_dev, 0x0039, 0x010a); | ||
2351 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | ||
2352 | cit_write_reg(gspca_dev, 0x0028, 0x0103); | ||
2353 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
2354 | cit_write_reg(gspca_dev, 0x001e, 0x0105); | ||
2355 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2356 | cit_write_reg(gspca_dev, 0x0016, 0x012f); | ||
2357 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2358 | cit_write_reg(gspca_dev, 0x000a, 0x0127); | ||
2359 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2360 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2361 | cit_write_reg(gspca_dev, 0x0014, 0x012d); | ||
2362 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2363 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2364 | cit_write_reg(gspca_dev, 0x00aa, 0x012e); | ||
2365 | cit_write_reg(gspca_dev, 0x001a, 0x0130); | ||
2366 | cit_write_reg(gspca_dev, 0x8a0a, 0x0124); | ||
2367 | cit_write_reg(gspca_dev, 0x005a, 0x012d); | ||
2368 | cit_write_reg(gspca_dev, 0x9545, 0x0124); | ||
2369 | cit_write_reg(gspca_dev, 0x00aa, 0x0127); | ||
2370 | cit_write_reg(gspca_dev, 0x0018, 0x012e); | ||
2371 | cit_write_reg(gspca_dev, 0x0043, 0x0130); | ||
2372 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2373 | cit_write_reg(gspca_dev, 0x00aa, 0x012f); | ||
2374 | cit_write_reg(gspca_dev, 0xd055, 0x0124); | ||
2375 | cit_write_reg(gspca_dev, 0x001c, 0x0127); | ||
2376 | cit_write_reg(gspca_dev, 0x00eb, 0x012e); | ||
2377 | cit_write_reg(gspca_dev, 0xaa28, 0x0124); | ||
2378 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2379 | cit_write_reg(gspca_dev, 0x0032, 0x012f); | ||
2380 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2381 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2382 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2383 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2384 | cit_write_reg(gspca_dev, 0x0036, 0x012d); | ||
2385 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2386 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2387 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2388 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2389 | cit_write_reg(gspca_dev, 0x001e, 0x012f); | ||
2390 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2391 | cit_write_reg(gspca_dev, 0x0017, 0x0127); | ||
2392 | cit_write_reg(gspca_dev, 0x0013, 0x012e); | ||
2393 | cit_write_reg(gspca_dev, 0x0031, 0x0130); | ||
2394 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2395 | cit_write_reg(gspca_dev, 0x0017, 0x012d); | ||
2396 | cit_write_reg(gspca_dev, 0x0078, 0x012f); | ||
2397 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2398 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2399 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
2400 | sd->sof_len = 2; | ||
2401 | break; | ||
2402 | case 160: /* 160x120 */ | ||
2403 | cit_write_reg(gspca_dev, 0x0038, 0x0119); | ||
2404 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | ||
2405 | cit_write_reg(gspca_dev, 0x00b9, 0x010a); | ||
2406 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | ||
2407 | cit_write_reg(gspca_dev, 0x0028, 0x0103); | ||
2408 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
2409 | cit_write_reg(gspca_dev, 0x001e, 0x0105); | ||
2410 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2411 | cit_write_reg(gspca_dev, 0x0016, 0x012f); | ||
2412 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2413 | cit_write_reg(gspca_dev, 0x000b, 0x0127); | ||
2414 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2415 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2416 | cit_write_reg(gspca_dev, 0x0014, 0x012d); | ||
2417 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2418 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2419 | cit_write_reg(gspca_dev, 0x00aa, 0x012e); | ||
2420 | cit_write_reg(gspca_dev, 0x001a, 0x0130); | ||
2421 | cit_write_reg(gspca_dev, 0x8a0a, 0x0124); | ||
2422 | cit_write_reg(gspca_dev, 0x005a, 0x012d); | ||
2423 | cit_write_reg(gspca_dev, 0x9545, 0x0124); | ||
2424 | cit_write_reg(gspca_dev, 0x00aa, 0x0127); | ||
2425 | cit_write_reg(gspca_dev, 0x0018, 0x012e); | ||
2426 | cit_write_reg(gspca_dev, 0x0043, 0x0130); | ||
2427 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2428 | cit_write_reg(gspca_dev, 0x00aa, 0x012f); | ||
2429 | cit_write_reg(gspca_dev, 0xd055, 0x0124); | ||
2430 | cit_write_reg(gspca_dev, 0x001c, 0x0127); | ||
2431 | cit_write_reg(gspca_dev, 0x00c7, 0x012e); | ||
2432 | cit_write_reg(gspca_dev, 0xaa28, 0x0124); | ||
2433 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2434 | cit_write_reg(gspca_dev, 0x0032, 0x012f); | ||
2435 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2436 | cit_write_reg(gspca_dev, 0x0025, 0x0127); | ||
2437 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2438 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2439 | cit_write_reg(gspca_dev, 0x0036, 0x012d); | ||
2440 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2441 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2442 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2443 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2444 | cit_write_reg(gspca_dev, 0x001e, 0x012f); | ||
2445 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2446 | cit_write_reg(gspca_dev, 0x0048, 0x0127); | ||
2447 | cit_write_reg(gspca_dev, 0x0035, 0x012e); | ||
2448 | cit_write_reg(gspca_dev, 0x00d0, 0x0130); | ||
2449 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2450 | cit_write_reg(gspca_dev, 0x0048, 0x012d); | ||
2451 | cit_write_reg(gspca_dev, 0x0090, 0x012f); | ||
2452 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2453 | cit_write_reg(gspca_dev, 0x0001, 0x0127); | ||
2454 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
2455 | sd->sof_len = 2; | ||
2456 | break; | ||
2457 | case 176: /* 176x144 */ | ||
2458 | cit_write_reg(gspca_dev, 0x0038, 0x0119); | ||
2459 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | ||
2460 | cit_write_reg(gspca_dev, 0x00b9, 0x010a); | ||
2461 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | ||
2462 | cit_write_reg(gspca_dev, 0x002c, 0x0103); | ||
2463 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
2464 | cit_write_reg(gspca_dev, 0x0024, 0x0105); | ||
2465 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2466 | cit_write_reg(gspca_dev, 0x0016, 0x012f); | ||
2467 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2468 | cit_write_reg(gspca_dev, 0x0007, 0x0127); | ||
2469 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2470 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2471 | cit_write_reg(gspca_dev, 0x0014, 0x012d); | ||
2472 | cit_write_reg(gspca_dev, 0x0001, 0x012f); | ||
2473 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2474 | cit_write_reg(gspca_dev, 0x00aa, 0x012e); | ||
2475 | cit_write_reg(gspca_dev, 0x001a, 0x0130); | ||
2476 | cit_write_reg(gspca_dev, 0x8a0a, 0x0124); | ||
2477 | cit_write_reg(gspca_dev, 0x005e, 0x012d); | ||
2478 | cit_write_reg(gspca_dev, 0x9545, 0x0124); | ||
2479 | cit_write_reg(gspca_dev, 0x00aa, 0x0127); | ||
2480 | cit_write_reg(gspca_dev, 0x0018, 0x012e); | ||
2481 | cit_write_reg(gspca_dev, 0x0049, 0x0130); | ||
2482 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2483 | cit_write_reg(gspca_dev, 0x00aa, 0x012f); | ||
2484 | cit_write_reg(gspca_dev, 0xd055, 0x0124); | ||
2485 | cit_write_reg(gspca_dev, 0x001c, 0x0127); | ||
2486 | cit_write_reg(gspca_dev, 0x00c7, 0x012e); | ||
2487 | cit_write_reg(gspca_dev, 0xaa28, 0x0124); | ||
2488 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2489 | cit_write_reg(gspca_dev, 0x0032, 0x012f); | ||
2490 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2491 | cit_write_reg(gspca_dev, 0x0028, 0x0127); | ||
2492 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2493 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2494 | cit_write_reg(gspca_dev, 0x0036, 0x012d); | ||
2495 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2496 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2497 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2498 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2499 | cit_write_reg(gspca_dev, 0x001e, 0x012f); | ||
2500 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2501 | cit_write_reg(gspca_dev, 0x0010, 0x0127); | ||
2502 | cit_write_reg(gspca_dev, 0x0013, 0x012e); | ||
2503 | cit_write_reg(gspca_dev, 0x002a, 0x0130); | ||
2504 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2505 | cit_write_reg(gspca_dev, 0x0010, 0x012d); | ||
2506 | cit_write_reg(gspca_dev, 0x006d, 0x012f); | ||
2507 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2508 | cit_write_reg(gspca_dev, 0x0001, 0x0127); | ||
2509 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
2510 | /* TESTME HDG: this does not seem right | ||
2511 | (it is 2 for all other resolutions) */ | ||
2512 | sd->sof_len = 10; | ||
2513 | break; | ||
2514 | case 320: /* 320x240 */ | ||
2515 | cit_write_reg(gspca_dev, 0x0070, 0x0119); | ||
2516 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | ||
2517 | cit_write_reg(gspca_dev, 0x0039, 0x010a); | ||
2518 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | ||
2519 | cit_write_reg(gspca_dev, 0x0028, 0x0103); | ||
2520 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
2521 | cit_write_reg(gspca_dev, 0x001e, 0x0105); | ||
2522 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2523 | cit_write_reg(gspca_dev, 0x0016, 0x012f); | ||
2524 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2525 | cit_write_reg(gspca_dev, 0x000a, 0x0127); | ||
2526 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2527 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2528 | cit_write_reg(gspca_dev, 0x0014, 0x012d); | ||
2529 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2530 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2531 | cit_write_reg(gspca_dev, 0x00aa, 0x012e); | ||
2532 | cit_write_reg(gspca_dev, 0x001a, 0x0130); | ||
2533 | cit_write_reg(gspca_dev, 0x8a0a, 0x0124); | ||
2534 | cit_write_reg(gspca_dev, 0x005a, 0x012d); | ||
2535 | cit_write_reg(gspca_dev, 0x9545, 0x0124); | ||
2536 | cit_write_reg(gspca_dev, 0x00aa, 0x0127); | ||
2537 | cit_write_reg(gspca_dev, 0x0018, 0x012e); | ||
2538 | cit_write_reg(gspca_dev, 0x0043, 0x0130); | ||
2539 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2540 | cit_write_reg(gspca_dev, 0x00aa, 0x012f); | ||
2541 | cit_write_reg(gspca_dev, 0xd055, 0x0124); | ||
2542 | cit_write_reg(gspca_dev, 0x001c, 0x0127); | ||
2543 | cit_write_reg(gspca_dev, 0x00eb, 0x012e); | ||
2544 | cit_write_reg(gspca_dev, 0xaa28, 0x0124); | ||
2545 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2546 | cit_write_reg(gspca_dev, 0x0032, 0x012f); | ||
2547 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2548 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2549 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2550 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2551 | cit_write_reg(gspca_dev, 0x0036, 0x012d); | ||
2552 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2553 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2554 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2555 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2556 | cit_write_reg(gspca_dev, 0x001e, 0x012f); | ||
2557 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2558 | cit_write_reg(gspca_dev, 0x0017, 0x0127); | ||
2559 | cit_write_reg(gspca_dev, 0x0013, 0x012e); | ||
2560 | cit_write_reg(gspca_dev, 0x0031, 0x0130); | ||
2561 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2562 | cit_write_reg(gspca_dev, 0x0017, 0x012d); | ||
2563 | cit_write_reg(gspca_dev, 0x0078, 0x012f); | ||
2564 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2565 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2566 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
2567 | sd->sof_len = 2; | ||
2568 | break; | ||
2569 | case 352: /* 352x288 */ | ||
2570 | cit_write_reg(gspca_dev, 0x0070, 0x0119); | ||
2571 | cit_write_reg(gspca_dev, 0x00c0, 0x0111); | ||
2572 | cit_write_reg(gspca_dev, 0x0039, 0x010a); | ||
2573 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | ||
2574 | cit_write_reg(gspca_dev, 0x002c, 0x0103); | ||
2575 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
2576 | cit_write_reg(gspca_dev, 0x0024, 0x0105); | ||
2577 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2578 | cit_write_reg(gspca_dev, 0x0016, 0x012f); | ||
2579 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2580 | cit_write_reg(gspca_dev, 0x0006, 0x0127); | ||
2581 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2582 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2583 | cit_write_reg(gspca_dev, 0x0014, 0x012d); | ||
2584 | cit_write_reg(gspca_dev, 0x0002, 0x012f); | ||
2585 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2586 | cit_write_reg(gspca_dev, 0x00aa, 0x012e); | ||
2587 | cit_write_reg(gspca_dev, 0x001a, 0x0130); | ||
2588 | cit_write_reg(gspca_dev, 0x8a0a, 0x0124); | ||
2589 | cit_write_reg(gspca_dev, 0x005e, 0x012d); | ||
2590 | cit_write_reg(gspca_dev, 0x9545, 0x0124); | ||
2591 | cit_write_reg(gspca_dev, 0x00aa, 0x0127); | ||
2592 | cit_write_reg(gspca_dev, 0x0018, 0x012e); | ||
2593 | cit_write_reg(gspca_dev, 0x0049, 0x0130); | ||
2594 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2595 | cit_write_reg(gspca_dev, 0x00aa, 0x012f); | ||
2596 | cit_write_reg(gspca_dev, 0xd055, 0x0124); | ||
2597 | cit_write_reg(gspca_dev, 0x001c, 0x0127); | ||
2598 | cit_write_reg(gspca_dev, 0x00cf, 0x012e); | ||
2599 | cit_write_reg(gspca_dev, 0xaa28, 0x0124); | ||
2600 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2601 | cit_write_reg(gspca_dev, 0x0032, 0x012f); | ||
2602 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2603 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2604 | cit_write_reg(gspca_dev, 0x00aa, 0x0130); | ||
2605 | cit_write_reg(gspca_dev, 0x82a8, 0x0124); | ||
2606 | cit_write_reg(gspca_dev, 0x0036, 0x012d); | ||
2607 | cit_write_reg(gspca_dev, 0x0008, 0x012f); | ||
2608 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2609 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | ||
2610 | cit_write_reg(gspca_dev, 0x00aa, 0x012d); | ||
2611 | cit_write_reg(gspca_dev, 0x001e, 0x012f); | ||
2612 | cit_write_reg(gspca_dev, 0xd141, 0x0124); | ||
2613 | cit_write_reg(gspca_dev, 0x0010, 0x0127); | ||
2614 | cit_write_reg(gspca_dev, 0x0013, 0x012e); | ||
2615 | cit_write_reg(gspca_dev, 0x0025, 0x0130); | ||
2616 | cit_write_reg(gspca_dev, 0x8a28, 0x0124); | ||
2617 | cit_write_reg(gspca_dev, 0x0010, 0x012d); | ||
2618 | cit_write_reg(gspca_dev, 0x0048, 0x012f); | ||
2619 | cit_write_reg(gspca_dev, 0xd145, 0x0124); | ||
2620 | cit_write_reg(gspca_dev, 0x0000, 0x0127); | ||
2621 | cit_write_reg(gspca_dev, 0xfea8, 0x0124); | ||
2622 | sd->sof_len = 2; | ||
2623 | break; | ||
2624 | } | ||
2625 | |||
2626 | cit_model4_Packet1(gspca_dev, 0x0038, 0x0004); | ||
2627 | |||
2628 | return 0; | ||
2629 | } | ||
2630 | |||
2631 | static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | ||
2632 | { | ||
2633 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ | ||
2634 | int i, clock_div; | ||
2635 | |||
2636 | clock_div = cit_get_clock_div(gspca_dev); | ||
2637 | if (clock_div < 0) | ||
2638 | return clock_div; | ||
2639 | |||
2640 | cit_write_reg(gspca_dev, 0x0003, 0x0133); | ||
2641 | cit_write_reg(gspca_dev, 0x0000, 0x0117); | ||
2642 | cit_write_reg(gspca_dev, 0x0008, 0x0123); | ||
2643 | cit_write_reg(gspca_dev, 0x0000, 0x0100); | ||
2644 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
2645 | /* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */ | ||
2646 | cit_write_reg(gspca_dev, 0x0000, 0x0133); | ||
2647 | cit_write_reg(gspca_dev, 0x0000, 0x0123); | ||
2648 | cit_write_reg(gspca_dev, 0x0001, 0x0117); | ||
2649 | cit_write_reg(gspca_dev, 0x0040, 0x0108); | ||
2650 | cit_write_reg(gspca_dev, 0x0019, 0x012c); | ||
2651 | cit_write_reg(gspca_dev, 0x0060, 0x0116); | ||
2652 | /* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */ | ||
2653 | |||
2654 | cit_model3_Packet1(gspca_dev, 0x0049, 0x0000); | ||
2655 | |||
2656 | cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ | ||
2657 | cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */ | ||
2658 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ | ||
2659 | cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */ | ||
2660 | cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ | ||
2661 | cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */ | ||
2662 | cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ | ||
2663 | cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ | ||
2664 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ | ||
2665 | |||
2666 | switch (gspca_dev->width) { | ||
2667 | case 160: /* 160x120 */ | ||
2668 | cit_write_reg(gspca_dev, 0x0024, 0x010b); | ||
2669 | cit_write_reg(gspca_dev, 0x0089, 0x0119); | ||
2670 | cit_write_reg(gspca_dev, 0x000a, 0x011b); | ||
2671 | cit_write_reg(gspca_dev, 0x0003, 0x011e); | ||
2672 | cit_write_reg(gspca_dev, 0x0007, 0x0104); | ||
2673 | cit_write_reg(gspca_dev, 0x0009, 0x011a); | ||
2674 | cit_write_reg(gspca_dev, 0x008b, 0x011c); | ||
2675 | cit_write_reg(gspca_dev, 0x0008, 0x0118); | ||
2676 | cit_write_reg(gspca_dev, 0x0000, 0x0132); | ||
2677 | break; | ||
2678 | case 320: /* 320x240 */ | ||
2679 | cit_write_reg(gspca_dev, 0x0028, 0x010b); | ||
2680 | cit_write_reg(gspca_dev, 0x00d9, 0x0119); | ||
2681 | cit_write_reg(gspca_dev, 0x0006, 0x011b); | ||
2682 | cit_write_reg(gspca_dev, 0x0000, 0x011e); | ||
2683 | cit_write_reg(gspca_dev, 0x000e, 0x0104); | ||
2684 | cit_write_reg(gspca_dev, 0x0004, 0x011a); | ||
2685 | cit_write_reg(gspca_dev, 0x003f, 0x011c); | ||
2686 | cit_write_reg(gspca_dev, 0x000c, 0x0118); | ||
2687 | cit_write_reg(gspca_dev, 0x0000, 0x0132); | ||
2688 | break; | ||
2689 | } | ||
2690 | |||
2691 | cit_model3_Packet1(gspca_dev, 0x0019, 0x0031); | ||
2692 | cit_model3_Packet1(gspca_dev, 0x001a, 0x0003); | ||
2693 | cit_model3_Packet1(gspca_dev, 0x001b, 0x0038); | ||
2694 | cit_model3_Packet1(gspca_dev, 0x001c, 0x0000); | ||
2695 | cit_model3_Packet1(gspca_dev, 0x0024, 0x0001); | ||
2696 | cit_model3_Packet1(gspca_dev, 0x0027, 0x0001); | ||
2697 | cit_model3_Packet1(gspca_dev, 0x002a, 0x0004); | ||
2698 | cit_model3_Packet1(gspca_dev, 0x0035, 0x000b); | ||
2699 | cit_model3_Packet1(gspca_dev, 0x003f, 0x0001); | ||
2700 | cit_model3_Packet1(gspca_dev, 0x0044, 0x0000); | ||
2701 | cit_model3_Packet1(gspca_dev, 0x0054, 0x0000); | ||
2702 | cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000); | ||
2703 | cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001); | ||
2704 | cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001); | ||
2705 | cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000); | ||
2706 | cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0); | ||
2707 | |||
2708 | cit_write_reg(gspca_dev, compression, 0x0109); | ||
2709 | cit_write_reg(gspca_dev, clock_div, 0x0111); | ||
2710 | |||
2711 | /* if (sd->input_index) { */ | ||
2712 | if (rca_input) { | ||
2713 | for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { | ||
2714 | if (rca_initdata[i][0]) | ||
2715 | cit_read_reg(gspca_dev, rca_initdata[i][2]); | ||
2716 | else | ||
2717 | cit_write_reg(gspca_dev, rca_initdata[i][1], | ||
2718 | rca_initdata[i][2]); | ||
2719 | } | ||
2720 | } | ||
2721 | |||
2722 | return 0; | ||
2723 | } | ||
2724 | |||
2725 | /* -- start the camera -- */ | ||
2726 | static int sd_start(struct gspca_dev *gspca_dev) | ||
2727 | { | ||
2728 | struct sd *sd = (struct sd *) gspca_dev; | ||
2729 | int packet_size; | ||
2730 | |||
2731 | packet_size = cit_get_packet_size(gspca_dev); | ||
2732 | if (packet_size < 0) | ||
2733 | return packet_size; | ||
2734 | |||
2735 | switch (sd->model) { | ||
2736 | case CIT_MODEL0: | ||
2737 | cit_start_model0(gspca_dev); | ||
2738 | break; | ||
2739 | case CIT_MODEL1: | ||
2740 | cit_start_model1(gspca_dev); | ||
2741 | break; | ||
2742 | case CIT_MODEL2: | ||
2743 | cit_start_model2(gspca_dev); | ||
2744 | break; | ||
2745 | case CIT_MODEL3: | ||
2746 | cit_start_model3(gspca_dev); | ||
2747 | break; | ||
2748 | case CIT_MODEL4: | ||
2749 | cit_start_model4(gspca_dev); | ||
2750 | break; | ||
2751 | case CIT_IBM_NETCAM_PRO: | ||
2752 | cit_start_ibm_netcam_pro(gspca_dev); | ||
2753 | break; | ||
2754 | } | ||
2755 | |||
2756 | cit_set_brightness(gspca_dev); | ||
2757 | cit_set_contrast(gspca_dev); | ||
2758 | cit_set_hue(gspca_dev); | ||
2759 | cit_set_sharpness(gspca_dev); | ||
2760 | cit_set_lighting(gspca_dev); | ||
2761 | cit_set_hflip(gspca_dev); | ||
2762 | |||
2763 | /* Program max isoc packet size */ | ||
2764 | cit_write_reg(gspca_dev, packet_size >> 8, 0x0106); | ||
2765 | cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107); | ||
2766 | |||
2767 | cit_restart_stream(gspca_dev); | ||
2768 | |||
2769 | return 0; | ||
2770 | } | ||
2771 | |||
2772 | static int sd_isoc_nego(struct gspca_dev *gspca_dev) | ||
2773 | { | ||
2774 | int ret, packet_size; | ||
2775 | struct usb_host_interface *alt; | ||
2776 | |||
2777 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | ||
2778 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
2779 | packet_size -= 100; | ||
2780 | if (packet_size < 300) | ||
2781 | return -EIO; | ||
2782 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); | ||
2783 | |||
2784 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | ||
2785 | if (ret < 0) | ||
2786 | err("set alt 1 err %d", ret); | ||
2787 | |||
2788 | return ret; | ||
2789 | } | ||
2790 | |||
2791 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
2792 | { | ||
2793 | cit_write_reg(gspca_dev, 0x0000, 0x010c); | ||
2794 | } | ||
2795 | |||
2796 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
2797 | { | ||
2798 | struct sd *sd = (struct sd *) gspca_dev; | ||
2799 | struct usb_host_interface *alt; | ||
2800 | |||
2801 | /* We cannot use gspca_dev->present here as that is not set when | ||
2802 | sd_init gets called and we get called from sd_init */ | ||
2803 | if (!gspca_dev->dev) | ||
2804 | return; | ||
2805 | |||
2806 | alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; | ||
2807 | |||
2808 | switch (sd->model) { | ||
2809 | case CIT_MODEL0: | ||
2810 | /* HDG windows does this, but it causes the cams autogain to | ||
2811 | restart from a gain of 0, which does not look good when | ||
2812 | changing resolutions. */ | ||
2813 | /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ | ||
2814 | cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */ | ||
2815 | break; | ||
2816 | case CIT_MODEL1: | ||
2817 | cit_send_FF_04_02(gspca_dev); | ||
2818 | cit_read_reg(gspca_dev, 0x0100); | ||
2819 | cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ | ||
2820 | break; | ||
2821 | case CIT_MODEL2: | ||
2822 | case CIT_MODEL4: | ||
2823 | cit_model2_Packet1(gspca_dev, 0x0030, 0x0004); | ||
2824 | |||
2825 | cit_write_reg(gspca_dev, 0x0080, 0x0100); /* LED Off */ | ||
2826 | cit_write_reg(gspca_dev, 0x0020, 0x0111); | ||
2827 | cit_write_reg(gspca_dev, 0x00a0, 0x0111); | ||
2828 | |||
2829 | cit_model2_Packet1(gspca_dev, 0x0030, 0x0002); | ||
2830 | |||
2831 | cit_write_reg(gspca_dev, 0x0020, 0x0111); | ||
2832 | cit_write_reg(gspca_dev, 0x0000, 0x0112); | ||
2833 | break; | ||
2834 | case CIT_MODEL3: | ||
2835 | cit_write_reg(gspca_dev, 0x0006, 0x012c); | ||
2836 | cit_model3_Packet1(gspca_dev, 0x0046, 0x0000); | ||
2837 | cit_read_reg(gspca_dev, 0x0116); | ||
2838 | cit_write_reg(gspca_dev, 0x0064, 0x0116); | ||
2839 | cit_read_reg(gspca_dev, 0x0115); | ||
2840 | cit_write_reg(gspca_dev, 0x0003, 0x0115); | ||
2841 | cit_write_reg(gspca_dev, 0x0008, 0x0123); | ||
2842 | cit_write_reg(gspca_dev, 0x0000, 0x0117); | ||
2843 | cit_write_reg(gspca_dev, 0x0000, 0x0112); | ||
2844 | cit_write_reg(gspca_dev, 0x0080, 0x0100); | ||
2845 | break; | ||
2846 | case CIT_IBM_NETCAM_PRO: | ||
2847 | cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff); | ||
2848 | cit_write_reg(gspca_dev, 0x0006, 0x012c); | ||
2849 | cit_write_reg(gspca_dev, 0x0000, 0x0116); | ||
2850 | /* HDG windows does this, but I cannot get the camera | ||
2851 | to restart with this without redoing the entire init | ||
2852 | sequence which makes switching modes really slow */ | ||
2853 | /* cit_write_reg(gspca_dev, 0x0006, 0x0115); */ | ||
2854 | cit_write_reg(gspca_dev, 0x0008, 0x0123); | ||
2855 | cit_write_reg(gspca_dev, 0x0000, 0x0117); | ||
2856 | cit_write_reg(gspca_dev, 0x0003, 0x0133); | ||
2857 | cit_write_reg(gspca_dev, 0x0000, 0x0111); | ||
2858 | /* HDG windows does this, but I get a green picture when | ||
2859 | restarting the stream after this */ | ||
2860 | /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ | ||
2861 | cit_write_reg(gspca_dev, 0x00c0, 0x0100); | ||
2862 | |||
2863 | /* Start isoc bandwidth "negotiation" at max isoc bandwith | ||
2864 | next stream start */ | ||
2865 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022); | ||
2866 | break; | ||
2867 | } | ||
2868 | } | ||
2869 | |||
2870 | static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | ||
2871 | { | ||
2872 | struct sd *sd = (struct sd *) gspca_dev; | ||
2873 | u8 byte3 = 0, byte4 = 0; | ||
2874 | int i; | ||
2875 | |||
2876 | switch (sd->model) { | ||
2877 | case CIT_MODEL0: | ||
2878 | case CIT_MODEL1: | ||
2879 | case CIT_MODEL3: | ||
2880 | case CIT_IBM_NETCAM_PRO: | ||
2881 | switch (gspca_dev->width) { | ||
2882 | case 160: /* 160x120 */ | ||
2883 | byte3 = 0x02; | ||
2884 | byte4 = 0x0a; | ||
2885 | break; | ||
2886 | case 176: /* 176x144 */ | ||
2887 | byte3 = 0x02; | ||
2888 | byte4 = 0x0e; | ||
2889 | break; | ||
2890 | case 320: /* 320x240 */ | ||
2891 | byte3 = 0x02; | ||
2892 | byte4 = 0x08; | ||
2893 | break; | ||
2894 | case 352: /* 352x288 */ | ||
2895 | byte3 = 0x02; | ||
2896 | byte4 = 0x00; | ||
2897 | break; | ||
2898 | case 640: | ||
2899 | byte3 = 0x03; | ||
2900 | byte4 = 0x08; | ||
2901 | break; | ||
2902 | } | ||
2903 | |||
2904 | /* These have a different byte3 */ | ||
2905 | if (sd->model <= CIT_MODEL1) | ||
2906 | byte3 = 0x00; | ||
2907 | |||
2908 | for (i = 0; i < len; i++) { | ||
2909 | /* For this model the SOF always starts at offset 0 | ||
2910 | so no need to search the entire frame */ | ||
2911 | if (sd->model == CIT_MODEL0 && sd->sof_read != i) | ||
2912 | break; | ||
2913 | |||
2914 | switch (sd->sof_read) { | ||
2915 | case 0: | ||
2916 | if (data[i] == 0x00) | ||
2917 | sd->sof_read++; | ||
2918 | break; | ||
2919 | case 1: | ||
2920 | if (data[i] == 0xff) | ||
2921 | sd->sof_read++; | ||
2922 | else if (data[i] == 0x00) | ||
2923 | sd->sof_read = 1; | ||
2924 | else | ||
2925 | sd->sof_read = 0; | ||
2926 | break; | ||
2927 | case 2: | ||
2928 | if (data[i] == byte3) | ||
2929 | sd->sof_read++; | ||
2930 | else if (data[i] == 0x00) | ||
2931 | sd->sof_read = 1; | ||
2932 | else | ||
2933 | sd->sof_read = 0; | ||
2934 | break; | ||
2935 | case 3: | ||
2936 | if (data[i] == byte4) { | ||
2937 | sd->sof_read = 0; | ||
2938 | return data + i + (sd->sof_len - 3); | ||
2939 | } | ||
2940 | if (byte3 == 0x00 && data[i] == 0xff) | ||
2941 | sd->sof_read = 2; | ||
2942 | else if (data[i] == 0x00) | ||
2943 | sd->sof_read = 1; | ||
2944 | else | ||
2945 | sd->sof_read = 0; | ||
2946 | break; | ||
2947 | } | ||
2948 | } | ||
2949 | break; | ||
2950 | case CIT_MODEL2: | ||
2951 | case CIT_MODEL4: | ||
2952 | /* TESTME we need to find a longer sof signature to avoid | ||
2953 | false positives */ | ||
2954 | for (i = 0; i < len; i++) { | ||
2955 | switch (sd->sof_read) { | ||
2956 | case 0: | ||
2957 | if (data[i] == 0x00) | ||
2958 | sd->sof_read++; | ||
2959 | break; | ||
2960 | case 1: | ||
2961 | sd->sof_read = 0; | ||
2962 | if (data[i] == 0xff) { | ||
2963 | if (i >= 4) | ||
2964 | PDEBUG(D_FRAM, | ||
2965 | "header found at offset: %d: %02x %02x 00 %02x %02x %02x\n", | ||
2966 | i - 1, | ||
2967 | data[i - 4], | ||
2968 | data[i - 3], | ||
2969 | data[i], | ||
2970 | data[i + 1], | ||
2971 | data[i + 2]); | ||
2972 | else | ||
2973 | PDEBUG(D_FRAM, | ||
2974 | "header found at offset: %d: 00 %02x %02x %02x\n", | ||
2975 | i - 1, | ||
2976 | data[i], | ||
2977 | data[i + 1], | ||
2978 | data[i + 2]); | ||
2979 | return data + i + (sd->sof_len - 1); | ||
2980 | } | ||
2981 | break; | ||
2982 | } | ||
2983 | } | ||
2984 | break; | ||
2985 | } | ||
2986 | return NULL; | ||
2987 | } | ||
2988 | |||
2989 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2990 | u8 *data, int len) | ||
2991 | { | ||
2992 | struct sd *sd = (struct sd *) gspca_dev; | ||
2993 | unsigned char *sof; | ||
2994 | |||
2995 | sof = cit_find_sof(gspca_dev, data, len); | ||
2996 | if (sof) { | ||
2997 | int n; | ||
2998 | |||
2999 | /* finish decoding current frame */ | ||
3000 | n = sof - data; | ||
3001 | if (n > sd->sof_len) | ||
3002 | n -= sd->sof_len; | ||
3003 | else | ||
3004 | n = 0; | ||
3005 | gspca_frame_add(gspca_dev, LAST_PACKET, | ||
3006 | data, n); | ||
3007 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); | ||
3008 | len -= sof - data; | ||
3009 | data = sof; | ||
3010 | } | ||
3011 | |||
3012 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | ||
3013 | } | ||
3014 | |||
3015 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
3016 | { | ||
3017 | struct sd *sd = (struct sd *) gspca_dev; | ||
3018 | |||
3019 | sd->brightness = val; | ||
3020 | if (gspca_dev->streaming) { | ||
3021 | if (sd->stop_on_control_change) | ||
3022 | sd_stopN(gspca_dev); | ||
3023 | cit_set_brightness(gspca_dev); | ||
3024 | if (sd->stop_on_control_change) | ||
3025 | cit_restart_stream(gspca_dev); | ||
3026 | } | ||
3027 | |||
3028 | return 0; | ||
3029 | } | ||
3030 | |||
3031 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
3032 | { | ||
3033 | struct sd *sd = (struct sd *) gspca_dev; | ||
3034 | |||
3035 | *val = sd->brightness; | ||
3036 | |||
3037 | return 0; | ||
3038 | } | ||
3039 | |||
3040 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
3041 | { | ||
3042 | struct sd *sd = (struct sd *) gspca_dev; | ||
3043 | |||
3044 | sd->contrast = val; | ||
3045 | if (gspca_dev->streaming) { | ||
3046 | if (sd->stop_on_control_change) | ||
3047 | sd_stopN(gspca_dev); | ||
3048 | cit_set_contrast(gspca_dev); | ||
3049 | if (sd->stop_on_control_change) | ||
3050 | cit_restart_stream(gspca_dev); | ||
3051 | } | ||
3052 | |||
3053 | return 0; | ||
3054 | } | ||
3055 | |||
3056 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
3057 | { | ||
3058 | struct sd *sd = (struct sd *) gspca_dev; | ||
3059 | |||
3060 | *val = sd->contrast; | ||
3061 | |||
3062 | return 0; | ||
3063 | } | ||
3064 | |||
3065 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
3066 | { | ||
3067 | struct sd *sd = (struct sd *) gspca_dev; | ||
3068 | |||
3069 | sd->hue = val; | ||
3070 | if (gspca_dev->streaming) { | ||
3071 | if (sd->stop_on_control_change) | ||
3072 | sd_stopN(gspca_dev); | ||
3073 | cit_set_hue(gspca_dev); | ||
3074 | if (sd->stop_on_control_change) | ||
3075 | cit_restart_stream(gspca_dev); | ||
3076 | } | ||
3077 | return 0; | ||
3078 | } | ||
3079 | |||
3080 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
3081 | { | ||
3082 | struct sd *sd = (struct sd *) gspca_dev; | ||
3083 | |||
3084 | *val = sd->hue; | ||
3085 | |||
3086 | return 0; | ||
3087 | } | ||
3088 | |||
3089 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
3090 | { | ||
3091 | struct sd *sd = (struct sd *) gspca_dev; | ||
3092 | |||
3093 | sd->sharpness = val; | ||
3094 | if (gspca_dev->streaming) { | ||
3095 | if (sd->stop_on_control_change) | ||
3096 | sd_stopN(gspca_dev); | ||
3097 | cit_set_sharpness(gspca_dev); | ||
3098 | if (sd->stop_on_control_change) | ||
3099 | cit_restart_stream(gspca_dev); | ||
3100 | } | ||
3101 | return 0; | ||
3102 | } | ||
3103 | |||
3104 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
3105 | { | ||
3106 | struct sd *sd = (struct sd *) gspca_dev; | ||
3107 | |||
3108 | *val = sd->sharpness; | ||
3109 | |||
3110 | return 0; | ||
3111 | } | ||
3112 | |||
3113 | static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val) | ||
3114 | { | ||
3115 | struct sd *sd = (struct sd *) gspca_dev; | ||
3116 | |||
3117 | sd->lighting = val; | ||
3118 | if (gspca_dev->streaming) { | ||
3119 | if (sd->stop_on_control_change) | ||
3120 | sd_stopN(gspca_dev); | ||
3121 | cit_set_lighting(gspca_dev); | ||
3122 | if (sd->stop_on_control_change) | ||
3123 | cit_restart_stream(gspca_dev); | ||
3124 | } | ||
3125 | return 0; | ||
3126 | } | ||
3127 | |||
3128 | static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val) | ||
3129 | { | ||
3130 | struct sd *sd = (struct sd *) gspca_dev; | ||
3131 | |||
3132 | *val = sd->lighting; | ||
3133 | |||
3134 | return 0; | ||
3135 | } | ||
3136 | |||
3137 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
3138 | { | ||
3139 | struct sd *sd = (struct sd *) gspca_dev; | ||
3140 | |||
3141 | sd->hflip = val; | ||
3142 | if (gspca_dev->streaming) { | ||
3143 | if (sd->stop_on_control_change) | ||
3144 | sd_stopN(gspca_dev); | ||
3145 | cit_set_hflip(gspca_dev); | ||
3146 | if (sd->stop_on_control_change) | ||
3147 | cit_restart_stream(gspca_dev); | ||
3148 | } | ||
3149 | return 0; | ||
3150 | } | ||
3151 | |||
3152 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
3153 | { | ||
3154 | struct sd *sd = (struct sd *) gspca_dev; | ||
3155 | |||
3156 | *val = sd->hflip; | ||
3157 | |||
3158 | return 0; | ||
3159 | } | ||
3160 | |||
3161 | |||
3162 | /* sub-driver description */ | ||
3163 | static const struct sd_desc sd_desc = { | ||
3164 | .name = MODULE_NAME, | ||
3165 | .ctrls = sd_ctrls, | ||
3166 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
3167 | .config = sd_config, | ||
3168 | .init = sd_init, | ||
3169 | .start = sd_start, | ||
3170 | .stopN = sd_stopN, | ||
3171 | .stop0 = sd_stop0, | ||
3172 | .pkt_scan = sd_pkt_scan, | ||
3173 | }; | ||
3174 | |||
3175 | static const struct sd_desc sd_desc_isoc_nego = { | ||
3176 | .name = MODULE_NAME, | ||
3177 | .ctrls = sd_ctrls, | ||
3178 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
3179 | .config = sd_config, | ||
3180 | .init = sd_init, | ||
3181 | .start = sd_start, | ||
3182 | .isoc_nego = sd_isoc_nego, | ||
3183 | .stopN = sd_stopN, | ||
3184 | .stop0 = sd_stop0, | ||
3185 | .pkt_scan = sd_pkt_scan, | ||
3186 | }; | ||
3187 | |||
3188 | /* -- module initialisation -- */ | ||
3189 | static const __devinitdata struct usb_device_id device_table[] = { | ||
3190 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 }, | ||
3191 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 }, | ||
3192 | { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, | ||
3193 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 }, | ||
3194 | { USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 }, | ||
3195 | { USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, | ||
3196 | { USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 }, | ||
3197 | {} | ||
3198 | }; | ||
3199 | MODULE_DEVICE_TABLE(usb, device_table); | ||
3200 | |||
3201 | /* -- device connect -- */ | ||
3202 | static int sd_probe(struct usb_interface *intf, | ||
3203 | const struct usb_device_id *id) | ||
3204 | { | ||
3205 | const struct sd_desc *desc = &sd_desc; | ||
3206 | |||
3207 | switch (id->driver_info) { | ||
3208 | case CIT_MODEL0: | ||
3209 | case CIT_MODEL1: | ||
3210 | if (intf->cur_altsetting->desc.bInterfaceNumber != 2) | ||
3211 | return -ENODEV; | ||
3212 | break; | ||
3213 | case CIT_MODEL2: | ||
3214 | case CIT_MODEL4: | ||
3215 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | ||
3216 | return -ENODEV; | ||
3217 | break; | ||
3218 | case CIT_MODEL3: | ||
3219 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | ||
3220 | return -ENODEV; | ||
3221 | /* FIXME this likely applies to all model3 cams and probably | ||
3222 | to other models too. */ | ||
3223 | if (ibm_netcam_pro) | ||
3224 | desc = &sd_desc_isoc_nego; | ||
3225 | break; | ||
3226 | } | ||
3227 | |||
3228 | return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE); | ||
3229 | } | ||
3230 | |||
3231 | static struct usb_driver sd_driver = { | ||
3232 | .name = MODULE_NAME, | ||
3233 | .id_table = device_table, | ||
3234 | .probe = sd_probe, | ||
3235 | .disconnect = gspca_disconnect, | ||
3236 | #ifdef CONFIG_PM | ||
3237 | .suspend = gspca_suspend, | ||
3238 | .resume = gspca_resume, | ||
3239 | #endif | ||
3240 | }; | ||
3241 | |||
3242 | /* -- module insert / remove -- */ | ||
3243 | static int __init sd_mod_init(void) | ||
3244 | { | ||
3245 | return usb_register(&sd_driver); | ||
3246 | } | ||
3247 | static void __exit sd_mod_exit(void) | ||
3248 | { | ||
3249 | usb_deregister(&sd_driver); | ||
3250 | } | ||
3251 | |||
3252 | module_init(sd_mod_init); | ||
3253 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 0666038a51b..c7e1970ca28 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -21,9 +21,7 @@ | |||
21 | 21 | ||
22 | #define MODULE_NAME "zc3xx" | 22 | #define MODULE_NAME "zc3xx" |
23 | 23 | ||
24 | #ifdef CONFIG_INPUT | ||
25 | #include <linux/input.h> | 24 | #include <linux/input.h> |
26 | #endif | ||
27 | #include "gspca.h" | 25 | #include "gspca.h" |
28 | #include "jpeg.h" | 26 | #include "jpeg.h" |
29 | 27 | ||
@@ -2953,7 +2951,7 @@ static const struct usb_action mc501cb_Initial[] = { | |||
2953 | {} | 2951 | {} |
2954 | }; | 2952 | }; |
2955 | 2953 | ||
2956 | static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */ | 2954 | static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */ |
2957 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | 2955 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ |
2958 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ | 2956 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ |
2959 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | 2957 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ |
@@ -3731,7 +3729,6 @@ static const struct usb_action pas106b_InitialScale[] = { /* 176x144 */ | |||
3731 | {0xaa, 0x0d, 0x0000}, | 3729 | {0xaa, 0x0d, 0x0000}, |
3732 | {0xaa, 0x0e, 0x0002}, | 3730 | {0xaa, 0x0e, 0x0002}, |
3733 | {0xaa, 0x14, 0x0081}, | 3731 | {0xaa, 0x14, 0x0081}, |
3734 | |||
3735 | /* Other registers */ | 3732 | /* Other registers */ |
3736 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | 3733 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, |
3737 | /* Frame retreiving */ | 3734 | /* Frame retreiving */ |
@@ -3785,7 +3782,6 @@ static const struct usb_action pas106b_InitialScale[] = { /* 176x144 */ | |||
3785 | {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, | 3782 | {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, |
3786 | {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, | 3783 | {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, |
3787 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | 3784 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, |
3788 | |||
3789 | /* Auto exposure and white balance */ | 3785 | /* Auto exposure and white balance */ |
3790 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | 3786 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, |
3791 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, | 3787 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, |
@@ -3849,7 +3845,6 @@ static const struct usb_action pas106b_Initial[] = { /* 352x288 */ | |||
3849 | {0xaa, 0x0d, 0x0000}, | 3845 | {0xaa, 0x0d, 0x0000}, |
3850 | {0xaa, 0x0e, 0x0002}, | 3846 | {0xaa, 0x0e, 0x0002}, |
3851 | {0xaa, 0x14, 0x0081}, | 3847 | {0xaa, 0x14, 0x0081}, |
3852 | |||
3853 | /* Other registers */ | 3848 | /* Other registers */ |
3854 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | 3849 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, |
3855 | /* Frame retreiving */ | 3850 | /* Frame retreiving */ |
@@ -5698,7 +5693,7 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev, | |||
5698 | index, gspca_dev->usb_buf, 1, | 5693 | index, gspca_dev->usb_buf, 1, |
5699 | 500); | 5694 | 500); |
5700 | if (ret < 0) { | 5695 | if (ret < 0) { |
5701 | PDEBUG(D_ERR, "reg_r_i err %d", ret); | 5696 | err("reg_r_i err %d", ret); |
5702 | gspca_dev->usb_err = ret; | 5697 | gspca_dev->usb_err = ret; |
5703 | return 0; | 5698 | return 0; |
5704 | } | 5699 | } |
@@ -5730,7 +5725,7 @@ static void reg_w_i(struct gspca_dev *gspca_dev, | |||
5730 | value, index, NULL, 0, | 5725 | value, index, NULL, 0, |
5731 | 500); | 5726 | 500); |
5732 | if (ret < 0) { | 5727 | if (ret < 0) { |
5733 | PDEBUG(D_ERR, "reg_w_i err %d", ret); | 5728 | err("reg_w_i err %d", ret); |
5734 | gspca_dev->usb_err = ret; | 5729 | gspca_dev->usb_err = ret; |
5735 | } | 5730 | } |
5736 | } | 5731 | } |
@@ -6309,8 +6304,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6309 | if (chipset_revision_sensor[i].revision == retword) { | 6304 | if (chipset_revision_sensor[i].revision == retword) { |
6310 | sd->chip_revision = retword; | 6305 | sd->chip_revision = retword; |
6311 | send_unknown(gspca_dev, SENSOR_PB0330); | 6306 | send_unknown(gspca_dev, SENSOR_PB0330); |
6312 | return chipset_revision_sensor[i] | 6307 | return chipset_revision_sensor[i].internal_sensor_id; |
6313 | .internal_sensor_id; | ||
6314 | } | 6308 | } |
6315 | } | 6309 | } |
6316 | 6310 | ||
@@ -6503,8 +6497,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6503 | PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); | 6497 | PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); |
6504 | break; | 6498 | break; |
6505 | default: | 6499 | default: |
6506 | PDEBUG(D_PROBE, | 6500 | warn("Unknown sensor - set to TAS5130C"); |
6507 | "Unknown sensor - set to TAS5130C"); | ||
6508 | sd->sensor = SENSOR_TAS5130C; | 6501 | sd->sensor = SENSOR_TAS5130C; |
6509 | } | 6502 | } |
6510 | break; | 6503 | break; |
@@ -6610,7 +6603,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6610 | sd->sensor = SENSOR_OV7620; /* same sensor (?) */ | 6603 | sd->sensor = SENSOR_OV7620; /* same sensor (?) */ |
6611 | break; | 6604 | break; |
6612 | default: | 6605 | default: |
6613 | PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor); | 6606 | err("Unknown sensor %04x", sensor); |
6614 | return -EINVAL; | 6607 | return -EINVAL; |
6615 | } | 6608 | } |
6616 | } | 6609 | } |
@@ -6790,7 +6783,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6790 | /* fall thru */ | 6783 | /* fall thru */ |
6791 | case SENSOR_PAS202B: | 6784 | case SENSOR_PAS202B: |
6792 | case SENSOR_PO2030: | 6785 | case SENSOR_PO2030: |
6793 | /* reg_w(gspca_dev, 0x40, ZC3XX_R117_GGAIN); * (from win traces) */ | 6786 | /* reg_w(gspca_dev, 0x40, ZC3XX_R117_GGAIN); in win traces */ |
6794 | reg_r(gspca_dev, 0x0180); | 6787 | reg_r(gspca_dev, 0x0180); |
6795 | break; | 6788 | break; |
6796 | case SENSOR_OV7620: | 6789 | case SENSOR_OV7620: |
@@ -6798,7 +6791,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6798 | reg_w(gspca_dev, 0x15, 0x01ae); | 6791 | reg_w(gspca_dev, 0x15, 0x01ae); |
6799 | i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ | 6792 | i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ |
6800 | i2c_write(gspca_dev, 0x13, 0xa3, 0x00); | 6793 | i2c_write(gspca_dev, 0x13, 0xa3, 0x00); |
6801 | /*fixme: returned value to send? */ | 6794 | /*fixme: returned value to send? */ |
6802 | reg_w(gspca_dev, 0x40, 0x0117); | 6795 | reg_w(gspca_dev, 0x40, 0x0117); |
6803 | reg_r(gspca_dev, 0x0180); | 6796 | reg_r(gspca_dev, 0x0180); |
6804 | break; | 6797 | break; |
@@ -6841,7 +6834,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
6841 | /* remove the webcam's header: | 6834 | /* remove the webcam's header: |
6842 | * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp | 6835 | * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp |
6843 | * - 'ss ss' is the frame sequence number (BE) | 6836 | * - 'ss ss' is the frame sequence number (BE) |
6844 | * - 'ww ww' and 'hh hh' are the window dimensions (BE) | 6837 | * - 'ww ww' and 'hh hh' are the window dimensions (BE) |
6845 | * - 'pp pp' is the packet sequence number (BE) | 6838 | * - 'pp pp' is the packet sequence number (BE) |
6846 | */ | 6839 | */ |
6847 | data += 18; | 6840 | data += 18; |
@@ -7007,7 +7000,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
7007 | return 0; | 7000 | return 0; |
7008 | } | 7001 | } |
7009 | 7002 | ||
7010 | #ifdef CONFIG_INPUT | 7003 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
7011 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 7004 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
7012 | u8 *data, /* interrupt packet data */ | 7005 | u8 *data, /* interrupt packet data */ |
7013 | int len) /* interrput packet length */ | 7006 | int len) /* interrput packet length */ |
@@ -7035,7 +7028,7 @@ static const struct sd_desc sd_desc = { | |||
7035 | .querymenu = sd_querymenu, | 7028 | .querymenu = sd_querymenu, |
7036 | .get_jcomp = sd_get_jcomp, | 7029 | .get_jcomp = sd_get_jcomp, |
7037 | .set_jcomp = sd_set_jcomp, | 7030 | .set_jcomp = sd_set_jcomp, |
7038 | #ifdef CONFIG_INPUT | 7031 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
7039 | .int_pkt_scan = sd_int_pkt_scan, | 7032 | .int_pkt_scan = sd_int_pkt_scan, |
7040 | #endif | 7033 | #endif |
7041 | }; | 7034 | }; |
@@ -7120,18 +7113,12 @@ static struct usb_driver sd_driver = { | |||
7120 | 7113 | ||
7121 | static int __init sd_mod_init(void) | 7114 | static int __init sd_mod_init(void) |
7122 | { | 7115 | { |
7123 | int ret; | 7116 | return usb_register(&sd_driver); |
7124 | ret = usb_register(&sd_driver); | ||
7125 | if (ret < 0) | ||
7126 | return ret; | ||
7127 | PDEBUG(D_PROBE, "registered"); | ||
7128 | return 0; | ||
7129 | } | 7117 | } |
7130 | 7118 | ||
7131 | static void __exit sd_mod_exit(void) | 7119 | static void __exit sd_mod_exit(void) |
7132 | { | 7120 | { |
7133 | usb_deregister(&sd_driver); | 7121 | usb_deregister(&sd_driver); |
7134 | PDEBUG(D_PROBE, "deregistered"); | ||
7135 | } | 7122 | } |
7136 | 7123 | ||
7137 | module_init(sd_mod_init); | 7124 | module_init(sd_mod_init); |
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c index 5a6b78b8d25..068df4ba3f5 100644 --- a/drivers/media/video/hdpvr/hdpvr-control.c +++ b/drivers/media/video/hdpvr/hdpvr-control.c | |||
@@ -29,8 +29,6 @@ int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf) | |||
29 | int ret; | 29 | int ret; |
30 | char request_type = 0x38, snd_request = 0x01; | 30 | char request_type = 0x38, snd_request = 0x01; |
31 | 31 | ||
32 | msleep(10); | ||
33 | |||
34 | mutex_lock(&dev->usbc_mutex); | 32 | mutex_lock(&dev->usbc_mutex); |
35 | dev->usbc_buf[0] = valbuf; | 33 | dev->usbc_buf[0] = valbuf; |
36 | ret = usb_control_msg(dev->udev, | 34 | ret = usb_control_msg(dev->udev, |
@@ -170,8 +168,7 @@ int hdpvr_set_audio(struct hdpvr_device *dev, u8 input, | |||
170 | if (ret == 2) | 168 | if (ret == 2) |
171 | ret = 0; | 169 | ret = 0; |
172 | } else | 170 | } else |
173 | ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE, | 171 | ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE, input); |
174 | dev->options.audio_input+1); | ||
175 | error: | 172 | error: |
176 | return ret; | 173 | return ret; |
177 | } | 174 | } |
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c index 0cae5b82e1a..b70d6afc9fe 100644 --- a/drivers/media/video/hdpvr/hdpvr-core.c +++ b/drivers/media/video/hdpvr/hdpvr-core.c | |||
@@ -60,6 +60,7 @@ static struct usb_device_id hdpvr_table[] = { | |||
60 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, | 60 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, |
61 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, | 61 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, |
62 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) }, | 62 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) }, |
63 | { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID4) }, | ||
63 | { } /* Terminating entry */ | 64 | { } /* Terminating entry */ |
64 | }; | 65 | }; |
65 | MODULE_DEVICE_TABLE(usb, hdpvr_table); | 66 | MODULE_DEVICE_TABLE(usb, hdpvr_table); |
@@ -152,19 +153,26 @@ static int device_authorization(struct hdpvr_device *dev) | |||
152 | ret, print_buf); | 153 | ret, print_buf); |
153 | } | 154 | } |
154 | #endif | 155 | #endif |
155 | if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) { | 156 | |
157 | v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n", | ||
158 | dev->usbc_buf[1], &dev->usbc_buf[2]); | ||
159 | |||
160 | switch (dev->usbc_buf[1]) { | ||
161 | case HDPVR_FIRMWARE_VERSION: | ||
156 | dev->flags &= ~HDPVR_FLAG_AC3_CAP; | 162 | dev->flags &= ~HDPVR_FLAG_AC3_CAP; |
157 | } else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) { | 163 | break; |
158 | dev->flags |= HDPVR_FLAG_AC3_CAP; | 164 | case HDPVR_FIRMWARE_VERSION_AC3: |
159 | } else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) { | 165 | case HDPVR_FIRMWARE_VERSION_0X12: |
160 | v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, " | 166 | case HDPVR_FIRMWARE_VERSION_0X15: |
161 | "the driver might not work\n", dev->usbc_buf[1]); | ||
162 | dev->flags |= HDPVR_FLAG_AC3_CAP; | 167 | dev->flags |= HDPVR_FLAG_AC3_CAP; |
163 | } else { | 168 | break; |
164 | v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n", | 169 | default: |
165 | dev->usbc_buf[1]); | 170 | v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might" |
166 | ret = -EINVAL; | 171 | " not work.\n"); |
167 | goto unlock; | 172 | if (dev->usbc_buf[1] >= HDPVR_FIRMWARE_VERSION_AC3) |
173 | dev->flags |= HDPVR_FLAG_AC3_CAP; | ||
174 | else | ||
175 | dev->flags &= ~HDPVR_FLAG_AC3_CAP; | ||
168 | } | 176 | } |
169 | 177 | ||
170 | response = dev->usbc_buf+38; | 178 | response = dev->usbc_buf+38; |
@@ -319,8 +327,12 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
319 | if (default_video_input < HDPVR_VIDEO_INPUTS) | 327 | if (default_video_input < HDPVR_VIDEO_INPUTS) |
320 | dev->options.video_input = default_video_input; | 328 | dev->options.video_input = default_video_input; |
321 | 329 | ||
322 | if (default_audio_input < HDPVR_AUDIO_INPUTS) | 330 | if (default_audio_input < HDPVR_AUDIO_INPUTS) { |
323 | dev->options.audio_input = default_audio_input; | 331 | dev->options.audio_input = default_audio_input; |
332 | if (default_audio_input == HDPVR_SPDIF) | ||
333 | dev->options.audio_codec = | ||
334 | V4L2_MPEG_AUDIO_ENCODING_AC3; | ||
335 | } | ||
324 | 336 | ||
325 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 337 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
326 | 338 | ||
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c index 463b81bef6e..409de11096d 100644 --- a/drivers/media/video/hdpvr/hdpvr-i2c.c +++ b/drivers/media/video/hdpvr/hdpvr-i2c.c | |||
@@ -127,7 +127,6 @@ int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) | |||
127 | strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C", | 127 | strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C", |
128 | sizeof(i2c_adap->name)); | 128 | sizeof(i2c_adap->name)); |
129 | i2c_adap->algo = &hdpvr_algo; | 129 | i2c_adap->algo = &hdpvr_algo; |
130 | i2c_adap->class = I2C_CLASS_TV_ANALOG; | ||
131 | i2c_adap->owner = THIS_MODULE; | 130 | i2c_adap->owner = THIS_MODULE; |
132 | i2c_adap->dev.parent = &dev->udev->dev; | 131 | i2c_adap->dev.parent = &dev->udev->dev; |
133 | 132 | ||
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index 4863a21b1f2..d38fe1043e4 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <media/v4l2-ioctl.h> | 26 | #include <media/v4l2-ioctl.h> |
27 | #include "hdpvr.h" | 27 | #include "hdpvr.h" |
28 | 28 | ||
29 | #define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */ | 29 | #define BULK_URB_TIMEOUT 90 /* 0.09 seconds */ |
30 | 30 | ||
31 | #define print_buffer_status() { \ | 31 | #define print_buffer_status() { \ |
32 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \ | 32 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \ |
@@ -157,6 +157,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) | |||
157 | mem, dev->bulk_in_size, | 157 | mem, dev->bulk_in_size, |
158 | hdpvr_read_bulk_callback, buf); | 158 | hdpvr_read_bulk_callback, buf); |
159 | 159 | ||
160 | buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
160 | buf->status = BUFSTAT_AVAILABLE; | 161 | buf->status = BUFSTAT_AVAILABLE; |
161 | list_add_tail(&buf->buff_list, &dev->free_buff_list); | 162 | list_add_tail(&buf->buff_list, &dev->free_buff_list); |
162 | } | 163 | } |
@@ -337,8 +338,6 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) | |||
337 | dev->bulk_in_endpointAddr), | 338 | dev->bulk_in_endpointAddr), |
338 | buf, dev->bulk_in_size, &actual_length, | 339 | buf, dev->bulk_in_size, &actual_length, |
339 | BULK_URB_TIMEOUT)) { | 340 | BULK_URB_TIMEOUT)) { |
340 | /* wait */ | ||
341 | msleep(5); | ||
342 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, | 341 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, |
343 | "%2d: got %d bytes\n", c, actual_length); | 342 | "%2d: got %d bytes\n", c, actual_length); |
344 | } | 343 | } |
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h index b0f046df3cd..5efc963f916 100644 --- a/drivers/media/video/hdpvr/hdpvr.h +++ b/drivers/media/video/hdpvr/hdpvr.h | |||
@@ -30,14 +30,17 @@ | |||
30 | #define HD_PVR_PRODUCT_ID 0x4900 | 30 | #define HD_PVR_PRODUCT_ID 0x4900 |
31 | #define HD_PVR_PRODUCT_ID1 0x4901 | 31 | #define HD_PVR_PRODUCT_ID1 0x4901 |
32 | #define HD_PVR_PRODUCT_ID2 0x4902 | 32 | #define HD_PVR_PRODUCT_ID2 0x4902 |
33 | #define HD_PVR_PRODUCT_ID4 0x4903 | ||
33 | #define HD_PVR_PRODUCT_ID3 0x4982 | 34 | #define HD_PVR_PRODUCT_ID3 0x4982 |
34 | 35 | ||
35 | #define UNSET (-1U) | 36 | #define UNSET (-1U) |
36 | 37 | ||
37 | #define NUM_BUFFERS 64 | 38 | #define NUM_BUFFERS 64 |
38 | 39 | ||
39 | #define HDPVR_FIRMWARE_VERSION 0x8 | 40 | #define HDPVR_FIRMWARE_VERSION 0x08 |
40 | #define HDPVR_FIRMWARE_VERSION_AC3 0xd | 41 | #define HDPVR_FIRMWARE_VERSION_AC3 0x0d |
42 | #define HDPVR_FIRMWARE_VERSION_0X12 0x12 | ||
43 | #define HDPVR_FIRMWARE_VERSION_0X15 0x15 | ||
41 | 44 | ||
42 | /* #define HDPVR_DEBUG */ | 45 | /* #define HDPVR_DEBUG */ |
43 | 46 | ||
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index ad2c232baa6..7ae96367b3a 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
@@ -367,7 +367,6 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d | |||
367 | saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); | 367 | saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); |
368 | 368 | ||
369 | hexium->i2c_adapter = (struct i2c_adapter) { | 369 | hexium->i2c_adapter = (struct i2c_adapter) { |
370 | .class = I2C_CLASS_TV_ANALOG, | ||
371 | .name = "hexium gemini", | 370 | .name = "hexium gemini", |
372 | }; | 371 | }; |
373 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); | 372 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 938a1f8f880..b72d0f0b831 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
@@ -230,7 +230,6 @@ static int hexium_probe(struct saa7146_dev *dev) | |||
230 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | 230 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); |
231 | 231 | ||
232 | hexium->i2c_adapter = (struct i2c_adapter) { | 232 | hexium->i2c_adapter = (struct i2c_adapter) { |
233 | .class = I2C_CLASS_TV_ANALOG, | ||
234 | .name = "hexium orion", | 233 | .name = "hexium orion", |
235 | }; | 234 | }; |
236 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); | 235 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); |
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c new file mode 100644 index 00000000000..380e459f899 --- /dev/null +++ b/drivers/media/video/imx074.c | |||
@@ -0,0 +1,508 @@ | |||
1 | /* | ||
2 | * Driver for IMX074 CMOS Image Sensor from Sony | ||
3 | * | ||
4 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * Partially inspired by the IMX074 driver from the Android / MSM tree | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/videodev2.h> | ||
17 | |||
18 | #include <media/soc_camera.h> | ||
19 | #include <media/soc_mediabus.h> | ||
20 | #include <media/v4l2-subdev.h> | ||
21 | #include <media/v4l2-chip-ident.h> | ||
22 | |||
23 | /* IMX074 registers */ | ||
24 | |||
25 | #define MODE_SELECT 0x0100 | ||
26 | #define IMAGE_ORIENTATION 0x0101 | ||
27 | #define GROUPED_PARAMETER_HOLD 0x0104 | ||
28 | |||
29 | /* Integration Time */ | ||
30 | #define COARSE_INTEGRATION_TIME_HI 0x0202 | ||
31 | #define COARSE_INTEGRATION_TIME_LO 0x0203 | ||
32 | /* Gain */ | ||
33 | #define ANALOGUE_GAIN_CODE_GLOBAL_HI 0x0204 | ||
34 | #define ANALOGUE_GAIN_CODE_GLOBAL_LO 0x0205 | ||
35 | |||
36 | /* PLL registers */ | ||
37 | #define PRE_PLL_CLK_DIV 0x0305 | ||
38 | #define PLL_MULTIPLIER 0x0307 | ||
39 | #define PLSTATIM 0x302b | ||
40 | #define VNDMY_ABLMGSHLMT 0x300a | ||
41 | #define Y_OPBADDR_START_DI 0x3014 | ||
42 | /* mode setting */ | ||
43 | #define FRAME_LENGTH_LINES_HI 0x0340 | ||
44 | #define FRAME_LENGTH_LINES_LO 0x0341 | ||
45 | #define LINE_LENGTH_PCK_HI 0x0342 | ||
46 | #define LINE_LENGTH_PCK_LO 0x0343 | ||
47 | #define YADDR_START 0x0347 | ||
48 | #define YADDR_END 0x034b | ||
49 | #define X_OUTPUT_SIZE_MSB 0x034c | ||
50 | #define X_OUTPUT_SIZE_LSB 0x034d | ||
51 | #define Y_OUTPUT_SIZE_MSB 0x034e | ||
52 | #define Y_OUTPUT_SIZE_LSB 0x034f | ||
53 | #define X_EVEN_INC 0x0381 | ||
54 | #define X_ODD_INC 0x0383 | ||
55 | #define Y_EVEN_INC 0x0385 | ||
56 | #define Y_ODD_INC 0x0387 | ||
57 | |||
58 | #define HMODEADD 0x3001 | ||
59 | #define VMODEADD 0x3016 | ||
60 | #define VAPPLINE_START 0x3069 | ||
61 | #define VAPPLINE_END 0x306b | ||
62 | #define SHUTTER 0x3086 | ||
63 | #define HADDAVE 0x30e8 | ||
64 | #define LANESEL 0x3301 | ||
65 | |||
66 | /* IMX074 supported geometry */ | ||
67 | #define IMX074_WIDTH 1052 | ||
68 | #define IMX074_HEIGHT 780 | ||
69 | |||
70 | /* IMX074 has only one fixed colorspace per pixelcode */ | ||
71 | struct imx074_datafmt { | ||
72 | enum v4l2_mbus_pixelcode code; | ||
73 | enum v4l2_colorspace colorspace; | ||
74 | }; | ||
75 | |||
76 | struct imx074 { | ||
77 | struct v4l2_subdev subdev; | ||
78 | const struct imx074_datafmt *fmt; | ||
79 | }; | ||
80 | |||
81 | static const struct imx074_datafmt imx074_colour_fmts[] = { | ||
82 | {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, | ||
83 | }; | ||
84 | |||
85 | static struct imx074 *to_imx074(const struct i2c_client *client) | ||
86 | { | ||
87 | return container_of(i2c_get_clientdata(client), struct imx074, subdev); | ||
88 | } | ||
89 | |||
90 | /* Find a data format by a pixel code in an array */ | ||
91 | static const struct imx074_datafmt *imx074_find_datafmt(enum v4l2_mbus_pixelcode code) | ||
92 | { | ||
93 | int i; | ||
94 | |||
95 | for (i = 0; i < ARRAY_SIZE(imx074_colour_fmts); i++) | ||
96 | if (imx074_colour_fmts[i].code == code) | ||
97 | return imx074_colour_fmts + i; | ||
98 | |||
99 | return NULL; | ||
100 | } | ||
101 | |||
102 | static int reg_write(struct i2c_client *client, const u16 addr, const u8 data) | ||
103 | { | ||
104 | struct i2c_adapter *adap = client->adapter; | ||
105 | struct i2c_msg msg; | ||
106 | unsigned char tx[3]; | ||
107 | int ret; | ||
108 | |||
109 | msg.addr = client->addr; | ||
110 | msg.buf = tx; | ||
111 | msg.len = 3; | ||
112 | msg.flags = 0; | ||
113 | |||
114 | tx[0] = addr >> 8; | ||
115 | tx[1] = addr & 0xff; | ||
116 | tx[2] = data; | ||
117 | |||
118 | ret = i2c_transfer(adap, &msg, 1); | ||
119 | |||
120 | mdelay(2); | ||
121 | |||
122 | return ret == 1 ? 0 : -EIO; | ||
123 | } | ||
124 | |||
125 | static int reg_read(struct i2c_client *client, const u16 addr) | ||
126 | { | ||
127 | u8 buf[2] = {addr >> 8, addr & 0xff}; | ||
128 | int ret; | ||
129 | struct i2c_msg msgs[] = { | ||
130 | { | ||
131 | .addr = client->addr, | ||
132 | .flags = 0, | ||
133 | .len = 2, | ||
134 | .buf = buf, | ||
135 | }, { | ||
136 | .addr = client->addr, | ||
137 | .flags = I2C_M_RD, | ||
138 | .len = 2, | ||
139 | .buf = buf, | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
144 | if (ret < 0) { | ||
145 | dev_warn(&client->dev, "Reading register %x from %x failed\n", | ||
146 | addr, client->addr); | ||
147 | return ret; | ||
148 | } | ||
149 | |||
150 | return buf[0] & 0xff; /* no sign-extension */ | ||
151 | } | ||
152 | |||
153 | static int imx074_try_fmt(struct v4l2_subdev *sd, | ||
154 | struct v4l2_mbus_framefmt *mf) | ||
155 | { | ||
156 | const struct imx074_datafmt *fmt = imx074_find_datafmt(mf->code); | ||
157 | |||
158 | dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code); | ||
159 | |||
160 | if (!fmt) { | ||
161 | mf->code = imx074_colour_fmts[0].code; | ||
162 | mf->colorspace = imx074_colour_fmts[0].colorspace; | ||
163 | } | ||
164 | |||
165 | mf->width = IMX074_WIDTH; | ||
166 | mf->height = IMX074_HEIGHT; | ||
167 | mf->field = V4L2_FIELD_NONE; | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int imx074_s_fmt(struct v4l2_subdev *sd, | ||
173 | struct v4l2_mbus_framefmt *mf) | ||
174 | { | ||
175 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
176 | struct imx074 *priv = to_imx074(client); | ||
177 | |||
178 | dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code); | ||
179 | |||
180 | /* MIPI CSI could have changed the format, double-check */ | ||
181 | if (!imx074_find_datafmt(mf->code)) | ||
182 | return -EINVAL; | ||
183 | |||
184 | imx074_try_fmt(sd, mf); | ||
185 | |||
186 | priv->fmt = imx074_find_datafmt(mf->code); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static int imx074_g_fmt(struct v4l2_subdev *sd, | ||
192 | struct v4l2_mbus_framefmt *mf) | ||
193 | { | ||
194 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
195 | struct imx074 *priv = to_imx074(client); | ||
196 | |||
197 | const struct imx074_datafmt *fmt = priv->fmt; | ||
198 | |||
199 | mf->code = fmt->code; | ||
200 | mf->colorspace = fmt->colorspace; | ||
201 | mf->width = IMX074_WIDTH; | ||
202 | mf->height = IMX074_HEIGHT; | ||
203 | mf->field = V4L2_FIELD_NONE; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int imx074_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
209 | { | ||
210 | struct v4l2_rect *rect = &a->c; | ||
211 | |||
212 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
213 | rect->top = 0; | ||
214 | rect->left = 0; | ||
215 | rect->width = IMX074_WIDTH; | ||
216 | rect->height = IMX074_HEIGHT; | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | ||
222 | { | ||
223 | a->bounds.left = 0; | ||
224 | a->bounds.top = 0; | ||
225 | a->bounds.width = IMX074_WIDTH; | ||
226 | a->bounds.height = IMX074_HEIGHT; | ||
227 | a->defrect = a->bounds; | ||
228 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
229 | a->pixelaspect.numerator = 1; | ||
230 | a->pixelaspect.denominator = 1; | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int imx074_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | ||
236 | enum v4l2_mbus_pixelcode *code) | ||
237 | { | ||
238 | if ((unsigned int)index >= ARRAY_SIZE(imx074_colour_fmts)) | ||
239 | return -EINVAL; | ||
240 | |||
241 | *code = imx074_colour_fmts[index].code; | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int imx074_s_stream(struct v4l2_subdev *sd, int enable) | ||
246 | { | ||
247 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
248 | |||
249 | /* MODE_SELECT: stream or standby */ | ||
250 | return reg_write(client, MODE_SELECT, !!enable); | ||
251 | } | ||
252 | |||
253 | static int imx074_g_chip_ident(struct v4l2_subdev *sd, | ||
254 | struct v4l2_dbg_chip_ident *id) | ||
255 | { | ||
256 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
257 | |||
258 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | ||
259 | return -EINVAL; | ||
260 | |||
261 | if (id->match.addr != client->addr) | ||
262 | return -ENODEV; | ||
263 | |||
264 | id->ident = V4L2_IDENT_IMX074; | ||
265 | id->revision = 0; | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { | ||
271 | .s_stream = imx074_s_stream, | ||
272 | .s_mbus_fmt = imx074_s_fmt, | ||
273 | .g_mbus_fmt = imx074_g_fmt, | ||
274 | .try_mbus_fmt = imx074_try_fmt, | ||
275 | .enum_mbus_fmt = imx074_enum_fmt, | ||
276 | .g_crop = imx074_g_crop, | ||
277 | .cropcap = imx074_cropcap, | ||
278 | }; | ||
279 | |||
280 | static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { | ||
281 | .g_chip_ident = imx074_g_chip_ident, | ||
282 | }; | ||
283 | |||
284 | static struct v4l2_subdev_ops imx074_subdev_ops = { | ||
285 | .core = &imx074_subdev_core_ops, | ||
286 | .video = &imx074_subdev_video_ops, | ||
287 | }; | ||
288 | |||
289 | /* | ||
290 | * We have to provide soc-camera operations, but we don't have anything to say | ||
291 | * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param | ||
292 | */ | ||
293 | static unsigned long imx074_query_bus_param(struct soc_camera_device *icd) | ||
294 | { | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int imx074_set_bus_param(struct soc_camera_device *icd, | ||
299 | unsigned long flags) | ||
300 | { | ||
301 | return -1; | ||
302 | } | ||
303 | |||
304 | static struct soc_camera_ops imx074_ops = { | ||
305 | .query_bus_param = imx074_query_bus_param, | ||
306 | .set_bus_param = imx074_set_bus_param, | ||
307 | }; | ||
308 | |||
309 | static int imx074_video_probe(struct soc_camera_device *icd, | ||
310 | struct i2c_client *client) | ||
311 | { | ||
312 | int ret; | ||
313 | u16 id; | ||
314 | |||
315 | /* Read sensor Model ID */ | ||
316 | ret = reg_read(client, 0); | ||
317 | if (ret < 0) | ||
318 | return ret; | ||
319 | |||
320 | id = ret << 8; | ||
321 | |||
322 | ret = reg_read(client, 1); | ||
323 | if (ret < 0) | ||
324 | return ret; | ||
325 | |||
326 | id |= ret; | ||
327 | |||
328 | dev_info(&client->dev, "Chip ID 0x%04x detected\n", id); | ||
329 | |||
330 | if (id != 0x74) | ||
331 | return -ENODEV; | ||
332 | |||
333 | /* PLL Setting EXTCLK=24MHz, 22.5times */ | ||
334 | reg_write(client, PLL_MULTIPLIER, 0x2D); | ||
335 | reg_write(client, PRE_PLL_CLK_DIV, 0x02); | ||
336 | reg_write(client, PLSTATIM, 0x4B); | ||
337 | |||
338 | /* 2-lane mode */ | ||
339 | reg_write(client, 0x3024, 0x00); | ||
340 | |||
341 | reg_write(client, IMAGE_ORIENTATION, 0x00); | ||
342 | |||
343 | /* select RAW mode: | ||
344 | * 0x08+0x08 = top 8 bits | ||
345 | * 0x0a+0x08 = compressed 8-bits | ||
346 | * 0x0a+0x0a = 10 bits | ||
347 | */ | ||
348 | reg_write(client, 0x0112, 0x08); | ||
349 | reg_write(client, 0x0113, 0x08); | ||
350 | |||
351 | /* Base setting for High frame mode */ | ||
352 | reg_write(client, VNDMY_ABLMGSHLMT, 0x80); | ||
353 | reg_write(client, Y_OPBADDR_START_DI, 0x08); | ||
354 | reg_write(client, 0x3015, 0x37); | ||
355 | reg_write(client, 0x301C, 0x01); | ||
356 | reg_write(client, 0x302C, 0x05); | ||
357 | reg_write(client, 0x3031, 0x26); | ||
358 | reg_write(client, 0x3041, 0x60); | ||
359 | reg_write(client, 0x3051, 0x24); | ||
360 | reg_write(client, 0x3053, 0x34); | ||
361 | reg_write(client, 0x3057, 0xC0); | ||
362 | reg_write(client, 0x305C, 0x09); | ||
363 | reg_write(client, 0x305D, 0x07); | ||
364 | reg_write(client, 0x3060, 0x30); | ||
365 | reg_write(client, 0x3065, 0x00); | ||
366 | reg_write(client, 0x30AA, 0x08); | ||
367 | reg_write(client, 0x30AB, 0x1C); | ||
368 | reg_write(client, 0x30B0, 0x32); | ||
369 | reg_write(client, 0x30B2, 0x83); | ||
370 | reg_write(client, 0x30D3, 0x04); | ||
371 | reg_write(client, 0x3106, 0x78); | ||
372 | reg_write(client, 0x310C, 0x82); | ||
373 | reg_write(client, 0x3304, 0x05); | ||
374 | reg_write(client, 0x3305, 0x04); | ||
375 | reg_write(client, 0x3306, 0x11); | ||
376 | reg_write(client, 0x3307, 0x02); | ||
377 | reg_write(client, 0x3308, 0x0C); | ||
378 | reg_write(client, 0x3309, 0x06); | ||
379 | reg_write(client, 0x330A, 0x08); | ||
380 | reg_write(client, 0x330B, 0x04); | ||
381 | reg_write(client, 0x330C, 0x08); | ||
382 | reg_write(client, 0x330D, 0x06); | ||
383 | reg_write(client, 0x330E, 0x01); | ||
384 | reg_write(client, 0x3381, 0x00); | ||
385 | |||
386 | /* V : 1/2V-addition (1,3), H : 1/2H-averaging (1,3) -> Full HD */ | ||
387 | /* 1608 = 1560 + 48 (black lines) */ | ||
388 | reg_write(client, FRAME_LENGTH_LINES_HI, 0x06); | ||
389 | reg_write(client, FRAME_LENGTH_LINES_LO, 0x48); | ||
390 | reg_write(client, YADDR_START, 0x00); | ||
391 | reg_write(client, YADDR_END, 0x2F); | ||
392 | /* 0x838 == 2104 */ | ||
393 | reg_write(client, X_OUTPUT_SIZE_MSB, 0x08); | ||
394 | reg_write(client, X_OUTPUT_SIZE_LSB, 0x38); | ||
395 | /* 0x618 == 1560 */ | ||
396 | reg_write(client, Y_OUTPUT_SIZE_MSB, 0x06); | ||
397 | reg_write(client, Y_OUTPUT_SIZE_LSB, 0x18); | ||
398 | reg_write(client, X_EVEN_INC, 0x01); | ||
399 | reg_write(client, X_ODD_INC, 0x03); | ||
400 | reg_write(client, Y_EVEN_INC, 0x01); | ||
401 | reg_write(client, Y_ODD_INC, 0x03); | ||
402 | reg_write(client, HMODEADD, 0x00); | ||
403 | reg_write(client, VMODEADD, 0x16); | ||
404 | reg_write(client, VAPPLINE_START, 0x24); | ||
405 | reg_write(client, VAPPLINE_END, 0x53); | ||
406 | reg_write(client, SHUTTER, 0x00); | ||
407 | reg_write(client, HADDAVE, 0x80); | ||
408 | |||
409 | reg_write(client, LANESEL, 0x00); | ||
410 | |||
411 | reg_write(client, GROUPED_PARAMETER_HOLD, 0x00); /* off */ | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static int imx074_probe(struct i2c_client *client, | ||
417 | const struct i2c_device_id *did) | ||
418 | { | ||
419 | struct imx074 *priv; | ||
420 | struct soc_camera_device *icd = client->dev.platform_data; | ||
421 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
422 | struct soc_camera_link *icl; | ||
423 | int ret; | ||
424 | |||
425 | if (!icd) { | ||
426 | dev_err(&client->dev, "IMX074: missing soc-camera data!\n"); | ||
427 | return -EINVAL; | ||
428 | } | ||
429 | |||
430 | icl = to_soc_camera_link(icd); | ||
431 | if (!icl) { | ||
432 | dev_err(&client->dev, "IMX074: missing platform data!\n"); | ||
433 | return -EINVAL; | ||
434 | } | ||
435 | |||
436 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
437 | dev_warn(&adapter->dev, | ||
438 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); | ||
439 | return -EIO; | ||
440 | } | ||
441 | |||
442 | priv = kzalloc(sizeof(struct imx074), GFP_KERNEL); | ||
443 | if (!priv) | ||
444 | return -ENOMEM; | ||
445 | |||
446 | v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops); | ||
447 | |||
448 | icd->ops = &imx074_ops; | ||
449 | priv->fmt = &imx074_colour_fmts[0]; | ||
450 | |||
451 | ret = imx074_video_probe(icd, client); | ||
452 | if (ret < 0) { | ||
453 | icd->ops = NULL; | ||
454 | i2c_set_clientdata(client, NULL); | ||
455 | kfree(priv); | ||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | return ret; | ||
460 | } | ||
461 | |||
462 | static int imx074_remove(struct i2c_client *client) | ||
463 | { | ||
464 | struct imx074 *priv = to_imx074(client); | ||
465 | struct soc_camera_device *icd = client->dev.platform_data; | ||
466 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
467 | |||
468 | icd->ops = NULL; | ||
469 | if (icl->free_bus) | ||
470 | icl->free_bus(icl); | ||
471 | i2c_set_clientdata(client, NULL); | ||
472 | client->driver = NULL; | ||
473 | kfree(priv); | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static const struct i2c_device_id imx074_id[] = { | ||
479 | { "imx074", 0 }, | ||
480 | { } | ||
481 | }; | ||
482 | MODULE_DEVICE_TABLE(i2c, imx074_id); | ||
483 | |||
484 | static struct i2c_driver imx074_i2c_driver = { | ||
485 | .driver = { | ||
486 | .name = "imx074", | ||
487 | }, | ||
488 | .probe = imx074_probe, | ||
489 | .remove = imx074_remove, | ||
490 | .id_table = imx074_id, | ||
491 | }; | ||
492 | |||
493 | static int __init imx074_mod_init(void) | ||
494 | { | ||
495 | return i2c_add_driver(&imx074_i2c_driver); | ||
496 | } | ||
497 | |||
498 | static void __exit imx074_mod_exit(void) | ||
499 | { | ||
500 | i2c_del_driver(&imx074_i2c_driver); | ||
501 | } | ||
502 | |||
503 | module_init(imx074_mod_init); | ||
504 | module_exit(imx074_mod_exit); | ||
505 | |||
506 | MODULE_DESCRIPTION("Sony IMX074 Camera driver"); | ||
507 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
508 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c index 3d6940163b1..e5ed4db32e7 100644 --- a/drivers/media/video/indycam.c +++ b/drivers/media/video/indycam.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <media/v4l2-device.h> | 25 | #include <media/v4l2-device.h> |
26 | #include <media/v4l2-chip-ident.h> | 26 | #include <media/v4l2-chip-ident.h> |
27 | #include <media/v4l2-i2c-drv.h> | ||
28 | 27 | ||
29 | #include "indycam.h" | 28 | #include "indycam.h" |
30 | 29 | ||
@@ -378,9 +377,25 @@ static const struct i2c_device_id indycam_id[] = { | |||
378 | }; | 377 | }; |
379 | MODULE_DEVICE_TABLE(i2c, indycam_id); | 378 | MODULE_DEVICE_TABLE(i2c, indycam_id); |
380 | 379 | ||
381 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 380 | static struct i2c_driver indycam_driver = { |
382 | .name = "indycam", | 381 | .driver = { |
383 | .probe = indycam_probe, | 382 | .owner = THIS_MODULE, |
384 | .remove = indycam_remove, | 383 | .name = "indycam", |
385 | .id_table = indycam_id, | 384 | }, |
385 | .probe = indycam_probe, | ||
386 | .remove = indycam_remove, | ||
387 | .id_table = indycam_id, | ||
386 | }; | 388 | }; |
389 | |||
390 | static __init int init_indycam(void) | ||
391 | { | ||
392 | return i2c_add_driver(&indycam_driver); | ||
393 | } | ||
394 | |||
395 | static __exit void exit_indycam(void) | ||
396 | { | ||
397 | i2c_del_driver(&indycam_driver); | ||
398 | } | ||
399 | |||
400 | module_init(init_indycam); | ||
401 | module_exit(exit_indycam); | ||
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 27ae8bbfb47..5a000c65ae9 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -146,26 +146,6 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
146 | return 1; | 146 | return 1; |
147 | } | 147 | } |
148 | 148 | ||
149 | static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
150 | { | ||
151 | unsigned char b; | ||
152 | |||
153 | /* poll IR chip */ | ||
154 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | ||
155 | dprintk(1,"read error\n"); | ||
156 | return -EIO; | ||
157 | } | ||
158 | |||
159 | /* ignore 0xaa */ | ||
160 | if (b==0xaa) | ||
161 | return 0; | ||
162 | dprintk(2,"key %02x\n", b); | ||
163 | |||
164 | *ir_key = b; | ||
165 | *ir_raw = b; | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 149 | static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
170 | { | 150 | { |
171 | unsigned char buf[4]; | 151 | unsigned char buf[4]; |
@@ -279,15 +259,9 @@ static void ir_key_poll(struct IR_i2c *ir) | |||
279 | static void ir_work(struct work_struct *work) | 259 | static void ir_work(struct work_struct *work) |
280 | { | 260 | { |
281 | struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work); | 261 | struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work); |
282 | int polling_interval = 100; | ||
283 | |||
284 | /* MSI TV@nywhere Plus requires more frequent polling | ||
285 | otherwise it will miss some keypresses */ | ||
286 | if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30) | ||
287 | polling_interval = 50; | ||
288 | 262 | ||
289 | ir_key_poll(ir); | 263 | ir_key_poll(ir); |
290 | schedule_delayed_work(&ir->work, msecs_to_jiffies(polling_interval)); | 264 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling_interval)); |
291 | } | 265 | } |
292 | 266 | ||
293 | /* ----------------------------------------------------------------------- */ | 267 | /* ----------------------------------------------------------------------- */ |
@@ -312,6 +286,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
312 | 286 | ||
313 | ir->c = client; | 287 | ir->c = client; |
314 | ir->input = input_dev; | 288 | ir->input = input_dev; |
289 | ir->polling_interval = DEFAULT_POLLING_INTERVAL; | ||
315 | i2c_set_clientdata(client, ir); | 290 | i2c_set_clientdata(client, ir); |
316 | 291 | ||
317 | switch(addr) { | 292 | switch(addr) { |
@@ -321,12 +296,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
321 | ir_type = IR_TYPE_OTHER; | 296 | ir_type = IR_TYPE_OTHER; |
322 | ir_codes = RC_MAP_EMPTY; | 297 | ir_codes = RC_MAP_EMPTY; |
323 | break; | 298 | break; |
324 | case 0x4b: | ||
325 | name = "PV951"; | ||
326 | ir->get_key = get_key_pv951; | ||
327 | ir_type = IR_TYPE_OTHER; | ||
328 | ir_codes = RC_MAP_PV951; | ||
329 | break; | ||
330 | case 0x18: | 299 | case 0x18: |
331 | case 0x1f: | 300 | case 0x1f: |
332 | case 0x1a: | 301 | case 0x1a: |
@@ -351,27 +320,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
351 | ir_type = IR_TYPE_RC5; | 320 | ir_type = IR_TYPE_RC5; |
352 | ir_codes = RC_MAP_FUSIONHDTV_MCE; | 321 | ir_codes = RC_MAP_FUSIONHDTV_MCE; |
353 | break; | 322 | break; |
354 | case 0x0b: | ||
355 | case 0x47: | ||
356 | case 0x71: | ||
357 | if (adap->id == I2C_HW_B_CX2388x || | ||
358 | adap->id == I2C_HW_B_CX2341X) { | ||
359 | /* Handled by cx88-input */ | ||
360 | name = adap->id == I2C_HW_B_CX2341X ? "CX2341x remote" | ||
361 | : "CX2388x remote"; | ||
362 | ir_type = IR_TYPE_RC5; | ||
363 | ir->get_key = get_key_haup_xvr; | ||
364 | if (hauppauge == 1) { | ||
365 | ir_codes = RC_MAP_HAUPPAUGE_NEW; | ||
366 | } else { | ||
367 | ir_codes = RC_MAP_RC5_TV; | ||
368 | } | ||
369 | } else { | ||
370 | /* Handled by saa7134-input */ | ||
371 | name = "SAA713x remote"; | ||
372 | ir_type = IR_TYPE_OTHER; | ||
373 | } | ||
374 | break; | ||
375 | case 0x40: | 323 | case 0x40: |
376 | name = "AVerMedia Cardbus remote"; | 324 | name = "AVerMedia Cardbus remote"; |
377 | ir->get_key = get_key_avermedia_cardbus; | 325 | ir->get_key = get_key_avermedia_cardbus; |
@@ -390,6 +338,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
390 | if (init_data->type) | 338 | if (init_data->type) |
391 | ir_type = init_data->type; | 339 | ir_type = init_data->type; |
392 | 340 | ||
341 | if (init_data->polling_interval) | ||
342 | ir->polling_interval = init_data->polling_interval; | ||
343 | |||
393 | switch (init_data->internal_get_key_func) { | 344 | switch (init_data->internal_get_key_func) { |
394 | case IR_KBD_GET_KEY_CUSTOM: | 345 | case IR_KBD_GET_KEY_CUSTOM: |
395 | /* The bridge driver provided us its own function */ | 346 | /* The bridge driver provided us its own function */ |
@@ -398,9 +349,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
398 | case IR_KBD_GET_KEY_PIXELVIEW: | 349 | case IR_KBD_GET_KEY_PIXELVIEW: |
399 | ir->get_key = get_key_pixelview; | 350 | ir->get_key = get_key_pixelview; |
400 | break; | 351 | break; |
401 | case IR_KBD_GET_KEY_PV951: | ||
402 | ir->get_key = get_key_pv951; | ||
403 | break; | ||
404 | case IR_KBD_GET_KEY_HAUP: | 352 | case IR_KBD_GET_KEY_HAUP: |
405 | ir->get_key = get_key_haup; | 353 | ir->get_key = get_key_haup; |
406 | break; | 354 | break; |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 75803141481..04bacdbd10b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -811,15 +811,23 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) | |||
811 | /* Call the specified callback for all subdevs matching hw (if 0, then | 811 | /* Call the specified callback for all subdevs matching hw (if 0, then |
812 | match them all). Ignore any errors. */ | 812 | match them all). Ignore any errors. */ |
813 | #define ivtv_call_hw(itv, hw, o, f, args...) \ | 813 | #define ivtv_call_hw(itv, hw, o, f, args...) \ |
814 | __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) | 814 | do { \ |
815 | struct v4l2_subdev *__sd; \ | ||
816 | __v4l2_device_call_subdevs_p(&(itv)->v4l2_dev, __sd, \ | ||
817 | !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \ | ||
818 | } while (0) | ||
815 | 819 | ||
816 | #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) | 820 | #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) |
817 | 821 | ||
818 | /* Call the specified callback for all subdevs matching hw (if 0, then | 822 | /* Call the specified callback for all subdevs matching hw (if 0, then |
819 | match them all). If the callback returns an error other than 0 or | 823 | match them all). If the callback returns an error other than 0 or |
820 | -ENOIOCTLCMD, then return with that error code. */ | 824 | -ENOIOCTLCMD, then return with that error code. */ |
821 | #define ivtv_call_hw_err(itv, hw, o, f, args...) \ | 825 | #define ivtv_call_hw_err(itv, hw, o, f, args...) \ |
822 | __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) | 826 | ({ \ |
827 | struct v4l2_subdev *__sd; \ | ||
828 | __v4l2_device_call_subdevs_until_err_p(&(itv)->v4l2_dev, __sd, \ | ||
829 | !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \ | ||
830 | }) | ||
823 | 831 | ||
824 | #define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args) | 832 | #define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args) |
825 | 833 | ||
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index a74fa099c56..9e8039ac909 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -121,31 +121,6 @@ static const u8 hw_addrs[] = { | |||
121 | }; | 121 | }; |
122 | 122 | ||
123 | /* This array should match the IVTV_HW_ defines */ | 123 | /* This array should match the IVTV_HW_ defines */ |
124 | static const char *hw_modules[] = { | ||
125 | "cx25840", | ||
126 | "saa7115", | ||
127 | "saa7127", | ||
128 | "msp3400", | ||
129 | "tuner", | ||
130 | "wm8775", | ||
131 | "cs53l32a", | ||
132 | NULL, | ||
133 | "saa7115", | ||
134 | "upd64031a", | ||
135 | "upd64083", | ||
136 | "saa717x", | ||
137 | "wm8739", | ||
138 | "vp27smpx", | ||
139 | "m52790", | ||
140 | NULL, | ||
141 | NULL, /* IVTV_HW_I2C_IR_RX_AVER */ | ||
142 | NULL, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ | ||
143 | NULL, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ | ||
144 | NULL, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ | ||
145 | NULL, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ | ||
146 | }; | ||
147 | |||
148 | /* This array should match the IVTV_HW_ defines */ | ||
149 | static const char * const hw_devicenames[] = { | 124 | static const char * const hw_devicenames[] = { |
150 | "cx25840", | 125 | "cx25840", |
151 | "saa7115", | 126 | "saa7115", |
@@ -257,7 +232,6 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) | |||
257 | { | 232 | { |
258 | struct v4l2_subdev *sd; | 233 | struct v4l2_subdev *sd; |
259 | struct i2c_adapter *adap = &itv->i2c_adap; | 234 | struct i2c_adapter *adap = &itv->i2c_adap; |
260 | const char *mod = hw_modules[idx]; | ||
261 | const char *type = hw_devicenames[idx]; | 235 | const char *type = hw_devicenames[idx]; |
262 | u32 hw = 1 << idx; | 236 | u32 hw = 1 << idx; |
263 | 237 | ||
@@ -266,17 +240,17 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) | |||
266 | if (hw == IVTV_HW_TUNER) { | 240 | if (hw == IVTV_HW_TUNER) { |
267 | /* special tuner handling */ | 241 | /* special tuner handling */ |
268 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | 242 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, |
269 | adap, mod, type, | 243 | adap, NULL, type, |
270 | 0, itv->card_i2c->radio); | 244 | 0, itv->card_i2c->radio); |
271 | if (sd) | 245 | if (sd) |
272 | sd->grp_id = 1 << idx; | 246 | sd->grp_id = 1 << idx; |
273 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | 247 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, |
274 | adap, mod, type, | 248 | adap, NULL, type, |
275 | 0, itv->card_i2c->demod); | 249 | 0, itv->card_i2c->demod); |
276 | if (sd) | 250 | if (sd) |
277 | sd->grp_id = 1 << idx; | 251 | sd->grp_id = 1 << idx; |
278 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | 252 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, |
279 | adap, mod, type, | 253 | adap, NULL, type, |
280 | 0, itv->card_i2c->tv); | 254 | 0, itv->card_i2c->tv); |
281 | if (sd) | 255 | if (sd) |
282 | sd->grp_id = 1 << idx; | 256 | sd->grp_id = 1 << idx; |
@@ -293,16 +267,17 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) | |||
293 | /* It's an I2C device other than an analog tuner or IR chip */ | 267 | /* It's an I2C device other than an analog tuner or IR chip */ |
294 | if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { | 268 | if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { |
295 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | 269 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, |
296 | adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx])); | 270 | adap, NULL, type, 0, I2C_ADDRS(hw_addrs[idx])); |
297 | } else if (hw == IVTV_HW_CX25840) { | 271 | } else if (hw == IVTV_HW_CX25840) { |
298 | struct cx25840_platform_data pdata; | 272 | struct cx25840_platform_data pdata; |
299 | 273 | ||
300 | pdata.pvr150_workaround = itv->pvr150_workaround; | 274 | pdata.pvr150_workaround = itv->pvr150_workaround; |
301 | sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev, | 275 | sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev, |
302 | adap, mod, type, 0, &pdata, hw_addrs[idx], NULL); | 276 | adap, NULL, type, 0, &pdata, hw_addrs[idx], |
277 | NULL); | ||
303 | } else { | 278 | } else { |
304 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | 279 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, |
305 | adap, mod, type, hw_addrs[idx], NULL); | 280 | adap, NULL, type, hw_addrs[idx], NULL); |
306 | } | 281 | } |
307 | if (sd) | 282 | if (sd) |
308 | sd->grp_id = 1 << idx; | 283 | sd->grp_id = 1 << idx; |
@@ -706,8 +681,7 @@ int init_ivtv_i2c(struct ivtv *itv) | |||
706 | /* Sanity checks for the I2C hardware arrays. They must be the | 681 | /* Sanity checks for the I2C hardware arrays. They must be the |
707 | * same size. | 682 | * same size. |
708 | */ | 683 | */ |
709 | if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || | 684 | if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs)) { |
710 | ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules)) { | ||
711 | IVTV_ERR("Mismatched I2C hardware arrays\n"); | 685 | IVTV_ERR("Mismatched I2C hardware arrays\n"); |
712 | return -ENODEV; | 686 | return -ENODEV; |
713 | } | 687 | } |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 4eed9123683..b686da5e432 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <media/v4l2-chip-ident.h> | 37 | #include <media/v4l2-chip-ident.h> |
38 | #include <media/v4l2-event.h> | 38 | #include <media/v4l2-event.h> |
39 | #include <linux/dvb/audio.h> | 39 | #include <linux/dvb/audio.h> |
40 | #include <linux/i2c-id.h> | ||
41 | 40 | ||
42 | u16 ivtv_service2vbi(int type) | 41 | u16 ivtv_service2vbi(int type) |
43 | { | 42 | { |
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index 94734828053..afa91182b44 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <media/v4l2-device.h> | 44 | #include <media/v4l2-device.h> |
45 | #include <media/v4l2-chip-ident.h> | 45 | #include <media/v4l2-chip-ident.h> |
46 | #include <media/v4l2-i2c-drv.h> | ||
47 | #include "ks0127.h" | 46 | #include "ks0127.h" |
48 | 47 | ||
49 | MODULE_DESCRIPTION("KS0127 video decoder driver"); | 48 | MODULE_DESCRIPTION("KS0127 video decoder driver"); |
@@ -712,9 +711,25 @@ static const struct i2c_device_id ks0127_id[] = { | |||
712 | }; | 711 | }; |
713 | MODULE_DEVICE_TABLE(i2c, ks0127_id); | 712 | MODULE_DEVICE_TABLE(i2c, ks0127_id); |
714 | 713 | ||
715 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 714 | static struct i2c_driver ks0127_driver = { |
716 | .name = "ks0127", | 715 | .driver = { |
717 | .probe = ks0127_probe, | 716 | .owner = THIS_MODULE, |
718 | .remove = ks0127_remove, | 717 | .name = "ks0127", |
719 | .id_table = ks0127_id, | 718 | }, |
719 | .probe = ks0127_probe, | ||
720 | .remove = ks0127_remove, | ||
721 | .id_table = ks0127_id, | ||
720 | }; | 722 | }; |
723 | |||
724 | static __init int init_ks0127(void) | ||
725 | { | ||
726 | return i2c_add_driver(&ks0127_driver); | ||
727 | } | ||
728 | |||
729 | static __exit void exit_ks0127(void) | ||
730 | { | ||
731 | i2c_del_driver(&ks0127_driver); | ||
732 | } | ||
733 | |||
734 | module_init(init_ks0127); | ||
735 | module_exit(exit_ks0127); | ||
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 4491d018eba..5e1c9a81984 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c | |||
@@ -26,12 +26,10 @@ | |||
26 | #include <linux/ioctl.h> | 26 | #include <linux/ioctl.h> |
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/i2c-id.h> | ||
30 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
31 | #include <media/m52790.h> | 30 | #include <media/m52790.h> |
32 | #include <media/v4l2-device.h> | 31 | #include <media/v4l2-device.h> |
33 | #include <media/v4l2-chip-ident.h> | 32 | #include <media/v4l2-chip-ident.h> |
34 | #include <media/v4l2-i2c-drv.h> | ||
35 | 33 | ||
36 | MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch"); | 34 | MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch"); |
37 | MODULE_AUTHOR("Hans Verkuil"); | 35 | MODULE_AUTHOR("Hans Verkuil"); |
@@ -205,9 +203,25 @@ static const struct i2c_device_id m52790_id[] = { | |||
205 | }; | 203 | }; |
206 | MODULE_DEVICE_TABLE(i2c, m52790_id); | 204 | MODULE_DEVICE_TABLE(i2c, m52790_id); |
207 | 205 | ||
208 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 206 | static struct i2c_driver m52790_driver = { |
209 | .name = "m52790", | 207 | .driver = { |
210 | .probe = m52790_probe, | 208 | .owner = THIS_MODULE, |
211 | .remove = m52790_remove, | 209 | .name = "m52790", |
212 | .id_table = m52790_id, | 210 | }, |
211 | .probe = m52790_probe, | ||
212 | .remove = m52790_remove, | ||
213 | .id_table = m52790_id, | ||
213 | }; | 214 | }; |
215 | |||
216 | static __init int init_m52790(void) | ||
217 | { | ||
218 | return i2c_add_driver(&m52790_driver); | ||
219 | } | ||
220 | |||
221 | static __exit void exit_m52790(void) | ||
222 | { | ||
223 | i2c_del_driver(&m52790_driver); | ||
224 | } | ||
225 | |||
226 | module_init(init_m52790); | ||
227 | module_exit(exit_m52790); | ||
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index a7210d98138..3b19f5b25a7 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c | |||
@@ -848,7 +848,7 @@ static void queue_init(void *priv, struct videobuf_queue *vq, | |||
848 | 848 | ||
849 | videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev, | 849 | videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev, |
850 | &ctx->dev->irqlock, type, V4L2_FIELD_NONE, | 850 | &ctx->dev->irqlock, type, V4L2_FIELD_NONE, |
851 | sizeof(struct m2mtest_buffer), priv); | 851 | sizeof(struct m2mtest_buffer), priv, NULL); |
852 | } | 852 | } |
853 | 853 | ||
854 | 854 | ||
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 0e412131da7..b1763ac93ab 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/videodev2.h> | 56 | #include <linux/videodev2.h> |
57 | #include <media/v4l2-device.h> | 57 | #include <media/v4l2-device.h> |
58 | #include <media/v4l2-ioctl.h> | 58 | #include <media/v4l2-ioctl.h> |
59 | #include <media/v4l2-i2c-drv.h> | ||
60 | #include <media/msp3400.h> | 59 | #include <media/msp3400.h> |
61 | #include <media/tvaudio.h> | 60 | #include <media/tvaudio.h> |
62 | #include "msp3400-driver.h" | 61 | #include "msp3400-driver.h" |
@@ -382,7 +381,12 @@ static int msp_s_ctrl(struct v4l2_ctrl *ctrl) | |||
382 | 381 | ||
383 | void msp_update_volume(struct msp_state *state) | 382 | void msp_update_volume(struct msp_state *state) |
384 | { | 383 | { |
385 | v4l2_ctrl_s_ctrl(state->volume, v4l2_ctrl_g_ctrl(state->volume)); | 384 | /* Force an update of the volume/mute cluster */ |
385 | v4l2_ctrl_lock(state->volume); | ||
386 | state->volume->val = state->volume->cur.val; | ||
387 | state->muted->val = state->muted->cur.val; | ||
388 | msp_s_ctrl(state->volume); | ||
389 | v4l2_ctrl_unlock(state->volume); | ||
386 | } | 390 | } |
387 | 391 | ||
388 | /* --- v4l2 ioctls --- */ | 392 | /* --- v4l2 ioctls --- */ |
@@ -843,15 +847,31 @@ static const struct i2c_device_id msp_id[] = { | |||
843 | }; | 847 | }; |
844 | MODULE_DEVICE_TABLE(i2c, msp_id); | 848 | MODULE_DEVICE_TABLE(i2c, msp_id); |
845 | 849 | ||
846 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 850 | static struct i2c_driver msp_driver = { |
847 | .name = "msp3400", | 851 | .driver = { |
848 | .probe = msp_probe, | 852 | .owner = THIS_MODULE, |
849 | .remove = msp_remove, | 853 | .name = "msp3400", |
850 | .suspend = msp_suspend, | 854 | }, |
851 | .resume = msp_resume, | 855 | .probe = msp_probe, |
852 | .id_table = msp_id, | 856 | .remove = msp_remove, |
857 | .suspend = msp_suspend, | ||
858 | .resume = msp_resume, | ||
859 | .id_table = msp_id, | ||
853 | }; | 860 | }; |
854 | 861 | ||
862 | static __init int init_msp(void) | ||
863 | { | ||
864 | return i2c_add_driver(&msp_driver); | ||
865 | } | ||
866 | |||
867 | static __exit void exit_msp(void) | ||
868 | { | ||
869 | i2c_del_driver(&msp_driver); | ||
870 | } | ||
871 | |||
872 | module_init(init_msp); | ||
873 | module_exit(exit_msp); | ||
874 | |||
855 | /* | 875 | /* |
856 | * Overrides for Emacs so that we follow Linus's tabbing style. | 876 | * Overrides for Emacs so that we follow Linus's tabbing style. |
857 | * --------------------------------------------------------------------------- | 877 | * --------------------------------------------------------------------------- |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 79f096ddcf5..fcb4cd94185 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -157,7 +157,7 @@ static int mt9m001_init(struct i2c_client *client) | |||
157 | 157 | ||
158 | static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) | 158 | static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) |
159 | { | 159 | { |
160 | struct i2c_client *client = sd->priv; | 160 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
161 | 161 | ||
162 | /* Switch to master "normal" mode or stop sensor readout */ | 162 | /* Switch to master "normal" mode or stop sensor readout */ |
163 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0) | 163 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0) |
@@ -206,7 +206,7 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) | |||
206 | 206 | ||
207 | static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 207 | static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
208 | { | 208 | { |
209 | struct i2c_client *client = sd->priv; | 209 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
210 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 210 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
211 | struct v4l2_rect rect = a->c; | 211 | struct v4l2_rect rect = a->c; |
212 | struct soc_camera_device *icd = client->dev.platform_data; | 212 | struct soc_camera_device *icd = client->dev.platform_data; |
@@ -271,7 +271,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
271 | 271 | ||
272 | static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 272 | static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
273 | { | 273 | { |
274 | struct i2c_client *client = sd->priv; | 274 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
275 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 275 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
276 | 276 | ||
277 | a->c = mt9m001->rect; | 277 | a->c = mt9m001->rect; |
@@ -297,7 +297,7 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
297 | static int mt9m001_g_fmt(struct v4l2_subdev *sd, | 297 | static int mt9m001_g_fmt(struct v4l2_subdev *sd, |
298 | struct v4l2_mbus_framefmt *mf) | 298 | struct v4l2_mbus_framefmt *mf) |
299 | { | 299 | { |
300 | struct i2c_client *client = sd->priv; | 300 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
301 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 301 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
302 | 302 | ||
303 | mf->width = mt9m001->rect.width; | 303 | mf->width = mt9m001->rect.width; |
@@ -312,7 +312,7 @@ static int mt9m001_g_fmt(struct v4l2_subdev *sd, | |||
312 | static int mt9m001_s_fmt(struct v4l2_subdev *sd, | 312 | static int mt9m001_s_fmt(struct v4l2_subdev *sd, |
313 | struct v4l2_mbus_framefmt *mf) | 313 | struct v4l2_mbus_framefmt *mf) |
314 | { | 314 | { |
315 | struct i2c_client *client = sd->priv; | 315 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
316 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 316 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
317 | struct v4l2_crop a = { | 317 | struct v4l2_crop a = { |
318 | .c = { | 318 | .c = { |
@@ -340,7 +340,7 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, | |||
340 | static int mt9m001_try_fmt(struct v4l2_subdev *sd, | 340 | static int mt9m001_try_fmt(struct v4l2_subdev *sd, |
341 | struct v4l2_mbus_framefmt *mf) | 341 | struct v4l2_mbus_framefmt *mf) |
342 | { | 342 | { |
343 | struct i2c_client *client = sd->priv; | 343 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
344 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 344 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
345 | const struct mt9m001_datafmt *fmt; | 345 | const struct mt9m001_datafmt *fmt; |
346 | 346 | ||
@@ -367,7 +367,7 @@ static int mt9m001_try_fmt(struct v4l2_subdev *sd, | |||
367 | static int mt9m001_g_chip_ident(struct v4l2_subdev *sd, | 367 | static int mt9m001_g_chip_ident(struct v4l2_subdev *sd, |
368 | struct v4l2_dbg_chip_ident *id) | 368 | struct v4l2_dbg_chip_ident *id) |
369 | { | 369 | { |
370 | struct i2c_client *client = sd->priv; | 370 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
371 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 371 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
372 | 372 | ||
373 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 373 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
@@ -386,7 +386,7 @@ static int mt9m001_g_chip_ident(struct v4l2_subdev *sd, | |||
386 | static int mt9m001_g_register(struct v4l2_subdev *sd, | 386 | static int mt9m001_g_register(struct v4l2_subdev *sd, |
387 | struct v4l2_dbg_register *reg) | 387 | struct v4l2_dbg_register *reg) |
388 | { | 388 | { |
389 | struct i2c_client *client = sd->priv; | 389 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
390 | 390 | ||
391 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 391 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
392 | return -EINVAL; | 392 | return -EINVAL; |
@@ -406,7 +406,7 @@ static int mt9m001_g_register(struct v4l2_subdev *sd, | |||
406 | static int mt9m001_s_register(struct v4l2_subdev *sd, | 406 | static int mt9m001_s_register(struct v4l2_subdev *sd, |
407 | struct v4l2_dbg_register *reg) | 407 | struct v4l2_dbg_register *reg) |
408 | { | 408 | { |
409 | struct i2c_client *client = sd->priv; | 409 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
410 | 410 | ||
411 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 411 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
412 | return -EINVAL; | 412 | return -EINVAL; |
@@ -468,7 +468,7 @@ static struct soc_camera_ops mt9m001_ops = { | |||
468 | 468 | ||
469 | static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 469 | static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
470 | { | 470 | { |
471 | struct i2c_client *client = sd->priv; | 471 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
472 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 472 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
473 | int data; | 473 | int data; |
474 | 474 | ||
@@ -494,7 +494,7 @@ static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
494 | 494 | ||
495 | static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 495 | static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
496 | { | 496 | { |
497 | struct i2c_client *client = sd->priv; | 497 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
498 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 498 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
499 | struct soc_camera_device *icd = client->dev.platform_data; | 499 | struct soc_camera_device *icd = client->dev.platform_data; |
500 | const struct v4l2_queryctrl *qctrl; | 500 | const struct v4l2_queryctrl *qctrl; |
@@ -683,7 +683,7 @@ static void mt9m001_video_remove(struct soc_camera_device *icd) | |||
683 | 683 | ||
684 | static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) | 684 | static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) |
685 | { | 685 | { |
686 | struct i2c_client *client = sd->priv; | 686 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
687 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 687 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
688 | 688 | ||
689 | *lines = mt9m001->y_skip_top; | 689 | *lines = mt9m001->y_skip_top; |
@@ -704,7 +704,7 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { | |||
704 | static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | 704 | static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, |
705 | enum v4l2_mbus_pixelcode *code) | 705 | enum v4l2_mbus_pixelcode *code) |
706 | { | 706 | { |
707 | struct i2c_client *client = sd->priv; | 707 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
708 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 708 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
709 | 709 | ||
710 | if (index >= mt9m001->num_fmts) | 710 | if (index >= mt9m001->num_fmts) |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index c71af4e0e51..525a16e7328 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -100,14 +100,14 @@ | |||
100 | #define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) | 100 | #define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) |
101 | #define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) | 101 | #define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) |
102 | #define MT9M111_OUTFMT_RGB (1 << 8) | 102 | #define MT9M111_OUTFMT_RGB (1 << 8) |
103 | #define MT9M111_OUTFMT_RGB565 (0x0 << 6) | 103 | #define MT9M111_OUTFMT_RGB565 (0 << 6) |
104 | #define MT9M111_OUTFMT_RGB555 (0x1 << 6) | 104 | #define MT9M111_OUTFMT_RGB555 (1 << 6) |
105 | #define MT9M111_OUTFMT_RGB444x (0x2 << 6) | 105 | #define MT9M111_OUTFMT_RGB444x (2 << 6) |
106 | #define MT9M111_OUTFMT_RGBx444 (0x3 << 6) | 106 | #define MT9M111_OUTFMT_RGBx444 (3 << 6) |
107 | #define MT9M111_OUTFMT_TST_RAMP_OFF (0x0 << 4) | 107 | #define MT9M111_OUTFMT_TST_RAMP_OFF (0 << 4) |
108 | #define MT9M111_OUTFMT_TST_RAMP_COL (0x1 << 4) | 108 | #define MT9M111_OUTFMT_TST_RAMP_COL (1 << 4) |
109 | #define MT9M111_OUTFMT_TST_RAMP_ROW (0x2 << 4) | 109 | #define MT9M111_OUTFMT_TST_RAMP_ROW (2 << 4) |
110 | #define MT9M111_OUTFMT_TST_RAMP_FRAME (0x3 << 4) | 110 | #define MT9M111_OUTFMT_TST_RAMP_FRAME (3 << 4) |
111 | #define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) | 111 | #define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) |
112 | #define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) | 112 | #define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) |
113 | #define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) | 113 | #define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) |
@@ -124,7 +124,7 @@ | |||
124 | #define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) | 124 | #define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) |
125 | 125 | ||
126 | #define MT9M111_MIN_DARK_ROWS 8 | 126 | #define MT9M111_MIN_DARK_ROWS 8 |
127 | #define MT9M111_MIN_DARK_COLS 24 | 127 | #define MT9M111_MIN_DARK_COLS 26 |
128 | #define MT9M111_MAX_HEIGHT 1024 | 128 | #define MT9M111_MAX_HEIGHT 1024 |
129 | #define MT9M111_MAX_WIDTH 1280 | 129 | #define MT9M111_MAX_WIDTH 1280 |
130 | 130 | ||
@@ -440,7 +440,7 @@ static int mt9m111_make_rect(struct i2c_client *client, | |||
440 | static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 440 | static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
441 | { | 441 | { |
442 | struct v4l2_rect rect = a->c; | 442 | struct v4l2_rect rect = a->c; |
443 | struct i2c_client *client = sd->priv; | 443 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
444 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 444 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
445 | int ret; | 445 | int ret; |
446 | 446 | ||
@@ -458,7 +458,7 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
458 | 458 | ||
459 | static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 459 | static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
460 | { | 460 | { |
461 | struct i2c_client *client = sd->priv; | 461 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
462 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 462 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
463 | 463 | ||
464 | a->c = mt9m111->rect; | 464 | a->c = mt9m111->rect; |
@@ -486,7 +486,7 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
486 | static int mt9m111_g_fmt(struct v4l2_subdev *sd, | 486 | static int mt9m111_g_fmt(struct v4l2_subdev *sd, |
487 | struct v4l2_mbus_framefmt *mf) | 487 | struct v4l2_mbus_framefmt *mf) |
488 | { | 488 | { |
489 | struct i2c_client *client = sd->priv; | 489 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
490 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 490 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
491 | 491 | ||
492 | mf->width = mt9m111->rect.width; | 492 | mf->width = mt9m111->rect.width; |
@@ -549,7 +549,7 @@ static int mt9m111_set_pixfmt(struct i2c_client *client, | |||
549 | static int mt9m111_s_fmt(struct v4l2_subdev *sd, | 549 | static int mt9m111_s_fmt(struct v4l2_subdev *sd, |
550 | struct v4l2_mbus_framefmt *mf) | 550 | struct v4l2_mbus_framefmt *mf) |
551 | { | 551 | { |
552 | struct i2c_client *client = sd->priv; | 552 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
553 | const struct mt9m111_datafmt *fmt; | 553 | const struct mt9m111_datafmt *fmt; |
554 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 554 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
555 | struct v4l2_rect rect = { | 555 | struct v4l2_rect rect = { |
@@ -584,7 +584,7 @@ static int mt9m111_s_fmt(struct v4l2_subdev *sd, | |||
584 | static int mt9m111_try_fmt(struct v4l2_subdev *sd, | 584 | static int mt9m111_try_fmt(struct v4l2_subdev *sd, |
585 | struct v4l2_mbus_framefmt *mf) | 585 | struct v4l2_mbus_framefmt *mf) |
586 | { | 586 | { |
587 | struct i2c_client *client = sd->priv; | 587 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
588 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 588 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
589 | const struct mt9m111_datafmt *fmt; | 589 | const struct mt9m111_datafmt *fmt; |
590 | bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || | 590 | bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || |
@@ -624,7 +624,7 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd, | |||
624 | static int mt9m111_g_chip_ident(struct v4l2_subdev *sd, | 624 | static int mt9m111_g_chip_ident(struct v4l2_subdev *sd, |
625 | struct v4l2_dbg_chip_ident *id) | 625 | struct v4l2_dbg_chip_ident *id) |
626 | { | 626 | { |
627 | struct i2c_client *client = sd->priv; | 627 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
628 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 628 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
629 | 629 | ||
630 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 630 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
@@ -643,7 +643,7 @@ static int mt9m111_g_chip_ident(struct v4l2_subdev *sd, | |||
643 | static int mt9m111_g_register(struct v4l2_subdev *sd, | 643 | static int mt9m111_g_register(struct v4l2_subdev *sd, |
644 | struct v4l2_dbg_register *reg) | 644 | struct v4l2_dbg_register *reg) |
645 | { | 645 | { |
646 | struct i2c_client *client = sd->priv; | 646 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
647 | int val; | 647 | int val; |
648 | 648 | ||
649 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 649 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
@@ -664,7 +664,7 @@ static int mt9m111_g_register(struct v4l2_subdev *sd, | |||
664 | static int mt9m111_s_register(struct v4l2_subdev *sd, | 664 | static int mt9m111_s_register(struct v4l2_subdev *sd, |
665 | struct v4l2_dbg_register *reg) | 665 | struct v4l2_dbg_register *reg) |
666 | { | 666 | { |
667 | struct i2c_client *client = sd->priv; | 667 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
668 | 668 | ||
669 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 669 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
670 | return -EINVAL; | 670 | return -EINVAL; |
@@ -812,7 +812,7 @@ static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on) | |||
812 | 812 | ||
813 | static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 813 | static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
814 | { | 814 | { |
815 | struct i2c_client *client = sd->priv; | 815 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
816 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 816 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
817 | int data; | 817 | int data; |
818 | 818 | ||
@@ -855,7 +855,7 @@ static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
855 | 855 | ||
856 | static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 856 | static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
857 | { | 857 | { |
858 | struct i2c_client *client = sd->priv; | 858 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
859 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 859 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
860 | const struct v4l2_queryctrl *qctrl; | 860 | const struct v4l2_queryctrl *qctrl; |
861 | int ret; | 861 | int ret; |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index a9a28b21423..9bd44a816ea 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -163,7 +163,7 @@ static int mt9t031_disable(struct i2c_client *client) | |||
163 | 163 | ||
164 | static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable) | 164 | static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable) |
165 | { | 165 | { |
166 | struct i2c_client *client = sd->priv; | 166 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
167 | int ret; | 167 | int ret; |
168 | 168 | ||
169 | if (enable) | 169 | if (enable) |
@@ -393,7 +393,7 @@ static int mt9t031_set_params(struct i2c_client *client, | |||
393 | static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 393 | static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
394 | { | 394 | { |
395 | struct v4l2_rect rect = a->c; | 395 | struct v4l2_rect rect = a->c; |
396 | struct i2c_client *client = sd->priv; | 396 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
397 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 397 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
398 | 398 | ||
399 | rect.width = ALIGN(rect.width, 2); | 399 | rect.width = ALIGN(rect.width, 2); |
@@ -410,7 +410,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
410 | 410 | ||
411 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 411 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
412 | { | 412 | { |
413 | struct i2c_client *client = sd->priv; | 413 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
414 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 414 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
415 | 415 | ||
416 | a->c = mt9t031->rect; | 416 | a->c = mt9t031->rect; |
@@ -436,7 +436,7 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
436 | static int mt9t031_g_fmt(struct v4l2_subdev *sd, | 436 | static int mt9t031_g_fmt(struct v4l2_subdev *sd, |
437 | struct v4l2_mbus_framefmt *mf) | 437 | struct v4l2_mbus_framefmt *mf) |
438 | { | 438 | { |
439 | struct i2c_client *client = sd->priv; | 439 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
440 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 440 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
441 | 441 | ||
442 | mf->width = mt9t031->rect.width / mt9t031->xskip; | 442 | mf->width = mt9t031->rect.width / mt9t031->xskip; |
@@ -451,7 +451,7 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd, | |||
451 | static int mt9t031_s_fmt(struct v4l2_subdev *sd, | 451 | static int mt9t031_s_fmt(struct v4l2_subdev *sd, |
452 | struct v4l2_mbus_framefmt *mf) | 452 | struct v4l2_mbus_framefmt *mf) |
453 | { | 453 | { |
454 | struct i2c_client *client = sd->priv; | 454 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
455 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 455 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
456 | u16 xskip, yskip; | 456 | u16 xskip, yskip; |
457 | struct v4l2_rect rect = mt9t031->rect; | 457 | struct v4l2_rect rect = mt9t031->rect; |
@@ -490,7 +490,7 @@ static int mt9t031_try_fmt(struct v4l2_subdev *sd, | |||
490 | static int mt9t031_g_chip_ident(struct v4l2_subdev *sd, | 490 | static int mt9t031_g_chip_ident(struct v4l2_subdev *sd, |
491 | struct v4l2_dbg_chip_ident *id) | 491 | struct v4l2_dbg_chip_ident *id) |
492 | { | 492 | { |
493 | struct i2c_client *client = sd->priv; | 493 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
494 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 494 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
495 | 495 | ||
496 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 496 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
@@ -509,7 +509,7 @@ static int mt9t031_g_chip_ident(struct v4l2_subdev *sd, | |||
509 | static int mt9t031_g_register(struct v4l2_subdev *sd, | 509 | static int mt9t031_g_register(struct v4l2_subdev *sd, |
510 | struct v4l2_dbg_register *reg) | 510 | struct v4l2_dbg_register *reg) |
511 | { | 511 | { |
512 | struct i2c_client *client = sd->priv; | 512 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
513 | 513 | ||
514 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 514 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
515 | return -EINVAL; | 515 | return -EINVAL; |
@@ -528,7 +528,7 @@ static int mt9t031_g_register(struct v4l2_subdev *sd, | |||
528 | static int mt9t031_s_register(struct v4l2_subdev *sd, | 528 | static int mt9t031_s_register(struct v4l2_subdev *sd, |
529 | struct v4l2_dbg_register *reg) | 529 | struct v4l2_dbg_register *reg) |
530 | { | 530 | { |
531 | struct i2c_client *client = sd->priv; | 531 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
532 | 532 | ||
533 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 533 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
534 | return -EINVAL; | 534 | return -EINVAL; |
@@ -545,7 +545,7 @@ static int mt9t031_s_register(struct v4l2_subdev *sd, | |||
545 | 545 | ||
546 | static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 546 | static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
547 | { | 547 | { |
548 | struct i2c_client *client = sd->priv; | 548 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
549 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 549 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
550 | int data; | 550 | int data; |
551 | 551 | ||
@@ -577,7 +577,7 @@ static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
577 | 577 | ||
578 | static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 578 | static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
579 | { | 579 | { |
580 | struct i2c_client *client = sd->priv; | 580 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
581 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 581 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
582 | const struct v4l2_queryctrl *qctrl; | 582 | const struct v4l2_queryctrl *qctrl; |
583 | int data; | 583 | int data; |
@@ -703,7 +703,7 @@ static int mt9t031_runtime_resume(struct device *dev) | |||
703 | struct soc_camera_device *icd = container_of(vdev->parent, | 703 | struct soc_camera_device *icd = container_of(vdev->parent, |
704 | struct soc_camera_device, dev); | 704 | struct soc_camera_device, dev); |
705 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 705 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
706 | struct i2c_client *client = sd->priv; | 706 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
707 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 707 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
708 | 708 | ||
709 | int ret; | 709 | int ret; |
@@ -780,7 +780,7 @@ static int mt9t031_video_probe(struct i2c_client *client) | |||
780 | 780 | ||
781 | static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) | 781 | static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) |
782 | { | 782 | { |
783 | struct i2c_client *client = sd->priv; | 783 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
784 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 784 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
785 | 785 | ||
786 | *lines = mt9t031->y_skip_top; | 786 | *lines = mt9t031->y_skip_top; |
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index 8ec47e42d4d..bffa9ee1096 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c | |||
@@ -804,7 +804,7 @@ static struct soc_camera_ops mt9t112_ops = { | |||
804 | static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, | 804 | static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, |
805 | struct v4l2_dbg_chip_ident *id) | 805 | struct v4l2_dbg_chip_ident *id) |
806 | { | 806 | { |
807 | struct i2c_client *client = sd->priv; | 807 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
808 | struct mt9t112_priv *priv = to_mt9t112(client); | 808 | struct mt9t112_priv *priv = to_mt9t112(client); |
809 | 809 | ||
810 | id->ident = priv->model; | 810 | id->ident = priv->model; |
@@ -817,7 +817,7 @@ static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, | |||
817 | static int mt9t112_g_register(struct v4l2_subdev *sd, | 817 | static int mt9t112_g_register(struct v4l2_subdev *sd, |
818 | struct v4l2_dbg_register *reg) | 818 | struct v4l2_dbg_register *reg) |
819 | { | 819 | { |
820 | struct i2c_client *client = sd->priv; | 820 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
821 | int ret; | 821 | int ret; |
822 | 822 | ||
823 | reg->size = 2; | 823 | reg->size = 2; |
@@ -831,7 +831,7 @@ static int mt9t112_g_register(struct v4l2_subdev *sd, | |||
831 | static int mt9t112_s_register(struct v4l2_subdev *sd, | 831 | static int mt9t112_s_register(struct v4l2_subdev *sd, |
832 | struct v4l2_dbg_register *reg) | 832 | struct v4l2_dbg_register *reg) |
833 | { | 833 | { |
834 | struct i2c_client *client = sd->priv; | 834 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
835 | int ret; | 835 | int ret; |
836 | 836 | ||
837 | mt9t112_reg_write(ret, client, reg->reg, reg->val); | 837 | mt9t112_reg_write(ret, client, reg->reg, reg->val); |
@@ -858,7 +858,7 @@ static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { | |||
858 | ************************************************************************/ | 858 | ************************************************************************/ |
859 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | 859 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) |
860 | { | 860 | { |
861 | struct i2c_client *client = sd->priv; | 861 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
862 | struct mt9t112_priv *priv = to_mt9t112(client); | 862 | struct mt9t112_priv *priv = to_mt9t112(client); |
863 | int ret = 0; | 863 | int ret = 0; |
864 | 864 | ||
@@ -968,7 +968,7 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
968 | 968 | ||
969 | static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 969 | static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
970 | { | 970 | { |
971 | struct i2c_client *client = sd->priv; | 971 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
972 | struct v4l2_rect *rect = &a->c; | 972 | struct v4l2_rect *rect = &a->c; |
973 | 973 | ||
974 | return mt9t112_set_params(client, rect->width, rect->height, | 974 | return mt9t112_set_params(client, rect->width, rect->height, |
@@ -978,7 +978,7 @@ static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
978 | static int mt9t112_g_fmt(struct v4l2_subdev *sd, | 978 | static int mt9t112_g_fmt(struct v4l2_subdev *sd, |
979 | struct v4l2_mbus_framefmt *mf) | 979 | struct v4l2_mbus_framefmt *mf) |
980 | { | 980 | { |
981 | struct i2c_client *client = sd->priv; | 981 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
982 | struct mt9t112_priv *priv = to_mt9t112(client); | 982 | struct mt9t112_priv *priv = to_mt9t112(client); |
983 | 983 | ||
984 | if (!priv->format) { | 984 | if (!priv->format) { |
@@ -1000,7 +1000,7 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd, | |||
1000 | static int mt9t112_s_fmt(struct v4l2_subdev *sd, | 1000 | static int mt9t112_s_fmt(struct v4l2_subdev *sd, |
1001 | struct v4l2_mbus_framefmt *mf) | 1001 | struct v4l2_mbus_framefmt *mf) |
1002 | { | 1002 | { |
1003 | struct i2c_client *client = sd->priv; | 1003 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1004 | 1004 | ||
1005 | /* TODO: set colorspace */ | 1005 | /* TODO: set colorspace */ |
1006 | return mt9t112_set_params(client, mf->width, mf->height, mf->code); | 1006 | return mt9t112_set_params(client, mf->width, mf->height, mf->code); |
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index f5e778d5ca9..209ff97261a 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c | |||
@@ -11,9 +11,8 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <asm/div64.h> | 12 | #include <asm/div64.h> |
13 | #include <media/v4l2-device.h> | 13 | #include <media/v4l2-device.h> |
14 | #include "mt9v011.h" | ||
15 | #include <media/v4l2-i2c-drv.h> | ||
16 | #include <media/v4l2-chip-ident.h> | 14 | #include <media/v4l2-chip-ident.h> |
15 | #include "mt9v011.h" | ||
17 | 16 | ||
18 | MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); | 17 | MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); |
19 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | 18 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); |
@@ -624,9 +623,25 @@ static const struct i2c_device_id mt9v011_id[] = { | |||
624 | }; | 623 | }; |
625 | MODULE_DEVICE_TABLE(i2c, mt9v011_id); | 624 | MODULE_DEVICE_TABLE(i2c, mt9v011_id); |
626 | 625 | ||
627 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 626 | static struct i2c_driver mt9v011_driver = { |
628 | .name = "mt9v011", | 627 | .driver = { |
629 | .probe = mt9v011_probe, | 628 | .owner = THIS_MODULE, |
630 | .remove = mt9v011_remove, | 629 | .name = "mt9v011", |
631 | .id_table = mt9v011_id, | 630 | }, |
631 | .probe = mt9v011_probe, | ||
632 | .remove = mt9v011_remove, | ||
633 | .id_table = mt9v011_id, | ||
632 | }; | 634 | }; |
635 | |||
636 | static __init int init_mt9v011(void) | ||
637 | { | ||
638 | return i2c_add_driver(&mt9v011_driver); | ||
639 | } | ||
640 | |||
641 | static __exit void exit_mt9v011(void) | ||
642 | { | ||
643 | i2c_del_driver(&mt9v011_driver); | ||
644 | } | ||
645 | |||
646 | module_init(init_mt9v011); | ||
647 | module_exit(exit_mt9v011); | ||
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index b48473c7896..b96171cc79f 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -184,7 +184,7 @@ static int mt9v022_init(struct i2c_client *client) | |||
184 | 184 | ||
185 | static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable) | 185 | static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable) |
186 | { | 186 | { |
187 | struct i2c_client *client = sd->priv; | 187 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
188 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 188 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
189 | 189 | ||
190 | if (enable) | 190 | if (enable) |
@@ -273,7 +273,7 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) | |||
273 | 273 | ||
274 | static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 274 | static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
275 | { | 275 | { |
276 | struct i2c_client *client = sd->priv; | 276 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
277 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 277 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
278 | struct v4l2_rect rect = a->c; | 278 | struct v4l2_rect rect = a->c; |
279 | int ret; | 279 | int ret; |
@@ -334,7 +334,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
334 | 334 | ||
335 | static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 335 | static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
336 | { | 336 | { |
337 | struct i2c_client *client = sd->priv; | 337 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
338 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 338 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
339 | 339 | ||
340 | a->c = mt9v022->rect; | 340 | a->c = mt9v022->rect; |
@@ -360,7 +360,7 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
360 | static int mt9v022_g_fmt(struct v4l2_subdev *sd, | 360 | static int mt9v022_g_fmt(struct v4l2_subdev *sd, |
361 | struct v4l2_mbus_framefmt *mf) | 361 | struct v4l2_mbus_framefmt *mf) |
362 | { | 362 | { |
363 | struct i2c_client *client = sd->priv; | 363 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
364 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 364 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
365 | 365 | ||
366 | mf->width = mt9v022->rect.width; | 366 | mf->width = mt9v022->rect.width; |
@@ -375,7 +375,7 @@ static int mt9v022_g_fmt(struct v4l2_subdev *sd, | |||
375 | static int mt9v022_s_fmt(struct v4l2_subdev *sd, | 375 | static int mt9v022_s_fmt(struct v4l2_subdev *sd, |
376 | struct v4l2_mbus_framefmt *mf) | 376 | struct v4l2_mbus_framefmt *mf) |
377 | { | 377 | { |
378 | struct i2c_client *client = sd->priv; | 378 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
379 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 379 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
380 | struct v4l2_crop a = { | 380 | struct v4l2_crop a = { |
381 | .c = { | 381 | .c = { |
@@ -422,7 +422,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, | |||
422 | static int mt9v022_try_fmt(struct v4l2_subdev *sd, | 422 | static int mt9v022_try_fmt(struct v4l2_subdev *sd, |
423 | struct v4l2_mbus_framefmt *mf) | 423 | struct v4l2_mbus_framefmt *mf) |
424 | { | 424 | { |
425 | struct i2c_client *client = sd->priv; | 425 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
426 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 426 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
427 | const struct mt9v022_datafmt *fmt; | 427 | const struct mt9v022_datafmt *fmt; |
428 | int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || | 428 | int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || |
@@ -448,7 +448,7 @@ static int mt9v022_try_fmt(struct v4l2_subdev *sd, | |||
448 | static int mt9v022_g_chip_ident(struct v4l2_subdev *sd, | 448 | static int mt9v022_g_chip_ident(struct v4l2_subdev *sd, |
449 | struct v4l2_dbg_chip_ident *id) | 449 | struct v4l2_dbg_chip_ident *id) |
450 | { | 450 | { |
451 | struct i2c_client *client = sd->priv; | 451 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
452 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 452 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
453 | 453 | ||
454 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 454 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
@@ -467,7 +467,7 @@ static int mt9v022_g_chip_ident(struct v4l2_subdev *sd, | |||
467 | static int mt9v022_g_register(struct v4l2_subdev *sd, | 467 | static int mt9v022_g_register(struct v4l2_subdev *sd, |
468 | struct v4l2_dbg_register *reg) | 468 | struct v4l2_dbg_register *reg) |
469 | { | 469 | { |
470 | struct i2c_client *client = sd->priv; | 470 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
471 | 471 | ||
472 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 472 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
473 | return -EINVAL; | 473 | return -EINVAL; |
@@ -487,7 +487,7 @@ static int mt9v022_g_register(struct v4l2_subdev *sd, | |||
487 | static int mt9v022_s_register(struct v4l2_subdev *sd, | 487 | static int mt9v022_s_register(struct v4l2_subdev *sd, |
488 | struct v4l2_dbg_register *reg) | 488 | struct v4l2_dbg_register *reg) |
489 | { | 489 | { |
490 | struct i2c_client *client = sd->priv; | 490 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
491 | 491 | ||
492 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 492 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
493 | return -EINVAL; | 493 | return -EINVAL; |
@@ -565,7 +565,7 @@ static struct soc_camera_ops mt9v022_ops = { | |||
565 | 565 | ||
566 | static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 566 | static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
567 | { | 567 | { |
568 | struct i2c_client *client = sd->priv; | 568 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
569 | const struct v4l2_queryctrl *qctrl; | 569 | const struct v4l2_queryctrl *qctrl; |
570 | unsigned long range; | 570 | unsigned long range; |
571 | int data; | 571 | int data; |
@@ -622,7 +622,7 @@ static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
622 | static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 622 | static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
623 | { | 623 | { |
624 | int data; | 624 | int data; |
625 | struct i2c_client *client = sd->priv; | 625 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
626 | const struct v4l2_queryctrl *qctrl; | 626 | const struct v4l2_queryctrl *qctrl; |
627 | 627 | ||
628 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | 628 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); |
@@ -817,7 +817,7 @@ static void mt9v022_video_remove(struct soc_camera_device *icd) | |||
817 | 817 | ||
818 | static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) | 818 | static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) |
819 | { | 819 | { |
820 | struct i2c_client *client = sd->priv; | 820 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
821 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 821 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
822 | 822 | ||
823 | *lines = mt9v022->y_skip_top; | 823 | *lines = mt9v022->y_skip_top; |
@@ -838,7 +838,7 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { | |||
838 | static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | 838 | static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, |
839 | enum v4l2_mbus_pixelcode *code) | 839 | enum v4l2_mbus_pixelcode *code) |
840 | { | 840 | { |
841 | struct i2c_client *client = sd->priv; | 841 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
842 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 842 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
843 | 843 | ||
844 | if (index >= mt9v022->num_fmts) | 844 | if (index >= mt9v022->num_fmts) |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 5c17f9ec3d7..5e486a88ad7 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -161,7 +161,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf) | |||
161 | * This waits until this buffer is out of danger, i.e., until it is no | 161 | * This waits until this buffer is out of danger, i.e., until it is no |
162 | * longer in STATE_QUEUED or STATE_ACTIVE | 162 | * longer in STATE_QUEUED or STATE_ACTIVE |
163 | */ | 163 | */ |
164 | videobuf_waiton(vb, 0, 0); | 164 | videobuf_waiton(vq, vb, 0, 0); |
165 | videobuf_dma_contig_free(vq, vb); | 165 | videobuf_dma_contig_free(vq, vb); |
166 | 166 | ||
167 | vb->state = VIDEOBUF_NEEDS_INIT; | 167 | vb->state = VIDEOBUF_NEEDS_INIT; |
@@ -385,7 +385,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q, | |||
385 | &pcdev->lock, | 385 | &pcdev->lock, |
386 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 386 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
387 | V4L2_FIELD_NONE, | 387 | V4L2_FIELD_NONE, |
388 | sizeof(struct mx1_buffer), icd); | 388 | sizeof(struct mx1_buffer), icd, NULL); |
389 | } | 389 | } |
390 | 390 | ||
391 | static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | 391 | static int mclk_get_divisor(struct mx1_camera_dev *pcdev) |
@@ -638,7 +638,7 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd, | |||
638 | return 0; | 638 | return 0; |
639 | } | 639 | } |
640 | 640 | ||
641 | static int mx1_camera_reqbufs(struct soc_camera_file *icf, | 641 | static int mx1_camera_reqbufs(struct soc_camera_device *icd, |
642 | struct v4l2_requestbuffers *p) | 642 | struct v4l2_requestbuffers *p) |
643 | { | 643 | { |
644 | int i; | 644 | int i; |
@@ -650,7 +650,7 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf, | |||
650 | * it hadn't triggered | 650 | * it hadn't triggered |
651 | */ | 651 | */ |
652 | for (i = 0; i < p->count; i++) { | 652 | for (i = 0; i < p->count; i++) { |
653 | struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], | 653 | struct mx1_buffer *buf = container_of(icd->vb_vidq.bufs[i], |
654 | struct mx1_buffer, vb); | 654 | struct mx1_buffer, vb); |
655 | buf->inwork = 0; | 655 | buf->inwork = 0; |
656 | INIT_LIST_HEAD(&buf->vb.queue); | 656 | INIT_LIST_HEAD(&buf->vb.queue); |
@@ -661,10 +661,10 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf, | |||
661 | 661 | ||
662 | static unsigned int mx1_camera_poll(struct file *file, poll_table *pt) | 662 | static unsigned int mx1_camera_poll(struct file *file, poll_table *pt) |
663 | { | 663 | { |
664 | struct soc_camera_file *icf = file->private_data; | 664 | struct soc_camera_device *icd = file->private_data; |
665 | struct mx1_buffer *buf; | 665 | struct mx1_buffer *buf; |
666 | 666 | ||
667 | buf = list_entry(icf->vb_vidq.stream.next, struct mx1_buffer, | 667 | buf = list_entry(icd->vb_vidq.stream.next, struct mx1_buffer, |
668 | vb.stream); | 668 | vb.stream); |
669 | 669 | ||
670 | poll_wait(file, &buf->vb.done, pt); | 670 | poll_wait(file, &buf->vb.done, pt); |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index b6ea67221d1..4a27862da30 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -461,9 +461,9 @@ static void free_buffer(struct videobuf_queue *vq, struct mx2_buffer *buf) | |||
461 | 461 | ||
462 | /* | 462 | /* |
463 | * This waits until this buffer is out of danger, i.e., until it is no | 463 | * This waits until this buffer is out of danger, i.e., until it is no |
464 | * longer in STATE_QUEUED or STATE_ACTIVE | 464 | * longer in state VIDEOBUF_QUEUED or VIDEOBUF_ACTIVE |
465 | */ | 465 | */ |
466 | videobuf_waiton(vb, 0, 0); | 466 | videobuf_waiton(vq, vb, 0, 0); |
467 | 467 | ||
468 | videobuf_dma_contig_free(vq, vb); | 468 | videobuf_dma_contig_free(vq, vb); |
469 | dev_dbg(&icd->dev, "%s freed\n", __func__); | 469 | dev_dbg(&icd->dev, "%s freed\n", __func__); |
@@ -640,15 +640,27 @@ static void mx2_videobuf_release(struct videobuf_queue *vq, | |||
640 | * Terminate only queued but inactive buffers. Active buffers are | 640 | * Terminate only queued but inactive buffers. Active buffers are |
641 | * released when they become inactive after videobuf_waiton(). | 641 | * released when they become inactive after videobuf_waiton(). |
642 | * | 642 | * |
643 | * FIXME: implement forced termination of active buffers, so that the | 643 | * FIXME: implement forced termination of active buffers for mx27 and |
644 | * user won't get stuck in an uninterruptible state. This requires a | 644 | * mx27 eMMA, so that the user won't get stuck in an uninterruptible |
645 | * specific handling for each of the three DMA types that this driver | 645 | * state. This requires a specific handling for each of the these DMA |
646 | * supports. | 646 | * types. |
647 | */ | 647 | */ |
648 | spin_lock_irqsave(&pcdev->lock, flags); | 648 | spin_lock_irqsave(&pcdev->lock, flags); |
649 | if (vb->state == VIDEOBUF_QUEUED) { | 649 | if (vb->state == VIDEOBUF_QUEUED) { |
650 | list_del(&vb->queue); | 650 | list_del(&vb->queue); |
651 | vb->state = VIDEOBUF_ERROR; | 651 | vb->state = VIDEOBUF_ERROR; |
652 | } else if (cpu_is_mx25() && vb->state == VIDEOBUF_ACTIVE) { | ||
653 | if (pcdev->fb1_active == buf) { | ||
654 | pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN; | ||
655 | writel(0, pcdev->base_csi + CSIDMASA_FB1); | ||
656 | pcdev->fb1_active = NULL; | ||
657 | } else if (pcdev->fb2_active == buf) { | ||
658 | pcdev->csicr1 &= ~CSICR1_FB2_DMA_INTEN; | ||
659 | writel(0, pcdev->base_csi + CSIDMASA_FB2); | ||
660 | pcdev->fb2_active = NULL; | ||
661 | } | ||
662 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); | ||
663 | vb->state = VIDEOBUF_ERROR; | ||
652 | } | 664 | } |
653 | spin_unlock_irqrestore(&pcdev->lock, flags); | 665 | spin_unlock_irqrestore(&pcdev->lock, flags); |
654 | 666 | ||
@@ -670,7 +682,7 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q, | |||
670 | 682 | ||
671 | videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, | 683 | videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, |
672 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 684 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
673 | V4L2_FIELD_NONE, sizeof(struct mx2_buffer), icd); | 685 | V4L2_FIELD_NONE, sizeof(struct mx2_buffer), icd, NULL); |
674 | } | 686 | } |
675 | 687 | ||
676 | #define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \ | 688 | #define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \ |
@@ -716,8 +728,11 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, | |||
716 | /* | 728 | /* |
717 | * We only use the EMMA engine to get rid of the broken | 729 | * We only use the EMMA engine to get rid of the broken |
718 | * DMA Engine. No color space consversion at the moment. | 730 | * DMA Engine. No color space consversion at the moment. |
719 | * We adjust incoming and outgoing pixelformat to rgb16 | 731 | * We set the incomming and outgoing pixelformat to an |
720 | * and adjust the bytesperline accordingly. | 732 | * 16 Bit wide format and adjust the bytesperline |
733 | * accordingly. With this configuration the inputdata | ||
734 | * will not be changed by the emma and could be any type | ||
735 | * of 16 Bit Pixelformat. | ||
721 | */ | 736 | */ |
722 | writel(PRP_CNTL_CH1EN | | 737 | writel(PRP_CNTL_CH1EN | |
723 | PRP_CNTL_CSIEN | | 738 | PRP_CNTL_CSIEN | |
@@ -903,10 +918,6 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd, | |||
903 | return -EINVAL; | 918 | return -EINVAL; |
904 | } | 919 | } |
905 | 920 | ||
906 | /* eMMA can only do RGB565 */ | ||
907 | if (mx27_camera_emma(pcdev) && pix->pixelformat != V4L2_PIX_FMT_RGB565) | ||
908 | return -EINVAL; | ||
909 | |||
910 | mf.width = pix->width; | 921 | mf.width = pix->width; |
911 | mf.height = pix->height; | 922 | mf.height = pix->height; |
912 | mf.field = pix->field; | 923 | mf.field = pix->field; |
@@ -950,10 +961,6 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, | |||
950 | 961 | ||
951 | /* FIXME: implement MX27 limits */ | 962 | /* FIXME: implement MX27 limits */ |
952 | 963 | ||
953 | /* eMMA can only do RGB565 */ | ||
954 | if (mx27_camera_emma(pcdev) && pixfmt != V4L2_PIX_FMT_RGB565) | ||
955 | return -EINVAL; | ||
956 | |||
957 | /* limit to MX25 hardware capabilities */ | 964 | /* limit to MX25 hardware capabilities */ |
958 | if (cpu_is_mx25()) { | 965 | if (cpu_is_mx25()) { |
959 | if (xlate->host_fmt->bits_per_sample <= 8) | 966 | if (xlate->host_fmt->bits_per_sample <= 8) |
@@ -1426,6 +1433,9 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1426 | if (err) | 1433 | if (err) |
1427 | goto exit_free_emma; | 1434 | goto exit_free_emma; |
1428 | 1435 | ||
1436 | dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n", | ||
1437 | clk_get_rate(pcdev->clk_csi)); | ||
1438 | |||
1429 | return 0; | 1439 | return 0; |
1430 | 1440 | ||
1431 | exit_free_emma: | 1441 | exit_free_emma: |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index a9be14c2391..29c5fc34813 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -185,7 +185,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf | |||
185 | * This waits until this buffer is out of danger, i.e., until it is no | 185 | * This waits until this buffer is out of danger, i.e., until it is no |
186 | * longer in STATE_QUEUED or STATE_ACTIVE | 186 | * longer in STATE_QUEUED or STATE_ACTIVE |
187 | */ | 187 | */ |
188 | videobuf_waiton(vb, 0, 0); | 188 | videobuf_waiton(vq, vb, 0, 0); |
189 | if (txd) { | 189 | if (txd) { |
190 | ichan = to_idmac_chan(txd->chan); | 190 | ichan = to_idmac_chan(txd->chan); |
191 | async_tx_ack(txd); | 191 | async_tx_ack(txd); |
@@ -441,7 +441,8 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q, | |||
441 | &mx3_cam->lock, | 441 | &mx3_cam->lock, |
442 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 442 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
443 | V4L2_FIELD_NONE, | 443 | V4L2_FIELD_NONE, |
444 | sizeof(struct mx3_camera_buffer), icd); | 444 | sizeof(struct mx3_camera_buffer), icd, |
445 | NULL); | ||
445 | } | 446 | } |
446 | 447 | ||
447 | /* First part of ipu_csi_init_interface() */ | 448 | /* First part of ipu_csi_init_interface() */ |
@@ -976,7 +977,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, | |||
976 | return ret; | 977 | return ret; |
977 | } | 978 | } |
978 | 979 | ||
979 | static int mx3_camera_reqbufs(struct soc_camera_file *icf, | 980 | static int mx3_camera_reqbufs(struct soc_camera_device *icd, |
980 | struct v4l2_requestbuffers *p) | 981 | struct v4l2_requestbuffers *p) |
981 | { | 982 | { |
982 | return 0; | 983 | return 0; |
@@ -984,9 +985,9 @@ static int mx3_camera_reqbufs(struct soc_camera_file *icf, | |||
984 | 985 | ||
985 | static unsigned int mx3_camera_poll(struct file *file, poll_table *pt) | 986 | static unsigned int mx3_camera_poll(struct file *file, poll_table *pt) |
986 | { | 987 | { |
987 | struct soc_camera_file *icf = file->private_data; | 988 | struct soc_camera_device *icd = file->private_data; |
988 | 989 | ||
989 | return videobuf_poll_stream(file, &icf->vb_vidq, pt); | 990 | return videobuf_poll_stream(file, &icd->vb_vidq, pt); |
990 | } | 991 | } |
991 | 992 | ||
992 | static int mx3_camera_querycap(struct soc_camera_host *ici, | 993 | static int mx3_camera_querycap(struct soc_camera_host *ici, |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index b1dbcf1d2bc..94ba698d0ad 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include "tea6415c.h" | 32 | #include "tea6415c.h" |
33 | #include "tea6420.h" | 33 | #include "tea6420.h" |
34 | 34 | ||
35 | #define I2C_SAA5246A 0x11 | ||
36 | #define I2C_SAA7111A 0x24 | 35 | #define I2C_SAA7111A 0x24 |
37 | #define I2C_TDA9840 0x42 | 36 | #define I2C_TDA9840 0x42 |
38 | #define I2C_TEA6415C 0x43 | 37 | #define I2C_TEA6415C 0x43 |
@@ -186,21 +185,17 @@ static int mxb_probe(struct saa7146_dev *dev) | |||
186 | } | 185 | } |
187 | 186 | ||
188 | mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | 187 | mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, |
189 | "saa7115", "saa7111", I2C_SAA7111A, NULL); | 188 | NULL, "saa7111", I2C_SAA7111A, NULL); |
190 | mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | 189 | mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, |
191 | "tea6420", "tea6420", I2C_TEA6420_1, NULL); | 190 | NULL, "tea6420", I2C_TEA6420_1, NULL); |
192 | mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | 191 | mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, |
193 | "tea6420", "tea6420", I2C_TEA6420_2, NULL); | 192 | NULL, "tea6420", I2C_TEA6420_2, NULL); |
194 | mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | 193 | mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, |
195 | "tea6415c", "tea6415c", I2C_TEA6415C, NULL); | 194 | NULL, "tea6415c", I2C_TEA6415C, NULL); |
196 | mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | 195 | mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, |
197 | "tda9840", "tda9840", I2C_TDA9840, NULL); | 196 | NULL, "tda9840", I2C_TDA9840, NULL); |
198 | mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | 197 | mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, |
199 | "tuner", "tuner", I2C_TUNER, NULL); | 198 | NULL, "tuner", I2C_TUNER, NULL); |
200 | if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, | ||
201 | "saa5246a", "saa5246a", I2C_SAA5246A, NULL)) { | ||
202 | printk(KERN_INFO "mxb: found teletext decoder\n"); | ||
203 | } | ||
204 | 199 | ||
205 | /* check if all devices are present */ | 200 | /* check if all devices are present */ |
206 | if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || | 201 | if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 4ed51b1552e..15f8793e325 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -1341,7 +1341,7 @@ static int omap_vout_open(struct file *file) | |||
1341 | 1341 | ||
1342 | videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev, | 1342 | videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev, |
1343 | &vout->vbq_lock, vout->type, V4L2_FIELD_NONE, | 1343 | &vout->vbq_lock, vout->type, V4L2_FIELD_NONE, |
1344 | sizeof(struct videobuf_buffer), vout); | 1344 | sizeof(struct videobuf_buffer), vout, NULL); |
1345 | 1345 | ||
1346 | v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); | 1346 | v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); |
1347 | return 0; | 1347 | return 0; |
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c new file mode 100644 index 00000000000..7c30e62b50d --- /dev/null +++ b/drivers/media/video/omap1_camera.c | |||
@@ -0,0 +1,1702 @@ | |||
1 | /* | ||
2 | * V4L2 SoC Camera driver for OMAP1 Camera Interface | ||
3 | * | ||
4 | * Copyright (C) 2010, Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> | ||
5 | * | ||
6 | * Based on V4L2 Driver for i.MXL/i.MXL camera (CSI) host | ||
7 | * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
8 | * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com> | ||
9 | * | ||
10 | * Based on PXA SoC camera driver | ||
11 | * Copyright (C) 2006, Sascha Hauer, Pengutronix | ||
12 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
13 | * | ||
14 | * Hardware specific bits initialy based on former work by Matt Callow | ||
15 | * drivers/media/video/omap/omap1510cam.c | ||
16 | * Copyright (C) 2006 Matt Callow | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License version 2 as | ||
20 | * published by the Free Software Foundation. | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <linux/clk.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/version.h> | ||
30 | |||
31 | #include <media/omap1_camera.h> | ||
32 | #include <media/soc_camera.h> | ||
33 | #include <media/soc_mediabus.h> | ||
34 | #include <media/videobuf-dma-contig.h> | ||
35 | #include <media/videobuf-dma-sg.h> | ||
36 | |||
37 | #include <plat/dma.h> | ||
38 | |||
39 | |||
40 | #define DRIVER_NAME "omap1-camera" | ||
41 | #define VERSION_CODE KERNEL_VERSION(0, 0, 1) | ||
42 | |||
43 | |||
44 | /* | ||
45 | * --------------------------------------------------------------------------- | ||
46 | * OMAP1 Camera Interface registers | ||
47 | * --------------------------------------------------------------------------- | ||
48 | */ | ||
49 | |||
50 | #define REG_CTRLCLOCK 0x00 | ||
51 | #define REG_IT_STATUS 0x04 | ||
52 | #define REG_MODE 0x08 | ||
53 | #define REG_STATUS 0x0C | ||
54 | #define REG_CAMDATA 0x10 | ||
55 | #define REG_GPIO 0x14 | ||
56 | #define REG_PEAK_COUNTER 0x18 | ||
57 | |||
58 | /* CTRLCLOCK bit shifts */ | ||
59 | #define LCLK_EN BIT(7) | ||
60 | #define DPLL_EN BIT(6) | ||
61 | #define MCLK_EN BIT(5) | ||
62 | #define CAMEXCLK_EN BIT(4) | ||
63 | #define POLCLK BIT(3) | ||
64 | #define FOSCMOD_SHIFT 0 | ||
65 | #define FOSCMOD_MASK (0x7 << FOSCMOD_SHIFT) | ||
66 | #define FOSCMOD_12MHz 0x0 | ||
67 | #define FOSCMOD_6MHz 0x2 | ||
68 | #define FOSCMOD_9_6MHz 0x4 | ||
69 | #define FOSCMOD_24MHz 0x5 | ||
70 | #define FOSCMOD_8MHz 0x6 | ||
71 | |||
72 | /* IT_STATUS bit shifts */ | ||
73 | #define DATA_TRANSFER BIT(5) | ||
74 | #define FIFO_FULL BIT(4) | ||
75 | #define H_DOWN BIT(3) | ||
76 | #define H_UP BIT(2) | ||
77 | #define V_DOWN BIT(1) | ||
78 | #define V_UP BIT(0) | ||
79 | |||
80 | /* MODE bit shifts */ | ||
81 | #define RAZ_FIFO BIT(18) | ||
82 | #define EN_FIFO_FULL BIT(17) | ||
83 | #define EN_NIRQ BIT(16) | ||
84 | #define THRESHOLD_SHIFT 9 | ||
85 | #define THRESHOLD_MASK (0x7f << THRESHOLD_SHIFT) | ||
86 | #define DMA BIT(8) | ||
87 | #define EN_H_DOWN BIT(7) | ||
88 | #define EN_H_UP BIT(6) | ||
89 | #define EN_V_DOWN BIT(5) | ||
90 | #define EN_V_UP BIT(4) | ||
91 | #define ORDERCAMD BIT(3) | ||
92 | |||
93 | #define IRQ_MASK (EN_V_UP | EN_V_DOWN | EN_H_UP | EN_H_DOWN | \ | ||
94 | EN_NIRQ | EN_FIFO_FULL) | ||
95 | |||
96 | /* STATUS bit shifts */ | ||
97 | #define HSTATUS BIT(1) | ||
98 | #define VSTATUS BIT(0) | ||
99 | |||
100 | /* GPIO bit shifts */ | ||
101 | #define CAM_RST BIT(0) | ||
102 | |||
103 | /* end of OMAP1 Camera Interface registers */ | ||
104 | |||
105 | |||
106 | #define SOCAM_BUS_FLAGS (SOCAM_MASTER | \ | ||
107 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | \ | ||
108 | SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \ | ||
109 | SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8) | ||
110 | |||
111 | |||
112 | #define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1) | ||
113 | #define FIFO_SHIFT __fls(FIFO_SIZE) | ||
114 | |||
115 | #define DMA_BURST_SHIFT (1 + OMAP_DMA_DATA_BURST_4) | ||
116 | #define DMA_BURST_SIZE (1 << DMA_BURST_SHIFT) | ||
117 | |||
118 | #define DMA_ELEMENT_SHIFT OMAP_DMA_DATA_TYPE_S32 | ||
119 | #define DMA_ELEMENT_SIZE (1 << DMA_ELEMENT_SHIFT) | ||
120 | |||
121 | #define DMA_FRAME_SHIFT_CONTIG (FIFO_SHIFT - 1) | ||
122 | #define DMA_FRAME_SHIFT_SG DMA_BURST_SHIFT | ||
123 | |||
124 | #define DMA_FRAME_SHIFT(x) ((x) == OMAP1_CAM_DMA_CONTIG ? \ | ||
125 | DMA_FRAME_SHIFT_CONTIG : \ | ||
126 | DMA_FRAME_SHIFT_SG) | ||
127 | #define DMA_FRAME_SIZE(x) (1 << DMA_FRAME_SHIFT(x)) | ||
128 | #define DMA_SYNC OMAP_DMA_SYNC_FRAME | ||
129 | #define THRESHOLD_LEVEL DMA_FRAME_SIZE | ||
130 | |||
131 | |||
132 | #define MAX_VIDEO_MEM 4 /* arbitrary video memory limit in MB */ | ||
133 | |||
134 | |||
135 | /* | ||
136 | * Structures | ||
137 | */ | ||
138 | |||
139 | /* buffer for one video frame */ | ||
140 | struct omap1_cam_buf { | ||
141 | struct videobuf_buffer vb; | ||
142 | enum v4l2_mbus_pixelcode code; | ||
143 | int inwork; | ||
144 | struct scatterlist *sgbuf; | ||
145 | int sgcount; | ||
146 | int bytes_left; | ||
147 | enum videobuf_state result; | ||
148 | }; | ||
149 | |||
150 | struct omap1_cam_dev { | ||
151 | struct soc_camera_host soc_host; | ||
152 | struct soc_camera_device *icd; | ||
153 | struct clk *clk; | ||
154 | |||
155 | unsigned int irq; | ||
156 | void __iomem *base; | ||
157 | |||
158 | int dma_ch; | ||
159 | |||
160 | struct omap1_cam_platform_data *pdata; | ||
161 | struct resource *res; | ||
162 | unsigned long pflags; | ||
163 | unsigned long camexclk; | ||
164 | |||
165 | struct list_head capture; | ||
166 | |||
167 | /* lock used to protect videobuf */ | ||
168 | spinlock_t lock; | ||
169 | |||
170 | /* Pointers to DMA buffers */ | ||
171 | struct omap1_cam_buf *active; | ||
172 | struct omap1_cam_buf *ready; | ||
173 | |||
174 | enum omap1_cam_vb_mode vb_mode; | ||
175 | int (*mmap_mapper)(struct videobuf_queue *q, | ||
176 | struct videobuf_buffer *buf, | ||
177 | struct vm_area_struct *vma); | ||
178 | |||
179 | u32 reg_cache[0]; | ||
180 | }; | ||
181 | |||
182 | |||
183 | static void cam_write(struct omap1_cam_dev *pcdev, u16 reg, u32 val) | ||
184 | { | ||
185 | pcdev->reg_cache[reg / sizeof(u32)] = val; | ||
186 | __raw_writel(val, pcdev->base + reg); | ||
187 | } | ||
188 | |||
189 | static u32 cam_read(struct omap1_cam_dev *pcdev, u16 reg, bool from_cache) | ||
190 | { | ||
191 | return !from_cache ? __raw_readl(pcdev->base + reg) : | ||
192 | pcdev->reg_cache[reg / sizeof(u32)]; | ||
193 | } | ||
194 | |||
195 | #define CAM_READ(pcdev, reg) \ | ||
196 | cam_read(pcdev, REG_##reg, false) | ||
197 | #define CAM_WRITE(pcdev, reg, val) \ | ||
198 | cam_write(pcdev, REG_##reg, val) | ||
199 | #define CAM_READ_CACHE(pcdev, reg) \ | ||
200 | cam_read(pcdev, REG_##reg, true) | ||
201 | |||
202 | /* | ||
203 | * Videobuf operations | ||
204 | */ | ||
205 | static int omap1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | ||
206 | unsigned int *size) | ||
207 | { | ||
208 | struct soc_camera_device *icd = vq->priv_data; | ||
209 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
210 | icd->current_fmt->host_fmt); | ||
211 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
212 | struct omap1_cam_dev *pcdev = ici->priv; | ||
213 | |||
214 | if (bytes_per_line < 0) | ||
215 | return bytes_per_line; | ||
216 | |||
217 | *size = bytes_per_line * icd->user_height; | ||
218 | |||
219 | if (!*count || *count < OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode)) | ||
220 | *count = OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode); | ||
221 | |||
222 | if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) | ||
223 | *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size; | ||
224 | |||
225 | dev_dbg(icd->dev.parent, | ||
226 | "%s: count=%d, size=%d\n", __func__, *count, *size); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void free_buffer(struct videobuf_queue *vq, struct omap1_cam_buf *buf, | ||
232 | enum omap1_cam_vb_mode vb_mode) | ||
233 | { | ||
234 | struct videobuf_buffer *vb = &buf->vb; | ||
235 | |||
236 | BUG_ON(in_interrupt()); | ||
237 | |||
238 | videobuf_waiton(vb, 0, 0); | ||
239 | |||
240 | if (vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
241 | videobuf_dma_contig_free(vq, vb); | ||
242 | } else { | ||
243 | struct soc_camera_device *icd = vq->priv_data; | ||
244 | struct device *dev = icd->dev.parent; | ||
245 | struct videobuf_dmabuf *dma = videobuf_to_dma(vb); | ||
246 | |||
247 | videobuf_dma_unmap(dev, dma); | ||
248 | videobuf_dma_free(dma); | ||
249 | } | ||
250 | |||
251 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
252 | } | ||
253 | |||
254 | static int omap1_videobuf_prepare(struct videobuf_queue *vq, | ||
255 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
256 | { | ||
257 | struct soc_camera_device *icd = vq->priv_data; | ||
258 | struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb); | ||
259 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
260 | icd->current_fmt->host_fmt); | ||
261 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
262 | struct omap1_cam_dev *pcdev = ici->priv; | ||
263 | int ret; | ||
264 | |||
265 | if (bytes_per_line < 0) | ||
266 | return bytes_per_line; | ||
267 | |||
268 | WARN_ON(!list_empty(&vb->queue)); | ||
269 | |||
270 | BUG_ON(NULL == icd->current_fmt); | ||
271 | |||
272 | buf->inwork = 1; | ||
273 | |||
274 | if (buf->code != icd->current_fmt->code || vb->field != field || | ||
275 | vb->width != icd->user_width || | ||
276 | vb->height != icd->user_height) { | ||
277 | buf->code = icd->current_fmt->code; | ||
278 | vb->width = icd->user_width; | ||
279 | vb->height = icd->user_height; | ||
280 | vb->field = field; | ||
281 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
282 | } | ||
283 | |||
284 | vb->size = bytes_per_line * vb->height; | ||
285 | |||
286 | if (vb->baddr && vb->bsize < vb->size) { | ||
287 | ret = -EINVAL; | ||
288 | goto out; | ||
289 | } | ||
290 | |||
291 | if (vb->state == VIDEOBUF_NEEDS_INIT) { | ||
292 | ret = videobuf_iolock(vq, vb, NULL); | ||
293 | if (ret) | ||
294 | goto fail; | ||
295 | |||
296 | vb->state = VIDEOBUF_PREPARED; | ||
297 | } | ||
298 | buf->inwork = 0; | ||
299 | |||
300 | return 0; | ||
301 | fail: | ||
302 | free_buffer(vq, buf, pcdev->vb_mode); | ||
303 | out: | ||
304 | buf->inwork = 0; | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | static void set_dma_dest_params(int dma_ch, struct omap1_cam_buf *buf, | ||
309 | enum omap1_cam_vb_mode vb_mode) | ||
310 | { | ||
311 | dma_addr_t dma_addr; | ||
312 | unsigned int block_size; | ||
313 | |||
314 | if (vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
315 | dma_addr = videobuf_to_dma_contig(&buf->vb); | ||
316 | block_size = buf->vb.size; | ||
317 | } else { | ||
318 | if (WARN_ON(!buf->sgbuf)) { | ||
319 | buf->result = VIDEOBUF_ERROR; | ||
320 | return; | ||
321 | } | ||
322 | dma_addr = sg_dma_address(buf->sgbuf); | ||
323 | if (WARN_ON(!dma_addr)) { | ||
324 | buf->sgbuf = NULL; | ||
325 | buf->result = VIDEOBUF_ERROR; | ||
326 | return; | ||
327 | } | ||
328 | block_size = sg_dma_len(buf->sgbuf); | ||
329 | if (WARN_ON(!block_size)) { | ||
330 | buf->sgbuf = NULL; | ||
331 | buf->result = VIDEOBUF_ERROR; | ||
332 | return; | ||
333 | } | ||
334 | if (unlikely(buf->bytes_left < block_size)) | ||
335 | block_size = buf->bytes_left; | ||
336 | if (WARN_ON(dma_addr & (DMA_FRAME_SIZE(vb_mode) * | ||
337 | DMA_ELEMENT_SIZE - 1))) { | ||
338 | dma_addr = ALIGN(dma_addr, DMA_FRAME_SIZE(vb_mode) * | ||
339 | DMA_ELEMENT_SIZE); | ||
340 | block_size &= ~(DMA_FRAME_SIZE(vb_mode) * | ||
341 | DMA_ELEMENT_SIZE - 1); | ||
342 | } | ||
343 | buf->bytes_left -= block_size; | ||
344 | buf->sgcount++; | ||
345 | } | ||
346 | |||
347 | omap_set_dma_dest_params(dma_ch, | ||
348 | OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); | ||
349 | omap_set_dma_transfer_params(dma_ch, | ||
350 | OMAP_DMA_DATA_TYPE_S32, DMA_FRAME_SIZE(vb_mode), | ||
351 | block_size >> (DMA_FRAME_SHIFT(vb_mode) + DMA_ELEMENT_SHIFT), | ||
352 | DMA_SYNC, 0, 0); | ||
353 | } | ||
354 | |||
355 | static struct omap1_cam_buf *prepare_next_vb(struct omap1_cam_dev *pcdev) | ||
356 | { | ||
357 | struct omap1_cam_buf *buf; | ||
358 | |||
359 | /* | ||
360 | * If there is already a buffer pointed out by the pcdev->ready, | ||
361 | * (re)use it, otherwise try to fetch and configure a new one. | ||
362 | */ | ||
363 | buf = pcdev->ready; | ||
364 | if (!buf) { | ||
365 | if (list_empty(&pcdev->capture)) | ||
366 | return buf; | ||
367 | buf = list_entry(pcdev->capture.next, | ||
368 | struct omap1_cam_buf, vb.queue); | ||
369 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
370 | pcdev->ready = buf; | ||
371 | list_del_init(&buf->vb.queue); | ||
372 | } | ||
373 | |||
374 | if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
375 | /* | ||
376 | * In CONTIG mode, we can safely enter next buffer parameters | ||
377 | * into the DMA programming register set after the DMA | ||
378 | * has already been activated on the previous buffer | ||
379 | */ | ||
380 | set_dma_dest_params(pcdev->dma_ch, buf, pcdev->vb_mode); | ||
381 | } else { | ||
382 | /* | ||
383 | * In SG mode, the above is not safe since there are probably | ||
384 | * a bunch of sgbufs from previous sglist still pending. | ||
385 | * Instead, mark the sglist fresh for the upcoming | ||
386 | * try_next_sgbuf(). | ||
387 | */ | ||
388 | buf->sgbuf = NULL; | ||
389 | } | ||
390 | |||
391 | return buf; | ||
392 | } | ||
393 | |||
394 | static struct scatterlist *try_next_sgbuf(int dma_ch, struct omap1_cam_buf *buf) | ||
395 | { | ||
396 | struct scatterlist *sgbuf; | ||
397 | |||
398 | if (likely(buf->sgbuf)) { | ||
399 | /* current sglist is active */ | ||
400 | if (unlikely(!buf->bytes_left)) { | ||
401 | /* indicate sglist complete */ | ||
402 | sgbuf = NULL; | ||
403 | } else { | ||
404 | /* process next sgbuf */ | ||
405 | sgbuf = sg_next(buf->sgbuf); | ||
406 | if (WARN_ON(!sgbuf)) { | ||
407 | buf->result = VIDEOBUF_ERROR; | ||
408 | } else if (WARN_ON(!sg_dma_len(sgbuf))) { | ||
409 | sgbuf = NULL; | ||
410 | buf->result = VIDEOBUF_ERROR; | ||
411 | } | ||
412 | } | ||
413 | buf->sgbuf = sgbuf; | ||
414 | } else { | ||
415 | /* sglist is fresh, initialize it before using */ | ||
416 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | ||
417 | |||
418 | sgbuf = dma->sglist; | ||
419 | if (!(WARN_ON(!sgbuf))) { | ||
420 | buf->sgbuf = sgbuf; | ||
421 | buf->sgcount = 0; | ||
422 | buf->bytes_left = buf->vb.size; | ||
423 | buf->result = VIDEOBUF_DONE; | ||
424 | } | ||
425 | } | ||
426 | if (sgbuf) | ||
427 | /* | ||
428 | * Put our next sgbuf parameters (address, size) | ||
429 | * into the DMA programming register set. | ||
430 | */ | ||
431 | set_dma_dest_params(dma_ch, buf, OMAP1_CAM_DMA_SG); | ||
432 | |||
433 | return sgbuf; | ||
434 | } | ||
435 | |||
436 | static void start_capture(struct omap1_cam_dev *pcdev) | ||
437 | { | ||
438 | struct omap1_cam_buf *buf = pcdev->active; | ||
439 | u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); | ||
440 | u32 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN; | ||
441 | |||
442 | if (WARN_ON(!buf)) | ||
443 | return; | ||
444 | |||
445 | /* | ||
446 | * Enable start of frame interrupt, which we will use for activating | ||
447 | * our end of frame watchdog when capture actually starts. | ||
448 | */ | ||
449 | mode |= EN_V_UP; | ||
450 | |||
451 | if (unlikely(ctrlclock & LCLK_EN)) | ||
452 | /* stop pixel clock before FIFO reset */ | ||
453 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); | ||
454 | /* reset FIFO */ | ||
455 | CAM_WRITE(pcdev, MODE, mode | RAZ_FIFO); | ||
456 | |||
457 | omap_start_dma(pcdev->dma_ch); | ||
458 | |||
459 | if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) { | ||
460 | /* | ||
461 | * In SG mode, it's a good moment for fetching next sgbuf | ||
462 | * from the current sglist and, if available, already putting | ||
463 | * its parameters into the DMA programming register set. | ||
464 | */ | ||
465 | try_next_sgbuf(pcdev->dma_ch, buf); | ||
466 | } | ||
467 | |||
468 | /* (re)enable pixel clock */ | ||
469 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | LCLK_EN); | ||
470 | /* release FIFO reset */ | ||
471 | CAM_WRITE(pcdev, MODE, mode); | ||
472 | } | ||
473 | |||
474 | static void suspend_capture(struct omap1_cam_dev *pcdev) | ||
475 | { | ||
476 | u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); | ||
477 | |||
478 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); | ||
479 | omap_stop_dma(pcdev->dma_ch); | ||
480 | } | ||
481 | |||
482 | static void disable_capture(struct omap1_cam_dev *pcdev) | ||
483 | { | ||
484 | u32 mode = CAM_READ_CACHE(pcdev, MODE); | ||
485 | |||
486 | CAM_WRITE(pcdev, MODE, mode & ~(IRQ_MASK | DMA)); | ||
487 | } | ||
488 | |||
489 | static void omap1_videobuf_queue(struct videobuf_queue *vq, | ||
490 | struct videobuf_buffer *vb) | ||
491 | { | ||
492 | struct soc_camera_device *icd = vq->priv_data; | ||
493 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
494 | struct omap1_cam_dev *pcdev = ici->priv; | ||
495 | struct omap1_cam_buf *buf; | ||
496 | u32 mode; | ||
497 | |||
498 | list_add_tail(&vb->queue, &pcdev->capture); | ||
499 | vb->state = VIDEOBUF_QUEUED; | ||
500 | |||
501 | if (pcdev->active) { | ||
502 | /* | ||
503 | * Capture in progress, so don't touch pcdev->ready even if | ||
504 | * empty. Since the transfer of the DMA programming register set | ||
505 | * content to the DMA working register set is done automatically | ||
506 | * by the DMA hardware, this can pretty well happen while we | ||
507 | * are keeping the lock here. Levae fetching it from the queue | ||
508 | * to be done when a next DMA interrupt occures instead. | ||
509 | */ | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | WARN_ON(pcdev->ready); | ||
514 | |||
515 | buf = prepare_next_vb(pcdev); | ||
516 | if (WARN_ON(!buf)) | ||
517 | return; | ||
518 | |||
519 | pcdev->active = buf; | ||
520 | pcdev->ready = NULL; | ||
521 | |||
522 | dev_dbg(icd->dev.parent, | ||
523 | "%s: capture not active, setup FIFO, start DMA\n", __func__); | ||
524 | mode = CAM_READ_CACHE(pcdev, MODE) & ~THRESHOLD_MASK; | ||
525 | mode |= THRESHOLD_LEVEL(pcdev->vb_mode) << THRESHOLD_SHIFT; | ||
526 | CAM_WRITE(pcdev, MODE, mode | EN_FIFO_FULL | DMA); | ||
527 | |||
528 | if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) { | ||
529 | /* | ||
530 | * In SG mode, the above prepare_next_vb() didn't actually | ||
531 | * put anything into the DMA programming register set, | ||
532 | * so we have to do it now, before activating DMA. | ||
533 | */ | ||
534 | try_next_sgbuf(pcdev->dma_ch, buf); | ||
535 | } | ||
536 | |||
537 | start_capture(pcdev); | ||
538 | } | ||
539 | |||
540 | static void omap1_videobuf_release(struct videobuf_queue *vq, | ||
541 | struct videobuf_buffer *vb) | ||
542 | { | ||
543 | struct omap1_cam_buf *buf = | ||
544 | container_of(vb, struct omap1_cam_buf, vb); | ||
545 | struct soc_camera_device *icd = vq->priv_data; | ||
546 | struct device *dev = icd->dev.parent; | ||
547 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
548 | struct omap1_cam_dev *pcdev = ici->priv; | ||
549 | |||
550 | switch (vb->state) { | ||
551 | case VIDEOBUF_DONE: | ||
552 | dev_dbg(dev, "%s (done)\n", __func__); | ||
553 | break; | ||
554 | case VIDEOBUF_ACTIVE: | ||
555 | dev_dbg(dev, "%s (active)\n", __func__); | ||
556 | break; | ||
557 | case VIDEOBUF_QUEUED: | ||
558 | dev_dbg(dev, "%s (queued)\n", __func__); | ||
559 | break; | ||
560 | case VIDEOBUF_PREPARED: | ||
561 | dev_dbg(dev, "%s (prepared)\n", __func__); | ||
562 | break; | ||
563 | default: | ||
564 | dev_dbg(dev, "%s (unknown %d)\n", __func__, vb->state); | ||
565 | break; | ||
566 | } | ||
567 | |||
568 | free_buffer(vq, buf, pcdev->vb_mode); | ||
569 | } | ||
570 | |||
571 | static void videobuf_done(struct omap1_cam_dev *pcdev, | ||
572 | enum videobuf_state result) | ||
573 | { | ||
574 | struct omap1_cam_buf *buf = pcdev->active; | ||
575 | struct videobuf_buffer *vb; | ||
576 | struct device *dev = pcdev->icd->dev.parent; | ||
577 | |||
578 | if (WARN_ON(!buf)) { | ||
579 | suspend_capture(pcdev); | ||
580 | disable_capture(pcdev); | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | if (result == VIDEOBUF_ERROR) | ||
585 | suspend_capture(pcdev); | ||
586 | |||
587 | vb = &buf->vb; | ||
588 | if (waitqueue_active(&vb->done)) { | ||
589 | if (!pcdev->ready && result != VIDEOBUF_ERROR) { | ||
590 | /* | ||
591 | * No next buffer has been entered into the DMA | ||
592 | * programming register set on time (could be done only | ||
593 | * while the previous DMA interurpt was processed, not | ||
594 | * later), so the last DMA block, be it a whole buffer | ||
595 | * if in CONTIG or its last sgbuf if in SG mode, is | ||
596 | * about to be reused by the just autoreinitialized DMA | ||
597 | * engine, and overwritten with next frame data. Best we | ||
598 | * can do is stopping the capture as soon as possible, | ||
599 | * hopefully before the next frame start. | ||
600 | */ | ||
601 | suspend_capture(pcdev); | ||
602 | } | ||
603 | vb->state = result; | ||
604 | do_gettimeofday(&vb->ts); | ||
605 | if (result != VIDEOBUF_ERROR) | ||
606 | vb->field_count++; | ||
607 | wake_up(&vb->done); | ||
608 | |||
609 | /* shift in next buffer */ | ||
610 | buf = pcdev->ready; | ||
611 | pcdev->active = buf; | ||
612 | pcdev->ready = NULL; | ||
613 | |||
614 | if (!buf) { | ||
615 | /* | ||
616 | * No next buffer was ready on time (see above), so | ||
617 | * indicate error condition to force capture restart or | ||
618 | * stop, depending on next buffer already queued or not. | ||
619 | */ | ||
620 | result = VIDEOBUF_ERROR; | ||
621 | prepare_next_vb(pcdev); | ||
622 | |||
623 | buf = pcdev->ready; | ||
624 | pcdev->active = buf; | ||
625 | pcdev->ready = NULL; | ||
626 | } | ||
627 | } else if (pcdev->ready) { | ||
628 | /* | ||
629 | * In both CONTIG and SG mode, the DMA engine has possibly | ||
630 | * been already autoreinitialized with the preprogrammed | ||
631 | * pcdev->ready buffer. We can either accept this fact | ||
632 | * and just swap the buffers, or provoke an error condition | ||
633 | * and restart capture. The former seems less intrusive. | ||
634 | */ | ||
635 | dev_dbg(dev, "%s: nobody waiting on videobuf, swap with next\n", | ||
636 | __func__); | ||
637 | pcdev->active = pcdev->ready; | ||
638 | |||
639 | if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) { | ||
640 | /* | ||
641 | * In SG mode, we have to make sure that the buffer we | ||
642 | * are putting back into the pcdev->ready is marked | ||
643 | * fresh. | ||
644 | */ | ||
645 | buf->sgbuf = NULL; | ||
646 | } | ||
647 | pcdev->ready = buf; | ||
648 | |||
649 | buf = pcdev->active; | ||
650 | } else { | ||
651 | /* | ||
652 | * No next buffer has been entered into | ||
653 | * the DMA programming register set on time. | ||
654 | */ | ||
655 | if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
656 | /* | ||
657 | * In CONTIG mode, the DMA engine has already been | ||
658 | * reinitialized with the current buffer. Best we can do | ||
659 | * is not touching it. | ||
660 | */ | ||
661 | dev_dbg(dev, | ||
662 | "%s: nobody waiting on videobuf, reuse it\n", | ||
663 | __func__); | ||
664 | } else { | ||
665 | /* | ||
666 | * In SG mode, the DMA engine has just been | ||
667 | * autoreinitialized with the last sgbuf from the | ||
668 | * current list. Restart capture in order to transfer | ||
669 | * next frame start into the first sgbuf, not the last | ||
670 | * one. | ||
671 | */ | ||
672 | if (result != VIDEOBUF_ERROR) { | ||
673 | suspend_capture(pcdev); | ||
674 | result = VIDEOBUF_ERROR; | ||
675 | } | ||
676 | } | ||
677 | } | ||
678 | |||
679 | if (!buf) { | ||
680 | dev_dbg(dev, "%s: no more videobufs, stop capture\n", __func__); | ||
681 | disable_capture(pcdev); | ||
682 | return; | ||
683 | } | ||
684 | |||
685 | if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
686 | /* | ||
687 | * In CONTIG mode, the current buffer parameters had already | ||
688 | * been entered into the DMA programming register set while the | ||
689 | * buffer was fetched with prepare_next_vb(), they may have also | ||
690 | * been transfered into the runtime set and already active if | ||
691 | * the DMA still running. | ||
692 | */ | ||
693 | } else { | ||
694 | /* In SG mode, extra steps are required */ | ||
695 | if (result == VIDEOBUF_ERROR) | ||
696 | /* make sure we (re)use sglist from start on error */ | ||
697 | buf->sgbuf = NULL; | ||
698 | |||
699 | /* | ||
700 | * In any case, enter the next sgbuf parameters into the DMA | ||
701 | * programming register set. They will be used either during | ||
702 | * nearest DMA autoreinitialization or, in case of an error, | ||
703 | * on DMA startup below. | ||
704 | */ | ||
705 | try_next_sgbuf(pcdev->dma_ch, buf); | ||
706 | } | ||
707 | |||
708 | if (result == VIDEOBUF_ERROR) { | ||
709 | dev_dbg(dev, "%s: videobuf error; reset FIFO, restart DMA\n", | ||
710 | __func__); | ||
711 | start_capture(pcdev); | ||
712 | /* | ||
713 | * In SG mode, the above also resulted in the next sgbuf | ||
714 | * parameters being entered into the DMA programming register | ||
715 | * set, making them ready for next DMA autoreinitialization. | ||
716 | */ | ||
717 | } | ||
718 | |||
719 | /* | ||
720 | * Finally, try fetching next buffer. | ||
721 | * In CONTIG mode, it will also enter it into the DMA programming | ||
722 | * register set, making it ready for next DMA autoreinitialization. | ||
723 | */ | ||
724 | prepare_next_vb(pcdev); | ||
725 | } | ||
726 | |||
727 | static void dma_isr(int channel, unsigned short status, void *data) | ||
728 | { | ||
729 | struct omap1_cam_dev *pcdev = data; | ||
730 | struct omap1_cam_buf *buf = pcdev->active; | ||
731 | unsigned long flags; | ||
732 | |||
733 | spin_lock_irqsave(&pcdev->lock, flags); | ||
734 | |||
735 | if (WARN_ON(!buf)) { | ||
736 | suspend_capture(pcdev); | ||
737 | disable_capture(pcdev); | ||
738 | goto out; | ||
739 | } | ||
740 | |||
741 | if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
742 | /* | ||
743 | * In CONTIG mode, assume we have just managed to collect the | ||
744 | * whole frame, hopefully before our end of frame watchdog is | ||
745 | * triggered. Then, all we have to do is disabling the watchdog | ||
746 | * for this frame, and calling videobuf_done() with success | ||
747 | * indicated. | ||
748 | */ | ||
749 | CAM_WRITE(pcdev, MODE, | ||
750 | CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN); | ||
751 | videobuf_done(pcdev, VIDEOBUF_DONE); | ||
752 | } else { | ||
753 | /* | ||
754 | * In SG mode, we have to process every sgbuf from the current | ||
755 | * sglist, one after another. | ||
756 | */ | ||
757 | if (buf->sgbuf) { | ||
758 | /* | ||
759 | * Current sglist not completed yet, try fetching next | ||
760 | * sgbuf, hopefully putting it into the DMA programming | ||
761 | * register set, making it ready for next DMA | ||
762 | * autoreinitialization. | ||
763 | */ | ||
764 | try_next_sgbuf(pcdev->dma_ch, buf); | ||
765 | if (buf->sgbuf) | ||
766 | goto out; | ||
767 | |||
768 | /* | ||
769 | * No more sgbufs left in the current sglist. This | ||
770 | * doesn't mean that the whole videobuffer is already | ||
771 | * complete, but only that the last sgbuf from the | ||
772 | * current sglist is about to be filled. It will be | ||
773 | * ready on next DMA interrupt, signalled with the | ||
774 | * buf->sgbuf set back to NULL. | ||
775 | */ | ||
776 | if (buf->result != VIDEOBUF_ERROR) { | ||
777 | /* | ||
778 | * Video frame collected without errors so far, | ||
779 | * we can prepare for collecting a next one | ||
780 | * as soon as DMA gets autoreinitialized | ||
781 | * after the current (last) sgbuf is completed. | ||
782 | */ | ||
783 | buf = prepare_next_vb(pcdev); | ||
784 | if (!buf) | ||
785 | goto out; | ||
786 | |||
787 | try_next_sgbuf(pcdev->dma_ch, buf); | ||
788 | goto out; | ||
789 | } | ||
790 | } | ||
791 | /* end of videobuf */ | ||
792 | videobuf_done(pcdev, buf->result); | ||
793 | } | ||
794 | |||
795 | out: | ||
796 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
797 | } | ||
798 | |||
799 | static irqreturn_t cam_isr(int irq, void *data) | ||
800 | { | ||
801 | struct omap1_cam_dev *pcdev = data; | ||
802 | struct device *dev = pcdev->icd->dev.parent; | ||
803 | struct omap1_cam_buf *buf = pcdev->active; | ||
804 | u32 it_status; | ||
805 | unsigned long flags; | ||
806 | |||
807 | it_status = CAM_READ(pcdev, IT_STATUS); | ||
808 | if (!it_status) | ||
809 | return IRQ_NONE; | ||
810 | |||
811 | spin_lock_irqsave(&pcdev->lock, flags); | ||
812 | |||
813 | if (WARN_ON(!buf)) { | ||
814 | dev_warn(dev, "%s: unhandled camera interrupt, status == " | ||
815 | "%#x\n", __func__, it_status); | ||
816 | suspend_capture(pcdev); | ||
817 | disable_capture(pcdev); | ||
818 | goto out; | ||
819 | } | ||
820 | |||
821 | if (unlikely(it_status & FIFO_FULL)) { | ||
822 | dev_warn(dev, "%s: FIFO overflow\n", __func__); | ||
823 | |||
824 | } else if (it_status & V_DOWN) { | ||
825 | /* end of video frame watchdog */ | ||
826 | if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
827 | /* | ||
828 | * In CONTIG mode, the watchdog is disabled with | ||
829 | * successful DMA end of block interrupt, and reenabled | ||
830 | * on next frame start. If we get here, there is nothing | ||
831 | * to check, we must be out of sync. | ||
832 | */ | ||
833 | } else { | ||
834 | if (buf->sgcount == 2) { | ||
835 | /* | ||
836 | * If exactly 2 sgbufs from the next sglist have | ||
837 | * been programmed into the DMA engine (the | ||
838 | * frist one already transfered into the DMA | ||
839 | * runtime register set, the second one still | ||
840 | * in the programming set), then we are in sync. | ||
841 | */ | ||
842 | goto out; | ||
843 | } | ||
844 | } | ||
845 | dev_notice(dev, "%s: unexpected end of video frame\n", | ||
846 | __func__); | ||
847 | |||
848 | } else if (it_status & V_UP) { | ||
849 | u32 mode; | ||
850 | |||
851 | if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) { | ||
852 | /* | ||
853 | * In CONTIG mode, we need this interrupt every frame | ||
854 | * in oredr to reenable our end of frame watchdog. | ||
855 | */ | ||
856 | mode = CAM_READ_CACHE(pcdev, MODE); | ||
857 | } else { | ||
858 | /* | ||
859 | * In SG mode, the below enabled end of frame watchdog | ||
860 | * is kept on permanently, so we can turn this one shot | ||
861 | * setup off. | ||
862 | */ | ||
863 | mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_UP; | ||
864 | } | ||
865 | |||
866 | if (!(mode & EN_V_DOWN)) { | ||
867 | /* (re)enable end of frame watchdog interrupt */ | ||
868 | mode |= EN_V_DOWN; | ||
869 | } | ||
870 | CAM_WRITE(pcdev, MODE, mode); | ||
871 | goto out; | ||
872 | |||
873 | } else { | ||
874 | dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n", | ||
875 | __func__, it_status); | ||
876 | goto out; | ||
877 | } | ||
878 | |||
879 | videobuf_done(pcdev, VIDEOBUF_ERROR); | ||
880 | out: | ||
881 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
882 | return IRQ_HANDLED; | ||
883 | } | ||
884 | |||
885 | static struct videobuf_queue_ops omap1_videobuf_ops = { | ||
886 | .buf_setup = omap1_videobuf_setup, | ||
887 | .buf_prepare = omap1_videobuf_prepare, | ||
888 | .buf_queue = omap1_videobuf_queue, | ||
889 | .buf_release = omap1_videobuf_release, | ||
890 | }; | ||
891 | |||
892 | |||
893 | /* | ||
894 | * SOC Camera host operations | ||
895 | */ | ||
896 | |||
897 | static void sensor_reset(struct omap1_cam_dev *pcdev, bool reset) | ||
898 | { | ||
899 | /* apply/release camera sensor reset if requested by platform data */ | ||
900 | if (pcdev->pflags & OMAP1_CAMERA_RST_HIGH) | ||
901 | CAM_WRITE(pcdev, GPIO, reset); | ||
902 | else if (pcdev->pflags & OMAP1_CAMERA_RST_LOW) | ||
903 | CAM_WRITE(pcdev, GPIO, !reset); | ||
904 | } | ||
905 | |||
906 | /* | ||
907 | * The following two functions absolutely depend on the fact, that | ||
908 | * there can be only one camera on OMAP1 camera sensor interface | ||
909 | */ | ||
910 | static int omap1_cam_add_device(struct soc_camera_device *icd) | ||
911 | { | ||
912 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
913 | struct omap1_cam_dev *pcdev = ici->priv; | ||
914 | u32 ctrlclock; | ||
915 | |||
916 | if (pcdev->icd) | ||
917 | return -EBUSY; | ||
918 | |||
919 | clk_enable(pcdev->clk); | ||
920 | |||
921 | /* setup sensor clock */ | ||
922 | ctrlclock = CAM_READ(pcdev, CTRLCLOCK); | ||
923 | ctrlclock &= ~(CAMEXCLK_EN | MCLK_EN | DPLL_EN); | ||
924 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock); | ||
925 | |||
926 | ctrlclock &= ~FOSCMOD_MASK; | ||
927 | switch (pcdev->camexclk) { | ||
928 | case 6000000: | ||
929 | ctrlclock |= CAMEXCLK_EN | FOSCMOD_6MHz; | ||
930 | break; | ||
931 | case 8000000: | ||
932 | ctrlclock |= CAMEXCLK_EN | FOSCMOD_8MHz | DPLL_EN; | ||
933 | break; | ||
934 | case 9600000: | ||
935 | ctrlclock |= CAMEXCLK_EN | FOSCMOD_9_6MHz | DPLL_EN; | ||
936 | break; | ||
937 | case 12000000: | ||
938 | ctrlclock |= CAMEXCLK_EN | FOSCMOD_12MHz; | ||
939 | break; | ||
940 | case 24000000: | ||
941 | ctrlclock |= CAMEXCLK_EN | FOSCMOD_24MHz | DPLL_EN; | ||
942 | default: | ||
943 | break; | ||
944 | } | ||
945 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~DPLL_EN); | ||
946 | |||
947 | /* enable internal clock */ | ||
948 | ctrlclock |= MCLK_EN; | ||
949 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock); | ||
950 | |||
951 | sensor_reset(pcdev, false); | ||
952 | |||
953 | pcdev->icd = icd; | ||
954 | |||
955 | dev_dbg(icd->dev.parent, "OMAP1 Camera driver attached to camera %d\n", | ||
956 | icd->devnum); | ||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static void omap1_cam_remove_device(struct soc_camera_device *icd) | ||
961 | { | ||
962 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
963 | struct omap1_cam_dev *pcdev = ici->priv; | ||
964 | u32 ctrlclock; | ||
965 | |||
966 | BUG_ON(icd != pcdev->icd); | ||
967 | |||
968 | suspend_capture(pcdev); | ||
969 | disable_capture(pcdev); | ||
970 | |||
971 | sensor_reset(pcdev, true); | ||
972 | |||
973 | /* disable and release system clocks */ | ||
974 | ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); | ||
975 | ctrlclock &= ~(MCLK_EN | DPLL_EN | CAMEXCLK_EN); | ||
976 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock); | ||
977 | |||
978 | ctrlclock = (ctrlclock & ~FOSCMOD_MASK) | FOSCMOD_12MHz; | ||
979 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock); | ||
980 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | MCLK_EN); | ||
981 | |||
982 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN); | ||
983 | |||
984 | clk_disable(pcdev->clk); | ||
985 | |||
986 | pcdev->icd = NULL; | ||
987 | |||
988 | dev_dbg(icd->dev.parent, | ||
989 | "OMAP1 Camera driver detached from camera %d\n", icd->devnum); | ||
990 | } | ||
991 | |||
992 | /* Duplicate standard formats based on host capability of byte swapping */ | ||
993 | static const struct soc_mbus_pixelfmt omap1_cam_formats[] = { | ||
994 | [V4L2_MBUS_FMT_UYVY8_2X8] = { | ||
995 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
996 | .name = "YUYV", | ||
997 | .bits_per_sample = 8, | ||
998 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
999 | .order = SOC_MBUS_ORDER_BE, | ||
1000 | }, | ||
1001 | [V4L2_MBUS_FMT_VYUY8_2X8] = { | ||
1002 | .fourcc = V4L2_PIX_FMT_YVYU, | ||
1003 | .name = "YVYU", | ||
1004 | .bits_per_sample = 8, | ||
1005 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1006 | .order = SOC_MBUS_ORDER_BE, | ||
1007 | }, | ||
1008 | [V4L2_MBUS_FMT_YUYV8_2X8] = { | ||
1009 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
1010 | .name = "UYVY", | ||
1011 | .bits_per_sample = 8, | ||
1012 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1013 | .order = SOC_MBUS_ORDER_BE, | ||
1014 | }, | ||
1015 | [V4L2_MBUS_FMT_YVYU8_2X8] = { | ||
1016 | .fourcc = V4L2_PIX_FMT_VYUY, | ||
1017 | .name = "VYUY", | ||
1018 | .bits_per_sample = 8, | ||
1019 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1020 | .order = SOC_MBUS_ORDER_BE, | ||
1021 | }, | ||
1022 | [V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE] = { | ||
1023 | .fourcc = V4L2_PIX_FMT_RGB555, | ||
1024 | .name = "RGB555", | ||
1025 | .bits_per_sample = 8, | ||
1026 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1027 | .order = SOC_MBUS_ORDER_BE, | ||
1028 | }, | ||
1029 | [V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE] = { | ||
1030 | .fourcc = V4L2_PIX_FMT_RGB555X, | ||
1031 | .name = "RGB555X", | ||
1032 | .bits_per_sample = 8, | ||
1033 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1034 | .order = SOC_MBUS_ORDER_BE, | ||
1035 | }, | ||
1036 | [V4L2_MBUS_FMT_RGB565_2X8_BE] = { | ||
1037 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
1038 | .name = "RGB565", | ||
1039 | .bits_per_sample = 8, | ||
1040 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1041 | .order = SOC_MBUS_ORDER_BE, | ||
1042 | }, | ||
1043 | [V4L2_MBUS_FMT_RGB565_2X8_LE] = { | ||
1044 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
1045 | .name = "RGB565X", | ||
1046 | .bits_per_sample = 8, | ||
1047 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
1048 | .order = SOC_MBUS_ORDER_BE, | ||
1049 | }, | ||
1050 | }; | ||
1051 | |||
1052 | static int omap1_cam_get_formats(struct soc_camera_device *icd, | ||
1053 | unsigned int idx, struct soc_camera_format_xlate *xlate) | ||
1054 | { | ||
1055 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1056 | struct device *dev = icd->dev.parent; | ||
1057 | int formats = 0, ret; | ||
1058 | enum v4l2_mbus_pixelcode code; | ||
1059 | const struct soc_mbus_pixelfmt *fmt; | ||
1060 | |||
1061 | ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); | ||
1062 | if (ret < 0) | ||
1063 | /* No more formats */ | ||
1064 | return 0; | ||
1065 | |||
1066 | fmt = soc_mbus_get_fmtdesc(code); | ||
1067 | if (!fmt) { | ||
1068 | dev_err(dev, "%s: invalid format code #%d: %d\n", __func__, | ||
1069 | idx, code); | ||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
1073 | /* Check support for the requested bits-per-sample */ | ||
1074 | if (fmt->bits_per_sample != 8) | ||
1075 | return 0; | ||
1076 | |||
1077 | switch (code) { | ||
1078 | case V4L2_MBUS_FMT_YUYV8_2X8: | ||
1079 | case V4L2_MBUS_FMT_YVYU8_2X8: | ||
1080 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
1081 | case V4L2_MBUS_FMT_VYUY8_2X8: | ||
1082 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: | ||
1083 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: | ||
1084 | case V4L2_MBUS_FMT_RGB565_2X8_BE: | ||
1085 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
1086 | formats++; | ||
1087 | if (xlate) { | ||
1088 | xlate->host_fmt = &omap1_cam_formats[code]; | ||
1089 | xlate->code = code; | ||
1090 | xlate++; | ||
1091 | dev_dbg(dev, "%s: providing format %s " | ||
1092 | "as byte swapped code #%d\n", __func__, | ||
1093 | omap1_cam_formats[code].name, code); | ||
1094 | } | ||
1095 | default: | ||
1096 | if (xlate) | ||
1097 | dev_dbg(dev, "%s: providing format %s " | ||
1098 | "in pass-through mode\n", __func__, | ||
1099 | fmt->name); | ||
1100 | } | ||
1101 | formats++; | ||
1102 | if (xlate) { | ||
1103 | xlate->host_fmt = fmt; | ||
1104 | xlate->code = code; | ||
1105 | xlate++; | ||
1106 | } | ||
1107 | |||
1108 | return formats; | ||
1109 | } | ||
1110 | |||
1111 | static bool is_dma_aligned(s32 bytes_per_line, unsigned int height, | ||
1112 | enum omap1_cam_vb_mode vb_mode) | ||
1113 | { | ||
1114 | int size = bytes_per_line * height; | ||
1115 | |||
1116 | return IS_ALIGNED(bytes_per_line, DMA_ELEMENT_SIZE) && | ||
1117 | IS_ALIGNED(size, DMA_FRAME_SIZE(vb_mode) * DMA_ELEMENT_SIZE); | ||
1118 | } | ||
1119 | |||
1120 | static int dma_align(int *width, int *height, | ||
1121 | const struct soc_mbus_pixelfmt *fmt, | ||
1122 | enum omap1_cam_vb_mode vb_mode, bool enlarge) | ||
1123 | { | ||
1124 | s32 bytes_per_line = soc_mbus_bytes_per_line(*width, fmt); | ||
1125 | |||
1126 | if (bytes_per_line < 0) | ||
1127 | return bytes_per_line; | ||
1128 | |||
1129 | if (!is_dma_aligned(bytes_per_line, *height, vb_mode)) { | ||
1130 | unsigned int pxalign = __fls(bytes_per_line / *width); | ||
1131 | unsigned int salign = DMA_FRAME_SHIFT(vb_mode) + | ||
1132 | DMA_ELEMENT_SHIFT - pxalign; | ||
1133 | unsigned int incr = enlarge << salign; | ||
1134 | |||
1135 | v4l_bound_align_image(width, 1, *width + incr, 0, | ||
1136 | height, 1, *height + incr, 0, salign); | ||
1137 | return 0; | ||
1138 | } | ||
1139 | return 1; | ||
1140 | } | ||
1141 | |||
1142 | #define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \ | ||
1143 | ({ \ | ||
1144 | struct soc_camera_sense sense = { \ | ||
1145 | .master_clock = pcdev->camexclk, \ | ||
1146 | .pixel_clock_max = 0, \ | ||
1147 | }; \ | ||
1148 | int __ret; \ | ||
1149 | \ | ||
1150 | if (pcdev->pdata) \ | ||
1151 | sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \ | ||
1152 | icd->sense = &sense; \ | ||
1153 | __ret = v4l2_subdev_call(sd, video, function, ##args); \ | ||
1154 | icd->sense = NULL; \ | ||
1155 | \ | ||
1156 | if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \ | ||
1157 | if (sense.pixel_clock > sense.pixel_clock_max) { \ | ||
1158 | dev_err(dev, "%s: pixel clock %lu " \ | ||
1159 | "set by the camera too high!\n", \ | ||
1160 | __func__, sense.pixel_clock); \ | ||
1161 | __ret = -EINVAL; \ | ||
1162 | } \ | ||
1163 | } \ | ||
1164 | __ret; \ | ||
1165 | }) | ||
1166 | |||
1167 | static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, | ||
1168 | struct soc_camera_device *icd, struct v4l2_subdev *sd, | ||
1169 | struct v4l2_mbus_framefmt *mf, | ||
1170 | const struct soc_camera_format_xlate *xlate) | ||
1171 | { | ||
1172 | s32 bytes_per_line; | ||
1173 | int ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_mbus_fmt, mf); | ||
1174 | |||
1175 | if (ret < 0) { | ||
1176 | dev_err(dev, "%s: s_mbus_fmt failed\n", __func__); | ||
1177 | return ret; | ||
1178 | } | ||
1179 | |||
1180 | if (mf->code != xlate->code) { | ||
1181 | dev_err(dev, "%s: unexpected pixel code change\n", __func__); | ||
1182 | return -EINVAL; | ||
1183 | } | ||
1184 | |||
1185 | bytes_per_line = soc_mbus_bytes_per_line(mf->width, xlate->host_fmt); | ||
1186 | if (bytes_per_line < 0) { | ||
1187 | dev_err(dev, "%s: soc_mbus_bytes_per_line() failed\n", | ||
1188 | __func__); | ||
1189 | return bytes_per_line; | ||
1190 | } | ||
1191 | |||
1192 | if (!is_dma_aligned(bytes_per_line, mf->height, pcdev->vb_mode)) { | ||
1193 | dev_err(dev, "%s: resulting geometry %ux%u not DMA aligned\n", | ||
1194 | __func__, mf->width, mf->height); | ||
1195 | return -EINVAL; | ||
1196 | } | ||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static int omap1_cam_set_crop(struct soc_camera_device *icd, | ||
1201 | struct v4l2_crop *crop) | ||
1202 | { | ||
1203 | struct v4l2_rect *rect = &crop->c; | ||
1204 | const struct soc_camera_format_xlate *xlate = icd->current_fmt; | ||
1205 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1206 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
1207 | struct omap1_cam_dev *pcdev = ici->priv; | ||
1208 | struct device *dev = icd->dev.parent; | ||
1209 | struct v4l2_mbus_framefmt mf; | ||
1210 | int ret; | ||
1211 | |||
1212 | ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_crop, crop); | ||
1213 | if (ret < 0) { | ||
1214 | dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__, | ||
1215 | rect->width, rect->height, rect->left, rect->top); | ||
1216 | return ret; | ||
1217 | } | ||
1218 | |||
1219 | ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); | ||
1220 | if (ret < 0) { | ||
1221 | dev_warn(dev, "%s: failed to fetch current format\n", __func__); | ||
1222 | return ret; | ||
1223 | } | ||
1224 | |||
1225 | ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode, | ||
1226 | false); | ||
1227 | if (ret < 0) { | ||
1228 | dev_err(dev, "%s: failed to align %ux%u %s with DMA\n", | ||
1229 | __func__, mf.width, mf.height, | ||
1230 | xlate->host_fmt->name); | ||
1231 | return ret; | ||
1232 | } | ||
1233 | |||
1234 | if (!ret) { | ||
1235 | /* sensor returned geometry not DMA aligned, trying to fix */ | ||
1236 | ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate); | ||
1237 | if (ret < 0) { | ||
1238 | dev_err(dev, "%s: failed to set format\n", __func__); | ||
1239 | return ret; | ||
1240 | } | ||
1241 | } | ||
1242 | |||
1243 | icd->user_width = mf.width; | ||
1244 | icd->user_height = mf.height; | ||
1245 | |||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | static int omap1_cam_set_fmt(struct soc_camera_device *icd, | ||
1250 | struct v4l2_format *f) | ||
1251 | { | ||
1252 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1253 | const struct soc_camera_format_xlate *xlate; | ||
1254 | struct device *dev = icd->dev.parent; | ||
1255 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
1256 | struct omap1_cam_dev *pcdev = ici->priv; | ||
1257 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
1258 | struct v4l2_mbus_framefmt mf; | ||
1259 | int ret; | ||
1260 | |||
1261 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | ||
1262 | if (!xlate) { | ||
1263 | dev_warn(dev, "%s: format %#x not found\n", __func__, | ||
1264 | pix->pixelformat); | ||
1265 | return -EINVAL; | ||
1266 | } | ||
1267 | |||
1268 | mf.width = pix->width; | ||
1269 | mf.height = pix->height; | ||
1270 | mf.field = pix->field; | ||
1271 | mf.colorspace = pix->colorspace; | ||
1272 | mf.code = xlate->code; | ||
1273 | |||
1274 | ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode, | ||
1275 | true); | ||
1276 | if (ret < 0) { | ||
1277 | dev_err(dev, "%s: failed to align %ux%u %s with DMA\n", | ||
1278 | __func__, pix->width, pix->height, | ||
1279 | xlate->host_fmt->name); | ||
1280 | return ret; | ||
1281 | } | ||
1282 | |||
1283 | ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate); | ||
1284 | if (ret < 0) { | ||
1285 | dev_err(dev, "%s: failed to set format\n", __func__); | ||
1286 | return ret; | ||
1287 | } | ||
1288 | |||
1289 | pix->width = mf.width; | ||
1290 | pix->height = mf.height; | ||
1291 | pix->field = mf.field; | ||
1292 | pix->colorspace = mf.colorspace; | ||
1293 | icd->current_fmt = xlate; | ||
1294 | |||
1295 | return 0; | ||
1296 | } | ||
1297 | |||
1298 | static int omap1_cam_try_fmt(struct soc_camera_device *icd, | ||
1299 | struct v4l2_format *f) | ||
1300 | { | ||
1301 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1302 | const struct soc_camera_format_xlate *xlate; | ||
1303 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
1304 | struct v4l2_mbus_framefmt mf; | ||
1305 | int ret; | ||
1306 | /* TODO: limit to mx1 hardware capabilities */ | ||
1307 | |||
1308 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | ||
1309 | if (!xlate) { | ||
1310 | dev_warn(icd->dev.parent, "Format %#x not found\n", | ||
1311 | pix->pixelformat); | ||
1312 | return -EINVAL; | ||
1313 | } | ||
1314 | |||
1315 | mf.width = pix->width; | ||
1316 | mf.height = pix->height; | ||
1317 | mf.field = pix->field; | ||
1318 | mf.colorspace = pix->colorspace; | ||
1319 | mf.code = xlate->code; | ||
1320 | |||
1321 | /* limit to sensor capabilities */ | ||
1322 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); | ||
1323 | if (ret < 0) | ||
1324 | return ret; | ||
1325 | |||
1326 | pix->width = mf.width; | ||
1327 | pix->height = mf.height; | ||
1328 | pix->field = mf.field; | ||
1329 | pix->colorspace = mf.colorspace; | ||
1330 | |||
1331 | return 0; | ||
1332 | } | ||
1333 | |||
1334 | static bool sg_mode; | ||
1335 | |||
1336 | /* | ||
1337 | * Local mmap_mapper wrapper, | ||
1338 | * used for detecting videobuf-dma-contig buffer allocation failures | ||
1339 | * and switching to videobuf-dma-sg automatically for future attempts. | ||
1340 | */ | ||
1341 | static int omap1_cam_mmap_mapper(struct videobuf_queue *q, | ||
1342 | struct videobuf_buffer *buf, | ||
1343 | struct vm_area_struct *vma) | ||
1344 | { | ||
1345 | struct soc_camera_device *icd = q->priv_data; | ||
1346 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
1347 | struct omap1_cam_dev *pcdev = ici->priv; | ||
1348 | int ret; | ||
1349 | |||
1350 | ret = pcdev->mmap_mapper(q, buf, vma); | ||
1351 | |||
1352 | if (ret == -ENOMEM) | ||
1353 | sg_mode = true; | ||
1354 | |||
1355 | return ret; | ||
1356 | } | ||
1357 | |||
1358 | static void omap1_cam_init_videobuf(struct videobuf_queue *q, | ||
1359 | struct soc_camera_device *icd) | ||
1360 | { | ||
1361 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
1362 | struct omap1_cam_dev *pcdev = ici->priv; | ||
1363 | |||
1364 | if (!sg_mode) | ||
1365 | videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, | ||
1366 | icd->dev.parent, &pcdev->lock, | ||
1367 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | ||
1368 | sizeof(struct omap1_cam_buf), icd); | ||
1369 | else | ||
1370 | videobuf_queue_sg_init(q, &omap1_videobuf_ops, | ||
1371 | icd->dev.parent, &pcdev->lock, | ||
1372 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | ||
1373 | sizeof(struct omap1_cam_buf), icd); | ||
1374 | |||
1375 | /* use videobuf mode (auto)selected with the module parameter */ | ||
1376 | pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; | ||
1377 | |||
1378 | /* | ||
1379 | * Ensure we substitute the videobuf-dma-contig version of the | ||
1380 | * mmap_mapper() callback with our own wrapper, used for switching | ||
1381 | * automatically to videobuf-dma-sg on buffer allocation failure. | ||
1382 | */ | ||
1383 | if (!sg_mode && q->int_ops->mmap_mapper != omap1_cam_mmap_mapper) { | ||
1384 | pcdev->mmap_mapper = q->int_ops->mmap_mapper; | ||
1385 | q->int_ops->mmap_mapper = omap1_cam_mmap_mapper; | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | static int omap1_cam_reqbufs(struct soc_camera_file *icf, | ||
1390 | struct v4l2_requestbuffers *p) | ||
1391 | { | ||
1392 | int i; | ||
1393 | |||
1394 | /* | ||
1395 | * This is for locking debugging only. I removed spinlocks and now I | ||
1396 | * check whether .prepare is ever called on a linked buffer, or whether | ||
1397 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now | ||
1398 | * it hadn't triggered | ||
1399 | */ | ||
1400 | for (i = 0; i < p->count; i++) { | ||
1401 | struct omap1_cam_buf *buf = container_of(icf->vb_vidq.bufs[i], | ||
1402 | struct omap1_cam_buf, vb); | ||
1403 | buf->inwork = 0; | ||
1404 | INIT_LIST_HEAD(&buf->vb.queue); | ||
1405 | } | ||
1406 | |||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | static int omap1_cam_querycap(struct soc_camera_host *ici, | ||
1411 | struct v4l2_capability *cap) | ||
1412 | { | ||
1413 | /* cap->name is set by the friendly caller:-> */ | ||
1414 | strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); | ||
1415 | cap->version = VERSION_CODE; | ||
1416 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | ||
1417 | |||
1418 | return 0; | ||
1419 | } | ||
1420 | |||
1421 | static int omap1_cam_set_bus_param(struct soc_camera_device *icd, | ||
1422 | __u32 pixfmt) | ||
1423 | { | ||
1424 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
1425 | struct omap1_cam_dev *pcdev = ici->priv; | ||
1426 | struct device *dev = icd->dev.parent; | ||
1427 | const struct soc_camera_format_xlate *xlate; | ||
1428 | const struct soc_mbus_pixelfmt *fmt; | ||
1429 | unsigned long camera_flags, common_flags; | ||
1430 | u32 ctrlclock, mode; | ||
1431 | int ret; | ||
1432 | |||
1433 | camera_flags = icd->ops->query_bus_param(icd); | ||
1434 | |||
1435 | common_flags = soc_camera_bus_param_compatible(camera_flags, | ||
1436 | SOCAM_BUS_FLAGS); | ||
1437 | if (!common_flags) | ||
1438 | return -EINVAL; | ||
1439 | |||
1440 | /* Make choices, possibly based on platform configuration */ | ||
1441 | if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && | ||
1442 | (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { | ||
1443 | if (!pcdev->pdata || | ||
1444 | pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING) | ||
1445 | common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; | ||
1446 | else | ||
1447 | common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; | ||
1448 | } | ||
1449 | |||
1450 | ret = icd->ops->set_bus_param(icd, common_flags); | ||
1451 | if (ret < 0) | ||
1452 | return ret; | ||
1453 | |||
1454 | ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); | ||
1455 | if (ctrlclock & LCLK_EN) | ||
1456 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); | ||
1457 | |||
1458 | if (common_flags & SOCAM_PCLK_SAMPLE_RISING) { | ||
1459 | dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n"); | ||
1460 | ctrlclock |= POLCLK; | ||
1461 | } else { | ||
1462 | dev_dbg(dev, "CTRLCLOCK_REG &= ~POLCLK\n"); | ||
1463 | ctrlclock &= ~POLCLK; | ||
1464 | } | ||
1465 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); | ||
1466 | |||
1467 | if (ctrlclock & LCLK_EN) | ||
1468 | CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock); | ||
1469 | |||
1470 | /* select bus endianess */ | ||
1471 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | ||
1472 | fmt = xlate->host_fmt; | ||
1473 | |||
1474 | mode = CAM_READ(pcdev, MODE) & ~(RAZ_FIFO | IRQ_MASK | DMA); | ||
1475 | if (fmt->order == SOC_MBUS_ORDER_LE) { | ||
1476 | dev_dbg(dev, "MODE_REG &= ~ORDERCAMD\n"); | ||
1477 | CAM_WRITE(pcdev, MODE, mode & ~ORDERCAMD); | ||
1478 | } else { | ||
1479 | dev_dbg(dev, "MODE_REG |= ORDERCAMD\n"); | ||
1480 | CAM_WRITE(pcdev, MODE, mode | ORDERCAMD); | ||
1481 | } | ||
1482 | |||
1483 | return 0; | ||
1484 | } | ||
1485 | |||
1486 | static unsigned int omap1_cam_poll(struct file *file, poll_table *pt) | ||
1487 | { | ||
1488 | struct soc_camera_file *icf = file->private_data; | ||
1489 | struct omap1_cam_buf *buf; | ||
1490 | |||
1491 | buf = list_entry(icf->vb_vidq.stream.next, struct omap1_cam_buf, | ||
1492 | vb.stream); | ||
1493 | |||
1494 | poll_wait(file, &buf->vb.done, pt); | ||
1495 | |||
1496 | if (buf->vb.state == VIDEOBUF_DONE || | ||
1497 | buf->vb.state == VIDEOBUF_ERROR) | ||
1498 | return POLLIN | POLLRDNORM; | ||
1499 | |||
1500 | return 0; | ||
1501 | } | ||
1502 | |||
1503 | static struct soc_camera_host_ops omap1_host_ops = { | ||
1504 | .owner = THIS_MODULE, | ||
1505 | .add = omap1_cam_add_device, | ||
1506 | .remove = omap1_cam_remove_device, | ||
1507 | .get_formats = omap1_cam_get_formats, | ||
1508 | .set_crop = omap1_cam_set_crop, | ||
1509 | .set_fmt = omap1_cam_set_fmt, | ||
1510 | .try_fmt = omap1_cam_try_fmt, | ||
1511 | .init_videobuf = omap1_cam_init_videobuf, | ||
1512 | .reqbufs = omap1_cam_reqbufs, | ||
1513 | .querycap = omap1_cam_querycap, | ||
1514 | .set_bus_param = omap1_cam_set_bus_param, | ||
1515 | .poll = omap1_cam_poll, | ||
1516 | }; | ||
1517 | |||
1518 | static int __init omap1_cam_probe(struct platform_device *pdev) | ||
1519 | { | ||
1520 | struct omap1_cam_dev *pcdev; | ||
1521 | struct resource *res; | ||
1522 | struct clk *clk; | ||
1523 | void __iomem *base; | ||
1524 | unsigned int irq; | ||
1525 | int err = 0; | ||
1526 | |||
1527 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1528 | irq = platform_get_irq(pdev, 0); | ||
1529 | if (!res || (int)irq <= 0) { | ||
1530 | err = -ENODEV; | ||
1531 | goto exit; | ||
1532 | } | ||
1533 | |||
1534 | clk = clk_get(&pdev->dev, "armper_ck"); | ||
1535 | if (IS_ERR(clk)) { | ||
1536 | err = PTR_ERR(clk); | ||
1537 | goto exit; | ||
1538 | } | ||
1539 | |||
1540 | pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL); | ||
1541 | if (!pcdev) { | ||
1542 | dev_err(&pdev->dev, "Could not allocate pcdev\n"); | ||
1543 | err = -ENOMEM; | ||
1544 | goto exit_put_clk; | ||
1545 | } | ||
1546 | |||
1547 | pcdev->res = res; | ||
1548 | pcdev->clk = clk; | ||
1549 | |||
1550 | pcdev->pdata = pdev->dev.platform_data; | ||
1551 | pcdev->pflags = pcdev->pdata->flags; | ||
1552 | |||
1553 | if (pcdev->pdata) | ||
1554 | pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000; | ||
1555 | |||
1556 | switch (pcdev->camexclk) { | ||
1557 | case 6000000: | ||
1558 | case 8000000: | ||
1559 | case 9600000: | ||
1560 | case 12000000: | ||
1561 | case 24000000: | ||
1562 | break; | ||
1563 | default: | ||
1564 | dev_warn(&pdev->dev, | ||
1565 | "Incorrect sensor clock frequency %ld kHz, " | ||
1566 | "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, " | ||
1567 | "please correct your platform data\n", | ||
1568 | pcdev->pdata->camexclk_khz); | ||
1569 | pcdev->camexclk = 0; | ||
1570 | case 0: | ||
1571 | dev_info(&pdev->dev, | ||
1572 | "Not providing sensor clock\n"); | ||
1573 | } | ||
1574 | |||
1575 | INIT_LIST_HEAD(&pcdev->capture); | ||
1576 | spin_lock_init(&pcdev->lock); | ||
1577 | |||
1578 | /* | ||
1579 | * Request the region. | ||
1580 | */ | ||
1581 | if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) { | ||
1582 | err = -EBUSY; | ||
1583 | goto exit_kfree; | ||
1584 | } | ||
1585 | |||
1586 | base = ioremap(res->start, resource_size(res)); | ||
1587 | if (!base) { | ||
1588 | err = -ENOMEM; | ||
1589 | goto exit_release; | ||
1590 | } | ||
1591 | pcdev->irq = irq; | ||
1592 | pcdev->base = base; | ||
1593 | |||
1594 | sensor_reset(pcdev, true); | ||
1595 | |||
1596 | err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME, | ||
1597 | dma_isr, (void *)pcdev, &pcdev->dma_ch); | ||
1598 | if (err < 0) { | ||
1599 | dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n"); | ||
1600 | err = -EBUSY; | ||
1601 | goto exit_iounmap; | ||
1602 | } | ||
1603 | dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch); | ||
1604 | |||
1605 | /* preconfigure DMA */ | ||
1606 | omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB, | ||
1607 | OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA, | ||
1608 | 0, 0); | ||
1609 | omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4); | ||
1610 | /* setup DMA autoinitialization */ | ||
1611 | omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch); | ||
1612 | |||
1613 | err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev); | ||
1614 | if (err) { | ||
1615 | dev_err(&pdev->dev, "Camera interrupt register failed\n"); | ||
1616 | goto exit_free_dma; | ||
1617 | } | ||
1618 | |||
1619 | pcdev->soc_host.drv_name = DRIVER_NAME; | ||
1620 | pcdev->soc_host.ops = &omap1_host_ops; | ||
1621 | pcdev->soc_host.priv = pcdev; | ||
1622 | pcdev->soc_host.v4l2_dev.dev = &pdev->dev; | ||
1623 | pcdev->soc_host.nr = pdev->id; | ||
1624 | |||
1625 | err = soc_camera_host_register(&pcdev->soc_host); | ||
1626 | if (err) | ||
1627 | goto exit_free_irq; | ||
1628 | |||
1629 | dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n"); | ||
1630 | |||
1631 | return 0; | ||
1632 | |||
1633 | exit_free_irq: | ||
1634 | free_irq(pcdev->irq, pcdev); | ||
1635 | exit_free_dma: | ||
1636 | omap_free_dma(pcdev->dma_ch); | ||
1637 | exit_iounmap: | ||
1638 | iounmap(base); | ||
1639 | exit_release: | ||
1640 | release_mem_region(res->start, resource_size(res)); | ||
1641 | exit_kfree: | ||
1642 | kfree(pcdev); | ||
1643 | exit_put_clk: | ||
1644 | clk_put(clk); | ||
1645 | exit: | ||
1646 | return err; | ||
1647 | } | ||
1648 | |||
1649 | static int __exit omap1_cam_remove(struct platform_device *pdev) | ||
1650 | { | ||
1651 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); | ||
1652 | struct omap1_cam_dev *pcdev = container_of(soc_host, | ||
1653 | struct omap1_cam_dev, soc_host); | ||
1654 | struct resource *res; | ||
1655 | |||
1656 | free_irq(pcdev->irq, pcdev); | ||
1657 | |||
1658 | omap_free_dma(pcdev->dma_ch); | ||
1659 | |||
1660 | soc_camera_host_unregister(soc_host); | ||
1661 | |||
1662 | iounmap(pcdev->base); | ||
1663 | |||
1664 | res = pcdev->res; | ||
1665 | release_mem_region(res->start, resource_size(res)); | ||
1666 | |||
1667 | kfree(pcdev); | ||
1668 | |||
1669 | clk_put(pcdev->clk); | ||
1670 | |||
1671 | dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n"); | ||
1672 | |||
1673 | return 0; | ||
1674 | } | ||
1675 | |||
1676 | static struct platform_driver omap1_cam_driver = { | ||
1677 | .driver = { | ||
1678 | .name = DRIVER_NAME, | ||
1679 | }, | ||
1680 | .probe = omap1_cam_probe, | ||
1681 | .remove = __exit_p(omap1_cam_remove), | ||
1682 | }; | ||
1683 | |||
1684 | static int __init omap1_cam_init(void) | ||
1685 | { | ||
1686 | return platform_driver_register(&omap1_cam_driver); | ||
1687 | } | ||
1688 | module_init(omap1_cam_init); | ||
1689 | |||
1690 | static void __exit omap1_cam_exit(void) | ||
1691 | { | ||
1692 | platform_driver_unregister(&omap1_cam_driver); | ||
1693 | } | ||
1694 | module_exit(omap1_cam_exit); | ||
1695 | |||
1696 | module_param(sg_mode, bool, 0644); | ||
1697 | MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg"); | ||
1698 | |||
1699 | MODULE_DESCRIPTION("OMAP1 Camera Interface driver"); | ||
1700 | MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>"); | ||
1701 | MODULE_LICENSE("GPL v2"); | ||
1702 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 926a5aa6f7f..378b094aff1 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c | |||
@@ -420,7 +420,7 @@ static void omap24xxcam_vbq_release(struct videobuf_queue *vbq, | |||
420 | struct videobuf_dmabuf *dma = videobuf_to_dma(vb); | 420 | struct videobuf_dmabuf *dma = videobuf_to_dma(vb); |
421 | 421 | ||
422 | /* wait for buffer, especially to get out of the sgdma queue */ | 422 | /* wait for buffer, especially to get out of the sgdma queue */ |
423 | videobuf_waiton(vb, 0, 0); | 423 | videobuf_waiton(vbq, vb, 0, 0); |
424 | if (vb->memory == V4L2_MEMORY_MMAP) { | 424 | if (vb->memory == V4L2_MEMORY_MMAP) { |
425 | dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen, | 425 | dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen, |
426 | dma->direction); | 426 | dma->direction); |
@@ -1491,7 +1491,7 @@ static int omap24xxcam_open(struct file *file) | |||
1491 | videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL, | 1491 | videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL, |
1492 | &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1492 | &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1493 | V4L2_FIELD_NONE, | 1493 | V4L2_FIELD_NONE, |
1494 | sizeof(struct videobuf_buffer), fh); | 1494 | sizeof(struct videobuf_buffer), fh, NULL); |
1495 | 1495 | ||
1496 | return 0; | 1496 | return 0; |
1497 | 1497 | ||
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c new file mode 100644 index 00000000000..b7cfeab0948 --- /dev/null +++ b/drivers/media/video/ov6650.c | |||
@@ -0,0 +1,1225 @@ | |||
1 | /* | ||
2 | * V4L2 SoC Camera driver for OmniVision OV6650 Camera Sensor | ||
3 | * | ||
4 | * Copyright (C) 2010 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> | ||
5 | * | ||
6 | * Based on OmniVision OV96xx Camera Driver | ||
7 | * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com> | ||
8 | * | ||
9 | * Based on ov772x camera driver: | ||
10 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
11 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
12 | * | ||
13 | * Based on ov7670 and soc_camera_platform driver, | ||
14 | * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> | ||
15 | * Copyright (C) 2008 Magnus Damm | ||
16 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
17 | * | ||
18 | * Hardware specific bits initialy based on former work by Matt Callow | ||
19 | * drivers/media/video/omap/sensor_ov6650.c | ||
20 | * Copyright (C) 2006 Matt Callow | ||
21 | * | ||
22 | * This program is free software; you can redistribute it and/or modify | ||
23 | * it under the terms of the GNU General Public License version 2 as | ||
24 | * published by the Free Software Foundation. | ||
25 | */ | ||
26 | |||
27 | #include <linux/bitops.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/slab.h> | ||
31 | |||
32 | #include <media/soc_camera.h> | ||
33 | #include <media/v4l2-chip-ident.h> | ||
34 | |||
35 | |||
36 | /* Register definitions */ | ||
37 | #define REG_GAIN 0x00 /* range 00 - 3F */ | ||
38 | #define REG_BLUE 0x01 | ||
39 | #define REG_RED 0x02 | ||
40 | #define REG_SAT 0x03 /* [7:4] saturation [0:3] reserved */ | ||
41 | #define REG_HUE 0x04 /* [7:6] rsrvd [5] hue en [4:0] hue */ | ||
42 | |||
43 | #define REG_BRT 0x06 | ||
44 | |||
45 | #define REG_PIDH 0x0a | ||
46 | #define REG_PIDL 0x0b | ||
47 | |||
48 | #define REG_AECH 0x10 | ||
49 | #define REG_CLKRC 0x11 /* Data Format and Internal Clock */ | ||
50 | /* [7:6] Input system clock (MHz)*/ | ||
51 | /* 00=8, 01=12, 10=16, 11=24 */ | ||
52 | /* [5:0]: Internal Clock Pre-Scaler */ | ||
53 | #define REG_COMA 0x12 /* [7] Reset */ | ||
54 | #define REG_COMB 0x13 | ||
55 | #define REG_COMC 0x14 | ||
56 | #define REG_COMD 0x15 | ||
57 | #define REG_COML 0x16 | ||
58 | #define REG_HSTRT 0x17 | ||
59 | #define REG_HSTOP 0x18 | ||
60 | #define REG_VSTRT 0x19 | ||
61 | #define REG_VSTOP 0x1a | ||
62 | #define REG_PSHFT 0x1b | ||
63 | #define REG_MIDH 0x1c | ||
64 | #define REG_MIDL 0x1d | ||
65 | #define REG_HSYNS 0x1e | ||
66 | #define REG_HSYNE 0x1f | ||
67 | #define REG_COME 0x20 | ||
68 | #define REG_YOFF 0x21 | ||
69 | #define REG_UOFF 0x22 | ||
70 | #define REG_VOFF 0x23 | ||
71 | #define REG_AEW 0x24 | ||
72 | #define REG_AEB 0x25 | ||
73 | #define REG_COMF 0x26 | ||
74 | #define REG_COMG 0x27 | ||
75 | #define REG_COMH 0x28 | ||
76 | #define REG_COMI 0x29 | ||
77 | |||
78 | #define REG_FRARL 0x2b | ||
79 | #define REG_COMJ 0x2c | ||
80 | #define REG_COMK 0x2d | ||
81 | #define REG_AVGY 0x2e | ||
82 | #define REG_REF0 0x2f | ||
83 | #define REG_REF1 0x30 | ||
84 | #define REG_REF2 0x31 | ||
85 | #define REG_FRAJH 0x32 | ||
86 | #define REG_FRAJL 0x33 | ||
87 | #define REG_FACT 0x34 | ||
88 | #define REG_L1AEC 0x35 | ||
89 | #define REG_AVGU 0x36 | ||
90 | #define REG_AVGV 0x37 | ||
91 | |||
92 | #define REG_SPCB 0x60 | ||
93 | #define REG_SPCC 0x61 | ||
94 | #define REG_GAM1 0x62 | ||
95 | #define REG_GAM2 0x63 | ||
96 | #define REG_GAM3 0x64 | ||
97 | #define REG_SPCD 0x65 | ||
98 | |||
99 | #define REG_SPCE 0x68 | ||
100 | #define REG_ADCL 0x69 | ||
101 | |||
102 | #define REG_RMCO 0x6c | ||
103 | #define REG_GMCO 0x6d | ||
104 | #define REG_BMCO 0x6e | ||
105 | |||
106 | |||
107 | /* Register bits, values, etc. */ | ||
108 | #define OV6650_PIDH 0x66 /* high byte of product ID number */ | ||
109 | #define OV6650_PIDL 0x50 /* low byte of product ID number */ | ||
110 | #define OV6650_MIDH 0x7F /* high byte of mfg ID */ | ||
111 | #define OV6650_MIDL 0xA2 /* low byte of mfg ID */ | ||
112 | |||
113 | #define DEF_GAIN 0x00 | ||
114 | #define DEF_BLUE 0x80 | ||
115 | #define DEF_RED 0x80 | ||
116 | |||
117 | #define SAT_SHIFT 4 | ||
118 | #define SAT_MASK (0xf << SAT_SHIFT) | ||
119 | #define SET_SAT(x) (((x) << SAT_SHIFT) & SAT_MASK) | ||
120 | |||
121 | #define HUE_EN BIT(5) | ||
122 | #define HUE_MASK 0x1f | ||
123 | #define DEF_HUE 0x10 | ||
124 | #define SET_HUE(x) (HUE_EN | ((x) & HUE_MASK)) | ||
125 | |||
126 | #define DEF_AECH 0x4D | ||
127 | |||
128 | #define CLKRC_6MHz 0x00 | ||
129 | #define CLKRC_12MHz 0x40 | ||
130 | #define CLKRC_16MHz 0x80 | ||
131 | #define CLKRC_24MHz 0xc0 | ||
132 | #define CLKRC_DIV_MASK 0x3f | ||
133 | #define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1) | ||
134 | |||
135 | #define COMA_RESET BIT(7) | ||
136 | #define COMA_QCIF BIT(5) | ||
137 | #define COMA_RAW_RGB BIT(4) | ||
138 | #define COMA_RGB BIT(3) | ||
139 | #define COMA_BW BIT(2) | ||
140 | #define COMA_WORD_SWAP BIT(1) | ||
141 | #define COMA_BYTE_SWAP BIT(0) | ||
142 | #define DEF_COMA 0x00 | ||
143 | |||
144 | #define COMB_FLIP_V BIT(7) | ||
145 | #define COMB_FLIP_H BIT(5) | ||
146 | #define COMB_BAND_FILTER BIT(4) | ||
147 | #define COMB_AWB BIT(2) | ||
148 | #define COMB_AGC BIT(1) | ||
149 | #define COMB_AEC BIT(0) | ||
150 | #define DEF_COMB 0x5f | ||
151 | |||
152 | #define COML_ONE_CHANNEL BIT(7) | ||
153 | |||
154 | #define DEF_HSTRT 0x24 | ||
155 | #define DEF_HSTOP 0xd4 | ||
156 | #define DEF_VSTRT 0x04 | ||
157 | #define DEF_VSTOP 0x94 | ||
158 | |||
159 | #define COMF_HREF_LOW BIT(4) | ||
160 | |||
161 | #define COMJ_PCLK_RISING BIT(4) | ||
162 | #define COMJ_VSYNC_HIGH BIT(0) | ||
163 | |||
164 | /* supported resolutions */ | ||
165 | #define W_QCIF (DEF_HSTOP - DEF_HSTRT) | ||
166 | #define W_CIF (W_QCIF << 1) | ||
167 | #define H_QCIF (DEF_VSTOP - DEF_VSTRT) | ||
168 | #define H_CIF (H_QCIF << 1) | ||
169 | |||
170 | #define FRAME_RATE_MAX 30 | ||
171 | |||
172 | |||
173 | struct ov6650_reg { | ||
174 | u8 reg; | ||
175 | u8 val; | ||
176 | }; | ||
177 | |||
178 | struct ov6650 { | ||
179 | struct v4l2_subdev subdev; | ||
180 | |||
181 | int gain; | ||
182 | int blue; | ||
183 | int red; | ||
184 | int saturation; | ||
185 | int hue; | ||
186 | int brightness; | ||
187 | int exposure; | ||
188 | int gamma; | ||
189 | int aec; | ||
190 | bool vflip; | ||
191 | bool hflip; | ||
192 | bool awb; | ||
193 | bool agc; | ||
194 | bool half_scale; /* scale down output by 2 */ | ||
195 | struct v4l2_rect rect; /* sensor cropping window */ | ||
196 | unsigned long pclk_limit; /* from host */ | ||
197 | unsigned long pclk_max; /* from resolution and format */ | ||
198 | struct v4l2_fract tpf; /* as requested with s_parm */ | ||
199 | enum v4l2_mbus_pixelcode code; | ||
200 | enum v4l2_colorspace colorspace; | ||
201 | }; | ||
202 | |||
203 | |||
204 | static enum v4l2_mbus_pixelcode ov6650_codes[] = { | ||
205 | V4L2_MBUS_FMT_YUYV8_2X8, | ||
206 | V4L2_MBUS_FMT_UYVY8_2X8, | ||
207 | V4L2_MBUS_FMT_YVYU8_2X8, | ||
208 | V4L2_MBUS_FMT_VYUY8_2X8, | ||
209 | V4L2_MBUS_FMT_SBGGR8_1X8, | ||
210 | V4L2_MBUS_FMT_GREY8_1X8, | ||
211 | }; | ||
212 | |||
213 | static const struct v4l2_queryctrl ov6650_controls[] = { | ||
214 | { | ||
215 | .id = V4L2_CID_AUTOGAIN, | ||
216 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
217 | .name = "AGC", | ||
218 | .minimum = 0, | ||
219 | .maximum = 1, | ||
220 | .step = 1, | ||
221 | .default_value = 1, | ||
222 | }, | ||
223 | { | ||
224 | .id = V4L2_CID_GAIN, | ||
225 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
226 | .name = "Gain", | ||
227 | .minimum = 0, | ||
228 | .maximum = 0x3f, | ||
229 | .step = 1, | ||
230 | .default_value = DEF_GAIN, | ||
231 | }, | ||
232 | { | ||
233 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
234 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
235 | .name = "AWB", | ||
236 | .minimum = 0, | ||
237 | .maximum = 1, | ||
238 | .step = 1, | ||
239 | .default_value = 1, | ||
240 | }, | ||
241 | { | ||
242 | .id = V4L2_CID_BLUE_BALANCE, | ||
243 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
244 | .name = "Blue", | ||
245 | .minimum = 0, | ||
246 | .maximum = 0xff, | ||
247 | .step = 1, | ||
248 | .default_value = DEF_BLUE, | ||
249 | }, | ||
250 | { | ||
251 | .id = V4L2_CID_RED_BALANCE, | ||
252 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
253 | .name = "Red", | ||
254 | .minimum = 0, | ||
255 | .maximum = 0xff, | ||
256 | .step = 1, | ||
257 | .default_value = DEF_RED, | ||
258 | }, | ||
259 | { | ||
260 | .id = V4L2_CID_SATURATION, | ||
261 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
262 | .name = "Saturation", | ||
263 | .minimum = 0, | ||
264 | .maximum = 0xf, | ||
265 | .step = 1, | ||
266 | .default_value = 0x8, | ||
267 | }, | ||
268 | { | ||
269 | .id = V4L2_CID_HUE, | ||
270 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
271 | .name = "Hue", | ||
272 | .minimum = 0, | ||
273 | .maximum = HUE_MASK, | ||
274 | .step = 1, | ||
275 | .default_value = DEF_HUE, | ||
276 | }, | ||
277 | { | ||
278 | .id = V4L2_CID_BRIGHTNESS, | ||
279 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
280 | .name = "Brightness", | ||
281 | .minimum = 0, | ||
282 | .maximum = 0xff, | ||
283 | .step = 1, | ||
284 | .default_value = 0x80, | ||
285 | }, | ||
286 | { | ||
287 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
288 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
289 | .name = "AEC", | ||
290 | .minimum = 0, | ||
291 | .maximum = 3, | ||
292 | .step = 1, | ||
293 | .default_value = 0, | ||
294 | }, | ||
295 | { | ||
296 | .id = V4L2_CID_EXPOSURE, | ||
297 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
298 | .name = "Exposure", | ||
299 | .minimum = 0, | ||
300 | .maximum = 0xff, | ||
301 | .step = 1, | ||
302 | .default_value = DEF_AECH, | ||
303 | }, | ||
304 | { | ||
305 | .id = V4L2_CID_GAMMA, | ||
306 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
307 | .name = "Gamma", | ||
308 | .minimum = 0, | ||
309 | .maximum = 0xff, | ||
310 | .step = 1, | ||
311 | .default_value = 0x12, | ||
312 | }, | ||
313 | { | ||
314 | .id = V4L2_CID_VFLIP, | ||
315 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
316 | .name = "Flip Vertically", | ||
317 | .minimum = 0, | ||
318 | .maximum = 1, | ||
319 | .step = 1, | ||
320 | .default_value = 0, | ||
321 | }, | ||
322 | { | ||
323 | .id = V4L2_CID_HFLIP, | ||
324 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
325 | .name = "Flip Horizontally", | ||
326 | .minimum = 0, | ||
327 | .maximum = 1, | ||
328 | .step = 1, | ||
329 | .default_value = 0, | ||
330 | }, | ||
331 | }; | ||
332 | |||
333 | /* read a register */ | ||
334 | static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) | ||
335 | { | ||
336 | int ret; | ||
337 | u8 data = reg; | ||
338 | struct i2c_msg msg = { | ||
339 | .addr = client->addr, | ||
340 | .flags = 0, | ||
341 | .len = 1, | ||
342 | .buf = &data, | ||
343 | }; | ||
344 | |||
345 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
346 | if (ret < 0) | ||
347 | goto err; | ||
348 | |||
349 | msg.flags = I2C_M_RD; | ||
350 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
351 | if (ret < 0) | ||
352 | goto err; | ||
353 | |||
354 | *val = data; | ||
355 | return 0; | ||
356 | |||
357 | err: | ||
358 | dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg); | ||
359 | return ret; | ||
360 | } | ||
361 | |||
362 | /* write a register */ | ||
363 | static int ov6650_reg_write(struct i2c_client *client, u8 reg, u8 val) | ||
364 | { | ||
365 | int ret; | ||
366 | unsigned char data[2] = { reg, val }; | ||
367 | struct i2c_msg msg = { | ||
368 | .addr = client->addr, | ||
369 | .flags = 0, | ||
370 | .len = 2, | ||
371 | .buf = data, | ||
372 | }; | ||
373 | |||
374 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
375 | udelay(100); | ||
376 | |||
377 | if (ret < 0) { | ||
378 | dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg); | ||
379 | return ret; | ||
380 | } | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | |||
385 | /* Read a register, alter its bits, write it back */ | ||
386 | static int ov6650_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 mask) | ||
387 | { | ||
388 | u8 val; | ||
389 | int ret; | ||
390 | |||
391 | ret = ov6650_reg_read(client, reg, &val); | ||
392 | if (ret) { | ||
393 | dev_err(&client->dev, | ||
394 | "[Read]-Modify-Write of register 0x%02x failed!\n", | ||
395 | reg); | ||
396 | return ret; | ||
397 | } | ||
398 | |||
399 | val &= ~mask; | ||
400 | val |= set; | ||
401 | |||
402 | ret = ov6650_reg_write(client, reg, val); | ||
403 | if (ret) | ||
404 | dev_err(&client->dev, | ||
405 | "Read-Modify-[Write] of register 0x%02x failed!\n", | ||
406 | reg); | ||
407 | |||
408 | return ret; | ||
409 | } | ||
410 | |||
411 | static struct ov6650 *to_ov6650(const struct i2c_client *client) | ||
412 | { | ||
413 | return container_of(i2c_get_clientdata(client), struct ov6650, subdev); | ||
414 | } | ||
415 | |||
416 | /* Start/Stop streaming from the device */ | ||
417 | static int ov6650_s_stream(struct v4l2_subdev *sd, int enable) | ||
418 | { | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | /* Alter bus settings on camera side */ | ||
423 | static int ov6650_set_bus_param(struct soc_camera_device *icd, | ||
424 | unsigned long flags) | ||
425 | { | ||
426 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
427 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
428 | int ret; | ||
429 | |||
430 | flags = soc_camera_apply_sensor_flags(icl, flags); | ||
431 | |||
432 | if (flags & SOCAM_PCLK_SAMPLE_RISING) | ||
433 | ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); | ||
434 | else | ||
435 | ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); | ||
436 | if (ret) | ||
437 | return ret; | ||
438 | |||
439 | if (flags & SOCAM_HSYNC_ACTIVE_LOW) | ||
440 | ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); | ||
441 | else | ||
442 | ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); | ||
443 | if (ret) | ||
444 | return ret; | ||
445 | |||
446 | if (flags & SOCAM_VSYNC_ACTIVE_HIGH) | ||
447 | ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); | ||
448 | else | ||
449 | ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); | ||
450 | |||
451 | return ret; | ||
452 | } | ||
453 | |||
454 | /* Request bus settings on camera side */ | ||
455 | static unsigned long ov6650_query_bus_param(struct soc_camera_device *icd) | ||
456 | { | ||
457 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
458 | |||
459 | unsigned long flags = SOCAM_MASTER | | ||
460 | SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | | ||
461 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW | | ||
462 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | | ||
463 | SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; | ||
464 | |||
465 | return soc_camera_apply_sensor_flags(icl, flags); | ||
466 | } | ||
467 | |||
468 | /* Get status of additional camera capabilities */ | ||
469 | static int ov6650_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
470 | { | ||
471 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
472 | struct ov6650 *priv = to_ov6650(client); | ||
473 | uint8_t reg; | ||
474 | int ret = 0; | ||
475 | |||
476 | switch (ctrl->id) { | ||
477 | case V4L2_CID_AUTOGAIN: | ||
478 | ctrl->value = priv->agc; | ||
479 | break; | ||
480 | case V4L2_CID_GAIN: | ||
481 | if (priv->agc) { | ||
482 | ret = ov6650_reg_read(client, REG_GAIN, ®); | ||
483 | ctrl->value = reg; | ||
484 | } else { | ||
485 | ctrl->value = priv->gain; | ||
486 | } | ||
487 | break; | ||
488 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
489 | ctrl->value = priv->awb; | ||
490 | break; | ||
491 | case V4L2_CID_BLUE_BALANCE: | ||
492 | if (priv->awb) { | ||
493 | ret = ov6650_reg_read(client, REG_BLUE, ®); | ||
494 | ctrl->value = reg; | ||
495 | } else { | ||
496 | ctrl->value = priv->blue; | ||
497 | } | ||
498 | break; | ||
499 | case V4L2_CID_RED_BALANCE: | ||
500 | if (priv->awb) { | ||
501 | ret = ov6650_reg_read(client, REG_RED, ®); | ||
502 | ctrl->value = reg; | ||
503 | } else { | ||
504 | ctrl->value = priv->red; | ||
505 | } | ||
506 | break; | ||
507 | case V4L2_CID_SATURATION: | ||
508 | ctrl->value = priv->saturation; | ||
509 | break; | ||
510 | case V4L2_CID_HUE: | ||
511 | ctrl->value = priv->hue; | ||
512 | break; | ||
513 | case V4L2_CID_BRIGHTNESS: | ||
514 | ctrl->value = priv->brightness; | ||
515 | break; | ||
516 | case V4L2_CID_EXPOSURE_AUTO: | ||
517 | ctrl->value = priv->aec; | ||
518 | break; | ||
519 | case V4L2_CID_EXPOSURE: | ||
520 | if (priv->aec) { | ||
521 | ret = ov6650_reg_read(client, REG_AECH, ®); | ||
522 | ctrl->value = reg; | ||
523 | } else { | ||
524 | ctrl->value = priv->exposure; | ||
525 | } | ||
526 | break; | ||
527 | case V4L2_CID_GAMMA: | ||
528 | ctrl->value = priv->gamma; | ||
529 | break; | ||
530 | case V4L2_CID_VFLIP: | ||
531 | ctrl->value = priv->vflip; | ||
532 | break; | ||
533 | case V4L2_CID_HFLIP: | ||
534 | ctrl->value = priv->hflip; | ||
535 | break; | ||
536 | } | ||
537 | return ret; | ||
538 | } | ||
539 | |||
540 | /* Set status of additional camera capabilities */ | ||
541 | static int ov6650_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
542 | { | ||
543 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
544 | struct ov6650 *priv = to_ov6650(client); | ||
545 | int ret = 0; | ||
546 | |||
547 | switch (ctrl->id) { | ||
548 | case V4L2_CID_AUTOGAIN: | ||
549 | ret = ov6650_reg_rmw(client, REG_COMB, | ||
550 | ctrl->value ? COMB_AGC : 0, COMB_AGC); | ||
551 | if (!ret) | ||
552 | priv->agc = ctrl->value; | ||
553 | break; | ||
554 | case V4L2_CID_GAIN: | ||
555 | ret = ov6650_reg_write(client, REG_GAIN, ctrl->value); | ||
556 | if (!ret) | ||
557 | priv->gain = ctrl->value; | ||
558 | break; | ||
559 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
560 | ret = ov6650_reg_rmw(client, REG_COMB, | ||
561 | ctrl->value ? COMB_AWB : 0, COMB_AWB); | ||
562 | if (!ret) | ||
563 | priv->awb = ctrl->value; | ||
564 | break; | ||
565 | case V4L2_CID_BLUE_BALANCE: | ||
566 | ret = ov6650_reg_write(client, REG_BLUE, ctrl->value); | ||
567 | if (!ret) | ||
568 | priv->blue = ctrl->value; | ||
569 | break; | ||
570 | case V4L2_CID_RED_BALANCE: | ||
571 | ret = ov6650_reg_write(client, REG_RED, ctrl->value); | ||
572 | if (!ret) | ||
573 | priv->red = ctrl->value; | ||
574 | break; | ||
575 | case V4L2_CID_SATURATION: | ||
576 | ret = ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->value), | ||
577 | SAT_MASK); | ||
578 | if (!ret) | ||
579 | priv->saturation = ctrl->value; | ||
580 | break; | ||
581 | case V4L2_CID_HUE: | ||
582 | ret = ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->value), | ||
583 | HUE_MASK); | ||
584 | if (!ret) | ||
585 | priv->hue = ctrl->value; | ||
586 | break; | ||
587 | case V4L2_CID_BRIGHTNESS: | ||
588 | ret = ov6650_reg_write(client, REG_BRT, ctrl->value); | ||
589 | if (!ret) | ||
590 | priv->brightness = ctrl->value; | ||
591 | break; | ||
592 | case V4L2_CID_EXPOSURE_AUTO: | ||
593 | switch (ctrl->value) { | ||
594 | case V4L2_EXPOSURE_AUTO: | ||
595 | ret = ov6650_reg_rmw(client, REG_COMB, COMB_AEC, 0); | ||
596 | break; | ||
597 | default: | ||
598 | ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_AEC); | ||
599 | break; | ||
600 | } | ||
601 | if (!ret) | ||
602 | priv->aec = ctrl->value; | ||
603 | break; | ||
604 | case V4L2_CID_EXPOSURE: | ||
605 | ret = ov6650_reg_write(client, REG_AECH, ctrl->value); | ||
606 | if (!ret) | ||
607 | priv->exposure = ctrl->value; | ||
608 | break; | ||
609 | case V4L2_CID_GAMMA: | ||
610 | ret = ov6650_reg_write(client, REG_GAM1, ctrl->value); | ||
611 | if (!ret) | ||
612 | priv->gamma = ctrl->value; | ||
613 | break; | ||
614 | case V4L2_CID_VFLIP: | ||
615 | ret = ov6650_reg_rmw(client, REG_COMB, | ||
616 | ctrl->value ? COMB_FLIP_V : 0, COMB_FLIP_V); | ||
617 | if (!ret) | ||
618 | priv->vflip = ctrl->value; | ||
619 | break; | ||
620 | case V4L2_CID_HFLIP: | ||
621 | ret = ov6650_reg_rmw(client, REG_COMB, | ||
622 | ctrl->value ? COMB_FLIP_H : 0, COMB_FLIP_H); | ||
623 | if (!ret) | ||
624 | priv->hflip = ctrl->value; | ||
625 | break; | ||
626 | } | ||
627 | |||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | /* Get chip identification */ | ||
632 | static int ov6650_g_chip_ident(struct v4l2_subdev *sd, | ||
633 | struct v4l2_dbg_chip_ident *id) | ||
634 | { | ||
635 | id->ident = V4L2_IDENT_OV6650; | ||
636 | id->revision = 0; | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
642 | static int ov6650_get_register(struct v4l2_subdev *sd, | ||
643 | struct v4l2_dbg_register *reg) | ||
644 | { | ||
645 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
646 | int ret; | ||
647 | u8 val; | ||
648 | |||
649 | if (reg->reg & ~0xff) | ||
650 | return -EINVAL; | ||
651 | |||
652 | reg->size = 1; | ||
653 | |||
654 | ret = ov6650_reg_read(client, reg->reg, &val); | ||
655 | if (!ret) | ||
656 | reg->val = (__u64)val; | ||
657 | |||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | static int ov6650_set_register(struct v4l2_subdev *sd, | ||
662 | struct v4l2_dbg_register *reg) | ||
663 | { | ||
664 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
665 | |||
666 | if (reg->reg & ~0xff || reg->val & ~0xff) | ||
667 | return -EINVAL; | ||
668 | |||
669 | return ov6650_reg_write(client, reg->reg, reg->val); | ||
670 | } | ||
671 | #endif | ||
672 | |||
673 | static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
674 | { | ||
675 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
676 | struct ov6650 *priv = to_ov6650(client); | ||
677 | |||
678 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
679 | a->c = priv->rect; | ||
680 | |||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | static int ov6650_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
685 | { | ||
686 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
687 | struct ov6650 *priv = to_ov6650(client); | ||
688 | struct v4l2_rect *rect = &a->c; | ||
689 | int ret; | ||
690 | |||
691 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
692 | return -EINVAL; | ||
693 | |||
694 | rect->left = ALIGN(rect->left, 2); | ||
695 | rect->width = ALIGN(rect->width, 2); | ||
696 | rect->top = ALIGN(rect->top, 2); | ||
697 | rect->height = ALIGN(rect->height, 2); | ||
698 | soc_camera_limit_side(&rect->left, &rect->width, | ||
699 | DEF_HSTRT << 1, 2, W_CIF); | ||
700 | soc_camera_limit_side(&rect->top, &rect->height, | ||
701 | DEF_VSTRT << 1, 2, H_CIF); | ||
702 | |||
703 | ret = ov6650_reg_write(client, REG_HSTRT, rect->left >> 1); | ||
704 | if (!ret) { | ||
705 | priv->rect.left = rect->left; | ||
706 | ret = ov6650_reg_write(client, REG_HSTOP, | ||
707 | (rect->left + rect->width) >> 1); | ||
708 | } | ||
709 | if (!ret) { | ||
710 | priv->rect.width = rect->width; | ||
711 | ret = ov6650_reg_write(client, REG_VSTRT, rect->top >> 1); | ||
712 | } | ||
713 | if (!ret) { | ||
714 | priv->rect.top = rect->top; | ||
715 | ret = ov6650_reg_write(client, REG_VSTOP, | ||
716 | (rect->top + rect->height) >> 1); | ||
717 | } | ||
718 | if (!ret) | ||
719 | priv->rect.height = rect->height; | ||
720 | |||
721 | return ret; | ||
722 | } | ||
723 | |||
724 | static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | ||
725 | { | ||
726 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
727 | return -EINVAL; | ||
728 | |||
729 | a->bounds.left = DEF_HSTRT << 1; | ||
730 | a->bounds.top = DEF_VSTRT << 1; | ||
731 | a->bounds.width = W_CIF; | ||
732 | a->bounds.height = H_CIF; | ||
733 | a->defrect = a->bounds; | ||
734 | a->pixelaspect.numerator = 1; | ||
735 | a->pixelaspect.denominator = 1; | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static int ov6650_g_fmt(struct v4l2_subdev *sd, | ||
741 | struct v4l2_mbus_framefmt *mf) | ||
742 | { | ||
743 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
744 | struct ov6650 *priv = to_ov6650(client); | ||
745 | |||
746 | mf->width = priv->rect.width >> priv->half_scale; | ||
747 | mf->height = priv->rect.height >> priv->half_scale; | ||
748 | mf->code = priv->code; | ||
749 | mf->colorspace = priv->colorspace; | ||
750 | mf->field = V4L2_FIELD_NONE; | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect) | ||
756 | { | ||
757 | return (width > rect->width >> 1 || height > rect->height >> 1); | ||
758 | } | ||
759 | |||
760 | static u8 to_clkrc(struct v4l2_fract *timeperframe, | ||
761 | unsigned long pclk_limit, unsigned long pclk_max) | ||
762 | { | ||
763 | unsigned long pclk; | ||
764 | |||
765 | if (timeperframe->numerator && timeperframe->denominator) | ||
766 | pclk = pclk_max * timeperframe->denominator / | ||
767 | (FRAME_RATE_MAX * timeperframe->numerator); | ||
768 | else | ||
769 | pclk = pclk_max; | ||
770 | |||
771 | if (pclk_limit && pclk_limit < pclk) | ||
772 | pclk = pclk_limit; | ||
773 | |||
774 | return (pclk_max - 1) / pclk; | ||
775 | } | ||
776 | |||
777 | /* set the format we will capture in */ | ||
778 | static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) | ||
779 | { | ||
780 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
781 | struct soc_camera_device *icd = client->dev.platform_data; | ||
782 | struct soc_camera_sense *sense = icd->sense; | ||
783 | struct ov6650 *priv = to_ov6650(client); | ||
784 | bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); | ||
785 | struct v4l2_crop a = { | ||
786 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
787 | .c = { | ||
788 | .left = priv->rect.left + (priv->rect.width >> 1) - | ||
789 | (mf->width >> (1 - half_scale)), | ||
790 | .top = priv->rect.top + (priv->rect.height >> 1) - | ||
791 | (mf->height >> (1 - half_scale)), | ||
792 | .width = mf->width << half_scale, | ||
793 | .height = mf->height << half_scale, | ||
794 | }, | ||
795 | }; | ||
796 | enum v4l2_mbus_pixelcode code = mf->code; | ||
797 | unsigned long mclk, pclk; | ||
798 | u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc; | ||
799 | int ret; | ||
800 | |||
801 | /* select color matrix configuration for given color encoding */ | ||
802 | switch (code) { | ||
803 | case V4L2_MBUS_FMT_GREY8_1X8: | ||
804 | dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); | ||
805 | coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; | ||
806 | coma_set |= COMA_BW; | ||
807 | break; | ||
808 | case V4L2_MBUS_FMT_YUYV8_2X8: | ||
809 | dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n"); | ||
810 | coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP; | ||
811 | coma_set |= COMA_WORD_SWAP; | ||
812 | break; | ||
813 | case V4L2_MBUS_FMT_YVYU8_2X8: | ||
814 | dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n"); | ||
815 | coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP | | ||
816 | COMA_BYTE_SWAP; | ||
817 | break; | ||
818 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
819 | dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n"); | ||
820 | if (half_scale) { | ||
821 | coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; | ||
822 | coma_set |= COMA_BYTE_SWAP; | ||
823 | } else { | ||
824 | coma_mask |= COMA_RGB | COMA_BW; | ||
825 | coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; | ||
826 | } | ||
827 | break; | ||
828 | case V4L2_MBUS_FMT_VYUY8_2X8: | ||
829 | dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n"); | ||
830 | if (half_scale) { | ||
831 | coma_mask |= COMA_RGB | COMA_BW; | ||
832 | coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; | ||
833 | } else { | ||
834 | coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; | ||
835 | coma_set |= COMA_BYTE_SWAP; | ||
836 | } | ||
837 | break; | ||
838 | case V4L2_MBUS_FMT_SBGGR8_1X8: | ||
839 | dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n"); | ||
840 | coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; | ||
841 | coma_set |= COMA_RAW_RGB | COMA_RGB; | ||
842 | break; | ||
843 | case 0: | ||
844 | break; | ||
845 | default: | ||
846 | dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code); | ||
847 | return -EINVAL; | ||
848 | } | ||
849 | priv->code = code; | ||
850 | |||
851 | if (code == V4L2_MBUS_FMT_GREY8_1X8 || | ||
852 | code == V4L2_MBUS_FMT_SBGGR8_1X8) { | ||
853 | coml_mask = COML_ONE_CHANNEL; | ||
854 | coml_set = 0; | ||
855 | priv->pclk_max = 4000000; | ||
856 | } else { | ||
857 | coml_mask = 0; | ||
858 | coml_set = COML_ONE_CHANNEL; | ||
859 | priv->pclk_max = 8000000; | ||
860 | } | ||
861 | |||
862 | if (code == V4L2_MBUS_FMT_SBGGR8_1X8) | ||
863 | priv->colorspace = V4L2_COLORSPACE_SRGB; | ||
864 | else if (code != 0) | ||
865 | priv->colorspace = V4L2_COLORSPACE_JPEG; | ||
866 | |||
867 | if (half_scale) { | ||
868 | dev_dbg(&client->dev, "max resolution: QCIF\n"); | ||
869 | coma_set |= COMA_QCIF; | ||
870 | priv->pclk_max /= 2; | ||
871 | } else { | ||
872 | dev_dbg(&client->dev, "max resolution: CIF\n"); | ||
873 | coma_mask |= COMA_QCIF; | ||
874 | } | ||
875 | priv->half_scale = half_scale; | ||
876 | |||
877 | if (sense) { | ||
878 | if (sense->master_clock == 8000000) { | ||
879 | dev_dbg(&client->dev, "8MHz input clock\n"); | ||
880 | clkrc = CLKRC_6MHz; | ||
881 | } else if (sense->master_clock == 12000000) { | ||
882 | dev_dbg(&client->dev, "12MHz input clock\n"); | ||
883 | clkrc = CLKRC_12MHz; | ||
884 | } else if (sense->master_clock == 16000000) { | ||
885 | dev_dbg(&client->dev, "16MHz input clock\n"); | ||
886 | clkrc = CLKRC_16MHz; | ||
887 | } else if (sense->master_clock == 24000000) { | ||
888 | dev_dbg(&client->dev, "24MHz input clock\n"); | ||
889 | clkrc = CLKRC_24MHz; | ||
890 | } else { | ||
891 | dev_err(&client->dev, | ||
892 | "unspported input clock, check platform data\n"); | ||
893 | return -EINVAL; | ||
894 | } | ||
895 | mclk = sense->master_clock; | ||
896 | priv->pclk_limit = sense->pixel_clock_max; | ||
897 | } else { | ||
898 | clkrc = CLKRC_24MHz; | ||
899 | mclk = 24000000; | ||
900 | priv->pclk_limit = 0; | ||
901 | dev_dbg(&client->dev, "using default 24MHz input clock\n"); | ||
902 | } | ||
903 | |||
904 | clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); | ||
905 | |||
906 | pclk = priv->pclk_max / GET_CLKRC_DIV(clkrc); | ||
907 | dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n", | ||
908 | mclk / pclk, 10 * mclk % pclk / pclk); | ||
909 | |||
910 | ret = ov6650_s_crop(sd, &a); | ||
911 | if (!ret) | ||
912 | ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); | ||
913 | if (!ret) | ||
914 | ret = ov6650_reg_write(client, REG_CLKRC, clkrc); | ||
915 | if (!ret) | ||
916 | ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); | ||
917 | |||
918 | if (!ret) { | ||
919 | mf->colorspace = priv->colorspace; | ||
920 | mf->width = priv->rect.width >> half_scale; | ||
921 | mf->height = priv->rect.height >> half_scale; | ||
922 | } | ||
923 | |||
924 | return ret; | ||
925 | } | ||
926 | |||
927 | static int ov6650_try_fmt(struct v4l2_subdev *sd, | ||
928 | struct v4l2_mbus_framefmt *mf) | ||
929 | { | ||
930 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
931 | struct ov6650 *priv = to_ov6650(client); | ||
932 | |||
933 | if (is_unscaled_ok(mf->width, mf->height, &priv->rect)) | ||
934 | v4l_bound_align_image(&mf->width, 2, W_CIF, 1, | ||
935 | &mf->height, 2, H_CIF, 1, 0); | ||
936 | |||
937 | mf->field = V4L2_FIELD_NONE; | ||
938 | |||
939 | switch (mf->code) { | ||
940 | case V4L2_MBUS_FMT_Y10_1X10: | ||
941 | mf->code = V4L2_MBUS_FMT_GREY8_1X8; | ||
942 | case V4L2_MBUS_FMT_GREY8_1X8: | ||
943 | case V4L2_MBUS_FMT_YVYU8_2X8: | ||
944 | case V4L2_MBUS_FMT_YUYV8_2X8: | ||
945 | case V4L2_MBUS_FMT_VYUY8_2X8: | ||
946 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
947 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
948 | break; | ||
949 | default: | ||
950 | mf->code = V4L2_MBUS_FMT_SBGGR8_1X8; | ||
951 | case V4L2_MBUS_FMT_SBGGR8_1X8: | ||
952 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
953 | break; | ||
954 | } | ||
955 | |||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | ||
960 | enum v4l2_mbus_pixelcode *code) | ||
961 | { | ||
962 | if (index >= ARRAY_SIZE(ov6650_codes)) | ||
963 | return -EINVAL; | ||
964 | |||
965 | *code = ov6650_codes[index]; | ||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | ||
970 | { | ||
971 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
972 | struct ov6650 *priv = to_ov6650(client); | ||
973 | struct v4l2_captureparm *cp = &parms->parm.capture; | ||
974 | |||
975 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
976 | return -EINVAL; | ||
977 | |||
978 | memset(cp, 0, sizeof(*cp)); | ||
979 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
980 | cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf, | ||
981 | priv->pclk_limit, priv->pclk_max)); | ||
982 | cp->timeperframe.denominator = FRAME_RATE_MAX; | ||
983 | |||
984 | dev_dbg(&client->dev, "Frame interval: %u/%u s\n", | ||
985 | cp->timeperframe.numerator, cp->timeperframe.denominator); | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | static int ov6650_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | ||
991 | { | ||
992 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
993 | struct ov6650 *priv = to_ov6650(client); | ||
994 | struct v4l2_captureparm *cp = &parms->parm.capture; | ||
995 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
996 | int div, ret; | ||
997 | u8 clkrc; | ||
998 | |||
999 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1000 | return -EINVAL; | ||
1001 | |||
1002 | if (cp->extendedmode != 0) | ||
1003 | return -EINVAL; | ||
1004 | |||
1005 | if (tpf->numerator == 0 || tpf->denominator == 0) | ||
1006 | div = 1; /* Reset to full rate */ | ||
1007 | else | ||
1008 | div = (tpf->numerator * FRAME_RATE_MAX) / tpf->denominator; | ||
1009 | |||
1010 | if (div == 0) | ||
1011 | div = 1; | ||
1012 | else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK)) | ||
1013 | div = GET_CLKRC_DIV(CLKRC_DIV_MASK); | ||
1014 | |||
1015 | /* | ||
1016 | * Keep result to be used as tpf limit | ||
1017 | * for subseqent clock divider calculations | ||
1018 | */ | ||
1019 | priv->tpf.numerator = div; | ||
1020 | priv->tpf.denominator = FRAME_RATE_MAX; | ||
1021 | |||
1022 | clkrc = to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); | ||
1023 | |||
1024 | ret = ov6650_reg_rmw(client, REG_CLKRC, clkrc, CLKRC_DIV_MASK); | ||
1025 | if (!ret) { | ||
1026 | tpf->numerator = GET_CLKRC_DIV(clkrc); | ||
1027 | tpf->denominator = FRAME_RATE_MAX; | ||
1028 | } | ||
1029 | |||
1030 | return ret; | ||
1031 | } | ||
1032 | |||
1033 | /* Soft reset the camera. This has nothing to do with the RESET pin! */ | ||
1034 | static int ov6650_reset(struct i2c_client *client) | ||
1035 | { | ||
1036 | int ret; | ||
1037 | |||
1038 | dev_dbg(&client->dev, "reset\n"); | ||
1039 | |||
1040 | ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0); | ||
1041 | if (ret) | ||
1042 | dev_err(&client->dev, | ||
1043 | "An error occured while entering soft reset!\n"); | ||
1044 | |||
1045 | return ret; | ||
1046 | } | ||
1047 | |||
1048 | /* program default register values */ | ||
1049 | static int ov6650_prog_dflt(struct i2c_client *client) | ||
1050 | { | ||
1051 | int ret; | ||
1052 | |||
1053 | dev_dbg(&client->dev, "initializing\n"); | ||
1054 | |||
1055 | ret = ov6650_reg_write(client, REG_COMA, 0); /* ~COMA_RESET */ | ||
1056 | if (!ret) | ||
1057 | ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_BAND_FILTER); | ||
1058 | |||
1059 | return ret; | ||
1060 | } | ||
1061 | |||
1062 | static int ov6650_video_probe(struct soc_camera_device *icd, | ||
1063 | struct i2c_client *client) | ||
1064 | { | ||
1065 | u8 pidh, pidl, midh, midl; | ||
1066 | int ret = 0; | ||
1067 | |||
1068 | /* | ||
1069 | * check and show product ID and manufacturer ID | ||
1070 | */ | ||
1071 | ret = ov6650_reg_read(client, REG_PIDH, &pidh); | ||
1072 | if (!ret) | ||
1073 | ret = ov6650_reg_read(client, REG_PIDL, &pidl); | ||
1074 | if (!ret) | ||
1075 | ret = ov6650_reg_read(client, REG_MIDH, &midh); | ||
1076 | if (!ret) | ||
1077 | ret = ov6650_reg_read(client, REG_MIDL, &midl); | ||
1078 | |||
1079 | if (ret) | ||
1080 | return ret; | ||
1081 | |||
1082 | if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) { | ||
1083 | dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n", | ||
1084 | pidh, pidl); | ||
1085 | return -ENODEV; | ||
1086 | } | ||
1087 | |||
1088 | dev_info(&client->dev, | ||
1089 | "ov6650 Product ID 0x%02x:0x%02x Manufacturer ID 0x%02x:0x%02x\n", | ||
1090 | pidh, pidl, midh, midl); | ||
1091 | |||
1092 | ret = ov6650_reset(client); | ||
1093 | if (!ret) | ||
1094 | ret = ov6650_prog_dflt(client); | ||
1095 | |||
1096 | return ret; | ||
1097 | } | ||
1098 | |||
1099 | static struct soc_camera_ops ov6650_ops = { | ||
1100 | .set_bus_param = ov6650_set_bus_param, | ||
1101 | .query_bus_param = ov6650_query_bus_param, | ||
1102 | .controls = ov6650_controls, | ||
1103 | .num_controls = ARRAY_SIZE(ov6650_controls), | ||
1104 | }; | ||
1105 | |||
1106 | static struct v4l2_subdev_core_ops ov6650_core_ops = { | ||
1107 | .g_ctrl = ov6650_g_ctrl, | ||
1108 | .s_ctrl = ov6650_s_ctrl, | ||
1109 | .g_chip_ident = ov6650_g_chip_ident, | ||
1110 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1111 | .g_register = ov6650_get_register, | ||
1112 | .s_register = ov6650_set_register, | ||
1113 | #endif | ||
1114 | }; | ||
1115 | |||
1116 | static struct v4l2_subdev_video_ops ov6650_video_ops = { | ||
1117 | .s_stream = ov6650_s_stream, | ||
1118 | .g_mbus_fmt = ov6650_g_fmt, | ||
1119 | .s_mbus_fmt = ov6650_s_fmt, | ||
1120 | .try_mbus_fmt = ov6650_try_fmt, | ||
1121 | .enum_mbus_fmt = ov6650_enum_fmt, | ||
1122 | .cropcap = ov6650_cropcap, | ||
1123 | .g_crop = ov6650_g_crop, | ||
1124 | .s_crop = ov6650_s_crop, | ||
1125 | .g_parm = ov6650_g_parm, | ||
1126 | .s_parm = ov6650_s_parm, | ||
1127 | }; | ||
1128 | |||
1129 | static struct v4l2_subdev_ops ov6650_subdev_ops = { | ||
1130 | .core = &ov6650_core_ops, | ||
1131 | .video = &ov6650_video_ops, | ||
1132 | }; | ||
1133 | |||
1134 | /* | ||
1135 | * i2c_driver function | ||
1136 | */ | ||
1137 | static int ov6650_probe(struct i2c_client *client, | ||
1138 | const struct i2c_device_id *did) | ||
1139 | { | ||
1140 | struct ov6650 *priv; | ||
1141 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1142 | struct soc_camera_link *icl; | ||
1143 | int ret; | ||
1144 | |||
1145 | if (!icd) { | ||
1146 | dev_err(&client->dev, "Missing soc-camera data!\n"); | ||
1147 | return -EINVAL; | ||
1148 | } | ||
1149 | |||
1150 | icl = to_soc_camera_link(icd); | ||
1151 | if (!icl) { | ||
1152 | dev_err(&client->dev, "Missing platform_data for driver\n"); | ||
1153 | return -EINVAL; | ||
1154 | } | ||
1155 | |||
1156 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1157 | if (!priv) { | ||
1158 | dev_err(&client->dev, | ||
1159 | "Failed to allocate memory for private data!\n"); | ||
1160 | return -ENOMEM; | ||
1161 | } | ||
1162 | |||
1163 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops); | ||
1164 | |||
1165 | icd->ops = &ov6650_ops; | ||
1166 | |||
1167 | priv->rect.left = DEF_HSTRT << 1; | ||
1168 | priv->rect.top = DEF_VSTRT << 1; | ||
1169 | priv->rect.width = W_CIF; | ||
1170 | priv->rect.height = H_CIF; | ||
1171 | priv->half_scale = false; | ||
1172 | priv->code = V4L2_MBUS_FMT_YUYV8_2X8; | ||
1173 | priv->colorspace = V4L2_COLORSPACE_JPEG; | ||
1174 | |||
1175 | ret = ov6650_video_probe(icd, client); | ||
1176 | |||
1177 | if (ret) { | ||
1178 | icd->ops = NULL; | ||
1179 | i2c_set_clientdata(client, NULL); | ||
1180 | kfree(priv); | ||
1181 | } | ||
1182 | |||
1183 | return ret; | ||
1184 | } | ||
1185 | |||
1186 | static int ov6650_remove(struct i2c_client *client) | ||
1187 | { | ||
1188 | struct ov6650 *priv = to_ov6650(client); | ||
1189 | |||
1190 | i2c_set_clientdata(client, NULL); | ||
1191 | kfree(priv); | ||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | static const struct i2c_device_id ov6650_id[] = { | ||
1196 | { "ov6650", 0 }, | ||
1197 | { } | ||
1198 | }; | ||
1199 | MODULE_DEVICE_TABLE(i2c, ov6650_id); | ||
1200 | |||
1201 | static struct i2c_driver ov6650_i2c_driver = { | ||
1202 | .driver = { | ||
1203 | .name = "ov6650", | ||
1204 | }, | ||
1205 | .probe = ov6650_probe, | ||
1206 | .remove = ov6650_remove, | ||
1207 | .id_table = ov6650_id, | ||
1208 | }; | ||
1209 | |||
1210 | static int __init ov6650_module_init(void) | ||
1211 | { | ||
1212 | return i2c_add_driver(&ov6650_i2c_driver); | ||
1213 | } | ||
1214 | |||
1215 | static void __exit ov6650_module_exit(void) | ||
1216 | { | ||
1217 | i2c_del_driver(&ov6650_i2c_driver); | ||
1218 | } | ||
1219 | |||
1220 | module_init(ov6650_module_init); | ||
1221 | module_exit(ov6650_module_exit); | ||
1222 | |||
1223 | MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650"); | ||
1224 | MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>"); | ||
1225 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 91c886ab15c..c881a64b41f 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c | |||
@@ -18,8 +18,9 @@ | |||
18 | #include <linux/videodev2.h> | 18 | #include <linux/videodev2.h> |
19 | #include <media/v4l2-device.h> | 19 | #include <media/v4l2-device.h> |
20 | #include <media/v4l2-chip-ident.h> | 20 | #include <media/v4l2-chip-ident.h> |
21 | #include <media/v4l2-i2c-drv.h> | 21 | #include <media/v4l2-mediabus.h> |
22 | 22 | ||
23 | #include "ov7670.h" | ||
23 | 24 | ||
24 | MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); | 25 | MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); |
25 | MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors"); | 26 | MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors"); |
@@ -43,11 +44,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
43 | #define QCIF_HEIGHT 144 | 44 | #define QCIF_HEIGHT 144 |
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Our nominal (default) frame rate. | ||
47 | */ | ||
48 | #define OV7670_FRAME_RATE 30 | ||
49 | |||
50 | /* | ||
51 | * The 7670 sits on i2c with ID 0x42 | 47 | * The 7670 sits on i2c with ID 0x42 |
52 | */ | 48 | */ |
53 | #define OV7670_I2C_ADDR 0x42 | 49 | #define OV7670_I2C_ADDR 0x42 |
@@ -198,7 +194,11 @@ struct ov7670_info { | |||
198 | struct ov7670_format_struct *fmt; /* Current format */ | 194 | struct ov7670_format_struct *fmt; /* Current format */ |
199 | unsigned char sat; /* Saturation value */ | 195 | unsigned char sat; /* Saturation value */ |
200 | int hue; /* Hue value */ | 196 | int hue; /* Hue value */ |
197 | int min_width; /* Filter out smaller sizes */ | ||
198 | int min_height; /* Filter out smaller sizes */ | ||
199 | int clock_speed; /* External clock speed (MHz) */ | ||
201 | u8 clkrc; /* Clock divider value */ | 200 | u8 clkrc; /* Clock divider value */ |
201 | bool use_smbus; /* Use smbus I/O instead of I2C */ | ||
202 | }; | 202 | }; |
203 | 203 | ||
204 | static inline struct ov7670_info *to_state(struct v4l2_subdev *sd) | 204 | static inline struct ov7670_info *to_state(struct v4l2_subdev *sd) |
@@ -415,8 +415,7 @@ static struct regval_list ov7670_fmt_raw[] = { | |||
415 | * ov7670 is not really an SMBUS device, though, so the communication | 415 | * ov7670 is not really an SMBUS device, though, so the communication |
416 | * is not always entirely reliable. | 416 | * is not always entirely reliable. |
417 | */ | 417 | */ |
418 | #ifdef CONFIG_OLPC_XO_1 | 418 | static int ov7670_read_smbus(struct v4l2_subdev *sd, unsigned char reg, |
419 | static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, | ||
420 | unsigned char *value) | 419 | unsigned char *value) |
421 | { | 420 | { |
422 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 421 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
@@ -431,7 +430,7 @@ static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, | |||
431 | } | 430 | } |
432 | 431 | ||
433 | 432 | ||
434 | static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, | 433 | static int ov7670_write_smbus(struct v4l2_subdev *sd, unsigned char reg, |
435 | unsigned char value) | 434 | unsigned char value) |
436 | { | 435 | { |
437 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 436 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
@@ -442,11 +441,10 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, | |||
442 | return ret; | 441 | return ret; |
443 | } | 442 | } |
444 | 443 | ||
445 | #else /* ! CONFIG_OLPC_XO_1 */ | ||
446 | /* | 444 | /* |
447 | * On most platforms, we'd rather do straight i2c I/O. | 445 | * On most platforms, we'd rather do straight i2c I/O. |
448 | */ | 446 | */ |
449 | static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, | 447 | static int ov7670_read_i2c(struct v4l2_subdev *sd, unsigned char reg, |
450 | unsigned char *value) | 448 | unsigned char *value) |
451 | { | 449 | { |
452 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 450 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
@@ -479,7 +477,7 @@ static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, | |||
479 | } | 477 | } |
480 | 478 | ||
481 | 479 | ||
482 | static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, | 480 | static int ov7670_write_i2c(struct v4l2_subdev *sd, unsigned char reg, |
483 | unsigned char value) | 481 | unsigned char value) |
484 | { | 482 | { |
485 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 483 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
@@ -498,8 +496,26 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, | |||
498 | msleep(5); /* Wait for reset to run */ | 496 | msleep(5); /* Wait for reset to run */ |
499 | return ret; | 497 | return ret; |
500 | } | 498 | } |
501 | #endif /* CONFIG_OLPC_XO_1 */ | ||
502 | 499 | ||
500 | static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, | ||
501 | unsigned char *value) | ||
502 | { | ||
503 | struct ov7670_info *info = to_state(sd); | ||
504 | if (info->use_smbus) | ||
505 | return ov7670_read_smbus(sd, reg, value); | ||
506 | else | ||
507 | return ov7670_read_i2c(sd, reg, value); | ||
508 | } | ||
509 | |||
510 | static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, | ||
511 | unsigned char value) | ||
512 | { | ||
513 | struct ov7670_info *info = to_state(sd); | ||
514 | if (info->use_smbus) | ||
515 | return ov7670_write_smbus(sd, reg, value); | ||
516 | else | ||
517 | return ov7670_write_i2c(sd, reg, value); | ||
518 | } | ||
503 | 519 | ||
504 | /* | 520 | /* |
505 | * Write a list of register settings; ff/ff stops the process. | 521 | * Write a list of register settings; ff/ff stops the process. |
@@ -572,42 +588,37 @@ static int ov7670_detect(struct v4l2_subdev *sd) | |||
572 | /* | 588 | /* |
573 | * Store information about the video data format. The color matrix | 589 | * Store information about the video data format. The color matrix |
574 | * is deeply tied into the format, so keep the relevant values here. | 590 | * is deeply tied into the format, so keep the relevant values here. |
575 | * The magic matrix nubmers come from OmniVision. | 591 | * The magic matrix numbers come from OmniVision. |
576 | */ | 592 | */ |
577 | static struct ov7670_format_struct { | 593 | static struct ov7670_format_struct { |
578 | __u8 *desc; | 594 | enum v4l2_mbus_pixelcode mbus_code; |
579 | __u32 pixelformat; | 595 | enum v4l2_colorspace colorspace; |
580 | struct regval_list *regs; | 596 | struct regval_list *regs; |
581 | int cmatrix[CMATRIX_LEN]; | 597 | int cmatrix[CMATRIX_LEN]; |
582 | int bpp; /* Bytes per pixel */ | ||
583 | } ov7670_formats[] = { | 598 | } ov7670_formats[] = { |
584 | { | 599 | { |
585 | .desc = "YUYV 4:2:2", | 600 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, |
586 | .pixelformat = V4L2_PIX_FMT_YUYV, | 601 | .colorspace = V4L2_COLORSPACE_JPEG, |
587 | .regs = ov7670_fmt_yuv422, | 602 | .regs = ov7670_fmt_yuv422, |
588 | .cmatrix = { 128, -128, 0, -34, -94, 128 }, | 603 | .cmatrix = { 128, -128, 0, -34, -94, 128 }, |
589 | .bpp = 2, | ||
590 | }, | 604 | }, |
591 | { | 605 | { |
592 | .desc = "RGB 444", | 606 | .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, |
593 | .pixelformat = V4L2_PIX_FMT_RGB444, | 607 | .colorspace = V4L2_COLORSPACE_SRGB, |
594 | .regs = ov7670_fmt_rgb444, | 608 | .regs = ov7670_fmt_rgb444, |
595 | .cmatrix = { 179, -179, 0, -61, -176, 228 }, | 609 | .cmatrix = { 179, -179, 0, -61, -176, 228 }, |
596 | .bpp = 2, | ||
597 | }, | 610 | }, |
598 | { | 611 | { |
599 | .desc = "RGB 565", | 612 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, |
600 | .pixelformat = V4L2_PIX_FMT_RGB565, | 613 | .colorspace = V4L2_COLORSPACE_SRGB, |
601 | .regs = ov7670_fmt_rgb565, | 614 | .regs = ov7670_fmt_rgb565, |
602 | .cmatrix = { 179, -179, 0, -61, -176, 228 }, | 615 | .cmatrix = { 179, -179, 0, -61, -176, 228 }, |
603 | .bpp = 2, | ||
604 | }, | 616 | }, |
605 | { | 617 | { |
606 | .desc = "Raw RGB Bayer", | 618 | .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, |
607 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | 619 | .colorspace = V4L2_COLORSPACE_SRGB, |
608 | .regs = ov7670_fmt_raw, | 620 | .regs = ov7670_fmt_raw, |
609 | .cmatrix = { 0, 0, 0, 0, 0, 0 }, | 621 | .cmatrix = { 0, 0, 0, 0, 0, 0 }, |
610 | .bpp = 1 | ||
611 | }, | 622 | }, |
612 | }; | 623 | }; |
613 | #define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats) | 624 | #define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats) |
@@ -680,10 +691,10 @@ static struct ov7670_win_size { | |||
680 | .width = QVGA_WIDTH, | 691 | .width = QVGA_WIDTH, |
681 | .height = QVGA_HEIGHT, | 692 | .height = QVGA_HEIGHT, |
682 | .com7_bit = COM7_FMT_QVGA, | 693 | .com7_bit = COM7_FMT_QVGA, |
683 | .hstart = 164, /* Empirically determined */ | 694 | .hstart = 168, /* Empirically determined */ |
684 | .hstop = 20, | 695 | .hstop = 24, |
685 | .vstart = 14, | 696 | .vstart = 12, |
686 | .vstop = 494, | 697 | .vstop = 492, |
687 | .regs = NULL, | 698 | .regs = NULL, |
688 | }, | 699 | }, |
689 | /* QCIF */ | 700 | /* QCIF */ |
@@ -734,51 +745,45 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, | |||
734 | } | 745 | } |
735 | 746 | ||
736 | 747 | ||
737 | static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) | 748 | static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, |
749 | enum v4l2_mbus_pixelcode *code) | ||
738 | { | 750 | { |
739 | struct ov7670_format_struct *ofmt; | 751 | if (index >= N_OV7670_FMTS) |
740 | |||
741 | if (fmt->index >= N_OV7670_FMTS) | ||
742 | return -EINVAL; | 752 | return -EINVAL; |
743 | 753 | ||
744 | ofmt = ov7670_formats + fmt->index; | 754 | *code = ov7670_formats[index].mbus_code; |
745 | fmt->flags = 0; | ||
746 | strcpy(fmt->description, ofmt->desc); | ||
747 | fmt->pixelformat = ofmt->pixelformat; | ||
748 | return 0; | 755 | return 0; |
749 | } | 756 | } |
750 | 757 | ||
751 | |||
752 | static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, | 758 | static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, |
753 | struct v4l2_format *fmt, | 759 | struct v4l2_mbus_framefmt *fmt, |
754 | struct ov7670_format_struct **ret_fmt, | 760 | struct ov7670_format_struct **ret_fmt, |
755 | struct ov7670_win_size **ret_wsize) | 761 | struct ov7670_win_size **ret_wsize) |
756 | { | 762 | { |
757 | int index; | 763 | int index; |
758 | struct ov7670_win_size *wsize; | 764 | struct ov7670_win_size *wsize; |
759 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
760 | 765 | ||
761 | for (index = 0; index < N_OV7670_FMTS; index++) | 766 | for (index = 0; index < N_OV7670_FMTS; index++) |
762 | if (ov7670_formats[index].pixelformat == pix->pixelformat) | 767 | if (ov7670_formats[index].mbus_code == fmt->code) |
763 | break; | 768 | break; |
764 | if (index >= N_OV7670_FMTS) { | 769 | if (index >= N_OV7670_FMTS) { |
765 | /* default to first format */ | 770 | /* default to first format */ |
766 | index = 0; | 771 | index = 0; |
767 | pix->pixelformat = ov7670_formats[0].pixelformat; | 772 | fmt->code = ov7670_formats[0].mbus_code; |
768 | } | 773 | } |
769 | if (ret_fmt != NULL) | 774 | if (ret_fmt != NULL) |
770 | *ret_fmt = ov7670_formats + index; | 775 | *ret_fmt = ov7670_formats + index; |
771 | /* | 776 | /* |
772 | * Fields: the OV devices claim to be progressive. | 777 | * Fields: the OV devices claim to be progressive. |
773 | */ | 778 | */ |
774 | pix->field = V4L2_FIELD_NONE; | 779 | fmt->field = V4L2_FIELD_NONE; |
775 | /* | 780 | /* |
776 | * Round requested image size down to the nearest | 781 | * Round requested image size down to the nearest |
777 | * we support, but not below the smallest. | 782 | * we support, but not below the smallest. |
778 | */ | 783 | */ |
779 | for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES; | 784 | for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES; |
780 | wsize++) | 785 | wsize++) |
781 | if (pix->width >= wsize->width && pix->height >= wsize->height) | 786 | if (fmt->width >= wsize->width && fmt->height >= wsize->height) |
782 | break; | 787 | break; |
783 | if (wsize >= ov7670_win_sizes + N_WIN_SIZES) | 788 | if (wsize >= ov7670_win_sizes + N_WIN_SIZES) |
784 | wsize--; /* Take the smallest one */ | 789 | wsize--; /* Take the smallest one */ |
@@ -787,14 +792,14 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, | |||
787 | /* | 792 | /* |
788 | * Note the size we'll actually handle. | 793 | * Note the size we'll actually handle. |
789 | */ | 794 | */ |
790 | pix->width = wsize->width; | 795 | fmt->width = wsize->width; |
791 | pix->height = wsize->height; | 796 | fmt->height = wsize->height; |
792 | pix->bytesperline = pix->width*ov7670_formats[index].bpp; | 797 | fmt->colorspace = ov7670_formats[index].colorspace; |
793 | pix->sizeimage = pix->height*pix->bytesperline; | ||
794 | return 0; | 798 | return 0; |
795 | } | 799 | } |
796 | 800 | ||
797 | static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | 801 | static int ov7670_try_mbus_fmt(struct v4l2_subdev *sd, |
802 | struct v4l2_mbus_framefmt *fmt) | ||
798 | { | 803 | { |
799 | return ov7670_try_fmt_internal(sd, fmt, NULL, NULL); | 804 | return ov7670_try_fmt_internal(sd, fmt, NULL, NULL); |
800 | } | 805 | } |
@@ -802,15 +807,17 @@ static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
802 | /* | 807 | /* |
803 | * Set a format. | 808 | * Set a format. |
804 | */ | 809 | */ |
805 | static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | 810 | static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd, |
811 | struct v4l2_mbus_framefmt *fmt) | ||
806 | { | 812 | { |
807 | int ret; | ||
808 | struct ov7670_format_struct *ovfmt; | 813 | struct ov7670_format_struct *ovfmt; |
809 | struct ov7670_win_size *wsize; | 814 | struct ov7670_win_size *wsize; |
810 | struct ov7670_info *info = to_state(sd); | 815 | struct ov7670_info *info = to_state(sd); |
811 | unsigned char com7; | 816 | unsigned char com7; |
817 | int ret; | ||
812 | 818 | ||
813 | ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); | 819 | ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); |
820 | |||
814 | if (ret) | 821 | if (ret) |
815 | return ret; | 822 | return ret; |
816 | /* | 823 | /* |
@@ -845,7 +852,7 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
845 | */ | 852 | */ |
846 | if (ret == 0) | 853 | if (ret == 0) |
847 | ret = ov7670_write(sd, REG_CLKRC, info->clkrc); | 854 | ret = ov7670_write(sd, REG_CLKRC, info->clkrc); |
848 | return ret; | 855 | return 0; |
849 | } | 856 | } |
850 | 857 | ||
851 | /* | 858 | /* |
@@ -863,7 +870,7 @@ static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | |||
863 | memset(cp, 0, sizeof(struct v4l2_captureparm)); | 870 | memset(cp, 0, sizeof(struct v4l2_captureparm)); |
864 | cp->capability = V4L2_CAP_TIMEPERFRAME; | 871 | cp->capability = V4L2_CAP_TIMEPERFRAME; |
865 | cp->timeperframe.numerator = 1; | 872 | cp->timeperframe.numerator = 1; |
866 | cp->timeperframe.denominator = OV7670_FRAME_RATE; | 873 | cp->timeperframe.denominator = info->clock_speed; |
867 | if ((info->clkrc & CLK_EXT) == 0 && (info->clkrc & CLK_SCALE) > 1) | 874 | if ((info->clkrc & CLK_EXT) == 0 && (info->clkrc & CLK_SCALE) > 1) |
868 | cp->timeperframe.denominator /= (info->clkrc & CLK_SCALE); | 875 | cp->timeperframe.denominator /= (info->clkrc & CLK_SCALE); |
869 | return 0; | 876 | return 0; |
@@ -884,26 +891,72 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | |||
884 | if (tpf->numerator == 0 || tpf->denominator == 0) | 891 | if (tpf->numerator == 0 || tpf->denominator == 0) |
885 | div = 1; /* Reset to full rate */ | 892 | div = 1; /* Reset to full rate */ |
886 | else | 893 | else |
887 | div = (tpf->numerator*OV7670_FRAME_RATE)/tpf->denominator; | 894 | div = (tpf->numerator * info->clock_speed) / tpf->denominator; |
888 | if (div == 0) | 895 | if (div == 0) |
889 | div = 1; | 896 | div = 1; |
890 | else if (div > CLK_SCALE) | 897 | else if (div > CLK_SCALE) |
891 | div = CLK_SCALE; | 898 | div = CLK_SCALE; |
892 | info->clkrc = (info->clkrc & 0x80) | div; | 899 | info->clkrc = (info->clkrc & 0x80) | div; |
893 | tpf->numerator = 1; | 900 | tpf->numerator = 1; |
894 | tpf->denominator = OV7670_FRAME_RATE/div; | 901 | tpf->denominator = info->clock_speed / div; |
895 | return ov7670_write(sd, REG_CLKRC, info->clkrc); | 902 | return ov7670_write(sd, REG_CLKRC, info->clkrc); |
896 | } | 903 | } |
897 | 904 | ||
898 | 905 | ||
899 | |||
900 | /* | 906 | /* |
901 | * Code for dealing with controls. | 907 | * Frame intervals. Since frame rates are controlled with the clock |
908 | * divider, we can only do 30/n for integer n values. So no continuous | ||
909 | * or stepwise options. Here we just pick a handful of logical values. | ||
902 | */ | 910 | */ |
903 | 911 | ||
912 | static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 }; | ||
913 | |||
914 | static int ov7670_enum_frameintervals(struct v4l2_subdev *sd, | ||
915 | struct v4l2_frmivalenum *interval) | ||
916 | { | ||
917 | if (interval->index >= ARRAY_SIZE(ov7670_frame_rates)) | ||
918 | return -EINVAL; | ||
919 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
920 | interval->discrete.numerator = 1; | ||
921 | interval->discrete.denominator = ov7670_frame_rates[interval->index]; | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | /* | ||
926 | * Frame size enumeration | ||
927 | */ | ||
928 | static int ov7670_enum_framesizes(struct v4l2_subdev *sd, | ||
929 | struct v4l2_frmsizeenum *fsize) | ||
930 | { | ||
931 | struct ov7670_info *info = to_state(sd); | ||
932 | int i; | ||
933 | int num_valid = -1; | ||
934 | __u32 index = fsize->index; | ||
904 | 935 | ||
936 | /* | ||
937 | * If a minimum width/height was requested, filter out the capture | ||
938 | * windows that fall outside that. | ||
939 | */ | ||
940 | for (i = 0; i < N_WIN_SIZES; i++) { | ||
941 | struct ov7670_win_size *win = &ov7670_win_sizes[index]; | ||
942 | if (info->min_width && win->width < info->min_width) | ||
943 | continue; | ||
944 | if (info->min_height && win->height < info->min_height) | ||
945 | continue; | ||
946 | if (index == ++num_valid) { | ||
947 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
948 | fsize->discrete.width = win->width; | ||
949 | fsize->discrete.height = win->height; | ||
950 | return 0; | ||
951 | } | ||
952 | } | ||
905 | 953 | ||
954 | return -EINVAL; | ||
955 | } | ||
906 | 956 | ||
957 | /* | ||
958 | * Code for dealing with controls. | ||
959 | */ | ||
907 | 960 | ||
908 | static int ov7670_store_cmatrix(struct v4l2_subdev *sd, | 961 | static int ov7670_store_cmatrix(struct v4l2_subdev *sd, |
909 | int matrix[CMATRIX_LEN]) | 962 | int matrix[CMATRIX_LEN]) |
@@ -1396,6 +1449,47 @@ static int ov7670_g_chip_ident(struct v4l2_subdev *sd, | |||
1396 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0); | 1449 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0); |
1397 | } | 1450 | } |
1398 | 1451 | ||
1452 | static int ov7670_s_config(struct v4l2_subdev *sd, int dumb, void *data) | ||
1453 | { | ||
1454 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1455 | struct ov7670_config *config = data; | ||
1456 | struct ov7670_info *info = to_state(sd); | ||
1457 | int ret; | ||
1458 | |||
1459 | info->clock_speed = 30; /* default: a guess */ | ||
1460 | |||
1461 | /* | ||
1462 | * Must apply configuration before initializing device, because it | ||
1463 | * selects I/O method. | ||
1464 | */ | ||
1465 | if (config) { | ||
1466 | info->min_width = config->min_width; | ||
1467 | info->min_height = config->min_height; | ||
1468 | info->use_smbus = config->use_smbus; | ||
1469 | |||
1470 | if (config->clock_speed) | ||
1471 | info->clock_speed = config->clock_speed; | ||
1472 | } | ||
1473 | |||
1474 | /* Make sure it's an ov7670 */ | ||
1475 | ret = ov7670_detect(sd); | ||
1476 | if (ret) { | ||
1477 | v4l_dbg(1, debug, client, | ||
1478 | "chip found @ 0x%x (%s) is not an ov7670 chip.\n", | ||
1479 | client->addr << 1, client->adapter->name); | ||
1480 | kfree(info); | ||
1481 | return ret; | ||
1482 | } | ||
1483 | v4l_info(client, "chip found @ 0x%02x (%s)\n", | ||
1484 | client->addr << 1, client->adapter->name); | ||
1485 | |||
1486 | info->fmt = &ov7670_formats[0]; | ||
1487 | info->sat = 128; /* Review this */ | ||
1488 | info->clkrc = info->clock_speed / 30; | ||
1489 | |||
1490 | return 0; | ||
1491 | } | ||
1492 | |||
1399 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1493 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1400 | static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) | 1494 | static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
1401 | { | 1495 | { |
@@ -1434,6 +1528,7 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { | |||
1434 | .s_ctrl = ov7670_s_ctrl, | 1528 | .s_ctrl = ov7670_s_ctrl, |
1435 | .queryctrl = ov7670_queryctrl, | 1529 | .queryctrl = ov7670_queryctrl, |
1436 | .reset = ov7670_reset, | 1530 | .reset = ov7670_reset, |
1531 | .s_config = ov7670_s_config, | ||
1437 | .init = ov7670_init, | 1532 | .init = ov7670_init, |
1438 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1533 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1439 | .g_register = ov7670_g_register, | 1534 | .g_register = ov7670_g_register, |
@@ -1442,11 +1537,13 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { | |||
1442 | }; | 1537 | }; |
1443 | 1538 | ||
1444 | static const struct v4l2_subdev_video_ops ov7670_video_ops = { | 1539 | static const struct v4l2_subdev_video_ops ov7670_video_ops = { |
1445 | .enum_fmt = ov7670_enum_fmt, | 1540 | .enum_mbus_fmt = ov7670_enum_mbus_fmt, |
1446 | .try_fmt = ov7670_try_fmt, | 1541 | .try_mbus_fmt = ov7670_try_mbus_fmt, |
1447 | .s_fmt = ov7670_s_fmt, | 1542 | .s_mbus_fmt = ov7670_s_mbus_fmt, |
1448 | .s_parm = ov7670_s_parm, | 1543 | .s_parm = ov7670_s_parm, |
1449 | .g_parm = ov7670_g_parm, | 1544 | .g_parm = ov7670_g_parm, |
1545 | .enum_frameintervals = ov7670_enum_frameintervals, | ||
1546 | .enum_framesizes = ov7670_enum_framesizes, | ||
1450 | }; | 1547 | }; |
1451 | 1548 | ||
1452 | static const struct v4l2_subdev_ops ov7670_ops = { | 1549 | static const struct v4l2_subdev_ops ov7670_ops = { |
@@ -1461,7 +1558,6 @@ static int ov7670_probe(struct i2c_client *client, | |||
1461 | { | 1558 | { |
1462 | struct v4l2_subdev *sd; | 1559 | struct v4l2_subdev *sd; |
1463 | struct ov7670_info *info; | 1560 | struct ov7670_info *info; |
1464 | int ret; | ||
1465 | 1561 | ||
1466 | info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL); | 1562 | info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL); |
1467 | if (info == NULL) | 1563 | if (info == NULL) |
@@ -1469,22 +1565,6 @@ static int ov7670_probe(struct i2c_client *client, | |||
1469 | sd = &info->sd; | 1565 | sd = &info->sd; |
1470 | v4l2_i2c_subdev_init(sd, client, &ov7670_ops); | 1566 | v4l2_i2c_subdev_init(sd, client, &ov7670_ops); |
1471 | 1567 | ||
1472 | /* Make sure it's an ov7670 */ | ||
1473 | ret = ov7670_detect(sd); | ||
1474 | if (ret) { | ||
1475 | v4l_dbg(1, debug, client, | ||
1476 | "chip found @ 0x%x (%s) is not an ov7670 chip.\n", | ||
1477 | client->addr << 1, client->adapter->name); | ||
1478 | kfree(info); | ||
1479 | return ret; | ||
1480 | } | ||
1481 | v4l_info(client, "chip found @ 0x%02x (%s)\n", | ||
1482 | client->addr << 1, client->adapter->name); | ||
1483 | |||
1484 | info->fmt = &ov7670_formats[0]; | ||
1485 | info->sat = 128; /* Review this */ | ||
1486 | info->clkrc = 1; /* 30fps */ | ||
1487 | |||
1488 | return 0; | 1568 | return 0; |
1489 | } | 1569 | } |
1490 | 1570 | ||
@@ -1504,9 +1584,25 @@ static const struct i2c_device_id ov7670_id[] = { | |||
1504 | }; | 1584 | }; |
1505 | MODULE_DEVICE_TABLE(i2c, ov7670_id); | 1585 | MODULE_DEVICE_TABLE(i2c, ov7670_id); |
1506 | 1586 | ||
1507 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 1587 | static struct i2c_driver ov7670_driver = { |
1508 | .name = "ov7670", | 1588 | .driver = { |
1509 | .probe = ov7670_probe, | 1589 | .owner = THIS_MODULE, |
1510 | .remove = ov7670_remove, | 1590 | .name = "ov7670", |
1511 | .id_table = ov7670_id, | 1591 | }, |
1592 | .probe = ov7670_probe, | ||
1593 | .remove = ov7670_remove, | ||
1594 | .id_table = ov7670_id, | ||
1512 | }; | 1595 | }; |
1596 | |||
1597 | static __init int init_ov7670(void) | ||
1598 | { | ||
1599 | return i2c_add_driver(&ov7670_driver); | ||
1600 | } | ||
1601 | |||
1602 | static __exit void exit_ov7670(void) | ||
1603 | { | ||
1604 | i2c_del_driver(&ov7670_driver); | ||
1605 | } | ||
1606 | |||
1607 | module_init(init_ov7670); | ||
1608 | module_exit(exit_ov7670); | ||
diff --git a/drivers/media/video/ov7670.h b/drivers/media/video/ov7670.h new file mode 100644 index 00000000000..b133bc12303 --- /dev/null +++ b/drivers/media/video/ov7670.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * A V4L2 driver for OmniVision OV7670 cameras. | ||
3 | * | ||
4 | * Copyright 2010 One Laptop Per Child | ||
5 | * | ||
6 | * This file may be distributed under the terms of the GNU General | ||
7 | * Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OV7670_H | ||
11 | #define __OV7670_H | ||
12 | |||
13 | struct ov7670_config { | ||
14 | int min_width; /* Filter out smaller sizes */ | ||
15 | int min_height; /* Filter out smaller sizes */ | ||
16 | int clock_speed; /* External clock speed (MHz) */ | ||
17 | bool use_smbus; /* Use smbus I/O instead of I2C */ | ||
18 | }; | ||
19 | |||
20 | #endif | ||
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 25eb5d637ee..a84b770352f 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -599,7 +599,7 @@ static int ov772x_reset(struct i2c_client *client) | |||
599 | 599 | ||
600 | static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | 600 | static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) |
601 | { | 601 | { |
602 | struct i2c_client *client = sd->priv; | 602 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
603 | struct ov772x_priv *priv = to_ov772x(client); | 603 | struct ov772x_priv *priv = to_ov772x(client); |
604 | 604 | ||
605 | if (!enable) { | 605 | if (!enable) { |
@@ -645,7 +645,7 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) | |||
645 | 645 | ||
646 | static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 646 | static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
647 | { | 647 | { |
648 | struct i2c_client *client = sd->priv; | 648 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
649 | struct ov772x_priv *priv = to_ov772x(client); | 649 | struct ov772x_priv *priv = to_ov772x(client); |
650 | 650 | ||
651 | switch (ctrl->id) { | 651 | switch (ctrl->id) { |
@@ -664,7 +664,7 @@ static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
664 | 664 | ||
665 | static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 665 | static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
666 | { | 666 | { |
667 | struct i2c_client *client = sd->priv; | 667 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
668 | struct ov772x_priv *priv = to_ov772x(client); | 668 | struct ov772x_priv *priv = to_ov772x(client); |
669 | int ret = 0; | 669 | int ret = 0; |
670 | u8 val; | 670 | u8 val; |
@@ -715,7 +715,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
715 | static int ov772x_g_chip_ident(struct v4l2_subdev *sd, | 715 | static int ov772x_g_chip_ident(struct v4l2_subdev *sd, |
716 | struct v4l2_dbg_chip_ident *id) | 716 | struct v4l2_dbg_chip_ident *id) |
717 | { | 717 | { |
718 | struct i2c_client *client = sd->priv; | 718 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
719 | struct ov772x_priv *priv = to_ov772x(client); | 719 | struct ov772x_priv *priv = to_ov772x(client); |
720 | 720 | ||
721 | id->ident = priv->model; | 721 | id->ident = priv->model; |
@@ -728,7 +728,7 @@ static int ov772x_g_chip_ident(struct v4l2_subdev *sd, | |||
728 | static int ov772x_g_register(struct v4l2_subdev *sd, | 728 | static int ov772x_g_register(struct v4l2_subdev *sd, |
729 | struct v4l2_dbg_register *reg) | 729 | struct v4l2_dbg_register *reg) |
730 | { | 730 | { |
731 | struct i2c_client *client = sd->priv; | 731 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
732 | int ret; | 732 | int ret; |
733 | 733 | ||
734 | reg->size = 1; | 734 | reg->size = 1; |
@@ -747,7 +747,7 @@ static int ov772x_g_register(struct v4l2_subdev *sd, | |||
747 | static int ov772x_s_register(struct v4l2_subdev *sd, | 747 | static int ov772x_s_register(struct v4l2_subdev *sd, |
748 | struct v4l2_dbg_register *reg) | 748 | struct v4l2_dbg_register *reg) |
749 | { | 749 | { |
750 | struct i2c_client *client = sd->priv; | 750 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
751 | 751 | ||
752 | if (reg->reg > 0xff || | 752 | if (reg->reg > 0xff || |
753 | reg->val > 0xff) | 753 | reg->val > 0xff) |
@@ -954,7 +954,7 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
954 | static int ov772x_g_fmt(struct v4l2_subdev *sd, | 954 | static int ov772x_g_fmt(struct v4l2_subdev *sd, |
955 | struct v4l2_mbus_framefmt *mf) | 955 | struct v4l2_mbus_framefmt *mf) |
956 | { | 956 | { |
957 | struct i2c_client *client = sd->priv; | 957 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
958 | struct ov772x_priv *priv = to_ov772x(client); | 958 | struct ov772x_priv *priv = to_ov772x(client); |
959 | 959 | ||
960 | if (!priv->win || !priv->cfmt) { | 960 | if (!priv->win || !priv->cfmt) { |
@@ -977,7 +977,7 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd, | |||
977 | static int ov772x_s_fmt(struct v4l2_subdev *sd, | 977 | static int ov772x_s_fmt(struct v4l2_subdev *sd, |
978 | struct v4l2_mbus_framefmt *mf) | 978 | struct v4l2_mbus_framefmt *mf) |
979 | { | 979 | { |
980 | struct i2c_client *client = sd->priv; | 980 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
981 | struct ov772x_priv *priv = to_ov772x(client); | 981 | struct ov772x_priv *priv = to_ov772x(client); |
982 | int ret = ov772x_set_params(client, &mf->width, &mf->height, | 982 | int ret = ov772x_set_params(client, &mf->width, &mf->height, |
983 | mf->code); | 983 | mf->code); |
@@ -991,7 +991,7 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, | |||
991 | static int ov772x_try_fmt(struct v4l2_subdev *sd, | 991 | static int ov772x_try_fmt(struct v4l2_subdev *sd, |
992 | struct v4l2_mbus_framefmt *mf) | 992 | struct v4l2_mbus_framefmt *mf) |
993 | { | 993 | { |
994 | struct i2c_client *client = sd->priv; | 994 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
995 | struct ov772x_priv *priv = to_ov772x(client); | 995 | struct ov772x_priv *priv = to_ov772x(client); |
996 | const struct ov772x_win_size *win; | 996 | const struct ov772x_win_size *win; |
997 | int i; | 997 | int i; |
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index 40cdfab74cc..99e9e1d3c83 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c | |||
@@ -308,7 +308,7 @@ static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd) | |||
308 | /* Get status of additional camera capabilities */ | 308 | /* Get status of additional camera capabilities */ |
309 | static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 309 | static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
310 | { | 310 | { |
311 | struct i2c_client *client = sd->priv; | 311 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
312 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), | 312 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), |
313 | struct ov9640_priv, subdev); | 313 | struct ov9640_priv, subdev); |
314 | 314 | ||
@@ -326,7 +326,7 @@ static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
326 | /* Set status of additional camera capabilities */ | 326 | /* Set status of additional camera capabilities */ |
327 | static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 327 | static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
328 | { | 328 | { |
329 | struct i2c_client *client = sd->priv; | 329 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
330 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), | 330 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), |
331 | struct ov9640_priv, subdev); | 331 | struct ov9640_priv, subdev); |
332 | 332 | ||
@@ -360,7 +360,7 @@ static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
360 | static int ov9640_g_chip_ident(struct v4l2_subdev *sd, | 360 | static int ov9640_g_chip_ident(struct v4l2_subdev *sd, |
361 | struct v4l2_dbg_chip_ident *id) | 361 | struct v4l2_dbg_chip_ident *id) |
362 | { | 362 | { |
363 | struct i2c_client *client = sd->priv; | 363 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
364 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), | 364 | struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), |
365 | struct ov9640_priv, subdev); | 365 | struct ov9640_priv, subdev); |
366 | 366 | ||
@@ -374,7 +374,7 @@ static int ov9640_g_chip_ident(struct v4l2_subdev *sd, | |||
374 | static int ov9640_get_register(struct v4l2_subdev *sd, | 374 | static int ov9640_get_register(struct v4l2_subdev *sd, |
375 | struct v4l2_dbg_register *reg) | 375 | struct v4l2_dbg_register *reg) |
376 | { | 376 | { |
377 | struct i2c_client *client = sd->priv; | 377 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
378 | int ret; | 378 | int ret; |
379 | u8 val; | 379 | u8 val; |
380 | 380 | ||
@@ -395,7 +395,7 @@ static int ov9640_get_register(struct v4l2_subdev *sd, | |||
395 | static int ov9640_set_register(struct v4l2_subdev *sd, | 395 | static int ov9640_set_register(struct v4l2_subdev *sd, |
396 | struct v4l2_dbg_register *reg) | 396 | struct v4l2_dbg_register *reg) |
397 | { | 397 | { |
398 | struct i2c_client *client = sd->priv; | 398 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
399 | 399 | ||
400 | if (reg->reg & ~0xff || reg->val & ~0xff) | 400 | if (reg->reg & ~0xff || reg->val & ~0xff) |
401 | return -EINVAL; | 401 | return -EINVAL; |
@@ -558,7 +558,7 @@ static int ov9640_prog_dflt(struct i2c_client *client) | |||
558 | static int ov9640_s_fmt(struct v4l2_subdev *sd, | 558 | static int ov9640_s_fmt(struct v4l2_subdev *sd, |
559 | struct v4l2_mbus_framefmt *mf) | 559 | struct v4l2_mbus_framefmt *mf) |
560 | { | 560 | { |
561 | struct i2c_client *client = sd->priv; | 561 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
562 | struct ov9640_reg_alt alts = {0}; | 562 | struct ov9640_reg_alt alts = {0}; |
563 | enum v4l2_colorspace cspace; | 563 | enum v4l2_colorspace cspace; |
564 | enum v4l2_mbus_pixelcode code = mf->code; | 564 | enum v4l2_mbus_pixelcode code = mf->code; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 70ea578d626..bef202752cc 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -2082,20 +2082,13 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, | |||
2082 | return -EINVAL; | 2082 | return -EINVAL; |
2083 | } | 2083 | } |
2084 | 2084 | ||
2085 | /* Note how the 2nd and 3rd arguments are the same for | ||
2086 | * v4l2_i2c_new_subdev(). Why? | ||
2087 | * Well the 2nd argument is the module name to load, while the 3rd | ||
2088 | * argument is documented in the framework as being the "chipid" - | ||
2089 | * and every other place where I can find examples of this, the | ||
2090 | * "chipid" appears to just be the module name again. So here we | ||
2091 | * just do the same thing. */ | ||
2092 | if (i2ccnt == 1) { | 2085 | if (i2ccnt == 1) { |
2093 | pvr2_trace(PVR2_TRACE_INIT, | 2086 | pvr2_trace(PVR2_TRACE_INIT, |
2094 | "Module ID %u:" | 2087 | "Module ID %u:" |
2095 | " Setting up with specified i2c address 0x%x", | 2088 | " Setting up with specified i2c address 0x%x", |
2096 | mid, i2caddr[0]); | 2089 | mid, i2caddr[0]); |
2097 | sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, | 2090 | sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, |
2098 | fname, fname, | 2091 | NULL, fname, |
2099 | i2caddr[0], NULL); | 2092 | i2caddr[0], NULL); |
2100 | } else { | 2093 | } else { |
2101 | pvr2_trace(PVR2_TRACE_INIT, | 2094 | pvr2_trace(PVR2_TRACE_INIT, |
@@ -2103,7 +2096,7 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, | |||
2103 | " Setting up with address probe list", | 2096 | " Setting up with address probe list", |
2104 | mid); | 2097 | mid); |
2105 | sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, | 2098 | sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, |
2106 | fname, fname, | 2099 | NULL, fname, |
2107 | 0, i2caddr); | 2100 | 0, i2caddr); |
2108 | } | 2101 | } |
2109 | 2102 | ||
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig index 11980db22d3..8da42e4f1ba 100644 --- a/drivers/media/video/pwc/Kconfig +++ b/drivers/media/video/pwc/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_PWC | 1 | config USB_PWC |
2 | tristate "USB Philips Cameras" | 2 | tristate "USB Philips Cameras" |
3 | depends on VIDEO_V4L1 | 3 | depends on VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y or M here if you want to use one of these Philips & OEM | 5 | Say Y or M here if you want to use one of these Philips & OEM |
6 | webcams: | 6 | webcams: |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index f7f7e04cf48..6b8fbddc074 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -261,7 +261,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) | |||
261 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); | 261 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); |
262 | return ret; | 262 | return ret; |
263 | } | 263 | } |
264 | if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) | 264 | if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) |
265 | pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); | 265 | pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); |
266 | 266 | ||
267 | pdev->cmd_len = 3; | 267 | pdev->cmd_len = 3; |
@@ -321,7 +321,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i | |||
321 | if (ret < 0) | 321 | if (ret < 0) |
322 | return ret; | 322 | return ret; |
323 | 323 | ||
324 | if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | 324 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) |
325 | pwc_dec23_init(pdev, pdev->type, buf); | 325 | pwc_dec23_init(pdev, pdev->type, buf); |
326 | 326 | ||
327 | pdev->cmd_len = 13; | 327 | pdev->cmd_len = 13; |
@@ -356,7 +356,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i | |||
356 | fps = (frames / 5) - 1; | 356 | fps = (frames / 5) - 1; |
357 | 357 | ||
358 | /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ | 358 | /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ |
359 | if (size == PSZ_VGA && frames == 5 && snapshot && pdev->vpalette == VIDEO_PALETTE_RAW) | 359 | if (size == PSZ_VGA && frames == 5 && snapshot && pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
360 | { | 360 | { |
361 | /* Only available in case the raw palette is selected or | 361 | /* Only available in case the raw palette is selected or |
362 | we have the decompressor available. This mode is | 362 | we have the decompressor available. This mode is |
@@ -394,7 +394,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i | |||
394 | if (ret < 0) | 394 | if (ret < 0) |
395 | return ret; | 395 | return ret; |
396 | 396 | ||
397 | if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | 397 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) |
398 | pwc_dec23_init(pdev, pdev->type, buf); | 398 | pwc_dec23_init(pdev, pdev->type, buf); |
399 | 399 | ||
400 | pdev->cmd_len = 12; | 400 | pdev->cmd_len = 12; |
@@ -429,7 +429,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame | |||
429 | { | 429 | { |
430 | int ret, size; | 430 | int ret, size; |
431 | 431 | ||
432 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); | 432 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt); |
433 | size = pwc_decode_size(pdev, width, height); | 433 | size = pwc_decode_size(pdev, width, height); |
434 | if (size < 0) { | 434 | if (size < 0) { |
435 | PWC_DEBUG_MODULE("Could not find suitable size.\n"); | 435 | PWC_DEBUG_MODULE("Could not find suitable size.\n"); |
@@ -519,13 +519,13 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev) | |||
519 | { | 519 | { |
520 | int i, factor = 0; | 520 | int i, factor = 0; |
521 | 521 | ||
522 | /* for PALETTE_YUV420P */ | 522 | /* for V4L2_PIX_FMT_YUV420 */ |
523 | switch(pdev->vpalette) | 523 | switch (pdev->pixfmt) { |
524 | { | 524 | case V4L2_PIX_FMT_YUV420: |
525 | case VIDEO_PALETTE_YUV420P: | ||
526 | factor = 6; | 525 | factor = 6; |
527 | break; | 526 | break; |
528 | case VIDEO_PALETTE_RAW: | 527 | case V4L2_PIX_FMT_PWC1: |
528 | case V4L2_PIX_FMT_PWC2: | ||
529 | factor = 6; /* can be uncompressed YUV420P */ | 529 | factor = 6; /* can be uncompressed YUV420P */ |
530 | break; | 530 | break; |
531 | } | 531 | } |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index aea7e224cef..e62beb4efdb 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -163,7 +163,7 @@ static const struct v4l2_file_operations pwc_fops = { | |||
163 | .read = pwc_video_read, | 163 | .read = pwc_video_read, |
164 | .poll = pwc_video_poll, | 164 | .poll = pwc_video_poll, |
165 | .mmap = pwc_video_mmap, | 165 | .mmap = pwc_video_mmap, |
166 | .ioctl = pwc_video_ioctl, | 166 | .unlocked_ioctl = pwc_video_ioctl, |
167 | }; | 167 | }; |
168 | static struct video_device pwc_template = { | 168 | static struct video_device pwc_template = { |
169 | .name = "Philips Webcam", /* Filled in later */ | 169 | .name = "Philips Webcam", /* Filled in later */ |
@@ -1247,8 +1247,8 @@ static int pwc_video_close(struct file *file) | |||
1247 | 1247 | ||
1248 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); | 1248 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
1249 | 1249 | ||
1250 | lock_kernel(); | ||
1251 | pdev = video_get_drvdata(vdev); | 1250 | pdev = video_get_drvdata(vdev); |
1251 | mutex_lock(&pdev->modlock); | ||
1252 | if (pdev->vopen == 0) | 1252 | if (pdev->vopen == 0) |
1253 | PWC_DEBUG_MODULE("video_close() called on closed device?\n"); | 1253 | PWC_DEBUG_MODULE("video_close() called on closed device?\n"); |
1254 | 1254 | ||
@@ -1286,7 +1286,7 @@ static int pwc_video_close(struct file *file) | |||
1286 | if (device_hint[hint].pdev == pdev) | 1286 | if (device_hint[hint].pdev == pdev) |
1287 | device_hint[hint].pdev = NULL; | 1287 | device_hint[hint].pdev = NULL; |
1288 | } | 1288 | } |
1289 | unlock_kernel(); | 1289 | mutex_unlock(&pdev->modlock); |
1290 | 1290 | ||
1291 | return 0; | 1291 | return 0; |
1292 | } | 1292 | } |
@@ -1365,7 +1365,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, | |||
1365 | } | 1365 | } |
1366 | 1366 | ||
1367 | PWC_DEBUG_READ("Copying data to user space.\n"); | 1367 | PWC_DEBUG_READ("Copying data to user space.\n"); |
1368 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 1368 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
1369 | bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); | 1369 | bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1370 | else | 1370 | else |
1371 | bytes_to_read = pdev->view.size; | 1371 | bytes_to_read = pdev->view.size; |
@@ -1800,13 +1800,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1800 | } | 1800 | } |
1801 | 1801 | ||
1802 | pdev->vdev->release = video_device_release; | 1802 | pdev->vdev->release = video_device_release; |
1803 | rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | ||
1804 | if (rc < 0) { | ||
1805 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | ||
1806 | goto err_video_release; | ||
1807 | } | ||
1808 | |||
1809 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); | ||
1810 | 1803 | ||
1811 | /* occupy slot */ | 1804 | /* occupy slot */ |
1812 | if (hint < MAX_DEV_HINTS) | 1805 | if (hint < MAX_DEV_HINTS) |
@@ -1814,14 +1807,22 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1814 | 1807 | ||
1815 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); | 1808 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); |
1816 | usb_set_intfdata(intf, pdev); | 1809 | usb_set_intfdata(intf, pdev); |
1817 | rc = pwc_create_sysfs_files(pdev->vdev); | ||
1818 | if (rc) | ||
1819 | goto err_video_unreg; | ||
1820 | 1810 | ||
1821 | /* Set the leds off */ | 1811 | /* Set the leds off */ |
1822 | pwc_set_leds(pdev, 0, 0); | 1812 | pwc_set_leds(pdev, 0, 0); |
1823 | pwc_camera_power(pdev, 0); | 1813 | pwc_camera_power(pdev, 0); |
1824 | 1814 | ||
1815 | rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | ||
1816 | if (rc < 0) { | ||
1817 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | ||
1818 | goto err_video_release; | ||
1819 | } | ||
1820 | rc = pwc_create_sysfs_files(pdev->vdev); | ||
1821 | if (rc) | ||
1822 | goto err_video_unreg; | ||
1823 | |||
1824 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); | ||
1825 | |||
1825 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 1826 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
1826 | /* register webcam snapshot button input device */ | 1827 | /* register webcam snapshot button input device */ |
1827 | pdev->button_dev = input_allocate_device(); | 1828 | pdev->button_dev = input_allocate_device(); |
@@ -1871,8 +1872,8 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1871 | struct pwc_device *pdev; | 1872 | struct pwc_device *pdev; |
1872 | int hint; | 1873 | int hint; |
1873 | 1874 | ||
1874 | lock_kernel(); | ||
1875 | pdev = usb_get_intfdata (intf); | 1875 | pdev = usb_get_intfdata (intf); |
1876 | mutex_lock(&pdev->modlock); | ||
1876 | usb_set_intfdata (intf, NULL); | 1877 | usb_set_intfdata (intf, NULL); |
1877 | if (pdev == NULL) { | 1878 | if (pdev == NULL) { |
1878 | PWC_ERROR("pwc_disconnect() Called without private pointer.\n"); | 1879 | PWC_ERROR("pwc_disconnect() Called without private pointer.\n"); |
@@ -1897,9 +1898,7 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1897 | wake_up_interruptible(&pdev->frameq); | 1898 | wake_up_interruptible(&pdev->frameq); |
1898 | /* Wait until device is closed */ | 1899 | /* Wait until device is closed */ |
1899 | if (pdev->vopen) { | 1900 | if (pdev->vopen) { |
1900 | mutex_lock(&pdev->modlock); | ||
1901 | pdev->unplugged = 1; | 1901 | pdev->unplugged = 1; |
1902 | mutex_unlock(&pdev->modlock); | ||
1903 | pwc_iso_stop(pdev); | 1902 | pwc_iso_stop(pdev); |
1904 | } else { | 1903 | } else { |
1905 | /* Device is closed, so we can safely unregister it */ | 1904 | /* Device is closed, so we can safely unregister it */ |
@@ -1913,7 +1912,7 @@ disconnect_out: | |||
1913 | device_hint[hint].pdev = NULL; | 1912 | device_hint[hint].pdev = NULL; |
1914 | } | 1913 | } |
1915 | 1914 | ||
1916 | unlock_kernel(); | 1915 | mutex_unlock(&pdev->modlock); |
1917 | } | 1916 | } |
1918 | 1917 | ||
1919 | 1918 | ||
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 589c687439d..6af5bb53835 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c | |||
@@ -47,7 +47,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) | |||
47 | you don't have the decompressor loaded or use RAW mode, | 47 | you don't have the decompressor loaded or use RAW mode, |
48 | the maximum viewable size is smaller. | 48 | the maximum viewable size is smaller. |
49 | */ | 49 | */ |
50 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 50 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
51 | { | 51 | { |
52 | if (width > pdev->abs_max.x || height > pdev->abs_max.y) | 52 | if (width > pdev->abs_max.x || height > pdev->abs_max.y) |
53 | { | 53 | { |
@@ -123,7 +123,7 @@ void pwc_construct(struct pwc_device *pdev) | |||
123 | pdev->frame_header_size = 0; | 123 | pdev->frame_header_size = 0; |
124 | pdev->frame_trailer_size = 0; | 124 | pdev->frame_trailer_size = 0; |
125 | } | 125 | } |
126 | pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ | 126 | pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ |
127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; | 127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; |
128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; | 128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; |
129 | /* length of image, in YUV format; always allocate enough memory. */ | 129 | /* length of image, in YUV format; always allocate enough memory. */ |
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index 5d82028ef94..3b73f295f03 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/media/video/pwc/pwc-uncompress.c | |||
@@ -54,7 +54,7 @@ int pwc_decompress(struct pwc_device *pdev) | |||
54 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ | 54 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ |
55 | 55 | ||
56 | /* Raw format; that's easy... */ | 56 | /* Raw format; that's easy... */ |
57 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 57 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
58 | { | 58 | { |
59 | struct pwc_raw_frame *raw_frame = image; | 59 | struct pwc_raw_frame *raw_frame = image; |
60 | raw_frame->type = cpu_to_le16(pdev->type); | 60 | raw_frame->type = cpu_to_le16(pdev->type); |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 62d89b3113a..7061a03f5cf 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -216,7 +216,7 @@ static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_forma | |||
216 | f->fmt.pix.width = pdev->view.x; | 216 | f->fmt.pix.width = pdev->view.x; |
217 | f->fmt.pix.height = pdev->view.y; | 217 | f->fmt.pix.height = pdev->view.y; |
218 | f->fmt.pix.field = V4L2_FIELD_NONE; | 218 | f->fmt.pix.field = V4L2_FIELD_NONE; |
219 | if (pdev->vpalette == VIDEO_PALETTE_YUV420P) { | 219 | if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) { |
220 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; | 220 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; |
221 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; | 221 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; |
222 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | 222 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; |
@@ -304,10 +304,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
304 | fps = pdev->vframes; | 304 | fps = pdev->vframes; |
305 | } | 305 | } |
306 | 306 | ||
307 | if (pixelformat == V4L2_PIX_FMT_YUV420) | 307 | if (pixelformat != V4L2_PIX_FMT_YUV420 && |
308 | pdev->vpalette = VIDEO_PALETTE_YUV420P; | 308 | pixelformat != V4L2_PIX_FMT_PWC1 && |
309 | else | 309 | pixelformat != V4L2_PIX_FMT_PWC2) |
310 | pdev->vpalette = VIDEO_PALETTE_RAW; | 310 | return -EINVAL; |
311 | 311 | ||
312 | PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " | 312 | PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " |
313 | "compression=%d snapshot=%d format=%c%c%c%c\n", | 313 | "compression=%d snapshot=%d format=%c%c%c%c\n", |
@@ -330,6 +330,8 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
330 | if (ret) | 330 | if (ret) |
331 | return ret; | 331 | return ret; |
332 | 332 | ||
333 | pdev->pixfmt = pixelformat; | ||
334 | |||
333 | pwc_vidioc_fill_fmt(pdev, f); | 335 | pwc_vidioc_fill_fmt(pdev, f); |
334 | 336 | ||
335 | return 0; | 337 | return 0; |
@@ -357,152 +359,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
357 | 359 | ||
358 | 360 | ||
359 | switch (cmd) { | 361 | switch (cmd) { |
360 | /* Query cabapilities */ | 362 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
361 | case VIDIOCGCAP: | ||
362 | { | ||
363 | struct video_capability *caps = arg; | ||
364 | |||
365 | strcpy(caps->name, vdev->name); | ||
366 | caps->type = VID_TYPE_CAPTURE; | ||
367 | caps->channels = 1; | ||
368 | caps->audios = 1; | ||
369 | caps->minwidth = pdev->view_min.x; | ||
370 | caps->minheight = pdev->view_min.y; | ||
371 | caps->maxwidth = pdev->view_max.x; | ||
372 | caps->maxheight = pdev->view_max.y; | ||
373 | break; | ||
374 | } | ||
375 | |||
376 | /* Channel functions (simulate 1 channel) */ | ||
377 | case VIDIOCGCHAN: | ||
378 | { | ||
379 | struct video_channel *v = arg; | ||
380 | |||
381 | if (v->channel != 0) | ||
382 | return -EINVAL; | ||
383 | v->flags = 0; | ||
384 | v->tuners = 0; | ||
385 | v->type = VIDEO_TYPE_CAMERA; | ||
386 | strcpy(v->name, "Webcam"); | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | case VIDIOCSCHAN: | ||
391 | { | ||
392 | /* The spec says the argument is an integer, but | ||
393 | the bttv driver uses a video_channel arg, which | ||
394 | makes sense becasue it also has the norm flag. | ||
395 | */ | ||
396 | struct video_channel *v = arg; | ||
397 | if (v->channel != 0) | ||
398 | return -EINVAL; | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | |||
403 | /* Picture functions; contrast etc. */ | ||
404 | case VIDIOCGPICT: | ||
405 | { | ||
406 | struct video_picture *p = arg; | ||
407 | int val; | ||
408 | |||
409 | val = pwc_get_brightness(pdev); | ||
410 | if (val >= 0) | ||
411 | p->brightness = (val<<9); | ||
412 | else | ||
413 | p->brightness = 0xffff; | ||
414 | val = pwc_get_contrast(pdev); | ||
415 | if (val >= 0) | ||
416 | p->contrast = (val<<10); | ||
417 | else | ||
418 | p->contrast = 0xffff; | ||
419 | /* Gamma, Whiteness, what's the difference? :) */ | ||
420 | val = pwc_get_gamma(pdev); | ||
421 | if (val >= 0) | ||
422 | p->whiteness = (val<<11); | ||
423 | else | ||
424 | p->whiteness = 0xffff; | ||
425 | if (pwc_get_saturation(pdev, &val)<0) | ||
426 | p->colour = 0xffff; | ||
427 | else | ||
428 | p->colour = 32768 + val * 327; | ||
429 | p->depth = 24; | ||
430 | p->palette = pdev->vpalette; | ||
431 | p->hue = 0xFFFF; /* N/A */ | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | case VIDIOCSPICT: | ||
436 | { | ||
437 | struct video_picture *p = arg; | ||
438 | /* | ||
439 | * FIXME: Suppose we are mid read | ||
440 | ANSWER: No problem: the firmware of the camera | ||
441 | can handle brightness/contrast/etc | ||
442 | changes at _any_ time, and the palette | ||
443 | is used exactly once in the uncompress | ||
444 | routine. | ||
445 | */ | ||
446 | pwc_set_brightness(pdev, p->brightness); | ||
447 | pwc_set_contrast(pdev, p->contrast); | ||
448 | pwc_set_gamma(pdev, p->whiteness); | ||
449 | pwc_set_saturation(pdev, (p->colour-32768)/327); | ||
450 | if (p->palette && p->palette != pdev->vpalette) { | ||
451 | switch (p->palette) { | ||
452 | case VIDEO_PALETTE_YUV420P: | ||
453 | case VIDEO_PALETTE_RAW: | ||
454 | pdev->vpalette = p->palette; | ||
455 | return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
456 | break; | ||
457 | default: | ||
458 | return -EINVAL; | ||
459 | break; | ||
460 | } | ||
461 | } | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | /* Window/size parameters */ | ||
466 | case VIDIOCGWIN: | ||
467 | { | ||
468 | struct video_window *vw = arg; | ||
469 | |||
470 | vw->x = 0; | ||
471 | vw->y = 0; | ||
472 | vw->width = pdev->view.x; | ||
473 | vw->height = pdev->view.y; | ||
474 | vw->chromakey = 0; | ||
475 | vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | | ||
476 | (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); | ||
477 | break; | ||
478 | } | ||
479 | |||
480 | case VIDIOCSWIN: | ||
481 | { | ||
482 | struct video_window *vw = arg; | ||
483 | int fps, snapshot, ret; | ||
484 | |||
485 | fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; | ||
486 | snapshot = vw->flags & PWC_FPS_SNAPSHOT; | ||
487 | if (fps == 0) | ||
488 | fps = pdev->vframes; | ||
489 | if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) | ||
490 | return 0; | ||
491 | ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); | ||
492 | if (ret) | ||
493 | return ret; | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | /* We don't have overlay support (yet) */ | ||
498 | case VIDIOCGFBUF: | ||
499 | { | ||
500 | struct video_buffer *vb = arg; | ||
501 | |||
502 | memset(vb,0,sizeof(*vb)); | ||
503 | break; | ||
504 | } | ||
505 | |||
506 | /* mmap() functions */ | 363 | /* mmap() functions */ |
507 | case VIDIOCGMBUF: | 364 | case VIDIOCGMBUF: |
508 | { | 365 | { |
@@ -517,164 +374,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
517 | vm->offsets[i] = i * pdev->len_per_image; | 374 | vm->offsets[i] = i * pdev->len_per_image; |
518 | break; | 375 | break; |
519 | } | 376 | } |
520 | 377 | #endif | |
521 | case VIDIOCMCAPTURE: | ||
522 | { | ||
523 | /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ | ||
524 | struct video_mmap *vm = arg; | ||
525 | |||
526 | PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); | ||
527 | if (vm->frame < 0 || vm->frame >= pwc_mbufs) | ||
528 | return -EINVAL; | ||
529 | |||
530 | /* xawtv is nasty. It probes the available palettes | ||
531 | by setting a very small image size and trying | ||
532 | various palettes... The driver doesn't support | ||
533 | such small images, so I'm working around it. | ||
534 | */ | ||
535 | if (vm->format) | ||
536 | { | ||
537 | switch (vm->format) | ||
538 | { | ||
539 | case VIDEO_PALETTE_YUV420P: | ||
540 | case VIDEO_PALETTE_RAW: | ||
541 | break; | ||
542 | default: | ||
543 | return -EINVAL; | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && | ||
549 | (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { | ||
550 | int ret; | ||
551 | |||
552 | PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); | ||
553 | ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
554 | if (ret) | ||
555 | return ret; | ||
556 | } /* ... size mismatch */ | ||
557 | |||
558 | /* FIXME: should we lock here? */ | ||
559 | if (pdev->image_used[vm->frame]) | ||
560 | return -EBUSY; /* buffer wasn't available. Bummer */ | ||
561 | pdev->image_used[vm->frame] = 1; | ||
562 | |||
563 | /* Okay, we're done here. In the SYNC call we wait until a | ||
564 | frame comes available, then expand image into the given | ||
565 | buffer. | ||
566 | In contrast to the CPiA cam the Philips cams deliver a | ||
567 | constant stream, almost like a grabber card. Also, | ||
568 | we have separate buffers for the rawdata and the image, | ||
569 | meaning we can nearly always expand into the requested buffer. | ||
570 | */ | ||
571 | PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n"); | ||
572 | break; | ||
573 | } | ||
574 | |||
575 | case VIDIOCSYNC: | ||
576 | { | ||
577 | /* The doc says: "Whenever a buffer is used it should | ||
578 | call VIDIOCSYNC to free this frame up and continue." | ||
579 | |||
580 | The only odd thing about this whole procedure is | ||
581 | that MCAPTURE flags the buffer as "in use", and | ||
582 | SYNC immediately unmarks it, while it isn't | ||
583 | after SYNC that you know that the buffer actually | ||
584 | got filled! So you better not start a CAPTURE in | ||
585 | the same frame immediately (use double buffering). | ||
586 | This is not a problem for this cam, since it has | ||
587 | extra intermediate buffers, but a hardware | ||
588 | grabber card will then overwrite the buffer | ||
589 | you're working on. | ||
590 | */ | ||
591 | int *mbuf = arg; | ||
592 | int ret; | ||
593 | |||
594 | PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf); | ||
595 | |||
596 | /* bounds check */ | ||
597 | if (*mbuf < 0 || *mbuf >= pwc_mbufs) | ||
598 | return -EINVAL; | ||
599 | /* check if this buffer was requested anyway */ | ||
600 | if (pdev->image_used[*mbuf] == 0) | ||
601 | return -EINVAL; | ||
602 | |||
603 | /* Add ourselves to the frame wait-queue. | ||
604 | |||
605 | FIXME: needs auditing for safety. | ||
606 | QUESTION: In what respect? I think that using the | ||
607 | frameq is safe now. | ||
608 | */ | ||
609 | add_wait_queue(&pdev->frameq, &wait); | ||
610 | while (pdev->full_frames == NULL) { | ||
611 | /* Check for unplugged/etc. here */ | ||
612 | if (pdev->error_status) { | ||
613 | remove_wait_queue(&pdev->frameq, &wait); | ||
614 | set_current_state(TASK_RUNNING); | ||
615 | return -pdev->error_status; | ||
616 | } | ||
617 | |||
618 | if (signal_pending(current)) { | ||
619 | remove_wait_queue(&pdev->frameq, &wait); | ||
620 | set_current_state(TASK_RUNNING); | ||
621 | return -ERESTARTSYS; | ||
622 | } | ||
623 | schedule(); | ||
624 | set_current_state(TASK_INTERRUPTIBLE); | ||
625 | } | ||
626 | remove_wait_queue(&pdev->frameq, &wait); | ||
627 | set_current_state(TASK_RUNNING); | ||
628 | |||
629 | /* The frame is ready. Expand in the image buffer | ||
630 | requested by the user. I don't care if you | ||
631 | mmap() 5 buffers and request data in this order: | ||
632 | buffer 4 2 3 0 1 2 3 0 4 3 1 . . . | ||
633 | Grabber hardware may not be so forgiving. | ||
634 | */ | ||
635 | PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n"); | ||
636 | pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ | ||
637 | /* Decompress, etc */ | ||
638 | ret = pwc_handle_frame(pdev); | ||
639 | pdev->image_used[*mbuf] = 0; | ||
640 | if (ret) | ||
641 | return -EFAULT; | ||
642 | break; | ||
643 | } | ||
644 | |||
645 | case VIDIOCGAUDIO: | ||
646 | { | ||
647 | struct video_audio *v = arg; | ||
648 | |||
649 | strcpy(v->name, "Microphone"); | ||
650 | v->audio = -1; /* unknown audio minor */ | ||
651 | v->flags = 0; | ||
652 | v->mode = VIDEO_SOUND_MONO; | ||
653 | v->volume = 0; | ||
654 | v->bass = 0; | ||
655 | v->treble = 0; | ||
656 | v->balance = 0x8000; | ||
657 | v->step = 1; | ||
658 | break; | ||
659 | } | ||
660 | |||
661 | case VIDIOCSAUDIO: | ||
662 | { | ||
663 | /* Dummy: nothing can be set */ | ||
664 | break; | ||
665 | } | ||
666 | |||
667 | case VIDIOCGUNIT: | ||
668 | { | ||
669 | struct video_unit *vu = arg; | ||
670 | |||
671 | vu->video = pdev->vdev->minor & 0x3F; | ||
672 | vu->audio = -1; /* not known yet */ | ||
673 | vu->vbi = -1; | ||
674 | vu->radio = -1; | ||
675 | vu->teletext = -1; | ||
676 | break; | ||
677 | } | ||
678 | 378 | ||
679 | /* V4L2 Layer */ | 379 | /* V4L2 Layer */ |
680 | case VIDIOC_QUERYCAP: | 380 | case VIDIOC_QUERYCAP: |
@@ -1081,7 +781,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1081 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 781 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1082 | buf->index = index; | 782 | buf->index = index; |
1083 | buf->m.offset = index * pdev->len_per_image; | 783 | buf->m.offset = index * pdev->len_per_image; |
1084 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 784 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
1085 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | 785 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1086 | else | 786 | else |
1087 | buf->bytesused = pdev->view.size; | 787 | buf->bytesused = pdev->view.size; |
@@ -1158,7 +858,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1158 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); | 858 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); |
1159 | 859 | ||
1160 | buf->index = pdev->fill_image; | 860 | buf->index = pdev->fill_image; |
1161 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 861 | if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) |
1162 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | 862 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1163 | else | 863 | else |
1164 | buf->bytesused = pdev->view.size; | 864 | buf->bytesused = pdev->view.size; |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index f1b20663295..36a9c83b5f5 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <asm/errno.h> | 36 | #include <asm/errno.h> |
37 | #include <linux/videodev.h> | 37 | #include <linux/videodev2.h> |
38 | #include <media/v4l2-common.h> | 38 | #include <media/v4l2-common.h> |
39 | #include <media/v4l2-ioctl.h> | 39 | #include <media/v4l2-ioctl.h> |
40 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 40 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
@@ -49,7 +49,7 @@ | |||
49 | #define PWC_MINOR 0 | 49 | #define PWC_MINOR 0 |
50 | #define PWC_EXTRAMINOR 12 | 50 | #define PWC_EXTRAMINOR 12 |
51 | #define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) | 51 | #define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) |
52 | #define PWC_VERSION "10.0.13" | 52 | #define PWC_VERSION "10.0.14" |
53 | #define PWC_NAME "pwc" | 53 | #define PWC_NAME "pwc" |
54 | #define PFX PWC_NAME ": " | 54 | #define PFX PWC_NAME ": " |
55 | 55 | ||
@@ -180,7 +180,7 @@ struct pwc_device | |||
180 | int vcinterface; /* video control interface */ | 180 | int vcinterface; /* video control interface */ |
181 | int valternate; /* alternate interface needed */ | 181 | int valternate; /* alternate interface needed */ |
182 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ | 182 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ |
183 | int vpalette; /* palette: 420P, RAW or RGBBAYER */ | 183 | int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or raw: _PWC1, _PWC2 */ |
184 | int vframe_count; /* received frames */ | 184 | int vframe_count; /* received frames */ |
185 | int vframes_dumped; /* counter for dumped frames */ | 185 | int vframes_dumped; /* counter for dumped frames */ |
186 | int vframes_error; /* frames received in error */ | 186 | int vframes_error; /* frames received in error */ |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 9de7d59916b..c143ed0a527 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -275,7 +275,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
275 | * This waits until this buffer is out of danger, i.e., until it is no | 275 | * This waits until this buffer is out of danger, i.e., until it is no |
276 | * longer in STATE_QUEUED or STATE_ACTIVE | 276 | * longer in STATE_QUEUED or STATE_ACTIVE |
277 | */ | 277 | */ |
278 | videobuf_waiton(&buf->vb, 0, 0); | 278 | videobuf_waiton(vq, &buf->vb, 0, 0); |
279 | videobuf_dma_unmap(vq->dev, dma); | 279 | videobuf_dma_unmap(vq->dev, dma); |
280 | videobuf_dma_free(dma); | 280 | videobuf_dma_free(dma); |
281 | 281 | ||
@@ -852,7 +852,7 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q, | |||
852 | */ | 852 | */ |
853 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, | 853 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, |
854 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 854 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
855 | sizeof(struct pxa_buffer), icd); | 855 | sizeof(struct pxa_buffer), icd, NULL); |
856 | } | 856 | } |
857 | 857 | ||
858 | static u32 mclk_get_divisor(struct platform_device *pdev, | 858 | static u32 mclk_get_divisor(struct platform_device *pdev, |
@@ -1539,7 +1539,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, | |||
1539 | return ret; | 1539 | return ret; |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | static int pxa_camera_reqbufs(struct soc_camera_file *icf, | 1542 | static int pxa_camera_reqbufs(struct soc_camera_device *icd, |
1543 | struct v4l2_requestbuffers *p) | 1543 | struct v4l2_requestbuffers *p) |
1544 | { | 1544 | { |
1545 | int i; | 1545 | int i; |
@@ -1551,7 +1551,7 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf, | |||
1551 | * it hadn't triggered | 1551 | * it hadn't triggered |
1552 | */ | 1552 | */ |
1553 | for (i = 0; i < p->count; i++) { | 1553 | for (i = 0; i < p->count; i++) { |
1554 | struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], | 1554 | struct pxa_buffer *buf = container_of(icd->vb_vidq.bufs[i], |
1555 | struct pxa_buffer, vb); | 1555 | struct pxa_buffer, vb); |
1556 | buf->inwork = 0; | 1556 | buf->inwork = 0; |
1557 | INIT_LIST_HEAD(&buf->vb.queue); | 1557 | INIT_LIST_HEAD(&buf->vb.queue); |
@@ -1562,10 +1562,10 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf, | |||
1562 | 1562 | ||
1563 | static unsigned int pxa_camera_poll(struct file *file, poll_table *pt) | 1563 | static unsigned int pxa_camera_poll(struct file *file, poll_table *pt) |
1564 | { | 1564 | { |
1565 | struct soc_camera_file *icf = file->private_data; | 1565 | struct soc_camera_device *icd = file->private_data; |
1566 | struct pxa_buffer *buf; | 1566 | struct pxa_buffer *buf; |
1567 | 1567 | ||
1568 | buf = list_entry(icf->vb_vidq.stream.next, struct pxa_buffer, | 1568 | buf = list_entry(icd->vb_vidq.stream.next, struct pxa_buffer, |
1569 | vb.stream); | 1569 | vb.stream); |
1570 | 1570 | ||
1571 | poll_wait(file, &buf->vb.done, pt); | 1571 | poll_wait(file, &buf->vb.done, pt); |
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index ce78fff2342..d2fa2d43ff1 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c | |||
@@ -493,7 +493,7 @@ static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |||
493 | 493 | ||
494 | static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) | 494 | static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) |
495 | { | 495 | { |
496 | struct i2c_client *client = sd->priv; | 496 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
497 | 497 | ||
498 | /* Switch between preview and still shot modes */ | 498 | /* Switch between preview and still shot modes */ |
499 | return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80); | 499 | return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80); |
@@ -503,7 +503,7 @@ static int rj54n1_set_bus_param(struct soc_camera_device *icd, | |||
503 | unsigned long flags) | 503 | unsigned long flags) |
504 | { | 504 | { |
505 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 505 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
506 | struct i2c_client *client = sd->priv; | 506 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
507 | /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */ | 507 | /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */ |
508 | 508 | ||
509 | if (flags & SOCAM_PCLK_SAMPLE_RISING) | 509 | if (flags & SOCAM_PCLK_SAMPLE_RISING) |
@@ -560,7 +560,7 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h, | |||
560 | 560 | ||
561 | static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 561 | static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
562 | { | 562 | { |
563 | struct i2c_client *client = sd->priv; | 563 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
564 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 564 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
565 | struct v4l2_rect *rect = &a->c; | 565 | struct v4l2_rect *rect = &a->c; |
566 | int dummy = 0, output_w, output_h, | 566 | int dummy = 0, output_w, output_h, |
@@ -595,7 +595,7 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
595 | 595 | ||
596 | static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 596 | static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
597 | { | 597 | { |
598 | struct i2c_client *client = sd->priv; | 598 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
599 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 599 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
600 | 600 | ||
601 | a->c = rj54n1->rect; | 601 | a->c = rj54n1->rect; |
@@ -621,7 +621,7 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
621 | static int rj54n1_g_fmt(struct v4l2_subdev *sd, | 621 | static int rj54n1_g_fmt(struct v4l2_subdev *sd, |
622 | struct v4l2_mbus_framefmt *mf) | 622 | struct v4l2_mbus_framefmt *mf) |
623 | { | 623 | { |
624 | struct i2c_client *client = sd->priv; | 624 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
625 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 625 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
626 | 626 | ||
627 | mf->code = rj54n1->fmt->code; | 627 | mf->code = rj54n1->fmt->code; |
@@ -641,7 +641,7 @@ static int rj54n1_g_fmt(struct v4l2_subdev *sd, | |||
641 | static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h, | 641 | static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h, |
642 | s32 *out_w, s32 *out_h) | 642 | s32 *out_w, s32 *out_h) |
643 | { | 643 | { |
644 | struct i2c_client *client = sd->priv; | 644 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
645 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 645 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
646 | unsigned int skip, resize, input_w = *in_w, input_h = *in_h, | 646 | unsigned int skip, resize, input_w = *in_w, input_h = *in_h, |
647 | output_w = *out_w, output_h = *out_h; | 647 | output_w = *out_w, output_h = *out_h; |
@@ -983,7 +983,7 @@ static int rj54n1_reg_init(struct i2c_client *client) | |||
983 | static int rj54n1_try_fmt(struct v4l2_subdev *sd, | 983 | static int rj54n1_try_fmt(struct v4l2_subdev *sd, |
984 | struct v4l2_mbus_framefmt *mf) | 984 | struct v4l2_mbus_framefmt *mf) |
985 | { | 985 | { |
986 | struct i2c_client *client = sd->priv; | 986 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
987 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 987 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
988 | const struct rj54n1_datafmt *fmt; | 988 | const struct rj54n1_datafmt *fmt; |
989 | int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || | 989 | int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || |
@@ -1014,7 +1014,7 @@ static int rj54n1_try_fmt(struct v4l2_subdev *sd, | |||
1014 | static int rj54n1_s_fmt(struct v4l2_subdev *sd, | 1014 | static int rj54n1_s_fmt(struct v4l2_subdev *sd, |
1015 | struct v4l2_mbus_framefmt *mf) | 1015 | struct v4l2_mbus_framefmt *mf) |
1016 | { | 1016 | { |
1017 | struct i2c_client *client = sd->priv; | 1017 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1018 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 1018 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
1019 | const struct rj54n1_datafmt *fmt; | 1019 | const struct rj54n1_datafmt *fmt; |
1020 | int output_w, output_h, max_w, max_h, | 1020 | int output_w, output_h, max_w, max_h, |
@@ -1145,7 +1145,7 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, | |||
1145 | static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, | 1145 | static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, |
1146 | struct v4l2_dbg_chip_ident *id) | 1146 | struct v4l2_dbg_chip_ident *id) |
1147 | { | 1147 | { |
1148 | struct i2c_client *client = sd->priv; | 1148 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1149 | 1149 | ||
1150 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 1150 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
1151 | return -EINVAL; | 1151 | return -EINVAL; |
@@ -1163,7 +1163,7 @@ static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, | |||
1163 | static int rj54n1_g_register(struct v4l2_subdev *sd, | 1163 | static int rj54n1_g_register(struct v4l2_subdev *sd, |
1164 | struct v4l2_dbg_register *reg) | 1164 | struct v4l2_dbg_register *reg) |
1165 | { | 1165 | { |
1166 | struct i2c_client *client = sd->priv; | 1166 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1167 | 1167 | ||
1168 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || | 1168 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || |
1169 | reg->reg < 0x400 || reg->reg > 0x1fff) | 1169 | reg->reg < 0x400 || reg->reg > 0x1fff) |
@@ -1185,7 +1185,7 @@ static int rj54n1_g_register(struct v4l2_subdev *sd, | |||
1185 | static int rj54n1_s_register(struct v4l2_subdev *sd, | 1185 | static int rj54n1_s_register(struct v4l2_subdev *sd, |
1186 | struct v4l2_dbg_register *reg) | 1186 | struct v4l2_dbg_register *reg) |
1187 | { | 1187 | { |
1188 | struct i2c_client *client = sd->priv; | 1188 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1189 | 1189 | ||
1190 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || | 1190 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || |
1191 | reg->reg < 0x400 || reg->reg > 0x1fff) | 1191 | reg->reg < 0x400 || reg->reg > 0x1fff) |
@@ -1248,7 +1248,7 @@ static struct soc_camera_ops rj54n1_ops = { | |||
1248 | 1248 | ||
1249 | static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 1249 | static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
1250 | { | 1250 | { |
1251 | struct i2c_client *client = sd->priv; | 1251 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1252 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 1252 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
1253 | int data; | 1253 | int data; |
1254 | 1254 | ||
@@ -1283,7 +1283,7 @@ static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
1283 | static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 1283 | static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
1284 | { | 1284 | { |
1285 | int data; | 1285 | int data; |
1286 | struct i2c_client *client = sd->priv; | 1286 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1287 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 1287 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
1288 | const struct v4l2_queryctrl *qctrl; | 1288 | const struct v4l2_queryctrl *qctrl; |
1289 | 1289 | ||
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 8ec7c9a45a1..f5a46c45871 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -600,7 +600,7 @@ static int s2255_got_frame(struct s2255_channel *channel, int jpgsize) | |||
600 | dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i); | 600 | dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i); |
601 | unlock: | 601 | unlock: |
602 | spin_unlock_irqrestore(&dev->slock, flags); | 602 | spin_unlock_irqrestore(&dev->slock, flags); |
603 | return 0; | 603 | return rc; |
604 | } | 604 | } |
605 | 605 | ||
606 | static const struct s2255_fmt *format_by_fourcc(int fourcc) | 606 | static const struct s2255_fmt *format_by_fourcc(int fourcc) |
@@ -1817,7 +1817,7 @@ static int s2255_open(struct file *file) | |||
1817 | NULL, &dev->slock, | 1817 | NULL, &dev->slock, |
1818 | fh->type, | 1818 | fh->type, |
1819 | V4L2_FIELD_INTERLACED, | 1819 | V4L2_FIELD_INTERLACED, |
1820 | sizeof(struct s2255_buffer), fh); | 1820 | sizeof(struct s2255_buffer), fh, NULL); |
1821 | return 0; | 1821 | return 0; |
1822 | } | 1822 | } |
1823 | 1823 | ||
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/video/s5p-fimc/Makefile index 0d9d54132ec..7ea1b1403b1 100644 --- a/drivers/media/video/s5p-fimc/Makefile +++ b/drivers/media/video/s5p-fimc/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | 1 | ||
2 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) := s5p-fimc.o | 2 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) := s5p-fimc.o |
3 | s5p-fimc-y := fimc-core.o fimc-reg.o | 3 | s5p-fimc-y := fimc-core.o fimc-reg.o fimc-capture.o |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c new file mode 100644 index 00000000000..e8f13d3e2df --- /dev/null +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -0,0 +1,819 @@ | |||
1 | /* | ||
2 | * Samsung S5P SoC series camera interface (camera capture) driver | ||
3 | * | ||
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd | ||
5 | * Author: Sylwester Nawrocki, <s.nawrocki@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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/version.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/bug.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | #include <linux/videodev2.h> | ||
27 | #include <media/v4l2-device.h> | ||
28 | #include <media/v4l2-ioctl.h> | ||
29 | #include <media/v4l2-mem2mem.h> | ||
30 | #include <media/videobuf-core.h> | ||
31 | #include <media/videobuf-dma-contig.h> | ||
32 | |||
33 | #include "fimc-core.h" | ||
34 | |||
35 | static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc, | ||
36 | struct s3c_fimc_isp_info *isp_info) | ||
37 | { | ||
38 | struct i2c_adapter *i2c_adap; | ||
39 | struct fimc_vid_cap *vid_cap = &fimc->vid_cap; | ||
40 | struct v4l2_subdev *sd = NULL; | ||
41 | |||
42 | i2c_adap = i2c_get_adapter(isp_info->i2c_bus_num); | ||
43 | if (!i2c_adap) | ||
44 | return ERR_PTR(-ENOMEM); | ||
45 | |||
46 | sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap, | ||
47 | MODULE_NAME, isp_info->board_info, NULL); | ||
48 | if (!sd) { | ||
49 | v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n"); | ||
50 | return NULL; | ||
51 | } | ||
52 | |||
53 | v4l2_info(&vid_cap->v4l2_dev, "subdevice %s registered successfuly\n", | ||
54 | isp_info->board_info->type); | ||
55 | |||
56 | return sd; | ||
57 | } | ||
58 | |||
59 | static void fimc_subdev_unregister(struct fimc_dev *fimc) | ||
60 | { | ||
61 | struct fimc_vid_cap *vid_cap = &fimc->vid_cap; | ||
62 | struct i2c_client *client; | ||
63 | |||
64 | if (vid_cap->input_index < 0) | ||
65 | return; /* Subdevice already released or not registered. */ | ||
66 | |||
67 | if (vid_cap->sd) { | ||
68 | v4l2_device_unregister_subdev(vid_cap->sd); | ||
69 | client = v4l2_get_subdevdata(vid_cap->sd); | ||
70 | i2c_unregister_device(client); | ||
71 | i2c_put_adapter(client->adapter); | ||
72 | vid_cap->sd = NULL; | ||
73 | } | ||
74 | |||
75 | vid_cap->input_index = -1; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * fimc_subdev_attach - attach v4l2_subdev to camera host interface | ||
80 | * | ||
81 | * @fimc: FIMC device information | ||
82 | * @index: index to the array of available subdevices, | ||
83 | * -1 for full array search or non negative value | ||
84 | * to select specific subdevice | ||
85 | */ | ||
86 | static int fimc_subdev_attach(struct fimc_dev *fimc, int index) | ||
87 | { | ||
88 | struct fimc_vid_cap *vid_cap = &fimc->vid_cap; | ||
89 | struct s3c_platform_fimc *pdata = fimc->pdata; | ||
90 | struct s3c_fimc_isp_info *isp_info; | ||
91 | struct v4l2_subdev *sd; | ||
92 | int i; | ||
93 | |||
94 | for (i = 0; i < FIMC_MAX_CAMIF_CLIENTS; ++i) { | ||
95 | isp_info = pdata->isp_info[i]; | ||
96 | |||
97 | if (!isp_info || (index >= 0 && i != index)) | ||
98 | continue; | ||
99 | |||
100 | sd = fimc_subdev_register(fimc, isp_info); | ||
101 | if (sd) { | ||
102 | vid_cap->sd = sd; | ||
103 | vid_cap->input_index = i; | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | vid_cap->input_index = -1; | ||
110 | vid_cap->sd = NULL; | ||
111 | v4l2_err(&vid_cap->v4l2_dev, "fimc%d: sensor attach failed\n", | ||
112 | fimc->id); | ||
113 | return -ENODEV; | ||
114 | } | ||
115 | |||
116 | static int fimc_isp_subdev_init(struct fimc_dev *fimc, int index) | ||
117 | { | ||
118 | struct s3c_fimc_isp_info *isp_info; | ||
119 | int ret; | ||
120 | |||
121 | ret = fimc_subdev_attach(fimc, index); | ||
122 | if (ret) | ||
123 | return ret; | ||
124 | |||
125 | isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index]; | ||
126 | ret = fimc_hw_set_camera_polarity(fimc, isp_info); | ||
127 | if (!ret) { | ||
128 | ret = v4l2_subdev_call(fimc->vid_cap.sd, core, | ||
129 | s_power, 1); | ||
130 | if (!ret) | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | fimc_subdev_unregister(fimc); | ||
135 | err("ISP initialization failed: %d", ret); | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * At least one buffer on the pending_buf_q queue is required. | ||
141 | * Locking: The caller holds fimc->slock spinlock. | ||
142 | */ | ||
143 | int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, | ||
144 | struct fimc_vid_buffer *fimc_vb) | ||
145 | { | ||
146 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
147 | struct fimc_ctx *ctx = cap->ctx; | ||
148 | int ret = 0; | ||
149 | |||
150 | BUG_ON(!fimc || !fimc_vb); | ||
151 | |||
152 | ret = fimc_prepare_addr(ctx, fimc_vb, &ctx->d_frame, | ||
153 | &fimc_vb->paddr); | ||
154 | if (ret) | ||
155 | return ret; | ||
156 | |||
157 | if (test_bit(ST_CAPT_STREAM, &fimc->state)) { | ||
158 | fimc_pending_queue_add(cap, fimc_vb); | ||
159 | } else { | ||
160 | /* Setup the buffer directly for processing. */ | ||
161 | int buf_id = (cap->reqbufs_count == 1) ? -1 : cap->buf_index; | ||
162 | fimc_hw_set_output_addr(fimc, &fimc_vb->paddr, buf_id); | ||
163 | |||
164 | fimc_vb->index = cap->buf_index; | ||
165 | active_queue_add(cap, fimc_vb); | ||
166 | |||
167 | if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) | ||
168 | cap->buf_index = 0; | ||
169 | } | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static int fimc_stop_capture(struct fimc_dev *fimc) | ||
174 | { | ||
175 | unsigned long flags; | ||
176 | struct fimc_vid_cap *cap; | ||
177 | int ret; | ||
178 | |||
179 | cap = &fimc->vid_cap; | ||
180 | |||
181 | if (!fimc_capture_active(fimc)) | ||
182 | return 0; | ||
183 | |||
184 | spin_lock_irqsave(&fimc->slock, flags); | ||
185 | set_bit(ST_CAPT_SHUT, &fimc->state); | ||
186 | fimc_deactivate_capture(fimc); | ||
187 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
188 | |||
189 | wait_event_timeout(fimc->irq_queue, | ||
190 | test_bit(ST_CAPT_SHUT, &fimc->state), | ||
191 | FIMC_SHUTDOWN_TIMEOUT); | ||
192 | |||
193 | ret = v4l2_subdev_call(cap->sd, video, s_stream, 0); | ||
194 | if (ret) | ||
195 | v4l2_err(&fimc->vid_cap.v4l2_dev, "s_stream(0) failed\n"); | ||
196 | |||
197 | spin_lock_irqsave(&fimc->slock, flags); | ||
198 | fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND | | ||
199 | 1 << ST_CAPT_STREAM); | ||
200 | |||
201 | fimc->vid_cap.active_buf_cnt = 0; | ||
202 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
203 | |||
204 | dbg("state: 0x%lx", fimc->state); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int fimc_capture_open(struct file *file) | ||
209 | { | ||
210 | struct fimc_dev *fimc = video_drvdata(file); | ||
211 | int ret = 0; | ||
212 | |||
213 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); | ||
214 | |||
215 | /* Return if the corresponding video mem2mem node is already opened. */ | ||
216 | if (fimc_m2m_active(fimc)) | ||
217 | return -EBUSY; | ||
218 | |||
219 | if (mutex_lock_interruptible(&fimc->lock)) | ||
220 | return -ERESTARTSYS; | ||
221 | |||
222 | if (++fimc->vid_cap.refcnt == 1) { | ||
223 | ret = fimc_isp_subdev_init(fimc, -1); | ||
224 | if (ret) { | ||
225 | fimc->vid_cap.refcnt--; | ||
226 | ret = -EIO; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | file->private_data = fimc->vid_cap.ctx; | ||
231 | |||
232 | mutex_unlock(&fimc->lock); | ||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | static int fimc_capture_close(struct file *file) | ||
237 | { | ||
238 | struct fimc_dev *fimc = video_drvdata(file); | ||
239 | |||
240 | if (mutex_lock_interruptible(&fimc->lock)) | ||
241 | return -ERESTARTSYS; | ||
242 | |||
243 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); | ||
244 | |||
245 | if (--fimc->vid_cap.refcnt == 0) { | ||
246 | fimc_stop_capture(fimc); | ||
247 | |||
248 | videobuf_stop(&fimc->vid_cap.vbq); | ||
249 | videobuf_mmap_free(&fimc->vid_cap.vbq); | ||
250 | |||
251 | v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n"); | ||
252 | v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); | ||
253 | fimc_subdev_unregister(fimc); | ||
254 | } | ||
255 | |||
256 | mutex_unlock(&fimc->lock); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static unsigned int fimc_capture_poll(struct file *file, | ||
261 | struct poll_table_struct *wait) | ||
262 | { | ||
263 | struct fimc_ctx *ctx = file->private_data; | ||
264 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
265 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
266 | int ret; | ||
267 | |||
268 | if (mutex_lock_interruptible(&fimc->lock)) | ||
269 | return POLLERR; | ||
270 | |||
271 | ret = videobuf_poll_stream(file, &cap->vbq, wait); | ||
272 | mutex_unlock(&fimc->lock); | ||
273 | |||
274 | return ret; | ||
275 | } | ||
276 | |||
277 | static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) | ||
278 | { | ||
279 | struct fimc_ctx *ctx = file->private_data; | ||
280 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
281 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
282 | int ret; | ||
283 | |||
284 | if (mutex_lock_interruptible(&fimc->lock)) | ||
285 | return -ERESTARTSYS; | ||
286 | |||
287 | ret = videobuf_mmap_mapper(&cap->vbq, vma); | ||
288 | mutex_unlock(&fimc->lock); | ||
289 | |||
290 | return ret; | ||
291 | } | ||
292 | |||
293 | /* video device file operations */ | ||
294 | static const struct v4l2_file_operations fimc_capture_fops = { | ||
295 | .owner = THIS_MODULE, | ||
296 | .open = fimc_capture_open, | ||
297 | .release = fimc_capture_close, | ||
298 | .poll = fimc_capture_poll, | ||
299 | .unlocked_ioctl = video_ioctl2, | ||
300 | .mmap = fimc_capture_mmap, | ||
301 | }; | ||
302 | |||
303 | static int fimc_vidioc_querycap_capture(struct file *file, void *priv, | ||
304 | struct v4l2_capability *cap) | ||
305 | { | ||
306 | struct fimc_ctx *ctx = file->private_data; | ||
307 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
308 | |||
309 | strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1); | ||
310 | strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1); | ||
311 | cap->bus_info[0] = 0; | ||
312 | cap->version = KERNEL_VERSION(1, 0, 0); | ||
313 | cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | /* Synchronize formats of the camera interface input and attached sensor. */ | ||
319 | static int sync_capture_fmt(struct fimc_ctx *ctx) | ||
320 | { | ||
321 | struct fimc_frame *frame = &ctx->s_frame; | ||
322 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
323 | struct v4l2_mbus_framefmt *fmt = &fimc->vid_cap.fmt; | ||
324 | int ret; | ||
325 | |||
326 | fmt->width = ctx->d_frame.o_width; | ||
327 | fmt->height = ctx->d_frame.o_height; | ||
328 | |||
329 | ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_mbus_fmt, fmt); | ||
330 | if (ret == -ENOIOCTLCMD) { | ||
331 | err("s_mbus_fmt failed"); | ||
332 | return ret; | ||
333 | } | ||
334 | dbg("w: %d, h: %d, code= %d", fmt->width, fmt->height, fmt->code); | ||
335 | |||
336 | frame->fmt = find_mbus_format(fmt, FMT_FLAGS_CAM); | ||
337 | if (!frame->fmt) { | ||
338 | err("fimc source format not found\n"); | ||
339 | return -EINVAL; | ||
340 | } | ||
341 | |||
342 | frame->f_width = fmt->width; | ||
343 | frame->f_height = fmt->height; | ||
344 | frame->width = fmt->width; | ||
345 | frame->height = fmt->height; | ||
346 | frame->o_width = fmt->width; | ||
347 | frame->o_height = fmt->height; | ||
348 | frame->offs_h = 0; | ||
349 | frame->offs_v = 0; | ||
350 | |||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int fimc_cap_s_fmt(struct file *file, void *priv, | ||
355 | struct v4l2_format *f) | ||
356 | { | ||
357 | struct fimc_ctx *ctx = priv; | ||
358 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
359 | struct fimc_frame *frame; | ||
360 | struct v4l2_pix_format *pix; | ||
361 | int ret; | ||
362 | |||
363 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
364 | return -EINVAL; | ||
365 | |||
366 | ret = fimc_vidioc_try_fmt(file, priv, f); | ||
367 | if (ret) | ||
368 | return ret; | ||
369 | |||
370 | if (mutex_lock_interruptible(&fimc->lock)) | ||
371 | return -ERESTARTSYS; | ||
372 | |||
373 | if (fimc_capture_active(fimc)) { | ||
374 | ret = -EBUSY; | ||
375 | goto sf_unlock; | ||
376 | } | ||
377 | |||
378 | frame = &ctx->d_frame; | ||
379 | |||
380 | pix = &f->fmt.pix; | ||
381 | frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM); | ||
382 | if (!frame->fmt) { | ||
383 | err("fimc target format not found\n"); | ||
384 | ret = -EINVAL; | ||
385 | goto sf_unlock; | ||
386 | } | ||
387 | |||
388 | /* Output DMA frame pixel size and offsets. */ | ||
389 | frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; | ||
390 | frame->f_height = pix->height; | ||
391 | frame->width = pix->width; | ||
392 | frame->height = pix->height; | ||
393 | frame->o_width = pix->width; | ||
394 | frame->o_height = pix->height; | ||
395 | frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3; | ||
396 | frame->offs_h = 0; | ||
397 | frame->offs_v = 0; | ||
398 | |||
399 | ret = sync_capture_fmt(ctx); | ||
400 | |||
401 | ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT); | ||
402 | |||
403 | sf_unlock: | ||
404 | mutex_unlock(&fimc->lock); | ||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | static int fimc_cap_enum_input(struct file *file, void *priv, | ||
409 | struct v4l2_input *i) | ||
410 | { | ||
411 | struct fimc_ctx *ctx = priv; | ||
412 | struct s3c_platform_fimc *pldata = ctx->fimc_dev->pdata; | ||
413 | struct s3c_fimc_isp_info *isp_info; | ||
414 | |||
415 | if (i->index >= FIMC_MAX_CAMIF_CLIENTS) | ||
416 | return -EINVAL; | ||
417 | |||
418 | isp_info = pldata->isp_info[i->index]; | ||
419 | if (isp_info == NULL) | ||
420 | return -EINVAL; | ||
421 | |||
422 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
423 | strncpy(i->name, isp_info->board_info->type, 32); | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static int fimc_cap_s_input(struct file *file, void *priv, | ||
428 | unsigned int i) | ||
429 | { | ||
430 | struct fimc_ctx *ctx = priv; | ||
431 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
432 | struct s3c_platform_fimc *pdata = fimc->pdata; | ||
433 | int ret; | ||
434 | |||
435 | if (fimc_capture_active(ctx->fimc_dev)) | ||
436 | return -EBUSY; | ||
437 | |||
438 | if (mutex_lock_interruptible(&fimc->lock)) | ||
439 | return -ERESTARTSYS; | ||
440 | |||
441 | if (i >= FIMC_MAX_CAMIF_CLIENTS || !pdata->isp_info[i]) { | ||
442 | ret = -EINVAL; | ||
443 | goto si_unlock; | ||
444 | } | ||
445 | |||
446 | if (fimc->vid_cap.sd) { | ||
447 | ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); | ||
448 | if (ret) | ||
449 | err("s_power failed: %d", ret); | ||
450 | } | ||
451 | |||
452 | /* Release the attached sensor subdevice. */ | ||
453 | fimc_subdev_unregister(fimc); | ||
454 | |||
455 | ret = fimc_isp_subdev_init(fimc, i); | ||
456 | |||
457 | si_unlock: | ||
458 | mutex_unlock(&fimc->lock); | ||
459 | return ret; | ||
460 | } | ||
461 | |||
462 | static int fimc_cap_g_input(struct file *file, void *priv, | ||
463 | unsigned int *i) | ||
464 | { | ||
465 | struct fimc_ctx *ctx = priv; | ||
466 | struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; | ||
467 | |||
468 | *i = cap->input_index; | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static int fimc_cap_streamon(struct file *file, void *priv, | ||
473 | enum v4l2_buf_type type) | ||
474 | { | ||
475 | struct s3c_fimc_isp_info *isp_info; | ||
476 | struct fimc_ctx *ctx = priv; | ||
477 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
478 | int ret = -EBUSY; | ||
479 | |||
480 | if (mutex_lock_interruptible(&fimc->lock)) | ||
481 | return -ERESTARTSYS; | ||
482 | |||
483 | if (fimc_capture_active(fimc) || !fimc->vid_cap.sd) | ||
484 | goto s_unlock; | ||
485 | |||
486 | if (!(ctx->state & FIMC_DST_FMT)) { | ||
487 | v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n"); | ||
488 | ret = -EINVAL; | ||
489 | goto s_unlock; | ||
490 | } | ||
491 | |||
492 | ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1); | ||
493 | if (ret && ret != -ENOIOCTLCMD) | ||
494 | goto s_unlock; | ||
495 | |||
496 | ret = fimc_prepare_config(ctx, ctx->state); | ||
497 | if (ret) | ||
498 | goto s_unlock; | ||
499 | |||
500 | isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index]; | ||
501 | fimc_hw_set_camera_type(fimc, isp_info); | ||
502 | fimc_hw_set_camera_source(fimc, isp_info); | ||
503 | fimc_hw_set_camera_offset(fimc, &ctx->s_frame); | ||
504 | |||
505 | if (ctx->state & FIMC_PARAMS) { | ||
506 | ret = fimc_set_scaler_info(ctx); | ||
507 | if (ret) { | ||
508 | err("Scaler setup error"); | ||
509 | goto s_unlock; | ||
510 | } | ||
511 | fimc_hw_set_input_path(ctx); | ||
512 | fimc_hw_set_scaler(ctx); | ||
513 | fimc_hw_set_target_format(ctx); | ||
514 | fimc_hw_set_rotation(ctx); | ||
515 | fimc_hw_set_effect(ctx); | ||
516 | } | ||
517 | |||
518 | fimc_hw_set_output_path(ctx); | ||
519 | fimc_hw_set_out_dma(ctx); | ||
520 | |||
521 | INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q); | ||
522 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); | ||
523 | fimc->vid_cap.active_buf_cnt = 0; | ||
524 | fimc->vid_cap.frame_count = 0; | ||
525 | |||
526 | set_bit(ST_CAPT_PEND, &fimc->state); | ||
527 | ret = videobuf_streamon(&fimc->vid_cap.vbq); | ||
528 | |||
529 | s_unlock: | ||
530 | mutex_unlock(&fimc->lock); | ||
531 | return ret; | ||
532 | } | ||
533 | |||
534 | static int fimc_cap_streamoff(struct file *file, void *priv, | ||
535 | enum v4l2_buf_type type) | ||
536 | { | ||
537 | struct fimc_ctx *ctx = priv; | ||
538 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
539 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
540 | unsigned long flags; | ||
541 | int ret; | ||
542 | |||
543 | spin_lock_irqsave(&fimc->slock, flags); | ||
544 | if (!fimc_capture_running(fimc) && !fimc_capture_pending(fimc)) { | ||
545 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
546 | dbg("state: 0x%lx", fimc->state); | ||
547 | return -EINVAL; | ||
548 | } | ||
549 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
550 | |||
551 | if (mutex_lock_interruptible(&fimc->lock)) | ||
552 | return -ERESTARTSYS; | ||
553 | |||
554 | fimc_stop_capture(fimc); | ||
555 | ret = videobuf_streamoff(&cap->vbq); | ||
556 | mutex_unlock(&fimc->lock); | ||
557 | return ret; | ||
558 | } | ||
559 | |||
560 | static int fimc_cap_reqbufs(struct file *file, void *priv, | ||
561 | struct v4l2_requestbuffers *reqbufs) | ||
562 | { | ||
563 | struct fimc_ctx *ctx = priv; | ||
564 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
565 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
566 | int ret; | ||
567 | |||
568 | if (fimc_capture_active(ctx->fimc_dev)) | ||
569 | return -EBUSY; | ||
570 | |||
571 | if (mutex_lock_interruptible(&fimc->lock)) | ||
572 | return -ERESTARTSYS; | ||
573 | |||
574 | ret = videobuf_reqbufs(&cap->vbq, reqbufs); | ||
575 | if (!ret) | ||
576 | cap->reqbufs_count = reqbufs->count; | ||
577 | |||
578 | mutex_unlock(&fimc->lock); | ||
579 | return ret; | ||
580 | } | ||
581 | |||
582 | static int fimc_cap_querybuf(struct file *file, void *priv, | ||
583 | struct v4l2_buffer *buf) | ||
584 | { | ||
585 | struct fimc_ctx *ctx = priv; | ||
586 | struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; | ||
587 | |||
588 | if (fimc_capture_active(ctx->fimc_dev)) | ||
589 | return -EBUSY; | ||
590 | |||
591 | return videobuf_querybuf(&cap->vbq, buf); | ||
592 | } | ||
593 | |||
594 | static int fimc_cap_qbuf(struct file *file, void *priv, | ||
595 | struct v4l2_buffer *buf) | ||
596 | { | ||
597 | struct fimc_ctx *ctx = priv; | ||
598 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
599 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
600 | int ret; | ||
601 | |||
602 | if (mutex_lock_interruptible(&fimc->lock)) | ||
603 | return -ERESTARTSYS; | ||
604 | |||
605 | ret = videobuf_qbuf(&cap->vbq, buf); | ||
606 | |||
607 | mutex_unlock(&fimc->lock); | ||
608 | return ret; | ||
609 | } | ||
610 | |||
611 | static int fimc_cap_dqbuf(struct file *file, void *priv, | ||
612 | struct v4l2_buffer *buf) | ||
613 | { | ||
614 | struct fimc_ctx *ctx = priv; | ||
615 | int ret; | ||
616 | |||
617 | if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) | ||
618 | return -ERESTARTSYS; | ||
619 | |||
620 | ret = videobuf_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf, | ||
621 | file->f_flags & O_NONBLOCK); | ||
622 | |||
623 | mutex_unlock(&ctx->fimc_dev->lock); | ||
624 | return ret; | ||
625 | } | ||
626 | |||
627 | static int fimc_cap_s_ctrl(struct file *file, void *priv, | ||
628 | struct v4l2_control *ctrl) | ||
629 | { | ||
630 | struct fimc_ctx *ctx = priv; | ||
631 | int ret = -EINVAL; | ||
632 | |||
633 | if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) | ||
634 | return -ERESTARTSYS; | ||
635 | |||
636 | /* Allow any controls but 90/270 rotation while streaming */ | ||
637 | if (!fimc_capture_active(ctx->fimc_dev) || | ||
638 | ctrl->id != V4L2_CID_ROTATE || | ||
639 | (ctrl->value != 90 && ctrl->value != 270)) { | ||
640 | ret = check_ctrl_val(ctx, ctrl); | ||
641 | if (!ret) { | ||
642 | ret = fimc_s_ctrl(ctx, ctrl); | ||
643 | if (!ret) | ||
644 | ctx->state |= FIMC_PARAMS; | ||
645 | } | ||
646 | } | ||
647 | if (ret == -EINVAL) | ||
648 | ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, | ||
649 | core, s_ctrl, ctrl); | ||
650 | |||
651 | mutex_unlock(&ctx->fimc_dev->lock); | ||
652 | return ret; | ||
653 | } | ||
654 | |||
655 | static int fimc_cap_s_crop(struct file *file, void *fh, | ||
656 | struct v4l2_crop *cr) | ||
657 | { | ||
658 | struct fimc_frame *f; | ||
659 | struct fimc_ctx *ctx = file->private_data; | ||
660 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
661 | int ret = -EINVAL; | ||
662 | |||
663 | if (fimc_capture_active(fimc)) | ||
664 | return -EBUSY; | ||
665 | |||
666 | ret = fimc_try_crop(ctx, cr); | ||
667 | if (ret) | ||
668 | return ret; | ||
669 | |||
670 | if (mutex_lock_interruptible(&fimc->lock)) | ||
671 | return -ERESTARTSYS; | ||
672 | |||
673 | if (!(ctx->state & FIMC_DST_FMT)) { | ||
674 | v4l2_err(&fimc->vid_cap.v4l2_dev, | ||
675 | "Capture color format not set\n"); | ||
676 | goto sc_unlock; | ||
677 | } | ||
678 | |||
679 | f = &ctx->s_frame; | ||
680 | /* Check for the pixel scaling ratio when cropping input image. */ | ||
681 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); | ||
682 | if (ret) { | ||
683 | v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); | ||
684 | } else { | ||
685 | ret = 0; | ||
686 | f->offs_h = cr->c.left; | ||
687 | f->offs_v = cr->c.top; | ||
688 | f->width = cr->c.width; | ||
689 | f->height = cr->c.height; | ||
690 | } | ||
691 | |||
692 | sc_unlock: | ||
693 | mutex_unlock(&fimc->lock); | ||
694 | return ret; | ||
695 | } | ||
696 | |||
697 | |||
698 | static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { | ||
699 | .vidioc_querycap = fimc_vidioc_querycap_capture, | ||
700 | |||
701 | .vidioc_enum_fmt_vid_cap = fimc_vidioc_enum_fmt, | ||
702 | .vidioc_try_fmt_vid_cap = fimc_vidioc_try_fmt, | ||
703 | .vidioc_s_fmt_vid_cap = fimc_cap_s_fmt, | ||
704 | .vidioc_g_fmt_vid_cap = fimc_vidioc_g_fmt, | ||
705 | |||
706 | .vidioc_reqbufs = fimc_cap_reqbufs, | ||
707 | .vidioc_querybuf = fimc_cap_querybuf, | ||
708 | |||
709 | .vidioc_qbuf = fimc_cap_qbuf, | ||
710 | .vidioc_dqbuf = fimc_cap_dqbuf, | ||
711 | |||
712 | .vidioc_streamon = fimc_cap_streamon, | ||
713 | .vidioc_streamoff = fimc_cap_streamoff, | ||
714 | |||
715 | .vidioc_queryctrl = fimc_vidioc_queryctrl, | ||
716 | .vidioc_g_ctrl = fimc_vidioc_g_ctrl, | ||
717 | .vidioc_s_ctrl = fimc_cap_s_ctrl, | ||
718 | |||
719 | .vidioc_g_crop = fimc_vidioc_g_crop, | ||
720 | .vidioc_s_crop = fimc_cap_s_crop, | ||
721 | .vidioc_cropcap = fimc_vidioc_cropcap, | ||
722 | |||
723 | .vidioc_enum_input = fimc_cap_enum_input, | ||
724 | .vidioc_s_input = fimc_cap_s_input, | ||
725 | .vidioc_g_input = fimc_cap_g_input, | ||
726 | }; | ||
727 | |||
728 | int fimc_register_capture_device(struct fimc_dev *fimc) | ||
729 | { | ||
730 | struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev; | ||
731 | struct video_device *vfd; | ||
732 | struct fimc_vid_cap *vid_cap; | ||
733 | struct fimc_ctx *ctx; | ||
734 | struct v4l2_format f; | ||
735 | int ret; | ||
736 | |||
737 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); | ||
738 | if (!ctx) | ||
739 | return -ENOMEM; | ||
740 | |||
741 | ctx->fimc_dev = fimc; | ||
742 | ctx->in_path = FIMC_CAMERA; | ||
743 | ctx->out_path = FIMC_DMA; | ||
744 | ctx->state = FIMC_CTX_CAP; | ||
745 | |||
746 | f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; | ||
747 | ctx->d_frame.fmt = find_format(&f, FMT_FLAGS_M2M); | ||
748 | |||
749 | if (!v4l2_dev->name[0]) | ||
750 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), | ||
751 | "%s.capture", dev_name(&fimc->pdev->dev)); | ||
752 | |||
753 | ret = v4l2_device_register(NULL, v4l2_dev); | ||
754 | if (ret) | ||
755 | goto err_info; | ||
756 | |||
757 | vfd = video_device_alloc(); | ||
758 | if (!vfd) { | ||
759 | v4l2_err(v4l2_dev, "Failed to allocate video device\n"); | ||
760 | goto err_v4l2_reg; | ||
761 | } | ||
762 | |||
763 | snprintf(vfd->name, sizeof(vfd->name), "%s:cap", | ||
764 | dev_name(&fimc->pdev->dev)); | ||
765 | |||
766 | vfd->fops = &fimc_capture_fops; | ||
767 | vfd->ioctl_ops = &fimc_capture_ioctl_ops; | ||
768 | vfd->minor = -1; | ||
769 | vfd->release = video_device_release; | ||
770 | video_set_drvdata(vfd, fimc); | ||
771 | |||
772 | vid_cap = &fimc->vid_cap; | ||
773 | vid_cap->vfd = vfd; | ||
774 | vid_cap->active_buf_cnt = 0; | ||
775 | vid_cap->reqbufs_count = 0; | ||
776 | vid_cap->refcnt = 0; | ||
777 | /* The default color format for image sensor. */ | ||
778 | vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; | ||
779 | |||
780 | INIT_LIST_HEAD(&vid_cap->pending_buf_q); | ||
781 | INIT_LIST_HEAD(&vid_cap->active_buf_q); | ||
782 | spin_lock_init(&ctx->slock); | ||
783 | vid_cap->ctx = ctx; | ||
784 | |||
785 | videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, | ||
786 | vid_cap->v4l2_dev.dev, &fimc->irqlock, | ||
787 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | ||
788 | sizeof(struct fimc_vid_buffer), (void *)ctx); | ||
789 | |||
790 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | ||
791 | if (ret) { | ||
792 | v4l2_err(v4l2_dev, "Failed to register video device\n"); | ||
793 | goto err_vd_reg; | ||
794 | } | ||
795 | |||
796 | v4l2_info(v4l2_dev, | ||
797 | "FIMC capture driver registered as /dev/video%d\n", | ||
798 | vfd->num); | ||
799 | |||
800 | return 0; | ||
801 | |||
802 | err_vd_reg: | ||
803 | video_device_release(vfd); | ||
804 | err_v4l2_reg: | ||
805 | v4l2_device_unregister(v4l2_dev); | ||
806 | err_info: | ||
807 | dev_err(&fimc->pdev->dev, "failed to install\n"); | ||
808 | return ret; | ||
809 | } | ||
810 | |||
811 | void fimc_unregister_capture_device(struct fimc_dev *fimc) | ||
812 | { | ||
813 | struct fimc_vid_cap *capture = &fimc->vid_cap; | ||
814 | |||
815 | if (capture->vfd) | ||
816 | video_unregister_device(capture->vfd); | ||
817 | |||
818 | kfree(capture->ctx); | ||
819 | } | ||
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 6961c55baf9..2e7c547894b 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * S5P camera interface (video postprocessor) driver | 2 | * S5P camera interface (video postprocessor) driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Samsung Electronics | 4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd |
5 | * | 5 | * |
6 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> | 6 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> |
7 | * | 7 | * |
@@ -38,86 +38,103 @@ static struct fimc_fmt fimc_formats[] = { | |||
38 | .depth = 16, | 38 | .depth = 16, |
39 | .color = S5P_FIMC_RGB565, | 39 | .color = S5P_FIMC_RGB565, |
40 | .buff_cnt = 1, | 40 | .buff_cnt = 1, |
41 | .planes_cnt = 1 | 41 | .planes_cnt = 1, |
42 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE, | ||
43 | .flags = FMT_FLAGS_M2M, | ||
42 | }, { | 44 | }, { |
43 | .name = "BGR666", | 45 | .name = "BGR666", |
44 | .fourcc = V4L2_PIX_FMT_BGR666, | 46 | .fourcc = V4L2_PIX_FMT_BGR666, |
45 | .depth = 32, | 47 | .depth = 32, |
46 | .color = S5P_FIMC_RGB666, | 48 | .color = S5P_FIMC_RGB666, |
47 | .buff_cnt = 1, | 49 | .buff_cnt = 1, |
48 | .planes_cnt = 1 | 50 | .planes_cnt = 1, |
51 | .flags = FMT_FLAGS_M2M, | ||
49 | }, { | 52 | }, { |
50 | .name = "XRGB-8-8-8-8, 24 bpp", | 53 | .name = "XRGB-8-8-8-8, 24 bpp", |
51 | .fourcc = V4L2_PIX_FMT_RGB24, | 54 | .fourcc = V4L2_PIX_FMT_RGB24, |
52 | .depth = 32, | 55 | .depth = 32, |
53 | .color = S5P_FIMC_RGB888, | 56 | .color = S5P_FIMC_RGB888, |
54 | .buff_cnt = 1, | 57 | .buff_cnt = 1, |
55 | .planes_cnt = 1 | 58 | .planes_cnt = 1, |
59 | .flags = FMT_FLAGS_M2M, | ||
56 | }, { | 60 | }, { |
57 | .name = "YUV 4:2:2 packed, YCbYCr", | 61 | .name = "YUV 4:2:2 packed, YCbYCr", |
58 | .fourcc = V4L2_PIX_FMT_YUYV, | 62 | .fourcc = V4L2_PIX_FMT_YUYV, |
59 | .depth = 16, | 63 | .depth = 16, |
60 | .color = S5P_FIMC_YCBYCR422, | 64 | .color = S5P_FIMC_YCBYCR422, |
61 | .buff_cnt = 1, | 65 | .buff_cnt = 1, |
62 | .planes_cnt = 1 | 66 | .planes_cnt = 1, |
63 | }, { | 67 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, |
68 | .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, | ||
69 | }, { | ||
64 | .name = "YUV 4:2:2 packed, CbYCrY", | 70 | .name = "YUV 4:2:2 packed, CbYCrY", |
65 | .fourcc = V4L2_PIX_FMT_UYVY, | 71 | .fourcc = V4L2_PIX_FMT_UYVY, |
66 | .depth = 16, | 72 | .depth = 16, |
67 | .color = S5P_FIMC_CBYCRY422, | 73 | .color = S5P_FIMC_CBYCRY422, |
68 | .buff_cnt = 1, | 74 | .buff_cnt = 1, |
69 | .planes_cnt = 1 | 75 | .planes_cnt = 1, |
76 | .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, | ||
77 | .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, | ||
70 | }, { | 78 | }, { |
71 | .name = "YUV 4:2:2 packed, CrYCbY", | 79 | .name = "YUV 4:2:2 packed, CrYCbY", |
72 | .fourcc = V4L2_PIX_FMT_VYUY, | 80 | .fourcc = V4L2_PIX_FMT_VYUY, |
73 | .depth = 16, | 81 | .depth = 16, |
74 | .color = S5P_FIMC_CRYCBY422, | 82 | .color = S5P_FIMC_CRYCBY422, |
75 | .buff_cnt = 1, | 83 | .buff_cnt = 1, |
76 | .planes_cnt = 1 | 84 | .planes_cnt = 1, |
85 | .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, | ||
86 | .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, | ||
77 | }, { | 87 | }, { |
78 | .name = "YUV 4:2:2 packed, YCrYCb", | 88 | .name = "YUV 4:2:2 packed, YCrYCb", |
79 | .fourcc = V4L2_PIX_FMT_YVYU, | 89 | .fourcc = V4L2_PIX_FMT_YVYU, |
80 | .depth = 16, | 90 | .depth = 16, |
81 | .color = S5P_FIMC_YCRYCB422, | 91 | .color = S5P_FIMC_YCRYCB422, |
82 | .buff_cnt = 1, | 92 | .buff_cnt = 1, |
83 | .planes_cnt = 1 | 93 | .planes_cnt = 1, |
94 | .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, | ||
95 | .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, | ||
84 | }, { | 96 | }, { |
85 | .name = "YUV 4:2:2 planar, Y/Cb/Cr", | 97 | .name = "YUV 4:2:2 planar, Y/Cb/Cr", |
86 | .fourcc = V4L2_PIX_FMT_YUV422P, | 98 | .fourcc = V4L2_PIX_FMT_YUV422P, |
87 | .depth = 12, | 99 | .depth = 12, |
88 | .color = S5P_FIMC_YCBCR422, | 100 | .color = S5P_FIMC_YCBCR422, |
89 | .buff_cnt = 1, | 101 | .buff_cnt = 1, |
90 | .planes_cnt = 3 | 102 | .planes_cnt = 3, |
103 | .flags = FMT_FLAGS_M2M, | ||
91 | }, { | 104 | }, { |
92 | .name = "YUV 4:2:2 planar, Y/CbCr", | 105 | .name = "YUV 4:2:2 planar, Y/CbCr", |
93 | .fourcc = V4L2_PIX_FMT_NV16, | 106 | .fourcc = V4L2_PIX_FMT_NV16, |
94 | .depth = 16, | 107 | .depth = 16, |
95 | .color = S5P_FIMC_YCBCR422, | 108 | .color = S5P_FIMC_YCBCR422, |
96 | .buff_cnt = 1, | 109 | .buff_cnt = 1, |
97 | .planes_cnt = 2 | 110 | .planes_cnt = 2, |
111 | .flags = FMT_FLAGS_M2M, | ||
98 | }, { | 112 | }, { |
99 | .name = "YUV 4:2:2 planar, Y/CrCb", | 113 | .name = "YUV 4:2:2 planar, Y/CrCb", |
100 | .fourcc = V4L2_PIX_FMT_NV61, | 114 | .fourcc = V4L2_PIX_FMT_NV61, |
101 | .depth = 16, | 115 | .depth = 16, |
102 | .color = S5P_FIMC_RGB565, | 116 | .color = S5P_FIMC_RGB565, |
103 | .buff_cnt = 1, | 117 | .buff_cnt = 1, |
104 | .planes_cnt = 2 | 118 | .planes_cnt = 2, |
119 | .flags = FMT_FLAGS_M2M, | ||
105 | }, { | 120 | }, { |
106 | .name = "YUV 4:2:0 planar, YCbCr", | 121 | .name = "YUV 4:2:0 planar, YCbCr", |
107 | .fourcc = V4L2_PIX_FMT_YUV420, | 122 | .fourcc = V4L2_PIX_FMT_YUV420, |
108 | .depth = 12, | 123 | .depth = 12, |
109 | .color = S5P_FIMC_YCBCR420, | 124 | .color = S5P_FIMC_YCBCR420, |
110 | .buff_cnt = 1, | 125 | .buff_cnt = 1, |
111 | .planes_cnt = 3 | 126 | .planes_cnt = 3, |
127 | .flags = FMT_FLAGS_M2M, | ||
112 | }, { | 128 | }, { |
113 | .name = "YUV 4:2:0 planar, Y/CbCr", | 129 | .name = "YUV 4:2:0 planar, Y/CbCr", |
114 | .fourcc = V4L2_PIX_FMT_NV12, | 130 | .fourcc = V4L2_PIX_FMT_NV12, |
115 | .depth = 12, | 131 | .depth = 12, |
116 | .color = S5P_FIMC_YCBCR420, | 132 | .color = S5P_FIMC_YCBCR420, |
117 | .buff_cnt = 1, | 133 | .buff_cnt = 1, |
118 | .planes_cnt = 2 | 134 | .planes_cnt = 2, |
119 | } | 135 | .flags = FMT_FLAGS_M2M, |
120 | }; | 136 | }, |
137 | }; | ||
121 | 138 | ||
122 | static struct v4l2_queryctrl fimc_ctrls[] = { | 139 | static struct v4l2_queryctrl fimc_ctrls[] = { |
123 | { | 140 | { |
@@ -127,16 +144,14 @@ static struct v4l2_queryctrl fimc_ctrls[] = { | |||
127 | .minimum = 0, | 144 | .minimum = 0, |
128 | .maximum = 1, | 145 | .maximum = 1, |
129 | .default_value = 0, | 146 | .default_value = 0, |
130 | }, | 147 | }, { |
131 | { | ||
132 | .id = V4L2_CID_VFLIP, | 148 | .id = V4L2_CID_VFLIP, |
133 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 149 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
134 | .name = "Vertical flip", | 150 | .name = "Vertical flip", |
135 | .minimum = 0, | 151 | .minimum = 0, |
136 | .maximum = 1, | 152 | .maximum = 1, |
137 | .default_value = 0, | 153 | .default_value = 0, |
138 | }, | 154 | }, { |
139 | { | ||
140 | .id = V4L2_CID_ROTATE, | 155 | .id = V4L2_CID_ROTATE, |
141 | .type = V4L2_CTRL_TYPE_INTEGER, | 156 | .type = V4L2_CTRL_TYPE_INTEGER, |
142 | .name = "Rotation (CCW)", | 157 | .name = "Rotation (CCW)", |
@@ -158,7 +173,7 @@ static struct v4l2_queryctrl *get_ctrl(int id) | |||
158 | return NULL; | 173 | return NULL; |
159 | } | 174 | } |
160 | 175 | ||
161 | static int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) | 176 | int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) |
162 | { | 177 | { |
163 | if (r->width > f->width) { | 178 | if (r->width > f->width) { |
164 | if (f->width > (r->width * SCALER_MAX_HRATIO)) | 179 | if (f->width > (r->width * SCALER_MAX_HRATIO)) |
@@ -181,32 +196,27 @@ static int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) | |||
181 | 196 | ||
182 | static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift) | 197 | static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift) |
183 | { | 198 | { |
184 | if (src >= tar * 64) { | 199 | u32 sh = 6; |
200 | |||
201 | if (src >= 64 * tar) | ||
185 | return -EINVAL; | 202 | return -EINVAL; |
186 | } else if (src >= tar * 32) { | 203 | |
187 | *ratio = 32; | 204 | while (sh--) { |
188 | *shift = 5; | 205 | u32 tmp = 1 << sh; |
189 | } else if (src >= tar * 16) { | 206 | if (src >= tar * tmp) { |
190 | *ratio = 16; | 207 | *shift = sh, *ratio = tmp; |
191 | *shift = 4; | 208 | return 0; |
192 | } else if (src >= tar * 8) { | 209 | } |
193 | *ratio = 8; | ||
194 | *shift = 3; | ||
195 | } else if (src >= tar * 4) { | ||
196 | *ratio = 4; | ||
197 | *shift = 2; | ||
198 | } else if (src >= tar * 2) { | ||
199 | *ratio = 2; | ||
200 | *shift = 1; | ||
201 | } else { | ||
202 | *ratio = 1; | ||
203 | *shift = 0; | ||
204 | } | 210 | } |
205 | 211 | ||
212 | *shift = 0, *ratio = 1; | ||
213 | |||
214 | dbg("s: %d, t: %d, shift: %d, ratio: %d", | ||
215 | src, tar, *shift, *ratio); | ||
206 | return 0; | 216 | return 0; |
207 | } | 217 | } |
208 | 218 | ||
209 | static int fimc_set_scaler_info(struct fimc_ctx *ctx) | 219 | int fimc_set_scaler_info(struct fimc_ctx *ctx) |
210 | { | 220 | { |
211 | struct fimc_scaler *sc = &ctx->scaler; | 221 | struct fimc_scaler *sc = &ctx->scaler; |
212 | struct fimc_frame *s_frame = &ctx->s_frame; | 222 | struct fimc_frame *s_frame = &ctx->s_frame; |
@@ -214,8 +224,13 @@ static int fimc_set_scaler_info(struct fimc_ctx *ctx) | |||
214 | int tx, ty, sx, sy; | 224 | int tx, ty, sx, sy; |
215 | int ret; | 225 | int ret; |
216 | 226 | ||
217 | tx = d_frame->width; | 227 | if (ctx->rotation == 90 || ctx->rotation == 270) { |
218 | ty = d_frame->height; | 228 | ty = d_frame->width; |
229 | tx = d_frame->height; | ||
230 | } else { | ||
231 | tx = d_frame->width; | ||
232 | ty = d_frame->height; | ||
233 | } | ||
219 | if (tx <= 0 || ty <= 0) { | 234 | if (tx <= 0 || ty <= 0) { |
220 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, | 235 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, |
221 | "invalid target size: %d x %d", tx, ty); | 236 | "invalid target size: %d x %d", tx, ty); |
@@ -261,12 +276,57 @@ static int fimc_set_scaler_info(struct fimc_ctx *ctx) | |||
261 | return 0; | 276 | return 0; |
262 | } | 277 | } |
263 | 278 | ||
279 | static void fimc_capture_handler(struct fimc_dev *fimc) | ||
280 | { | ||
281 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
282 | struct fimc_vid_buffer *v_buf = NULL; | ||
283 | |||
284 | if (!list_empty(&cap->active_buf_q)) { | ||
285 | v_buf = active_queue_pop(cap); | ||
286 | fimc_buf_finish(fimc, v_buf); | ||
287 | } | ||
288 | |||
289 | if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { | ||
290 | wake_up(&fimc->irq_queue); | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | if (!list_empty(&cap->pending_buf_q)) { | ||
295 | |||
296 | v_buf = pending_queue_pop(cap); | ||
297 | fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index); | ||
298 | v_buf->index = cap->buf_index; | ||
299 | |||
300 | dbg("hw ptr: %d, sw ptr: %d", | ||
301 | fimc_hw_get_frame_index(fimc), cap->buf_index); | ||
302 | |||
303 | spin_lock(&fimc->irqlock); | ||
304 | v_buf->vb.state = VIDEOBUF_ACTIVE; | ||
305 | spin_unlock(&fimc->irqlock); | ||
306 | |||
307 | /* Move the buffer to the capture active queue */ | ||
308 | active_queue_add(cap, v_buf); | ||
309 | |||
310 | dbg("next frame: %d, done frame: %d", | ||
311 | fimc_hw_get_frame_index(fimc), v_buf->index); | ||
312 | |||
313 | if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) | ||
314 | cap->buf_index = 0; | ||
315 | |||
316 | } else if (test_and_clear_bit(ST_CAPT_STREAM, &fimc->state) && | ||
317 | cap->active_buf_cnt <= 1) { | ||
318 | fimc_deactivate_capture(fimc); | ||
319 | } | ||
320 | |||
321 | dbg("frame: %d, active_buf_cnt= %d", | ||
322 | fimc_hw_get_frame_index(fimc), cap->active_buf_cnt); | ||
323 | } | ||
264 | 324 | ||
265 | static irqreturn_t fimc_isr(int irq, void *priv) | 325 | static irqreturn_t fimc_isr(int irq, void *priv) |
266 | { | 326 | { |
267 | struct fimc_vid_buffer *src_buf, *dst_buf; | 327 | struct fimc_vid_buffer *src_buf, *dst_buf; |
268 | struct fimc_dev *fimc = (struct fimc_dev *)priv; | ||
269 | struct fimc_ctx *ctx; | 328 | struct fimc_ctx *ctx; |
329 | struct fimc_dev *fimc = priv; | ||
270 | 330 | ||
271 | BUG_ON(!fimc); | 331 | BUG_ON(!fimc); |
272 | fimc_hw_clear_irq(fimc); | 332 | fimc_hw_clear_irq(fimc); |
@@ -281,12 +341,22 @@ static irqreturn_t fimc_isr(int irq, void *priv) | |||
281 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); | 341 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); |
282 | if (src_buf && dst_buf) { | 342 | if (src_buf && dst_buf) { |
283 | spin_lock(&fimc->irqlock); | 343 | spin_lock(&fimc->irqlock); |
284 | src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE; | 344 | src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE; |
285 | wake_up(&src_buf->vb.done); | 345 | wake_up(&src_buf->vb.done); |
286 | wake_up(&dst_buf->vb.done); | 346 | wake_up(&dst_buf->vb.done); |
287 | spin_unlock(&fimc->irqlock); | 347 | spin_unlock(&fimc->irqlock); |
288 | v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx); | 348 | v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx); |
289 | } | 349 | } |
350 | goto isr_unlock; | ||
351 | |||
352 | } | ||
353 | |||
354 | if (test_bit(ST_CAPT_RUN, &fimc->state)) | ||
355 | fimc_capture_handler(fimc); | ||
356 | |||
357 | if (test_and_clear_bit(ST_CAPT_PEND, &fimc->state)) { | ||
358 | set_bit(ST_CAPT_RUN, &fimc->state); | ||
359 | wake_up(&fimc->irq_queue); | ||
290 | } | 360 | } |
291 | 361 | ||
292 | isr_unlock: | 362 | isr_unlock: |
@@ -295,20 +365,13 @@ isr_unlock: | |||
295 | } | 365 | } |
296 | 366 | ||
297 | /* The color format (planes_cnt, buff_cnt) must be already configured. */ | 367 | /* The color format (planes_cnt, buff_cnt) must be already configured. */ |
298 | static int fimc_prepare_addr(struct fimc_ctx *ctx, | 368 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, |
299 | struct fimc_vid_buffer *buf, enum v4l2_buf_type type) | 369 | struct fimc_frame *frame, struct fimc_addr *paddr) |
300 | { | 370 | { |
301 | struct fimc_frame *frame; | ||
302 | struct fimc_addr *paddr; | ||
303 | u32 pix_size; | ||
304 | int ret = 0; | 371 | int ret = 0; |
372 | u32 pix_size; | ||
305 | 373 | ||
306 | frame = ctx_m2m_get_frame(ctx, type); | 374 | if (buf == NULL || frame == NULL) |
307 | if (IS_ERR(frame)) | ||
308 | return PTR_ERR(frame); | ||
309 | paddr = &frame->paddr; | ||
310 | |||
311 | if (!buf) | ||
312 | return -EINVAL; | 375 | return -EINVAL; |
313 | 376 | ||
314 | pix_size = frame->width * frame->height; | 377 | pix_size = frame->width * frame->height; |
@@ -344,8 +407,8 @@ static int fimc_prepare_addr(struct fimc_ctx *ctx, | |||
344 | } | 407 | } |
345 | } | 408 | } |
346 | 409 | ||
347 | dbg("PHYS_ADDR: type= %d, y= 0x%X cb= 0x%X cr= 0x%X ret= %d", | 410 | dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d", |
348 | type, paddr->y, paddr->cb, paddr->cr, ret); | 411 | paddr->y, paddr->cb, paddr->cr, ret); |
349 | 412 | ||
350 | return ret; | 413 | return ret; |
351 | } | 414 | } |
@@ -433,7 +496,7 @@ static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) | |||
433 | * | 496 | * |
434 | * Return: 0 if dimensions are valid or non zero otherwise. | 497 | * Return: 0 if dimensions are valid or non zero otherwise. |
435 | */ | 498 | */ |
436 | static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | 499 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) |
437 | { | 500 | { |
438 | struct fimc_frame *s_frame, *d_frame; | 501 | struct fimc_frame *s_frame, *d_frame; |
439 | struct fimc_vid_buffer *buf = NULL; | 502 | struct fimc_vid_buffer *buf = NULL; |
@@ -443,12 +506,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | |||
443 | d_frame = &ctx->d_frame; | 506 | d_frame = &ctx->d_frame; |
444 | 507 | ||
445 | if (flags & FIMC_PARAMS) { | 508 | if (flags & FIMC_PARAMS) { |
446 | if ((ctx->out_path == FIMC_DMA) && | ||
447 | (ctx->rotation == 90 || ctx->rotation == 270)) { | ||
448 | swap(d_frame->f_width, d_frame->f_height); | ||
449 | swap(d_frame->width, d_frame->height); | ||
450 | } | ||
451 | |||
452 | /* Prepare the DMA offset ratios for scaler. */ | 509 | /* Prepare the DMA offset ratios for scaler. */ |
453 | fimc_prepare_dma_offset(ctx, &ctx->s_frame); | 510 | fimc_prepare_dma_offset(ctx, &ctx->s_frame); |
454 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); | 511 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); |
@@ -466,16 +523,14 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | |||
466 | 523 | ||
467 | if (flags & FIMC_SRC_ADDR) { | 524 | if (flags & FIMC_SRC_ADDR) { |
468 | buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); | 525 | buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); |
469 | ret = fimc_prepare_addr(ctx, buf, | 526 | ret = fimc_prepare_addr(ctx, buf, s_frame, &s_frame->paddr); |
470 | V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
471 | if (ret) | 527 | if (ret) |
472 | return ret; | 528 | return ret; |
473 | } | 529 | } |
474 | 530 | ||
475 | if (flags & FIMC_DST_ADDR) { | 531 | if (flags & FIMC_DST_ADDR) { |
476 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); | 532 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); |
477 | ret = fimc_prepare_addr(ctx, buf, | 533 | ret = fimc_prepare_addr(ctx, buf, d_frame, &d_frame->paddr); |
478 | V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
479 | } | 534 | } |
480 | 535 | ||
481 | return ret; | 536 | return ret; |
@@ -499,12 +554,14 @@ static void fimc_dma_run(void *priv) | |||
499 | ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR); | 554 | ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR); |
500 | ret = fimc_prepare_config(ctx, ctx->state); | 555 | ret = fimc_prepare_config(ctx, ctx->state); |
501 | if (ret) { | 556 | if (ret) { |
502 | err("general configuration error"); | 557 | err("Wrong parameters"); |
503 | goto dma_unlock; | 558 | goto dma_unlock; |
504 | } | 559 | } |
505 | 560 | /* Reconfigure hardware if the context has changed. */ | |
506 | if (fimc->m2m.ctx != ctx) | 561 | if (fimc->m2m.ctx != ctx) { |
507 | ctx->state |= FIMC_PARAMS; | 562 | ctx->state |= FIMC_PARAMS; |
563 | fimc->m2m.ctx = ctx; | ||
564 | } | ||
508 | 565 | ||
509 | fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr); | 566 | fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr); |
510 | 567 | ||
@@ -512,10 +569,9 @@ static void fimc_dma_run(void *priv) | |||
512 | fimc_hw_set_input_path(ctx); | 569 | fimc_hw_set_input_path(ctx); |
513 | fimc_hw_set_in_dma(ctx); | 570 | fimc_hw_set_in_dma(ctx); |
514 | if (fimc_set_scaler_info(ctx)) { | 571 | if (fimc_set_scaler_info(ctx)) { |
515 | err("scaler configuration error"); | 572 | err("Scaler setup error"); |
516 | goto dma_unlock; | 573 | goto dma_unlock; |
517 | } | 574 | } |
518 | fimc_hw_set_prescaler(ctx); | ||
519 | fimc_hw_set_scaler(ctx); | 575 | fimc_hw_set_scaler(ctx); |
520 | fimc_hw_set_target_format(ctx); | 576 | fimc_hw_set_target_format(ctx); |
521 | fimc_hw_set_rotation(ctx); | 577 | fimc_hw_set_rotation(ctx); |
@@ -524,19 +580,15 @@ static void fimc_dma_run(void *priv) | |||
524 | 580 | ||
525 | fimc_hw_set_output_path(ctx); | 581 | fimc_hw_set_output_path(ctx); |
526 | if (ctx->state & (FIMC_DST_ADDR | FIMC_PARAMS)) | 582 | if (ctx->state & (FIMC_DST_ADDR | FIMC_PARAMS)) |
527 | fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr); | 583 | fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr, -1); |
528 | 584 | ||
529 | if (ctx->state & FIMC_PARAMS) | 585 | if (ctx->state & FIMC_PARAMS) |
530 | fimc_hw_set_out_dma(ctx); | 586 | fimc_hw_set_out_dma(ctx); |
531 | 587 | ||
532 | if (ctx->scaler.enabled) | 588 | fimc_activate_capture(ctx); |
533 | fimc_hw_start_scaler(fimc); | ||
534 | fimc_hw_en_capture(ctx); | ||
535 | 589 | ||
536 | ctx->state = 0; | 590 | ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP); |
537 | fimc_hw_start_in_dma(fimc); | 591 | fimc_hw_activate_input_dma(fimc, true); |
538 | |||
539 | fimc->m2m.ctx = ctx; | ||
540 | 592 | ||
541 | dma_unlock: | 593 | dma_unlock: |
542 | spin_unlock_irqrestore(&ctx->slock, flags); | 594 | spin_unlock_irqrestore(&ctx->slock, flags); |
@@ -560,7 +612,7 @@ static int fimc_buf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
560 | struct fimc_ctx *ctx = vq->priv_data; | 612 | struct fimc_ctx *ctx = vq->priv_data; |
561 | struct fimc_frame *frame; | 613 | struct fimc_frame *frame; |
562 | 614 | ||
563 | frame = ctx_m2m_get_frame(ctx, vq->type); | 615 | frame = ctx_get_frame(ctx, vq->type); |
564 | if (IS_ERR(frame)) | 616 | if (IS_ERR(frame)) |
565 | return PTR_ERR(frame); | 617 | return PTR_ERR(frame); |
566 | 618 | ||
@@ -578,7 +630,7 @@ static int fimc_buf_prepare(struct videobuf_queue *vq, | |||
578 | struct fimc_frame *frame; | 630 | struct fimc_frame *frame; |
579 | int ret; | 631 | int ret; |
580 | 632 | ||
581 | frame = ctx_m2m_get_frame(ctx, vq->type); | 633 | frame = ctx_get_frame(ctx, vq->type); |
582 | if (IS_ERR(frame)) | 634 | if (IS_ERR(frame)) |
583 | return PTR_ERR(frame); | 635 | return PTR_ERR(frame); |
584 | 636 | ||
@@ -618,10 +670,31 @@ static void fimc_buf_queue(struct videobuf_queue *vq, | |||
618 | struct videobuf_buffer *vb) | 670 | struct videobuf_buffer *vb) |
619 | { | 671 | { |
620 | struct fimc_ctx *ctx = vq->priv_data; | 672 | struct fimc_ctx *ctx = vq->priv_data; |
621 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb); | 673 | struct fimc_dev *fimc = ctx->fimc_dev; |
674 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
675 | unsigned long flags; | ||
676 | |||
677 | dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state); | ||
678 | |||
679 | if ((ctx->state & FIMC_CTX_M2M) && ctx->m2m_ctx) { | ||
680 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb); | ||
681 | } else if (ctx->state & FIMC_CTX_CAP) { | ||
682 | spin_lock_irqsave(&fimc->slock, flags); | ||
683 | fimc_vid_cap_buf_queue(fimc, (struct fimc_vid_buffer *)vb); | ||
684 | |||
685 | dbg("fimc->cap.active_buf_cnt: %d", | ||
686 | fimc->vid_cap.active_buf_cnt); | ||
687 | |||
688 | if (cap->active_buf_cnt >= cap->reqbufs_count || | ||
689 | cap->active_buf_cnt >= FIMC_MAX_OUT_BUFS) { | ||
690 | if (!test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) | ||
691 | fimc_activate_capture(ctx); | ||
692 | } | ||
693 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
694 | } | ||
622 | } | 695 | } |
623 | 696 | ||
624 | static struct videobuf_queue_ops fimc_qops = { | 697 | struct videobuf_queue_ops fimc_qops = { |
625 | .buf_setup = fimc_buf_setup, | 698 | .buf_setup = fimc_buf_setup, |
626 | .buf_prepare = fimc_buf_prepare, | 699 | .buf_prepare = fimc_buf_prepare, |
627 | .buf_queue = fimc_buf_queue, | 700 | .buf_queue = fimc_buf_queue, |
@@ -644,7 +717,7 @@ static int fimc_m2m_querycap(struct file *file, void *priv, | |||
644 | return 0; | 717 | return 0; |
645 | } | 718 | } |
646 | 719 | ||
647 | static int fimc_m2m_enum_fmt(struct file *file, void *priv, | 720 | int fimc_vidioc_enum_fmt(struct file *file, void *priv, |
648 | struct v4l2_fmtdesc *f) | 721 | struct v4l2_fmtdesc *f) |
649 | { | 722 | { |
650 | struct fimc_fmt *fmt; | 723 | struct fimc_fmt *fmt; |
@@ -655,189 +728,210 @@ static int fimc_m2m_enum_fmt(struct file *file, void *priv, | |||
655 | fmt = &fimc_formats[f->index]; | 728 | fmt = &fimc_formats[f->index]; |
656 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | 729 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); |
657 | f->pixelformat = fmt->fourcc; | 730 | f->pixelformat = fmt->fourcc; |
731 | |||
658 | return 0; | 732 | return 0; |
659 | } | 733 | } |
660 | 734 | ||
661 | static int fimc_m2m_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | 735 | int fimc_vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) |
662 | { | 736 | { |
663 | struct fimc_ctx *ctx = priv; | 737 | struct fimc_ctx *ctx = priv; |
738 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
664 | struct fimc_frame *frame; | 739 | struct fimc_frame *frame; |
665 | 740 | ||
666 | frame = ctx_m2m_get_frame(ctx, f->type); | 741 | frame = ctx_get_frame(ctx, f->type); |
667 | if (IS_ERR(frame)) | 742 | if (IS_ERR(frame)) |
668 | return PTR_ERR(frame); | 743 | return PTR_ERR(frame); |
669 | 744 | ||
745 | if (mutex_lock_interruptible(&fimc->lock)) | ||
746 | return -ERESTARTSYS; | ||
747 | |||
670 | f->fmt.pix.width = frame->width; | 748 | f->fmt.pix.width = frame->width; |
671 | f->fmt.pix.height = frame->height; | 749 | f->fmt.pix.height = frame->height; |
672 | f->fmt.pix.field = V4L2_FIELD_NONE; | 750 | f->fmt.pix.field = V4L2_FIELD_NONE; |
673 | f->fmt.pix.pixelformat = frame->fmt->fourcc; | 751 | f->fmt.pix.pixelformat = frame->fmt->fourcc; |
674 | 752 | ||
753 | mutex_unlock(&fimc->lock); | ||
675 | return 0; | 754 | return 0; |
676 | } | 755 | } |
677 | 756 | ||
678 | static struct fimc_fmt *find_format(struct v4l2_format *f) | 757 | struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask) |
679 | { | 758 | { |
680 | struct fimc_fmt *fmt; | 759 | struct fimc_fmt *fmt; |
681 | unsigned int i; | 760 | unsigned int i; |
682 | 761 | ||
683 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { | 762 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { |
684 | fmt = &fimc_formats[i]; | 763 | fmt = &fimc_formats[i]; |
685 | if (fmt->fourcc == f->fmt.pix.pixelformat) | 764 | if (fmt->fourcc == f->fmt.pix.pixelformat && |
765 | (fmt->flags & mask)) | ||
686 | break; | 766 | break; |
687 | } | 767 | } |
688 | if (i == ARRAY_SIZE(fimc_formats)) | ||
689 | return NULL; | ||
690 | 768 | ||
691 | return fmt; | 769 | return (i == ARRAY_SIZE(fimc_formats)) ? NULL : fmt; |
692 | } | 770 | } |
693 | 771 | ||
694 | static int fimc_m2m_try_fmt(struct file *file, void *priv, | 772 | struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, |
695 | struct v4l2_format *f) | 773 | unsigned int mask) |
696 | { | 774 | { |
697 | struct fimc_fmt *fmt; | 775 | struct fimc_fmt *fmt; |
698 | u32 max_width, max_height, mod_x, mod_y; | 776 | unsigned int i; |
777 | |||
778 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { | ||
779 | fmt = &fimc_formats[i]; | ||
780 | if (fmt->mbus_code == f->code && (fmt->flags & mask)) | ||
781 | break; | ||
782 | } | ||
783 | |||
784 | return (i == ARRAY_SIZE(fimc_formats)) ? NULL : fmt; | ||
785 | } | ||
786 | |||
787 | |||
788 | int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | ||
789 | { | ||
699 | struct fimc_ctx *ctx = priv; | 790 | struct fimc_ctx *ctx = priv; |
700 | struct fimc_dev *fimc = ctx->fimc_dev; | 791 | struct fimc_dev *fimc = ctx->fimc_dev; |
701 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
702 | struct samsung_fimc_variant *variant = fimc->variant; | 792 | struct samsung_fimc_variant *variant = fimc->variant; |
793 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
794 | struct fimc_fmt *fmt; | ||
795 | u32 max_width, mod_x, mod_y, mask; | ||
796 | int ret = -EINVAL, is_output = 0; | ||
703 | 797 | ||
704 | fmt = find_format(f); | 798 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { |
705 | if (!fmt) { | 799 | if (ctx->state & FIMC_CTX_CAP) |
706 | v4l2_err(&fimc->m2m.v4l2_dev, | 800 | return -EINVAL; |
707 | "Fourcc format (0x%X) invalid.\n", pix->pixelformat); | 801 | is_output = 1; |
802 | } else if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
708 | return -EINVAL; | 803 | return -EINVAL; |
709 | } | 804 | } |
710 | 805 | ||
806 | dbg("w: %d, h: %d, bpl: %d", | ||
807 | pix->width, pix->height, pix->bytesperline); | ||
808 | |||
809 | if (mutex_lock_interruptible(&fimc->lock)) | ||
810 | return -ERESTARTSYS; | ||
811 | |||
812 | mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM; | ||
813 | fmt = find_format(f, mask); | ||
814 | if (!fmt) { | ||
815 | v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n", | ||
816 | pix->pixelformat); | ||
817 | goto tf_out; | ||
818 | } | ||
819 | |||
711 | if (pix->field == V4L2_FIELD_ANY) | 820 | if (pix->field == V4L2_FIELD_ANY) |
712 | pix->field = V4L2_FIELD_NONE; | 821 | pix->field = V4L2_FIELD_NONE; |
713 | else if (V4L2_FIELD_NONE != pix->field) | 822 | else if (V4L2_FIELD_NONE != pix->field) |
714 | return -EINVAL; | 823 | goto tf_out; |
715 | 824 | ||
716 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | 825 | if (is_output) { |
717 | max_width = variant->scaler_dis_w; | 826 | max_width = variant->pix_limit->scaler_dis_w; |
718 | max_height = variant->scaler_dis_w; | 827 | mod_x = ffs(variant->min_inp_pixsize) - 1; |
719 | mod_x = variant->min_inp_pixsize; | ||
720 | mod_y = variant->min_inp_pixsize; | ||
721 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
722 | max_width = variant->out_rot_dis_w; | ||
723 | max_height = variant->out_rot_dis_w; | ||
724 | mod_x = variant->min_out_pixsize; | ||
725 | mod_y = variant->min_out_pixsize; | ||
726 | } else { | 828 | } else { |
727 | err("Wrong stream type (%d)", f->type); | 829 | max_width = variant->pix_limit->out_rot_dis_w; |
728 | return -EINVAL; | 830 | mod_x = ffs(variant->min_out_pixsize) - 1; |
729 | } | 831 | } |
730 | 832 | ||
731 | dbg("max_w= %d, max_h= %d", max_width, max_height); | ||
732 | |||
733 | if (pix->height > max_height) | ||
734 | pix->height = max_height; | ||
735 | if (pix->width > max_width) | ||
736 | pix->width = max_width; | ||
737 | |||
738 | if (tiled_fmt(fmt)) { | 833 | if (tiled_fmt(fmt)) { |
739 | mod_x = 64; /* 64x32 tile */ | 834 | mod_x = 6; /* 64 x 32 pixels tile */ |
740 | mod_y = 32; | 835 | mod_y = 5; |
836 | } else { | ||
837 | if (fimc->id == 1 && fimc->variant->pix_hoff) | ||
838 | mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1; | ||
839 | else | ||
840 | mod_y = mod_x; | ||
741 | } | 841 | } |
742 | 842 | ||
743 | dbg("mod_x= 0x%X, mod_y= 0x%X", mod_x, mod_y); | 843 | dbg("mod_x: %d, mod_y: %d, max_w: %d", mod_x, mod_y, max_width); |
744 | 844 | ||
745 | pix->width = (pix->width == 0) ? mod_x : ALIGN(pix->width, mod_x); | 845 | v4l_bound_align_image(&pix->width, 16, max_width, mod_x, |
746 | pix->height = (pix->height == 0) ? mod_y : ALIGN(pix->height, mod_y); | 846 | &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0); |
747 | 847 | ||
748 | if (pix->bytesperline == 0 || | 848 | if (pix->bytesperline == 0 || |
749 | pix->bytesperline * 8 / fmt->depth > pix->width) | 849 | (pix->bytesperline * 8 / fmt->depth) > pix->width) |
750 | pix->bytesperline = (pix->width * fmt->depth) >> 3; | 850 | pix->bytesperline = (pix->width * fmt->depth) >> 3; |
751 | 851 | ||
752 | if (pix->sizeimage == 0) | 852 | if (pix->sizeimage == 0) |
753 | pix->sizeimage = pix->height * pix->bytesperline; | 853 | pix->sizeimage = pix->height * pix->bytesperline; |
754 | 854 | ||
755 | dbg("pix->bytesperline= %d, fmt->depth= %d", | 855 | dbg("w: %d, h: %d, bpl: %d, depth: %d", |
756 | pix->bytesperline, fmt->depth); | 856 | pix->width, pix->height, pix->bytesperline, fmt->depth); |
757 | 857 | ||
758 | return 0; | 858 | ret = 0; |
759 | } | ||
760 | 859 | ||
860 | tf_out: | ||
861 | mutex_unlock(&fimc->lock); | ||
862 | return ret; | ||
863 | } | ||
761 | 864 | ||
762 | static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | 865 | static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) |
763 | { | 866 | { |
764 | struct fimc_ctx *ctx = priv; | 867 | struct fimc_ctx *ctx = priv; |
765 | struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev; | 868 | struct fimc_dev *fimc = ctx->fimc_dev; |
766 | struct videobuf_queue *src_vq, *dst_vq; | 869 | struct v4l2_device *v4l2_dev = &fimc->m2m.v4l2_dev; |
870 | struct videobuf_queue *vq; | ||
767 | struct fimc_frame *frame; | 871 | struct fimc_frame *frame; |
768 | struct v4l2_pix_format *pix; | 872 | struct v4l2_pix_format *pix; |
769 | unsigned long flags; | 873 | unsigned long flags; |
770 | int ret = 0; | 874 | int ret = 0; |
771 | 875 | ||
772 | BUG_ON(!ctx); | 876 | ret = fimc_vidioc_try_fmt(file, priv, f); |
773 | |||
774 | ret = fimc_m2m_try_fmt(file, priv, f); | ||
775 | if (ret) | 877 | if (ret) |
776 | return ret; | 878 | return ret; |
777 | 879 | ||
778 | mutex_lock(&ctx->fimc_dev->lock); | 880 | if (mutex_lock_interruptible(&fimc->lock)) |
881 | return -ERESTARTSYS; | ||
779 | 882 | ||
780 | src_vq = v4l2_m2m_get_src_vq(ctx->m2m_ctx); | 883 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
781 | dst_vq = v4l2_m2m_get_dst_vq(ctx->m2m_ctx); | 884 | mutex_lock(&vq->vb_lock); |
782 | 885 | ||
783 | mutex_lock(&src_vq->vb_lock); | 886 | if (videobuf_queue_is_busy(vq)) { |
784 | mutex_lock(&dst_vq->vb_lock); | 887 | v4l2_err(v4l2_dev, "%s: queue (%d) busy\n", __func__, f->type); |
888 | ret = -EBUSY; | ||
889 | goto sf_out; | ||
890 | } | ||
785 | 891 | ||
892 | spin_lock_irqsave(&ctx->slock, flags); | ||
786 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | 893 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { |
787 | if (videobuf_queue_is_busy(src_vq)) { | ||
788 | v4l2_err(v4l2_dev, "%s queue busy\n", __func__); | ||
789 | ret = -EBUSY; | ||
790 | goto s_fmt_out; | ||
791 | } | ||
792 | frame = &ctx->s_frame; | 894 | frame = &ctx->s_frame; |
793 | spin_lock_irqsave(&ctx->slock, flags); | ||
794 | ctx->state |= FIMC_SRC_FMT; | 895 | ctx->state |= FIMC_SRC_FMT; |
795 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
796 | |||
797 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 896 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
798 | if (videobuf_queue_is_busy(dst_vq)) { | ||
799 | v4l2_err(v4l2_dev, "%s queue busy\n", __func__); | ||
800 | ret = -EBUSY; | ||
801 | goto s_fmt_out; | ||
802 | } | ||
803 | frame = &ctx->d_frame; | 897 | frame = &ctx->d_frame; |
804 | spin_lock_irqsave(&ctx->slock, flags); | ||
805 | ctx->state |= FIMC_DST_FMT; | 898 | ctx->state |= FIMC_DST_FMT; |
806 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
807 | } else { | 899 | } else { |
900 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
808 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, | 901 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, |
809 | "Wrong buffer/video queue type (%d)\n", f->type); | 902 | "Wrong buffer/video queue type (%d)\n", f->type); |
810 | ret = -EINVAL; | 903 | ret = -EINVAL; |
811 | goto s_fmt_out; | 904 | goto sf_out; |
812 | } | 905 | } |
906 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
813 | 907 | ||
814 | pix = &f->fmt.pix; | 908 | pix = &f->fmt.pix; |
815 | frame->fmt = find_format(f); | 909 | frame->fmt = find_format(f, FMT_FLAGS_M2M); |
816 | if (!frame->fmt) { | 910 | if (!frame->fmt) { |
817 | ret = -EINVAL; | 911 | ret = -EINVAL; |
818 | goto s_fmt_out; | 912 | goto sf_out; |
819 | } | 913 | } |
820 | 914 | ||
821 | frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; | 915 | frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; |
822 | frame->f_height = pix->sizeimage/pix->bytesperline; | 916 | frame->f_height = pix->height; |
823 | frame->width = pix->width; | 917 | frame->width = pix->width; |
824 | frame->height = pix->height; | 918 | frame->height = pix->height; |
825 | frame->o_width = pix->width; | 919 | frame->o_width = pix->width; |
826 | frame->o_height = pix->height; | 920 | frame->o_height = pix->height; |
827 | frame->offs_h = 0; | 921 | frame->offs_h = 0; |
828 | frame->offs_v = 0; | 922 | frame->offs_v = 0; |
829 | frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3; | 923 | frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3; |
830 | src_vq->field = dst_vq->field = pix->field; | 924 | vq->field = pix->field; |
925 | |||
831 | spin_lock_irqsave(&ctx->slock, flags); | 926 | spin_lock_irqsave(&ctx->slock, flags); |
832 | ctx->state |= FIMC_PARAMS; | 927 | ctx->state |= FIMC_PARAMS; |
833 | spin_unlock_irqrestore(&ctx->slock, flags); | 928 | spin_unlock_irqrestore(&ctx->slock, flags); |
834 | 929 | ||
835 | dbg("f_width= %d, f_height= %d", frame->f_width, frame->f_height); | 930 | dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); |
836 | 931 | ||
837 | s_fmt_out: | 932 | sf_out: |
838 | mutex_unlock(&dst_vq->vb_lock); | 933 | mutex_unlock(&vq->vb_lock); |
839 | mutex_unlock(&src_vq->vb_lock); | 934 | mutex_unlock(&fimc->lock); |
840 | mutex_unlock(&ctx->fimc_dev->lock); | ||
841 | return ret; | 935 | return ret; |
842 | } | 936 | } |
843 | 937 | ||
@@ -884,21 +978,33 @@ static int fimc_m2m_streamoff(struct file *file, void *priv, | |||
884 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); | 978 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); |
885 | } | 979 | } |
886 | 980 | ||
887 | int fimc_m2m_queryctrl(struct file *file, void *priv, | 981 | int fimc_vidioc_queryctrl(struct file *file, void *priv, |
888 | struct v4l2_queryctrl *qc) | 982 | struct v4l2_queryctrl *qc) |
889 | { | 983 | { |
984 | struct fimc_ctx *ctx = priv; | ||
890 | struct v4l2_queryctrl *c; | 985 | struct v4l2_queryctrl *c; |
986 | |||
891 | c = get_ctrl(qc->id); | 987 | c = get_ctrl(qc->id); |
892 | if (!c) | 988 | if (c) { |
893 | return -EINVAL; | 989 | *qc = *c; |
894 | *qc = *c; | 990 | return 0; |
895 | return 0; | 991 | } |
992 | |||
993 | if (ctx->state & FIMC_CTX_CAP) | ||
994 | return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, | ||
995 | core, queryctrl, qc); | ||
996 | return -EINVAL; | ||
896 | } | 997 | } |
897 | 998 | ||
898 | int fimc_m2m_g_ctrl(struct file *file, void *priv, | 999 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, |
899 | struct v4l2_control *ctrl) | 1000 | struct v4l2_control *ctrl) |
900 | { | 1001 | { |
901 | struct fimc_ctx *ctx = priv; | 1002 | struct fimc_ctx *ctx = priv; |
1003 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
1004 | int ret = 0; | ||
1005 | |||
1006 | if (mutex_lock_interruptible(&fimc->lock)) | ||
1007 | return -ERESTARTSYS; | ||
902 | 1008 | ||
903 | switch (ctrl->id) { | 1009 | switch (ctrl->id) { |
904 | case V4L2_CID_HFLIP: | 1010 | case V4L2_CID_HFLIP: |
@@ -911,15 +1017,22 @@ int fimc_m2m_g_ctrl(struct file *file, void *priv, | |||
911 | ctrl->value = ctx->rotation; | 1017 | ctrl->value = ctx->rotation; |
912 | break; | 1018 | break; |
913 | default: | 1019 | default: |
914 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, "Invalid control\n"); | 1020 | if (ctx->state & FIMC_CTX_CAP) { |
915 | return -EINVAL; | 1021 | ret = v4l2_subdev_call(fimc->vid_cap.sd, core, |
1022 | g_ctrl, ctrl); | ||
1023 | } else { | ||
1024 | v4l2_err(&fimc->m2m.v4l2_dev, | ||
1025 | "Invalid control\n"); | ||
1026 | ret = -EINVAL; | ||
1027 | } | ||
916 | } | 1028 | } |
917 | dbg("ctrl->value= %d", ctrl->value); | 1029 | dbg("ctrl->value= %d", ctrl->value); |
918 | return 0; | 1030 | |
1031 | mutex_unlock(&fimc->lock); | ||
1032 | return ret; | ||
919 | } | 1033 | } |
920 | 1034 | ||
921 | static int check_ctrl_val(struct fimc_ctx *ctx, | 1035 | int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl) |
922 | struct v4l2_control *ctrl) | ||
923 | { | 1036 | { |
924 | struct v4l2_queryctrl *c; | 1037 | struct v4l2_queryctrl *c; |
925 | c = get_ctrl(ctrl->id); | 1038 | c = get_ctrl(ctrl->id); |
@@ -936,22 +1049,23 @@ static int check_ctrl_val(struct fimc_ctx *ctx, | |||
936 | return 0; | 1049 | return 0; |
937 | } | 1050 | } |
938 | 1051 | ||
939 | int fimc_m2m_s_ctrl(struct file *file, void *priv, | 1052 | int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl) |
940 | struct v4l2_control *ctrl) | ||
941 | { | 1053 | { |
942 | struct fimc_ctx *ctx = priv; | ||
943 | struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; | 1054 | struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; |
1055 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
944 | unsigned long flags; | 1056 | unsigned long flags; |
945 | int ret = 0; | ||
946 | 1057 | ||
947 | ret = check_ctrl_val(ctx, ctrl); | 1058 | if (ctx->rotation != 0 && |
948 | if (ret) | 1059 | (ctrl->id == V4L2_CID_HFLIP || ctrl->id == V4L2_CID_VFLIP)) { |
949 | return ret; | 1060 | v4l2_err(&fimc->m2m.v4l2_dev, |
1061 | "Simultaneous flip and rotation is not supported\n"); | ||
1062 | return -EINVAL; | ||
1063 | } | ||
1064 | |||
1065 | spin_lock_irqsave(&ctx->slock, flags); | ||
950 | 1066 | ||
951 | switch (ctrl->id) { | 1067 | switch (ctrl->id) { |
952 | case V4L2_CID_HFLIP: | 1068 | case V4L2_CID_HFLIP: |
953 | if (ctx->rotation != 0) | ||
954 | return 0; | ||
955 | if (ctrl->value) | 1069 | if (ctrl->value) |
956 | ctx->flip |= FLIP_X_AXIS; | 1070 | ctx->flip |= FLIP_X_AXIS; |
957 | else | 1071 | else |
@@ -959,8 +1073,6 @@ int fimc_m2m_s_ctrl(struct file *file, void *priv, | |||
959 | break; | 1073 | break; |
960 | 1074 | ||
961 | case V4L2_CID_VFLIP: | 1075 | case V4L2_CID_VFLIP: |
962 | if (ctx->rotation != 0) | ||
963 | return 0; | ||
964 | if (ctrl->value) | 1076 | if (ctrl->value) |
965 | ctx->flip |= FLIP_Y_AXIS; | 1077 | ctx->flip |= FLIP_Y_AXIS; |
966 | else | 1078 | else |
@@ -968,77 +1080,95 @@ int fimc_m2m_s_ctrl(struct file *file, void *priv, | |||
968 | break; | 1080 | break; |
969 | 1081 | ||
970 | case V4L2_CID_ROTATE: | 1082 | case V4L2_CID_ROTATE: |
971 | if (ctrl->value == 90 || ctrl->value == 270) { | 1083 | /* Check for the output rotator availability */ |
972 | if (ctx->out_path == FIMC_LCDFIFO && | 1084 | if ((ctrl->value == 90 || ctrl->value == 270) && |
973 | !variant->has_inp_rot) { | 1085 | (ctx->in_path == FIMC_DMA && !variant->has_out_rot)) { |
974 | return -EINVAL; | 1086 | spin_unlock_irqrestore(&ctx->slock, flags); |
975 | } else if (ctx->in_path == FIMC_DMA && | 1087 | return -EINVAL; |
976 | !variant->has_out_rot) { | 1088 | } else { |
977 | return -EINVAL; | 1089 | ctx->rotation = ctrl->value; |
978 | } | ||
979 | } | 1090 | } |
980 | ctx->rotation = ctrl->value; | ||
981 | if (ctrl->value == 180) | ||
982 | ctx->flip = FLIP_XY_AXIS; | ||
983 | break; | 1091 | break; |
984 | 1092 | ||
985 | default: | 1093 | default: |
986 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, "Invalid control\n"); | 1094 | spin_unlock_irqrestore(&ctx->slock, flags); |
1095 | v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n"); | ||
987 | return -EINVAL; | 1096 | return -EINVAL; |
988 | } | 1097 | } |
989 | spin_lock_irqsave(&ctx->slock, flags); | ||
990 | ctx->state |= FIMC_PARAMS; | 1098 | ctx->state |= FIMC_PARAMS; |
991 | spin_unlock_irqrestore(&ctx->slock, flags); | 1099 | spin_unlock_irqrestore(&ctx->slock, flags); |
1100 | |||
992 | return 0; | 1101 | return 0; |
993 | } | 1102 | } |
994 | 1103 | ||
1104 | static int fimc_m2m_s_ctrl(struct file *file, void *priv, | ||
1105 | struct v4l2_control *ctrl) | ||
1106 | { | ||
1107 | struct fimc_ctx *ctx = priv; | ||
1108 | int ret = 0; | ||
1109 | |||
1110 | ret = check_ctrl_val(ctx, ctrl); | ||
1111 | if (ret) | ||
1112 | return ret; | ||
1113 | |||
1114 | ret = fimc_s_ctrl(ctx, ctrl); | ||
1115 | return 0; | ||
1116 | } | ||
995 | 1117 | ||
996 | static int fimc_m2m_cropcap(struct file *file, void *fh, | 1118 | int fimc_vidioc_cropcap(struct file *file, void *fh, |
997 | struct v4l2_cropcap *cr) | 1119 | struct v4l2_cropcap *cr) |
998 | { | 1120 | { |
999 | struct fimc_frame *frame; | 1121 | struct fimc_frame *frame; |
1000 | struct fimc_ctx *ctx = fh; | 1122 | struct fimc_ctx *ctx = fh; |
1123 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
1001 | 1124 | ||
1002 | frame = ctx_m2m_get_frame(ctx, cr->type); | 1125 | frame = ctx_get_frame(ctx, cr->type); |
1003 | if (IS_ERR(frame)) | 1126 | if (IS_ERR(frame)) |
1004 | return PTR_ERR(frame); | 1127 | return PTR_ERR(frame); |
1005 | 1128 | ||
1006 | cr->bounds.left = 0; | 1129 | if (mutex_lock_interruptible(&fimc->lock)) |
1007 | cr->bounds.top = 0; | 1130 | return -ERESTARTSYS; |
1008 | cr->bounds.width = frame->f_width; | 1131 | |
1009 | cr->bounds.height = frame->f_height; | 1132 | cr->bounds.left = 0; |
1010 | cr->defrect.left = frame->offs_h; | 1133 | cr->bounds.top = 0; |
1011 | cr->defrect.top = frame->offs_v; | 1134 | cr->bounds.width = frame->f_width; |
1012 | cr->defrect.width = frame->o_width; | 1135 | cr->bounds.height = frame->f_height; |
1013 | cr->defrect.height = frame->o_height; | 1136 | cr->defrect = cr->bounds; |
1137 | |||
1138 | mutex_unlock(&fimc->lock); | ||
1014 | return 0; | 1139 | return 0; |
1015 | } | 1140 | } |
1016 | 1141 | ||
1017 | static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1142 | int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) |
1018 | { | 1143 | { |
1019 | struct fimc_frame *frame; | 1144 | struct fimc_frame *frame; |
1020 | struct fimc_ctx *ctx = file->private_data; | 1145 | struct fimc_ctx *ctx = file->private_data; |
1146 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
1021 | 1147 | ||
1022 | frame = ctx_m2m_get_frame(ctx, cr->type); | 1148 | frame = ctx_get_frame(ctx, cr->type); |
1023 | if (IS_ERR(frame)) | 1149 | if (IS_ERR(frame)) |
1024 | return PTR_ERR(frame); | 1150 | return PTR_ERR(frame); |
1025 | 1151 | ||
1152 | if (mutex_lock_interruptible(&fimc->lock)) | ||
1153 | return -ERESTARTSYS; | ||
1154 | |||
1026 | cr->c.left = frame->offs_h; | 1155 | cr->c.left = frame->offs_h; |
1027 | cr->c.top = frame->offs_v; | 1156 | cr->c.top = frame->offs_v; |
1028 | cr->c.width = frame->width; | 1157 | cr->c.width = frame->width; |
1029 | cr->c.height = frame->height; | 1158 | cr->c.height = frame->height; |
1030 | 1159 | ||
1160 | mutex_unlock(&fimc->lock); | ||
1031 | return 0; | 1161 | return 0; |
1032 | } | 1162 | } |
1033 | 1163 | ||
1034 | static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1164 | int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) |
1035 | { | 1165 | { |
1036 | struct fimc_ctx *ctx = file->private_data; | ||
1037 | struct fimc_dev *fimc = ctx->fimc_dev; | 1166 | struct fimc_dev *fimc = ctx->fimc_dev; |
1038 | unsigned long flags; | ||
1039 | struct fimc_frame *f; | 1167 | struct fimc_frame *f; |
1040 | u32 min_size; | 1168 | u32 min_size, halign; |
1041 | int ret = 0; | 1169 | |
1170 | f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? | ||
1171 | &ctx->s_frame : &ctx->d_frame; | ||
1042 | 1172 | ||
1043 | if (cr->c.top < 0 || cr->c.left < 0) { | 1173 | if (cr->c.top < 0 || cr->c.left < 0) { |
1044 | v4l2_err(&fimc->m2m.v4l2_dev, | 1174 | v4l2_err(&fimc->m2m.v4l2_dev, |
@@ -1046,66 +1176,98 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | |||
1046 | return -EINVAL; | 1176 | return -EINVAL; |
1047 | } | 1177 | } |
1048 | 1178 | ||
1049 | if (cr->c.width <= 0 || cr->c.height <= 0) { | 1179 | f = ctx_get_frame(ctx, cr->type); |
1050 | v4l2_err(&fimc->m2m.v4l2_dev, | ||
1051 | "crop width and height must be greater than 0\n"); | ||
1052 | return -EINVAL; | ||
1053 | } | ||
1054 | |||
1055 | f = ctx_m2m_get_frame(ctx, cr->type); | ||
1056 | if (IS_ERR(f)) | 1180 | if (IS_ERR(f)) |
1057 | return PTR_ERR(f); | 1181 | return PTR_ERR(f); |
1058 | 1182 | ||
1059 | /* Adjust to required pixel boundary. */ | 1183 | min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) |
1060 | min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? | 1184 | ? fimc->variant->min_inp_pixsize |
1061 | fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; | 1185 | : fimc->variant->min_out_pixsize; |
1062 | |||
1063 | cr->c.width = round_down(cr->c.width, min_size); | ||
1064 | cr->c.height = round_down(cr->c.height, min_size); | ||
1065 | cr->c.left = round_down(cr->c.left + 1, min_size); | ||
1066 | cr->c.top = round_down(cr->c.top + 1, min_size); | ||
1067 | 1186 | ||
1068 | if ((cr->c.left + cr->c.width > f->o_width) | 1187 | if (ctx->state & FIMC_CTX_M2M) { |
1069 | || (cr->c.top + cr->c.height > f->o_height)) { | 1188 | if (fimc->id == 1 && fimc->variant->pix_hoff) |
1070 | v4l2_err(&fimc->m2m.v4l2_dev, "Error in S_CROP params\n"); | 1189 | halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1; |
1071 | return -EINVAL; | 1190 | else |
1191 | halign = ffs(min_size) - 1; | ||
1192 | /* there are more strict aligment requirements at camera interface */ | ||
1193 | } else { | ||
1194 | min_size = 16; | ||
1195 | halign = 4; | ||
1072 | } | 1196 | } |
1073 | 1197 | ||
1198 | v4l_bound_align_image(&cr->c.width, min_size, f->o_width, | ||
1199 | ffs(min_size) - 1, | ||
1200 | &cr->c.height, min_size, f->o_height, | ||
1201 | halign, 64/(ALIGN(f->fmt->depth, 8))); | ||
1202 | |||
1203 | /* adjust left/top if cropping rectangle is out of bounds */ | ||
1204 | if (cr->c.left + cr->c.width > f->o_width) | ||
1205 | cr->c.left = f->o_width - cr->c.width; | ||
1206 | if (cr->c.top + cr->c.height > f->o_height) | ||
1207 | cr->c.top = f->o_height - cr->c.height; | ||
1208 | |||
1209 | cr->c.left = round_down(cr->c.left, min_size); | ||
1210 | cr->c.top = round_down(cr->c.top, | ||
1211 | ctx->state & FIMC_CTX_M2M ? 8 : 16); | ||
1212 | |||
1213 | dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d", | ||
1214 | cr->c.left, cr->c.top, cr->c.width, cr->c.height, | ||
1215 | f->f_width, f->f_height); | ||
1216 | |||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | |||
1221 | static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | ||
1222 | { | ||
1223 | struct fimc_ctx *ctx = file->private_data; | ||
1224 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
1225 | unsigned long flags; | ||
1226 | struct fimc_frame *f; | ||
1227 | int ret; | ||
1228 | |||
1229 | ret = fimc_try_crop(ctx, cr); | ||
1230 | if (ret) | ||
1231 | return ret; | ||
1232 | |||
1233 | f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? | ||
1234 | &ctx->s_frame : &ctx->d_frame; | ||
1235 | |||
1074 | spin_lock_irqsave(&ctx->slock, flags); | 1236 | spin_lock_irqsave(&ctx->slock, flags); |
1075 | if ((ctx->state & FIMC_SRC_FMT) && (ctx->state & FIMC_DST_FMT)) { | 1237 | if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { |
1076 | /* Check for the pixel scaling ratio when cropping input img. */ | 1238 | /* Check to see if scaling ratio is within supported range */ |
1077 | if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | 1239 | if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) |
1078 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); | 1240 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); |
1079 | else if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1241 | else |
1080 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); | 1242 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); |
1081 | |||
1082 | if (ret) { | 1243 | if (ret) { |
1083 | spin_unlock_irqrestore(&ctx->slock, flags); | 1244 | spin_unlock_irqrestore(&ctx->slock, flags); |
1084 | v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); | 1245 | v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); |
1085 | return -EINVAL; | 1246 | return -EINVAL; |
1086 | } | 1247 | } |
1087 | } | 1248 | } |
1088 | ctx->state |= FIMC_PARAMS; | 1249 | ctx->state |= FIMC_PARAMS; |
1089 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
1090 | 1250 | ||
1091 | f->offs_h = cr->c.left; | 1251 | f->offs_h = cr->c.left; |
1092 | f->offs_v = cr->c.top; | 1252 | f->offs_v = cr->c.top; |
1093 | f->width = cr->c.width; | 1253 | f->width = cr->c.width; |
1094 | f->height = cr->c.height; | 1254 | f->height = cr->c.height; |
1255 | |||
1256 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
1095 | return 0; | 1257 | return 0; |
1096 | } | 1258 | } |
1097 | 1259 | ||
1098 | static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { | 1260 | static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { |
1099 | .vidioc_querycap = fimc_m2m_querycap, | 1261 | .vidioc_querycap = fimc_m2m_querycap, |
1100 | 1262 | ||
1101 | .vidioc_enum_fmt_vid_cap = fimc_m2m_enum_fmt, | 1263 | .vidioc_enum_fmt_vid_cap = fimc_vidioc_enum_fmt, |
1102 | .vidioc_enum_fmt_vid_out = fimc_m2m_enum_fmt, | 1264 | .vidioc_enum_fmt_vid_out = fimc_vidioc_enum_fmt, |
1103 | 1265 | ||
1104 | .vidioc_g_fmt_vid_cap = fimc_m2m_g_fmt, | 1266 | .vidioc_g_fmt_vid_cap = fimc_vidioc_g_fmt, |
1105 | .vidioc_g_fmt_vid_out = fimc_m2m_g_fmt, | 1267 | .vidioc_g_fmt_vid_out = fimc_vidioc_g_fmt, |
1106 | 1268 | ||
1107 | .vidioc_try_fmt_vid_cap = fimc_m2m_try_fmt, | 1269 | .vidioc_try_fmt_vid_cap = fimc_vidioc_try_fmt, |
1108 | .vidioc_try_fmt_vid_out = fimc_m2m_try_fmt, | 1270 | .vidioc_try_fmt_vid_out = fimc_vidioc_try_fmt, |
1109 | 1271 | ||
1110 | .vidioc_s_fmt_vid_cap = fimc_m2m_s_fmt, | 1272 | .vidioc_s_fmt_vid_cap = fimc_m2m_s_fmt, |
1111 | .vidioc_s_fmt_vid_out = fimc_m2m_s_fmt, | 1273 | .vidioc_s_fmt_vid_out = fimc_m2m_s_fmt, |
@@ -1119,13 +1281,13 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { | |||
1119 | .vidioc_streamon = fimc_m2m_streamon, | 1281 | .vidioc_streamon = fimc_m2m_streamon, |
1120 | .vidioc_streamoff = fimc_m2m_streamoff, | 1282 | .vidioc_streamoff = fimc_m2m_streamoff, |
1121 | 1283 | ||
1122 | .vidioc_queryctrl = fimc_m2m_queryctrl, | 1284 | .vidioc_queryctrl = fimc_vidioc_queryctrl, |
1123 | .vidioc_g_ctrl = fimc_m2m_g_ctrl, | 1285 | .vidioc_g_ctrl = fimc_vidioc_g_ctrl, |
1124 | .vidioc_s_ctrl = fimc_m2m_s_ctrl, | 1286 | .vidioc_s_ctrl = fimc_m2m_s_ctrl, |
1125 | 1287 | ||
1126 | .vidioc_g_crop = fimc_m2m_g_crop, | 1288 | .vidioc_g_crop = fimc_vidioc_g_crop, |
1127 | .vidioc_s_crop = fimc_m2m_s_crop, | 1289 | .vidioc_s_crop = fimc_m2m_s_crop, |
1128 | .vidioc_cropcap = fimc_m2m_cropcap | 1290 | .vidioc_cropcap = fimc_vidioc_cropcap |
1129 | 1291 | ||
1130 | }; | 1292 | }; |
1131 | 1293 | ||
@@ -1136,9 +1298,9 @@ static void queue_init(void *priv, struct videobuf_queue *vq, | |||
1136 | struct fimc_dev *fimc = ctx->fimc_dev; | 1298 | struct fimc_dev *fimc = ctx->fimc_dev; |
1137 | 1299 | ||
1138 | videobuf_queue_dma_contig_init(vq, &fimc_qops, | 1300 | videobuf_queue_dma_contig_init(vq, &fimc_qops, |
1139 | fimc->m2m.v4l2_dev.dev, | 1301 | &fimc->pdev->dev, |
1140 | &fimc->irqlock, type, V4L2_FIELD_NONE, | 1302 | &fimc->irqlock, type, V4L2_FIELD_NONE, |
1141 | sizeof(struct fimc_vid_buffer), priv); | 1303 | sizeof(struct fimc_vid_buffer), priv, NULL); |
1142 | } | 1304 | } |
1143 | 1305 | ||
1144 | static int fimc_m2m_open(struct file *file) | 1306 | static int fimc_m2m_open(struct file *file) |
@@ -1147,25 +1309,38 @@ static int fimc_m2m_open(struct file *file) | |||
1147 | struct fimc_ctx *ctx = NULL; | 1309 | struct fimc_ctx *ctx = NULL; |
1148 | int err = 0; | 1310 | int err = 0; |
1149 | 1311 | ||
1150 | mutex_lock(&fimc->lock); | 1312 | if (mutex_lock_interruptible(&fimc->lock)) |
1313 | return -ERESTARTSYS; | ||
1314 | |||
1315 | dbg("pid: %d, state: 0x%lx, refcnt: %d", | ||
1316 | task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); | ||
1317 | |||
1318 | /* | ||
1319 | * Return if the corresponding video capture node | ||
1320 | * is already opened. | ||
1321 | */ | ||
1322 | if (fimc->vid_cap.refcnt > 0) { | ||
1323 | err = -EBUSY; | ||
1324 | goto err_unlock; | ||
1325 | } | ||
1326 | |||
1151 | fimc->m2m.refcnt++; | 1327 | fimc->m2m.refcnt++; |
1152 | set_bit(ST_OUTDMA_RUN, &fimc->state); | 1328 | set_bit(ST_OUTDMA_RUN, &fimc->state); |
1153 | mutex_unlock(&fimc->lock); | ||
1154 | |||
1155 | 1329 | ||
1156 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); | 1330 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
1157 | if (!ctx) | 1331 | if (!ctx) { |
1158 | return -ENOMEM; | 1332 | err = -ENOMEM; |
1333 | goto err_unlock; | ||
1334 | } | ||
1159 | 1335 | ||
1160 | file->private_data = ctx; | 1336 | file->private_data = ctx; |
1161 | ctx->fimc_dev = fimc; | 1337 | ctx->fimc_dev = fimc; |
1162 | /* default format */ | 1338 | /* Default color format */ |
1163 | ctx->s_frame.fmt = &fimc_formats[0]; | 1339 | ctx->s_frame.fmt = &fimc_formats[0]; |
1164 | ctx->d_frame.fmt = &fimc_formats[0]; | 1340 | ctx->d_frame.fmt = &fimc_formats[0]; |
1165 | /* per user process device context initialization */ | 1341 | /* Setup the device context for mem2mem mode. */ |
1166 | ctx->state = 0; | 1342 | ctx->state = FIMC_CTX_M2M; |
1167 | ctx->flags = 0; | 1343 | ctx->flags = 0; |
1168 | ctx->effect.type = S5P_FIMC_EFFECT_ORIGINAL; | ||
1169 | ctx->in_path = FIMC_DMA; | 1344 | ctx->in_path = FIMC_DMA; |
1170 | ctx->out_path = FIMC_DMA; | 1345 | ctx->out_path = FIMC_DMA; |
1171 | spin_lock_init(&ctx->slock); | 1346 | spin_lock_init(&ctx->slock); |
@@ -1175,6 +1350,9 @@ static int fimc_m2m_open(struct file *file) | |||
1175 | err = PTR_ERR(ctx->m2m_ctx); | 1350 | err = PTR_ERR(ctx->m2m_ctx); |
1176 | kfree(ctx); | 1351 | kfree(ctx); |
1177 | } | 1352 | } |
1353 | |||
1354 | err_unlock: | ||
1355 | mutex_unlock(&fimc->lock); | ||
1178 | return err; | 1356 | return err; |
1179 | } | 1357 | } |
1180 | 1358 | ||
@@ -1183,11 +1361,16 @@ static int fimc_m2m_release(struct file *file) | |||
1183 | struct fimc_ctx *ctx = file->private_data; | 1361 | struct fimc_ctx *ctx = file->private_data; |
1184 | struct fimc_dev *fimc = ctx->fimc_dev; | 1362 | struct fimc_dev *fimc = ctx->fimc_dev; |
1185 | 1363 | ||
1364 | mutex_lock(&fimc->lock); | ||
1365 | |||
1366 | dbg("pid: %d, state: 0x%lx, refcnt= %d", | ||
1367 | task_pid_nr(current), fimc->state, fimc->m2m.refcnt); | ||
1368 | |||
1186 | v4l2_m2m_ctx_release(ctx->m2m_ctx); | 1369 | v4l2_m2m_ctx_release(ctx->m2m_ctx); |
1187 | kfree(ctx); | 1370 | kfree(ctx); |
1188 | mutex_lock(&fimc->lock); | ||
1189 | if (--fimc->m2m.refcnt <= 0) | 1371 | if (--fimc->m2m.refcnt <= 0) |
1190 | clear_bit(ST_OUTDMA_RUN, &fimc->state); | 1372 | clear_bit(ST_OUTDMA_RUN, &fimc->state); |
1373 | |||
1191 | mutex_unlock(&fimc->lock); | 1374 | mutex_unlock(&fimc->lock); |
1192 | return 0; | 1375 | return 0; |
1193 | } | 1376 | } |
@@ -1196,6 +1379,7 @@ static unsigned int fimc_m2m_poll(struct file *file, | |||
1196 | struct poll_table_struct *wait) | 1379 | struct poll_table_struct *wait) |
1197 | { | 1380 | { |
1198 | struct fimc_ctx *ctx = file->private_data; | 1381 | struct fimc_ctx *ctx = file->private_data; |
1382 | |||
1199 | return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); | 1383 | return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); |
1200 | } | 1384 | } |
1201 | 1385 | ||
@@ -1203,6 +1387,7 @@ static unsigned int fimc_m2m_poll(struct file *file, | |||
1203 | static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) | 1387 | static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) |
1204 | { | 1388 | { |
1205 | struct fimc_ctx *ctx = file->private_data; | 1389 | struct fimc_ctx *ctx = file->private_data; |
1390 | |||
1206 | return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); | 1391 | return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); |
1207 | } | 1392 | } |
1208 | 1393 | ||
@@ -1241,7 +1426,7 @@ static int fimc_register_m2m_device(struct fimc_dev *fimc) | |||
1241 | 1426 | ||
1242 | ret = v4l2_device_register(&pdev->dev, v4l2_dev); | 1427 | ret = v4l2_device_register(&pdev->dev, v4l2_dev); |
1243 | if (ret) | 1428 | if (ret) |
1244 | return ret;; | 1429 | goto err_m2m_r1; |
1245 | 1430 | ||
1246 | vfd = video_device_alloc(); | 1431 | vfd = video_device_alloc(); |
1247 | if (!vfd) { | 1432 | if (!vfd) { |
@@ -1293,7 +1478,7 @@ static void fimc_unregister_m2m_device(struct fimc_dev *fimc) | |||
1293 | if (fimc) { | 1478 | if (fimc) { |
1294 | v4l2_m2m_release(fimc->m2m.m2m_dev); | 1479 | v4l2_m2m_release(fimc->m2m.m2m_dev); |
1295 | video_unregister_device(fimc->m2m.vfd); | 1480 | video_unregister_device(fimc->m2m.vfd); |
1296 | video_device_release(fimc->m2m.vfd); | 1481 | |
1297 | v4l2_device_unregister(&fimc->m2m.v4l2_dev); | 1482 | v4l2_device_unregister(&fimc->m2m.v4l2_dev); |
1298 | } | 1483 | } |
1299 | } | 1484 | } |
@@ -1337,7 +1522,7 @@ static int fimc_probe(struct platform_device *pdev) | |||
1337 | drv_data = (struct samsung_fimc_driverdata *) | 1522 | drv_data = (struct samsung_fimc_driverdata *) |
1338 | platform_get_device_id(pdev)->driver_data; | 1523 | platform_get_device_id(pdev)->driver_data; |
1339 | 1524 | ||
1340 | if (pdev->id >= drv_data->devs_cnt) { | 1525 | if (pdev->id >= drv_data->num_entities) { |
1341 | dev_err(&pdev->dev, "Invalid platform device id: %d\n", | 1526 | dev_err(&pdev->dev, "Invalid platform device id: %d\n", |
1342 | pdev->id); | 1527 | pdev->id); |
1343 | return -EINVAL; | 1528 | return -EINVAL; |
@@ -1350,9 +1535,11 @@ static int fimc_probe(struct platform_device *pdev) | |||
1350 | fimc->id = pdev->id; | 1535 | fimc->id = pdev->id; |
1351 | fimc->variant = drv_data->variant[fimc->id]; | 1536 | fimc->variant = drv_data->variant[fimc->id]; |
1352 | fimc->pdev = pdev; | 1537 | fimc->pdev = pdev; |
1538 | fimc->pdata = pdev->dev.platform_data; | ||
1353 | fimc->state = ST_IDLE; | 1539 | fimc->state = ST_IDLE; |
1354 | 1540 | ||
1355 | spin_lock_init(&fimc->irqlock); | 1541 | spin_lock_init(&fimc->irqlock); |
1542 | init_waitqueue_head(&fimc->irq_queue); | ||
1356 | spin_lock_init(&fimc->slock); | 1543 | spin_lock_init(&fimc->slock); |
1357 | 1544 | ||
1358 | mutex_init(&fimc->lock); | 1545 | mutex_init(&fimc->lock); |
@@ -1382,6 +1569,7 @@ static int fimc_probe(struct platform_device *pdev) | |||
1382 | ret = fimc_clk_get(fimc); | 1569 | ret = fimc_clk_get(fimc); |
1383 | if (ret) | 1570 | if (ret) |
1384 | goto err_regs_unmap; | 1571 | goto err_regs_unmap; |
1572 | clk_set_rate(fimc->clock[0], drv_data->lclk_frequency); | ||
1385 | 1573 | ||
1386 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1574 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1387 | if (!res) { | 1575 | if (!res) { |
@@ -1399,25 +1587,38 @@ static int fimc_probe(struct platform_device *pdev) | |||
1399 | goto err_clk; | 1587 | goto err_clk; |
1400 | } | 1588 | } |
1401 | 1589 | ||
1402 | fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev)); | ||
1403 | if (!fimc->work_queue) { | ||
1404 | ret = -ENOMEM; | ||
1405 | goto err_irq; | ||
1406 | } | ||
1407 | |||
1408 | ret = fimc_register_m2m_device(fimc); | 1590 | ret = fimc_register_m2m_device(fimc); |
1409 | if (ret) | 1591 | if (ret) |
1410 | goto err_wq; | 1592 | goto err_irq; |
1593 | |||
1594 | /* At least one camera sensor is required to register capture node */ | ||
1595 | if (fimc->pdata) { | ||
1596 | int i; | ||
1597 | for (i = 0; i < FIMC_MAX_CAMIF_CLIENTS; ++i) | ||
1598 | if (fimc->pdata->isp_info[i]) | ||
1599 | break; | ||
1600 | |||
1601 | if (i < FIMC_MAX_CAMIF_CLIENTS) { | ||
1602 | ret = fimc_register_capture_device(fimc); | ||
1603 | if (ret) | ||
1604 | goto err_m2m; | ||
1605 | } | ||
1606 | } | ||
1411 | 1607 | ||
1412 | fimc_hw_en_lastirq(fimc, true); | 1608 | /* |
1609 | * Exclude the additional output DMA address registers by masking | ||
1610 | * them out on HW revisions that provide extended capabilites. | ||
1611 | */ | ||
1612 | if (fimc->variant->out_buf_count > 4) | ||
1613 | fimc_hw_set_dma_seq(fimc, 0xF); | ||
1413 | 1614 | ||
1414 | dev_dbg(&pdev->dev, "%s(): fimc-%d registered successfully\n", | 1615 | dev_dbg(&pdev->dev, "%s(): fimc-%d registered successfully\n", |
1415 | __func__, fimc->id); | 1616 | __func__, fimc->id); |
1416 | 1617 | ||
1417 | return 0; | 1618 | return 0; |
1418 | 1619 | ||
1419 | err_wq: | 1620 | err_m2m: |
1420 | destroy_workqueue(fimc->work_queue); | 1621 | fimc_unregister_m2m_device(fimc); |
1421 | err_irq: | 1622 | err_irq: |
1422 | free_irq(fimc->irq, fimc); | 1623 | free_irq(fimc->irq, fimc); |
1423 | err_clk: | 1624 | err_clk: |
@@ -1429,7 +1630,7 @@ err_req_region: | |||
1429 | kfree(fimc->regs_res); | 1630 | kfree(fimc->regs_res); |
1430 | err_info: | 1631 | err_info: |
1431 | kfree(fimc); | 1632 | kfree(fimc); |
1432 | dev_err(&pdev->dev, "failed to install\n"); | 1633 | |
1433 | return ret; | 1634 | return ret; |
1434 | } | 1635 | } |
1435 | 1636 | ||
@@ -1438,91 +1639,151 @@ static int __devexit fimc_remove(struct platform_device *pdev) | |||
1438 | struct fimc_dev *fimc = | 1639 | struct fimc_dev *fimc = |
1439 | (struct fimc_dev *)platform_get_drvdata(pdev); | 1640 | (struct fimc_dev *)platform_get_drvdata(pdev); |
1440 | 1641 | ||
1441 | v4l2_info(&fimc->m2m.v4l2_dev, "Removing %s\n", pdev->name); | ||
1442 | |||
1443 | free_irq(fimc->irq, fimc); | 1642 | free_irq(fimc->irq, fimc); |
1444 | |||
1445 | fimc_hw_reset(fimc); | 1643 | fimc_hw_reset(fimc); |
1446 | 1644 | ||
1447 | fimc_unregister_m2m_device(fimc); | 1645 | fimc_unregister_m2m_device(fimc); |
1646 | fimc_unregister_capture_device(fimc); | ||
1647 | |||
1448 | fimc_clk_release(fimc); | 1648 | fimc_clk_release(fimc); |
1449 | iounmap(fimc->regs); | 1649 | iounmap(fimc->regs); |
1450 | release_resource(fimc->regs_res); | 1650 | release_resource(fimc->regs_res); |
1451 | kfree(fimc->regs_res); | 1651 | kfree(fimc->regs_res); |
1452 | kfree(fimc); | 1652 | kfree(fimc); |
1653 | |||
1654 | dev_info(&pdev->dev, "%s driver unloaded\n", pdev->name); | ||
1453 | return 0; | 1655 | return 0; |
1454 | } | 1656 | } |
1455 | 1657 | ||
1456 | static struct samsung_fimc_variant fimc01_variant_s5p = { | 1658 | /* Image pixel limits, similar across several FIMC HW revisions. */ |
1457 | .has_inp_rot = 1, | 1659 | static struct fimc_pix_limit s5p_pix_limit[3] = { |
1458 | .has_out_rot = 1, | 1660 | [0] = { |
1661 | .scaler_en_w = 3264, | ||
1662 | .scaler_dis_w = 8192, | ||
1663 | .in_rot_en_h = 1920, | ||
1664 | .in_rot_dis_w = 8192, | ||
1665 | .out_rot_en_w = 1920, | ||
1666 | .out_rot_dis_w = 4224, | ||
1667 | }, | ||
1668 | [1] = { | ||
1669 | .scaler_en_w = 4224, | ||
1670 | .scaler_dis_w = 8192, | ||
1671 | .in_rot_en_h = 1920, | ||
1672 | .in_rot_dis_w = 8192, | ||
1673 | .out_rot_en_w = 1920, | ||
1674 | .out_rot_dis_w = 4224, | ||
1675 | }, | ||
1676 | [2] = { | ||
1677 | .scaler_en_w = 1920, | ||
1678 | .scaler_dis_w = 8192, | ||
1679 | .in_rot_en_h = 1280, | ||
1680 | .in_rot_dis_w = 8192, | ||
1681 | .out_rot_en_w = 1280, | ||
1682 | .out_rot_dis_w = 1920, | ||
1683 | }, | ||
1684 | }; | ||
1685 | |||
1686 | static struct samsung_fimc_variant fimc0_variant_s5p = { | ||
1687 | .has_inp_rot = 1, | ||
1688 | .has_out_rot = 1, | ||
1459 | .min_inp_pixsize = 16, | 1689 | .min_inp_pixsize = 16, |
1460 | .min_out_pixsize = 16, | 1690 | .min_out_pixsize = 16, |
1461 | 1691 | .hor_offs_align = 8, | |
1462 | .scaler_en_w = 3264, | 1692 | .out_buf_count = 4, |
1463 | .scaler_dis_w = 8192, | 1693 | .pix_limit = &s5p_pix_limit[0], |
1464 | .in_rot_en_h = 1920, | ||
1465 | .in_rot_dis_w = 8192, | ||
1466 | .out_rot_en_w = 1920, | ||
1467 | .out_rot_dis_w = 4224, | ||
1468 | }; | 1694 | }; |
1469 | 1695 | ||
1470 | static struct samsung_fimc_variant fimc2_variant_s5p = { | 1696 | static struct samsung_fimc_variant fimc2_variant_s5p = { |
1471 | .min_inp_pixsize = 16, | 1697 | .min_inp_pixsize = 16, |
1472 | .min_out_pixsize = 16, | 1698 | .min_out_pixsize = 16, |
1699 | .hor_offs_align = 8, | ||
1700 | .out_buf_count = 4, | ||
1701 | .pix_limit = &s5p_pix_limit[1], | ||
1702 | }; | ||
1473 | 1703 | ||
1474 | .scaler_en_w = 4224, | 1704 | static struct samsung_fimc_variant fimc0_variant_s5pv210 = { |
1475 | .scaler_dis_w = 8192, | 1705 | .pix_hoff = 1, |
1476 | .in_rot_en_h = 1920, | 1706 | .has_inp_rot = 1, |
1477 | .in_rot_dis_w = 8192, | 1707 | .has_out_rot = 1, |
1478 | .out_rot_en_w = 1920, | 1708 | .min_inp_pixsize = 16, |
1479 | .out_rot_dis_w = 4224, | 1709 | .min_out_pixsize = 16, |
1710 | .hor_offs_align = 8, | ||
1711 | .out_buf_count = 4, | ||
1712 | .pix_limit = &s5p_pix_limit[1], | ||
1480 | }; | 1713 | }; |
1481 | 1714 | ||
1482 | static struct samsung_fimc_variant fimc01_variant_s5pv210 = { | 1715 | static struct samsung_fimc_variant fimc1_variant_s5pv210 = { |
1483 | .pix_hoff = 1, | 1716 | .pix_hoff = 1, |
1484 | .has_inp_rot = 1, | 1717 | .has_inp_rot = 1, |
1485 | .has_out_rot = 1, | 1718 | .has_out_rot = 1, |
1486 | .min_inp_pixsize = 16, | 1719 | .min_inp_pixsize = 16, |
1487 | .min_out_pixsize = 32, | 1720 | .min_out_pixsize = 16, |
1488 | 1721 | .hor_offs_align = 1, | |
1489 | .scaler_en_w = 4224, | 1722 | .out_buf_count = 4, |
1490 | .scaler_dis_w = 8192, | 1723 | .pix_limit = &s5p_pix_limit[2], |
1491 | .in_rot_en_h = 1920, | ||
1492 | .in_rot_dis_w = 8192, | ||
1493 | .out_rot_en_w = 1920, | ||
1494 | .out_rot_dis_w = 4224, | ||
1495 | }; | 1724 | }; |
1496 | 1725 | ||
1497 | static struct samsung_fimc_variant fimc2_variant_s5pv210 = { | 1726 | static struct samsung_fimc_variant fimc2_variant_s5pv210 = { |
1498 | .pix_hoff = 1, | 1727 | .pix_hoff = 1, |
1499 | .min_inp_pixsize = 16, | 1728 | .min_inp_pixsize = 16, |
1500 | .min_out_pixsize = 32, | 1729 | .min_out_pixsize = 16, |
1501 | 1730 | .hor_offs_align = 8, | |
1502 | .scaler_en_w = 1920, | 1731 | .out_buf_count = 4, |
1503 | .scaler_dis_w = 8192, | 1732 | .pix_limit = &s5p_pix_limit[2], |
1504 | .in_rot_en_h = 1280, | 1733 | }; |
1505 | .in_rot_dis_w = 8192, | 1734 | |
1506 | .out_rot_en_w = 1280, | 1735 | static struct samsung_fimc_variant fimc0_variant_s5pv310 = { |
1507 | .out_rot_dis_w = 1920, | 1736 | .pix_hoff = 1, |
1737 | .has_inp_rot = 1, | ||
1738 | .has_out_rot = 1, | ||
1739 | .min_inp_pixsize = 16, | ||
1740 | .min_out_pixsize = 16, | ||
1741 | .hor_offs_align = 1, | ||
1742 | .out_buf_count = 32, | ||
1743 | .pix_limit = &s5p_pix_limit[1], | ||
1744 | }; | ||
1745 | |||
1746 | static struct samsung_fimc_variant fimc2_variant_s5pv310 = { | ||
1747 | .pix_hoff = 1, | ||
1748 | .min_inp_pixsize = 16, | ||
1749 | .min_out_pixsize = 16, | ||
1750 | .hor_offs_align = 1, | ||
1751 | .out_buf_count = 32, | ||
1752 | .pix_limit = &s5p_pix_limit[2], | ||
1508 | }; | 1753 | }; |
1509 | 1754 | ||
1755 | /* S5PC100 */ | ||
1510 | static struct samsung_fimc_driverdata fimc_drvdata_s5p = { | 1756 | static struct samsung_fimc_driverdata fimc_drvdata_s5p = { |
1511 | .variant = { | 1757 | .variant = { |
1512 | [0] = &fimc01_variant_s5p, | 1758 | [0] = &fimc0_variant_s5p, |
1513 | [1] = &fimc01_variant_s5p, | 1759 | [1] = &fimc0_variant_s5p, |
1514 | [2] = &fimc2_variant_s5p, | 1760 | [2] = &fimc2_variant_s5p, |
1515 | }, | 1761 | }, |
1516 | .devs_cnt = 3 | 1762 | .num_entities = 3, |
1763 | .lclk_frequency = 133000000UL, | ||
1517 | }; | 1764 | }; |
1518 | 1765 | ||
1766 | /* S5PV210, S5PC110 */ | ||
1519 | static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { | 1767 | static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { |
1520 | .variant = { | 1768 | .variant = { |
1521 | [0] = &fimc01_variant_s5pv210, | 1769 | [0] = &fimc0_variant_s5pv210, |
1522 | [1] = &fimc01_variant_s5pv210, | 1770 | [1] = &fimc1_variant_s5pv210, |
1523 | [2] = &fimc2_variant_s5pv210, | 1771 | [2] = &fimc2_variant_s5pv210, |
1524 | }, | 1772 | }, |
1525 | .devs_cnt = 3 | 1773 | .num_entities = 3, |
1774 | .lclk_frequency = 166000000UL, | ||
1775 | }; | ||
1776 | |||
1777 | /* S5PV310, S5PC210 */ | ||
1778 | static struct samsung_fimc_driverdata fimc_drvdata_s5pv310 = { | ||
1779 | .variant = { | ||
1780 | [0] = &fimc0_variant_s5pv310, | ||
1781 | [1] = &fimc0_variant_s5pv310, | ||
1782 | [2] = &fimc0_variant_s5pv310, | ||
1783 | [3] = &fimc2_variant_s5pv310, | ||
1784 | }, | ||
1785 | .num_entities = 4, | ||
1786 | .lclk_frequency = 166000000UL, | ||
1526 | }; | 1787 | }; |
1527 | 1788 | ||
1528 | static struct platform_device_id fimc_driver_ids[] = { | 1789 | static struct platform_device_id fimc_driver_ids[] = { |
@@ -1532,6 +1793,9 @@ static struct platform_device_id fimc_driver_ids[] = { | |||
1532 | }, { | 1793 | }, { |
1533 | .name = "s5pv210-fimc", | 1794 | .name = "s5pv210-fimc", |
1534 | .driver_data = (unsigned long)&fimc_drvdata_s5pv210, | 1795 | .driver_data = (unsigned long)&fimc_drvdata_s5pv210, |
1796 | }, { | ||
1797 | .name = "s5pv310-fimc", | ||
1798 | .driver_data = (unsigned long)&fimc_drvdata_s5pv310, | ||
1535 | }, | 1799 | }, |
1536 | {}, | 1800 | {}, |
1537 | }; | 1801 | }; |
@@ -1547,20 +1811,12 @@ static struct platform_driver fimc_driver = { | |||
1547 | } | 1811 | } |
1548 | }; | 1812 | }; |
1549 | 1813 | ||
1550 | static char banner[] __initdata = KERN_INFO | ||
1551 | "S5PC Camera Interface V4L2 Driver, (c) 2010 Samsung Electronics\n"; | ||
1552 | |||
1553 | static int __init fimc_init(void) | 1814 | static int __init fimc_init(void) |
1554 | { | 1815 | { |
1555 | u32 ret; | 1816 | int ret = platform_driver_register(&fimc_driver); |
1556 | printk(banner); | 1817 | if (ret) |
1557 | 1818 | err("platform_driver_register failed: %d\n", ret); | |
1558 | ret = platform_driver_register(&fimc_driver); | 1819 | return ret; |
1559 | if (ret) { | ||
1560 | printk(KERN_ERR "FIMC platform driver register failed\n"); | ||
1561 | return -1; | ||
1562 | } | ||
1563 | return 0; | ||
1564 | } | 1820 | } |
1565 | 1821 | ||
1566 | static void __exit fimc_exit(void) | 1822 | static void __exit fimc_exit(void) |
@@ -1571,6 +1827,6 @@ static void __exit fimc_exit(void) | |||
1571 | module_init(fimc_init); | 1827 | module_init(fimc_init); |
1572 | module_exit(fimc_exit); | 1828 | module_exit(fimc_exit); |
1573 | 1829 | ||
1574 | MODULE_AUTHOR("Sylwester Nawrocki, s.nawrocki@samsung.com"); | 1830 | MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); |
1575 | MODULE_DESCRIPTION("S3C/S5P FIMC (video postprocessor) driver"); | 1831 | MODULE_DESCRIPTION("S5P FIMC camera host interface/video postprocessor driver"); |
1576 | MODULE_LICENSE("GPL"); | 1832 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 6b3e0cd73cd..3e107851656 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -11,10 +11,14 @@ | |||
11 | #ifndef FIMC_CORE_H_ | 11 | #ifndef FIMC_CORE_H_ |
12 | #define FIMC_CORE_H_ | 12 | #define FIMC_CORE_H_ |
13 | 13 | ||
14 | /*#define DEBUG*/ | ||
15 | |||
14 | #include <linux/types.h> | 16 | #include <linux/types.h> |
15 | #include <media/videobuf-core.h> | 17 | #include <media/videobuf-core.h> |
16 | #include <media/v4l2-device.h> | 18 | #include <media/v4l2-device.h> |
17 | #include <media/v4l2-mem2mem.h> | 19 | #include <media/v4l2-mem2mem.h> |
20 | #include <media/v4l2-mediabus.h> | ||
21 | #include <media/s3c_fimc.h> | ||
18 | #include <linux/videodev2.h> | 22 | #include <linux/videodev2.h> |
19 | #include "regs-fimc.h" | 23 | #include "regs-fimc.h" |
20 | 24 | ||
@@ -28,47 +32,72 @@ | |||
28 | #define dbg(fmt, args...) | 32 | #define dbg(fmt, args...) |
29 | #endif | 33 | #endif |
30 | 34 | ||
35 | /* Time to wait for next frame VSYNC interrupt while stopping operation. */ | ||
36 | #define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000) | ||
31 | #define NUM_FIMC_CLOCKS 2 | 37 | #define NUM_FIMC_CLOCKS 2 |
32 | #define MODULE_NAME "s5p-fimc" | 38 | #define MODULE_NAME "s5p-fimc" |
33 | #define FIMC_MAX_DEVS 3 | 39 | #define FIMC_MAX_DEVS 4 |
34 | #define FIMC_MAX_OUT_BUFS 4 | 40 | #define FIMC_MAX_OUT_BUFS 4 |
35 | #define SCALER_MAX_HRATIO 64 | 41 | #define SCALER_MAX_HRATIO 64 |
36 | #define SCALER_MAX_VRATIO 64 | 42 | #define SCALER_MAX_VRATIO 64 |
43 | #define DMA_MIN_SIZE 8 | ||
37 | 44 | ||
38 | enum { | 45 | /* FIMC device state flags */ |
46 | enum fimc_dev_flags { | ||
47 | /* for m2m node */ | ||
39 | ST_IDLE, | 48 | ST_IDLE, |
40 | ST_OUTDMA_RUN, | 49 | ST_OUTDMA_RUN, |
41 | ST_M2M_PEND, | 50 | ST_M2M_PEND, |
51 | /* for capture node */ | ||
52 | ST_CAPT_PEND, | ||
53 | ST_CAPT_RUN, | ||
54 | ST_CAPT_STREAM, | ||
55 | ST_CAPT_SHUT, | ||
42 | }; | 56 | }; |
43 | 57 | ||
44 | #define fimc_m2m_active(dev) test_bit(ST_OUTDMA_RUN, &(dev)->state) | 58 | #define fimc_m2m_active(dev) test_bit(ST_OUTDMA_RUN, &(dev)->state) |
45 | #define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state) | 59 | #define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state) |
46 | 60 | ||
61 | #define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state) | ||
62 | #define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state) | ||
63 | |||
64 | #define fimc_capture_active(dev) \ | ||
65 | (test_bit(ST_CAPT_RUN, &(dev)->state) || \ | ||
66 | test_bit(ST_CAPT_PEND, &(dev)->state)) | ||
67 | |||
68 | #define fimc_capture_streaming(dev) \ | ||
69 | test_bit(ST_CAPT_STREAM, &(dev)->state) | ||
70 | |||
71 | #define fimc_buf_finish(dev, vid_buf) do { \ | ||
72 | spin_lock(&(dev)->irqlock); \ | ||
73 | (vid_buf)->vb.state = VIDEOBUF_DONE; \ | ||
74 | spin_unlock(&(dev)->irqlock); \ | ||
75 | wake_up(&(vid_buf)->vb.done); \ | ||
76 | } while (0) | ||
77 | |||
47 | enum fimc_datapath { | 78 | enum fimc_datapath { |
48 | FIMC_ITU_CAM_A, | 79 | FIMC_CAMERA, |
49 | FIMC_ITU_CAM_B, | ||
50 | FIMC_MIPI_CAM, | ||
51 | FIMC_DMA, | 80 | FIMC_DMA, |
52 | FIMC_LCDFIFO, | 81 | FIMC_LCDFIFO, |
53 | FIMC_WRITEBACK | 82 | FIMC_WRITEBACK |
54 | }; | 83 | }; |
55 | 84 | ||
56 | enum fimc_color_fmt { | 85 | enum fimc_color_fmt { |
57 | S5P_FIMC_RGB565, | 86 | S5P_FIMC_RGB565 = 0x10, |
58 | S5P_FIMC_RGB666, | 87 | S5P_FIMC_RGB666, |
59 | S5P_FIMC_RGB888, | 88 | S5P_FIMC_RGB888, |
60 | S5P_FIMC_YCBCR420, | 89 | S5P_FIMC_RGB30_LOCAL, |
90 | S5P_FIMC_YCBCR420 = 0x20, | ||
61 | S5P_FIMC_YCBCR422, | 91 | S5P_FIMC_YCBCR422, |
62 | S5P_FIMC_YCBYCR422, | 92 | S5P_FIMC_YCBYCR422, |
63 | S5P_FIMC_YCRYCB422, | 93 | S5P_FIMC_YCRYCB422, |
64 | S5P_FIMC_CBYCRY422, | 94 | S5P_FIMC_CBYCRY422, |
65 | S5P_FIMC_CRYCBY422, | 95 | S5P_FIMC_CRYCBY422, |
66 | S5P_FIMC_RGB30_LOCAL, | ||
67 | S5P_FIMC_YCBCR444_LOCAL, | 96 | S5P_FIMC_YCBCR444_LOCAL, |
68 | S5P_FIMC_MAX_COLOR = S5P_FIMC_YCBCR444_LOCAL, | ||
69 | S5P_FIMC_COLOR_MASK = 0x0F, | ||
70 | }; | 97 | }; |
71 | 98 | ||
99 | #define fimc_fmt_is_rgb(x) ((x) & 0x10) | ||
100 | |||
72 | /* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */ | 101 | /* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */ |
73 | #define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY | 102 | #define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY |
74 | #define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB | 103 | #define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB |
@@ -93,11 +122,13 @@ enum fimc_color_fmt { | |||
93 | #define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE | 122 | #define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE |
94 | 123 | ||
95 | /* The hardware context state. */ | 124 | /* The hardware context state. */ |
96 | #define FIMC_PARAMS (1 << 0) | 125 | #define FIMC_PARAMS (1 << 0) |
97 | #define FIMC_SRC_ADDR (1 << 1) | 126 | #define FIMC_SRC_ADDR (1 << 1) |
98 | #define FIMC_DST_ADDR (1 << 2) | 127 | #define FIMC_DST_ADDR (1 << 2) |
99 | #define FIMC_SRC_FMT (1 << 3) | 128 | #define FIMC_SRC_FMT (1 << 3) |
100 | #define FIMC_DST_FMT (1 << 4) | 129 | #define FIMC_DST_FMT (1 << 4) |
130 | #define FIMC_CTX_M2M (1 << 5) | ||
131 | #define FIMC_CTX_CAP (1 << 6) | ||
101 | 132 | ||
102 | /* Image conversion flags */ | 133 | /* Image conversion flags */ |
103 | #define FIMC_IN_DMA_ACCESS_TILED (1 << 0) | 134 | #define FIMC_IN_DMA_ACCESS_TILED (1 << 0) |
@@ -106,7 +137,9 @@ enum fimc_color_fmt { | |||
106 | #define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1) | 137 | #define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1) |
107 | #define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2) | 138 | #define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2) |
108 | #define FIMC_SCAN_MODE_INTERLACED (1 << 2) | 139 | #define FIMC_SCAN_MODE_INTERLACED (1 << 2) |
109 | /* YCbCr data dynamic range for RGB-YUV color conversion. Y/Cb/Cr: (0 ~ 255) */ | 140 | /* |
141 | * YCbCr data dynamic range for RGB-YUV color conversion. | ||
142 | * Y/Cb/Cr: (0 ~ 255) */ | ||
110 | #define FIMC_COLOR_RANGE_WIDE (0 << 3) | 143 | #define FIMC_COLOR_RANGE_WIDE (0 << 3) |
111 | /* Y (16 ~ 235), Cb/Cr (16 ~ 240) */ | 144 | /* Y (16 ~ 235), Cb/Cr (16 ~ 240) */ |
112 | #define FIMC_COLOR_RANGE_NARROW (1 << 3) | 145 | #define FIMC_COLOR_RANGE_NARROW (1 << 3) |
@@ -118,20 +151,25 @@ enum fimc_color_fmt { | |||
118 | 151 | ||
119 | /** | 152 | /** |
120 | * struct fimc_fmt - the driver's internal color format data | 153 | * struct fimc_fmt - the driver's internal color format data |
154 | * @mbus_code: Media Bus pixel code, -1 if not applicable | ||
121 | * @name: format description | 155 | * @name: format description |
122 | * @fourcc: the fourcc code for this format | 156 | * @fourcc: the fourcc code for this format, 0 if not applicable |
123 | * @color: the corresponding fimc_color_fmt | 157 | * @color: the corresponding fimc_color_fmt |
124 | * @depth: number of bits per pixel | 158 | * @depth: driver's private 'number of bits per pixel' |
125 | * @buff_cnt: number of physically non-contiguous data planes | 159 | * @buff_cnt: number of physically non-contiguous data planes |
126 | * @planes_cnt: number of physically contiguous data planes | 160 | * @planes_cnt: number of physically contiguous data planes |
127 | */ | 161 | */ |
128 | struct fimc_fmt { | 162 | struct fimc_fmt { |
163 | enum v4l2_mbus_pixelcode mbus_code; | ||
129 | char *name; | 164 | char *name; |
130 | u32 fourcc; | 165 | u32 fourcc; |
131 | u32 color; | 166 | u32 color; |
132 | u32 depth; | ||
133 | u16 buff_cnt; | 167 | u16 buff_cnt; |
134 | u16 planes_cnt; | 168 | u16 planes_cnt; |
169 | u16 depth; | ||
170 | u16 flags; | ||
171 | #define FMT_FLAGS_CAM (1 << 0) | ||
172 | #define FMT_FLAGS_M2M (1 << 1) | ||
135 | }; | 173 | }; |
136 | 174 | ||
137 | /** | 175 | /** |
@@ -167,37 +205,37 @@ struct fimc_effect { | |||
167 | /** | 205 | /** |
168 | * struct fimc_scaler - the configuration data for FIMC inetrnal scaler | 206 | * struct fimc_scaler - the configuration data for FIMC inetrnal scaler |
169 | * | 207 | * |
170 | * @enabled: the flag set when the scaler is used | 208 | * @scaleup_h: flag indicating scaling up horizontally |
209 | * @scaleup_v: flag indicating scaling up vertically | ||
210 | * @copy_mode: flag indicating transparent DMA transfer (no scaling | ||
211 | * and color format conversion) | ||
212 | * @enabled: flag indicating if the scaler is used | ||
171 | * @hfactor: horizontal shift factor | 213 | * @hfactor: horizontal shift factor |
172 | * @vfactor: vertical shift factor | 214 | * @vfactor: vertical shift factor |
173 | * @pre_hratio: horizontal ratio of the prescaler | 215 | * @pre_hratio: horizontal ratio of the prescaler |
174 | * @pre_vratio: vertical ratio of the prescaler | 216 | * @pre_vratio: vertical ratio of the prescaler |
175 | * @pre_dst_width: the prescaler's destination width | 217 | * @pre_dst_width: the prescaler's destination width |
176 | * @pre_dst_height: the prescaler's destination height | 218 | * @pre_dst_height: the prescaler's destination height |
177 | * @scaleup_h: flag indicating scaling up horizontally | ||
178 | * @scaleup_v: flag indicating scaling up vertically | ||
179 | * @main_hratio: the main scaler's horizontal ratio | 219 | * @main_hratio: the main scaler's horizontal ratio |
180 | * @main_vratio: the main scaler's vertical ratio | 220 | * @main_vratio: the main scaler's vertical ratio |
181 | * @real_width: source width - offset | 221 | * @real_width: source pixel (width - offset) |
182 | * @real_height: source height - offset | 222 | * @real_height: source pixel (height - offset) |
183 | * @copy_mode: flag set if one-to-one mode is used, i.e. no scaling | ||
184 | * and color format conversion | ||
185 | */ | 223 | */ |
186 | struct fimc_scaler { | 224 | struct fimc_scaler { |
187 | u32 enabled; | 225 | unsigned int scaleup_h:1; |
226 | unsigned int scaleup_v:1; | ||
227 | unsigned int copy_mode:1; | ||
228 | unsigned int enabled:1; | ||
188 | u32 hfactor; | 229 | u32 hfactor; |
189 | u32 vfactor; | 230 | u32 vfactor; |
190 | u32 pre_hratio; | 231 | u32 pre_hratio; |
191 | u32 pre_vratio; | 232 | u32 pre_vratio; |
192 | u32 pre_dst_width; | 233 | u32 pre_dst_width; |
193 | u32 pre_dst_height; | 234 | u32 pre_dst_height; |
194 | u32 scaleup_h; | ||
195 | u32 scaleup_v; | ||
196 | u32 main_hratio; | 235 | u32 main_hratio; |
197 | u32 main_vratio; | 236 | u32 main_vratio; |
198 | u32 real_width; | 237 | u32 real_width; |
199 | u32 real_height; | 238 | u32 real_height; |
200 | u32 copy_mode; | ||
201 | }; | 239 | }; |
202 | 240 | ||
203 | /** | 241 | /** |
@@ -215,15 +253,18 @@ struct fimc_addr { | |||
215 | 253 | ||
216 | /** | 254 | /** |
217 | * struct fimc_vid_buffer - the driver's video buffer | 255 | * struct fimc_vid_buffer - the driver's video buffer |
218 | * @vb: v4l videobuf buffer | 256 | * @vb: v4l videobuf buffer |
257 | * @paddr: precalculated physical address set | ||
258 | * @index: buffer index for the output DMA engine | ||
219 | */ | 259 | */ |
220 | struct fimc_vid_buffer { | 260 | struct fimc_vid_buffer { |
221 | struct videobuf_buffer vb; | 261 | struct videobuf_buffer vb; |
262 | struct fimc_addr paddr; | ||
263 | int index; | ||
222 | }; | 264 | }; |
223 | 265 | ||
224 | /** | 266 | /** |
225 | * struct fimc_frame - input/output frame format properties | 267 | * struct fimc_frame - source/target frame properties |
226 | * | ||
227 | * @f_width: image full width (virtual screen size) | 268 | * @f_width: image full width (virtual screen size) |
228 | * @f_height: image full height (virtual screen size) | 269 | * @f_height: image full height (virtual screen size) |
229 | * @o_width: original image width as set by S_FMT | 270 | * @o_width: original image width as set by S_FMT |
@@ -270,67 +311,119 @@ struct fimc_m2m_device { | |||
270 | }; | 311 | }; |
271 | 312 | ||
272 | /** | 313 | /** |
314 | * struct fimc_vid_cap - camera capture device information | ||
315 | * @ctx: hardware context data | ||
316 | * @vfd: video device node for camera capture mode | ||
317 | * @v4l2_dev: v4l2_device struct to manage subdevs | ||
318 | * @sd: pointer to camera sensor subdevice currently in use | ||
319 | * @fmt: Media Bus format configured at selected image sensor | ||
320 | * @pending_buf_q: the pending buffer queue head | ||
321 | * @active_buf_q: the queue head of buffers scheduled in hardware | ||
322 | * @vbq: the capture am video buffer queue | ||
323 | * @active_buf_cnt: number of video buffers scheduled in hardware | ||
324 | * @buf_index: index for managing the output DMA buffers | ||
325 | * @frame_count: the frame counter for statistics | ||
326 | * @reqbufs_count: the number of buffers requested in REQBUFS ioctl | ||
327 | * @input_index: input (camera sensor) index | ||
328 | * @refcnt: driver's private reference counter | ||
329 | */ | ||
330 | struct fimc_vid_cap { | ||
331 | struct fimc_ctx *ctx; | ||
332 | struct video_device *vfd; | ||
333 | struct v4l2_device v4l2_dev; | ||
334 | struct v4l2_subdev *sd; | ||
335 | struct v4l2_mbus_framefmt fmt; | ||
336 | struct list_head pending_buf_q; | ||
337 | struct list_head active_buf_q; | ||
338 | struct videobuf_queue vbq; | ||
339 | int active_buf_cnt; | ||
340 | int buf_index; | ||
341 | unsigned int frame_count; | ||
342 | unsigned int reqbufs_count; | ||
343 | int input_index; | ||
344 | int refcnt; | ||
345 | }; | ||
346 | |||
347 | /** | ||
348 | * struct fimc_pix_limit - image pixel size limits in various IP configurations | ||
349 | * | ||
350 | * @scaler_en_w: max input pixel width when the scaler is enabled | ||
351 | * @scaler_dis_w: max input pixel width when the scaler is disabled | ||
352 | * @in_rot_en_h: max input width with the input rotator is on | ||
353 | * @in_rot_dis_w: max input width with the input rotator is off | ||
354 | * @out_rot_en_w: max output width with the output rotator on | ||
355 | * @out_rot_dis_w: max output width with the output rotator off | ||
356 | */ | ||
357 | struct fimc_pix_limit { | ||
358 | u16 scaler_en_w; | ||
359 | u16 scaler_dis_w; | ||
360 | u16 in_rot_en_h; | ||
361 | u16 in_rot_dis_w; | ||
362 | u16 out_rot_en_w; | ||
363 | u16 out_rot_dis_w; | ||
364 | }; | ||
365 | |||
366 | /** | ||
273 | * struct samsung_fimc_variant - camera interface variant information | 367 | * struct samsung_fimc_variant - camera interface variant information |
274 | * | 368 | * |
275 | * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes | 369 | * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes |
276 | * @has_inp_rot: set if has input rotator | 370 | * @has_inp_rot: set if has input rotator |
277 | * @has_out_rot: set if has output rotator | 371 | * @has_out_rot: set if has output rotator |
372 | * @pix_limit: pixel size constraints for the scaler | ||
278 | * @min_inp_pixsize: minimum input pixel size | 373 | * @min_inp_pixsize: minimum input pixel size |
279 | * @min_out_pixsize: minimum output pixel size | 374 | * @min_out_pixsize: minimum output pixel size |
280 | * @scaler_en_w: maximum input pixel width when the scaler is enabled | 375 | * @hor_offs_align: horizontal pixel offset aligment |
281 | * @scaler_dis_w: maximum input pixel width when the scaler is disabled | 376 | * @out_buf_count: the number of buffers in output DMA sequence |
282 | * @in_rot_en_h: maximum input width when the input rotator is used | ||
283 | * @in_rot_dis_w: maximum input width when the input rotator is used | ||
284 | * @out_rot_en_w: maximum output width for the output rotator enabled | ||
285 | * @out_rot_dis_w: maximum output width for the output rotator enabled | ||
286 | */ | 377 | */ |
287 | struct samsung_fimc_variant { | 378 | struct samsung_fimc_variant { |
288 | unsigned int pix_hoff:1; | 379 | unsigned int pix_hoff:1; |
289 | unsigned int has_inp_rot:1; | 380 | unsigned int has_inp_rot:1; |
290 | unsigned int has_out_rot:1; | 381 | unsigned int has_out_rot:1; |
291 | 382 | struct fimc_pix_limit *pix_limit; | |
292 | u16 min_inp_pixsize; | 383 | u16 min_inp_pixsize; |
293 | u16 min_out_pixsize; | 384 | u16 min_out_pixsize; |
294 | u16 scaler_en_w; | 385 | u16 hor_offs_align; |
295 | u16 scaler_dis_w; | 386 | u16 out_buf_count; |
296 | u16 in_rot_en_h; | ||
297 | u16 in_rot_dis_w; | ||
298 | u16 out_rot_en_w; | ||
299 | u16 out_rot_dis_w; | ||
300 | }; | 387 | }; |
301 | 388 | ||
302 | /** | 389 | /** |
303 | * struct samsung_fimc_driverdata - per-device type driver data for init time. | 390 | * struct samsung_fimc_driverdata - per device type driver data for init time. |
304 | * | 391 | * |
305 | * @variant: the variant information for this driver. | 392 | * @variant: the variant information for this driver. |
306 | * @dev_cnt: number of fimc sub-devices available in SoC | 393 | * @dev_cnt: number of fimc sub-devices available in SoC |
394 | * @lclk_frequency: fimc bus clock frequency | ||
307 | */ | 395 | */ |
308 | struct samsung_fimc_driverdata { | 396 | struct samsung_fimc_driverdata { |
309 | struct samsung_fimc_variant *variant[FIMC_MAX_DEVS]; | 397 | struct samsung_fimc_variant *variant[FIMC_MAX_DEVS]; |
310 | int devs_cnt; | 398 | unsigned long lclk_frequency; |
399 | int num_entities; | ||
311 | }; | 400 | }; |
312 | 401 | ||
313 | struct fimc_ctx; | 402 | struct fimc_ctx; |
314 | 403 | ||
315 | /** | 404 | /** |
316 | * struct fimc_subdev - abstraction for a FIMC entity | 405 | * struct fimc_dev - abstraction for FIMC entity |
317 | * | 406 | * |
318 | * @slock: the spinlock protecting this data structure | 407 | * @slock: the spinlock protecting this data structure |
319 | * @lock: the mutex protecting this data structure | 408 | * @lock: the mutex protecting this data structure |
320 | * @pdev: pointer to the FIMC platform device | 409 | * @pdev: pointer to the FIMC platform device |
410 | * @pdata: pointer to the device platform data | ||
321 | * @id: FIMC device index (0..2) | 411 | * @id: FIMC device index (0..2) |
322 | * @clock[]: the clocks required for FIMC operation | 412 | * @clock[]: the clocks required for FIMC operation |
323 | * @regs: the mapped hardware registers | 413 | * @regs: the mapped hardware registers |
324 | * @regs_res: the resource claimed for IO registers | 414 | * @regs_res: the resource claimed for IO registers |
325 | * @irq: interrupt number of the FIMC subdevice | 415 | * @irq: interrupt number of the FIMC subdevice |
326 | * @irqlock: spinlock protecting videbuffer queue | 416 | * @irqlock: spinlock protecting videobuffer queue |
417 | * @irq_queue: | ||
327 | * @m2m: memory-to-memory V4L2 device information | 418 | * @m2m: memory-to-memory V4L2 device information |
328 | * @state: the FIMC device state flags | 419 | * @vid_cap: camera capture device information |
420 | * @state: flags used to synchronize m2m and capture mode operation | ||
329 | */ | 421 | */ |
330 | struct fimc_dev { | 422 | struct fimc_dev { |
331 | spinlock_t slock; | 423 | spinlock_t slock; |
332 | struct mutex lock; | 424 | struct mutex lock; |
333 | struct platform_device *pdev; | 425 | struct platform_device *pdev; |
426 | struct s3c_platform_fimc *pdata; | ||
334 | struct samsung_fimc_variant *variant; | 427 | struct samsung_fimc_variant *variant; |
335 | int id; | 428 | int id; |
336 | struct clk *clock[NUM_FIMC_CLOCKS]; | 429 | struct clk *clock[NUM_FIMC_CLOCKS]; |
@@ -338,8 +431,9 @@ struct fimc_dev { | |||
338 | struct resource *regs_res; | 431 | struct resource *regs_res; |
339 | int irq; | 432 | int irq; |
340 | spinlock_t irqlock; | 433 | spinlock_t irqlock; |
341 | struct workqueue_struct *work_queue; | 434 | wait_queue_head_t irq_queue; |
342 | struct fimc_m2m_device m2m; | 435 | struct fimc_m2m_device m2m; |
436 | struct fimc_vid_cap vid_cap; | ||
343 | unsigned long state; | 437 | unsigned long state; |
344 | }; | 438 | }; |
345 | 439 | ||
@@ -359,7 +453,7 @@ struct fimc_dev { | |||
359 | * @effect: image effect | 453 | * @effect: image effect |
360 | * @rotation: image clockwise rotation in degrees | 454 | * @rotation: image clockwise rotation in degrees |
361 | * @flip: image flip mode | 455 | * @flip: image flip mode |
362 | * @flags: an additional flags for image conversion | 456 | * @flags: additional flags for image conversion |
363 | * @state: flags to keep track of user configuration | 457 | * @state: flags to keep track of user configuration |
364 | * @fimc_dev: the FIMC device this context applies to | 458 | * @fimc_dev: the FIMC device this context applies to |
365 | * @m2m_ctx: memory-to-memory device context | 459 | * @m2m_ctx: memory-to-memory device context |
@@ -384,6 +478,7 @@ struct fimc_ctx { | |||
384 | struct v4l2_m2m_ctx *m2m_ctx; | 478 | struct v4l2_m2m_ctx *m2m_ctx; |
385 | }; | 479 | }; |
386 | 480 | ||
481 | extern struct videobuf_queue_ops fimc_qops; | ||
387 | 482 | ||
388 | static inline int tiled_fmt(struct fimc_fmt *fmt) | 483 | static inline int tiled_fmt(struct fimc_fmt *fmt) |
389 | { | 484 | { |
@@ -397,18 +492,24 @@ static inline void fimc_hw_clear_irq(struct fimc_dev *dev) | |||
397 | writel(cfg, dev->regs + S5P_CIGCTRL); | 492 | writel(cfg, dev->regs + S5P_CIGCTRL); |
398 | } | 493 | } |
399 | 494 | ||
400 | static inline void fimc_hw_start_scaler(struct fimc_dev *dev) | 495 | static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on) |
401 | { | 496 | { |
402 | u32 cfg = readl(dev->regs + S5P_CISCCTRL); | 497 | u32 cfg = readl(dev->regs + S5P_CISCCTRL); |
403 | cfg |= S5P_CISCCTRL_SCALERSTART; | 498 | if (on) |
499 | cfg |= S5P_CISCCTRL_SCALERSTART; | ||
500 | else | ||
501 | cfg &= ~S5P_CISCCTRL_SCALERSTART; | ||
404 | writel(cfg, dev->regs + S5P_CISCCTRL); | 502 | writel(cfg, dev->regs + S5P_CISCCTRL); |
405 | } | 503 | } |
406 | 504 | ||
407 | static inline void fimc_hw_stop_scaler(struct fimc_dev *dev) | 505 | static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on) |
408 | { | 506 | { |
409 | u32 cfg = readl(dev->regs + S5P_CISCCTRL); | 507 | u32 cfg = readl(dev->regs + S5P_MSCTRL); |
410 | cfg &= ~S5P_CISCCTRL_SCALERSTART; | 508 | if (on) |
411 | writel(cfg, dev->regs + S5P_CISCCTRL); | 509 | cfg |= S5P_MSCTRL_ENVID; |
510 | else | ||
511 | cfg &= ~S5P_MSCTRL_ENVID; | ||
512 | writel(cfg, dev->regs + S5P_MSCTRL); | ||
412 | } | 513 | } |
413 | 514 | ||
414 | static inline void fimc_hw_dis_capture(struct fimc_dev *dev) | 515 | static inline void fimc_hw_dis_capture(struct fimc_dev *dev) |
@@ -418,27 +519,30 @@ static inline void fimc_hw_dis_capture(struct fimc_dev *dev) | |||
418 | writel(cfg, dev->regs + S5P_CIIMGCPT); | 519 | writel(cfg, dev->regs + S5P_CIIMGCPT); |
419 | } | 520 | } |
420 | 521 | ||
421 | static inline void fimc_hw_start_in_dma(struct fimc_dev *dev) | 522 | /** |
422 | { | 523 | * fimc_hw_set_dma_seq - configure output DMA buffer sequence |
423 | u32 cfg = readl(dev->regs + S5P_MSCTRL); | 524 | * @mask: each bit corresponds to one of 32 output buffer registers set |
424 | cfg |= S5P_MSCTRL_ENVID; | 525 | * 1 to include buffer in the sequence, 0 to disable |
425 | writel(cfg, dev->regs + S5P_MSCTRL); | 526 | * |
426 | } | 527 | * This function mask output DMA ring buffers, i.e. it allows to configure |
427 | 528 | * which of the output buffer address registers will be used by the DMA | |
428 | static inline void fimc_hw_stop_in_dma(struct fimc_dev *dev) | 529 | * engine. |
530 | */ | ||
531 | static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask) | ||
429 | { | 532 | { |
430 | u32 cfg = readl(dev->regs + S5P_MSCTRL); | 533 | writel(mask, dev->regs + S5P_CIFCNTSEQ); |
431 | cfg &= ~S5P_MSCTRL_ENVID; | ||
432 | writel(cfg, dev->regs + S5P_MSCTRL); | ||
433 | } | 534 | } |
434 | 535 | ||
435 | static inline struct fimc_frame *ctx_m2m_get_frame(struct fimc_ctx *ctx, | 536 | static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, |
436 | enum v4l2_buf_type type) | 537 | enum v4l2_buf_type type) |
437 | { | 538 | { |
438 | struct fimc_frame *frame; | 539 | struct fimc_frame *frame; |
439 | 540 | ||
440 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) { | 541 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) { |
441 | frame = &ctx->s_frame; | 542 | if (ctx->state & FIMC_CTX_M2M) |
543 | frame = &ctx->s_frame; | ||
544 | else | ||
545 | return ERR_PTR(-EINVAL); | ||
442 | } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) { | 546 | } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) { |
443 | frame = &ctx->d_frame; | 547 | frame = &ctx->d_frame; |
444 | } else { | 548 | } else { |
@@ -450,22 +554,137 @@ static inline struct fimc_frame *ctx_m2m_get_frame(struct fimc_ctx *ctx, | |||
450 | return frame; | 554 | return frame; |
451 | } | 555 | } |
452 | 556 | ||
557 | static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev) | ||
558 | { | ||
559 | u32 reg = readl(dev->regs + S5P_CISTATUS); | ||
560 | return (reg & S5P_CISTATUS_FRAMECNT_MASK) >> | ||
561 | S5P_CISTATUS_FRAMECNT_SHIFT; | ||
562 | } | ||
563 | |||
453 | /* -----------------------------------------------------*/ | 564 | /* -----------------------------------------------------*/ |
454 | /* fimc-reg.c */ | 565 | /* fimc-reg.c */ |
455 | void fimc_hw_reset(struct fimc_dev *dev); | 566 | void fimc_hw_reset(struct fimc_dev *fimc); |
456 | void fimc_hw_set_rotation(struct fimc_ctx *ctx); | 567 | void fimc_hw_set_rotation(struct fimc_ctx *ctx); |
457 | void fimc_hw_set_target_format(struct fimc_ctx *ctx); | 568 | void fimc_hw_set_target_format(struct fimc_ctx *ctx); |
458 | void fimc_hw_set_out_dma(struct fimc_ctx *ctx); | 569 | void fimc_hw_set_out_dma(struct fimc_ctx *ctx); |
459 | void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable); | 570 | void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable); |
460 | void fimc_hw_en_irq(struct fimc_dev *dev, int enable); | 571 | void fimc_hw_en_irq(struct fimc_dev *fimc, int enable); |
461 | void fimc_hw_set_prescaler(struct fimc_ctx *ctx); | ||
462 | void fimc_hw_set_scaler(struct fimc_ctx *ctx); | 572 | void fimc_hw_set_scaler(struct fimc_ctx *ctx); |
463 | void fimc_hw_en_capture(struct fimc_ctx *ctx); | 573 | void fimc_hw_en_capture(struct fimc_ctx *ctx); |
464 | void fimc_hw_set_effect(struct fimc_ctx *ctx); | 574 | void fimc_hw_set_effect(struct fimc_ctx *ctx); |
465 | void fimc_hw_set_in_dma(struct fimc_ctx *ctx); | 575 | void fimc_hw_set_in_dma(struct fimc_ctx *ctx); |
466 | void fimc_hw_set_input_path(struct fimc_ctx *ctx); | 576 | void fimc_hw_set_input_path(struct fimc_ctx *ctx); |
467 | void fimc_hw_set_output_path(struct fimc_ctx *ctx); | 577 | void fimc_hw_set_output_path(struct fimc_ctx *ctx); |
468 | void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr); | 578 | void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr); |
469 | void fimc_hw_set_output_addr(struct fimc_dev *dev, struct fimc_addr *paddr); | 579 | void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr, |
580 | int index); | ||
581 | int fimc_hw_set_camera_source(struct fimc_dev *fimc, | ||
582 | struct s3c_fimc_isp_info *cam); | ||
583 | int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f); | ||
584 | int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, | ||
585 | struct s3c_fimc_isp_info *cam); | ||
586 | int fimc_hw_set_camera_type(struct fimc_dev *fimc, | ||
587 | struct s3c_fimc_isp_info *cam); | ||
588 | |||
589 | /* -----------------------------------------------------*/ | ||
590 | /* fimc-core.c */ | ||
591 | int fimc_vidioc_enum_fmt(struct file *file, void *priv, | ||
592 | struct v4l2_fmtdesc *f); | ||
593 | int fimc_vidioc_g_fmt(struct file *file, void *priv, | ||
594 | struct v4l2_format *f); | ||
595 | int fimc_vidioc_try_fmt(struct file *file, void *priv, | ||
596 | struct v4l2_format *f); | ||
597 | int fimc_vidioc_g_crop(struct file *file, void *fh, | ||
598 | struct v4l2_crop *cr); | ||
599 | int fimc_vidioc_cropcap(struct file *file, void *fh, | ||
600 | struct v4l2_cropcap *cr); | ||
601 | int fimc_vidioc_queryctrl(struct file *file, void *priv, | ||
602 | struct v4l2_queryctrl *qc); | ||
603 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, | ||
604 | struct v4l2_control *ctrl); | ||
605 | |||
606 | int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr); | ||
607 | int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl); | ||
608 | int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl); | ||
609 | |||
610 | struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask); | ||
611 | struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, | ||
612 | unsigned int mask); | ||
613 | |||
614 | int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); | ||
615 | int fimc_set_scaler_info(struct fimc_ctx *ctx); | ||
616 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); | ||
617 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, | ||
618 | struct fimc_frame *frame, struct fimc_addr *paddr); | ||
619 | |||
620 | /* -----------------------------------------------------*/ | ||
621 | /* fimc-capture.c */ | ||
622 | int fimc_register_capture_device(struct fimc_dev *fimc); | ||
623 | void fimc_unregister_capture_device(struct fimc_dev *fimc); | ||
624 | int fimc_sensor_sd_init(struct fimc_dev *fimc, int index); | ||
625 | int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, | ||
626 | struct fimc_vid_buffer *fimc_vb); | ||
627 | |||
628 | /* Locking: the caller holds fimc->slock */ | ||
629 | static inline void fimc_activate_capture(struct fimc_ctx *ctx) | ||
630 | { | ||
631 | fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled); | ||
632 | fimc_hw_en_capture(ctx); | ||
633 | } | ||
634 | |||
635 | static inline void fimc_deactivate_capture(struct fimc_dev *fimc) | ||
636 | { | ||
637 | fimc_hw_en_lastirq(fimc, true); | ||
638 | fimc_hw_dis_capture(fimc); | ||
639 | fimc_hw_enable_scaler(fimc, false); | ||
640 | fimc_hw_en_lastirq(fimc, false); | ||
641 | } | ||
642 | |||
643 | /* | ||
644 | * Add video buffer to the active buffers queue. | ||
645 | * The caller holds irqlock spinlock. | ||
646 | */ | ||
647 | static inline void active_queue_add(struct fimc_vid_cap *vid_cap, | ||
648 | struct fimc_vid_buffer *buf) | ||
649 | { | ||
650 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
651 | list_add_tail(&buf->vb.queue, &vid_cap->active_buf_q); | ||
652 | vid_cap->active_buf_cnt++; | ||
653 | } | ||
654 | |||
655 | /* | ||
656 | * Pop a video buffer from the capture active buffers queue | ||
657 | * Locking: Need to be called with dev->slock held. | ||
658 | */ | ||
659 | static inline struct fimc_vid_buffer * | ||
660 | active_queue_pop(struct fimc_vid_cap *vid_cap) | ||
661 | { | ||
662 | struct fimc_vid_buffer *buf; | ||
663 | buf = list_entry(vid_cap->active_buf_q.next, | ||
664 | struct fimc_vid_buffer, vb.queue); | ||
665 | list_del(&buf->vb.queue); | ||
666 | vid_cap->active_buf_cnt--; | ||
667 | return buf; | ||
668 | } | ||
669 | |||
670 | /* Add video buffer to the capture pending buffers queue */ | ||
671 | static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap, | ||
672 | struct fimc_vid_buffer *buf) | ||
673 | { | ||
674 | buf->vb.state = VIDEOBUF_QUEUED; | ||
675 | list_add_tail(&buf->vb.queue, &vid_cap->pending_buf_q); | ||
676 | } | ||
677 | |||
678 | /* Add video buffer to the capture pending buffers queue */ | ||
679 | static inline struct fimc_vid_buffer * | ||
680 | pending_queue_pop(struct fimc_vid_cap *vid_cap) | ||
681 | { | ||
682 | struct fimc_vid_buffer *buf; | ||
683 | buf = list_entry(vid_cap->pending_buf_q.next, | ||
684 | struct fimc_vid_buffer, vb.queue); | ||
685 | list_del(&buf->vb.queue); | ||
686 | return buf; | ||
687 | } | ||
688 | |||
470 | 689 | ||
471 | #endif /* FIMC_CORE_H_ */ | 690 | #endif /* FIMC_CORE_H_ */ |
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c index 5570f1ce0c9..511631a2e5c 100644 --- a/drivers/media/video/s5p-fimc/fimc-reg.c +++ b/drivers/media/video/s5p-fimc/fimc-reg.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <mach/map.h> | 15 | #include <mach/map.h> |
16 | #include <media/s3c_fimc.h> | ||
16 | 17 | ||
17 | #include "fimc-core.h" | 18 | #include "fimc-core.h" |
18 | 19 | ||
@@ -29,49 +30,11 @@ void fimc_hw_reset(struct fimc_dev *dev) | |||
29 | cfg = readl(dev->regs + S5P_CIGCTRL); | 30 | cfg = readl(dev->regs + S5P_CIGCTRL); |
30 | cfg |= (S5P_CIGCTRL_SWRST | S5P_CIGCTRL_IRQ_LEVEL); | 31 | cfg |= (S5P_CIGCTRL_SWRST | S5P_CIGCTRL_IRQ_LEVEL); |
31 | writel(cfg, dev->regs + S5P_CIGCTRL); | 32 | writel(cfg, dev->regs + S5P_CIGCTRL); |
32 | msleep(1); | 33 | udelay(1000); |
33 | 34 | ||
34 | cfg = readl(dev->regs + S5P_CIGCTRL); | 35 | cfg = readl(dev->regs + S5P_CIGCTRL); |
35 | cfg &= ~S5P_CIGCTRL_SWRST; | 36 | cfg &= ~S5P_CIGCTRL_SWRST; |
36 | writel(cfg, dev->regs + S5P_CIGCTRL); | 37 | writel(cfg, dev->regs + S5P_CIGCTRL); |
37 | |||
38 | } | ||
39 | |||
40 | void fimc_hw_set_rotation(struct fimc_ctx *ctx) | ||
41 | { | ||
42 | u32 cfg, flip; | ||
43 | struct fimc_dev *dev = ctx->fimc_dev; | ||
44 | |||
45 | cfg = readl(dev->regs + S5P_CITRGFMT); | ||
46 | cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90); | ||
47 | |||
48 | flip = readl(dev->regs + S5P_MSCTRL); | ||
49 | flip &= ~S5P_MSCTRL_FLIP_MASK; | ||
50 | |||
51 | /* | ||
52 | * The input and output rotator cannot work simultaneously. | ||
53 | * Use the output rotator in output DMA mode or the input rotator | ||
54 | * in direct fifo output mode. | ||
55 | */ | ||
56 | if (ctx->rotation == 90 || ctx->rotation == 270) { | ||
57 | if (ctx->out_path == FIMC_LCDFIFO) { | ||
58 | cfg |= S5P_CITRGFMT_INROT90; | ||
59 | if (ctx->rotation == 270) | ||
60 | flip |= S5P_MSCTRL_FLIP_180; | ||
61 | } else { | ||
62 | cfg |= S5P_CITRGFMT_OUTROT90; | ||
63 | if (ctx->rotation == 270) | ||
64 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
65 | } | ||
66 | } else if (ctx->rotation == 180) { | ||
67 | if (ctx->out_path == FIMC_LCDFIFO) | ||
68 | flip |= S5P_MSCTRL_FLIP_180; | ||
69 | else | ||
70 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
71 | } | ||
72 | if (ctx->rotation == 180 || ctx->rotation == 270) | ||
73 | writel(flip, dev->regs + S5P_MSCTRL); | ||
74 | writel(cfg, dev->regs + S5P_CITRGFMT); | ||
75 | } | 38 | } |
76 | 39 | ||
77 | static u32 fimc_hw_get_in_flip(u32 ctx_flip) | 40 | static u32 fimc_hw_get_in_flip(u32 ctx_flip) |
@@ -114,6 +77,46 @@ static u32 fimc_hw_get_target_flip(u32 ctx_flip) | |||
114 | return flip; | 77 | return flip; |
115 | } | 78 | } |
116 | 79 | ||
80 | void fimc_hw_set_rotation(struct fimc_ctx *ctx) | ||
81 | { | ||
82 | u32 cfg, flip; | ||
83 | struct fimc_dev *dev = ctx->fimc_dev; | ||
84 | |||
85 | cfg = readl(dev->regs + S5P_CITRGFMT); | ||
86 | cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 | | ||
87 | S5P_CITRGFMT_FLIP_180); | ||
88 | |||
89 | flip = readl(dev->regs + S5P_MSCTRL); | ||
90 | flip &= ~S5P_MSCTRL_FLIP_MASK; | ||
91 | |||
92 | /* | ||
93 | * The input and output rotator cannot work simultaneously. | ||
94 | * Use the output rotator in output DMA mode or the input rotator | ||
95 | * in direct fifo output mode. | ||
96 | */ | ||
97 | if (ctx->rotation == 90 || ctx->rotation == 270) { | ||
98 | if (ctx->out_path == FIMC_LCDFIFO) { | ||
99 | cfg |= S5P_CITRGFMT_INROT90; | ||
100 | if (ctx->rotation == 270) | ||
101 | flip |= S5P_MSCTRL_FLIP_180; | ||
102 | } else { | ||
103 | cfg |= S5P_CITRGFMT_OUTROT90; | ||
104 | if (ctx->rotation == 270) | ||
105 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
106 | } | ||
107 | } else if (ctx->rotation == 180) { | ||
108 | if (ctx->out_path == FIMC_LCDFIFO) | ||
109 | flip |= S5P_MSCTRL_FLIP_180; | ||
110 | else | ||
111 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
112 | } | ||
113 | if (ctx->rotation == 180 || ctx->rotation == 270) | ||
114 | writel(flip, dev->regs + S5P_MSCTRL); | ||
115 | |||
116 | cfg |= fimc_hw_get_target_flip(ctx->flip); | ||
117 | writel(cfg, dev->regs + S5P_CITRGFMT); | ||
118 | } | ||
119 | |||
117 | void fimc_hw_set_target_format(struct fimc_ctx *ctx) | 120 | void fimc_hw_set_target_format(struct fimc_ctx *ctx) |
118 | { | 121 | { |
119 | u32 cfg; | 122 | u32 cfg; |
@@ -149,13 +152,15 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx) | |||
149 | break; | 152 | break; |
150 | } | 153 | } |
151 | 154 | ||
152 | cfg |= S5P_CITRGFMT_HSIZE(frame->width); | 155 | if (ctx->rotation == 90 || ctx->rotation == 270) { |
153 | cfg |= S5P_CITRGFMT_VSIZE(frame->height); | 156 | cfg |= S5P_CITRGFMT_HSIZE(frame->height); |
157 | cfg |= S5P_CITRGFMT_VSIZE(frame->width); | ||
158 | } else { | ||
154 | 159 | ||
155 | if (ctx->rotation == 0) { | 160 | cfg |= S5P_CITRGFMT_HSIZE(frame->width); |
156 | cfg &= ~S5P_CITRGFMT_FLIP_MASK; | 161 | cfg |= S5P_CITRGFMT_VSIZE(frame->height); |
157 | cfg |= fimc_hw_get_target_flip(ctx->flip); | ||
158 | } | 162 | } |
163 | |||
159 | writel(cfg, dev->regs + S5P_CITRGFMT); | 164 | writel(cfg, dev->regs + S5P_CITRGFMT); |
160 | 165 | ||
161 | cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK; | 166 | cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK; |
@@ -167,16 +172,20 @@ static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx) | |||
167 | { | 172 | { |
168 | struct fimc_dev *dev = ctx->fimc_dev; | 173 | struct fimc_dev *dev = ctx->fimc_dev; |
169 | struct fimc_frame *frame = &ctx->d_frame; | 174 | struct fimc_frame *frame = &ctx->d_frame; |
170 | u32 cfg = 0; | 175 | u32 cfg; |
171 | 176 | ||
172 | if (ctx->rotation == 90 || ctx->rotation == 270) { | 177 | cfg = S5P_ORIG_SIZE_HOR(frame->f_width); |
173 | cfg |= S5P_ORIG_SIZE_HOR(frame->f_height); | 178 | cfg |= S5P_ORIG_SIZE_VER(frame->f_height); |
174 | cfg |= S5P_ORIG_SIZE_VER(frame->f_width); | ||
175 | } else { | ||
176 | cfg |= S5P_ORIG_SIZE_HOR(frame->f_width); | ||
177 | cfg |= S5P_ORIG_SIZE_VER(frame->f_height); | ||
178 | } | ||
179 | writel(cfg, dev->regs + S5P_ORGOSIZE); | 179 | writel(cfg, dev->regs + S5P_ORGOSIZE); |
180 | |||
181 | /* Select color space conversion equation (HD/SD size).*/ | ||
182 | cfg = readl(dev->regs + S5P_CIGCTRL); | ||
183 | if (frame->f_width >= 1280) /* HD */ | ||
184 | cfg |= S5P_CIGCTRL_CSC_ITU601_709; | ||
185 | else /* SD */ | ||
186 | cfg &= ~S5P_CIGCTRL_CSC_ITU601_709; | ||
187 | writel(cfg, dev->regs + S5P_CIGCTRL); | ||
188 | |||
180 | } | 189 | } |
181 | 190 | ||
182 | void fimc_hw_set_out_dma(struct fimc_ctx *ctx) | 191 | void fimc_hw_set_out_dma(struct fimc_ctx *ctx) |
@@ -232,36 +241,28 @@ static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable) | |||
232 | 241 | ||
233 | void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable) | 242 | void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable) |
234 | { | 243 | { |
235 | unsigned long flags; | 244 | u32 cfg = readl(dev->regs + S5P_CIOCTRL); |
236 | u32 cfg; | ||
237 | |||
238 | spin_lock_irqsave(&dev->slock, flags); | ||
239 | |||
240 | cfg = readl(dev->regs + S5P_CIOCTRL); | ||
241 | if (enable) | 245 | if (enable) |
242 | cfg |= S5P_CIOCTRL_LASTIRQ_ENABLE; | 246 | cfg |= S5P_CIOCTRL_LASTIRQ_ENABLE; |
243 | else | 247 | else |
244 | cfg &= ~S5P_CIOCTRL_LASTIRQ_ENABLE; | 248 | cfg &= ~S5P_CIOCTRL_LASTIRQ_ENABLE; |
245 | writel(cfg, dev->regs + S5P_CIOCTRL); | 249 | writel(cfg, dev->regs + S5P_CIOCTRL); |
246 | |||
247 | spin_unlock_irqrestore(&dev->slock, flags); | ||
248 | } | 250 | } |
249 | 251 | ||
250 | void fimc_hw_set_prescaler(struct fimc_ctx *ctx) | 252 | static void fimc_hw_set_prescaler(struct fimc_ctx *ctx) |
251 | { | 253 | { |
252 | struct fimc_dev *dev = ctx->fimc_dev; | 254 | struct fimc_dev *dev = ctx->fimc_dev; |
253 | struct fimc_scaler *sc = &ctx->scaler; | 255 | struct fimc_scaler *sc = &ctx->scaler; |
254 | u32 cfg = 0, shfactor; | 256 | u32 cfg, shfactor; |
255 | 257 | ||
256 | shfactor = 10 - (sc->hfactor + sc->vfactor); | 258 | shfactor = 10 - (sc->hfactor + sc->vfactor); |
257 | 259 | ||
258 | cfg |= S5P_CISCPRERATIO_SHFACTOR(shfactor); | 260 | cfg = S5P_CISCPRERATIO_SHFACTOR(shfactor); |
259 | cfg |= S5P_CISCPRERATIO_HOR(sc->pre_hratio); | 261 | cfg |= S5P_CISCPRERATIO_HOR(sc->pre_hratio); |
260 | cfg |= S5P_CISCPRERATIO_VER(sc->pre_vratio); | 262 | cfg |= S5P_CISCPRERATIO_VER(sc->pre_vratio); |
261 | writel(cfg, dev->regs + S5P_CISCPRERATIO); | 263 | writel(cfg, dev->regs + S5P_CISCPRERATIO); |
262 | 264 | ||
263 | cfg = 0; | 265 | cfg = S5P_CISCPREDST_WIDTH(sc->pre_dst_width); |
264 | cfg |= S5P_CISCPREDST_WIDTH(sc->pre_dst_width); | ||
265 | cfg |= S5P_CISCPREDST_HEIGHT(sc->pre_dst_height); | 266 | cfg |= S5P_CISCPREDST_HEIGHT(sc->pre_dst_height); |
266 | writel(cfg, dev->regs + S5P_CISCPREDST); | 267 | writel(cfg, dev->regs + S5P_CISCPREDST); |
267 | } | 268 | } |
@@ -274,6 +275,8 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx) | |||
274 | struct fimc_frame *dst_frame = &ctx->d_frame; | 275 | struct fimc_frame *dst_frame = &ctx->d_frame; |
275 | u32 cfg = 0; | 276 | u32 cfg = 0; |
276 | 277 | ||
278 | fimc_hw_set_prescaler(ctx); | ||
279 | |||
277 | if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) | 280 | if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) |
278 | cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); | 281 | cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); |
279 | 282 | ||
@@ -325,14 +328,18 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx) | |||
325 | void fimc_hw_en_capture(struct fimc_ctx *ctx) | 328 | void fimc_hw_en_capture(struct fimc_ctx *ctx) |
326 | { | 329 | { |
327 | struct fimc_dev *dev = ctx->fimc_dev; | 330 | struct fimc_dev *dev = ctx->fimc_dev; |
328 | u32 cfg; | ||
329 | 331 | ||
330 | cfg = readl(dev->regs + S5P_CIIMGCPT); | 332 | u32 cfg = readl(dev->regs + S5P_CIIMGCPT); |
331 | /* One shot mode for output DMA or freerun for FIFO. */ | 333 | |
332 | if (ctx->out_path == FIMC_DMA) | 334 | if (ctx->out_path == FIMC_DMA) { |
333 | cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE; | 335 | /* one shot mode */ |
334 | else | 336 | cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE | S5P_CIIMGCPT_IMGCPTEN; |
335 | cfg &= ~S5P_CIIMGCPT_CPT_FREN_ENABLE; | 337 | } else { |
338 | /* Continous frame capture mode (freerun). */ | ||
339 | cfg &= ~(S5P_CIIMGCPT_CPT_FREN_ENABLE | | ||
340 | S5P_CIIMGCPT_CPT_FRMOD_CNT); | ||
341 | cfg |= S5P_CIIMGCPT_IMGCPTEN; | ||
342 | } | ||
336 | 343 | ||
337 | if (ctx->scaler.enabled) | 344 | if (ctx->scaler.enabled) |
338 | cfg |= S5P_CIIMGCPT_IMGCPTEN_SC; | 345 | cfg |= S5P_CIIMGCPT_IMGCPTEN_SC; |
@@ -364,7 +371,7 @@ static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx) | |||
364 | u32 cfg_r = 0; | 371 | u32 cfg_r = 0; |
365 | 372 | ||
366 | if (FIMC_LCDFIFO == ctx->out_path) | 373 | if (FIMC_LCDFIFO == ctx->out_path) |
367 | cfg_r |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; | 374 | cfg_r |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; |
368 | 375 | ||
369 | cfg_o |= S5P_ORIG_SIZE_HOR(frame->f_width); | 376 | cfg_o |= S5P_ORIG_SIZE_HOR(frame->f_width); |
370 | cfg_o |= S5P_ORIG_SIZE_VER(frame->f_height); | 377 | cfg_o |= S5P_ORIG_SIZE_VER(frame->f_height); |
@@ -380,27 +387,25 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx) | |||
380 | struct fimc_dev *dev = ctx->fimc_dev; | 387 | struct fimc_dev *dev = ctx->fimc_dev; |
381 | struct fimc_frame *frame = &ctx->s_frame; | 388 | struct fimc_frame *frame = &ctx->s_frame; |
382 | struct fimc_dma_offset *offset = &frame->dma_offset; | 389 | struct fimc_dma_offset *offset = &frame->dma_offset; |
383 | u32 cfg = 0; | 390 | u32 cfg; |
384 | 391 | ||
385 | /* Set the pixel offsets. */ | 392 | /* Set the pixel offsets. */ |
386 | cfg |= S5P_CIO_OFFS_HOR(offset->y_h); | 393 | cfg = S5P_CIO_OFFS_HOR(offset->y_h); |
387 | cfg |= S5P_CIO_OFFS_VER(offset->y_v); | 394 | cfg |= S5P_CIO_OFFS_VER(offset->y_v); |
388 | writel(cfg, dev->regs + S5P_CIIYOFF); | 395 | writel(cfg, dev->regs + S5P_CIIYOFF); |
389 | 396 | ||
390 | cfg = 0; | 397 | cfg = S5P_CIO_OFFS_HOR(offset->cb_h); |
391 | cfg |= S5P_CIO_OFFS_HOR(offset->cb_h); | ||
392 | cfg |= S5P_CIO_OFFS_VER(offset->cb_v); | 398 | cfg |= S5P_CIO_OFFS_VER(offset->cb_v); |
393 | writel(cfg, dev->regs + S5P_CIICBOFF); | 399 | writel(cfg, dev->regs + S5P_CIICBOFF); |
394 | 400 | ||
395 | cfg = 0; | 401 | cfg = S5P_CIO_OFFS_HOR(offset->cr_h); |
396 | cfg |= S5P_CIO_OFFS_HOR(offset->cr_h); | ||
397 | cfg |= S5P_CIO_OFFS_VER(offset->cr_v); | 402 | cfg |= S5P_CIO_OFFS_VER(offset->cr_v); |
398 | writel(cfg, dev->regs + S5P_CIICROFF); | 403 | writel(cfg, dev->regs + S5P_CIICROFF); |
399 | 404 | ||
400 | /* Input original and real size. */ | 405 | /* Input original and real size. */ |
401 | fimc_hw_set_in_dma_size(ctx); | 406 | fimc_hw_set_in_dma_size(ctx); |
402 | 407 | ||
403 | /* Autoload is used currently only in FIFO mode. */ | 408 | /* Use DMA autoload only in FIFO mode. */ |
404 | fimc_hw_en_autoload(dev, ctx->out_path == FIMC_LCDFIFO); | 409 | fimc_hw_en_autoload(dev, ctx->out_path == FIMC_LCDFIFO); |
405 | 410 | ||
406 | /* Set the input DMA to process single frame only. */ | 411 | /* Set the input DMA to process single frame only. */ |
@@ -501,27 +506,163 @@ void fimc_hw_set_output_path(struct fimc_ctx *ctx) | |||
501 | 506 | ||
502 | void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr) | 507 | void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr) |
503 | { | 508 | { |
504 | u32 cfg = 0; | 509 | u32 cfg = readl(dev->regs + S5P_CIREAL_ISIZE); |
505 | |||
506 | cfg = readl(dev->regs + S5P_CIREAL_ISIZE); | ||
507 | cfg |= S5P_CIREAL_ISIZE_ADDR_CH_DIS; | 510 | cfg |= S5P_CIREAL_ISIZE_ADDR_CH_DIS; |
508 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); | 511 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); |
509 | 512 | ||
510 | writel(paddr->y, dev->regs + S5P_CIIYSA0); | 513 | writel(paddr->y, dev->regs + S5P_CIIYSA(0)); |
511 | writel(paddr->cb, dev->regs + S5P_CIICBSA0); | 514 | writel(paddr->cb, dev->regs + S5P_CIICBSA(0)); |
512 | writel(paddr->cr, dev->regs + S5P_CIICRSA0); | 515 | writel(paddr->cr, dev->regs + S5P_CIICRSA(0)); |
513 | 516 | ||
514 | cfg &= ~S5P_CIREAL_ISIZE_ADDR_CH_DIS; | 517 | cfg &= ~S5P_CIREAL_ISIZE_ADDR_CH_DIS; |
515 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); | 518 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); |
516 | } | 519 | } |
517 | 520 | ||
518 | void fimc_hw_set_output_addr(struct fimc_dev *dev, struct fimc_addr *paddr) | 521 | void fimc_hw_set_output_addr(struct fimc_dev *dev, |
522 | struct fimc_addr *paddr, int index) | ||
519 | { | 523 | { |
520 | int i; | 524 | int i = (index == -1) ? 0 : index; |
521 | /* Set all the output register sets to point to single video buffer. */ | 525 | do { |
522 | for (i = 0; i < FIMC_MAX_OUT_BUFS; i++) { | ||
523 | writel(paddr->y, dev->regs + S5P_CIOYSA(i)); | 526 | writel(paddr->y, dev->regs + S5P_CIOYSA(i)); |
524 | writel(paddr->cb, dev->regs + S5P_CIOCBSA(i)); | 527 | writel(paddr->cb, dev->regs + S5P_CIOCBSA(i)); |
525 | writel(paddr->cr, dev->regs + S5P_CIOCRSA(i)); | 528 | writel(paddr->cr, dev->regs + S5P_CIOCRSA(i)); |
529 | dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X", | ||
530 | i, paddr->y, paddr->cb, paddr->cr); | ||
531 | } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS); | ||
532 | } | ||
533 | |||
534 | int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, | ||
535 | struct s3c_fimc_isp_info *cam) | ||
536 | { | ||
537 | u32 cfg = readl(fimc->regs + S5P_CIGCTRL); | ||
538 | |||
539 | cfg &= ~(S5P_CIGCTRL_INVPOLPCLK | S5P_CIGCTRL_INVPOLVSYNC | | ||
540 | S5P_CIGCTRL_INVPOLHREF | S5P_CIGCTRL_INVPOLHSYNC); | ||
541 | |||
542 | if (cam->flags & FIMC_CLK_INV_PCLK) | ||
543 | cfg |= S5P_CIGCTRL_INVPOLPCLK; | ||
544 | |||
545 | if (cam->flags & FIMC_CLK_INV_VSYNC) | ||
546 | cfg |= S5P_CIGCTRL_INVPOLVSYNC; | ||
547 | |||
548 | if (cam->flags & FIMC_CLK_INV_HREF) | ||
549 | cfg |= S5P_CIGCTRL_INVPOLHREF; | ||
550 | |||
551 | if (cam->flags & FIMC_CLK_INV_HSYNC) | ||
552 | cfg |= S5P_CIGCTRL_INVPOLHSYNC; | ||
553 | |||
554 | writel(cfg, fimc->regs + S5P_CIGCTRL); | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | int fimc_hw_set_camera_source(struct fimc_dev *fimc, | ||
560 | struct s3c_fimc_isp_info *cam) | ||
561 | { | ||
562 | struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; | ||
563 | u32 cfg = 0; | ||
564 | |||
565 | if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) { | ||
566 | |||
567 | switch (fimc->vid_cap.fmt.code) { | ||
568 | case V4L2_MBUS_FMT_YUYV8_2X8: | ||
569 | cfg = S5P_CISRCFMT_ORDER422_YCBYCR; | ||
570 | break; | ||
571 | case V4L2_MBUS_FMT_YVYU8_2X8: | ||
572 | cfg = S5P_CISRCFMT_ORDER422_YCRYCB; | ||
573 | break; | ||
574 | case V4L2_MBUS_FMT_VYUY8_2X8: | ||
575 | cfg = S5P_CISRCFMT_ORDER422_CRYCBY; | ||
576 | break; | ||
577 | case V4L2_MBUS_FMT_UYVY8_2X8: | ||
578 | cfg = S5P_CISRCFMT_ORDER422_CBYCRY; | ||
579 | break; | ||
580 | default: | ||
581 | err("camera image format not supported: %d", | ||
582 | fimc->vid_cap.fmt.code); | ||
583 | return -EINVAL; | ||
584 | } | ||
585 | |||
586 | if (cam->bus_type == FIMC_ITU_601) { | ||
587 | if (cam->bus_width == 8) { | ||
588 | cfg |= S5P_CISRCFMT_ITU601_8BIT; | ||
589 | } else if (cam->bus_width == 16) { | ||
590 | cfg |= S5P_CISRCFMT_ITU601_16BIT; | ||
591 | } else { | ||
592 | err("invalid bus width: %d", cam->bus_width); | ||
593 | return -EINVAL; | ||
594 | } | ||
595 | } /* else defaults to ITU-R BT.656 8-bit */ | ||
526 | } | 596 | } |
597 | |||
598 | cfg |= S5P_CISRCFMT_HSIZE(f->o_width) | S5P_CISRCFMT_VSIZE(f->o_height); | ||
599 | writel(cfg, fimc->regs + S5P_CISRCFMT); | ||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | |||
604 | int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f) | ||
605 | { | ||
606 | u32 hoff2, voff2; | ||
607 | |||
608 | u32 cfg = readl(fimc->regs + S5P_CIWDOFST); | ||
609 | |||
610 | cfg &= ~(S5P_CIWDOFST_HOROFF_MASK | S5P_CIWDOFST_VEROFF_MASK); | ||
611 | cfg |= S5P_CIWDOFST_OFF_EN | | ||
612 | S5P_CIWDOFST_HOROFF(f->offs_h) | | ||
613 | S5P_CIWDOFST_VEROFF(f->offs_v); | ||
614 | |||
615 | writel(cfg, fimc->regs + S5P_CIWDOFST); | ||
616 | |||
617 | /* See CIWDOFSTn register description in the datasheet for details. */ | ||
618 | hoff2 = f->o_width - f->width - f->offs_h; | ||
619 | voff2 = f->o_height - f->height - f->offs_v; | ||
620 | cfg = S5P_CIWDOFST2_HOROFF(hoff2) | S5P_CIWDOFST2_VEROFF(voff2); | ||
621 | |||
622 | writel(cfg, fimc->regs + S5P_CIWDOFST2); | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | int fimc_hw_set_camera_type(struct fimc_dev *fimc, | ||
627 | struct s3c_fimc_isp_info *cam) | ||
628 | { | ||
629 | u32 cfg, tmp; | ||
630 | struct fimc_vid_cap *vid_cap = &fimc->vid_cap; | ||
631 | |||
632 | cfg = readl(fimc->regs + S5P_CIGCTRL); | ||
633 | |||
634 | /* Select ITU B interface, disable Writeback path and test pattern. */ | ||
635 | cfg &= ~(S5P_CIGCTRL_TESTPAT_MASK | S5P_CIGCTRL_SELCAM_ITU_A | | ||
636 | S5P_CIGCTRL_SELCAM_MIPI | S5P_CIGCTRL_CAMIF_SELWB | | ||
637 | S5P_CIGCTRL_SELCAM_MIPI_A); | ||
638 | |||
639 | if (cam->bus_type == FIMC_MIPI_CSI2) { | ||
640 | cfg |= S5P_CIGCTRL_SELCAM_MIPI; | ||
641 | |||
642 | if (cam->mux_id == 0) | ||
643 | cfg |= S5P_CIGCTRL_SELCAM_MIPI_A; | ||
644 | |||
645 | /* TODO: add remaining supported formats. */ | ||
646 | if (vid_cap->fmt.code == V4L2_MBUS_FMT_VYUY8_2X8) { | ||
647 | tmp = S5P_CSIIMGFMT_YCBCR422_8BIT; | ||
648 | } else { | ||
649 | err("camera image format not supported: %d", | ||
650 | vid_cap->fmt.code); | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | writel(tmp | (0x1 << 8), fimc->regs + S5P_CSIIMGFMT); | ||
654 | |||
655 | } else if (cam->bus_type == FIMC_ITU_601 || | ||
656 | cam->bus_type == FIMC_ITU_656) { | ||
657 | if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */ | ||
658 | cfg |= S5P_CIGCTRL_SELCAM_ITU_A; | ||
659 | } else if (cam->bus_type == FIMC_LCD_WB) { | ||
660 | cfg |= S5P_CIGCTRL_CAMIF_SELWB; | ||
661 | } else { | ||
662 | err("invalid camera bus type selected\n"); | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | writel(cfg, fimc->regs + S5P_CIGCTRL); | ||
666 | |||
667 | return 0; | ||
527 | } | 668 | } |
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h index a3cfe824db0..a57daedb5b5 100644 --- a/drivers/media/video/s5p-fimc/regs-fimc.h +++ b/drivers/media/video/s5p-fimc/regs-fimc.h | |||
@@ -11,10 +11,6 @@ | |||
11 | #ifndef REGS_FIMC_H_ | 11 | #ifndef REGS_FIMC_H_ |
12 | #define REGS_FIMC_H_ | 12 | #define REGS_FIMC_H_ |
13 | 13 | ||
14 | #define S5P_CIOYSA(__x) (0x18 + (__x) * 4) | ||
15 | #define S5P_CIOCBSA(__x) (0x28 + (__x) * 4) | ||
16 | #define S5P_CIOCRSA(__x) (0x38 + (__x) * 4) | ||
17 | |||
18 | /* Input source format */ | 14 | /* Input source format */ |
19 | #define S5P_CISRCFMT 0x00 | 15 | #define S5P_CISRCFMT 0x00 |
20 | #define S5P_CISRCFMT_ITU601_8BIT (1 << 31) | 16 | #define S5P_CISRCFMT_ITU601_8BIT (1 << 31) |
@@ -28,22 +24,21 @@ | |||
28 | 24 | ||
29 | /* Window offset */ | 25 | /* Window offset */ |
30 | #define S5P_CIWDOFST 0x04 | 26 | #define S5P_CIWDOFST 0x04 |
31 | #define S5P_CIWDOFST_WINOFSEN (1 << 31) | 27 | #define S5P_CIWDOFST_OFF_EN (1 << 31) |
32 | #define S5P_CIWDOFST_CLROVFIY (1 << 30) | 28 | #define S5P_CIWDOFST_CLROVFIY (1 << 30) |
33 | #define S5P_CIWDOFST_CLROVRLB (1 << 29) | 29 | #define S5P_CIWDOFST_CLROVRLB (1 << 29) |
34 | #define S5P_CIWDOFST_WINHOROFST_MASK (0x7ff << 16) | 30 | #define S5P_CIWDOFST_HOROFF_MASK (0x7ff << 16) |
35 | #define S5P_CIWDOFST_CLROVFICB (1 << 15) | 31 | #define S5P_CIWDOFST_CLROVFICB (1 << 15) |
36 | #define S5P_CIWDOFST_CLROVFICR (1 << 14) | 32 | #define S5P_CIWDOFST_CLROVFICR (1 << 14) |
37 | #define S5P_CIWDOFST_WINHOROFST(x) ((x) << 16) | 33 | #define S5P_CIWDOFST_HOROFF(x) ((x) << 16) |
38 | #define S5P_CIWDOFST_WINVEROFST(x) ((x) << 0) | 34 | #define S5P_CIWDOFST_VEROFF(x) ((x) << 0) |
39 | #define S5P_CIWDOFST_WINVEROFST_MASK (0xfff << 0) | 35 | #define S5P_CIWDOFST_VEROFF_MASK (0xfff << 0) |
40 | 36 | ||
41 | /* Global control */ | 37 | /* Global control */ |
42 | #define S5P_CIGCTRL 0x08 | 38 | #define S5P_CIGCTRL 0x08 |
43 | #define S5P_CIGCTRL_SWRST (1 << 31) | 39 | #define S5P_CIGCTRL_SWRST (1 << 31) |
44 | #define S5P_CIGCTRL_CAMRST_A (1 << 30) | 40 | #define S5P_CIGCTRL_CAMRST_A (1 << 30) |
45 | #define S5P_CIGCTRL_SELCAM_ITU_A (1 << 29) | 41 | #define S5P_CIGCTRL_SELCAM_ITU_A (1 << 29) |
46 | #define S5P_CIGCTRL_SELCAM_ITU_MASK (1 << 29) | ||
47 | #define S5P_CIGCTRL_TESTPAT_NORMAL (0 << 27) | 42 | #define S5P_CIGCTRL_TESTPAT_NORMAL (0 << 27) |
48 | #define S5P_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27) | 43 | #define S5P_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27) |
49 | #define S5P_CIGCTRL_TESTPAT_HOR_INC (2 << 27) | 44 | #define S5P_CIGCTRL_TESTPAT_HOR_INC (2 << 27) |
@@ -61,6 +56,8 @@ | |||
61 | #define S5P_CIGCTRL_SHDW_DISABLE (1 << 12) | 56 | #define S5P_CIGCTRL_SHDW_DISABLE (1 << 12) |
62 | #define S5P_CIGCTRL_SELCAM_MIPI_A (1 << 7) | 57 | #define S5P_CIGCTRL_SELCAM_MIPI_A (1 << 7) |
63 | #define S5P_CIGCTRL_CAMIF_SELWB (1 << 6) | 58 | #define S5P_CIGCTRL_CAMIF_SELWB (1 << 6) |
59 | /* 0 - ITU601; 1 - ITU709 */ | ||
60 | #define S5P_CIGCTRL_CSC_ITU601_709 (1 << 5) | ||
64 | #define S5P_CIGCTRL_INVPOLHSYNC (1 << 4) | 61 | #define S5P_CIGCTRL_INVPOLHSYNC (1 << 4) |
65 | #define S5P_CIGCTRL_SELCAM_MIPI (1 << 3) | 62 | #define S5P_CIGCTRL_SELCAM_MIPI (1 << 3) |
66 | #define S5P_CIGCTRL_INTERLACE (1 << 0) | 63 | #define S5P_CIGCTRL_INTERLACE (1 << 0) |
@@ -72,23 +69,10 @@ | |||
72 | #define S5P_CIWDOFST2_HOROFF(x) ((x) << 16) | 69 | #define S5P_CIWDOFST2_HOROFF(x) ((x) << 16) |
73 | #define S5P_CIWDOFST2_VEROFF(x) ((x) << 0) | 70 | #define S5P_CIWDOFST2_VEROFF(x) ((x) << 0) |
74 | 71 | ||
75 | /* Output DMA Y plane start address */ | 72 | /* Output DMA Y/Cb/Cr plane start addresses */ |
76 | #define S5P_CIOYSA1 0x18 | 73 | #define S5P_CIOYSA(n) (0x18 + (n) * 4) |
77 | #define S5P_CIOYSA2 0x1c | 74 | #define S5P_CIOCBSA(n) (0x28 + (n) * 4) |
78 | #define S5P_CIOYSA3 0x20 | 75 | #define S5P_CIOCRSA(n) (0x38 + (n) * 4) |
79 | #define S5P_CIOYSA4 0x24 | ||
80 | |||
81 | /* Output DMA Cb plane start address */ | ||
82 | #define S5P_CIOCBSA1 0x28 | ||
83 | #define S5P_CIOCBSA2 0x2c | ||
84 | #define S5P_CIOCBSA3 0x30 | ||
85 | #define S5P_CIOCBSA4 0x34 | ||
86 | |||
87 | /* Output DMA Cr plane start address */ | ||
88 | #define S5P_CIOCRSA1 0x38 | ||
89 | #define S5P_CIOCRSA2 0x3c | ||
90 | #define S5P_CIOCRSA3 0x40 | ||
91 | #define S5P_CIOCRSA4 0x44 | ||
92 | 76 | ||
93 | /* Target image format */ | 77 | /* Target image format */ |
94 | #define S5P_CITRGFMT 0x48 | 78 | #define S5P_CITRGFMT 0x48 |
@@ -168,6 +152,8 @@ | |||
168 | #define S5P_CISTATUS_OVFICB (1 << 30) | 152 | #define S5P_CISTATUS_OVFICB (1 << 30) |
169 | #define S5P_CISTATUS_OVFICR (1 << 29) | 153 | #define S5P_CISTATUS_OVFICR (1 << 29) |
170 | #define S5P_CISTATUS_VSYNC (1 << 28) | 154 | #define S5P_CISTATUS_VSYNC (1 << 28) |
155 | #define S5P_CISTATUS_FRAMECNT_MASK (3 << 26) | ||
156 | #define S5P_CISTATUS_FRAMECNT_SHIFT 26 | ||
171 | #define S5P_CISTATUS_WINOFF_EN (1 << 25) | 157 | #define S5P_CISTATUS_WINOFF_EN (1 << 25) |
172 | #define S5P_CISTATUS_IMGCPT_EN (1 << 22) | 158 | #define S5P_CISTATUS_IMGCPT_EN (1 << 22) |
173 | #define S5P_CISTATUS_IMGCPT_SCEN (1 << 21) | 159 | #define S5P_CISTATUS_IMGCPT_SCEN (1 << 21) |
@@ -206,10 +192,10 @@ | |||
206 | #define S5P_CIIMGEFF_PAT_CB(x) ((x) << 13) | 192 | #define S5P_CIIMGEFF_PAT_CB(x) ((x) << 13) |
207 | #define S5P_CIIMGEFF_PAT_CR(x) ((x) << 0) | 193 | #define S5P_CIIMGEFF_PAT_CR(x) ((x) << 0) |
208 | 194 | ||
209 | /* Input DMA Y/Cb/Cr plane start address 0 */ | 195 | /* Input DMA Y/Cb/Cr plane start address 0/1 */ |
210 | #define S5P_CIIYSA0 0xd4 | 196 | #define S5P_CIIYSA(n) (0xd4 + (n) * 0x70) |
211 | #define S5P_CIICBSA0 0xd8 | 197 | #define S5P_CIICBSA(n) (0xd8 + (n) * 0x70) |
212 | #define S5P_CIICRSA0 0xdc | 198 | #define S5P_CIICRSA(n) (0xdc + (n) * 0x70) |
213 | 199 | ||
214 | /* Real input DMA image size */ | 200 | /* Real input DMA image size */ |
215 | #define S5P_CIREAL_ISIZE 0xf8 | 201 | #define S5P_CIREAL_ISIZE 0xf8 |
@@ -250,11 +236,6 @@ | |||
250 | #define S5P_MSCTRL_ENVID (1 << 0) | 236 | #define S5P_MSCTRL_ENVID (1 << 0) |
251 | #define S5P_MSCTRL_FRAME_COUNT(x) ((x) << 24) | 237 | #define S5P_MSCTRL_FRAME_COUNT(x) ((x) << 24) |
252 | 238 | ||
253 | /* Input DMA Y/Cb/Cr plane start address 1 */ | ||
254 | #define S5P_CIIYSA1 0x144 | ||
255 | #define S5P_CIICBSA1 0x148 | ||
256 | #define S5P_CIICRSA1 0x14c | ||
257 | |||
258 | /* Output DMA Y/Cb/Cr offset */ | 239 | /* Output DMA Y/Cb/Cr offset */ |
259 | #define S5P_CIOYOFF 0x168 | 240 | #define S5P_CIOYOFF 0x168 |
260 | #define S5P_CIOCBOFF 0x16c | 241 | #define S5P_CIOCBOFF 0x16c |
@@ -289,5 +270,16 @@ | |||
289 | 270 | ||
290 | /* MIPI CSI image format */ | 271 | /* MIPI CSI image format */ |
291 | #define S5P_CSIIMGFMT 0x194 | 272 | #define S5P_CSIIMGFMT 0x194 |
273 | #define S5P_CSIIMGFMT_YCBCR422_8BIT 0x1e | ||
274 | #define S5P_CSIIMGFMT_RAW8 0x2a | ||
275 | #define S5P_CSIIMGFMT_RAW10 0x2b | ||
276 | #define S5P_CSIIMGFMT_RAW12 0x2c | ||
277 | #define S5P_CSIIMGFMT_USER1 0x30 | ||
278 | #define S5P_CSIIMGFMT_USER2 0x31 | ||
279 | #define S5P_CSIIMGFMT_USER3 0x32 | ||
280 | #define S5P_CSIIMGFMT_USER4 0x33 | ||
281 | |||
282 | /* Output frame buffer sequence mask */ | ||
283 | #define S5P_CIFCNTSEQ 0x1FC | ||
292 | 284 | ||
293 | #endif /* REGS_FIMC_H_ */ | 285 | #endif /* REGS_FIMC_H_ */ |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c deleted file mode 100644 index 6b3b09ef897..00000000000 --- a/drivers/media/video/saa5246a.c +++ /dev/null | |||
@@ -1,1123 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from | ||
3 | * Philips. | ||
4 | * | ||
5 | * Only capturing of Teletext pages is tested. The videotext chips also have a | ||
6 | * TV output but my hardware doesn't use it. For this reason this driver does | ||
7 | * not support changing any TV display settings. | ||
8 | * | ||
9 | * Copyright (C) 2004 Michael Geng <linux@MichaelGeng.de> | ||
10 | * | ||
11 | * Derived from | ||
12 | * | ||
13 | * saa5249 driver | ||
14 | * Copyright (C) 1998 Richard Guenther | ||
15 | * <richard.guenther@student.uni-tuebingen.de> | ||
16 | * | ||
17 | * with changes by | ||
18 | * Alan Cox <alan@lxorguk.ukuu.org.uk> | ||
19 | * | ||
20 | * and | ||
21 | * | ||
22 | * vtx.c | ||
23 | * Copyright (C) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de> | ||
24 | * | ||
25 | * This program is free software; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License as published by | ||
27 | * the Free Software Foundation; either version 2 of the License, or | ||
28 | * (at your option) any later version. | ||
29 | * | ||
30 | * This program is distributed in the hope that it will be useful, | ||
31 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
32 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
33 | * GNU General Public License for more details. | ||
34 | * | ||
35 | * You should have received a copy of the GNU General Public License | ||
36 | * along with this program; if not, write to the Free Software | ||
37 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
38 | * USA. | ||
39 | */ | ||
40 | |||
41 | #include <linux/module.h> | ||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/mm.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/i2c.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/mutex.h> | ||
48 | #include <linux/videotext.h> | ||
49 | #include <linux/videodev2.h> | ||
50 | #include <media/v4l2-device.h> | ||
51 | #include <media/v4l2-chip-ident.h> | ||
52 | #include <media/v4l2-ioctl.h> | ||
53 | #include <media/v4l2-i2c-drv.h> | ||
54 | |||
55 | MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); | ||
56 | MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver"); | ||
57 | MODULE_LICENSE("GPL"); | ||
58 | |||
59 | #define MAJOR_VERSION 1 /* driver major version number */ | ||
60 | #define MINOR_VERSION 8 /* driver minor version number */ | ||
61 | |||
62 | /* Number of DAUs = number of pages that can be searched at the same time. */ | ||
63 | #define NUM_DAUS 4 | ||
64 | |||
65 | #define NUM_ROWS_PER_PAGE 40 | ||
66 | |||
67 | /* first column is 0 (not 1) */ | ||
68 | #define POS_TIME_START 32 | ||
69 | #define POS_TIME_END 39 | ||
70 | |||
71 | #define POS_HEADER_START 7 | ||
72 | #define POS_HEADER_END 31 | ||
73 | |||
74 | /* Returns 'true' if the part of the videotext page described with req contains | ||
75 | (at least parts of) the time field */ | ||
76 | #define REQ_CONTAINS_TIME(p_req) \ | ||
77 | ((p_req)->start <= POS_TIME_END && \ | ||
78 | (p_req)->end >= POS_TIME_START) | ||
79 | |||
80 | /* Returns 'true' if the part of the videotext page described with req contains | ||
81 | (at least parts of) the page header */ | ||
82 | #define REQ_CONTAINS_HEADER(p_req) \ | ||
83 | ((p_req)->start <= POS_HEADER_END && \ | ||
84 | (p_req)->end >= POS_HEADER_START) | ||
85 | |||
86 | /*****************************************************************************/ | ||
87 | /* Mode register numbers of the SAA5246A */ | ||
88 | /*****************************************************************************/ | ||
89 | #define SAA5246A_REGISTER_R0 0 | ||
90 | #define SAA5246A_REGISTER_R1 1 | ||
91 | #define SAA5246A_REGISTER_R2 2 | ||
92 | #define SAA5246A_REGISTER_R3 3 | ||
93 | #define SAA5246A_REGISTER_R4 4 | ||
94 | #define SAA5246A_REGISTER_R5 5 | ||
95 | #define SAA5246A_REGISTER_R6 6 | ||
96 | #define SAA5246A_REGISTER_R7 7 | ||
97 | #define SAA5246A_REGISTER_R8 8 | ||
98 | #define SAA5246A_REGISTER_R9 9 | ||
99 | #define SAA5246A_REGISTER_R10 10 | ||
100 | #define SAA5246A_REGISTER_R11 11 | ||
101 | #define SAA5246A_REGISTER_R11B 11 | ||
102 | |||
103 | /* SAA5246A mode registers often autoincrement to the next register. | ||
104 | Therefore we use variable argument lists. The following macro indicates | ||
105 | the end of a command list. */ | ||
106 | #define COMMAND_END (-1) | ||
107 | |||
108 | /*****************************************************************************/ | ||
109 | /* Contents of the mode registers of the SAA5246A */ | ||
110 | /*****************************************************************************/ | ||
111 | /* Register R0 (Advanced Control) */ | ||
112 | #define R0_SELECT_R11 0x00 | ||
113 | #define R0_SELECT_R11B 0x01 | ||
114 | |||
115 | #define R0_PLL_TIME_CONSTANT_LONG 0x00 | ||
116 | #define R0_PLL_TIME_CONSTANT_SHORT 0x02 | ||
117 | |||
118 | #define R0_ENABLE_nODD_EVEN_OUTPUT 0x00 | ||
119 | #define R0_DISABLE_nODD_EVEN_OUTPUT 0x04 | ||
120 | |||
121 | #define R0_ENABLE_HDR_POLL 0x00 | ||
122 | #define R0_DISABLE_HDR_POLL 0x10 | ||
123 | |||
124 | #define R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x00 | ||
125 | #define R0_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x20 | ||
126 | |||
127 | #define R0_NO_FREE_RUN_PLL 0x00 | ||
128 | #define R0_FREE_RUN_PLL 0x40 | ||
129 | |||
130 | #define R0_NO_AUTOMATIC_FASTEXT_PROMPT 0x00 | ||
131 | #define R0_AUTOMATIC_FASTEXT_PROMPT 0x80 | ||
132 | |||
133 | /* Register R1 (Mode) */ | ||
134 | #define R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES 0x00 | ||
135 | #define R1_NON_INTERLACED_312_313_LINES 0x01 | ||
136 | #define R1_NON_INTERLACED_312_312_LINES 0x02 | ||
137 | #define R1_FFB_LEADING_EDGE_IN_FIRST_BROAD_PULSE 0x03 | ||
138 | #define R1_FFB_LEADING_EDGE_IN_SECOND_BROAD_PULSE 0x07 | ||
139 | |||
140 | #define R1_DEW 0x00 | ||
141 | #define R1_FULL_FIELD 0x08 | ||
142 | |||
143 | #define R1_EXTENDED_PACKET_DISABLE 0x00 | ||
144 | #define R1_EXTENDED_PACKET_ENABLE 0x10 | ||
145 | |||
146 | #define R1_DAUS_ALL_ON 0x00 | ||
147 | #define R1_DAUS_ALL_OFF 0x20 | ||
148 | |||
149 | #define R1_7_BITS_PLUS_PARITY 0x00 | ||
150 | #define R1_8_BITS_NO_PARITY 0x40 | ||
151 | |||
152 | #define R1_VCS_TO_SCS 0x00 | ||
153 | #define R1_NO_VCS_TO_SCS 0x80 | ||
154 | |||
155 | /* Register R2 (Page request address) */ | ||
156 | #define R2_IN_R3_SELECT_PAGE_HUNDREDS 0x00 | ||
157 | #define R2_IN_R3_SELECT_PAGE_TENS 0x01 | ||
158 | #define R2_IN_R3_SELECT_PAGE_UNITS 0x02 | ||
159 | #define R2_IN_R3_SELECT_HOURS_TENS 0x03 | ||
160 | #define R2_IN_R3_SELECT_HOURS_UNITS 0x04 | ||
161 | #define R2_IN_R3_SELECT_MINUTES_TENS 0x05 | ||
162 | #define R2_IN_R3_SELECT_MINUTES_UNITS 0x06 | ||
163 | |||
164 | #define R2_DAU_0 0x00 | ||
165 | #define R2_DAU_1 0x10 | ||
166 | #define R2_DAU_2 0x20 | ||
167 | #define R2_DAU_3 0x30 | ||
168 | |||
169 | #define R2_BANK_0 0x00 | ||
170 | #define R2_BANK 1 0x40 | ||
171 | |||
172 | #define R2_HAMMING_CHECK_ON 0x80 | ||
173 | #define R2_HAMMING_CHECK_OFF 0x00 | ||
174 | |||
175 | /* Register R3 (Page request data) */ | ||
176 | #define R3_PAGE_HUNDREDS_0 0x00 | ||
177 | #define R3_PAGE_HUNDREDS_1 0x01 | ||
178 | #define R3_PAGE_HUNDREDS_2 0x02 | ||
179 | #define R3_PAGE_HUNDREDS_3 0x03 | ||
180 | #define R3_PAGE_HUNDREDS_4 0x04 | ||
181 | #define R3_PAGE_HUNDREDS_5 0x05 | ||
182 | #define R3_PAGE_HUNDREDS_6 0x06 | ||
183 | #define R3_PAGE_HUNDREDS_7 0x07 | ||
184 | |||
185 | #define R3_HOLD_PAGE 0x00 | ||
186 | #define R3_UPDATE_PAGE 0x08 | ||
187 | |||
188 | #define R3_PAGE_HUNDREDS_DO_NOT_CARE 0x00 | ||
189 | #define R3_PAGE_HUNDREDS_DO_CARE 0x10 | ||
190 | |||
191 | #define R3_PAGE_TENS_DO_NOT_CARE 0x00 | ||
192 | #define R3_PAGE_TENS_DO_CARE 0x10 | ||
193 | |||
194 | #define R3_PAGE_UNITS_DO_NOT_CARE 0x00 | ||
195 | #define R3_PAGE_UNITS_DO_CARE 0x10 | ||
196 | |||
197 | #define R3_HOURS_TENS_DO_NOT_CARE 0x00 | ||
198 | #define R3_HOURS_TENS_DO_CARE 0x10 | ||
199 | |||
200 | #define R3_HOURS_UNITS_DO_NOT_CARE 0x00 | ||
201 | #define R3_HOURS_UNITS_DO_CARE 0x10 | ||
202 | |||
203 | #define R3_MINUTES_TENS_DO_NOT_CARE 0x00 | ||
204 | #define R3_MINUTES_TENS_DO_CARE 0x10 | ||
205 | |||
206 | #define R3_MINUTES_UNITS_DO_NOT_CARE 0x00 | ||
207 | #define R3_MINUTES_UNITS_DO_CARE 0x10 | ||
208 | |||
209 | /* Register R4 (Display chapter) */ | ||
210 | #define R4_DISPLAY_PAGE_0 0x00 | ||
211 | #define R4_DISPLAY_PAGE_1 0x01 | ||
212 | #define R4_DISPLAY_PAGE_2 0x02 | ||
213 | #define R4_DISPLAY_PAGE_3 0x03 | ||
214 | #define R4_DISPLAY_PAGE_4 0x04 | ||
215 | #define R4_DISPLAY_PAGE_5 0x05 | ||
216 | #define R4_DISPLAY_PAGE_6 0x06 | ||
217 | #define R4_DISPLAY_PAGE_7 0x07 | ||
218 | |||
219 | /* Register R5 (Normal display control) */ | ||
220 | #define R5_PICTURE_INSIDE_BOXING_OFF 0x00 | ||
221 | #define R5_PICTURE_INSIDE_BOXING_ON 0x01 | ||
222 | |||
223 | #define R5_PICTURE_OUTSIDE_BOXING_OFF 0x00 | ||
224 | #define R5_PICTURE_OUTSIDE_BOXING_ON 0x02 | ||
225 | |||
226 | #define R5_TEXT_INSIDE_BOXING_OFF 0x00 | ||
227 | #define R5_TEXT_INSIDE_BOXING_ON 0x04 | ||
228 | |||
229 | #define R5_TEXT_OUTSIDE_BOXING_OFF 0x00 | ||
230 | #define R5_TEXT_OUTSIDE_BOXING_ON 0x08 | ||
231 | |||
232 | #define R5_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00 | ||
233 | #define R5_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10 | ||
234 | |||
235 | #define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00 | ||
236 | #define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20 | ||
237 | |||
238 | #define R5_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00 | ||
239 | #define R5_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40 | ||
240 | |||
241 | #define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00 | ||
242 | #define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80 | ||
243 | |||
244 | /* Register R6 (Newsflash display) */ | ||
245 | #define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_OFF 0x00 | ||
246 | #define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_ON 0x01 | ||
247 | |||
248 | #define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_OFF 0x00 | ||
249 | #define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_ON 0x02 | ||
250 | |||
251 | #define R6_NEWSFLASH_TEXT_INSIDE_BOXING_OFF 0x00 | ||
252 | #define R6_NEWSFLASH_TEXT_INSIDE_BOXING_ON 0x04 | ||
253 | |||
254 | #define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_OFF 0x00 | ||
255 | #define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_ON 0x08 | ||
256 | |||
257 | #define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00 | ||
258 | #define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10 | ||
259 | |||
260 | #define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00 | ||
261 | #define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20 | ||
262 | |||
263 | #define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00 | ||
264 | #define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40 | ||
265 | |||
266 | #define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00 | ||
267 | #define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80 | ||
268 | |||
269 | /* Register R7 (Display mode) */ | ||
270 | #define R7_BOX_OFF_ROW_0 0x00 | ||
271 | #define R7_BOX_ON_ROW_0 0x01 | ||
272 | |||
273 | #define R7_BOX_OFF_ROW_1_TO_23 0x00 | ||
274 | #define R7_BOX_ON_ROW_1_TO_23 0x02 | ||
275 | |||
276 | #define R7_BOX_OFF_ROW_24 0x00 | ||
277 | #define R7_BOX_ON_ROW_24 0x04 | ||
278 | |||
279 | #define R7_SINGLE_HEIGHT 0x00 | ||
280 | #define R7_DOUBLE_HEIGHT 0x08 | ||
281 | |||
282 | #define R7_TOP_HALF 0x00 | ||
283 | #define R7_BOTTOM_HALF 0x10 | ||
284 | |||
285 | #define R7_REVEAL_OFF 0x00 | ||
286 | #define R7_REVEAL_ON 0x20 | ||
287 | |||
288 | #define R7_CURSER_OFF 0x00 | ||
289 | #define R7_CURSER_ON 0x40 | ||
290 | |||
291 | #define R7_STATUS_BOTTOM 0x00 | ||
292 | #define R7_STATUS_TOP 0x80 | ||
293 | |||
294 | /* Register R8 (Active chapter) */ | ||
295 | #define R8_ACTIVE_CHAPTER_0 0x00 | ||
296 | #define R8_ACTIVE_CHAPTER_1 0x01 | ||
297 | #define R8_ACTIVE_CHAPTER_2 0x02 | ||
298 | #define R8_ACTIVE_CHAPTER_3 0x03 | ||
299 | #define R8_ACTIVE_CHAPTER_4 0x04 | ||
300 | #define R8_ACTIVE_CHAPTER_5 0x05 | ||
301 | #define R8_ACTIVE_CHAPTER_6 0x06 | ||
302 | #define R8_ACTIVE_CHAPTER_7 0x07 | ||
303 | |||
304 | #define R8_CLEAR_MEMORY 0x08 | ||
305 | #define R8_DO_NOT_CLEAR_MEMORY 0x00 | ||
306 | |||
307 | /* Register R9 (Curser row) */ | ||
308 | #define R9_CURSER_ROW_0 0x00 | ||
309 | #define R9_CURSER_ROW_1 0x01 | ||
310 | #define R9_CURSER_ROW_2 0x02 | ||
311 | #define R9_CURSER_ROW_25 0x19 | ||
312 | |||
313 | /* Register R10 (Curser column) */ | ||
314 | #define R10_CURSER_COLUMN_0 0x00 | ||
315 | #define R10_CURSER_COLUMN_6 0x06 | ||
316 | #define R10_CURSER_COLUMN_8 0x08 | ||
317 | |||
318 | /*****************************************************************************/ | ||
319 | /* Row 25 control data in column 0 to 9 */ | ||
320 | /*****************************************************************************/ | ||
321 | #define ROW25_COLUMN0_PAGE_UNITS 0x0F | ||
322 | |||
323 | #define ROW25_COLUMN1_PAGE_TENS 0x0F | ||
324 | |||
325 | #define ROW25_COLUMN2_MINUTES_UNITS 0x0F | ||
326 | |||
327 | #define ROW25_COLUMN3_MINUTES_TENS 0x07 | ||
328 | #define ROW25_COLUMN3_DELETE_PAGE 0x08 | ||
329 | |||
330 | #define ROW25_COLUMN4_HOUR_UNITS 0x0F | ||
331 | |||
332 | #define ROW25_COLUMN5_HOUR_TENS 0x03 | ||
333 | #define ROW25_COLUMN5_INSERT_HEADLINE 0x04 | ||
334 | #define ROW25_COLUMN5_INSERT_SUBTITLE 0x08 | ||
335 | |||
336 | #define ROW25_COLUMN6_SUPPRESS_HEADER 0x01 | ||
337 | #define ROW25_COLUMN6_UPDATE_PAGE 0x02 | ||
338 | #define ROW25_COLUMN6_INTERRUPTED_SEQUENCE 0x04 | ||
339 | #define ROW25_COLUMN6_SUPPRESS_DISPLAY 0x08 | ||
340 | |||
341 | #define ROW25_COLUMN7_SERIAL_MODE 0x01 | ||
342 | #define ROW25_COLUMN7_CHARACTER_SET 0x0E | ||
343 | |||
344 | #define ROW25_COLUMN8_PAGE_HUNDREDS 0x07 | ||
345 | #define ROW25_COLUMN8_PAGE_NOT_FOUND 0x10 | ||
346 | |||
347 | #define ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR 0x20 | ||
348 | |||
349 | #define ROW25_COLUMN0_TO_7_HAMMING_ERROR 0x10 | ||
350 | |||
351 | /*****************************************************************************/ | ||
352 | /* Helper macros for extracting page, hour and minute digits */ | ||
353 | /*****************************************************************************/ | ||
354 | /* BYTE_POS 0 is at row 0, column 0, | ||
355 | BYTE_POS 1 is at row 0, column 1, | ||
356 | BYTE_POS 40 is at row 1, column 0, (with NUM_ROWS_PER_PAGE = 40) | ||
357 | BYTE_POS 41 is at row 1, column 1, (with NUM_ROWS_PER_PAGE = 40), | ||
358 | ... */ | ||
359 | #define ROW(BYTE_POS) (BYTE_POS / NUM_ROWS_PER_PAGE) | ||
360 | #define COLUMN(BYTE_POS) (BYTE_POS % NUM_ROWS_PER_PAGE) | ||
361 | |||
362 | /*****************************************************************************/ | ||
363 | /* Helper macros for extracting page, hour and minute digits */ | ||
364 | /*****************************************************************************/ | ||
365 | /* Macros for extracting hundreds, tens and units of a page number which | ||
366 | must be in the range 0 ... 0x799. | ||
367 | Note that page is coded in hexadecimal, i.e. 0x123 means page 123. | ||
368 | page 0x.. means page 8.. */ | ||
369 | #define HUNDREDS_OF_PAGE(page) (((page) / 0x100) & 0x7) | ||
370 | #define TENS_OF_PAGE(page) (((page) / 0x10) & 0xF) | ||
371 | #define UNITS_OF_PAGE(page) ((page) & 0xF) | ||
372 | |||
373 | /* Macros for extracting tens and units of a hour information which | ||
374 | must be in the range 0 ... 0x24. | ||
375 | Note that hour is coded in hexadecimal, i.e. 0x12 means 12 hours */ | ||
376 | #define TENS_OF_HOUR(hour) ((hour) / 0x10) | ||
377 | #define UNITS_OF_HOUR(hour) ((hour) & 0xF) | ||
378 | |||
379 | /* Macros for extracting tens and units of a minute information which | ||
380 | must be in the range 0 ... 0x59. | ||
381 | Note that minute is coded in hexadecimal, i.e. 0x12 means 12 minutes */ | ||
382 | #define TENS_OF_MINUTE(minute) ((minute) / 0x10) | ||
383 | #define UNITS_OF_MINUTE(minute) ((minute) & 0xF) | ||
384 | |||
385 | #define HOUR_MAX 0x23 | ||
386 | #define MINUTE_MAX 0x59 | ||
387 | #define PAGE_MAX 0x8FF | ||
388 | |||
389 | |||
390 | struct saa5246a_device | ||
391 | { | ||
392 | struct v4l2_subdev sd; | ||
393 | struct video_device *vdev; | ||
394 | u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; | ||
395 | int is_searching[NUM_DAUS]; | ||
396 | unsigned long in_use; | ||
397 | struct mutex lock; | ||
398 | }; | ||
399 | |||
400 | static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd) | ||
401 | { | ||
402 | return container_of(sd, struct saa5246a_device, sd); | ||
403 | } | ||
404 | |||
405 | static struct video_device saa_template; /* Declared near bottom */ | ||
406 | |||
407 | /* | ||
408 | * I2C interfaces | ||
409 | */ | ||
410 | |||
411 | static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data) | ||
412 | { | ||
413 | struct i2c_client *client = v4l2_get_subdevdata(&t->sd); | ||
414 | char buf[64]; | ||
415 | |||
416 | buf[0] = reg; | ||
417 | memcpy(buf+1, data, count); | ||
418 | |||
419 | if (i2c_master_send(client, buf, count + 1) == count + 1) | ||
420 | return 0; | ||
421 | return -1; | ||
422 | } | ||
423 | |||
424 | static int i2c_senddata(struct saa5246a_device *t, ...) | ||
425 | { | ||
426 | unsigned char buf[64]; | ||
427 | int v; | ||
428 | int ct = 0; | ||
429 | va_list argp; | ||
430 | va_start(argp, t); | ||
431 | |||
432 | while ((v = va_arg(argp, int)) != -1) | ||
433 | buf[ct++] = v; | ||
434 | |||
435 | va_end(argp); | ||
436 | return i2c_sendbuf(t, buf[0], ct-1, buf+1); | ||
437 | } | ||
438 | |||
439 | /* Get count number of bytes from I²C-device at address adr, store them in buf. | ||
440 | * Start & stop handshaking is done by this routine, ack will be sent after the | ||
441 | * last byte to inhibit further sending of data. If uaccess is 'true', data is | ||
442 | * written to user-space with put_user. Returns -1 if I²C-device didn't send | ||
443 | * acknowledge, 0 otherwise | ||
444 | */ | ||
445 | static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf) | ||
446 | { | ||
447 | struct i2c_client *client = v4l2_get_subdevdata(&t->sd); | ||
448 | |||
449 | if (i2c_master_recv(client, buf, count) != count) | ||
450 | return -1; | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | /* When a page is found then the not FOUND bit in one of the status registers | ||
455 | * of the SAA5264A chip is cleared. Unfortunately this bit is not set | ||
456 | * automatically when a new page is requested. Instead this function must be | ||
457 | * called after a page has been requested. | ||
458 | * | ||
459 | * Return value: 0 if successful | ||
460 | */ | ||
461 | static int saa5246a_clear_found_bit(struct saa5246a_device *t, | ||
462 | unsigned char dau_no) | ||
463 | { | ||
464 | unsigned char row_25_column_8; | ||
465 | |||
466 | if (i2c_senddata(t, SAA5246A_REGISTER_R8, | ||
467 | |||
468 | dau_no | | ||
469 | R8_DO_NOT_CLEAR_MEMORY, | ||
470 | |||
471 | R9_CURSER_ROW_25, | ||
472 | |||
473 | R10_CURSER_COLUMN_8, | ||
474 | |||
475 | COMMAND_END) || | ||
476 | i2c_getdata(t, 1, &row_25_column_8)) | ||
477 | { | ||
478 | return -EIO; | ||
479 | } | ||
480 | row_25_column_8 |= ROW25_COLUMN8_PAGE_NOT_FOUND; | ||
481 | if (i2c_senddata(t, SAA5246A_REGISTER_R8, | ||
482 | |||
483 | dau_no | | ||
484 | R8_DO_NOT_CLEAR_MEMORY, | ||
485 | |||
486 | R9_CURSER_ROW_25, | ||
487 | |||
488 | R10_CURSER_COLUMN_8, | ||
489 | |||
490 | row_25_column_8, | ||
491 | |||
492 | COMMAND_END)) | ||
493 | { | ||
494 | return -EIO; | ||
495 | } | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | /* Requests one videotext page as described in req. The fields of req are | ||
501 | * checked and an error is returned if something is invalid. | ||
502 | * | ||
503 | * Return value: 0 if successful | ||
504 | */ | ||
505 | static int saa5246a_request_page(struct saa5246a_device *t, | ||
506 | vtx_pagereq_t *req) | ||
507 | { | ||
508 | if (req->pagemask < 0 || req->pagemask >= PGMASK_MAX) | ||
509 | return -EINVAL; | ||
510 | if (req->pagemask & PGMASK_PAGE) | ||
511 | if (req->page < 0 || req->page > PAGE_MAX) | ||
512 | return -EINVAL; | ||
513 | if (req->pagemask & PGMASK_HOUR) | ||
514 | if (req->hour < 0 || req->hour > HOUR_MAX) | ||
515 | return -EINVAL; | ||
516 | if (req->pagemask & PGMASK_MINUTE) | ||
517 | if (req->minute < 0 || req->minute > MINUTE_MAX) | ||
518 | return -EINVAL; | ||
519 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
520 | return -EINVAL; | ||
521 | |||
522 | if (i2c_senddata(t, SAA5246A_REGISTER_R2, | ||
523 | |||
524 | R2_IN_R3_SELECT_PAGE_HUNDREDS | | ||
525 | req->pgbuf << 4 | | ||
526 | R2_BANK_0 | | ||
527 | R2_HAMMING_CHECK_OFF, | ||
528 | |||
529 | HUNDREDS_OF_PAGE(req->page) | | ||
530 | R3_HOLD_PAGE | | ||
531 | (req->pagemask & PG_HUND ? | ||
532 | R3_PAGE_HUNDREDS_DO_CARE : | ||
533 | R3_PAGE_HUNDREDS_DO_NOT_CARE), | ||
534 | |||
535 | TENS_OF_PAGE(req->page) | | ||
536 | (req->pagemask & PG_TEN ? | ||
537 | R3_PAGE_TENS_DO_CARE : | ||
538 | R3_PAGE_TENS_DO_NOT_CARE), | ||
539 | |||
540 | UNITS_OF_PAGE(req->page) | | ||
541 | (req->pagemask & PG_UNIT ? | ||
542 | R3_PAGE_UNITS_DO_CARE : | ||
543 | R3_PAGE_UNITS_DO_NOT_CARE), | ||
544 | |||
545 | TENS_OF_HOUR(req->hour) | | ||
546 | (req->pagemask & HR_TEN ? | ||
547 | R3_HOURS_TENS_DO_CARE : | ||
548 | R3_HOURS_TENS_DO_NOT_CARE), | ||
549 | |||
550 | UNITS_OF_HOUR(req->hour) | | ||
551 | (req->pagemask & HR_UNIT ? | ||
552 | R3_HOURS_UNITS_DO_CARE : | ||
553 | R3_HOURS_UNITS_DO_NOT_CARE), | ||
554 | |||
555 | TENS_OF_MINUTE(req->minute) | | ||
556 | (req->pagemask & MIN_TEN ? | ||
557 | R3_MINUTES_TENS_DO_CARE : | ||
558 | R3_MINUTES_TENS_DO_NOT_CARE), | ||
559 | |||
560 | UNITS_OF_MINUTE(req->minute) | | ||
561 | (req->pagemask & MIN_UNIT ? | ||
562 | R3_MINUTES_UNITS_DO_CARE : | ||
563 | R3_MINUTES_UNITS_DO_NOT_CARE), | ||
564 | |||
565 | COMMAND_END) || i2c_senddata(t, SAA5246A_REGISTER_R2, | ||
566 | |||
567 | R2_IN_R3_SELECT_PAGE_HUNDREDS | | ||
568 | req->pgbuf << 4 | | ||
569 | R2_BANK_0 | | ||
570 | R2_HAMMING_CHECK_OFF, | ||
571 | |||
572 | HUNDREDS_OF_PAGE(req->page) | | ||
573 | R3_UPDATE_PAGE | | ||
574 | (req->pagemask & PG_HUND ? | ||
575 | R3_PAGE_HUNDREDS_DO_CARE : | ||
576 | R3_PAGE_HUNDREDS_DO_NOT_CARE), | ||
577 | |||
578 | COMMAND_END)) | ||
579 | { | ||
580 | return -EIO; | ||
581 | } | ||
582 | |||
583 | t->is_searching[req->pgbuf] = true; | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | /* This routine decodes the page number from the infobits contained in line 25. | ||
588 | * | ||
589 | * Parameters: | ||
590 | * infobits: must be bits 0 to 9 of column 25 | ||
591 | * | ||
592 | * Return value: page number coded in hexadecimal, i. e. page 123 is coded 0x123 | ||
593 | */ | ||
594 | static inline int saa5246a_extract_pagenum_from_infobits( | ||
595 | unsigned char infobits[10]) | ||
596 | { | ||
597 | int page_hundreds, page_tens, page_units; | ||
598 | |||
599 | page_units = infobits[0] & ROW25_COLUMN0_PAGE_UNITS; | ||
600 | page_tens = infobits[1] & ROW25_COLUMN1_PAGE_TENS; | ||
601 | page_hundreds = infobits[8] & ROW25_COLUMN8_PAGE_HUNDREDS; | ||
602 | |||
603 | /* page 0x.. means page 8.. */ | ||
604 | if (page_hundreds == 0) | ||
605 | page_hundreds = 8; | ||
606 | |||
607 | return((page_hundreds << 8) | (page_tens << 4) | page_units); | ||
608 | } | ||
609 | |||
610 | /* Decodes the hour from the infobits contained in line 25. | ||
611 | * | ||
612 | * Parameters: | ||
613 | * infobits: must be bits 0 to 9 of column 25 | ||
614 | * | ||
615 | * Return: hour coded in hexadecimal, i. e. 12h is coded 0x12 | ||
616 | */ | ||
617 | static inline int saa5246a_extract_hour_from_infobits( | ||
618 | unsigned char infobits[10]) | ||
619 | { | ||
620 | int hour_tens, hour_units; | ||
621 | |||
622 | hour_units = infobits[4] & ROW25_COLUMN4_HOUR_UNITS; | ||
623 | hour_tens = infobits[5] & ROW25_COLUMN5_HOUR_TENS; | ||
624 | |||
625 | return((hour_tens << 4) | hour_units); | ||
626 | } | ||
627 | |||
628 | /* Decodes the minutes from the infobits contained in line 25. | ||
629 | * | ||
630 | * Parameters: | ||
631 | * infobits: must be bits 0 to 9 of column 25 | ||
632 | * | ||
633 | * Return: minutes coded in hexadecimal, i. e. 10min is coded 0x10 | ||
634 | */ | ||
635 | static inline int saa5246a_extract_minutes_from_infobits( | ||
636 | unsigned char infobits[10]) | ||
637 | { | ||
638 | int minutes_tens, minutes_units; | ||
639 | |||
640 | minutes_units = infobits[2] & ROW25_COLUMN2_MINUTES_UNITS; | ||
641 | minutes_tens = infobits[3] & ROW25_COLUMN3_MINUTES_TENS; | ||
642 | |||
643 | return((minutes_tens << 4) | minutes_units); | ||
644 | } | ||
645 | |||
646 | /* Reads the status bits contained in the first 10 columns of the first line | ||
647 | * and extracts the information into info. | ||
648 | * | ||
649 | * Return value: 0 if successful | ||
650 | */ | ||
651 | static inline int saa5246a_get_status(struct saa5246a_device *t, | ||
652 | vtx_pageinfo_t *info, unsigned char dau_no) | ||
653 | { | ||
654 | unsigned char infobits[10]; | ||
655 | int column; | ||
656 | |||
657 | if (dau_no >= NUM_DAUS) | ||
658 | return -EINVAL; | ||
659 | |||
660 | if (i2c_senddata(t, SAA5246A_REGISTER_R8, | ||
661 | |||
662 | dau_no | | ||
663 | R8_DO_NOT_CLEAR_MEMORY, | ||
664 | |||
665 | R9_CURSER_ROW_25, | ||
666 | |||
667 | R10_CURSER_COLUMN_0, | ||
668 | |||
669 | COMMAND_END) || | ||
670 | i2c_getdata(t, 10, infobits)) | ||
671 | { | ||
672 | return -EIO; | ||
673 | } | ||
674 | |||
675 | info->pagenum = saa5246a_extract_pagenum_from_infobits(infobits); | ||
676 | info->hour = saa5246a_extract_hour_from_infobits(infobits); | ||
677 | info->minute = saa5246a_extract_minutes_from_infobits(infobits); | ||
678 | info->charset = ((infobits[7] & ROW25_COLUMN7_CHARACTER_SET) >> 1); | ||
679 | info->delete = !!(infobits[3] & ROW25_COLUMN3_DELETE_PAGE); | ||
680 | info->headline = !!(infobits[5] & ROW25_COLUMN5_INSERT_HEADLINE); | ||
681 | info->subtitle = !!(infobits[5] & ROW25_COLUMN5_INSERT_SUBTITLE); | ||
682 | info->supp_header = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_HEADER); | ||
683 | info->update = !!(infobits[6] & ROW25_COLUMN6_UPDATE_PAGE); | ||
684 | info->inter_seq = !!(infobits[6] & ROW25_COLUMN6_INTERRUPTED_SEQUENCE); | ||
685 | info->dis_disp = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_DISPLAY); | ||
686 | info->serial = !!(infobits[7] & ROW25_COLUMN7_SERIAL_MODE); | ||
687 | info->notfound = !!(infobits[8] & ROW25_COLUMN8_PAGE_NOT_FOUND); | ||
688 | info->pblf = !!(infobits[9] & ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR); | ||
689 | info->hamming = 0; | ||
690 | for (column = 0; column <= 7; column++) { | ||
691 | if (infobits[column] & ROW25_COLUMN0_TO_7_HAMMING_ERROR) { | ||
692 | info->hamming = 1; | ||
693 | break; | ||
694 | } | ||
695 | } | ||
696 | if (!info->hamming && !info->notfound) | ||
697 | t->is_searching[dau_no] = false; | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | /* Reads 1 videotext page buffer of the SAA5246A. | ||
702 | * | ||
703 | * req is used both as input and as output. It contains information which part | ||
704 | * must be read. The videotext page is copied into req->buffer. | ||
705 | * | ||
706 | * Return value: 0 if successful | ||
707 | */ | ||
708 | static inline int saa5246a_get_page(struct saa5246a_device *t, | ||
709 | vtx_pagereq_t *req) | ||
710 | { | ||
711 | int start, end, size; | ||
712 | char *buf; | ||
713 | int err; | ||
714 | |||
715 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || | ||
716 | req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE) | ||
717 | return -EINVAL; | ||
718 | |||
719 | buf = kmalloc(VTX_PAGESIZE, GFP_KERNEL); | ||
720 | if (!buf) | ||
721 | return -ENOMEM; | ||
722 | |||
723 | /* Read "normal" part of page */ | ||
724 | err = -EIO; | ||
725 | |||
726 | end = min(req->end, VTX_PAGESIZE - 1); | ||
727 | if (i2c_senddata(t, SAA5246A_REGISTER_R8, | ||
728 | req->pgbuf | R8_DO_NOT_CLEAR_MEMORY, | ||
729 | ROW(req->start), COLUMN(req->start), COMMAND_END)) | ||
730 | goto out; | ||
731 | if (i2c_getdata(t, end - req->start + 1, buf)) | ||
732 | goto out; | ||
733 | err = -EFAULT; | ||
734 | if (copy_to_user(req->buffer, buf, end - req->start + 1)) | ||
735 | goto out; | ||
736 | |||
737 | /* Always get the time from buffer 4, since this stupid SAA5246A only | ||
738 | * updates the currently displayed buffer... | ||
739 | */ | ||
740 | if (REQ_CONTAINS_TIME(req)) { | ||
741 | start = max(req->start, POS_TIME_START); | ||
742 | end = min(req->end, POS_TIME_END); | ||
743 | size = end - start + 1; | ||
744 | err = -EINVAL; | ||
745 | if (size < 0) | ||
746 | goto out; | ||
747 | err = -EIO; | ||
748 | if (i2c_senddata(t, SAA5246A_REGISTER_R8, | ||
749 | R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY, | ||
750 | R9_CURSER_ROW_0, start, COMMAND_END)) | ||
751 | goto out; | ||
752 | if (i2c_getdata(t, size, buf)) | ||
753 | goto out; | ||
754 | err = -EFAULT; | ||
755 | if (copy_to_user(req->buffer + start - req->start, buf, size)) | ||
756 | goto out; | ||
757 | } | ||
758 | /* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */ | ||
759 | if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) { | ||
760 | start = max(req->start, POS_HEADER_START); | ||
761 | end = min(req->end, POS_HEADER_END); | ||
762 | size = end - start + 1; | ||
763 | err = -EINVAL; | ||
764 | if (size < 0) | ||
765 | goto out; | ||
766 | err = -EIO; | ||
767 | if (i2c_senddata(t, SAA5246A_REGISTER_R8, | ||
768 | R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY, | ||
769 | R9_CURSER_ROW_0, start, COMMAND_END)) | ||
770 | goto out; | ||
771 | if (i2c_getdata(t, end - start + 1, buf)) | ||
772 | goto out; | ||
773 | err = -EFAULT; | ||
774 | if (copy_to_user(req->buffer + start - req->start, buf, size)) | ||
775 | goto out; | ||
776 | } | ||
777 | err = 0; | ||
778 | out: | ||
779 | kfree(buf); | ||
780 | return err; | ||
781 | } | ||
782 | |||
783 | /* Stops the acquisition circuit given in dau_no. The page buffer associated | ||
784 | * with this acquisition circuit will no more be updated. The other daus are | ||
785 | * not affected. | ||
786 | * | ||
787 | * Return value: 0 if successful | ||
788 | */ | ||
789 | static inline int saa5246a_stop_dau(struct saa5246a_device *t, | ||
790 | unsigned char dau_no) | ||
791 | { | ||
792 | if (dau_no >= NUM_DAUS) | ||
793 | return -EINVAL; | ||
794 | if (i2c_senddata(t, SAA5246A_REGISTER_R2, | ||
795 | |||
796 | R2_IN_R3_SELECT_PAGE_HUNDREDS | | ||
797 | dau_no << 4 | | ||
798 | R2_BANK_0 | | ||
799 | R2_HAMMING_CHECK_OFF, | ||
800 | |||
801 | R3_PAGE_HUNDREDS_0 | | ||
802 | R3_HOLD_PAGE | | ||
803 | R3_PAGE_HUNDREDS_DO_NOT_CARE, | ||
804 | |||
805 | COMMAND_END)) | ||
806 | { | ||
807 | return -EIO; | ||
808 | } | ||
809 | t->is_searching[dau_no] = false; | ||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | /* Handles ioctls defined in videotext.h | ||
814 | * | ||
815 | * Returns 0 if successful | ||
816 | */ | ||
817 | static long do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg) | ||
818 | { | ||
819 | struct saa5246a_device *t = video_drvdata(file); | ||
820 | |||
821 | switch(cmd) | ||
822 | { | ||
823 | case VTXIOCGETINFO: | ||
824 | { | ||
825 | vtx_info_t *info = arg; | ||
826 | |||
827 | info->version_major = MAJOR_VERSION; | ||
828 | info->version_minor = MINOR_VERSION; | ||
829 | info->numpages = NUM_DAUS; | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | case VTXIOCCLRPAGE: | ||
834 | { | ||
835 | vtx_pagereq_t *req = arg; | ||
836 | |||
837 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
838 | return -EINVAL; | ||
839 | memset(t->pgbuf[req->pgbuf], ' ', sizeof(t->pgbuf[0])); | ||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | case VTXIOCCLRFOUND: | ||
844 | { | ||
845 | vtx_pagereq_t *req = arg; | ||
846 | |||
847 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
848 | return -EINVAL; | ||
849 | return(saa5246a_clear_found_bit(t, req->pgbuf)); | ||
850 | } | ||
851 | |||
852 | case VTXIOCPAGEREQ: | ||
853 | { | ||
854 | vtx_pagereq_t *req = arg; | ||
855 | |||
856 | return(saa5246a_request_page(t, req)); | ||
857 | } | ||
858 | |||
859 | case VTXIOCGETSTAT: | ||
860 | { | ||
861 | vtx_pagereq_t *req = arg; | ||
862 | vtx_pageinfo_t info; | ||
863 | int rval; | ||
864 | |||
865 | if ((rval = saa5246a_get_status(t, &info, req->pgbuf))) | ||
866 | return rval; | ||
867 | if(copy_to_user(req->buffer, &info, | ||
868 | sizeof(vtx_pageinfo_t))) | ||
869 | return -EFAULT; | ||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | case VTXIOCGETPAGE: | ||
874 | { | ||
875 | vtx_pagereq_t *req = arg; | ||
876 | |||
877 | return(saa5246a_get_page(t, req)); | ||
878 | } | ||
879 | |||
880 | case VTXIOCSTOPDAU: | ||
881 | { | ||
882 | vtx_pagereq_t *req = arg; | ||
883 | |||
884 | return(saa5246a_stop_dau(t, req->pgbuf)); | ||
885 | } | ||
886 | |||
887 | case VTXIOCPUTPAGE: | ||
888 | case VTXIOCSETDISP: | ||
889 | case VTXIOCPUTSTAT: | ||
890 | return 0; | ||
891 | |||
892 | case VTXIOCCLRCACHE: | ||
893 | { | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | case VTXIOCSETVIRT: | ||
898 | { | ||
899 | /* I do not know what "virtual mode" means */ | ||
900 | return 0; | ||
901 | } | ||
902 | } | ||
903 | return -EINVAL; | ||
904 | } | ||
905 | |||
906 | /* | ||
907 | * Translates old vtx IOCTLs to new ones | ||
908 | * | ||
909 | * This keeps new kernel versions compatible with old userspace programs. | ||
910 | */ | ||
911 | static inline unsigned int vtx_fix_command(unsigned int cmd) | ||
912 | { | ||
913 | switch (cmd) { | ||
914 | case VTXIOCGETINFO_OLD: | ||
915 | cmd = VTXIOCGETINFO; | ||
916 | break; | ||
917 | case VTXIOCCLRPAGE_OLD: | ||
918 | cmd = VTXIOCCLRPAGE; | ||
919 | break; | ||
920 | case VTXIOCCLRFOUND_OLD: | ||
921 | cmd = VTXIOCCLRFOUND; | ||
922 | break; | ||
923 | case VTXIOCPAGEREQ_OLD: | ||
924 | cmd = VTXIOCPAGEREQ; | ||
925 | break; | ||
926 | case VTXIOCGETSTAT_OLD: | ||
927 | cmd = VTXIOCGETSTAT; | ||
928 | break; | ||
929 | case VTXIOCGETPAGE_OLD: | ||
930 | cmd = VTXIOCGETPAGE; | ||
931 | break; | ||
932 | case VTXIOCSTOPDAU_OLD: | ||
933 | cmd = VTXIOCSTOPDAU; | ||
934 | break; | ||
935 | case VTXIOCPUTPAGE_OLD: | ||
936 | cmd = VTXIOCPUTPAGE; | ||
937 | break; | ||
938 | case VTXIOCSETDISP_OLD: | ||
939 | cmd = VTXIOCSETDISP; | ||
940 | break; | ||
941 | case VTXIOCPUTSTAT_OLD: | ||
942 | cmd = VTXIOCPUTSTAT; | ||
943 | break; | ||
944 | case VTXIOCCLRCACHE_OLD: | ||
945 | cmd = VTXIOCCLRCACHE; | ||
946 | break; | ||
947 | case VTXIOCSETVIRT_OLD: | ||
948 | cmd = VTXIOCSETVIRT; | ||
949 | break; | ||
950 | } | ||
951 | return cmd; | ||
952 | } | ||
953 | |||
954 | /* | ||
955 | * Handle the locking | ||
956 | */ | ||
957 | static long saa5246a_ioctl(struct file *file, | ||
958 | unsigned int cmd, unsigned long arg) | ||
959 | { | ||
960 | struct saa5246a_device *t = video_drvdata(file); | ||
961 | long err; | ||
962 | |||
963 | cmd = vtx_fix_command(cmd); | ||
964 | mutex_lock(&t->lock); | ||
965 | err = video_usercopy(file, cmd, arg, do_saa5246a_ioctl); | ||
966 | mutex_unlock(&t->lock); | ||
967 | return err; | ||
968 | } | ||
969 | |||
970 | static int saa5246a_open(struct file *file) | ||
971 | { | ||
972 | struct saa5246a_device *t = video_drvdata(file); | ||
973 | |||
974 | if (test_and_set_bit(0, &t->in_use)) | ||
975 | return -EBUSY; | ||
976 | |||
977 | if (i2c_senddata(t, SAA5246A_REGISTER_R0, | ||
978 | R0_SELECT_R11 | | ||
979 | R0_PLL_TIME_CONSTANT_LONG | | ||
980 | R0_ENABLE_nODD_EVEN_OUTPUT | | ||
981 | R0_ENABLE_HDR_POLL | | ||
982 | R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED | | ||
983 | R0_NO_FREE_RUN_PLL | | ||
984 | R0_NO_AUTOMATIC_FASTEXT_PROMPT, | ||
985 | |||
986 | R1_NON_INTERLACED_312_312_LINES | | ||
987 | R1_DEW | | ||
988 | R1_EXTENDED_PACKET_DISABLE | | ||
989 | R1_DAUS_ALL_ON | | ||
990 | R1_8_BITS_NO_PARITY | | ||
991 | R1_VCS_TO_SCS, | ||
992 | |||
993 | COMMAND_END) || | ||
994 | i2c_senddata(t, SAA5246A_REGISTER_R4, | ||
995 | |||
996 | /* We do not care much for the TV display but nevertheless we | ||
997 | * need the currently displayed page later because only on that | ||
998 | * page the time is updated. */ | ||
999 | R4_DISPLAY_PAGE_4, | ||
1000 | |||
1001 | COMMAND_END)) | ||
1002 | { | ||
1003 | clear_bit(0, &t->in_use); | ||
1004 | return -EIO; | ||
1005 | } | ||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | static int saa5246a_release(struct file *file) | ||
1010 | { | ||
1011 | struct saa5246a_device *t = video_drvdata(file); | ||
1012 | |||
1013 | /* Stop all acquisition circuits. */ | ||
1014 | i2c_senddata(t, SAA5246A_REGISTER_R1, | ||
1015 | |||
1016 | R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES | | ||
1017 | R1_DEW | | ||
1018 | R1_EXTENDED_PACKET_DISABLE | | ||
1019 | R1_DAUS_ALL_OFF | | ||
1020 | R1_8_BITS_NO_PARITY | | ||
1021 | R1_VCS_TO_SCS, | ||
1022 | |||
1023 | COMMAND_END); | ||
1024 | clear_bit(0, &t->in_use); | ||
1025 | return 0; | ||
1026 | } | ||
1027 | |||
1028 | static const struct v4l2_file_operations saa_fops = { | ||
1029 | .owner = THIS_MODULE, | ||
1030 | .open = saa5246a_open, | ||
1031 | .release = saa5246a_release, | ||
1032 | .ioctl = saa5246a_ioctl, | ||
1033 | }; | ||
1034 | |||
1035 | static struct video_device saa_template = | ||
1036 | { | ||
1037 | .name = "saa5246a", | ||
1038 | .fops = &saa_fops, | ||
1039 | .release = video_device_release, | ||
1040 | }; | ||
1041 | |||
1042 | static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) | ||
1043 | { | ||
1044 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1045 | |||
1046 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5246A, 0); | ||
1047 | } | ||
1048 | |||
1049 | static const struct v4l2_subdev_core_ops saa5246a_core_ops = { | ||
1050 | .g_chip_ident = saa5246a_g_chip_ident, | ||
1051 | }; | ||
1052 | |||
1053 | static const struct v4l2_subdev_ops saa5246a_ops = { | ||
1054 | .core = &saa5246a_core_ops, | ||
1055 | }; | ||
1056 | |||
1057 | |||
1058 | static int saa5246a_probe(struct i2c_client *client, | ||
1059 | const struct i2c_device_id *id) | ||
1060 | { | ||
1061 | int pgbuf; | ||
1062 | int err; | ||
1063 | struct saa5246a_device *t; | ||
1064 | struct v4l2_subdev *sd; | ||
1065 | |||
1066 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
1067 | client->addr << 1, client->adapter->name); | ||
1068 | v4l_info(client, "VideoText version %d.%d\n", | ||
1069 | MAJOR_VERSION, MINOR_VERSION); | ||
1070 | t = kzalloc(sizeof(*t), GFP_KERNEL); | ||
1071 | if (t == NULL) | ||
1072 | return -ENOMEM; | ||
1073 | sd = &t->sd; | ||
1074 | v4l2_i2c_subdev_init(sd, client, &saa5246a_ops); | ||
1075 | mutex_init(&t->lock); | ||
1076 | |||
1077 | /* Now create a video4linux device */ | ||
1078 | t->vdev = video_device_alloc(); | ||
1079 | if (t->vdev == NULL) { | ||
1080 | kfree(t); | ||
1081 | return -ENOMEM; | ||
1082 | } | ||
1083 | memcpy(t->vdev, &saa_template, sizeof(*t->vdev)); | ||
1084 | |||
1085 | for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { | ||
1086 | memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); | ||
1087 | t->is_searching[pgbuf] = false; | ||
1088 | } | ||
1089 | video_set_drvdata(t->vdev, t); | ||
1090 | |||
1091 | /* Register it */ | ||
1092 | err = video_register_device(t->vdev, VFL_TYPE_VTX, -1); | ||
1093 | if (err < 0) { | ||
1094 | video_device_release(t->vdev); | ||
1095 | kfree(t); | ||
1096 | return err; | ||
1097 | } | ||
1098 | return 0; | ||
1099 | } | ||
1100 | |||
1101 | static int saa5246a_remove(struct i2c_client *client) | ||
1102 | { | ||
1103 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
1104 | struct saa5246a_device *t = to_dev(sd); | ||
1105 | |||
1106 | video_unregister_device(t->vdev); | ||
1107 | v4l2_device_unregister_subdev(sd); | ||
1108 | kfree(t); | ||
1109 | return 0; | ||
1110 | } | ||
1111 | |||
1112 | static const struct i2c_device_id saa5246a_id[] = { | ||
1113 | { "saa5246a", 0 }, | ||
1114 | { } | ||
1115 | }; | ||
1116 | MODULE_DEVICE_TABLE(i2c, saa5246a_id); | ||
1117 | |||
1118 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
1119 | .name = "saa5246a", | ||
1120 | .probe = saa5246a_probe, | ||
1121 | .remove = saa5246a_remove, | ||
1122 | .id_table = saa5246a_id, | ||
1123 | }; | ||
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c deleted file mode 100644 index 31ff27df4cb..00000000000 --- a/drivers/media/video/saa5249.c +++ /dev/null | |||
@@ -1,650 +0,0 @@ | |||
1 | /* | ||
2 | * Modified in order to keep it compatible both with new and old videotext IOCTLs by | ||
3 | * Michael Geng <linux@MichaelGeng.de> | ||
4 | * | ||
5 | * Cleaned up to use existing videodev interface and allow the idea | ||
6 | * of multiple teletext decoders on the video4linux iface. Changed i2c | ||
7 | * to cover addressing clashes on device busses. It's also rebuilt so | ||
8 | * you can add arbitary multiple teletext devices to Linux video4linux | ||
9 | * now (well 32 anyway). | ||
10 | * | ||
11 | * Alan Cox <alan@lxorguk.ukuu.org.uk> | ||
12 | * | ||
13 | * The original driver was heavily modified to match the i2c interface | ||
14 | * It was truncated to use the WinTV boards, too. | ||
15 | * | ||
16 | * Copyright (c) 1998 Richard Guenther <richard.guenther@student.uni-tuebingen.de> | ||
17 | * | ||
18 | * Derived From | ||
19 | * | ||
20 | * vtx.c: | ||
21 | * This is a loadable character-device-driver for videotext-interfaces | ||
22 | * (aka teletext). Please check the Makefile/README for a list of supported | ||
23 | * interfaces. | ||
24 | * | ||
25 | * Copyright (c) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de> | ||
26 | * | ||
27 | * | ||
28 | * This program is free software; you can redistribute it and/or modify | ||
29 | * it under the terms of the GNU General Public License as published by | ||
30 | * the Free Software Foundation; either version 2 of the License, or | ||
31 | * (at your option) any later version. | ||
32 | * | ||
33 | * This program is distributed in the hope that it will be useful, | ||
34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
36 | * GNU General Public License for more details. | ||
37 | * | ||
38 | * You should have received a copy of the GNU General Public License | ||
39 | * along with this program; if not, write to the Free Software | ||
40 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
41 | * USA. | ||
42 | */ | ||
43 | |||
44 | #include <linux/module.h> | ||
45 | #include <linux/kernel.h> | ||
46 | #include <linux/mm.h> | ||
47 | #include <linux/init.h> | ||
48 | #include <linux/i2c.h> | ||
49 | #include <linux/mutex.h> | ||
50 | #include <linux/delay.h> | ||
51 | #include <linux/videotext.h> | ||
52 | #include <linux/videodev2.h> | ||
53 | #include <linux/slab.h> | ||
54 | #include <media/v4l2-device.h> | ||
55 | #include <media/v4l2-chip-ident.h> | ||
56 | #include <media/v4l2-ioctl.h> | ||
57 | #include <media/v4l2-i2c-drv.h> | ||
58 | |||
59 | MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); | ||
60 | MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver"); | ||
61 | MODULE_LICENSE("GPL"); | ||
62 | |||
63 | |||
64 | #define VTX_VER_MAJ 1 | ||
65 | #define VTX_VER_MIN 8 | ||
66 | |||
67 | |||
68 | #define NUM_DAUS 4 | ||
69 | #define NUM_BUFS 8 | ||
70 | |||
71 | static const int disp_modes[8][3] = | ||
72 | { | ||
73 | { 0x46, 0x03, 0x03 }, /* DISPOFF */ | ||
74 | { 0x46, 0xcc, 0xcc }, /* DISPNORM */ | ||
75 | { 0x44, 0x0f, 0x0f }, /* DISPTRANS */ | ||
76 | { 0x46, 0xcc, 0x46 }, /* DISPINS */ | ||
77 | { 0x44, 0x03, 0x03 }, /* DISPOFF, interlaced */ | ||
78 | { 0x44, 0xcc, 0xcc }, /* DISPNORM, interlaced */ | ||
79 | { 0x44, 0x0f, 0x0f }, /* DISPTRANS, interlaced */ | ||
80 | { 0x44, 0xcc, 0x46 } /* DISPINS, interlaced */ | ||
81 | }; | ||
82 | |||
83 | |||
84 | |||
85 | #define PAGE_WAIT msecs_to_jiffies(300) /* Time between requesting page and */ | ||
86 | /* checking status bits */ | ||
87 | #define PGBUF_EXPIRE msecs_to_jiffies(15000) /* Time to wait before retransmitting */ | ||
88 | /* page regardless of infobits */ | ||
89 | typedef struct { | ||
90 | u8 pgbuf[VTX_VIRTUALSIZE]; /* Page-buffer */ | ||
91 | u8 laststat[10]; /* Last value of infobits for DAU */ | ||
92 | u8 sregs[7]; /* Page-request registers */ | ||
93 | unsigned long expire; /* Time when page will be expired */ | ||
94 | unsigned clrfound : 1; /* VTXIOCCLRFOUND has been called */ | ||
95 | unsigned stopped : 1; /* VTXIOCSTOPDAU has been called */ | ||
96 | } vdau_t; | ||
97 | |||
98 | struct saa5249_device | ||
99 | { | ||
100 | struct v4l2_subdev sd; | ||
101 | struct video_device *vdev; | ||
102 | vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */ | ||
103 | /* real DAU, so we have to simulate some more) */ | ||
104 | int vtx_use_count; | ||
105 | int is_searching[NUM_DAUS]; | ||
106 | int disp_mode; | ||
107 | int virtual_mode; | ||
108 | unsigned long in_use; | ||
109 | struct mutex lock; | ||
110 | }; | ||
111 | |||
112 | static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd) | ||
113 | { | ||
114 | return container_of(sd, struct saa5249_device, sd); | ||
115 | } | ||
116 | |||
117 | |||
118 | #define CCTWR 34 /* I²C write/read-address of vtx-chip */ | ||
119 | #define CCTRD 35 | ||
120 | #define NOACK_REPEAT 10 /* Retry access this many times on failure */ | ||
121 | #define CLEAR_DELAY msecs_to_jiffies(50) /* Time required to clear a page */ | ||
122 | #define READY_TIMEOUT msecs_to_jiffies(30) /* Time to wait for ready signal of I2C-bus interface */ | ||
123 | #define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */ | ||
124 | #define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */ | ||
125 | |||
126 | #define VTX_DEV_MINOR 0 | ||
127 | |||
128 | static struct video_device saa_template; /* Declared near bottom */ | ||
129 | |||
130 | /* | ||
131 | * Wait the given number of jiffies (10ms). This calls the scheduler, so the actual | ||
132 | * delay may be longer. | ||
133 | */ | ||
134 | |||
135 | static void jdelay(unsigned long delay) | ||
136 | { | ||
137 | sigset_t oldblocked = current->blocked; | ||
138 | |||
139 | spin_lock_irq(¤t->sighand->siglock); | ||
140 | sigfillset(¤t->blocked); | ||
141 | recalc_sigpending(); | ||
142 | spin_unlock_irq(¤t->sighand->siglock); | ||
143 | msleep_interruptible(jiffies_to_msecs(delay)); | ||
144 | |||
145 | spin_lock_irq(¤t->sighand->siglock); | ||
146 | current->blocked = oldblocked; | ||
147 | recalc_sigpending(); | ||
148 | spin_unlock_irq(¤t->sighand->siglock); | ||
149 | } | ||
150 | |||
151 | |||
152 | /* | ||
153 | * I2C interfaces | ||
154 | */ | ||
155 | |||
156 | static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) | ||
157 | { | ||
158 | struct i2c_client *client = v4l2_get_subdevdata(&t->sd); | ||
159 | char buf[64]; | ||
160 | |||
161 | buf[0] = reg; | ||
162 | memcpy(buf+1, data, count); | ||
163 | |||
164 | if (i2c_master_send(client, buf, count + 1) == count + 1) | ||
165 | return 0; | ||
166 | return -1; | ||
167 | } | ||
168 | |||
169 | static int i2c_senddata(struct saa5249_device *t, ...) | ||
170 | { | ||
171 | unsigned char buf[64]; | ||
172 | int v; | ||
173 | int ct = 0; | ||
174 | va_list argp; | ||
175 | va_start(argp,t); | ||
176 | |||
177 | while ((v = va_arg(argp, int)) != -1) | ||
178 | buf[ct++] = v; | ||
179 | |||
180 | va_end(argp); | ||
181 | return i2c_sendbuf(t, buf[0], ct-1, buf+1); | ||
182 | } | ||
183 | |||
184 | /* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop | ||
185 | * handshaking is done by this routine, ack will be sent after the last byte to inhibit further | ||
186 | * sending of data. If uaccess is 'true', data is written to user-space with put_user. | ||
187 | * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise | ||
188 | */ | ||
189 | |||
190 | static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) | ||
191 | { | ||
192 | struct i2c_client *client = v4l2_get_subdevdata(&t->sd); | ||
193 | |||
194 | if (i2c_master_recv(client, buf, count) != count) | ||
195 | return -1; | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | |||
200 | /* | ||
201 | * Standard character-device-driver functions | ||
202 | */ | ||
203 | |||
204 | static long do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg) | ||
205 | { | ||
206 | static int virtual_mode = false; | ||
207 | struct saa5249_device *t = video_drvdata(file); | ||
208 | |||
209 | switch (cmd) { | ||
210 | case VTXIOCGETINFO: | ||
211 | { | ||
212 | vtx_info_t *info = arg; | ||
213 | info->version_major = VTX_VER_MAJ; | ||
214 | info->version_minor = VTX_VER_MIN; | ||
215 | info->numpages = NUM_DAUS; | ||
216 | /*info->cct_type = CCT_TYPE;*/ | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | case VTXIOCCLRPAGE: | ||
221 | { | ||
222 | vtx_pagereq_t *req = arg; | ||
223 | |||
224 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
225 | return -EINVAL; | ||
226 | memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); | ||
227 | t->vdau[req->pgbuf].clrfound = true; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | case VTXIOCCLRFOUND: | ||
232 | { | ||
233 | vtx_pagereq_t *req = arg; | ||
234 | |||
235 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
236 | return -EINVAL; | ||
237 | t->vdau[req->pgbuf].clrfound = true; | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | case VTXIOCPAGEREQ: | ||
242 | { | ||
243 | vtx_pagereq_t *req = arg; | ||
244 | if (!(req->pagemask & PGMASK_PAGE)) | ||
245 | req->page = 0; | ||
246 | if (!(req->pagemask & PGMASK_HOUR)) | ||
247 | req->hour = 0; | ||
248 | if (!(req->pagemask & PGMASK_MINUTE)) | ||
249 | req->minute = 0; | ||
250 | if (req->page < 0 || req->page > 0x8ff) /* 7FF ?? */ | ||
251 | return -EINVAL; | ||
252 | req->page &= 0x7ff; | ||
253 | if (req->hour < 0 || req->hour > 0x3f || req->minute < 0 || req->minute > 0x7f || | ||
254 | req->pagemask < 0 || req->pagemask >= PGMASK_MAX || req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
255 | return -EINVAL; | ||
256 | t->vdau[req->pgbuf].sregs[0] = (req->pagemask & PG_HUND ? 0x10 : 0) | (req->page / 0x100); | ||
257 | t->vdau[req->pgbuf].sregs[1] = (req->pagemask & PG_TEN ? 0x10 : 0) | ((req->page / 0x10) & 0xf); | ||
258 | t->vdau[req->pgbuf].sregs[2] = (req->pagemask & PG_UNIT ? 0x10 : 0) | (req->page & 0xf); | ||
259 | t->vdau[req->pgbuf].sregs[3] = (req->pagemask & HR_TEN ? 0x10 : 0) | (req->hour / 0x10); | ||
260 | t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf); | ||
261 | t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10); | ||
262 | t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf); | ||
263 | t->vdau[req->pgbuf].stopped = false; | ||
264 | t->vdau[req->pgbuf].clrfound = true; | ||
265 | t->is_searching[req->pgbuf] = true; | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | case VTXIOCGETSTAT: | ||
270 | { | ||
271 | vtx_pagereq_t *req = arg; | ||
272 | u8 infobits[10]; | ||
273 | vtx_pageinfo_t info; | ||
274 | int a; | ||
275 | |||
276 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
277 | return -EINVAL; | ||
278 | if (!t->vdau[req->pgbuf].stopped) { | ||
279 | if (i2c_senddata(t, 2, 0, -1) || | ||
280 | i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req->pgbuf].sregs) || | ||
281 | i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) || | ||
282 | i2c_senddata(t, 2, 0, t->vdau[req->pgbuf].sregs[0] | 8, -1) || | ||
283 | i2c_senddata(t, 8, 0, 25, 0, -1)) | ||
284 | return -EIO; | ||
285 | jdelay(PAGE_WAIT); | ||
286 | if (i2c_getdata(t, 10, infobits)) | ||
287 | return -EIO; | ||
288 | |||
289 | if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */ | ||
290 | (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) || | ||
291 | time_after_eq(jiffies, t->vdau[req->pgbuf].expire))) | ||
292 | { /* check if new page arrived */ | ||
293 | if (i2c_senddata(t, 8, 0, 0, 0, -1) || | ||
294 | i2c_getdata(t, VTX_PAGESIZE, t->vdau[req->pgbuf].pgbuf)) | ||
295 | return -EIO; | ||
296 | t->vdau[req->pgbuf].expire = jiffies + PGBUF_EXPIRE; | ||
297 | memset(t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE); | ||
298 | if (t->virtual_mode) { | ||
299 | /* Packet X/24 */ | ||
300 | if (i2c_senddata(t, 8, 0, 0x20, 0, -1) || | ||
301 | i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40)) | ||
302 | return -EIO; | ||
303 | /* Packet X/27/0 */ | ||
304 | if (i2c_senddata(t, 8, 0, 0x21, 0, -1) || | ||
305 | i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40)) | ||
306 | return -EIO; | ||
307 | /* Packet 8/30/0...8/30/15 | ||
308 | * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30, | ||
309 | * so we should undo this here. | ||
310 | */ | ||
311 | if (i2c_senddata(t, 8, 0, 0x22, 0, -1) || | ||
312 | i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40)) | ||
313 | return -EIO; | ||
314 | } | ||
315 | t->vdau[req->pgbuf].clrfound = false; | ||
316 | memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits)); | ||
317 | } else { | ||
318 | memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)); | ||
319 | } | ||
320 | } else { | ||
321 | memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)); | ||
322 | } | ||
323 | |||
324 | info.pagenum = ((infobits[8] << 8) & 0x700) | ((infobits[1] << 4) & 0xf0) | (infobits[0] & 0x0f); | ||
325 | if (info.pagenum < 0x100) | ||
326 | info.pagenum += 0x800; | ||
327 | info.hour = ((infobits[5] << 4) & 0x30) | (infobits[4] & 0x0f); | ||
328 | info.minute = ((infobits[3] << 4) & 0x70) | (infobits[2] & 0x0f); | ||
329 | info.charset = ((infobits[7] >> 1) & 7); | ||
330 | info.delete = !!(infobits[3] & 8); | ||
331 | info.headline = !!(infobits[5] & 4); | ||
332 | info.subtitle = !!(infobits[5] & 8); | ||
333 | info.supp_header = !!(infobits[6] & 1); | ||
334 | info.update = !!(infobits[6] & 2); | ||
335 | info.inter_seq = !!(infobits[6] & 4); | ||
336 | info.dis_disp = !!(infobits[6] & 8); | ||
337 | info.serial = !!(infobits[7] & 1); | ||
338 | info.notfound = !!(infobits[8] & 0x10); | ||
339 | info.pblf = !!(infobits[9] & 0x20); | ||
340 | info.hamming = 0; | ||
341 | for (a = 0; a <= 7; a++) { | ||
342 | if (infobits[a] & 0xf0) { | ||
343 | info.hamming = 1; | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | if (t->vdau[req->pgbuf].clrfound) | ||
348 | info.notfound = 1; | ||
349 | if (copy_to_user(req->buffer, &info, sizeof(vtx_pageinfo_t))) | ||
350 | return -EFAULT; | ||
351 | if (!info.hamming && !info.notfound) | ||
352 | t->is_searching[req->pgbuf] = false; | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | case VTXIOCGETPAGE: | ||
357 | { | ||
358 | vtx_pagereq_t *req = arg; | ||
359 | int start, end; | ||
360 | |||
361 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || req->start < 0 || | ||
362 | req->start > req->end || req->end >= (virtual_mode ? VTX_VIRTUALSIZE : VTX_PAGESIZE)) | ||
363 | return -EINVAL; | ||
364 | if (copy_to_user(req->buffer, &t->vdau[req->pgbuf].pgbuf[req->start], req->end - req->start + 1)) | ||
365 | return -EFAULT; | ||
366 | |||
367 | /* | ||
368 | * Always read the time directly from SAA5249 | ||
369 | */ | ||
370 | |||
371 | if (req->start <= 39 && req->end >= 32) { | ||
372 | int len; | ||
373 | char buf[16]; | ||
374 | start = max(req->start, 32); | ||
375 | end = min(req->end, 39); | ||
376 | len = end - start + 1; | ||
377 | if (i2c_senddata(t, 8, 0, 0, start, -1) || | ||
378 | i2c_getdata(t, len, buf)) | ||
379 | return -EIO; | ||
380 | if (copy_to_user(req->buffer + start - req->start, buf, len)) | ||
381 | return -EFAULT; | ||
382 | } | ||
383 | /* Insert the current header if DAU is still searching for a page */ | ||
384 | if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf]) { | ||
385 | char buf[32]; | ||
386 | int len; | ||
387 | |||
388 | start = max(req->start, 7); | ||
389 | end = min(req->end, 31); | ||
390 | len = end - start + 1; | ||
391 | if (i2c_senddata(t, 8, 0, 0, start, -1) || | ||
392 | i2c_getdata(t, len, buf)) | ||
393 | return -EIO; | ||
394 | if (copy_to_user(req->buffer + start - req->start, buf, len)) | ||
395 | return -EFAULT; | ||
396 | } | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | case VTXIOCSTOPDAU: | ||
401 | { | ||
402 | vtx_pagereq_t *req = arg; | ||
403 | |||
404 | if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) | ||
405 | return -EINVAL; | ||
406 | t->vdau[req->pgbuf].stopped = true; | ||
407 | t->is_searching[req->pgbuf] = false; | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | case VTXIOCPUTPAGE: | ||
412 | case VTXIOCSETDISP: | ||
413 | case VTXIOCPUTSTAT: | ||
414 | return 0; | ||
415 | |||
416 | case VTXIOCCLRCACHE: | ||
417 | { | ||
418 | if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11, | ||
419 | ' ', ' ', ' ', ' ', ' ', ' ', | ||
420 | ' ', ' ', ' ', ' ', ' ', ' ', | ||
421 | ' ', ' ', ' ', ' ', ' ', ' ', | ||
422 | ' ', ' ', ' ', ' ', ' ', ' ', | ||
423 | -1)) | ||
424 | return -EIO; | ||
425 | if (i2c_senddata(t, 3, 0x20, -1)) | ||
426 | return -EIO; | ||
427 | jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */ | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | case VTXIOCSETVIRT: | ||
432 | { | ||
433 | /* The SAA5249 has virtual-row reception turned on always */ | ||
434 | t->virtual_mode = (int)(long)arg; | ||
435 | return 0; | ||
436 | } | ||
437 | } | ||
438 | return -EINVAL; | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Translates old vtx IOCTLs to new ones | ||
443 | * | ||
444 | * This keeps new kernel versions compatible with old userspace programs. | ||
445 | */ | ||
446 | static inline unsigned int vtx_fix_command(unsigned int cmd) | ||
447 | { | ||
448 | switch (cmd) { | ||
449 | case VTXIOCGETINFO_OLD: | ||
450 | cmd = VTXIOCGETINFO; | ||
451 | break; | ||
452 | case VTXIOCCLRPAGE_OLD: | ||
453 | cmd = VTXIOCCLRPAGE; | ||
454 | break; | ||
455 | case VTXIOCCLRFOUND_OLD: | ||
456 | cmd = VTXIOCCLRFOUND; | ||
457 | break; | ||
458 | case VTXIOCPAGEREQ_OLD: | ||
459 | cmd = VTXIOCPAGEREQ; | ||
460 | break; | ||
461 | case VTXIOCGETSTAT_OLD: | ||
462 | cmd = VTXIOCGETSTAT; | ||
463 | break; | ||
464 | case VTXIOCGETPAGE_OLD: | ||
465 | cmd = VTXIOCGETPAGE; | ||
466 | break; | ||
467 | case VTXIOCSTOPDAU_OLD: | ||
468 | cmd = VTXIOCSTOPDAU; | ||
469 | break; | ||
470 | case VTXIOCPUTPAGE_OLD: | ||
471 | cmd = VTXIOCPUTPAGE; | ||
472 | break; | ||
473 | case VTXIOCSETDISP_OLD: | ||
474 | cmd = VTXIOCSETDISP; | ||
475 | break; | ||
476 | case VTXIOCPUTSTAT_OLD: | ||
477 | cmd = VTXIOCPUTSTAT; | ||
478 | break; | ||
479 | case VTXIOCCLRCACHE_OLD: | ||
480 | cmd = VTXIOCCLRCACHE; | ||
481 | break; | ||
482 | case VTXIOCSETVIRT_OLD: | ||
483 | cmd = VTXIOCSETVIRT; | ||
484 | break; | ||
485 | } | ||
486 | return cmd; | ||
487 | } | ||
488 | |||
489 | /* | ||
490 | * Handle the locking | ||
491 | */ | ||
492 | |||
493 | static long saa5249_ioctl(struct file *file, | ||
494 | unsigned int cmd, unsigned long arg) | ||
495 | { | ||
496 | struct saa5249_device *t = video_drvdata(file); | ||
497 | long err; | ||
498 | |||
499 | cmd = vtx_fix_command(cmd); | ||
500 | mutex_lock(&t->lock); | ||
501 | err = video_usercopy(file, cmd, arg, do_saa5249_ioctl); | ||
502 | mutex_unlock(&t->lock); | ||
503 | return err; | ||
504 | } | ||
505 | |||
506 | static int saa5249_open(struct file *file) | ||
507 | { | ||
508 | struct saa5249_device *t = video_drvdata(file); | ||
509 | int pgbuf; | ||
510 | |||
511 | if (test_and_set_bit(0, &t->in_use)) | ||
512 | return -EBUSY; | ||
513 | |||
514 | if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */ | ||
515 | /* Turn off parity checks (we do this ourselves) */ | ||
516 | i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) || | ||
517 | /* Display TV-picture, no virtual rows */ | ||
518 | i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) | ||
519 | /* Set display to page 4 */ | ||
520 | { | ||
521 | clear_bit(0, &t->in_use); | ||
522 | return -EIO; | ||
523 | } | ||
524 | |||
525 | for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { | ||
526 | memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); | ||
527 | memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); | ||
528 | memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); | ||
529 | t->vdau[pgbuf].expire = 0; | ||
530 | t->vdau[pgbuf].clrfound = true; | ||
531 | t->vdau[pgbuf].stopped = true; | ||
532 | t->is_searching[pgbuf] = false; | ||
533 | } | ||
534 | t->virtual_mode = false; | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | |||
539 | |||
540 | static int saa5249_release(struct file *file) | ||
541 | { | ||
542 | struct saa5249_device *t = video_drvdata(file); | ||
543 | |||
544 | i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */ | ||
545 | i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */ | ||
546 | clear_bit(0, &t->in_use); | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static const struct v4l2_file_operations saa_fops = { | ||
551 | .owner = THIS_MODULE, | ||
552 | .open = saa5249_open, | ||
553 | .release = saa5249_release, | ||
554 | .ioctl = saa5249_ioctl, | ||
555 | }; | ||
556 | |||
557 | static struct video_device saa_template = | ||
558 | { | ||
559 | .name = "saa5249", | ||
560 | .fops = &saa_fops, | ||
561 | .release = video_device_release, | ||
562 | }; | ||
563 | |||
564 | static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) | ||
565 | { | ||
566 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
567 | |||
568 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0); | ||
569 | } | ||
570 | |||
571 | static const struct v4l2_subdev_core_ops saa5249_core_ops = { | ||
572 | .g_chip_ident = saa5249_g_chip_ident, | ||
573 | }; | ||
574 | |||
575 | static const struct v4l2_subdev_ops saa5249_ops = { | ||
576 | .core = &saa5249_core_ops, | ||
577 | }; | ||
578 | |||
579 | static int saa5249_probe(struct i2c_client *client, | ||
580 | const struct i2c_device_id *id) | ||
581 | { | ||
582 | int pgbuf; | ||
583 | int err; | ||
584 | struct saa5249_device *t; | ||
585 | struct v4l2_subdev *sd; | ||
586 | |||
587 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
588 | client->addr << 1, client->adapter->name); | ||
589 | v4l_info(client, "VideoText version %d.%d\n", | ||
590 | VTX_VER_MAJ, VTX_VER_MIN); | ||
591 | t = kzalloc(sizeof(*t), GFP_KERNEL); | ||
592 | if (t == NULL) | ||
593 | return -ENOMEM; | ||
594 | sd = &t->sd; | ||
595 | v4l2_i2c_subdev_init(sd, client, &saa5249_ops); | ||
596 | mutex_init(&t->lock); | ||
597 | |||
598 | /* Now create a video4linux device */ | ||
599 | t->vdev = video_device_alloc(); | ||
600 | if (t->vdev == NULL) { | ||
601 | kfree(t); | ||
602 | kfree(client); | ||
603 | return -ENOMEM; | ||
604 | } | ||
605 | memcpy(t->vdev, &saa_template, sizeof(*t->vdev)); | ||
606 | |||
607 | for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { | ||
608 | memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); | ||
609 | memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); | ||
610 | memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); | ||
611 | t->vdau[pgbuf].expire = 0; | ||
612 | t->vdau[pgbuf].clrfound = true; | ||
613 | t->vdau[pgbuf].stopped = true; | ||
614 | t->is_searching[pgbuf] = false; | ||
615 | } | ||
616 | video_set_drvdata(t->vdev, t); | ||
617 | |||
618 | /* Register it */ | ||
619 | err = video_register_device(t->vdev, VFL_TYPE_VTX, -1); | ||
620 | if (err < 0) { | ||
621 | video_device_release(t->vdev); | ||
622 | kfree(t); | ||
623 | return err; | ||
624 | } | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static int saa5249_remove(struct i2c_client *client) | ||
629 | { | ||
630 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
631 | struct saa5249_device *t = to_dev(sd); | ||
632 | |||
633 | video_unregister_device(t->vdev); | ||
634 | v4l2_device_unregister_subdev(sd); | ||
635 | kfree(t); | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | static const struct i2c_device_id saa5249_id[] = { | ||
640 | { "saa5249", 0 }, | ||
641 | { } | ||
642 | }; | ||
643 | MODULE_DEVICE_TABLE(i2c, saa5249_id); | ||
644 | |||
645 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
646 | .name = "saa5249", | ||
647 | .probe = saa5249_probe, | ||
648 | .remove = saa5249_remove, | ||
649 | .id_table = saa5249_id, | ||
650 | }; | ||
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index c3e96f07097..984c0feb2a4 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <media/rds.h> | 34 | #include <media/rds.h> |
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 36 | #include <media/v4l2-chip-ident.h> |
37 | #include <media/v4l2-i2c-drv.h> | ||
38 | 37 | ||
39 | 38 | ||
40 | /* insmod options */ | 39 | /* insmod options */ |
@@ -430,7 +429,7 @@ static int saa6588_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
430 | { | 429 | { |
431 | struct saa6588 *s = to_saa6588(sd); | 430 | struct saa6588 *s = to_saa6588(sd); |
432 | 431 | ||
433 | vt->capability |= V4L2_TUNER_CAP_RDS; | 432 | vt->capability |= V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; |
434 | if (s->sync) | 433 | if (s->sync) |
435 | vt->rxsubchans |= V4L2_TUNER_SUB_RDS; | 434 | vt->rxsubchans |= V4L2_TUNER_SUB_RDS; |
436 | return 0; | 435 | return 0; |
@@ -530,9 +529,25 @@ static const struct i2c_device_id saa6588_id[] = { | |||
530 | }; | 529 | }; |
531 | MODULE_DEVICE_TABLE(i2c, saa6588_id); | 530 | MODULE_DEVICE_TABLE(i2c, saa6588_id); |
532 | 531 | ||
533 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 532 | static struct i2c_driver saa6588_driver = { |
534 | .name = "saa6588", | 533 | .driver = { |
535 | .probe = saa6588_probe, | 534 | .owner = THIS_MODULE, |
536 | .remove = saa6588_remove, | 535 | .name = "saa6588", |
537 | .id_table = saa6588_id, | 536 | }, |
537 | .probe = saa6588_probe, | ||
538 | .remove = saa6588_remove, | ||
539 | .id_table = saa6588_id, | ||
538 | }; | 540 | }; |
541 | |||
542 | static __init int init_saa6588(void) | ||
543 | { | ||
544 | return i2c_add_driver(&saa6588_driver); | ||
545 | } | ||
546 | |||
547 | static __exit void exit_saa6588(void) | ||
548 | { | ||
549 | i2c_del_driver(&saa6588_driver); | ||
550 | } | ||
551 | |||
552 | module_init(init_saa6588); | ||
553 | module_exit(exit_saa6588); | ||
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 3bca744e43a..7913f93979b 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/videodev2.h> | 36 | #include <linux/videodev2.h> |
37 | #include <media/v4l2-device.h> | 37 | #include <media/v4l2-device.h> |
38 | #include <media/v4l2-chip-ident.h> | 38 | #include <media/v4l2-chip-ident.h> |
39 | #include <media/v4l2-i2c-drv.h> | ||
40 | 39 | ||
41 | MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); | 40 | MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); |
42 | MODULE_AUTHOR("Pauline Middelink"); | 41 | MODULE_AUTHOR("Pauline Middelink"); |
@@ -505,9 +504,25 @@ static const struct i2c_device_id saa7110_id[] = { | |||
505 | }; | 504 | }; |
506 | MODULE_DEVICE_TABLE(i2c, saa7110_id); | 505 | MODULE_DEVICE_TABLE(i2c, saa7110_id); |
507 | 506 | ||
508 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 507 | static struct i2c_driver saa7110_driver = { |
509 | .name = "saa7110", | 508 | .driver = { |
510 | .probe = saa7110_probe, | 509 | .owner = THIS_MODULE, |
511 | .remove = saa7110_remove, | 510 | .name = "saa7110", |
512 | .id_table = saa7110_id, | 511 | }, |
512 | .probe = saa7110_probe, | ||
513 | .remove = saa7110_remove, | ||
514 | .id_table = saa7110_id, | ||
513 | }; | 515 | }; |
516 | |||
517 | static __init int init_saa7110(void) | ||
518 | { | ||
519 | return i2c_add_driver(&saa7110_driver); | ||
520 | } | ||
521 | |||
522 | static __exit void exit_saa7110(void) | ||
523 | { | ||
524 | i2c_del_driver(&saa7110_driver); | ||
525 | } | ||
526 | |||
527 | module_init(init_saa7110); | ||
528 | module_exit(exit_saa7110); | ||
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index ee963f4d01b..301c62b88ca 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <media/v4l2-device.h> | 47 | #include <media/v4l2-device.h> |
48 | #include <media/v4l2-ctrls.h> | 48 | #include <media/v4l2-ctrls.h> |
49 | #include <media/v4l2-chip-ident.h> | 49 | #include <media/v4l2-chip-ident.h> |
50 | #include <media/v4l2-i2c-drv.h> | ||
51 | #include <media/saa7115.h> | 50 | #include <media/saa7115.h> |
52 | #include <asm/div64.h> | 51 | #include <asm/div64.h> |
53 | 52 | ||
@@ -1676,7 +1675,7 @@ static int saa711x_remove(struct i2c_client *client) | |||
1676 | return 0; | 1675 | return 0; |
1677 | } | 1676 | } |
1678 | 1677 | ||
1679 | static const struct i2c_device_id saa7115_id[] = { | 1678 | static const struct i2c_device_id saa711x_id[] = { |
1680 | { "saa7115_auto", 1 }, /* autodetect */ | 1679 | { "saa7115_auto", 1 }, /* autodetect */ |
1681 | { "saa7111", 0 }, | 1680 | { "saa7111", 0 }, |
1682 | { "saa7113", 0 }, | 1681 | { "saa7113", 0 }, |
@@ -1685,11 +1684,27 @@ static const struct i2c_device_id saa7115_id[] = { | |||
1685 | { "saa7118", 0 }, | 1684 | { "saa7118", 0 }, |
1686 | { } | 1685 | { } |
1687 | }; | 1686 | }; |
1688 | MODULE_DEVICE_TABLE(i2c, saa7115_id); | 1687 | MODULE_DEVICE_TABLE(i2c, saa711x_id); |
1689 | 1688 | ||
1690 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 1689 | static struct i2c_driver saa711x_driver = { |
1691 | .name = "saa7115", | 1690 | .driver = { |
1692 | .probe = saa711x_probe, | 1691 | .owner = THIS_MODULE, |
1693 | .remove = saa711x_remove, | 1692 | .name = "saa7115", |
1694 | .id_table = saa7115_id, | 1693 | }, |
1694 | .probe = saa711x_probe, | ||
1695 | .remove = saa711x_remove, | ||
1696 | .id_table = saa711x_id, | ||
1695 | }; | 1697 | }; |
1698 | |||
1699 | static __init int init_saa711x(void) | ||
1700 | { | ||
1701 | return i2c_add_driver(&saa711x_driver); | ||
1702 | } | ||
1703 | |||
1704 | static __exit void exit_saa711x(void) | ||
1705 | { | ||
1706 | i2c_del_driver(&saa711x_driver); | ||
1707 | } | ||
1708 | |||
1709 | module_init(init_saa711x); | ||
1710 | module_exit(exit_saa711x); | ||
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 79fffcf39ba..ad964616c9d 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
@@ -55,7 +55,6 @@ | |||
55 | #include <linux/videodev2.h> | 55 | #include <linux/videodev2.h> |
56 | #include <media/v4l2-device.h> | 56 | #include <media/v4l2-device.h> |
57 | #include <media/v4l2-chip-ident.h> | 57 | #include <media/v4l2-chip-ident.h> |
58 | #include <media/v4l2-i2c-drv.h> | ||
59 | #include <media/saa7127.h> | 58 | #include <media/saa7127.h> |
60 | 59 | ||
61 | static int debug; | 60 | static int debug; |
@@ -843,9 +842,25 @@ static struct i2c_device_id saa7127_id[] = { | |||
843 | }; | 842 | }; |
844 | MODULE_DEVICE_TABLE(i2c, saa7127_id); | 843 | MODULE_DEVICE_TABLE(i2c, saa7127_id); |
845 | 844 | ||
846 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 845 | static struct i2c_driver saa7127_driver = { |
847 | .name = "saa7127", | 846 | .driver = { |
848 | .probe = saa7127_probe, | 847 | .owner = THIS_MODULE, |
849 | .remove = saa7127_remove, | 848 | .name = "saa7127", |
850 | .id_table = saa7127_id, | 849 | }, |
850 | .probe = saa7127_probe, | ||
851 | .remove = saa7127_remove, | ||
852 | .id_table = saa7127_id, | ||
851 | }; | 853 | }; |
854 | |||
855 | static __init int init_saa7127(void) | ||
856 | { | ||
857 | return i2c_add_driver(&saa7127_driver); | ||
858 | } | ||
859 | |||
860 | static __exit void exit_saa7127(void) | ||
861 | { | ||
862 | i2c_del_driver(&saa7127_driver); | ||
863 | } | ||
864 | |||
865 | module_init(init_saa7127); | ||
866 | module_exit(exit_saa7127); | ||
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index fda005e0167..3fe71be41a1 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -1,8 +1,7 @@ | |||
1 | config VIDEO_SAA7134 | 1 | config VIDEO_SAA7134 |
2 | tristate "Philips SAA7134 support" | 2 | tristate "Philips SAA7134 support" |
3 | depends on VIDEO_DEV && PCI && I2C && INPUT | 3 | depends on VIDEO_DEV && PCI && I2C |
4 | select VIDEOBUF_DMA_SG | 4 | select VIDEOBUF_DMA_SG |
5 | depends on VIDEO_IR | ||
6 | select VIDEO_TUNER | 5 | select VIDEO_TUNER |
7 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
8 | select CRC32 | 7 | select CRC32 |
@@ -25,6 +24,14 @@ config VIDEO_SAA7134_ALSA | |||
25 | To compile this driver as a module, choose M here: the | 24 | To compile this driver as a module, choose M here: the |
26 | module will be called saa7134-alsa. | 25 | module will be called saa7134-alsa. |
27 | 26 | ||
27 | config VIDEO_SAA7134_RC | ||
28 | bool "Philips SAA7134 Remote Controller support" | ||
29 | depends on VIDEO_IR | ||
30 | depends on VIDEO_SAA7134 | ||
31 | default y | ||
32 | ---help--- | ||
33 | Enables Remote Controller support on saa7134 driver. | ||
34 | |||
28 | config VIDEO_SAA7134_DVB | 35 | config VIDEO_SAA7134_DVB |
29 | tristate "DVB/ATSC Support for saa7134 based TV cards" | 36 | tristate "DVB/ATSC Support for saa7134 based TV cards" |
30 | depends on VIDEO_SAA7134 && DVB_CORE | 37 | depends on VIDEO_SAA7134 && DVB_CORE |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 604158a8c23..8a5ff4d3cf1 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | 1 | ||
2 | saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ | 2 | saa7134-y := saa7134-cards.o saa7134-core.o saa7134-i2c.o |
3 | saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ | 3 | saa7134-y += saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o |
4 | saa7134-video.o saa7134-input.o | 4 | saa7134-y += saa7134-video.o |
5 | saa7134-$(CONFIG_VIDEO_SAA7134_RC) += saa7134-input.o | ||
5 | 6 | ||
6 | obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o | 7 | obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o |
7 | 8 | ||
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 40fd31ca771..f9f29cc93a8 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <media/v4l2-device.h> | 36 | #include <media/v4l2-device.h> |
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <media/v4l2-chip-ident.h> | 38 | #include <media/v4l2-chip-ident.h> |
39 | #include <media/v4l2-i2c-drv.h> | ||
40 | #include <linux/init.h> | 39 | #include <linux/init.h> |
41 | #include <linux/crc32.h> | 40 | #include <linux/crc32.h> |
42 | 41 | ||
@@ -992,13 +991,29 @@ static const struct i2c_device_id saa6752hs_id[] = { | |||
992 | }; | 991 | }; |
993 | MODULE_DEVICE_TABLE(i2c, saa6752hs_id); | 992 | MODULE_DEVICE_TABLE(i2c, saa6752hs_id); |
994 | 993 | ||
995 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 994 | static struct i2c_driver saa6752hs_driver = { |
996 | .name = "saa6752hs", | 995 | .driver = { |
997 | .probe = saa6752hs_probe, | 996 | .owner = THIS_MODULE, |
998 | .remove = saa6752hs_remove, | 997 | .name = "saa6752hs", |
999 | .id_table = saa6752hs_id, | 998 | }, |
999 | .probe = saa6752hs_probe, | ||
1000 | .remove = saa6752hs_remove, | ||
1001 | .id_table = saa6752hs_id, | ||
1000 | }; | 1002 | }; |
1001 | 1003 | ||
1004 | static __init int init_saa6752hs(void) | ||
1005 | { | ||
1006 | return i2c_add_driver(&saa6752hs_driver); | ||
1007 | } | ||
1008 | |||
1009 | static __exit void exit_saa6752hs(void) | ||
1010 | { | ||
1011 | i2c_del_driver(&saa6752hs_driver); | ||
1012 | } | ||
1013 | |||
1014 | module_init(init_saa6752hs); | ||
1015 | module_exit(exit_saa6752hs); | ||
1016 | |||
1002 | /* | 1017 | /* |
1003 | * Overrides for Emacs so that we follow Linus's tabbing style. | 1018 | * Overrides for Emacs so that we follow Linus's tabbing style. |
1004 | * --------------------------------------------------------------------------- | 1019 | * --------------------------------------------------------------------------- |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index bb8d83d8dda..10a6cbf6a79 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -7551,22 +7551,22 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
7551 | so we do not need to probe for a radio tuner device. */ | 7551 | so we do not need to probe for a radio tuner device. */ |
7552 | if (dev->radio_type != UNSET) | 7552 | if (dev->radio_type != UNSET) |
7553 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | 7553 | v4l2_i2c_new_subdev(&dev->v4l2_dev, |
7554 | &dev->i2c_adap, "tuner", "tuner", | 7554 | &dev->i2c_adap, NULL, "tuner", |
7555 | dev->radio_addr, NULL); | 7555 | dev->radio_addr, NULL); |
7556 | if (has_demod) | 7556 | if (has_demod) |
7557 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | 7557 | v4l2_i2c_new_subdev(&dev->v4l2_dev, |
7558 | &dev->i2c_adap, "tuner", "tuner", | 7558 | &dev->i2c_adap, NULL, "tuner", |
7559 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | 7559 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); |
7560 | if (dev->tuner_addr == ADDR_UNSET) { | 7560 | if (dev->tuner_addr == ADDR_UNSET) { |
7561 | enum v4l2_i2c_tuner_type type = | 7561 | enum v4l2_i2c_tuner_type type = |
7562 | has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; | 7562 | has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; |
7563 | 7563 | ||
7564 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | 7564 | v4l2_i2c_new_subdev(&dev->v4l2_dev, |
7565 | &dev->i2c_adap, "tuner", "tuner", | 7565 | &dev->i2c_adap, NULL, "tuner", |
7566 | 0, v4l2_i2c_tuner_addrs(type)); | 7566 | 0, v4l2_i2c_tuner_addrs(type)); |
7567 | } else { | 7567 | } else { |
7568 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | 7568 | v4l2_i2c_new_subdev(&dev->v4l2_dev, |
7569 | &dev->i2c_adap, "tuner", "tuner", | 7569 | &dev->i2c_adap, NULL, "tuner", |
7570 | dev->tuner_addr, NULL); | 7570 | dev->tuner_addr, NULL); |
7571 | } | 7571 | } |
7572 | } | 7572 | } |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 40bc635e8a3..764d7d219fe 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -255,7 +255,7 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) | |||
255 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 255 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
256 | BUG_ON(in_interrupt()); | 256 | BUG_ON(in_interrupt()); |
257 | 257 | ||
258 | videobuf_waiton(&buf->vb,0,0); | 258 | videobuf_waiton(q, &buf->vb, 0, 0); |
259 | videobuf_dma_unmap(q->dev, dma); | 259 | videobuf_dma_unmap(q->dev, dma); |
260 | videobuf_dma_free(dma); | 260 | videobuf_dma_free(dma); |
261 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 261 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
@@ -991,7 +991,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
991 | if (card_is_empress(dev)) { | 991 | if (card_is_empress(dev)) { |
992 | struct v4l2_subdev *sd = | 992 | struct v4l2_subdev *sd = |
993 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 993 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
994 | "saa6752hs", "saa6752hs", | 994 | NULL, "saa6752hs", |
995 | saa7134_boards[dev->board].empress_addr, NULL); | 995 | saa7134_boards[dev->board].empress_addr, NULL); |
996 | 996 | ||
997 | if (sd) | 997 | if (sd) |
@@ -1002,7 +1002,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1002 | struct v4l2_subdev *sd; | 1002 | struct v4l2_subdev *sd; |
1003 | 1003 | ||
1004 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1004 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1005 | &dev->i2c_adap, "saa6588", "saa6588", | 1005 | &dev->i2c_adap, NULL, "saa6588", |
1006 | 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr)); | 1006 | 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr)); |
1007 | if (sd) { | 1007 | if (sd) { |
1008 | printk(KERN_INFO "%s: found RDS decoder\n", dev->name); | 1008 | printk(KERN_INFO "%s: found RDS decoder\n", dev->name); |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index f26fe7661a1..beb95e21d10 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -1111,7 +1111,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1111 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1111 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1112 | V4L2_FIELD_ALTERNATE, | 1112 | V4L2_FIELD_ALTERNATE, |
1113 | sizeof(struct saa7134_buf), | 1113 | sizeof(struct saa7134_buf), |
1114 | dev); | 1114 | dev, NULL); |
1115 | 1115 | ||
1116 | switch (dev->board) { | 1116 | switch (dev->board) { |
1117 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: | 1117 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index e763f9fd013..1467a30a434 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -542,7 +542,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
542 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 542 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
543 | V4L2_FIELD_ALTERNATE, | 543 | V4L2_FIELD_ALTERNATE, |
544 | sizeof(struct saa7134_buf), | 544 | sizeof(struct saa7134_buf), |
545 | dev); | 545 | dev, NULL); |
546 | 546 | ||
547 | empress_signal_update(&dev->empress_workqueue); | 547 | empress_signal_update(&dev->empress_workqueue); |
548 | return 0; | 548 | return 0; |
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index da41b6b1e64..2d3f6d265bb 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -328,7 +328,6 @@ static struct i2c_algorithm saa7134_algo = { | |||
328 | static struct i2c_adapter saa7134_adap_template = { | 328 | static struct i2c_adapter saa7134_adap_template = { |
329 | .owner = THIS_MODULE, | 329 | .owner = THIS_MODULE, |
330 | .name = "saa7134", | 330 | .name = "saa7134", |
331 | .id = I2C_HW_SAA7134, | ||
332 | .algo = &saa7134_algo, | 331 | .algo = &saa7134_algo, |
333 | }; | 332 | }; |
334 | 333 | ||
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 0b336ca6d55..46d31dfca7a 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -429,7 +429,7 @@ static void saa7134_input_timer(unsigned long data) | |||
429 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | 429 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
430 | } | 430 | } |
431 | 431 | ||
432 | void ir_raw_decode_timer_end(unsigned long data) | 432 | static void ir_raw_decode_timer_end(unsigned long data) |
433 | { | 433 | { |
434 | struct saa7134_dev *dev = (struct saa7134_dev *)data; | 434 | struct saa7134_dev *dev = (struct saa7134_dev *)data; |
435 | struct card_ir *ir = dev->remote; | 435 | struct card_ir *ir = dev->remote; |
@@ -550,7 +550,7 @@ static void saa7134_ir_close(void *priv) | |||
550 | } | 550 | } |
551 | 551 | ||
552 | 552 | ||
553 | int saa7134_ir_change_protocol(void *priv, u64 ir_type) | 553 | static int saa7134_ir_change_protocol(void *priv, u64 ir_type) |
554 | { | 554 | { |
555 | struct saa7134_dev *dev = priv; | 555 | struct saa7134_dev *dev = priv; |
556 | struct card_ir *ir = dev->remote; | 556 | struct card_ir *ir = dev->remote; |
@@ -772,8 +772,10 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
772 | case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: | 772 | case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: |
773 | case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: | 773 | case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: |
774 | ir_codes = RC_MAP_ASUS_PC39; | 774 | ir_codes = RC_MAP_ASUS_PC39; |
775 | mask_keydown = 0x0040000; | 775 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ |
776 | rc5_gpio = 1; | 776 | mask_keyup = 0x0040000; |
777 | mask_keycode = 0xffff; | ||
778 | raw_decode = 1; | ||
777 | break; | 779 | break; |
778 | case SAA7134_BOARD_ENCORE_ENLTV: | 780 | case SAA7134_BOARD_ENCORE_ENLTV: |
779 | case SAA7134_BOARD_ENCORE_ENLTV_FM: | 781 | case SAA7134_BOARD_ENCORE_ENLTV_FM: |
@@ -959,6 +961,11 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | |||
959 | dev->init_data.name = "MSI TV@nywhere Plus"; | 961 | dev->init_data.name = "MSI TV@nywhere Plus"; |
960 | dev->init_data.get_key = get_key_msi_tvanywhere_plus; | 962 | dev->init_data.get_key = get_key_msi_tvanywhere_plus; |
961 | dev->init_data.ir_codes = RC_MAP_MSI_TVANYWHERE_PLUS; | 963 | dev->init_data.ir_codes = RC_MAP_MSI_TVANYWHERE_PLUS; |
964 | /* | ||
965 | * MSI TV@nyware Plus requires more frequent polling | ||
966 | * otherwise it will miss some keypresses | ||
967 | */ | ||
968 | dev->init_data.polling_interval = 50; | ||
962 | info.addr = 0x30; | 969 | info.addr = 0x30; |
963 | /* MSI TV@nywhere Plus controller doesn't seem to | 970 | /* MSI TV@nywhere Plus controller doesn't seem to |
964 | respond to probes unless we read something from | 971 | respond to probes unless we read something from |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 45f0ac8f3c0..f0b1573137f 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -1366,13 +1366,13 @@ static int video_open(struct file *file) | |||
1366 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1366 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1367 | V4L2_FIELD_INTERLACED, | 1367 | V4L2_FIELD_INTERLACED, |
1368 | sizeof(struct saa7134_buf), | 1368 | sizeof(struct saa7134_buf), |
1369 | fh); | 1369 | fh, NULL); |
1370 | videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops, | 1370 | videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops, |
1371 | &dev->pci->dev, &dev->slock, | 1371 | &dev->pci->dev, &dev->slock, |
1372 | V4L2_BUF_TYPE_VBI_CAPTURE, | 1372 | V4L2_BUF_TYPE_VBI_CAPTURE, |
1373 | V4L2_FIELD_SEQ_TB, | 1373 | V4L2_FIELD_SEQ_TB, |
1374 | sizeof(struct saa7134_buf), | 1374 | sizeof(struct saa7134_buf), |
1375 | fh); | 1375 | fh, NULL); |
1376 | saa7134_pgtable_alloc(dev->pci,&fh->pt_cap); | 1376 | saa7134_pgtable_alloc(dev->pci,&fh->pt_cap); |
1377 | saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi); | 1377 | saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi); |
1378 | 1378 | ||
@@ -1825,7 +1825,7 @@ static int saa7134_querycap(struct file *file, void *priv, | |||
1825 | 1825 | ||
1826 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) | 1826 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) |
1827 | cap->capabilities &= ~V4L2_CAP_TUNER; | 1827 | cap->capabilities &= ~V4L2_CAP_TUNER; |
1828 | return 0; | 1828 | return 0; |
1829 | } | 1829 | } |
1830 | 1830 | ||
1831 | int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id) | 1831 | int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id) |
@@ -1871,9 +1871,12 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_ | |||
1871 | else | 1871 | else |
1872 | fixup = V4L2_STD_SECAM; | 1872 | fixup = V4L2_STD_SECAM; |
1873 | } | 1873 | } |
1874 | for (i = 0; i < TVNORMS; i++) | 1874 | for (i = 0; i < TVNORMS; i++) { |
1875 | if (fixup == tvnorms[i].id) | 1875 | if (fixup == tvnorms[i].id) |
1876 | break; | 1876 | break; |
1877 | } | ||
1878 | if (i == TVNORMS) | ||
1879 | return -EINVAL; | ||
1877 | } | 1880 | } |
1878 | 1881 | ||
1879 | *id = tvnorms[i].id; | 1882 | *id = tvnorms[i].id; |
@@ -1997,9 +2000,12 @@ static int saa7134_g_tuner(struct file *file, void *priv, | |||
1997 | if (0 != t->index) | 2000 | if (0 != t->index) |
1998 | return -EINVAL; | 2001 | return -EINVAL; |
1999 | memset(t, 0, sizeof(*t)); | 2002 | memset(t, 0, sizeof(*t)); |
2000 | for (n = 0; n < SAA7134_INPUT_MAX; n++) | 2003 | for (n = 0; n < SAA7134_INPUT_MAX; n++) { |
2001 | if (card_in(dev, n).tv) | 2004 | if (card_in(dev, n).tv) |
2002 | break; | 2005 | break; |
2006 | } | ||
2007 | if (n == SAA7134_INPUT_MAX) | ||
2008 | return -EINVAL; | ||
2003 | if (NULL != card_in(dev, n).name) { | 2009 | if (NULL != card_in(dev, n).name) { |
2004 | strcpy(t->name, "Television"); | 2010 | strcpy(t->name, "Television"); |
2005 | t->type = V4L2_TUNER_ANALOG_TV; | 2011 | t->type = V4L2_TUNER_ANALOG_TV; |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index c040a180854..d3b6a196e5d 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -810,16 +810,18 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status); | |||
810 | /* ----------------------------------------------------------- */ | 810 | /* ----------------------------------------------------------- */ |
811 | /* saa7134-input.c */ | 811 | /* saa7134-input.c */ |
812 | 812 | ||
813 | #if defined(CONFIG_VIDEO_SAA7134_RC) | ||
813 | int saa7134_input_init1(struct saa7134_dev *dev); | 814 | int saa7134_input_init1(struct saa7134_dev *dev); |
814 | void saa7134_input_fini(struct saa7134_dev *dev); | 815 | void saa7134_input_fini(struct saa7134_dev *dev); |
815 | void saa7134_input_irq(struct saa7134_dev *dev); | 816 | void saa7134_input_irq(struct saa7134_dev *dev); |
816 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev); | 817 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev); |
817 | int saa7134_ir_start(struct saa7134_dev *dev); | 818 | int saa7134_ir_start(struct saa7134_dev *dev); |
818 | void saa7134_ir_stop(struct saa7134_dev *dev); | 819 | void saa7134_ir_stop(struct saa7134_dev *dev); |
819 | 820 | #else | |
820 | 821 | #define saa7134_input_init1(dev) (0) | |
821 | /* | 822 | #define saa7134_input_fini(dev) (0) |
822 | * Local variables: | 823 | #define saa7134_input_irq(dev) (0) |
823 | * c-basic-offset: 8 | 824 | #define saa7134_probe_i2c_ir(dev) (0) |
824 | * End: | 825 | #define saa7134_ir_start(dev) (0) |
825 | */ | 826 | #define saa7134_ir_stop(dev) (0) |
827 | #endif | ||
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile index 4b329fd42ad..6303a8e60ea 100644 --- a/drivers/media/video/saa7164/Makefile +++ b/drivers/media/video/saa7164/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \ | 1 | saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \ |
2 | saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \ | 2 | saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \ |
3 | saa7164-buffer.o | 3 | saa7164-buffer.o saa7164-encoder.o saa7164-vbi.o |
4 | 4 | ||
5 | obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o | 5 | obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o |
6 | 6 | ||
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c index 3f1262b00cc..ad3bc415417 100644 --- a/drivers/media/video/saa7164/saa7164-api.c +++ b/drivers/media/video/saa7164/saa7164-api.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -24,14 +24,750 @@ | |||
24 | 24 | ||
25 | #include "saa7164.h" | 25 | #include "saa7164.h" |
26 | 26 | ||
27 | int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode) | 27 | int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i) |
28 | { | 28 | { |
29 | int ret; | 29 | int ret; |
30 | 30 | ||
31 | if (!(saa_debug & DBGLVL_CPU)) | ||
32 | return 0; | ||
33 | |||
34 | dprintk(DBGLVL_API, "%s()\n", __func__); | ||
35 | |||
36 | i->deviceinst = 0; | ||
37 | i->devicespec = 0; | ||
38 | i->mode = 0; | ||
39 | i->status = 0; | ||
40 | |||
41 | ret = saa7164_cmd_send(dev, 0, GET_CUR, | ||
42 | GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i); | ||
43 | if (ret != SAA_OK) { | ||
44 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
45 | } | ||
46 | |||
47 | printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad); | ||
48 | |||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | int saa7164_api_collect_debug(struct saa7164_dev *dev) | ||
53 | { | ||
54 | struct tmComResDebugGetData d; | ||
55 | u8 more = 255; | ||
56 | int ret; | ||
57 | |||
58 | dprintk(DBGLVL_API, "%s()\n", __func__); | ||
59 | |||
60 | while (more--) { | ||
61 | |||
62 | memset(&d, 0, sizeof(d)); | ||
63 | |||
64 | ret = saa7164_cmd_send(dev, 0, GET_CUR, | ||
65 | GET_DEBUG_DATA_CONTROL, sizeof(d), &d); | ||
66 | if (ret != SAA_OK) { | ||
67 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
68 | } | ||
69 | |||
70 | if (d.dwResult != SAA_OK) | ||
71 | break; | ||
72 | |||
73 | printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData); | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level) | ||
80 | { | ||
81 | struct tmComResDebugSetLevel lvl; | ||
82 | int ret; | ||
83 | |||
84 | dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level); | ||
85 | |||
86 | /* Retrieve current state */ | ||
87 | ret = saa7164_cmd_send(dev, 0, GET_CUR, | ||
88 | SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); | ||
89 | if (ret != SAA_OK) { | ||
90 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
91 | } | ||
92 | dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel); | ||
93 | |||
94 | lvl.dwDebugLevel = level; | ||
95 | |||
96 | /* set new state */ | ||
97 | ret = saa7164_cmd_send(dev, 0, SET_CUR, | ||
98 | SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl); | ||
99 | if (ret != SAA_OK) { | ||
100 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
101 | } | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | int saa7164_api_set_vbi_format(struct saa7164_port *port) | ||
107 | { | ||
108 | struct saa7164_dev *dev = port->dev; | ||
109 | struct tmComResProbeCommit fmt, rsp; | ||
110 | int ret; | ||
111 | |||
112 | dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__, | ||
113 | port->nr, port->hwcfg.unitid); | ||
114 | |||
115 | fmt.bmHint = 0; | ||
116 | fmt.bFormatIndex = 1; | ||
117 | fmt.bFrameIndex = 1; | ||
118 | |||
119 | /* Probe, see if it can support this format */ | ||
120 | ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, | ||
121 | SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt); | ||
122 | if (ret != SAA_OK) | ||
123 | printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret); | ||
124 | |||
125 | /* See of the format change was successful */ | ||
126 | ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, | ||
127 | GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp); | ||
128 | if (ret != SAA_OK) { | ||
129 | printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret); | ||
130 | } else { | ||
131 | /* Compare requested vs received, should be same */ | ||
132 | if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) { | ||
133 | dprintk(DBGLVL_API, "SET/PROBE Verified\n"); | ||
134 | |||
135 | /* Ask the device to select the negotiated format */ | ||
136 | ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, | ||
137 | SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt); | ||
138 | if (ret != SAA_OK) | ||
139 | printk(KERN_ERR "%s() commit error, ret = 0x%x\n", | ||
140 | __func__, ret); | ||
141 | |||
142 | ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, | ||
143 | GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp); | ||
144 | if (ret != SAA_OK) | ||
145 | printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n", | ||
146 | __func__, ret); | ||
147 | |||
148 | if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) { | ||
149 | printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n", | ||
150 | __func__, ret); | ||
151 | } else | ||
152 | dprintk(DBGLVL_API, "SET/COMMIT Verified\n"); | ||
153 | |||
154 | dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint); | ||
155 | dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex); | ||
156 | dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex); | ||
157 | } else | ||
158 | printk(KERN_ERR "%s() compare failed\n", __func__); | ||
159 | } | ||
160 | |||
161 | if (ret == SAA_OK) | ||
162 | dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr); | ||
163 | |||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | int saa7164_api_set_gop_size(struct saa7164_port *port) | ||
168 | { | ||
169 | struct saa7164_dev *dev = port->dev; | ||
170 | struct tmComResEncVideoGopStructure gs; | ||
171 | int ret; | ||
172 | |||
173 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
174 | |||
175 | gs.ucRefFrameDist = port->encoder_params.refdist; | ||
176 | gs.ucGOPSize = port->encoder_params.gop_size; | ||
177 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | ||
178 | EU_VIDEO_GOP_STRUCTURE_CONTROL, | ||
179 | sizeof(gs), &gs); | ||
180 | if (ret != SAA_OK) | ||
181 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
182 | |||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | int saa7164_api_set_encoder(struct saa7164_port *port) | ||
187 | { | ||
188 | struct saa7164_dev *dev = port->dev; | ||
189 | struct tmComResEncVideoBitRate vb; | ||
190 | struct tmComResEncAudioBitRate ab; | ||
191 | int ret; | ||
192 | |||
193 | dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, | ||
194 | port->hwcfg.sourceid); | ||
195 | |||
196 | if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) | ||
197 | port->encoder_profile = EU_PROFILE_PS_DVD; | ||
198 | else | ||
199 | port->encoder_profile = EU_PROFILE_TS_HQ; | ||
200 | |||
201 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | ||
202 | EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); | ||
203 | if (ret != SAA_OK) | ||
204 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
205 | |||
206 | /* Resolution */ | ||
207 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | ||
208 | EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); | ||
209 | if (ret != SAA_OK) | ||
210 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
211 | |||
212 | /* Establish video bitrates */ | ||
213 | if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) | ||
214 | vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT; | ||
215 | else | ||
216 | vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK; | ||
217 | vb.dwVideoBitRate = port->encoder_params.bitrate; | ||
218 | vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak; | ||
219 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | ||
220 | EU_VIDEO_BIT_RATE_CONTROL, sizeof(struct tmComResEncVideoBitRate), &vb); | ||
221 | if (ret != SAA_OK) | ||
222 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
223 | |||
224 | /* Establish audio bitrates */ | ||
225 | ab.ucAudioBitRateMode = 0; | ||
226 | ab.dwAudioBitRate = 384000; | ||
227 | ab.dwAudioBitRatePeak = ab.dwAudioBitRate; | ||
228 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | ||
229 | EU_AUDIO_BIT_RATE_CONTROL, sizeof(struct tmComResEncAudioBitRate), &ab); | ||
230 | if (ret != SAA_OK) | ||
231 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
232 | |||
233 | saa7164_api_set_aspect_ratio(port); | ||
234 | saa7164_api_set_gop_size(port); | ||
235 | |||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | int saa7164_api_get_encoder(struct saa7164_port *port) | ||
240 | { | ||
241 | struct saa7164_dev *dev = port->dev; | ||
242 | struct tmComResEncVideoBitRate v; | ||
243 | struct tmComResEncAudioBitRate a; | ||
244 | struct tmComResEncVideoInputAspectRatio ar; | ||
245 | int ret; | ||
246 | |||
247 | dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid); | ||
248 | |||
249 | port->encoder_profile = 0; | ||
250 | port->video_format = 0; | ||
251 | port->video_resolution = 0; | ||
252 | port->audio_format = 0; | ||
253 | |||
254 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
255 | EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile); | ||
256 | if (ret != SAA_OK) | ||
257 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
258 | |||
259 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
260 | EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution); | ||
261 | if (ret != SAA_OK) | ||
262 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
263 | |||
264 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
265 | EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format); | ||
266 | if (ret != SAA_OK) | ||
267 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
268 | |||
269 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
270 | EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v); | ||
271 | if (ret != SAA_OK) | ||
272 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
273 | |||
274 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
275 | EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format); | ||
276 | if (ret != SAA_OK) | ||
277 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
278 | |||
279 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
280 | EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a); | ||
281 | if (ret != SAA_OK) | ||
282 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
283 | |||
284 | /* Aspect Ratio */ | ||
285 | ar.width = 0; | ||
286 | ar.height = 0; | ||
287 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR, | ||
288 | EU_VIDEO_INPUT_ASPECT_CONTROL, | ||
289 | sizeof(struct tmComResEncVideoInputAspectRatio), &ar); | ||
290 | if (ret != SAA_OK) | ||
291 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
292 | |||
293 | dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile); | ||
294 | dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format); | ||
295 | dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format); | ||
296 | dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution); | ||
297 | dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode); | ||
298 | dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", v.dwVideoBitRate); | ||
299 | dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak); | ||
300 | dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode); | ||
301 | dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", a.dwAudioBitRate); | ||
302 | dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak); | ||
303 | dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height); | ||
304 | |||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | int saa7164_api_set_aspect_ratio(struct saa7164_port *port) | ||
309 | { | ||
310 | struct saa7164_dev *dev = port->dev; | ||
311 | struct tmComResEncVideoInputAspectRatio ar; | ||
312 | int ret; | ||
313 | |||
314 | dprintk(DBGLVL_ENC, "%s(%d)\n", __func__, | ||
315 | port->encoder_params.ctl_aspect); | ||
316 | |||
317 | switch (port->encoder_params.ctl_aspect) { | ||
318 | case V4L2_MPEG_VIDEO_ASPECT_1x1: | ||
319 | ar.width = 1; | ||
320 | ar.height = 1; | ||
321 | break; | ||
322 | case V4L2_MPEG_VIDEO_ASPECT_4x3: | ||
323 | ar.width = 4; | ||
324 | ar.height = 3; | ||
325 | break; | ||
326 | case V4L2_MPEG_VIDEO_ASPECT_16x9: | ||
327 | ar.width = 16; | ||
328 | ar.height = 9; | ||
329 | break; | ||
330 | case V4L2_MPEG_VIDEO_ASPECT_221x100: | ||
331 | ar.width = 221; | ||
332 | ar.height = 100; | ||
333 | break; | ||
334 | default: | ||
335 | BUG(); | ||
336 | } | ||
337 | |||
338 | dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__, | ||
339 | port->encoder_params.ctl_aspect, | ||
340 | ar.width, ar.height); | ||
341 | |||
342 | /* Aspect Ratio */ | ||
343 | ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR, | ||
344 | EU_VIDEO_INPUT_ASPECT_CONTROL, | ||
345 | sizeof(struct tmComResEncVideoInputAspectRatio), &ar); | ||
346 | if (ret != SAA_OK) | ||
347 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
348 | |||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl) | ||
353 | { | ||
354 | struct saa7164_dev *dev = port->dev; | ||
355 | int ret; | ||
356 | u16 val; | ||
357 | |||
358 | if (ctl == PU_BRIGHTNESS_CONTROL) | ||
359 | val = port->ctl_brightness; | ||
360 | else | ||
361 | if (ctl == PU_CONTRAST_CONTROL) | ||
362 | val = port->ctl_contrast; | ||
363 | else | ||
364 | if (ctl == PU_HUE_CONTROL) | ||
365 | val = port->ctl_hue; | ||
366 | else | ||
367 | if (ctl == PU_SATURATION_CONTROL) | ||
368 | val = port->ctl_saturation; | ||
369 | else | ||
370 | if (ctl == PU_SHARPNESS_CONTROL) | ||
371 | val = port->ctl_sharpness; | ||
372 | else | ||
373 | return -EINVAL; | ||
374 | |||
375 | dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n", | ||
376 | __func__, port->encunit.vsourceid, ctl, val); | ||
377 | |||
378 | ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR, | ||
379 | ctl, sizeof(u16), &val); | ||
380 | if (ret != SAA_OK) | ||
381 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
382 | |||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl) | ||
387 | { | ||
388 | struct saa7164_dev *dev = port->dev; | ||
389 | int ret; | ||
390 | u16 val; | ||
391 | |||
392 | ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR, | ||
393 | ctl, sizeof(u16), &val); | ||
394 | if (ret != SAA_OK) { | ||
395 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
396 | return ret; | ||
397 | } | ||
398 | |||
399 | dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n", | ||
400 | __func__, ctl, val); | ||
401 | |||
402 | if (ctl == PU_BRIGHTNESS_CONTROL) | ||
403 | port->ctl_brightness = val; | ||
404 | else | ||
405 | if (ctl == PU_CONTRAST_CONTROL) | ||
406 | port->ctl_contrast = val; | ||
407 | else | ||
408 | if (ctl == PU_HUE_CONTROL) | ||
409 | port->ctl_hue = val; | ||
410 | else | ||
411 | if (ctl == PU_SATURATION_CONTROL) | ||
412 | port->ctl_saturation = val; | ||
413 | else | ||
414 | if (ctl == PU_SHARPNESS_CONTROL) | ||
415 | port->ctl_sharpness = val; | ||
416 | |||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | int saa7164_api_set_videomux(struct saa7164_port *port) | ||
421 | { | ||
422 | struct saa7164_dev *dev = port->dev; | ||
423 | u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 }; | ||
424 | int ret; | ||
425 | |||
426 | dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n", | ||
427 | __func__, port->mux_input, inputs[port->mux_input - 1]); | ||
428 | |||
429 | /* Audio Mute */ | ||
430 | ret = saa7164_api_audio_mute(port, 1); | ||
431 | if (ret != SAA_OK) | ||
432 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
433 | |||
434 | /* Video Mux */ | ||
435 | ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR, | ||
436 | SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input); | ||
437 | if (ret != SAA_OK) | ||
438 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
439 | |||
440 | /* Audio Mux */ | ||
441 | ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR, | ||
442 | SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[port->mux_input - 1]); | ||
443 | if (ret != SAA_OK) | ||
444 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
445 | |||
446 | /* Audio UnMute */ | ||
447 | ret = saa7164_api_audio_mute(port, 0); | ||
448 | if (ret != SAA_OK) | ||
449 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
450 | |||
451 | return ret; | ||
452 | } | ||
453 | |||
454 | int saa7164_api_audio_mute(struct saa7164_port *port, int mute) | ||
455 | { | ||
456 | struct saa7164_dev *dev = port->dev; | ||
457 | u8 v = mute; | ||
458 | int ret; | ||
459 | |||
460 | dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute); | ||
461 | |||
462 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, | ||
463 | MUTE_CONTROL, sizeof(u8), &v); | ||
464 | if (ret != SAA_OK) | ||
465 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
466 | |||
467 | return ret; | ||
468 | } | ||
469 | |||
470 | /* 0 = silence, 0xff = full */ | ||
471 | int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level) | ||
472 | { | ||
473 | struct saa7164_dev *dev = port->dev; | ||
474 | s16 v, min, max; | ||
475 | int ret; | ||
476 | |||
477 | dprintk(DBGLVL_API, "%s(%d)\n", __func__, level); | ||
478 | |||
479 | /* Obtain the min/max ranges */ | ||
480 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN, | ||
481 | VOLUME_CONTROL, sizeof(u16), &min); | ||
482 | if (ret != SAA_OK) | ||
483 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
484 | |||
485 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX, | ||
486 | VOLUME_CONTROL, sizeof(u16), &max); | ||
487 | if (ret != SAA_OK) | ||
488 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
489 | |||
490 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR, | ||
491 | (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v); | ||
492 | if (ret != SAA_OK) | ||
493 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
494 | |||
495 | dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v); | ||
496 | |||
497 | v = level; | ||
498 | if (v < min) | ||
499 | v = min; | ||
500 | if (v > max) | ||
501 | v = max; | ||
502 | |||
503 | /* Left */ | ||
504 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, | ||
505 | (0x01 << 8) | VOLUME_CONTROL, sizeof(s16), &v); | ||
506 | if (ret != SAA_OK) | ||
507 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
508 | |||
509 | /* Right */ | ||
510 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, | ||
511 | (0x02 << 8) | VOLUME_CONTROL, sizeof(s16), &v); | ||
512 | if (ret != SAA_OK) | ||
513 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
514 | |||
515 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR, | ||
516 | (0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v); | ||
517 | if (ret != SAA_OK) | ||
518 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
519 | |||
520 | dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v); | ||
521 | |||
522 | return ret; | ||
523 | } | ||
524 | |||
525 | int saa7164_api_set_audio_std(struct saa7164_port *port) | ||
526 | { | ||
527 | struct saa7164_dev *dev = port->dev; | ||
528 | struct tmComResAudioDefaults lvl; | ||
529 | struct tmComResTunerStandard tvaudio; | ||
530 | int ret; | ||
531 | |||
532 | dprintk(DBGLVL_API, "%s()\n", __func__); | ||
533 | |||
534 | /* Establish default levels */ | ||
535 | lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT; | ||
536 | lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT; | ||
537 | lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT; | ||
538 | lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT; | ||
539 | lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT; | ||
540 | lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT; | ||
541 | ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR, | ||
542 | AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), &lvl); | ||
543 | if (ret != SAA_OK) | ||
544 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
545 | |||
546 | /* Manually select the appropriate TV audio standard */ | ||
547 | if (port->encodernorm.id & V4L2_STD_NTSC) { | ||
548 | tvaudio.std = TU_STANDARD_NTSC_M; | ||
549 | tvaudio.country = 1; | ||
550 | } else { | ||
551 | tvaudio.std = TU_STANDARD_PAL_I; | ||
552 | tvaudio.country = 44; | ||
553 | } | ||
554 | |||
555 | ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, | ||
556 | TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio); | ||
557 | if (ret != SAA_OK) | ||
558 | printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret); | ||
559 | return ret; | ||
560 | } | ||
561 | |||
562 | int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect) | ||
563 | { | ||
564 | struct saa7164_dev *dev = port->dev; | ||
565 | struct tmComResTunerStandardAuto p; | ||
566 | int ret; | ||
567 | |||
568 | dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect); | ||
569 | |||
570 | /* Disable TV Audio autodetect if not already set (buggy) */ | ||
571 | if (autodetect) | ||
572 | p.mode = TU_STANDARD_AUTO; | ||
573 | else | ||
574 | p.mode = TU_STANDARD_MANUAL; | ||
575 | ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR, | ||
576 | TU_STANDARD_AUTO_CONTROL, sizeof(p), &p); | ||
577 | if (ret != SAA_OK) | ||
578 | printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret); | ||
579 | |||
580 | return ret; | ||
581 | } | ||
582 | |||
583 | int saa7164_api_get_videomux(struct saa7164_port *port) | ||
584 | { | ||
585 | struct saa7164_dev *dev = port->dev; | ||
586 | int ret; | ||
587 | |||
588 | ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR, | ||
589 | SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input); | ||
590 | if (ret != SAA_OK) | ||
591 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | ||
592 | |||
593 | dprintk(DBGLVL_ENC, "%s() v_mux=%d\n", | ||
594 | __func__, port->mux_input); | ||
595 | |||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val) | ||
600 | { | ||
601 | struct saa7164_dev *dev = port->dev; | ||
602 | |||
603 | u16 len = 0; | ||
604 | u8 buf[256]; | ||
605 | int ret; | ||
606 | u8 mas; | ||
607 | |||
608 | dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__, | ||
609 | port->nr, port->type, val); | ||
610 | |||
611 | if (port->nr == 0) | ||
612 | mas = 0xd0; | ||
613 | else | ||
614 | mas = 0xe0; | ||
615 | |||
616 | memset(buf, 0, sizeof(buf)); | ||
617 | |||
618 | buf[0x00] = 0x04; | ||
619 | buf[0x01] = 0x00; | ||
620 | buf[0x02] = 0x00; | ||
621 | buf[0x03] = 0x00; | ||
622 | |||
623 | buf[0x04] = 0x04; | ||
624 | buf[0x05] = 0x00; | ||
625 | buf[0x06] = 0x00; | ||
626 | buf[0x07] = 0x00; | ||
627 | |||
628 | buf[0x08] = reg; | ||
629 | buf[0x09] = 0x26; | ||
630 | buf[0x0a] = mas; | ||
631 | buf[0x0b] = 0xb0; | ||
632 | |||
633 | buf[0x0c] = val; | ||
634 | buf[0x0d] = 0x00; | ||
635 | buf[0x0e] = 0x00; | ||
636 | buf[0x0f] = 0x00; | ||
637 | |||
638 | ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN, | ||
639 | EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len); | ||
640 | if (ret != SAA_OK) { | ||
641 | printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret); | ||
642 | return -EIO; | ||
643 | } | ||
644 | |||
645 | ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR, | ||
646 | EXU_REGISTER_ACCESS_CONTROL, len, &buf); | ||
647 | if (ret != SAA_OK) | ||
648 | printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); | ||
649 | |||
650 | //saa7164_dumphex16(dev, buf, 16); | ||
651 | |||
652 | return ret == SAA_OK ? 0 : -EIO; | ||
653 | } | ||
654 | |||
655 | /* Disable the IF block AGC controls */ | ||
656 | int saa7164_api_configure_dif(struct saa7164_port *port, u32 std) | ||
657 | { | ||
658 | struct saa7164_dev *dev = port->dev; | ||
659 | int ret = 0; | ||
660 | u8 agc_disable; | ||
661 | |||
662 | dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std); | ||
663 | |||
664 | if (std & V4L2_STD_NTSC) { | ||
665 | dprintk(DBGLVL_API, " NTSC\n"); | ||
666 | saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ | ||
667 | agc_disable = 0; | ||
668 | } else if (std & V4L2_STD_PAL_I) { | ||
669 | dprintk(DBGLVL_API, " PAL-I\n"); | ||
670 | saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */ | ||
671 | agc_disable = 0; | ||
672 | } else if (std & V4L2_STD_PAL_M) { | ||
673 | dprintk(DBGLVL_API, " PAL-M\n"); | ||
674 | saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ | ||
675 | agc_disable = 0; | ||
676 | } else if (std & V4L2_STD_PAL_N) { | ||
677 | dprintk(DBGLVL_API, " PAL-N\n"); | ||
678 | saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ | ||
679 | agc_disable = 0; | ||
680 | } else if (std & V4L2_STD_PAL_Nc) { | ||
681 | dprintk(DBGLVL_API, " PAL-Nc\n"); | ||
682 | saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */ | ||
683 | agc_disable = 0; | ||
684 | } else if (std & V4L2_STD_PAL_B) { | ||
685 | dprintk(DBGLVL_API, " PAL-B\n"); | ||
686 | saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */ | ||
687 | agc_disable = 0; | ||
688 | } else if (std & V4L2_STD_PAL_DK) { | ||
689 | dprintk(DBGLVL_API, " PAL-DK\n"); | ||
690 | saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */ | ||
691 | agc_disable = 0; | ||
692 | } else if (std & V4L2_STD_SECAM_L) { | ||
693 | dprintk(DBGLVL_API, " SECAM-L\n"); | ||
694 | saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */ | ||
695 | agc_disable = 0; | ||
696 | } else { | ||
697 | /* Unknown standard, assume DTV */ | ||
698 | dprintk(DBGLVL_API, " Unknown (assuming DTV)\n"); | ||
699 | saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */ | ||
700 | agc_disable = 1; | ||
701 | } | ||
702 | |||
703 | saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */ | ||
704 | saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */ | ||
705 | saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */ | ||
706 | saa7164_api_set_dif(port, 0x04, 0x01); /* Active */ | ||
707 | msleep(100); | ||
708 | saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */ | ||
709 | msleep(100); | ||
710 | |||
711 | return ret; | ||
712 | } | ||
713 | |||
714 | /* Ensure the dif is in the correct state for the operating mode | ||
715 | * (analog / dtv). We only configure the diff through the analog encoder | ||
716 | * so when we're in digital mode we need to find the appropriate encoder | ||
717 | * and use it to configure the DIF. | ||
718 | */ | ||
719 | int saa7164_api_initialize_dif(struct saa7164_port *port) | ||
720 | { | ||
721 | struct saa7164_dev *dev = port->dev; | ||
722 | struct saa7164_port *p = 0; | ||
723 | int ret = -EINVAL; | ||
724 | u32 std = 0; | ||
725 | |||
726 | dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__, | ||
727 | port->nr, port->type); | ||
728 | |||
729 | if (port->type == SAA7164_MPEG_ENCODER) { | ||
730 | /* Pick any analog standard to init the diff. | ||
731 | * we'll come back during encoder_init' | ||
732 | * and set the correct standard if requried. | ||
733 | */ | ||
734 | std = V4L2_STD_NTSC; | ||
735 | } else | ||
736 | if (port->type == SAA7164_MPEG_DVB) { | ||
737 | if (port->nr == SAA7164_PORT_TS1) | ||
738 | p = &dev->ports[SAA7164_PORT_ENC1]; | ||
739 | else | ||
740 | p = &dev->ports[SAA7164_PORT_ENC2]; | ||
741 | } else | ||
742 | if (port->type == SAA7164_MPEG_VBI) { | ||
743 | std = V4L2_STD_NTSC; | ||
744 | if (port->nr == SAA7164_PORT_VBI1) | ||
745 | p = &dev->ports[SAA7164_PORT_ENC1]; | ||
746 | else | ||
747 | p = &dev->ports[SAA7164_PORT_ENC2]; | ||
748 | } else | ||
749 | BUG(); | ||
750 | |||
751 | if (p) | ||
752 | ret = saa7164_api_configure_dif(p, std); | ||
753 | |||
754 | return ret; | ||
755 | } | ||
756 | |||
757 | int saa7164_api_transition_port(struct saa7164_port *port, u8 mode) | ||
758 | { | ||
759 | struct saa7164_dev *dev = port->dev; | ||
760 | |||
761 | int ret; | ||
762 | |||
763 | dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n", | ||
764 | __func__, port->nr, port->hwcfg.unitid, mode); | ||
765 | |||
31 | ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR, | 766 | ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR, |
32 | SAA_STATE_CONTROL, sizeof(mode), &mode); | 767 | SAA_STATE_CONTROL, sizeof(mode), &mode); |
33 | if (ret != SAA_OK) | 768 | if (ret != SAA_OK) |
34 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret); | 769 | printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n", |
770 | __func__, port->nr, port->hwcfg.unitid, ret); | ||
35 | 771 | ||
36 | return ret; | 772 | return ret; |
37 | } | 773 | } |
@@ -61,10 +797,45 @@ int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen) | |||
61 | ®[0], 128, buf); | 797 | ®[0], 128, buf); |
62 | } | 798 | } |
63 | 799 | ||
800 | int saa7164_api_configure_port_vbi(struct saa7164_dev *dev, | ||
801 | struct saa7164_port *port) | ||
802 | { | ||
803 | struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc; | ||
804 | |||
805 | dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex); | ||
806 | dprintk(DBGLVL_API, " VideoStandard = 0x%x\n", fmt->VideoStandard); | ||
807 | dprintk(DBGLVL_API, " StartLine = %d\n", fmt->StartLine); | ||
808 | dprintk(DBGLVL_API, " EndLine = %d\n", fmt->EndLine); | ||
809 | dprintk(DBGLVL_API, " FieldRate = %d\n", fmt->FieldRate); | ||
810 | dprintk(DBGLVL_API, " bNumLines = %d\n", fmt->bNumLines); | ||
811 | |||
812 | /* Cache the hardware configuration in the port */ | ||
813 | |||
814 | port->bufcounter = port->hwcfg.BARLocation; | ||
815 | port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); | ||
816 | port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); | ||
817 | port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); | ||
818 | port->bufptr32l = port->hwcfg.BARLocation + | ||
819 | (4 * sizeof(u32)) + | ||
820 | (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); | ||
821 | port->bufptr32h = port->hwcfg.BARLocation + | ||
822 | (4 * sizeof(u32)) + | ||
823 | (sizeof(u32) * port->hwcfg.buffercount); | ||
824 | port->bufptr64 = port->hwcfg.BARLocation + | ||
825 | (4 * sizeof(u32)) + | ||
826 | (sizeof(u32) * port->hwcfg.buffercount); | ||
827 | dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", | ||
828 | port->hwcfg.BARLocation); | ||
829 | |||
830 | dprintk(DBGLVL_API, " = VS_FORMAT_VBI (becomes dev->en[%d])\n", | ||
831 | port->nr); | ||
832 | |||
833 | return 0; | ||
834 | } | ||
64 | 835 | ||
65 | int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev, | 836 | int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev, |
66 | struct saa7164_tsport *port, | 837 | struct saa7164_port *port, |
67 | tmComResTSFormatDescrHeader_t *tsfmt) | 838 | struct tmComResTSFormatDescrHeader *tsfmt) |
68 | { | 839 | { |
69 | dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex); | 840 | dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex); |
70 | dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset); | 841 | dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset); |
@@ -96,27 +867,68 @@ int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev, | |||
96 | return 0; | 867 | return 0; |
97 | } | 868 | } |
98 | 869 | ||
870 | int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev, | ||
871 | struct saa7164_port *port, | ||
872 | struct tmComResPSFormatDescrHeader *fmt) | ||
873 | { | ||
874 | dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex); | ||
875 | dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength); | ||
876 | dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength); | ||
877 | dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType); | ||
878 | |||
879 | /* Cache the hardware configuration in the port */ | ||
880 | /* TODO: CHECK THIS in the port config */ | ||
881 | port->bufcounter = port->hwcfg.BARLocation; | ||
882 | port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32)); | ||
883 | port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32)); | ||
884 | port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32)); | ||
885 | port->bufptr32l = port->hwcfg.BARLocation + | ||
886 | (4 * sizeof(u32)) + | ||
887 | (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32); | ||
888 | port->bufptr32h = port->hwcfg.BARLocation + | ||
889 | (4 * sizeof(u32)) + | ||
890 | (sizeof(u32) * port->hwcfg.buffercount); | ||
891 | port->bufptr64 = port->hwcfg.BARLocation + | ||
892 | (4 * sizeof(u32)) + | ||
893 | (sizeof(u32) * port->hwcfg.buffercount); | ||
894 | dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n", | ||
895 | port->hwcfg.BARLocation); | ||
896 | |||
897 | dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n", | ||
898 | port->nr); | ||
899 | |||
900 | return 0; | ||
901 | } | ||
902 | |||
99 | int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | 903 | int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) |
100 | { | 904 | { |
101 | struct saa7164_tsport *port = 0; | 905 | struct saa7164_port *tsport = 0; |
906 | struct saa7164_port *encport = 0; | ||
907 | struct saa7164_port *vbiport = 0; | ||
102 | u32 idx, next_offset; | 908 | u32 idx, next_offset; |
103 | int i; | 909 | int i; |
104 | tmComResDescrHeader_t *hdr, *t; | 910 | struct tmComResDescrHeader *hdr, *t; |
105 | tmComResExtDevDescrHeader_t *exthdr; | 911 | struct tmComResExtDevDescrHeader *exthdr; |
106 | tmComResPathDescrHeader_t *pathhdr; | 912 | struct tmComResPathDescrHeader *pathhdr; |
107 | tmComResAntTermDescrHeader_t *anttermhdr; | 913 | struct tmComResAntTermDescrHeader *anttermhdr; |
108 | tmComResTunerDescrHeader_t *tunerunithdr; | 914 | struct tmComResTunerDescrHeader *tunerunithdr; |
109 | tmComResDMATermDescrHeader_t *vcoutputtermhdr; | 915 | struct tmComResDMATermDescrHeader *vcoutputtermhdr; |
110 | tmComResTSFormatDescrHeader_t *tsfmt; | 916 | struct tmComResTSFormatDescrHeader *tsfmt; |
917 | struct tmComResPSFormatDescrHeader *psfmt; | ||
918 | struct tmComResSelDescrHeader *psel; | ||
919 | struct tmComResProcDescrHeader *pdh; | ||
920 | struct tmComResAFeatureDescrHeader *afd; | ||
921 | struct tmComResEncoderDescrHeader *edh; | ||
922 | struct tmComResVBIFormatDescrHeader *vbifmt; | ||
111 | u32 currpath = 0; | 923 | u32 currpath = 0; |
112 | 924 | ||
113 | dprintk(DBGLVL_API, | 925 | dprintk(DBGLVL_API, |
114 | "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n", | 926 | "%s(?,?,%d) sizeof(struct tmComResDescrHeader) = %d bytes\n", |
115 | __func__, len, (u32)sizeof(tmComResDescrHeader_t)); | 927 | __func__, len, (u32)sizeof(struct tmComResDescrHeader)); |
116 | 928 | ||
117 | for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) { | 929 | for (idx = 0; idx < (len - sizeof(struct tmComResDescrHeader));) { |
118 | 930 | ||
119 | hdr = (tmComResDescrHeader_t *)(buf + idx); | 931 | hdr = (struct tmComResDescrHeader *)(buf + idx); |
120 | 932 | ||
121 | if (hdr->type != CS_INTERFACE) | 933 | if (hdr->type != CS_INTERFACE) |
122 | return SAA_ERR_NOT_SUPPORTED; | 934 | return SAA_ERR_NOT_SUPPORTED; |
@@ -128,7 +940,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
128 | break; | 940 | break; |
129 | case VC_TUNER_PATH: | 941 | case VC_TUNER_PATH: |
130 | dprintk(DBGLVL_API, " VC_TUNER_PATH\n"); | 942 | dprintk(DBGLVL_API, " VC_TUNER_PATH\n"); |
131 | pathhdr = (tmComResPathDescrHeader_t *)(buf + idx); | 943 | pathhdr = (struct tmComResPathDescrHeader *)(buf + idx); |
132 | dprintk(DBGLVL_API, " pathid = 0x%x\n", | 944 | dprintk(DBGLVL_API, " pathid = 0x%x\n", |
133 | pathhdr->pathid); | 945 | pathhdr->pathid); |
134 | currpath = pathhdr->pathid; | 946 | currpath = pathhdr->pathid; |
@@ -136,7 +948,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
136 | case VC_INPUT_TERMINAL: | 948 | case VC_INPUT_TERMINAL: |
137 | dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n"); | 949 | dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n"); |
138 | anttermhdr = | 950 | anttermhdr = |
139 | (tmComResAntTermDescrHeader_t *)(buf + idx); | 951 | (struct tmComResAntTermDescrHeader *)(buf + idx); |
140 | dprintk(DBGLVL_API, " terminalid = 0x%x\n", | 952 | dprintk(DBGLVL_API, " terminalid = 0x%x\n", |
141 | anttermhdr->terminalid); | 953 | anttermhdr->terminalid); |
142 | dprintk(DBGLVL_API, " terminaltype = 0x%x\n", | 954 | dprintk(DBGLVL_API, " terminaltype = 0x%x\n", |
@@ -179,7 +991,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
179 | case VC_OUTPUT_TERMINAL: | 991 | case VC_OUTPUT_TERMINAL: |
180 | dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n"); | 992 | dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n"); |
181 | vcoutputtermhdr = | 993 | vcoutputtermhdr = |
182 | (tmComResDMATermDescrHeader_t *)(buf + idx); | 994 | (struct tmComResDMATermDescrHeader *)(buf + idx); |
183 | dprintk(DBGLVL_API, " unitid = 0x%x\n", | 995 | dprintk(DBGLVL_API, " unitid = 0x%x\n", |
184 | vcoutputtermhdr->unitid); | 996 | vcoutputtermhdr->unitid); |
185 | dprintk(DBGLVL_API, " terminaltype = 0x%x\n", | 997 | dprintk(DBGLVL_API, " terminaltype = 0x%x\n", |
@@ -233,32 +1045,49 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
233 | dprintk(DBGLVL_API, " numformats = 0x%x\n", | 1045 | dprintk(DBGLVL_API, " numformats = 0x%x\n", |
234 | vcoutputtermhdr->numformats); | 1046 | vcoutputtermhdr->numformats); |
235 | 1047 | ||
236 | t = (tmComResDescrHeader_t *) | 1048 | t = (struct tmComResDescrHeader *) |
237 | ((tmComResDMATermDescrHeader_t *)(buf + idx)); | 1049 | ((struct tmComResDMATermDescrHeader *)(buf + idx)); |
238 | next_offset = idx + (vcoutputtermhdr->len); | 1050 | next_offset = idx + (vcoutputtermhdr->len); |
239 | for (i = 0; i < vcoutputtermhdr->numformats; i++) { | 1051 | for (i = 0; i < vcoutputtermhdr->numformats; i++) { |
240 | t = (tmComResDescrHeader_t *) | 1052 | t = (struct tmComResDescrHeader *) |
241 | (buf + next_offset); | 1053 | (buf + next_offset); |
242 | switch (t->subtype) { | 1054 | switch (t->subtype) { |
243 | case VS_FORMAT_MPEG2TS: | 1055 | case VS_FORMAT_MPEG2TS: |
244 | tsfmt = | 1056 | tsfmt = |
245 | (tmComResTSFormatDescrHeader_t *)t; | 1057 | (struct tmComResTSFormatDescrHeader *)t; |
246 | if (currpath == 1) | 1058 | if (currpath == 1) |
247 | port = &dev->ts1; | 1059 | tsport = &dev->ports[SAA7164_PORT_TS1]; |
248 | else | 1060 | else |
249 | port = &dev->ts2; | 1061 | tsport = &dev->ports[SAA7164_PORT_TS2]; |
250 | memcpy(&port->hwcfg, vcoutputtermhdr, | 1062 | memcpy(&tsport->hwcfg, vcoutputtermhdr, |
251 | sizeof(*vcoutputtermhdr)); | 1063 | sizeof(*vcoutputtermhdr)); |
252 | saa7164_api_configure_port_mpeg2ts(dev, | 1064 | saa7164_api_configure_port_mpeg2ts(dev, |
253 | port, tsfmt); | 1065 | tsport, tsfmt); |
254 | break; | 1066 | break; |
255 | case VS_FORMAT_MPEG2PS: | 1067 | case VS_FORMAT_MPEG2PS: |
256 | dprintk(DBGLVL_API, | 1068 | psfmt = |
257 | " = VS_FORMAT_MPEG2PS\n"); | 1069 | (struct tmComResPSFormatDescrHeader *)t; |
1070 | if (currpath == 1) | ||
1071 | encport = &dev->ports[SAA7164_PORT_ENC1]; | ||
1072 | else | ||
1073 | encport = &dev->ports[SAA7164_PORT_ENC2]; | ||
1074 | memcpy(&encport->hwcfg, vcoutputtermhdr, | ||
1075 | sizeof(*vcoutputtermhdr)); | ||
1076 | saa7164_api_configure_port_mpeg2ps(dev, | ||
1077 | encport, psfmt); | ||
258 | break; | 1078 | break; |
259 | case VS_FORMAT_VBI: | 1079 | case VS_FORMAT_VBI: |
260 | dprintk(DBGLVL_API, | 1080 | vbifmt = |
261 | " = VS_FORMAT_VBI\n"); | 1081 | (struct tmComResVBIFormatDescrHeader *)t; |
1082 | if (currpath == 1) | ||
1083 | vbiport = &dev->ports[SAA7164_PORT_VBI1]; | ||
1084 | else | ||
1085 | vbiport = &dev->ports[SAA7164_PORT_VBI2]; | ||
1086 | memcpy(&vbiport->hwcfg, vcoutputtermhdr, | ||
1087 | sizeof(*vcoutputtermhdr)); | ||
1088 | memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt)); | ||
1089 | saa7164_api_configure_port_vbi(dev, | ||
1090 | vbiport); | ||
262 | break; | 1091 | break; |
263 | case VS_FORMAT_RDS: | 1092 | case VS_FORMAT_RDS: |
264 | dprintk(DBGLVL_API, | 1093 | dprintk(DBGLVL_API, |
@@ -284,7 +1113,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
284 | case TUNER_UNIT: | 1113 | case TUNER_UNIT: |
285 | dprintk(DBGLVL_API, " TUNER_UNIT\n"); | 1114 | dprintk(DBGLVL_API, " TUNER_UNIT\n"); |
286 | tunerunithdr = | 1115 | tunerunithdr = |
287 | (tmComResTunerDescrHeader_t *)(buf + idx); | 1116 | (struct tmComResTunerDescrHeader *)(buf + idx); |
288 | dprintk(DBGLVL_API, " unitid = 0x%x\n", | 1117 | dprintk(DBGLVL_API, " unitid = 0x%x\n", |
289 | tunerunithdr->unitid); | 1118 | tunerunithdr->unitid); |
290 | dprintk(DBGLVL_API, " sourceid = 0x%x\n", | 1119 | dprintk(DBGLVL_API, " sourceid = 0x%x\n", |
@@ -297,22 +1126,84 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
297 | tunerunithdr->controlsize); | 1126 | tunerunithdr->controlsize); |
298 | dprintk(DBGLVL_API, " controls = 0x%x\n", | 1127 | dprintk(DBGLVL_API, " controls = 0x%x\n", |
299 | tunerunithdr->controls); | 1128 | tunerunithdr->controls); |
1129 | |||
1130 | if (tunerunithdr->unitid == tunerunithdr->iunit) { | ||
1131 | if (currpath == 1) | ||
1132 | encport = &dev->ports[SAA7164_PORT_ENC1]; | ||
1133 | else | ||
1134 | encport = &dev->ports[SAA7164_PORT_ENC2]; | ||
1135 | memcpy(&encport->tunerunit, tunerunithdr, | ||
1136 | sizeof(struct tmComResTunerDescrHeader)); | ||
1137 | dprintk(DBGLVL_API, " (becomes dev->enc[%d] tuner)\n", encport->nr); | ||
1138 | } | ||
300 | break; | 1139 | break; |
301 | case VC_SELECTOR_UNIT: | 1140 | case VC_SELECTOR_UNIT: |
1141 | psel = (struct tmComResSelDescrHeader *)(buf + idx); | ||
302 | dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n"); | 1142 | dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n"); |
1143 | dprintk(DBGLVL_API, " unitid = 0x%x\n", | ||
1144 | psel->unitid); | ||
1145 | dprintk(DBGLVL_API, " nrinpins = 0x%x\n", | ||
1146 | psel->nrinpins); | ||
1147 | dprintk(DBGLVL_API, " sourceid = 0x%x\n", | ||
1148 | psel->sourceid); | ||
303 | break; | 1149 | break; |
304 | case VC_PROCESSING_UNIT: | 1150 | case VC_PROCESSING_UNIT: |
1151 | pdh = (struct tmComResProcDescrHeader *)(buf + idx); | ||
305 | dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n"); | 1152 | dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n"); |
1153 | dprintk(DBGLVL_API, " unitid = 0x%x\n", | ||
1154 | pdh->unitid); | ||
1155 | dprintk(DBGLVL_API, " sourceid = 0x%x\n", | ||
1156 | pdh->sourceid); | ||
1157 | dprintk(DBGLVL_API, " controlsize = 0x%x\n", | ||
1158 | pdh->controlsize); | ||
1159 | if (pdh->controlsize == 0x04) { | ||
1160 | if (currpath == 1) | ||
1161 | encport = &dev->ports[SAA7164_PORT_ENC1]; | ||
1162 | else | ||
1163 | encport = &dev->ports[SAA7164_PORT_ENC2]; | ||
1164 | memcpy(&encport->vidproc, pdh, | ||
1165 | sizeof(struct tmComResProcDescrHeader)); | ||
1166 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | ||
1167 | } | ||
306 | break; | 1168 | break; |
307 | case FEATURE_UNIT: | 1169 | case FEATURE_UNIT: |
1170 | afd = (struct tmComResAFeatureDescrHeader *)(buf + idx); | ||
308 | dprintk(DBGLVL_API, " FEATURE_UNIT\n"); | 1171 | dprintk(DBGLVL_API, " FEATURE_UNIT\n"); |
1172 | dprintk(DBGLVL_API, " unitid = 0x%x\n", | ||
1173 | afd->unitid); | ||
1174 | dprintk(DBGLVL_API, " sourceid = 0x%x\n", | ||
1175 | afd->sourceid); | ||
1176 | dprintk(DBGLVL_API, " controlsize = 0x%x\n", | ||
1177 | afd->controlsize); | ||
1178 | if (currpath == 1) | ||
1179 | encport = &dev->ports[SAA7164_PORT_ENC1]; | ||
1180 | else | ||
1181 | encport = &dev->ports[SAA7164_PORT_ENC2]; | ||
1182 | memcpy(&encport->audfeat, afd, | ||
1183 | sizeof(struct tmComResAFeatureDescrHeader)); | ||
1184 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | ||
309 | break; | 1185 | break; |
310 | case ENCODER_UNIT: | 1186 | case ENCODER_UNIT: |
1187 | edh = (struct tmComResEncoderDescrHeader *)(buf + idx); | ||
311 | dprintk(DBGLVL_API, " ENCODER_UNIT\n"); | 1188 | dprintk(DBGLVL_API, " ENCODER_UNIT\n"); |
1189 | dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype); | ||
1190 | dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid); | ||
1191 | dprintk(DBGLVL_API, " vsourceid = 0x%x\n", edh->vsourceid); | ||
1192 | dprintk(DBGLVL_API, " asourceid = 0x%x\n", edh->asourceid); | ||
1193 | dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit); | ||
1194 | if (edh->iunit == edh->unitid) { | ||
1195 | if (currpath == 1) | ||
1196 | encport = &dev->ports[SAA7164_PORT_ENC1]; | ||
1197 | else | ||
1198 | encport = &dev->ports[SAA7164_PORT_ENC2]; | ||
1199 | memcpy(&encport->encunit, edh, | ||
1200 | sizeof(struct tmComResEncoderDescrHeader)); | ||
1201 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | ||
1202 | } | ||
312 | break; | 1203 | break; |
313 | case EXTENSION_UNIT: | 1204 | case EXTENSION_UNIT: |
314 | dprintk(DBGLVL_API, " EXTENSION_UNIT\n"); | 1205 | dprintk(DBGLVL_API, " EXTENSION_UNIT\n"); |
315 | exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx); | 1206 | exthdr = (struct tmComResExtDevDescrHeader *)(buf + idx); |
316 | dprintk(DBGLVL_API, " unitid = 0x%x\n", | 1207 | dprintk(DBGLVL_API, " unitid = 0x%x\n", |
317 | exthdr->unitid); | 1208 | exthdr->unitid); |
318 | dprintk(DBGLVL_API, " deviceid = 0x%x\n", | 1209 | dprintk(DBGLVL_API, " deviceid = 0x%x\n", |
@@ -364,6 +1255,15 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) | |||
364 | exthdr->numgpiogroups); | 1255 | exthdr->numgpiogroups); |
365 | dprintk(DBGLVL_API, " controlsize = 0x%x\n", | 1256 | dprintk(DBGLVL_API, " controlsize = 0x%x\n", |
366 | exthdr->controlsize); | 1257 | exthdr->controlsize); |
1258 | if (exthdr->devicetype & 0x80) { | ||
1259 | if (currpath == 1) | ||
1260 | encport = &dev->ports[SAA7164_PORT_ENC1]; | ||
1261 | else | ||
1262 | encport = &dev->ports[SAA7164_PORT_ENC2]; | ||
1263 | memcpy(&encport->ifunit, exthdr, | ||
1264 | sizeof(struct tmComResExtDevDescrHeader)); | ||
1265 | dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr); | ||
1266 | } | ||
367 | break; | 1267 | break; |
368 | case PVC_INFRARED_UNIT: | 1268 | case PVC_INFRARED_UNIT: |
369 | dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n"); | 1269 | dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n"); |
@@ -560,12 +1460,11 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, | |||
560 | return ret == SAA_OK ? 0 : -EIO; | 1460 | return ret == SAA_OK ? 0 : -EIO; |
561 | } | 1461 | } |
562 | 1462 | ||
563 | |||
564 | int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid, | 1463 | int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid, |
565 | u8 pin, u8 state) | 1464 | u8 pin, u8 state) |
566 | { | 1465 | { |
567 | int ret; | 1466 | int ret; |
568 | tmComResGPIO_t t; | 1467 | struct tmComResGPIO t; |
569 | 1468 | ||
570 | dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n", | 1469 | dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n", |
571 | __func__, unitid, pin, state); | 1470 | __func__, unitid, pin, state); |
@@ -597,5 +1496,3 @@ int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, | |||
597 | return saa7164_api_modify_gpio(dev, unitid, pin, 0); | 1496 | return saa7164_api_modify_gpio(dev, unitid, pin, 0); |
598 | } | 1497 | } |
599 | 1498 | ||
600 | |||
601 | |||
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c index ddd25d32723..7230912acc7 100644 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ b/drivers/media/video/saa7164/saa7164-buffer.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -66,12 +66,33 @@ | |||
66 | | etc | 66 | | etc |
67 | */ | 67 | */ |
68 | 68 | ||
69 | void saa7164_buffer_display(struct saa7164_buffer *buf) | ||
70 | { | ||
71 | struct saa7164_dev *dev = buf->port->dev; | ||
72 | int i; | ||
73 | |||
74 | dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n", | ||
75 | __func__, buf, buf->idx); | ||
76 | dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n", | ||
77 | buf->cpu, (long long)buf->dma, buf->pci_size); | ||
78 | dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n", | ||
79 | buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size); | ||
80 | |||
81 | /* Format the Page Table Entries to point into the data buffer */ | ||
82 | for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) { | ||
83 | |||
84 | dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n", | ||
85 | i, buf->pt_cpu, (u64)*(buf->pt_cpu)); | ||
86 | |||
87 | } | ||
88 | } | ||
69 | /* Allocate a new buffer structure and associated PCI space in bytes. | 89 | /* Allocate a new buffer structure and associated PCI space in bytes. |
70 | * len must be a multiple of sizeof(u64) | 90 | * len must be a multiple of sizeof(u64) |
71 | */ | 91 | */ |
72 | struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port, | 92 | struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port, |
73 | u32 len) | 93 | u32 len) |
74 | { | 94 | { |
95 | struct tmHWStreamParameters *params = &port->hw_streamingparams; | ||
75 | struct saa7164_buffer *buf = 0; | 96 | struct saa7164_buffer *buf = 0; |
76 | struct saa7164_dev *dev = port->dev; | 97 | struct saa7164_dev *dev = port->dev; |
77 | int i; | 98 | int i; |
@@ -87,8 +108,12 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port, | |||
87 | goto ret; | 108 | goto ret; |
88 | } | 109 | } |
89 | 110 | ||
111 | buf->idx = -1; | ||
90 | buf->port = port; | 112 | buf->port = port; |
91 | buf->flags = SAA7164_BUFFER_FREE; | 113 | buf->flags = SAA7164_BUFFER_FREE; |
114 | buf->pos = 0; | ||
115 | buf->actual_size = params->pitch * params->numberoflines; | ||
116 | buf->crc = 0; | ||
92 | /* TODO: arg len is being ignored */ | 117 | /* TODO: arg len is being ignored */ |
93 | buf->pci_size = SAA7164_PT_ENTRIES * 0x1000; | 118 | buf->pci_size = SAA7164_PT_ENTRIES * 0x1000; |
94 | buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000; | 119 | buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000; |
@@ -105,19 +130,23 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port, | |||
105 | goto fail2; | 130 | goto fail2; |
106 | 131 | ||
107 | /* init the buffers to a known pattern, easier during debugging */ | 132 | /* init the buffers to a known pattern, easier during debugging */ |
108 | memset(buf->cpu, 0xff, buf->pci_size); | 133 | memset_io(buf->cpu, 0xff, buf->pci_size); |
109 | memset(buf->pt_cpu, 0xff, buf->pt_size); | 134 | buf->crc = crc32(0, buf->cpu, buf->actual_size); |
135 | memset_io(buf->pt_cpu, 0xff, buf->pt_size); | ||
110 | 136 | ||
111 | dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p\n", __func__, buf); | 137 | dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n", |
138 | __func__, buf, params->numpagetables); | ||
112 | dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n", | 139 | dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n", |
113 | buf->cpu, (long)buf->dma, buf->pci_size); | 140 | buf->cpu, (long)buf->dma, buf->pci_size); |
114 | dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n", | 141 | dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n", |
115 | buf->pt_cpu, (long)buf->pt_dma, buf->pt_size); | 142 | buf->pt_cpu, (long)buf->pt_dma, buf->pt_size); |
116 | 143 | ||
117 | /* Format the Page Table Entries to point into the data buffer */ | 144 | /* Format the Page Table Entries to point into the data buffer */ |
118 | for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) { | 145 | for (i = 0 ; i < params->numpagetables; i++) { |
119 | 146 | ||
120 | *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */ | 147 | *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */ |
148 | dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n", | ||
149 | i, buf->pt_cpu, (u64)*(buf->pt_cpu)); | ||
121 | 150 | ||
122 | } | 151 | } |
123 | 152 | ||
@@ -133,26 +162,163 @@ ret: | |||
133 | return buf; | 162 | return buf; |
134 | } | 163 | } |
135 | 164 | ||
136 | int saa7164_buffer_dealloc(struct saa7164_tsport *port, | 165 | int saa7164_buffer_dealloc(struct saa7164_buffer *buf) |
137 | struct saa7164_buffer *buf) | ||
138 | { | 166 | { |
139 | struct saa7164_dev *dev; | 167 | struct saa7164_dev *dev; |
140 | 168 | ||
141 | if (!buf || !port) | 169 | if (!buf || !buf->port) |
142 | return SAA_ERR_BAD_PARAMETER; | 170 | return SAA_ERR_BAD_PARAMETER; |
143 | dev = port->dev; | 171 | dev = buf->port->dev; |
144 | 172 | ||
145 | dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf); | 173 | dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", |
174 | __func__, buf); | ||
146 | 175 | ||
147 | if (buf->flags != SAA7164_BUFFER_FREE) | 176 | if (buf->flags != SAA7164_BUFFER_FREE) |
148 | log_warn(" freeing a non-free buffer\n"); | 177 | log_warn(" freeing a non-free buffer\n"); |
149 | 178 | ||
150 | pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma); | 179 | pci_free_consistent(dev->pci, buf->pci_size, buf->cpu, buf->dma); |
151 | pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu, | 180 | pci_free_consistent(dev->pci, buf->pt_size, buf->pt_cpu, buf->pt_dma); |
152 | buf->pt_dma); | ||
153 | 181 | ||
154 | kfree(buf); | 182 | kfree(buf); |
155 | 183 | ||
156 | return SAA_OK; | 184 | return SAA_OK; |
157 | } | 185 | } |
158 | 186 | ||
187 | int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i) | ||
188 | { | ||
189 | struct saa7164_dev *dev = port->dev; | ||
190 | |||
191 | if ((i < 0) || (i >= port->hwcfg.buffercount)) | ||
192 | return -EINVAL; | ||
193 | |||
194 | dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i); | ||
195 | |||
196 | saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* Write a buffer into the hardware */ | ||
202 | int saa7164_buffer_activate(struct saa7164_buffer *buf, int i) | ||
203 | { | ||
204 | struct saa7164_port *port = buf->port; | ||
205 | struct saa7164_dev *dev = port->dev; | ||
206 | |||
207 | if ((i < 0) || (i >= port->hwcfg.buffercount)) | ||
208 | return -EINVAL; | ||
209 | |||
210 | dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i); | ||
211 | |||
212 | buf->idx = i; /* Note of which buffer list index position we occupy */ | ||
213 | buf->flags = SAA7164_BUFFER_BUSY; | ||
214 | buf->pos = 0; | ||
215 | |||
216 | /* TODO: Review this in light of 32v64 assignments */ | ||
217 | saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0); | ||
218 | saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma); | ||
219 | saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0); | ||
220 | |||
221 | dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) " | ||
222 | "buf 0x%llx/%llx (0x%x/%x) nr=%d\n", | ||
223 | buf->idx, | ||
224 | (u64)port->bufoffset + (i * sizeof(u32)), | ||
225 | saa7164_readl(port->bufoffset + (sizeof(u32) * i)), | ||
226 | (u64)port->bufptr32h + ((sizeof(u32) * 2) * i), | ||
227 | (u64)port->bufptr32l + ((sizeof(u32) * 2) * i), | ||
228 | saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)), | ||
229 | saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)), | ||
230 | buf->idx); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | int saa7164_buffer_cfg_port(struct saa7164_port *port) | ||
236 | { | ||
237 | struct tmHWStreamParameters *params = &port->hw_streamingparams; | ||
238 | struct saa7164_dev *dev = port->dev; | ||
239 | struct saa7164_buffer *buf; | ||
240 | struct list_head *c, *n; | ||
241 | int i = 0; | ||
242 | |||
243 | dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr); | ||
244 | |||
245 | saa7164_writel(port->bufcounter, 0); | ||
246 | saa7164_writel(port->pitch, params->pitch); | ||
247 | saa7164_writel(port->bufsize, params->pitch * params->numberoflines); | ||
248 | |||
249 | dprintk(DBGLVL_BUF, " configured:\n"); | ||
250 | dprintk(DBGLVL_BUF, " lmmio 0x%p\n", dev->lmmio); | ||
251 | dprintk(DBGLVL_BUF, " bufcounter 0x%x = 0x%x\n", port->bufcounter, | ||
252 | saa7164_readl(port->bufcounter)); | ||
253 | |||
254 | dprintk(DBGLVL_BUF, " pitch 0x%x = %d\n", port->pitch, | ||
255 | saa7164_readl(port->pitch)); | ||
256 | |||
257 | dprintk(DBGLVL_BUF, " bufsize 0x%x = %d\n", port->bufsize, | ||
258 | saa7164_readl(port->bufsize)); | ||
259 | |||
260 | dprintk(DBGLVL_BUF, " buffercount = %d\n", port->hwcfg.buffercount); | ||
261 | dprintk(DBGLVL_BUF, " bufoffset = 0x%x\n", port->bufoffset); | ||
262 | dprintk(DBGLVL_BUF, " bufptr32h = 0x%x\n", port->bufptr32h); | ||
263 | dprintk(DBGLVL_BUF, " bufptr32l = 0x%x\n", port->bufptr32l); | ||
264 | |||
265 | /* Poke the buffers and offsets into PCI space */ | ||
266 | mutex_lock(&port->dmaqueue_lock); | ||
267 | list_for_each_safe(c, n, &port->dmaqueue.list) { | ||
268 | buf = list_entry(c, struct saa7164_buffer, list); | ||
269 | |||
270 | if (buf->flags != SAA7164_BUFFER_FREE) | ||
271 | BUG(); | ||
272 | |||
273 | /* Place the buffer in the h/w queue */ | ||
274 | saa7164_buffer_activate(buf, i); | ||
275 | |||
276 | /* Don't exceed the device maximum # bufs */ | ||
277 | if (i++ > port->hwcfg.buffercount) | ||
278 | BUG(); | ||
279 | |||
280 | } | ||
281 | mutex_unlock(&port->dmaqueue_lock); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, u32 len) | ||
287 | { | ||
288 | struct saa7164_user_buffer *buf; | ||
289 | |||
290 | buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL); | ||
291 | if (buf == 0) | ||
292 | return 0; | ||
293 | |||
294 | buf->data = kzalloc(len, GFP_KERNEL); | ||
295 | |||
296 | if (buf->data == 0) { | ||
297 | kfree(buf); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | buf->actual_size = len; | ||
302 | buf->pos = 0; | ||
303 | buf->crc = 0; | ||
304 | |||
305 | dprintk(DBGLVL_BUF, "%s() allocated user buffer @ 0x%p\n", | ||
306 | __func__, buf); | ||
307 | |||
308 | return buf; | ||
309 | } | ||
310 | |||
311 | void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf) | ||
312 | { | ||
313 | if (!buf) | ||
314 | return; | ||
315 | |||
316 | if (buf->data) { | ||
317 | kfree(buf->data); | ||
318 | buf->data = 0; | ||
319 | } | ||
320 | |||
321 | if (buf) | ||
322 | kfree(buf); | ||
323 | } | ||
324 | |||
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c index 83a04640a25..30d5283da41 100644 --- a/drivers/media/video/saa7164/saa7164-bus.c +++ b/drivers/media/video/saa7164/saa7164-bus.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | int saa7164_bus_setup(struct saa7164_dev *dev) | 27 | int saa7164_bus_setup(struct saa7164_dev *dev) |
28 | { | 28 | { |
29 | tmComResBusInfo_t *b = &dev->bus; | 29 | struct tmComResBusInfo *b = &dev->bus; |
30 | 30 | ||
31 | mutex_init(&b->lock); | 31 | mutex_init(&b->lock); |
32 | 32 | ||
@@ -43,24 +43,18 @@ int saa7164_bus_setup(struct saa7164_dev *dev) | |||
43 | 43 | ||
44 | b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; | 44 | b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; |
45 | 45 | ||
46 | b->m_pdwSetWritePos = (u32 *)((u8 *)(dev->bmmio + | 46 | b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64)); |
47 | ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64)))); | 47 | b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32)); |
48 | 48 | ||
49 | b->m_pdwSetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos + | 49 | b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32)); |
50 | 1 * sizeof(u32)); | 50 | b->m_dwGetReadPos = b->m_dwSetWritePos + (3 * sizeof(u32)); |
51 | |||
52 | b->m_pdwGetWritePos = (u32 *)((u8 *)b->m_pdwSetWritePos + | ||
53 | 2 * sizeof(u32)); | ||
54 | |||
55 | b->m_pdwGetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos + | ||
56 | 3 * sizeof(u32)); | ||
57 | 51 | ||
58 | return 0; | 52 | return 0; |
59 | } | 53 | } |
60 | 54 | ||
61 | void saa7164_bus_dump(struct saa7164_dev *dev) | 55 | void saa7164_bus_dump(struct saa7164_dev *dev) |
62 | { | 56 | { |
63 | tmComResBusInfo_t *b = &dev->bus; | 57 | struct tmComResBusInfo *b = &dev->bus; |
64 | 58 | ||
65 | dprintk(DBGLVL_BUS, "Dumping the bus structure:\n"); | 59 | dprintk(DBGLVL_BUS, "Dumping the bus structure:\n"); |
66 | dprintk(DBGLVL_BUS, " .type = %d\n", b->Type); | 60 | dprintk(DBGLVL_BUS, " .type = %d\n", b->Type); |
@@ -71,20 +65,47 @@ void saa7164_bus_dump(struct saa7164_dev *dev) | |||
71 | dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing); | 65 | dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing); |
72 | dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing); | 66 | dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing); |
73 | 67 | ||
74 | dprintk(DBGLVL_BUS, " .m_pdwSetWritePos = 0x%p (0x%08x)\n", | 68 | dprintk(DBGLVL_BUS, " .m_dwSetReadPos = 0x%x (0x%08x)\n", |
75 | b->m_pdwSetWritePos, *b->m_pdwSetWritePos); | 69 | b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos)); |
70 | |||
71 | dprintk(DBGLVL_BUS, " .m_dwSetWritePos = 0x%x (0x%08x)\n", | ||
72 | b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos)); | ||
73 | |||
74 | dprintk(DBGLVL_BUS, " .m_dwGetReadPos = 0x%x (0x%08x)\n", | ||
75 | b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos)); | ||
76 | |||
77 | dprintk(DBGLVL_BUS, " .m_dwGetWritePos = 0x%x (0x%08x)\n", | ||
78 | b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos)); | ||
79 | |||
80 | } | ||
81 | |||
82 | /* Intensionally throw a BUG() if the state of the message bus looks corrupt */ | ||
83 | void saa7164_bus_verify(struct saa7164_dev *dev) | ||
84 | { | ||
85 | struct tmComResBusInfo *b = &dev->bus; | ||
86 | int bug = 0; | ||
76 | 87 | ||
77 | dprintk(DBGLVL_BUS, " .m_pdwSetReadPos = 0x%p (0x%08x)\n", | 88 | if (saa7164_readl(b->m_dwSetReadPos) > b->m_dwSizeSetRing) |
78 | b->m_pdwSetReadPos, *b->m_pdwSetReadPos); | 89 | bug++; |
79 | 90 | ||
80 | dprintk(DBGLVL_BUS, " .m_pdwGetWritePos = 0x%p (0x%08x)\n", | 91 | if (saa7164_readl(b->m_dwSetWritePos) > b->m_dwSizeSetRing) |
81 | b->m_pdwGetWritePos, *b->m_pdwGetWritePos); | 92 | bug++; |
82 | 93 | ||
83 | dprintk(DBGLVL_BUS, " .m_pdwGetReadPos = 0x%p (0x%08x)\n", | 94 | if (saa7164_readl(b->m_dwGetReadPos) > b->m_dwSizeGetRing) |
84 | b->m_pdwGetReadPos, *b->m_pdwGetReadPos); | 95 | bug++; |
96 | |||
97 | if (saa7164_readl(b->m_dwGetWritePos) > b->m_dwSizeGetRing) | ||
98 | bug++; | ||
99 | |||
100 | if (bug) { | ||
101 | saa_debug = 0xffff; /* Ensure we get the bus dump */ | ||
102 | saa7164_bus_dump(dev); | ||
103 | saa_debug = 1024; /* Ensure we get the bus dump */ | ||
104 | BUG(); | ||
105 | } | ||
85 | } | 106 | } |
86 | 107 | ||
87 | void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf) | 108 | void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void *buf) |
88 | { | 109 | { |
89 | dprintk(DBGLVL_BUS, "Dumping msg structure:\n"); | 110 | dprintk(DBGLVL_BUS, "Dumping msg structure:\n"); |
90 | dprintk(DBGLVL_BUS, " .id = %d\n", m->id); | 111 | dprintk(DBGLVL_BUS, " .id = %d\n", m->id); |
@@ -100,7 +121,7 @@ void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf) | |||
100 | /* | 121 | /* |
101 | * Places a command or a response on the bus. The implementation does not | 122 | * Places a command or a response on the bus. The implementation does not |
102 | * know if it is a command or a response it just places the data on the | 123 | * know if it is a command or a response it just places the data on the |
103 | * bus depending on the bus information given in the tmComResBusInfo_t | 124 | * bus depending on the bus information given in the struct tmComResBusInfo |
104 | * structure. If the command or response does not fit into the bus ring | 125 | * structure. If the command or response does not fit into the bus ring |
105 | * buffer it will be refused. | 126 | * buffer it will be refused. |
106 | * | 127 | * |
@@ -108,10 +129,10 @@ void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf) | |||
108 | * SAA_OK The function executed successfully. | 129 | * SAA_OK The function executed successfully. |
109 | * < 0 One or more members are not initialized. | 130 | * < 0 One or more members are not initialized. |
110 | */ | 131 | */ |
111 | int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf) | 132 | int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf) |
112 | { | 133 | { |
113 | tmComResBusInfo_t *bus = &dev->bus; | 134 | struct tmComResBusInfo *bus = &dev->bus; |
114 | u32 bytes_to_write, read_distance, timeout, curr_srp, curr_swp; | 135 | u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; |
115 | u32 new_swp, space_rem; | 136 | u32 new_swp, space_rem; |
116 | int ret = SAA_ERR_BAD_PARAMETER; | 137 | int ret = SAA_ERR_BAD_PARAMETER; |
117 | 138 | ||
@@ -122,6 +143,8 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf) | |||
122 | 143 | ||
123 | dprintk(DBGLVL_BUS, "%s()\n", __func__); | 144 | dprintk(DBGLVL_BUS, "%s()\n", __func__); |
124 | 145 | ||
146 | saa7164_bus_verify(dev); | ||
147 | |||
125 | msg->size = cpu_to_le16(msg->size); | 148 | msg->size = cpu_to_le16(msg->size); |
126 | msg->command = cpu_to_le16(msg->command); | 149 | msg->command = cpu_to_le16(msg->command); |
127 | msg->controlselector = cpu_to_le16(msg->controlselector); | 150 | msg->controlselector = cpu_to_le16(msg->controlselector); |
@@ -141,30 +164,30 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf) | |||
141 | mutex_lock(&bus->lock); | 164 | mutex_lock(&bus->lock); |
142 | 165 | ||
143 | bytes_to_write = sizeof(*msg) + msg->size; | 166 | bytes_to_write = sizeof(*msg) + msg->size; |
144 | read_distance = 0; | 167 | free_write_space = 0; |
145 | timeout = SAA_BUS_TIMEOUT; | 168 | timeout = SAA_BUS_TIMEOUT; |
146 | curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos); | 169 | curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); |
147 | curr_swp = le32_to_cpu(*bus->m_pdwSetWritePos); | 170 | curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos)); |
148 | 171 | ||
149 | /* Deal with ring wrapping issues */ | 172 | /* Deal with ring wrapping issues */ |
150 | if (curr_srp > curr_swp) | 173 | if (curr_srp > curr_swp) |
151 | /* The ring has not wrapped yet */ | ||
152 | read_distance = curr_srp - curr_swp; | ||
153 | else | ||
154 | /* Deal with the wrapped ring */ | 174 | /* Deal with the wrapped ring */ |
155 | read_distance = (curr_srp + bus->m_dwSizeSetRing) - curr_swp; | 175 | free_write_space = curr_srp - curr_swp; |
176 | else | ||
177 | /* The ring has not wrapped yet */ | ||
178 | free_write_space = (curr_srp + bus->m_dwSizeSetRing) - curr_swp; | ||
156 | 179 | ||
157 | dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__, | 180 | dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__, |
158 | bytes_to_write); | 181 | bytes_to_write); |
159 | 182 | ||
160 | dprintk(DBGLVL_BUS, "%s() read_distance = %d\n", __func__, | 183 | dprintk(DBGLVL_BUS, "%s() free_write_space = %d\n", __func__, |
161 | read_distance); | 184 | free_write_space); |
162 | 185 | ||
163 | dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp); | 186 | dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp); |
164 | dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp); | 187 | dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp); |
165 | 188 | ||
166 | /* Process the msg and write the content onto the bus */ | 189 | /* Process the msg and write the content onto the bus */ |
167 | while (bytes_to_write >= read_distance) { | 190 | while (bytes_to_write >= free_write_space) { |
168 | 191 | ||
169 | if (timeout-- == 0) { | 192 | if (timeout-- == 0) { |
170 | printk(KERN_ERR "%s() bus timeout\n", __func__); | 193 | printk(KERN_ERR "%s() bus timeout\n", __func__); |
@@ -177,15 +200,15 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf) | |||
177 | mdelay(1); | 200 | mdelay(1); |
178 | 201 | ||
179 | /* Check the space usage again */ | 202 | /* Check the space usage again */ |
180 | curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos); | 203 | curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); |
181 | 204 | ||
182 | /* Deal with ring wrapping issues */ | 205 | /* Deal with ring wrapping issues */ |
183 | if (curr_srp > curr_swp) | 206 | if (curr_srp > curr_swp) |
184 | /* Read didn't wrap around the buffer */ | ||
185 | read_distance = curr_srp - curr_swp; | ||
186 | else | ||
187 | /* Deal with the wrapped ring */ | 207 | /* Deal with the wrapped ring */ |
188 | read_distance = (curr_srp + bus->m_dwSizeSetRing) - | 208 | free_write_space = curr_srp - curr_swp; |
209 | else | ||
210 | /* Read didn't wrap around the buffer */ | ||
211 | free_write_space = (curr_srp + bus->m_dwSizeSetRing) - | ||
189 | curr_swp; | 212 | curr_swp; |
190 | 213 | ||
191 | } | 214 | } |
@@ -257,37 +280,37 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf) | |||
257 | 280 | ||
258 | dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp); | 281 | dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp); |
259 | 282 | ||
260 | /* TODO: Convert all of the direct PCI writes into | ||
261 | * saa7164_writel/b calls for consistency. | ||
262 | */ | ||
263 | |||
264 | /* Update the bus write position */ | 283 | /* Update the bus write position */ |
265 | *bus->m_pdwSetWritePos = cpu_to_le32(new_swp); | 284 | saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp)); |
266 | ret = SAA_OK; | 285 | ret = SAA_OK; |
267 | 286 | ||
268 | out: | 287 | out: |
288 | saa7164_bus_dump(dev); | ||
269 | mutex_unlock(&bus->lock); | 289 | mutex_unlock(&bus->lock); |
290 | saa7164_bus_verify(dev); | ||
270 | return ret; | 291 | return ret; |
271 | } | 292 | } |
272 | 293 | ||
273 | /* | 294 | /* |
274 | * Receive a command or a response from the bus. The implementation does not | 295 | * Receive a command or a response from the bus. The implementation does not |
275 | * know if it is a command or a response it simply dequeues the data, | 296 | * know if it is a command or a response it simply dequeues the data, |
276 | * depending on the bus information given in the tmComResBusInfo_t structure. | 297 | * depending on the bus information given in the struct tmComResBusInfo structure. |
277 | * | 298 | * |
278 | * Return Value: | 299 | * Return Value: |
279 | * 0 The function executed successfully. | 300 | * 0 The function executed successfully. |
280 | * < 0 One or more members are not initialized. | 301 | * < 0 One or more members are not initialized. |
281 | */ | 302 | */ |
282 | int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf, | 303 | int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf, |
283 | int peekonly) | 304 | int peekonly) |
284 | { | 305 | { |
285 | tmComResBusInfo_t *bus = &dev->bus; | 306 | struct tmComResBusInfo *bus = &dev->bus; |
286 | u32 bytes_to_read, write_distance, curr_grp, curr_gwp, | 307 | u32 bytes_to_read, write_distance, curr_grp, curr_gwp, |
287 | new_grp, buf_size, space_rem; | 308 | new_grp, buf_size, space_rem; |
288 | tmComResInfo_t msg_tmp; | 309 | struct tmComResInfo msg_tmp; |
289 | int ret = SAA_ERR_BAD_PARAMETER; | 310 | int ret = SAA_ERR_BAD_PARAMETER; |
290 | 311 | ||
312 | saa7164_bus_verify(dev); | ||
313 | |||
291 | if (msg == 0) | 314 | if (msg == 0) |
292 | return ret; | 315 | return ret; |
293 | 316 | ||
@@ -309,11 +332,10 @@ int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf, | |||
309 | /* Peek the bus to see if a msg exists, if it's not what we're expecting | 332 | /* Peek the bus to see if a msg exists, if it's not what we're expecting |
310 | * then return cleanly else read the message from the bus. | 333 | * then return cleanly else read the message from the bus. |
311 | */ | 334 | */ |
312 | curr_gwp = le32_to_cpu(*bus->m_pdwGetWritePos); | 335 | curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos)); |
313 | curr_grp = le32_to_cpu(*bus->m_pdwGetReadPos); | 336 | curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos)); |
314 | 337 | ||
315 | if (curr_gwp == curr_grp) { | 338 | if (curr_gwp == curr_grp) { |
316 | dprintk(DBGLVL_BUS, "%s() No message on the bus\n", __func__); | ||
317 | ret = SAA_ERR_EMPTY; | 339 | ret = SAA_ERR_EMPTY; |
318 | goto out; | 340 | goto out; |
319 | } | 341 | } |
@@ -434,7 +456,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf, | |||
434 | } | 456 | } |
435 | 457 | ||
436 | /* Update the read positions, adjusting the ring */ | 458 | /* Update the read positions, adjusting the ring */ |
437 | *bus->m_pdwGetReadPos = cpu_to_le32(new_grp); | 459 | saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp)); |
438 | 460 | ||
439 | peekout: | 461 | peekout: |
440 | msg->size = le16_to_cpu(msg->size); | 462 | msg->size = le16_to_cpu(msg->size); |
@@ -443,6 +465,7 @@ peekout: | |||
443 | ret = SAA_OK; | 465 | ret = SAA_OK; |
444 | out: | 466 | out: |
445 | mutex_unlock(&bus->lock); | 467 | mutex_unlock(&bus->lock); |
468 | saa7164_bus_verify(dev); | ||
446 | return ret; | 469 | return ret; |
447 | } | 470 | } |
448 | 471 | ||
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c index a3c299405f4..4cb634e952a 100644 --- a/drivers/media/video/saa7164/saa7164-cards.c +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -55,6 +55,10 @@ struct saa7164_board saa7164_boards[] = { | |||
55 | .name = "Hauppauge WinTV-HVR2200", | 55 | .name = "Hauppauge WinTV-HVR2200", |
56 | .porta = SAA7164_MPEG_DVB, | 56 | .porta = SAA7164_MPEG_DVB, |
57 | .portb = SAA7164_MPEG_DVB, | 57 | .portb = SAA7164_MPEG_DVB, |
58 | .portc = SAA7164_MPEG_ENCODER, | ||
59 | .portd = SAA7164_MPEG_ENCODER, | ||
60 | .porte = SAA7164_MPEG_VBI, | ||
61 | .portf = SAA7164_MPEG_VBI, | ||
58 | .chiprev = SAA7164_CHIP_REV3, | 62 | .chiprev = SAA7164_CHIP_REV3, |
59 | .unit = {{ | 63 | .unit = {{ |
60 | .id = 0x1d, | 64 | .id = 0x1d, |
@@ -97,6 +101,10 @@ struct saa7164_board saa7164_boards[] = { | |||
97 | .name = "Hauppauge WinTV-HVR2200", | 101 | .name = "Hauppauge WinTV-HVR2200", |
98 | .porta = SAA7164_MPEG_DVB, | 102 | .porta = SAA7164_MPEG_DVB, |
99 | .portb = SAA7164_MPEG_DVB, | 103 | .portb = SAA7164_MPEG_DVB, |
104 | .portc = SAA7164_MPEG_ENCODER, | ||
105 | .portd = SAA7164_MPEG_ENCODER, | ||
106 | .porte = SAA7164_MPEG_VBI, | ||
107 | .portf = SAA7164_MPEG_VBI, | ||
100 | .chiprev = SAA7164_CHIP_REV2, | 108 | .chiprev = SAA7164_CHIP_REV2, |
101 | .unit = {{ | 109 | .unit = {{ |
102 | .id = 0x06, | 110 | .id = 0x06, |
@@ -139,6 +147,10 @@ struct saa7164_board saa7164_boards[] = { | |||
139 | .name = "Hauppauge WinTV-HVR2200", | 147 | .name = "Hauppauge WinTV-HVR2200", |
140 | .porta = SAA7164_MPEG_DVB, | 148 | .porta = SAA7164_MPEG_DVB, |
141 | .portb = SAA7164_MPEG_DVB, | 149 | .portb = SAA7164_MPEG_DVB, |
150 | .portc = SAA7164_MPEG_ENCODER, | ||
151 | .portd = SAA7164_MPEG_ENCODER, | ||
152 | .porte = SAA7164_MPEG_VBI, | ||
153 | .portf = SAA7164_MPEG_VBI, | ||
142 | .chiprev = SAA7164_CHIP_REV2, | 154 | .chiprev = SAA7164_CHIP_REV2, |
143 | .unit = {{ | 155 | .unit = {{ |
144 | .id = 0x1d, | 156 | .id = 0x1d, |
@@ -195,6 +207,12 @@ struct saa7164_board saa7164_boards[] = { | |||
195 | .name = "Hauppauge WinTV-HVR2250", | 207 | .name = "Hauppauge WinTV-HVR2250", |
196 | .porta = SAA7164_MPEG_DVB, | 208 | .porta = SAA7164_MPEG_DVB, |
197 | .portb = SAA7164_MPEG_DVB, | 209 | .portb = SAA7164_MPEG_DVB, |
210 | .portc = SAA7164_MPEG_ENCODER, | ||
211 | .portd = SAA7164_MPEG_ENCODER, | ||
212 | .portc = SAA7164_MPEG_ENCODER, | ||
213 | .portd = SAA7164_MPEG_ENCODER, | ||
214 | .porte = SAA7164_MPEG_VBI, | ||
215 | .portf = SAA7164_MPEG_VBI, | ||
198 | .chiprev = SAA7164_CHIP_REV3, | 216 | .chiprev = SAA7164_CHIP_REV3, |
199 | .unit = {{ | 217 | .unit = {{ |
200 | .id = 0x22, | 218 | .id = 0x22, |
@@ -251,6 +269,12 @@ struct saa7164_board saa7164_boards[] = { | |||
251 | .name = "Hauppauge WinTV-HVR2250", | 269 | .name = "Hauppauge WinTV-HVR2250", |
252 | .porta = SAA7164_MPEG_DVB, | 270 | .porta = SAA7164_MPEG_DVB, |
253 | .portb = SAA7164_MPEG_DVB, | 271 | .portb = SAA7164_MPEG_DVB, |
272 | .portc = SAA7164_MPEG_ENCODER, | ||
273 | .portd = SAA7164_MPEG_ENCODER, | ||
274 | .porte = SAA7164_MPEG_VBI, | ||
275 | .portf = SAA7164_MPEG_VBI, | ||
276 | .porte = SAA7164_MPEG_VBI, | ||
277 | .portf = SAA7164_MPEG_VBI, | ||
254 | .chiprev = SAA7164_CHIP_REV3, | 278 | .chiprev = SAA7164_CHIP_REV3, |
255 | .unit = {{ | 279 | .unit = {{ |
256 | .id = 0x28, | 280 | .id = 0x28, |
@@ -307,6 +331,10 @@ struct saa7164_board saa7164_boards[] = { | |||
307 | .name = "Hauppauge WinTV-HVR2250", | 331 | .name = "Hauppauge WinTV-HVR2250", |
308 | .porta = SAA7164_MPEG_DVB, | 332 | .porta = SAA7164_MPEG_DVB, |
309 | .portb = SAA7164_MPEG_DVB, | 333 | .portb = SAA7164_MPEG_DVB, |
334 | .portc = SAA7164_MPEG_ENCODER, | ||
335 | .portd = SAA7164_MPEG_ENCODER, | ||
336 | .porte = SAA7164_MPEG_VBI, | ||
337 | .portf = SAA7164_MPEG_VBI, | ||
310 | .chiprev = SAA7164_CHIP_REV3, | 338 | .chiprev = SAA7164_CHIP_REV3, |
311 | .unit = {{ | 339 | .unit = {{ |
312 | .id = 0x26, | 340 | .id = 0x26, |
@@ -437,8 +465,6 @@ void saa7164_card_list(struct saa7164_dev *dev) | |||
437 | 465 | ||
438 | void saa7164_gpio_setup(struct saa7164_dev *dev) | 466 | void saa7164_gpio_setup(struct saa7164_dev *dev) |
439 | { | 467 | { |
440 | |||
441 | |||
442 | switch (dev->board) { | 468 | switch (dev->board) { |
443 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | 469 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: |
444 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | 470 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: |
@@ -462,7 +488,6 @@ void saa7164_gpio_setup(struct saa7164_dev *dev) | |||
462 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | 488 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); |
463 | break; | 489 | break; |
464 | } | 490 | } |
465 | |||
466 | } | 491 | } |
467 | 492 | ||
468 | static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) | 493 | static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) |
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c index 9c1d3ac4386..301a9e302f4 100644 --- a/drivers/media/video/saa7164/saa7164-cmd.c +++ b/drivers/media/video/saa7164/saa7164-cmd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -82,16 +82,17 @@ u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno) | |||
82 | * -bus/c running buffer. */ | 82 | * -bus/c running buffer. */ |
83 | int saa7164_irq_dequeue(struct saa7164_dev *dev) | 83 | int saa7164_irq_dequeue(struct saa7164_dev *dev) |
84 | { | 84 | { |
85 | int ret = SAA_OK; | 85 | int ret = SAA_OK, i = 0; |
86 | u32 timeout; | 86 | u32 timeout; |
87 | wait_queue_head_t *q = 0; | 87 | wait_queue_head_t *q = 0; |
88 | u8 tmp[512]; | ||
88 | dprintk(DBGLVL_CMD, "%s()\n", __func__); | 89 | dprintk(DBGLVL_CMD, "%s()\n", __func__); |
89 | 90 | ||
90 | /* While any outstand message on the bus exists... */ | 91 | /* While any outstand message on the bus exists... */ |
91 | do { | 92 | do { |
92 | 93 | ||
93 | /* Peek the msg bus */ | 94 | /* Peek the msg bus */ |
94 | tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 }; | 95 | struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 }; |
95 | ret = saa7164_bus_get(dev, &tRsp, NULL, 1); | 96 | ret = saa7164_bus_get(dev, &tRsp, NULL, 1); |
96 | if (ret != SAA_OK) | 97 | if (ret != SAA_OK) |
97 | break; | 98 | break; |
@@ -109,8 +110,22 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev) | |||
109 | printk(KERN_ERR | 110 | printk(KERN_ERR |
110 | "%s() found timed out command on the bus\n", | 111 | "%s() found timed out command on the bus\n", |
111 | __func__); | 112 | __func__); |
113 | |||
114 | /* Clean the bus */ | ||
115 | ret = saa7164_bus_get(dev, &tRsp, &tmp, 0); | ||
116 | printk(KERN_ERR "%s() ret = %x\n", __func__, ret); | ||
117 | if (ret == SAA_ERR_EMPTY) | ||
118 | /* Someone else already fetched the response */ | ||
119 | return SAA_OK; | ||
120 | |||
121 | if (ret != SAA_OK) | ||
122 | return ret; | ||
112 | } | 123 | } |
113 | } while (0); | 124 | |
125 | /* It's unlikely to have more than 4 or 5 pending messages, ensure we exit | ||
126 | * at some point regardles. | ||
127 | */ | ||
128 | } while (i++ < 32); | ||
114 | 129 | ||
115 | return ret; | 130 | return ret; |
116 | } | 131 | } |
@@ -128,7 +143,7 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev) | |||
128 | 143 | ||
129 | while (loop) { | 144 | while (loop) { |
130 | 145 | ||
131 | tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 }; | 146 | struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 }; |
132 | ret = saa7164_bus_get(dev, &tRsp, NULL, 1); | 147 | ret = saa7164_bus_get(dev, &tRsp, NULL, 1); |
133 | if (ret == SAA_ERR_EMPTY) | 148 | if (ret == SAA_ERR_EMPTY) |
134 | return SAA_OK; | 149 | return SAA_OK; |
@@ -171,9 +186,9 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev) | |||
171 | return SAA_OK; | 186 | return SAA_OK; |
172 | } | 187 | } |
173 | 188 | ||
174 | int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf) | 189 | int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf) |
175 | { | 190 | { |
176 | tmComResBusInfo_t *bus = &dev->bus; | 191 | struct tmComResBusInfo *bus = &dev->bus; |
177 | u8 cmd_sent; | 192 | u8 cmd_sent; |
178 | u16 size, idx; | 193 | u16 size, idx; |
179 | u32 cmds; | 194 | u32 cmds; |
@@ -324,11 +339,11 @@ void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno) | |||
324 | mutex_unlock(&dev->lock); | 339 | mutex_unlock(&dev->lock); |
325 | } | 340 | } |
326 | 341 | ||
327 | int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command, | 342 | int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command, |
328 | u16 controlselector, u16 size, void *buf) | 343 | u16 controlselector, u16 size, void *buf) |
329 | { | 344 | { |
330 | tmComResInfo_t command_t, *pcommand_t; | 345 | struct tmComResInfo command_t, *pcommand_t; |
331 | tmComResInfo_t response_t, *presponse_t; | 346 | struct tmComResInfo response_t, *presponse_t; |
332 | u8 errdata[256]; | 347 | u8 errdata[256]; |
333 | u16 resp_dsize; | 348 | u16 resp_dsize; |
334 | u16 data_recd; | 349 | u16 data_recd; |
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index e6aa0fbd1e9..e1bac505146 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -30,6 +30,9 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
32 | 32 | ||
33 | #ifdef CONFIG_PROC_FS | ||
34 | #include <linux/proc_fs.h> | ||
35 | #endif | ||
33 | #include "saa7164.h" | 36 | #include "saa7164.h" |
34 | 37 | ||
35 | MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards"); | 38 | MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards"); |
@@ -49,14 +52,38 @@ unsigned int saa_debug; | |||
49 | module_param_named(debug, saa_debug, int, 0644); | 52 | module_param_named(debug, saa_debug, int, 0644); |
50 | MODULE_PARM_DESC(debug, "enable debug messages"); | 53 | MODULE_PARM_DESC(debug, "enable debug messages"); |
51 | 54 | ||
55 | unsigned int fw_debug; | ||
56 | module_param(fw_debug, int, 0644); | ||
57 | MODULE_PARM_DESC(fw_debug, "Firware debug level def:2"); | ||
58 | |||
59 | unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS; | ||
60 | module_param(encoder_buffers, int, 0644); | ||
61 | MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64"); | ||
62 | |||
63 | unsigned int vbi_buffers = SAA7164_MAX_VBI_BUFFERS; | ||
64 | module_param(vbi_buffers, int, 0644); | ||
65 | MODULE_PARM_DESC(vbi_buffers, "Total buffers in read queue 16-512 def:64"); | ||
66 | |||
52 | unsigned int waitsecs = 10; | 67 | unsigned int waitsecs = 10; |
53 | module_param(waitsecs, int, 0644); | 68 | module_param(waitsecs, int, 0644); |
54 | MODULE_PARM_DESC(debug, "timeout on firmware messages"); | 69 | MODULE_PARM_DESC(waitsecs, "timeout on firmware messages"); |
55 | 70 | ||
56 | static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET }; | 71 | static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET }; |
57 | module_param_array(card, int, NULL, 0444); | 72 | module_param_array(card, int, NULL, 0444); |
58 | MODULE_PARM_DESC(card, "card type"); | 73 | MODULE_PARM_DESC(card, "card type"); |
59 | 74 | ||
75 | unsigned int print_histogram = 64; | ||
76 | module_param(print_histogram, int, 0644); | ||
77 | MODULE_PARM_DESC(print_histogram, "print histogram values once"); | ||
78 | |||
79 | unsigned int crc_checking = 1; | ||
80 | module_param(crc_checking, int, 0644); | ||
81 | MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers"); | ||
82 | |||
83 | unsigned int guard_checking = 1; | ||
84 | module_param(guard_checking, int, 0644); | ||
85 | MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns"); | ||
86 | |||
60 | static unsigned int saa7164_devcount; | 87 | static unsigned int saa7164_devcount; |
61 | 88 | ||
62 | static DEFINE_MUTEX(devlist); | 89 | static DEFINE_MUTEX(devlist); |
@@ -64,6 +91,444 @@ LIST_HEAD(saa7164_devlist); | |||
64 | 91 | ||
65 | #define INT_SIZE 16 | 92 | #define INT_SIZE 16 |
66 | 93 | ||
94 | void saa7164_dumphex16FF(struct saa7164_dev *dev, u8 *buf, int len) | ||
95 | { | ||
96 | int i; | ||
97 | u8 tmp[16]; | ||
98 | memset(&tmp[0], 0xff, sizeof(tmp)); | ||
99 | |||
100 | printk(KERN_INFO "--------------------> " | ||
101 | "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); | ||
102 | |||
103 | for (i = 0; i < len; i += 16) { | ||
104 | if (memcmp(&tmp, buf + i, sizeof(tmp)) != 0) { | ||
105 | printk(KERN_INFO " [0x%08x] " | ||
106 | "%02x %02x %02x %02x %02x %02x %02x %02x " | ||
107 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", i, | ||
108 | *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3), | ||
109 | *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7), | ||
110 | *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11), | ||
111 | *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15)); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | static void saa7164_pack_verifier(struct saa7164_buffer *buf) | ||
117 | { | ||
118 | u8 *p = (u8 *)buf->cpu; | ||
119 | int i; | ||
120 | |||
121 | for (i = 0; i < buf->actual_size; i += 2048) { | ||
122 | |||
123 | if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) || | ||
124 | (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) { | ||
125 | printk(KERN_ERR "No pack at 0x%x\n", i); | ||
126 | // saa7164_dumphex16FF(buf->port->dev, (p + i), 32); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | #define FIXED_VIDEO_PID 0xf1 | ||
132 | #define FIXED_AUDIO_PID 0xf2 | ||
133 | |||
134 | static void saa7164_ts_verifier(struct saa7164_buffer *buf) | ||
135 | { | ||
136 | struct saa7164_port *port = buf->port; | ||
137 | u32 i; | ||
138 | u8 cc, a; | ||
139 | u16 pid; | ||
140 | u8 __iomem *bufcpu = (u8 *)buf->cpu; | ||
141 | |||
142 | port->sync_errors = 0; | ||
143 | port->v_cc_errors = 0; | ||
144 | port->a_cc_errors = 0; | ||
145 | |||
146 | for (i = 0; i < buf->actual_size; i += 188) { | ||
147 | if (*(bufcpu + i) != 0x47) | ||
148 | port->sync_errors++; | ||
149 | |||
150 | /* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */ | ||
151 | pid = ((*(bufcpu + i + 1) & 0x1f) << 8) | *(bufcpu + i + 2); | ||
152 | cc = *(bufcpu + i + 3) & 0x0f; | ||
153 | |||
154 | if (pid == FIXED_VIDEO_PID) { | ||
155 | a = ((port->last_v_cc + 1) & 0x0f); | ||
156 | if (a != cc) { | ||
157 | printk(KERN_ERR "video cc last = %x current = %x i = %d\n", | ||
158 | port->last_v_cc, cc, i); | ||
159 | port->v_cc_errors++; | ||
160 | } | ||
161 | |||
162 | port->last_v_cc = cc; | ||
163 | } else | ||
164 | if (pid == FIXED_AUDIO_PID) { | ||
165 | a = ((port->last_a_cc + 1) & 0x0f); | ||
166 | if (a != cc) { | ||
167 | printk(KERN_ERR "audio cc last = %x current = %x i = %d\n", | ||
168 | port->last_a_cc, cc, i); | ||
169 | port->a_cc_errors++; | ||
170 | } | ||
171 | |||
172 | port->last_a_cc = cc; | ||
173 | } | ||
174 | |||
175 | } | ||
176 | |||
177 | /* Only report errors if we've been through this function atleast | ||
178 | * once already and the cached cc values are primed. First time through | ||
179 | * always generates errors. | ||
180 | */ | ||
181 | if (port->v_cc_errors && (port->done_first_interrupt > 1)) | ||
182 | printk(KERN_ERR "video pid cc, %d errors\n", port->v_cc_errors); | ||
183 | |||
184 | if (port->a_cc_errors && (port->done_first_interrupt > 1)) | ||
185 | printk(KERN_ERR "audio pid cc, %d errors\n", port->a_cc_errors); | ||
186 | |||
187 | if (port->sync_errors && (port->done_first_interrupt > 1)) | ||
188 | printk(KERN_ERR "sync_errors = %d\n", port->sync_errors); | ||
189 | |||
190 | if (port->done_first_interrupt == 1) | ||
191 | port->done_first_interrupt++; | ||
192 | } | ||
193 | |||
194 | static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name) | ||
195 | { | ||
196 | int i; | ||
197 | |||
198 | memset(hg, 0, sizeof(struct saa7164_histogram)); | ||
199 | strcpy(hg->name, name); | ||
200 | |||
201 | /* First 30ms x 1ms */ | ||
202 | for (i = 0; i < 30; i++) { | ||
203 | hg->counter1[0 + i].val = i; | ||
204 | } | ||
205 | |||
206 | /* 30 - 200ms x 10ms */ | ||
207 | for (i = 0; i < 18; i++) { | ||
208 | hg->counter1[30 + i].val = 30 + (i * 10); | ||
209 | } | ||
210 | |||
211 | /* 200 - 2000ms x 100ms */ | ||
212 | for (i = 0; i < 15; i++) { | ||
213 | hg->counter1[48 + i].val = 200 + (i * 200); | ||
214 | } | ||
215 | |||
216 | /* Catch all massive value (2secs) */ | ||
217 | hg->counter1[55].val = 2000; | ||
218 | |||
219 | /* Catch all massive value (4secs) */ | ||
220 | hg->counter1[56].val = 4000; | ||
221 | |||
222 | /* Catch all massive value (8secs) */ | ||
223 | hg->counter1[57].val = 8000; | ||
224 | |||
225 | /* Catch all massive value (15secs) */ | ||
226 | hg->counter1[58].val = 15000; | ||
227 | |||
228 | /* Catch all massive value (30secs) */ | ||
229 | hg->counter1[59].val = 30000; | ||
230 | |||
231 | /* Catch all massive value (60secs) */ | ||
232 | hg->counter1[60].val = 60000; | ||
233 | |||
234 | /* Catch all massive value (5mins) */ | ||
235 | hg->counter1[61].val = 300000; | ||
236 | |||
237 | /* Catch all massive value (15mins) */ | ||
238 | hg->counter1[62].val = 900000; | ||
239 | |||
240 | /* Catch all massive values (1hr) */ | ||
241 | hg->counter1[63].val = 3600000; | ||
242 | } | ||
243 | |||
244 | void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val) | ||
245 | { | ||
246 | int i; | ||
247 | for (i = 0; i < 64; i++) { | ||
248 | if (val <= hg->counter1[i].val) { | ||
249 | hg->counter1[i].count++; | ||
250 | hg->counter1[i].update_time = jiffies; | ||
251 | break; | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
256 | static void saa7164_histogram_print(struct saa7164_port *port, | ||
257 | struct saa7164_histogram *hg) | ||
258 | { | ||
259 | u32 entries = 0; | ||
260 | int i; | ||
261 | |||
262 | printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name); | ||
263 | for (i = 0; i < 64; i++) { | ||
264 | if (hg->counter1[i].count == 0) | ||
265 | continue; | ||
266 | |||
267 | printk(KERN_ERR " %4d %12d %Ld\n", | ||
268 | hg->counter1[i].val, | ||
269 | hg->counter1[i].count, | ||
270 | hg->counter1[i].update_time); | ||
271 | |||
272 | entries++; | ||
273 | } | ||
274 | printk(KERN_ERR "Total: %d\n", entries); | ||
275 | } | ||
276 | |||
277 | static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) | ||
278 | { | ||
279 | struct saa7164_dev *dev = port->dev; | ||
280 | struct saa7164_buffer *buf = 0; | ||
281 | struct saa7164_user_buffer *ubuf = 0; | ||
282 | struct list_head *c, *n; | ||
283 | int i = 0; | ||
284 | u8 __iomem *p; | ||
285 | |||
286 | mutex_lock(&port->dmaqueue_lock); | ||
287 | list_for_each_safe(c, n, &port->dmaqueue.list) { | ||
288 | |||
289 | buf = list_entry(c, struct saa7164_buffer, list); | ||
290 | if (i++ > port->hwcfg.buffercount) { | ||
291 | printk(KERN_ERR "%s() illegal i count %d\n", | ||
292 | __func__, i); | ||
293 | break; | ||
294 | } | ||
295 | |||
296 | if (buf->idx == bufnr) { | ||
297 | |||
298 | /* Found the buffer, deal with it */ | ||
299 | dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr); | ||
300 | |||
301 | if (crc_checking) { | ||
302 | /* Throw a new checksum on the dma buffer */ | ||
303 | buf->crc = crc32(0, buf->cpu, buf->actual_size); | ||
304 | } | ||
305 | |||
306 | if (guard_checking) { | ||
307 | p = (u8 *)buf->cpu; | ||
308 | if ((*(p + buf->actual_size + 0) != 0xff) || | ||
309 | (*(p + buf->actual_size + 1) != 0xff) || | ||
310 | (*(p + buf->actual_size + 2) != 0xff) || | ||
311 | (*(p + buf->actual_size + 3) != 0xff) || | ||
312 | (*(p + buf->actual_size + 0x10) != 0xff) || | ||
313 | (*(p + buf->actual_size + 0x11) != 0xff) || | ||
314 | (*(p + buf->actual_size + 0x12) != 0xff) || | ||
315 | (*(p + buf->actual_size + 0x13) != 0xff)) { | ||
316 | printk(KERN_ERR "%s() buf %p guard buffer breach\n", | ||
317 | __func__, buf); | ||
318 | // saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | if ((port->nr != SAA7164_PORT_VBI1) && (port->nr != SAA7164_PORT_VBI2)) { | ||
323 | /* Validate the incoming buffer content */ | ||
324 | if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) | ||
325 | saa7164_ts_verifier(buf); | ||
326 | else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) | ||
327 | saa7164_pack_verifier(buf); | ||
328 | } | ||
329 | |||
330 | /* find a free user buffer and clone to it */ | ||
331 | if (!list_empty(&port->list_buf_free.list)) { | ||
332 | |||
333 | /* Pull the first buffer from the used list */ | ||
334 | ubuf = list_first_entry(&port->list_buf_free.list, | ||
335 | struct saa7164_user_buffer, list); | ||
336 | |||
337 | if (buf->actual_size <= ubuf->actual_size) { | ||
338 | |||
339 | memcpy_fromio(ubuf->data, buf->cpu, | ||
340 | ubuf->actual_size); | ||
341 | |||
342 | if (crc_checking) { | ||
343 | /* Throw a new checksum on the read buffer */ | ||
344 | ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size); | ||
345 | } | ||
346 | |||
347 | /* Requeue the buffer on the free list */ | ||
348 | ubuf->pos = 0; | ||
349 | |||
350 | list_move_tail(&ubuf->list, | ||
351 | &port->list_buf_used.list); | ||
352 | |||
353 | /* Flag any userland waiters */ | ||
354 | wake_up_interruptible(&port->wait_read); | ||
355 | |||
356 | } else { | ||
357 | printk(KERN_ERR "buf %p bufsize fails match\n", buf); | ||
358 | } | ||
359 | |||
360 | } else | ||
361 | printk(KERN_ERR "encirq no free buffers, increase param encoder_buffers\n"); | ||
362 | |||
363 | /* Ensure offset into buffer remains 0, fill buffer | ||
364 | * with known bad data. We check for this data at a later point | ||
365 | * in time. */ | ||
366 | saa7164_buffer_zero_offsets(port, bufnr); | ||
367 | memset_io(buf->cpu, 0xff, buf->pci_size); | ||
368 | if (crc_checking) { | ||
369 | /* Throw yet aanother new checksum on the dma buffer */ | ||
370 | buf->crc = crc32(0, buf->cpu, buf->actual_size); | ||
371 | } | ||
372 | |||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | mutex_unlock(&port->dmaqueue_lock); | ||
377 | } | ||
378 | |||
379 | static void saa7164_work_enchandler(struct work_struct *w) | ||
380 | { | ||
381 | struct saa7164_port *port = | ||
382 | container_of(w, struct saa7164_port, workenc); | ||
383 | struct saa7164_dev *dev = port->dev; | ||
384 | |||
385 | u32 wp, mcb, rp, cnt = 0; | ||
386 | |||
387 | port->last_svc_msecs_diff = port->last_svc_msecs; | ||
388 | port->last_svc_msecs = jiffies_to_msecs(jiffies); | ||
389 | |||
390 | port->last_svc_msecs_diff = port->last_svc_msecs - | ||
391 | port->last_svc_msecs_diff; | ||
392 | |||
393 | saa7164_histogram_update(&port->svc_interval, | ||
394 | port->last_svc_msecs_diff); | ||
395 | |||
396 | port->last_irq_svc_msecs_diff = port->last_svc_msecs - | ||
397 | port->last_irq_msecs; | ||
398 | |||
399 | saa7164_histogram_update(&port->irq_svc_interval, | ||
400 | port->last_irq_svc_msecs_diff); | ||
401 | |||
402 | dprintk(DBGLVL_IRQ, | ||
403 | "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n", | ||
404 | __func__, | ||
405 | port->last_svc_msecs_diff, | ||
406 | port->last_irq_svc_msecs_diff, | ||
407 | port->last_svc_wp, | ||
408 | port->last_svc_rp | ||
409 | ); | ||
410 | |||
411 | /* Current write position */ | ||
412 | wp = saa7164_readl(port->bufcounter); | ||
413 | if (wp > (port->hwcfg.buffercount - 1)) { | ||
414 | printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp); | ||
415 | return; | ||
416 | } | ||
417 | |||
418 | /* Most current complete buffer */ | ||
419 | if (wp == 0) | ||
420 | mcb = (port->hwcfg.buffercount - 1); | ||
421 | else | ||
422 | mcb = wp - 1; | ||
423 | |||
424 | while (1) { | ||
425 | if (port->done_first_interrupt == 0) { | ||
426 | port->done_first_interrupt++; | ||
427 | rp = mcb; | ||
428 | } else | ||
429 | rp = (port->last_svc_rp + 1) % 8; | ||
430 | |||
431 | if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) { | ||
432 | printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp); | ||
433 | break; | ||
434 | } | ||
435 | |||
436 | saa7164_work_enchandler_helper(port, rp); | ||
437 | port->last_svc_rp = rp; | ||
438 | cnt++; | ||
439 | |||
440 | if (rp == mcb) | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | /* TODO: Convert this into a /proc/saa7164 style readable file */ | ||
445 | if (print_histogram == port->nr) { | ||
446 | saa7164_histogram_print(port, &port->irq_interval); | ||
447 | saa7164_histogram_print(port, &port->svc_interval); | ||
448 | saa7164_histogram_print(port, &port->irq_svc_interval); | ||
449 | saa7164_histogram_print(port, &port->read_interval); | ||
450 | saa7164_histogram_print(port, &port->poll_interval); | ||
451 | /* TODO: fix this to preserve any previous state */ | ||
452 | print_histogram = 64 + port->nr; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | static void saa7164_work_vbihandler(struct work_struct *w) | ||
457 | { | ||
458 | struct saa7164_port *port = | ||
459 | container_of(w, struct saa7164_port, workenc); | ||
460 | struct saa7164_dev *dev = port->dev; | ||
461 | |||
462 | u32 wp, mcb, rp, cnt = 0; | ||
463 | |||
464 | port->last_svc_msecs_diff = port->last_svc_msecs; | ||
465 | port->last_svc_msecs = jiffies_to_msecs(jiffies); | ||
466 | port->last_svc_msecs_diff = port->last_svc_msecs - | ||
467 | port->last_svc_msecs_diff; | ||
468 | |||
469 | saa7164_histogram_update(&port->svc_interval, | ||
470 | port->last_svc_msecs_diff); | ||
471 | |||
472 | port->last_irq_svc_msecs_diff = port->last_svc_msecs - | ||
473 | port->last_irq_msecs; | ||
474 | |||
475 | saa7164_histogram_update(&port->irq_svc_interval, | ||
476 | port->last_irq_svc_msecs_diff); | ||
477 | |||
478 | dprintk(DBGLVL_IRQ, | ||
479 | "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n", | ||
480 | __func__, | ||
481 | port->last_svc_msecs_diff, | ||
482 | port->last_irq_svc_msecs_diff, | ||
483 | port->last_svc_wp, | ||
484 | port->last_svc_rp | ||
485 | ); | ||
486 | |||
487 | /* Current write position */ | ||
488 | wp = saa7164_readl(port->bufcounter); | ||
489 | if (wp > (port->hwcfg.buffercount - 1)) { | ||
490 | printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | /* Most current complete buffer */ | ||
495 | if (wp == 0) | ||
496 | mcb = (port->hwcfg.buffercount - 1); | ||
497 | else | ||
498 | mcb = wp - 1; | ||
499 | |||
500 | while (1) { | ||
501 | if (port->done_first_interrupt == 0) { | ||
502 | port->done_first_interrupt++; | ||
503 | rp = mcb; | ||
504 | } else | ||
505 | rp = (port->last_svc_rp + 1) % 8; | ||
506 | |||
507 | if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) { | ||
508 | printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp); | ||
509 | break; | ||
510 | } | ||
511 | |||
512 | saa7164_work_enchandler_helper(port, rp); | ||
513 | port->last_svc_rp = rp; | ||
514 | cnt++; | ||
515 | |||
516 | if (rp == mcb) | ||
517 | break; | ||
518 | } | ||
519 | |||
520 | /* TODO: Convert this into a /proc/saa7164 style readable file */ | ||
521 | if (print_histogram == port->nr) { | ||
522 | saa7164_histogram_print(port, &port->irq_interval); | ||
523 | saa7164_histogram_print(port, &port->svc_interval); | ||
524 | saa7164_histogram_print(port, &port->irq_svc_interval); | ||
525 | saa7164_histogram_print(port, &port->read_interval); | ||
526 | saa7164_histogram_print(port, &port->poll_interval); | ||
527 | /* TODO: fix this to preserve any previous state */ | ||
528 | print_histogram = 64 + port->nr; | ||
529 | } | ||
530 | } | ||
531 | |||
67 | static void saa7164_work_cmdhandler(struct work_struct *w) | 532 | static void saa7164_work_cmdhandler(struct work_struct *w) |
68 | { | 533 | { |
69 | struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd); | 534 | struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd); |
@@ -74,7 +539,7 @@ static void saa7164_work_cmdhandler(struct work_struct *w) | |||
74 | 539 | ||
75 | static void saa7164_buffer_deliver(struct saa7164_buffer *buf) | 540 | static void saa7164_buffer_deliver(struct saa7164_buffer *buf) |
76 | { | 541 | { |
77 | struct saa7164_tsport *port = buf->port; | 542 | struct saa7164_port *port = buf->port; |
78 | 543 | ||
79 | /* Feed the transport payload into the kernel demux */ | 544 | /* Feed the transport payload into the kernel demux */ |
80 | dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu, | 545 | dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu, |
@@ -82,7 +547,56 @@ static void saa7164_buffer_deliver(struct saa7164_buffer *buf) | |||
82 | 547 | ||
83 | } | 548 | } |
84 | 549 | ||
85 | static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port) | 550 | static irqreturn_t saa7164_irq_vbi(struct saa7164_port *port) |
551 | { | ||
552 | struct saa7164_dev *dev = port->dev; | ||
553 | |||
554 | /* Store old time */ | ||
555 | port->last_irq_msecs_diff = port->last_irq_msecs; | ||
556 | |||
557 | /* Collect new stats */ | ||
558 | port->last_irq_msecs = jiffies_to_msecs(jiffies); | ||
559 | |||
560 | /* Calculate stats */ | ||
561 | port->last_irq_msecs_diff = port->last_irq_msecs - | ||
562 | port->last_irq_msecs_diff; | ||
563 | |||
564 | saa7164_histogram_update(&port->irq_interval, | ||
565 | port->last_irq_msecs_diff); | ||
566 | |||
567 | dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__, | ||
568 | port->last_irq_msecs_diff); | ||
569 | |||
570 | /* Tis calls the vbi irq handler */ | ||
571 | schedule_work(&port->workenc); | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port) | ||
576 | { | ||
577 | struct saa7164_dev *dev = port->dev; | ||
578 | |||
579 | /* Store old time */ | ||
580 | port->last_irq_msecs_diff = port->last_irq_msecs; | ||
581 | |||
582 | /* Collect new stats */ | ||
583 | port->last_irq_msecs = jiffies_to_msecs(jiffies); | ||
584 | |||
585 | /* Calculate stats */ | ||
586 | port->last_irq_msecs_diff = port->last_irq_msecs - | ||
587 | port->last_irq_msecs_diff; | ||
588 | |||
589 | saa7164_histogram_update(&port->irq_interval, | ||
590 | port->last_irq_msecs_diff); | ||
591 | |||
592 | dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__, | ||
593 | port->last_irq_msecs_diff); | ||
594 | |||
595 | schedule_work(&port->workenc); | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static irqreturn_t saa7164_irq_ts(struct saa7164_port *port) | ||
86 | { | 600 | { |
87 | struct saa7164_dev *dev = port->dev; | 601 | struct saa7164_dev *dev = port->dev; |
88 | struct saa7164_buffer *buf; | 602 | struct saa7164_buffer *buf; |
@@ -96,7 +610,7 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port) | |||
96 | 610 | ||
97 | /* Find the previous buffer to the current write point */ | 611 | /* Find the previous buffer to the current write point */ |
98 | if (wp == 0) | 612 | if (wp == 0) |
99 | rp = 7; | 613 | rp = (port->hwcfg.buffercount - 1); |
100 | else | 614 | else |
101 | rp = wp - 1; | 615 | rp = wp - 1; |
102 | 616 | ||
@@ -107,7 +621,7 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port) | |||
107 | if (i++ > port->hwcfg.buffercount) | 621 | if (i++ > port->hwcfg.buffercount) |
108 | BUG(); | 622 | BUG(); |
109 | 623 | ||
110 | if (buf->nr == rp) { | 624 | if (buf->idx == rp) { |
111 | /* Found the buffer, deal with it */ | 625 | /* Found the buffer, deal with it */ |
112 | dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n", | 626 | dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n", |
113 | __func__, wp, rp); | 627 | __func__, wp, rp); |
@@ -123,6 +637,13 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port) | |||
123 | static irqreturn_t saa7164_irq(int irq, void *dev_id) | 637 | static irqreturn_t saa7164_irq(int irq, void *dev_id) |
124 | { | 638 | { |
125 | struct saa7164_dev *dev = dev_id; | 639 | struct saa7164_dev *dev = dev_id; |
640 | struct saa7164_port *porta = &dev->ports[SAA7164_PORT_TS1]; | ||
641 | struct saa7164_port *portb = &dev->ports[SAA7164_PORT_TS2]; | ||
642 | struct saa7164_port *portc = &dev->ports[SAA7164_PORT_ENC1]; | ||
643 | struct saa7164_port *portd = &dev->ports[SAA7164_PORT_ENC2]; | ||
644 | struct saa7164_port *porte = &dev->ports[SAA7164_PORT_VBI1]; | ||
645 | struct saa7164_port *portf = &dev->ports[SAA7164_PORT_VBI2]; | ||
646 | |||
126 | u32 intid, intstat[INT_SIZE/4]; | 647 | u32 intid, intstat[INT_SIZE/4]; |
127 | int i, handled = 0, bit; | 648 | int i, handled = 0, bit; |
128 | 649 | ||
@@ -168,17 +689,35 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id) | |||
168 | if (intid == dev->intfdesc.bInterruptId) { | 689 | if (intid == dev->intfdesc.bInterruptId) { |
169 | /* A response to an cmd/api call */ | 690 | /* A response to an cmd/api call */ |
170 | schedule_work(&dev->workcmd); | 691 | schedule_work(&dev->workcmd); |
171 | } else if (intid == | 692 | } else if (intid == porta->hwcfg.interruptid) { |
172 | dev->ts1.hwcfg.interruptid) { | ||
173 | 693 | ||
174 | /* Transport path 1 */ | 694 | /* Transport path 1 */ |
175 | saa7164_irq_ts(&dev->ts1); | 695 | saa7164_irq_ts(porta); |
176 | 696 | ||
177 | } else if (intid == | 697 | } else if (intid == portb->hwcfg.interruptid) { |
178 | dev->ts2.hwcfg.interruptid) { | ||
179 | 698 | ||
180 | /* Transport path 2 */ | 699 | /* Transport path 2 */ |
181 | saa7164_irq_ts(&dev->ts2); | 700 | saa7164_irq_ts(portb); |
701 | |||
702 | } else if (intid == portc->hwcfg.interruptid) { | ||
703 | |||
704 | /* Encoder path 1 */ | ||
705 | saa7164_irq_encoder(portc); | ||
706 | |||
707 | } else if (intid == portd->hwcfg.interruptid) { | ||
708 | |||
709 | /* Encoder path 2 */ | ||
710 | saa7164_irq_encoder(portd); | ||
711 | |||
712 | } else if (intid == porte->hwcfg.interruptid) { | ||
713 | |||
714 | /* VBI path 1 */ | ||
715 | saa7164_irq_vbi(porte); | ||
716 | |||
717 | } else if (intid == portf->hwcfg.interruptid) { | ||
718 | |||
719 | /* VBI path 2 */ | ||
720 | saa7164_irq_vbi(portf); | ||
182 | 721 | ||
183 | } else { | 722 | } else { |
184 | /* Find the function */ | 723 | /* Find the function */ |
@@ -286,8 +825,8 @@ void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr) | |||
286 | 825 | ||
287 | static void saa7164_dump_hwdesc(struct saa7164_dev *dev) | 826 | static void saa7164_dump_hwdesc(struct saa7164_dev *dev) |
288 | { | 827 | { |
289 | dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n", | 828 | dprintk(1, "@0x%p hwdesc sizeof(struct tmComResHWDescr) = %d bytes\n", |
290 | &dev->hwdesc, (u32)sizeof(tmComResHWDescr_t)); | 829 | &dev->hwdesc, (u32)sizeof(struct tmComResHWDescr)); |
291 | 830 | ||
292 | dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength); | 831 | dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength); |
293 | dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType); | 832 | dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType); |
@@ -317,8 +856,8 @@ static void saa7164_dump_hwdesc(struct saa7164_dev *dev) | |||
317 | static void saa7164_dump_intfdesc(struct saa7164_dev *dev) | 856 | static void saa7164_dump_intfdesc(struct saa7164_dev *dev) |
318 | { | 857 | { |
319 | dprintk(1, "@0x%p intfdesc " | 858 | dprintk(1, "@0x%p intfdesc " |
320 | "sizeof(tmComResInterfaceDescr_t) = %d bytes\n", | 859 | "sizeof(struct tmComResInterfaceDescr) = %d bytes\n", |
321 | &dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t)); | 860 | &dev->intfdesc, (u32)sizeof(struct tmComResInterfaceDescr)); |
322 | 861 | ||
323 | dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength); | 862 | dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength); |
324 | dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType); | 863 | dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType); |
@@ -338,8 +877,8 @@ static void saa7164_dump_intfdesc(struct saa7164_dev *dev) | |||
338 | 877 | ||
339 | static void saa7164_dump_busdesc(struct saa7164_dev *dev) | 878 | static void saa7164_dump_busdesc(struct saa7164_dev *dev) |
340 | { | 879 | { |
341 | dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n", | 880 | dprintk(1, "@0x%p busdesc sizeof(struct tmComResBusDescr) = %d bytes\n", |
342 | &dev->busdesc, (u32)sizeof(tmComResBusDescr_t)); | 881 | &dev->busdesc, (u32)sizeof(struct tmComResBusDescr)); |
343 | 882 | ||
344 | dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing); | 883 | dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing); |
345 | dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing); | 884 | dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing); |
@@ -356,23 +895,23 @@ static void saa7164_dump_busdesc(struct saa7164_dev *dev) | |||
356 | */ | 895 | */ |
357 | static void saa7164_get_descriptors(struct saa7164_dev *dev) | 896 | static void saa7164_get_descriptors(struct saa7164_dev *dev) |
358 | { | 897 | { |
359 | memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t)); | 898 | memcpy_fromio(&dev->hwdesc, dev->bmmio, sizeof(struct tmComResHWDescr)); |
360 | memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t), | 899 | memcpy_fromio(&dev->intfdesc, dev->bmmio + sizeof(struct tmComResHWDescr), |
361 | sizeof(tmComResInterfaceDescr_t)); | 900 | sizeof(struct tmComResInterfaceDescr)); |
362 | memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation, | 901 | memcpy_fromio(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation, |
363 | sizeof(tmComResBusDescr_t)); | 902 | sizeof(struct tmComResBusDescr)); |
364 | 903 | ||
365 | if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) { | 904 | if (dev->hwdesc.bLength != sizeof(struct tmComResHWDescr)) { |
366 | printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n"); | 905 | printk(KERN_ERR "Structure struct tmComResHWDescr is mangled\n"); |
367 | printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength, | 906 | printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength, |
368 | (u32)sizeof(tmComResHWDescr_t)); | 907 | (u32)sizeof(struct tmComResHWDescr)); |
369 | } else | 908 | } else |
370 | saa7164_dump_hwdesc(dev); | 909 | saa7164_dump_hwdesc(dev); |
371 | 910 | ||
372 | if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) { | 911 | if (dev->intfdesc.bLength != sizeof(struct tmComResInterfaceDescr)) { |
373 | printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n"); | 912 | printk(KERN_ERR "struct struct tmComResInterfaceDescr is mangled\n"); |
374 | printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength, | 913 | printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength, |
375 | (u32)sizeof(tmComResInterfaceDescr_t)); | 914 | (u32)sizeof(struct tmComResInterfaceDescr)); |
376 | } else | 915 | } else |
377 | saa7164_dump_intfdesc(dev); | 916 | saa7164_dump_intfdesc(dev); |
378 | 917 | ||
@@ -402,6 +941,58 @@ static int get_resources(struct saa7164_dev *dev) | |||
402 | return -EBUSY; | 941 | return -EBUSY; |
403 | } | 942 | } |
404 | 943 | ||
944 | static int saa7164_port_init(struct saa7164_dev *dev, int portnr) | ||
945 | { | ||
946 | struct saa7164_port *port = 0; | ||
947 | |||
948 | if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS)) | ||
949 | BUG(); | ||
950 | |||
951 | port = &dev->ports[portnr]; | ||
952 | |||
953 | port->dev = dev; | ||
954 | port->nr = portnr; | ||
955 | |||
956 | if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2)) | ||
957 | port->type = SAA7164_MPEG_DVB; | ||
958 | else | ||
959 | if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2)) { | ||
960 | port->type = SAA7164_MPEG_ENCODER; | ||
961 | |||
962 | /* We need a deferred interrupt handler for cmd handling */ | ||
963 | INIT_WORK(&port->workenc, saa7164_work_enchandler); | ||
964 | } | ||
965 | else | ||
966 | if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) { | ||
967 | port->type = SAA7164_MPEG_VBI; | ||
968 | |||
969 | /* We need a deferred interrupt handler for cmd handling */ | ||
970 | INIT_WORK(&port->workenc, saa7164_work_vbihandler); | ||
971 | } else | ||
972 | BUG(); | ||
973 | |||
974 | /* Init all the critical resources */ | ||
975 | mutex_init(&port->dvb.lock); | ||
976 | INIT_LIST_HEAD(&port->dmaqueue.list); | ||
977 | mutex_init(&port->dmaqueue_lock); | ||
978 | |||
979 | INIT_LIST_HEAD(&port->list_buf_used.list); | ||
980 | INIT_LIST_HEAD(&port->list_buf_free.list); | ||
981 | init_waitqueue_head(&port->wait_read); | ||
982 | |||
983 | |||
984 | saa7164_histogram_reset(&port->irq_interval, "irq intervals"); | ||
985 | saa7164_histogram_reset(&port->svc_interval, "deferred intervals"); | ||
986 | saa7164_histogram_reset(&port->irq_svc_interval, | ||
987 | "irq to deferred intervals"); | ||
988 | saa7164_histogram_reset(&port->read_interval, | ||
989 | "encoder/vbi read() intervals"); | ||
990 | saa7164_histogram_reset(&port->poll_interval, | ||
991 | "encoder/vbi poll() intervals"); | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
405 | static int saa7164_dev_setup(struct saa7164_dev *dev) | 996 | static int saa7164_dev_setup(struct saa7164_dev *dev) |
406 | { | 997 | { |
407 | int i; | 998 | int i; |
@@ -443,23 +1034,13 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) | |||
443 | dev->i2c_bus[2].dev = dev; | 1034 | dev->i2c_bus[2].dev = dev; |
444 | dev->i2c_bus[2].nr = 2; | 1035 | dev->i2c_bus[2].nr = 2; |
445 | 1036 | ||
446 | /* Transport port A Defaults / setup */ | 1037 | /* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */ |
447 | dev->ts1.dev = dev; | 1038 | saa7164_port_init(dev, SAA7164_PORT_TS1); |
448 | dev->ts1.nr = 0; | 1039 | saa7164_port_init(dev, SAA7164_PORT_TS2); |
449 | mutex_init(&dev->ts1.dvb.lock); | 1040 | saa7164_port_init(dev, SAA7164_PORT_ENC1); |
450 | INIT_LIST_HEAD(&dev->ts1.dmaqueue.list); | 1041 | saa7164_port_init(dev, SAA7164_PORT_ENC2); |
451 | INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list); | 1042 | saa7164_port_init(dev, SAA7164_PORT_VBI1); |
452 | mutex_init(&dev->ts1.dmaqueue_lock); | 1043 | saa7164_port_init(dev, SAA7164_PORT_VBI2); |
453 | mutex_init(&dev->ts1.dummy_dmaqueue_lock); | ||
454 | |||
455 | /* Transport port B Defaults / setup */ | ||
456 | dev->ts2.dev = dev; | ||
457 | dev->ts2.nr = 1; | ||
458 | mutex_init(&dev->ts2.dvb.lock); | ||
459 | INIT_LIST_HEAD(&dev->ts2.dmaqueue.list); | ||
460 | INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list); | ||
461 | mutex_init(&dev->ts2.dmaqueue_lock); | ||
462 | mutex_init(&dev->ts2.dummy_dmaqueue_lock); | ||
463 | 1044 | ||
464 | if (get_resources(dev) < 0) { | 1045 | if (get_resources(dev) < 0) { |
465 | printk(KERN_ERR "CORE %s No more PCIe resources for " | 1046 | printk(KERN_ERR "CORE %s No more PCIe resources for " |
@@ -516,6 +1097,132 @@ static void saa7164_dev_unregister(struct saa7164_dev *dev) | |||
516 | return; | 1097 | return; |
517 | } | 1098 | } |
518 | 1099 | ||
1100 | #ifdef CONFIG_PROC_FS | ||
1101 | static int saa7164_proc_show(struct seq_file *m, void *v) | ||
1102 | { | ||
1103 | struct saa7164_dev *dev; | ||
1104 | struct tmComResBusInfo *b; | ||
1105 | struct list_head *list; | ||
1106 | int i, c; | ||
1107 | |||
1108 | if (saa7164_devcount == 0) | ||
1109 | return 0; | ||
1110 | |||
1111 | list_for_each(list, &saa7164_devlist) { | ||
1112 | dev = list_entry(list, struct saa7164_dev, devlist); | ||
1113 | seq_printf(m, "%s = %p\n", dev->name, dev); | ||
1114 | |||
1115 | /* Lock the bus from any other access */ | ||
1116 | b = &dev->bus; | ||
1117 | mutex_lock(&b->lock); | ||
1118 | |||
1119 | seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n", | ||
1120 | b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos)); | ||
1121 | |||
1122 | seq_printf(m, " .m_pdwSetReadPos = 0x%x (0x%08x)\n", | ||
1123 | b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos)); | ||
1124 | |||
1125 | seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n", | ||
1126 | b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos)); | ||
1127 | |||
1128 | seq_printf(m, " .m_pdwGetReadPos = 0x%x (0x%08x)\n", | ||
1129 | b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos)); | ||
1130 | c = 0; | ||
1131 | seq_printf(m, "\n Set Ring:\n"); | ||
1132 | seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); | ||
1133 | for (i = 0; i < b->m_dwSizeSetRing; i++) { | ||
1134 | if (c == 0) | ||
1135 | seq_printf(m, " %04x:", i); | ||
1136 | |||
1137 | seq_printf(m, " %02x", *(b->m_pdwSetRing + i)); | ||
1138 | |||
1139 | if (++c == 16) { | ||
1140 | seq_printf(m, "\n"); | ||
1141 | c = 0; | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | c = 0; | ||
1146 | seq_printf(m, "\n Get Ring:\n"); | ||
1147 | seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); | ||
1148 | for (i = 0; i < b->m_dwSizeGetRing; i++) { | ||
1149 | if (c == 0) | ||
1150 | seq_printf(m, " %04x:", i); | ||
1151 | |||
1152 | seq_printf(m, " %02x", *(b->m_pdwGetRing + i)); | ||
1153 | |||
1154 | if (++c == 16) { | ||
1155 | seq_printf(m, "\n"); | ||
1156 | c = 0; | ||
1157 | } | ||
1158 | } | ||
1159 | |||
1160 | mutex_unlock(&b->lock); | ||
1161 | |||
1162 | } | ||
1163 | |||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1167 | static int saa7164_proc_open(struct inode *inode, struct file *filp) | ||
1168 | { | ||
1169 | return single_open(filp, saa7164_proc_show, NULL); | ||
1170 | } | ||
1171 | |||
1172 | static struct file_operations saa7164_proc_fops = { | ||
1173 | .open = saa7164_proc_open, | ||
1174 | .read = seq_read, | ||
1175 | .llseek = seq_lseek, | ||
1176 | .release = single_release, | ||
1177 | }; | ||
1178 | |||
1179 | static int saa7164_proc_create(void) | ||
1180 | { | ||
1181 | struct proc_dir_entry *pe; | ||
1182 | |||
1183 | pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops); | ||
1184 | if (!pe) | ||
1185 | return -ENOMEM; | ||
1186 | |||
1187 | return 0; | ||
1188 | } | ||
1189 | #endif | ||
1190 | |||
1191 | static int saa7164_thread_function(void *data) | ||
1192 | { | ||
1193 | struct saa7164_dev *dev = data; | ||
1194 | struct tmFwInfoStruct fwinfo; | ||
1195 | u64 last_poll_time = 0; | ||
1196 | |||
1197 | dprintk(DBGLVL_THR, "thread started\n"); | ||
1198 | |||
1199 | set_freezable(); | ||
1200 | |||
1201 | while (1) { | ||
1202 | msleep_interruptible(100); | ||
1203 | if (kthread_should_stop()) | ||
1204 | break; | ||
1205 | try_to_freeze(); | ||
1206 | |||
1207 | dprintk(DBGLVL_THR, "thread running\n"); | ||
1208 | |||
1209 | /* Dump the firmware debug message to console */ | ||
1210 | /* Polling this costs us 1-2% of the arm CPU */ | ||
1211 | /* convert this into a respnde to interrupt 0x7a */ | ||
1212 | saa7164_api_collect_debug(dev); | ||
1213 | |||
1214 | /* Monitor CPU load every 1 second */ | ||
1215 | if ((last_poll_time + 1000 /* ms */) < jiffies_to_msecs(jiffies)) { | ||
1216 | saa7164_api_get_load_info(dev, &fwinfo); | ||
1217 | last_poll_time = jiffies_to_msecs(jiffies); | ||
1218 | } | ||
1219 | |||
1220 | } | ||
1221 | |||
1222 | dprintk(DBGLVL_THR, "thread exiting\n"); | ||
1223 | return 0; | ||
1224 | } | ||
1225 | |||
519 | static int __devinit saa7164_initdev(struct pci_dev *pci_dev, | 1226 | static int __devinit saa7164_initdev(struct pci_dev *pci_dev, |
520 | const struct pci_device_id *pci_id) | 1227 | const struct pci_device_id *pci_id) |
521 | { | 1228 | { |
@@ -622,7 +1329,6 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev, | |||
622 | saa7164_gpio_setup(dev); | 1329 | saa7164_gpio_setup(dev); |
623 | saa7164_card_setup(dev); | 1330 | saa7164_card_setup(dev); |
624 | 1331 | ||
625 | |||
626 | /* Parse the dynamic device configuration, find various | 1332 | /* Parse the dynamic device configuration, find various |
627 | * media endpoints (MPEG, WMV, PS, TS) and cache their | 1333 | * media endpoints (MPEG, WMV, PS, TS) and cache their |
628 | * configuration details into the driver, so we can | 1334 | * configuration details into the driver, so we can |
@@ -633,7 +1339,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev, | |||
633 | 1339 | ||
634 | /* Begin to create the video sub-systems and register funcs */ | 1340 | /* Begin to create the video sub-systems and register funcs */ |
635 | if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) { | 1341 | if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) { |
636 | if (saa7164_dvb_register(&dev->ts1) < 0) { | 1342 | if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS1]) < 0) { |
637 | printk(KERN_ERR "%s() Failed to register " | 1343 | printk(KERN_ERR "%s() Failed to register " |
638 | "dvb adapters on porta\n", | 1344 | "dvb adapters on porta\n", |
639 | __func__); | 1345 | __func__); |
@@ -641,13 +1347,50 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev, | |||
641 | } | 1347 | } |
642 | 1348 | ||
643 | if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) { | 1349 | if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) { |
644 | if (saa7164_dvb_register(&dev->ts2) < 0) { | 1350 | if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS2]) < 0) { |
645 | printk(KERN_ERR"%s() Failed to register " | 1351 | printk(KERN_ERR"%s() Failed to register " |
646 | "dvb adapters on portb\n", | 1352 | "dvb adapters on portb\n", |
647 | __func__); | 1353 | __func__); |
648 | } | 1354 | } |
649 | } | 1355 | } |
650 | 1356 | ||
1357 | if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) { | ||
1358 | if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC1]) < 0) { | ||
1359 | printk(KERN_ERR"%s() Failed to register " | ||
1360 | "mpeg encoder\n", __func__); | ||
1361 | } | ||
1362 | } | ||
1363 | |||
1364 | if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) { | ||
1365 | if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC2]) < 0) { | ||
1366 | printk(KERN_ERR"%s() Failed to register " | ||
1367 | "mpeg encoder\n", __func__); | ||
1368 | } | ||
1369 | } | ||
1370 | |||
1371 | if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) { | ||
1372 | if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI1]) < 0) { | ||
1373 | printk(KERN_ERR"%s() Failed to register " | ||
1374 | "vbi device\n", __func__); | ||
1375 | } | ||
1376 | } | ||
1377 | |||
1378 | if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) { | ||
1379 | if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI2]) < 0) { | ||
1380 | printk(KERN_ERR"%s() Failed to register " | ||
1381 | "vbi device\n", __func__); | ||
1382 | } | ||
1383 | } | ||
1384 | saa7164_api_set_debug(dev, fw_debug); | ||
1385 | |||
1386 | if (fw_debug) { | ||
1387 | dev->kthread = kthread_run(saa7164_thread_function, dev, | ||
1388 | "saa7164 debug"); | ||
1389 | if (!dev->kthread) | ||
1390 | printk(KERN_ERR "%s() Failed to create " | ||
1391 | "debug kernel thread\n", __func__); | ||
1392 | } | ||
1393 | |||
651 | } /* != BOARD_UNKNOWN */ | 1394 | } /* != BOARD_UNKNOWN */ |
652 | else | 1395 | else |
653 | printk(KERN_ERR "%s() Unsupported board detected, " | 1396 | printk(KERN_ERR "%s() Unsupported board detected, " |
@@ -675,13 +1418,49 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev) | |||
675 | { | 1418 | { |
676 | struct saa7164_dev *dev = pci_get_drvdata(pci_dev); | 1419 | struct saa7164_dev *dev = pci_get_drvdata(pci_dev); |
677 | 1420 | ||
1421 | if (dev->board != SAA7164_BOARD_UNKNOWN) { | ||
1422 | if (fw_debug && dev->kthread) { | ||
1423 | kthread_stop(dev->kthread); | ||
1424 | dev->kthread = NULL; | ||
1425 | } | ||
1426 | if (dev->firmwareloaded) | ||
1427 | saa7164_api_set_debug(dev, 0x00); | ||
1428 | } | ||
1429 | |||
1430 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], | ||
1431 | &dev->ports[SAA7164_PORT_ENC1].irq_interval); | ||
1432 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], | ||
1433 | &dev->ports[SAA7164_PORT_ENC1].svc_interval); | ||
1434 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], | ||
1435 | &dev->ports[SAA7164_PORT_ENC1].irq_svc_interval); | ||
1436 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], | ||
1437 | &dev->ports[SAA7164_PORT_ENC1].read_interval); | ||
1438 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_ENC1], | ||
1439 | &dev->ports[SAA7164_PORT_ENC1].poll_interval); | ||
1440 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI1], | ||
1441 | &dev->ports[SAA7164_PORT_VBI1].read_interval); | ||
1442 | saa7164_histogram_print(&dev->ports[SAA7164_PORT_VBI2], | ||
1443 | &dev->ports[SAA7164_PORT_VBI2].poll_interval); | ||
1444 | |||
678 | saa7164_shutdown(dev); | 1445 | saa7164_shutdown(dev); |
679 | 1446 | ||
680 | if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) | 1447 | if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) |
681 | saa7164_dvb_unregister(&dev->ts1); | 1448 | saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS1]); |
682 | 1449 | ||
683 | if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) | 1450 | if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) |
684 | saa7164_dvb_unregister(&dev->ts2); | 1451 | saa7164_dvb_unregister(&dev->ports[SAA7164_PORT_TS2]); |
1452 | |||
1453 | if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) | ||
1454 | saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC1]); | ||
1455 | |||
1456 | if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) | ||
1457 | saa7164_encoder_unregister(&dev->ports[SAA7164_PORT_ENC2]); | ||
1458 | |||
1459 | if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) | ||
1460 | saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI1]); | ||
1461 | |||
1462 | if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) | ||
1463 | saa7164_vbi_unregister(&dev->ports[SAA7164_PORT_VBI2]); | ||
685 | 1464 | ||
686 | saa7164_i2c_unregister(&dev->i2c_bus[0]); | 1465 | saa7164_i2c_unregister(&dev->i2c_bus[0]); |
687 | saa7164_i2c_unregister(&dev->i2c_bus[1]); | 1466 | saa7164_i2c_unregister(&dev->i2c_bus[1]); |
@@ -727,11 +1506,18 @@ static struct pci_driver saa7164_pci_driver = { | |||
727 | static int __init saa7164_init(void) | 1506 | static int __init saa7164_init(void) |
728 | { | 1507 | { |
729 | printk(KERN_INFO "saa7164 driver loaded\n"); | 1508 | printk(KERN_INFO "saa7164 driver loaded\n"); |
1509 | |||
1510 | #ifdef CONFIG_PROC_FS | ||
1511 | saa7164_proc_create(); | ||
1512 | #endif | ||
730 | return pci_register_driver(&saa7164_pci_driver); | 1513 | return pci_register_driver(&saa7164_pci_driver); |
731 | } | 1514 | } |
732 | 1515 | ||
733 | static void __exit saa7164_fini(void) | 1516 | static void __exit saa7164_fini(void) |
734 | { | 1517 | { |
1518 | #ifdef CONFIG_PROC_FS | ||
1519 | remove_proc_entry("saa7164", NULL); | ||
1520 | #endif | ||
735 | pci_unregister_driver(&saa7164_pci_driver); | 1521 | pci_unregister_driver(&saa7164_pci_driver); |
736 | } | 1522 | } |
737 | 1523 | ||
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c index cf099c59b38..b305a01b3bd 100644 --- a/drivers/media/video/saa7164/saa7164-dvb.c +++ b/drivers/media/video/saa7164/saa7164-dvb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -82,7 +82,7 @@ static struct s5h1411_config hauppauge_s5h1411_config = { | |||
82 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 82 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port) | 85 | static int saa7164_dvb_stop_port(struct saa7164_port *port) |
86 | { | 86 | { |
87 | struct saa7164_dev *dev = port->dev; | 87 | struct saa7164_dev *dev = port->dev; |
88 | int ret; | 88 | int ret; |
@@ -100,7 +100,7 @@ static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port) | |||
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port) | 103 | static int saa7164_dvb_acquire_port(struct saa7164_port *port) |
104 | { | 104 | { |
105 | struct saa7164_dev *dev = port->dev; | 105 | struct saa7164_dev *dev = port->dev; |
106 | int ret; | 106 | int ret; |
@@ -118,7 +118,7 @@ static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port) | |||
118 | return ret; | 118 | return ret; |
119 | } | 119 | } |
120 | 120 | ||
121 | static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port) | 121 | static int saa7164_dvb_pause_port(struct saa7164_port *port) |
122 | { | 122 | { |
123 | struct saa7164_dev *dev = port->dev; | 123 | struct saa7164_dev *dev = port->dev; |
124 | int ret; | 124 | int ret; |
@@ -140,90 +140,38 @@ static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port) | |||
140 | * the part through AVStream / KS Windows stages, forwards or backwards. | 140 | * the part through AVStream / KS Windows stages, forwards or backwards. |
141 | * States are: stopped, acquired (h/w), paused, started. | 141 | * States are: stopped, acquired (h/w), paused, started. |
142 | */ | 142 | */ |
143 | static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port) | 143 | static int saa7164_dvb_stop_streaming(struct saa7164_port *port) |
144 | { | 144 | { |
145 | struct saa7164_dev *dev = port->dev; | 145 | struct saa7164_dev *dev = port->dev; |
146 | int ret; | ||
147 | |||
148 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); | ||
149 | |||
150 | ret = saa7164_dvb_pause_tsport(port); | ||
151 | ret = saa7164_dvb_acquire_tsport(port); | ||
152 | ret = saa7164_dvb_stop_tsport(port); | ||
153 | |||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port) | ||
158 | { | ||
159 | tmHWStreamParameters_t *params = &port->hw_streamingparams; | ||
160 | struct saa7164_dev *dev = port->dev; | ||
161 | struct saa7164_buffer *buf; | 146 | struct saa7164_buffer *buf; |
162 | struct list_head *c, *n; | 147 | struct list_head *p, *q; |
163 | int i = 0; | 148 | int ret; |
164 | 149 | ||
165 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); | 150 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); |
166 | 151 | ||
167 | saa7164_writel(port->pitch, params->pitch); | 152 | ret = saa7164_dvb_pause_port(port); |
168 | saa7164_writel(port->bufsize, params->pitch * params->numberoflines); | 153 | ret = saa7164_dvb_acquire_port(port); |
154 | ret = saa7164_dvb_stop_port(port); | ||
169 | 155 | ||
170 | dprintk(DBGLVL_DVB, " configured:\n"); | 156 | /* Mark the hardware buffers as free */ |
171 | dprintk(DBGLVL_DVB, " lmmio 0x%p\n", dev->lmmio); | ||
172 | dprintk(DBGLVL_DVB, " bufcounter 0x%x = 0x%x\n", port->bufcounter, | ||
173 | saa7164_readl(port->bufcounter)); | ||
174 | |||
175 | dprintk(DBGLVL_DVB, " pitch 0x%x = %d\n", port->pitch, | ||
176 | saa7164_readl(port->pitch)); | ||
177 | |||
178 | dprintk(DBGLVL_DVB, " bufsize 0x%x = %d\n", port->bufsize, | ||
179 | saa7164_readl(port->bufsize)); | ||
180 | |||
181 | dprintk(DBGLVL_DVB, " buffercount = %d\n", port->hwcfg.buffercount); | ||
182 | dprintk(DBGLVL_DVB, " bufoffset = 0x%x\n", port->bufoffset); | ||
183 | dprintk(DBGLVL_DVB, " bufptr32h = 0x%x\n", port->bufptr32h); | ||
184 | dprintk(DBGLVL_DVB, " bufptr32l = 0x%x\n", port->bufptr32l); | ||
185 | |||
186 | /* Poke the buffers and offsets into PCI space */ | ||
187 | mutex_lock(&port->dmaqueue_lock); | 157 | mutex_lock(&port->dmaqueue_lock); |
188 | list_for_each_safe(c, n, &port->dmaqueue.list) { | 158 | list_for_each_safe(p, q, &port->dmaqueue.list) { |
189 | buf = list_entry(c, struct saa7164_buffer, list); | 159 | buf = list_entry(p, struct saa7164_buffer, list); |
190 | 160 | buf->flags = SAA7164_BUFFER_FREE; | |
191 | /* TODO: Review this in light of 32v64 assignments */ | ||
192 | saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0); | ||
193 | saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), | ||
194 | buf->pt_dma); | ||
195 | saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0); | ||
196 | |||
197 | dprintk(DBGLVL_DVB, | ||
198 | " buf[%d] offset 0x%llx (0x%x) " | ||
199 | "buf 0x%llx/%llx (0x%x/%x)\n", | ||
200 | i, | ||
201 | (u64)port->bufoffset + (i * sizeof(u32)), | ||
202 | saa7164_readl(port->bufoffset + (sizeof(u32) * i)), | ||
203 | (u64)port->bufptr32h + ((sizeof(u32) * 2) * i), | ||
204 | (u64)port->bufptr32l + ((sizeof(u32) * 2) * i), | ||
205 | saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) | ||
206 | * 2)), | ||
207 | saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) | ||
208 | * 2))); | ||
209 | |||
210 | if (i++ > port->hwcfg.buffercount) | ||
211 | BUG(); | ||
212 | |||
213 | } | 161 | } |
214 | mutex_unlock(&port->dmaqueue_lock); | 162 | mutex_unlock(&port->dmaqueue_lock); |
215 | 163 | ||
216 | return 0; | 164 | return ret; |
217 | } | 165 | } |
218 | 166 | ||
219 | static int saa7164_dvb_start_tsport(struct saa7164_tsport *port) | 167 | static int saa7164_dvb_start_port(struct saa7164_port *port) |
220 | { | 168 | { |
221 | struct saa7164_dev *dev = port->dev; | 169 | struct saa7164_dev *dev = port->dev; |
222 | int ret = 0, result; | 170 | int ret = 0, result; |
223 | 171 | ||
224 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); | 172 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); |
225 | 173 | ||
226 | saa7164_dvb_cfg_tsport(port); | 174 | saa7164_buffer_cfg_port(port); |
227 | 175 | ||
228 | /* Acquire the hardware */ | 176 | /* Acquire the hardware */ |
229 | result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); | 177 | result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); |
@@ -284,7 +232,7 @@ out: | |||
284 | static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) | 232 | static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) |
285 | { | 233 | { |
286 | struct dvb_demux *demux = feed->demux; | 234 | struct dvb_demux *demux = feed->demux; |
287 | struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv; | 235 | struct saa7164_port *port = (struct saa7164_port *) demux->priv; |
288 | struct saa7164_dvb *dvb = &port->dvb; | 236 | struct saa7164_dvb *dvb = &port->dvb; |
289 | struct saa7164_dev *dev = port->dev; | 237 | struct saa7164_dev *dev = port->dev; |
290 | int ret = 0; | 238 | int ret = 0; |
@@ -298,7 +246,7 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) | |||
298 | mutex_lock(&dvb->lock); | 246 | mutex_lock(&dvb->lock); |
299 | if (dvb->feeding++ == 0) { | 247 | if (dvb->feeding++ == 0) { |
300 | /* Start transport */ | 248 | /* Start transport */ |
301 | ret = saa7164_dvb_start_tsport(port); | 249 | ret = saa7164_dvb_start_port(port); |
302 | } | 250 | } |
303 | mutex_unlock(&dvb->lock); | 251 | mutex_unlock(&dvb->lock); |
304 | dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", | 252 | dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", |
@@ -311,7 +259,7 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) | |||
311 | static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) | 259 | static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) |
312 | { | 260 | { |
313 | struct dvb_demux *demux = feed->demux; | 261 | struct dvb_demux *demux = feed->demux; |
314 | struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv; | 262 | struct saa7164_port *port = (struct saa7164_port *) demux->priv; |
315 | struct saa7164_dvb *dvb = &port->dvb; | 263 | struct saa7164_dvb *dvb = &port->dvb; |
316 | struct saa7164_dev *dev = port->dev; | 264 | struct saa7164_dev *dev = port->dev; |
317 | int ret = 0; | 265 | int ret = 0; |
@@ -332,7 +280,7 @@ static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
332 | return ret; | 280 | return ret; |
333 | } | 281 | } |
334 | 282 | ||
335 | static int dvb_register(struct saa7164_tsport *port) | 283 | static int dvb_register(struct saa7164_port *port) |
336 | { | 284 | { |
337 | struct saa7164_dvb *dvb = &port->dvb; | 285 | struct saa7164_dvb *dvb = &port->dvb; |
338 | struct saa7164_dev *dev = port->dev; | 286 | struct saa7164_dev *dev = port->dev; |
@@ -341,6 +289,9 @@ static int dvb_register(struct saa7164_tsport *port) | |||
341 | 289 | ||
342 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); | 290 | dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); |
343 | 291 | ||
292 | if (port->type != SAA7164_MPEG_DVB) | ||
293 | BUG(); | ||
294 | |||
344 | /* Sanity check that the PCI configuration space is active */ | 295 | /* Sanity check that the PCI configuration space is active */ |
345 | if (port->hwcfg.BARLocation == 0) { | 296 | if (port->hwcfg.BARLocation == 0) { |
346 | result = -ENOMEM; | 297 | result = -ENOMEM; |
@@ -378,7 +329,6 @@ static int dvb_register(struct saa7164_tsport *port) | |||
378 | DRIVER_NAME, result); | 329 | DRIVER_NAME, result); |
379 | goto fail_adapter; | 330 | goto fail_adapter; |
380 | } | 331 | } |
381 | buf->nr = i; | ||
382 | 332 | ||
383 | mutex_lock(&port->dmaqueue_lock); | 333 | mutex_lock(&port->dmaqueue_lock); |
384 | list_add_tail(&buf->list, &port->dmaqueue.list); | 334 | list_add_tail(&buf->list, &port->dmaqueue.list); |
@@ -473,7 +423,7 @@ fail_adapter: | |||
473 | return result; | 423 | return result; |
474 | } | 424 | } |
475 | 425 | ||
476 | int saa7164_dvb_unregister(struct saa7164_tsport *port) | 426 | int saa7164_dvb_unregister(struct saa7164_port *port) |
477 | { | 427 | { |
478 | struct saa7164_dvb *dvb = &port->dvb; | 428 | struct saa7164_dvb *dvb = &port->dvb; |
479 | struct saa7164_dev *dev = port->dev; | 429 | struct saa7164_dev *dev = port->dev; |
@@ -482,12 +432,15 @@ int saa7164_dvb_unregister(struct saa7164_tsport *port) | |||
482 | 432 | ||
483 | dprintk(DBGLVL_DVB, "%s()\n", __func__); | 433 | dprintk(DBGLVL_DVB, "%s()\n", __func__); |
484 | 434 | ||
435 | if (port->type != SAA7164_MPEG_DVB) | ||
436 | BUG(); | ||
437 | |||
485 | /* Remove any allocated buffers */ | 438 | /* Remove any allocated buffers */ |
486 | mutex_lock(&port->dmaqueue_lock); | 439 | mutex_lock(&port->dmaqueue_lock); |
487 | list_for_each_safe(c, n, &port->dmaqueue.list) { | 440 | list_for_each_safe(c, n, &port->dmaqueue.list) { |
488 | b = list_entry(c, struct saa7164_buffer, list); | 441 | b = list_entry(c, struct saa7164_buffer, list); |
489 | list_del(c); | 442 | list_del(c); |
490 | saa7164_buffer_dealloc(port, b); | 443 | saa7164_buffer_dealloc(b); |
491 | } | 444 | } |
492 | mutex_unlock(&port->dmaqueue_lock); | 445 | mutex_unlock(&port->dmaqueue_lock); |
493 | 446 | ||
@@ -508,7 +461,7 @@ int saa7164_dvb_unregister(struct saa7164_tsport *port) | |||
508 | /* All the DVB attach calls go here, this function get's modified | 461 | /* All the DVB attach calls go here, this function get's modified |
509 | * for each new card. | 462 | * for each new card. |
510 | */ | 463 | */ |
511 | int saa7164_dvb_register(struct saa7164_tsport *port) | 464 | int saa7164_dvb_register(struct saa7164_port *port) |
512 | { | 465 | { |
513 | struct saa7164_dev *dev = port->dev; | 466 | struct saa7164_dev *dev = port->dev; |
514 | struct saa7164_dvb *dvb = &port->dvb; | 467 | struct saa7164_dvb *dvb = &port->dvb; |
@@ -588,8 +541,6 @@ int saa7164_dvb_register(struct saa7164_tsport *port) | |||
588 | return -1; | 541 | return -1; |
589 | } | 542 | } |
590 | 543 | ||
591 | /* Put the analog decoder in standby to keep it quiet */ | ||
592 | |||
593 | /* register everything */ | 544 | /* register everything */ |
594 | ret = dvb_register(port); | 545 | ret = dvb_register(port); |
595 | if (ret < 0) { | 546 | if (ret < 0) { |
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c new file mode 100644 index 00000000000..cbb53d0ee97 --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-encoder.c | |||
@@ -0,0 +1,1503 @@ | |||
1 | /* | ||
2 | * Driver for the NXP SAA7164 PCIe bridge | ||
3 | * | ||
4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include "saa7164.h" | ||
23 | |||
24 | #define ENCODER_MAX_BITRATE 6500000 | ||
25 | #define ENCODER_MIN_BITRATE 1000000 | ||
26 | #define ENCODER_DEF_BITRATE 5000000 | ||
27 | |||
28 | static struct saa7164_tvnorm saa7164_tvnorms[] = { | ||
29 | { | ||
30 | .name = "NTSC-M", | ||
31 | .id = V4L2_STD_NTSC_M, | ||
32 | }, { | ||
33 | .name = "NTSC-JP", | ||
34 | .id = V4L2_STD_NTSC_M_JP, | ||
35 | } | ||
36 | }; | ||
37 | |||
38 | static const u32 saa7164_v4l2_ctrls[] = { | ||
39 | V4L2_CID_BRIGHTNESS, | ||
40 | V4L2_CID_CONTRAST, | ||
41 | V4L2_CID_SATURATION, | ||
42 | V4L2_CID_HUE, | ||
43 | V4L2_CID_AUDIO_VOLUME, | ||
44 | V4L2_CID_SHARPNESS, | ||
45 | V4L2_CID_MPEG_STREAM_TYPE, | ||
46 | V4L2_CID_MPEG_VIDEO_ASPECT, | ||
47 | V4L2_CID_MPEG_VIDEO_B_FRAMES, | ||
48 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, | ||
49 | V4L2_CID_MPEG_AUDIO_MUTE, | ||
50 | V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | ||
51 | V4L2_CID_MPEG_VIDEO_BITRATE, | ||
52 | V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, | ||
53 | 0 | ||
54 | }; | ||
55 | |||
56 | /* Take the encoder configuration form the port struct and | ||
57 | * flush it to the hardware. | ||
58 | */ | ||
59 | static void saa7164_encoder_configure(struct saa7164_port *port) | ||
60 | { | ||
61 | struct saa7164_dev *dev = port->dev; | ||
62 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
63 | |||
64 | port->encoder_params.width = port->width; | ||
65 | port->encoder_params.height = port->height; | ||
66 | port->encoder_params.is_50hz = | ||
67 | (port->encodernorm.id & V4L2_STD_625_50) != 0; | ||
68 | |||
69 | /* Set up the DIF (enable it) for analog mode by default */ | ||
70 | saa7164_api_initialize_dif(port); | ||
71 | |||
72 | /* Configure the correct video standard */ | ||
73 | saa7164_api_configure_dif(port, port->encodernorm.id); | ||
74 | |||
75 | /* Ensure the audio decoder is correct configured */ | ||
76 | saa7164_api_set_audio_std(port); | ||
77 | } | ||
78 | |||
79 | static int saa7164_encoder_buffers_dealloc(struct saa7164_port *port) | ||
80 | { | ||
81 | struct list_head *c, *n, *p, *q, *l, *v; | ||
82 | struct saa7164_dev *dev = port->dev; | ||
83 | struct saa7164_buffer *buf; | ||
84 | struct saa7164_user_buffer *ubuf; | ||
85 | |||
86 | /* Remove any allocated buffers */ | ||
87 | mutex_lock(&port->dmaqueue_lock); | ||
88 | |||
89 | dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr); | ||
90 | list_for_each_safe(c, n, &port->dmaqueue.list) { | ||
91 | buf = list_entry(c, struct saa7164_buffer, list); | ||
92 | list_del(c); | ||
93 | saa7164_buffer_dealloc(buf); | ||
94 | } | ||
95 | |||
96 | dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr); | ||
97 | list_for_each_safe(p, q, &port->list_buf_used.list) { | ||
98 | ubuf = list_entry(p, struct saa7164_user_buffer, list); | ||
99 | list_del(p); | ||
100 | saa7164_buffer_dealloc_user(ubuf); | ||
101 | } | ||
102 | |||
103 | dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr); | ||
104 | list_for_each_safe(l, v, &port->list_buf_free.list) { | ||
105 | ubuf = list_entry(l, struct saa7164_user_buffer, list); | ||
106 | list_del(l); | ||
107 | saa7164_buffer_dealloc_user(ubuf); | ||
108 | } | ||
109 | |||
110 | mutex_unlock(&port->dmaqueue_lock); | ||
111 | dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr); | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* Dynamic buffer switch at encoder start time */ | ||
117 | static int saa7164_encoder_buffers_alloc(struct saa7164_port *port) | ||
118 | { | ||
119 | struct saa7164_dev *dev = port->dev; | ||
120 | struct saa7164_buffer *buf; | ||
121 | struct saa7164_user_buffer *ubuf; | ||
122 | struct tmHWStreamParameters *params = &port->hw_streamingparams; | ||
123 | int result = -ENODEV, i; | ||
124 | int len = 0; | ||
125 | |||
126 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
127 | |||
128 | if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { | ||
129 | dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__); | ||
130 | params->samplesperline = 128; | ||
131 | params->numberoflines = 256; | ||
132 | params->pitch = 128; | ||
133 | params->numpagetables = 2 + | ||
134 | ((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE); | ||
135 | } else | ||
136 | if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) { | ||
137 | dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__); | ||
138 | params->samplesperline = 188; | ||
139 | params->numberoflines = 312; | ||
140 | params->pitch = 188; | ||
141 | params->numpagetables = 2 + | ||
142 | ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); | ||
143 | } else | ||
144 | BUG(); | ||
145 | |||
146 | /* Init and establish defaults */ | ||
147 | params->bitspersample = 8; | ||
148 | params->linethreshold = 0; | ||
149 | params->pagetablelistvirt = 0; | ||
150 | params->pagetablelistphys = 0; | ||
151 | params->numpagetableentries = port->hwcfg.buffercount; | ||
152 | |||
153 | /* Allocate the PCI resources, buffers (hard) */ | ||
154 | for (i = 0; i < port->hwcfg.buffercount; i++) { | ||
155 | buf = saa7164_buffer_alloc(port, | ||
156 | params->numberoflines * | ||
157 | params->pitch); | ||
158 | |||
159 | if (!buf) { | ||
160 | printk(KERN_ERR "%s() failed " | ||
161 | "(errno = %d), unable to allocate buffer\n", | ||
162 | __func__, result); | ||
163 | result = -ENOMEM; | ||
164 | goto failed; | ||
165 | } else { | ||
166 | |||
167 | mutex_lock(&port->dmaqueue_lock); | ||
168 | list_add_tail(&buf->list, &port->dmaqueue.list); | ||
169 | mutex_unlock(&port->dmaqueue_lock); | ||
170 | |||
171 | } | ||
172 | } | ||
173 | |||
174 | /* Allocate some kenrel kernel buffers for copying | ||
175 | * to userpsace. | ||
176 | */ | ||
177 | len = params->numberoflines * params->pitch; | ||
178 | |||
179 | if (encoder_buffers < 16) | ||
180 | encoder_buffers = 16; | ||
181 | if (encoder_buffers > 512) | ||
182 | encoder_buffers = 512; | ||
183 | |||
184 | for (i = 0; i < encoder_buffers; i++) { | ||
185 | |||
186 | ubuf = saa7164_buffer_alloc_user(dev, len); | ||
187 | if (ubuf) { | ||
188 | mutex_lock(&port->dmaqueue_lock); | ||
189 | list_add_tail(&ubuf->list, &port->list_buf_free.list); | ||
190 | mutex_unlock(&port->dmaqueue_lock); | ||
191 | } | ||
192 | |||
193 | } | ||
194 | |||
195 | result = 0; | ||
196 | |||
197 | failed: | ||
198 | return result; | ||
199 | } | ||
200 | |||
201 | static int saa7164_encoder_initialize(struct saa7164_port *port) | ||
202 | { | ||
203 | saa7164_encoder_configure(port); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | /* -- V4L2 --------------------------------------------------------- */ | ||
208 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) | ||
209 | { | ||
210 | struct saa7164_encoder_fh *fh = file->private_data; | ||
211 | struct saa7164_port *port = fh->port; | ||
212 | struct saa7164_dev *dev = port->dev; | ||
213 | unsigned int i; | ||
214 | |||
215 | dprintk(DBGLVL_ENC, "%s(id=0x%x)\n", __func__, (u32)*id); | ||
216 | |||
217 | for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) { | ||
218 | if (*id & saa7164_tvnorms[i].id) | ||
219 | break; | ||
220 | } | ||
221 | if (i == ARRAY_SIZE(saa7164_tvnorms)) | ||
222 | return -EINVAL; | ||
223 | |||
224 | port->encodernorm = saa7164_tvnorms[i]; | ||
225 | |||
226 | /* Update the audio decoder while is not running in | ||
227 | * auto detect mode. | ||
228 | */ | ||
229 | saa7164_api_set_audio_std(port); | ||
230 | |||
231 | dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int vidioc_enum_input(struct file *file, void *priv, | ||
237 | struct v4l2_input *i) | ||
238 | { | ||
239 | int n; | ||
240 | |||
241 | char *inputs[] = { "tuner", "composite", "svideo", "aux", | ||
242 | "composite 2", "svideo 2", "aux 2" }; | ||
243 | |||
244 | if (i->index >= 7) | ||
245 | return -EINVAL; | ||
246 | |||
247 | strcpy(i->name, inputs[i->index]); | ||
248 | |||
249 | if (i->index == 0) | ||
250 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
251 | else | ||
252 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
253 | |||
254 | for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++) | ||
255 | i->std |= saa7164_tvnorms[n].id; | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
261 | { | ||
262 | struct saa7164_encoder_fh *fh = file->private_data; | ||
263 | struct saa7164_port *port = fh->port; | ||
264 | struct saa7164_dev *dev = port->dev; | ||
265 | |||
266 | if (saa7164_api_get_videomux(port) != SAA_OK) | ||
267 | return -EIO; | ||
268 | |||
269 | *i = (port->mux_input - 1); | ||
270 | |||
271 | dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, *i); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
277 | { | ||
278 | struct saa7164_encoder_fh *fh = file->private_data; | ||
279 | struct saa7164_port *port = fh->port; | ||
280 | struct saa7164_dev *dev = port->dev; | ||
281 | |||
282 | dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i); | ||
283 | |||
284 | if (i >= 7) | ||
285 | return -EINVAL; | ||
286 | |||
287 | port->mux_input = i + 1; | ||
288 | |||
289 | if (saa7164_api_set_videomux(port) != SAA_OK) | ||
290 | return -EIO; | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
296 | struct v4l2_tuner *t) | ||
297 | { | ||
298 | struct saa7164_encoder_fh *fh = file->private_data; | ||
299 | struct saa7164_port *port = fh->port; | ||
300 | struct saa7164_dev *dev = port->dev; | ||
301 | |||
302 | if (0 != t->index) | ||
303 | return -EINVAL; | ||
304 | |||
305 | strcpy(t->name, "tuner"); | ||
306 | t->type = V4L2_TUNER_ANALOG_TV; | ||
307 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO; | ||
308 | |||
309 | dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
315 | struct v4l2_tuner *t) | ||
316 | { | ||
317 | /* Update the A/V core */ | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
322 | struct v4l2_frequency *f) | ||
323 | { | ||
324 | struct saa7164_encoder_fh *fh = file->private_data; | ||
325 | struct saa7164_port *port = fh->port; | ||
326 | |||
327 | f->type = V4L2_TUNER_ANALOG_TV; | ||
328 | f->frequency = port->freq; | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
334 | struct v4l2_frequency *f) | ||
335 | { | ||
336 | struct saa7164_encoder_fh *fh = file->private_data; | ||
337 | struct saa7164_port *port = fh->port; | ||
338 | struct saa7164_dev *dev = port->dev; | ||
339 | struct saa7164_port *tsport; | ||
340 | struct dvb_frontend *fe; | ||
341 | |||
342 | /* TODO: Pull this for the std */ | ||
343 | struct analog_parameters params = { | ||
344 | .mode = V4L2_TUNER_ANALOG_TV, | ||
345 | .audmode = V4L2_TUNER_MODE_STEREO, | ||
346 | .std = port->encodernorm.id, | ||
347 | .frequency = f->frequency | ||
348 | }; | ||
349 | |||
350 | /* Stop the encoder */ | ||
351 | dprintk(DBGLVL_ENC, "%s() frequency=%d tuner=%d\n", __func__, | ||
352 | f->frequency, f->tuner); | ||
353 | |||
354 | if (f->tuner != 0) | ||
355 | return -EINVAL; | ||
356 | |||
357 | if (f->type != V4L2_TUNER_ANALOG_TV) | ||
358 | return -EINVAL; | ||
359 | |||
360 | port->freq = f->frequency; | ||
361 | |||
362 | /* Update the hardware */ | ||
363 | if (port->nr == SAA7164_PORT_ENC1) | ||
364 | tsport = &dev->ports[SAA7164_PORT_TS1]; | ||
365 | else | ||
366 | if (port->nr == SAA7164_PORT_ENC2) | ||
367 | tsport = &dev->ports[SAA7164_PORT_TS2]; | ||
368 | else | ||
369 | BUG(); | ||
370 | |||
371 | fe = tsport->dvb.frontend; | ||
372 | |||
373 | if (fe && fe->ops.tuner_ops.set_analog_params) | ||
374 | fe->ops.tuner_ops.set_analog_params(fe, ¶ms); | ||
375 | else | ||
376 | printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); | ||
377 | |||
378 | saa7164_encoder_initialize(port); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
384 | struct v4l2_control *ctl) | ||
385 | { | ||
386 | struct saa7164_encoder_fh *fh = file->private_data; | ||
387 | struct saa7164_port *port = fh->port; | ||
388 | struct saa7164_dev *dev = port->dev; | ||
389 | |||
390 | dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__, | ||
391 | ctl->id, ctl->value); | ||
392 | |||
393 | switch (ctl->id) { | ||
394 | case V4L2_CID_BRIGHTNESS: | ||
395 | ctl->value = port->ctl_brightness; | ||
396 | break; | ||
397 | case V4L2_CID_CONTRAST: | ||
398 | ctl->value = port->ctl_contrast; | ||
399 | break; | ||
400 | case V4L2_CID_SATURATION: | ||
401 | ctl->value = port->ctl_saturation; | ||
402 | break; | ||
403 | case V4L2_CID_HUE: | ||
404 | ctl->value = port->ctl_hue; | ||
405 | break; | ||
406 | case V4L2_CID_SHARPNESS: | ||
407 | ctl->value = port->ctl_sharpness; | ||
408 | break; | ||
409 | case V4L2_CID_AUDIO_VOLUME: | ||
410 | ctl->value = port->ctl_volume; | ||
411 | break; | ||
412 | default: | ||
413 | return -EINVAL; | ||
414 | } | ||
415 | |||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
420 | struct v4l2_control *ctl) | ||
421 | { | ||
422 | struct saa7164_encoder_fh *fh = file->private_data; | ||
423 | struct saa7164_port *port = fh->port; | ||
424 | struct saa7164_dev *dev = port->dev; | ||
425 | int ret = 0; | ||
426 | |||
427 | dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__, | ||
428 | ctl->id, ctl->value); | ||
429 | |||
430 | switch (ctl->id) { | ||
431 | case V4L2_CID_BRIGHTNESS: | ||
432 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
433 | port->ctl_brightness = ctl->value; | ||
434 | saa7164_api_set_usercontrol(port, | ||
435 | PU_BRIGHTNESS_CONTROL); | ||
436 | } else | ||
437 | ret = -EINVAL; | ||
438 | break; | ||
439 | case V4L2_CID_CONTRAST: | ||
440 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
441 | port->ctl_contrast = ctl->value; | ||
442 | saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); | ||
443 | } else | ||
444 | ret = -EINVAL; | ||
445 | break; | ||
446 | case V4L2_CID_SATURATION: | ||
447 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
448 | port->ctl_saturation = ctl->value; | ||
449 | saa7164_api_set_usercontrol(port, | ||
450 | PU_SATURATION_CONTROL); | ||
451 | } else | ||
452 | ret = -EINVAL; | ||
453 | break; | ||
454 | case V4L2_CID_HUE: | ||
455 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
456 | port->ctl_hue = ctl->value; | ||
457 | saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); | ||
458 | } else | ||
459 | ret = -EINVAL; | ||
460 | break; | ||
461 | case V4L2_CID_SHARPNESS: | ||
462 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
463 | port->ctl_sharpness = ctl->value; | ||
464 | saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); | ||
465 | } else | ||
466 | ret = -EINVAL; | ||
467 | break; | ||
468 | case V4L2_CID_AUDIO_VOLUME: | ||
469 | if ((ctl->value >= -83) && (ctl->value <= 24)) { | ||
470 | port->ctl_volume = ctl->value; | ||
471 | saa7164_api_set_audio_volume(port, port->ctl_volume); | ||
472 | } else | ||
473 | ret = -EINVAL; | ||
474 | break; | ||
475 | default: | ||
476 | ret = -EINVAL; | ||
477 | } | ||
478 | |||
479 | return ret; | ||
480 | } | ||
481 | |||
482 | static int saa7164_get_ctrl(struct saa7164_port *port, | ||
483 | struct v4l2_ext_control *ctrl) | ||
484 | { | ||
485 | struct saa7164_encoder_params *params = &port->encoder_params; | ||
486 | |||
487 | switch (ctrl->id) { | ||
488 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
489 | ctrl->value = params->bitrate; | ||
490 | break; | ||
491 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
492 | ctrl->value = params->stream_type; | ||
493 | break; | ||
494 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
495 | ctrl->value = params->ctl_mute; | ||
496 | break; | ||
497 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
498 | ctrl->value = params->ctl_aspect; | ||
499 | break; | ||
500 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
501 | ctrl->value = params->bitrate_mode; | ||
502 | break; | ||
503 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
504 | ctrl->value = params->refdist; | ||
505 | break; | ||
506 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
507 | ctrl->value = params->bitrate_peak; | ||
508 | break; | ||
509 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
510 | ctrl->value = params->gop_size; | ||
511 | break; | ||
512 | default: | ||
513 | return -EINVAL; | ||
514 | } | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int vidioc_g_ext_ctrls(struct file *file, void *priv, | ||
519 | struct v4l2_ext_controls *ctrls) | ||
520 | { | ||
521 | struct saa7164_encoder_fh *fh = file->private_data; | ||
522 | struct saa7164_port *port = fh->port; | ||
523 | int i, err = 0; | ||
524 | |||
525 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
526 | for (i = 0; i < ctrls->count; i++) { | ||
527 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
528 | |||
529 | err = saa7164_get_ctrl(port, ctrl); | ||
530 | if (err) { | ||
531 | ctrls->error_idx = i; | ||
532 | break; | ||
533 | } | ||
534 | } | ||
535 | return err; | ||
536 | |||
537 | } | ||
538 | |||
539 | return -EINVAL; | ||
540 | } | ||
541 | |||
542 | static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) | ||
543 | { | ||
544 | int ret = -EINVAL; | ||
545 | |||
546 | switch (ctrl->id) { | ||
547 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
548 | if ((ctrl->value >= ENCODER_MIN_BITRATE) && | ||
549 | (ctrl->value <= ENCODER_MAX_BITRATE)) | ||
550 | ret = 0; | ||
551 | break; | ||
552 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
553 | if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) || | ||
554 | (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)) | ||
555 | ret = 0; | ||
556 | break; | ||
557 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
558 | if ((ctrl->value >= 0) && | ||
559 | (ctrl->value <= 1)) | ||
560 | ret = 0; | ||
561 | break; | ||
562 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
563 | if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) && | ||
564 | (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100)) | ||
565 | ret = 0; | ||
566 | break; | ||
567 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
568 | if ((ctrl->value >= 0) && | ||
569 | (ctrl->value <= 255)) | ||
570 | ret = 0; | ||
571 | break; | ||
572 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
573 | if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) || | ||
574 | (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) | ||
575 | ret = 0; | ||
576 | break; | ||
577 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
578 | if ((ctrl->value >= 1) && | ||
579 | (ctrl->value <= 3)) | ||
580 | ret = 0; | ||
581 | break; | ||
582 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
583 | if ((ctrl->value >= ENCODER_MIN_BITRATE) && | ||
584 | (ctrl->value <= ENCODER_MAX_BITRATE)) | ||
585 | ret = 0; | ||
586 | break; | ||
587 | default: | ||
588 | ret = -EINVAL; | ||
589 | } | ||
590 | |||
591 | return ret; | ||
592 | } | ||
593 | |||
594 | static int vidioc_try_ext_ctrls(struct file *file, void *priv, | ||
595 | struct v4l2_ext_controls *ctrls) | ||
596 | { | ||
597 | int i, err = 0; | ||
598 | |||
599 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
600 | for (i = 0; i < ctrls->count; i++) { | ||
601 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
602 | |||
603 | err = saa7164_try_ctrl(ctrl, 0); | ||
604 | if (err) { | ||
605 | ctrls->error_idx = i; | ||
606 | break; | ||
607 | } | ||
608 | } | ||
609 | return err; | ||
610 | } | ||
611 | |||
612 | return -EINVAL; | ||
613 | } | ||
614 | |||
615 | static int saa7164_set_ctrl(struct saa7164_port *port, | ||
616 | struct v4l2_ext_control *ctrl) | ||
617 | { | ||
618 | struct saa7164_encoder_params *params = &port->encoder_params; | ||
619 | int ret = 0; | ||
620 | |||
621 | switch (ctrl->id) { | ||
622 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
623 | params->bitrate = ctrl->value; | ||
624 | break; | ||
625 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
626 | params->stream_type = ctrl->value; | ||
627 | break; | ||
628 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
629 | params->ctl_mute = ctrl->value; | ||
630 | ret = saa7164_api_audio_mute(port, params->ctl_mute); | ||
631 | if (ret != SAA_OK) { | ||
632 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, | ||
633 | ret); | ||
634 | ret = -EIO; | ||
635 | } | ||
636 | break; | ||
637 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
638 | params->ctl_aspect = ctrl->value; | ||
639 | ret = saa7164_api_set_aspect_ratio(port); | ||
640 | if (ret != SAA_OK) { | ||
641 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, | ||
642 | ret); | ||
643 | ret = -EIO; | ||
644 | } | ||
645 | break; | ||
646 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
647 | params->bitrate_mode = ctrl->value; | ||
648 | break; | ||
649 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
650 | params->refdist = ctrl->value; | ||
651 | break; | ||
652 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
653 | params->bitrate_peak = ctrl->value; | ||
654 | break; | ||
655 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
656 | params->gop_size = ctrl->value; | ||
657 | break; | ||
658 | default: | ||
659 | return -EINVAL; | ||
660 | } | ||
661 | |||
662 | /* TODO: Update the hardware */ | ||
663 | |||
664 | return ret; | ||
665 | } | ||
666 | |||
667 | static int vidioc_s_ext_ctrls(struct file *file, void *priv, | ||
668 | struct v4l2_ext_controls *ctrls) | ||
669 | { | ||
670 | struct saa7164_encoder_fh *fh = file->private_data; | ||
671 | struct saa7164_port *port = fh->port; | ||
672 | int i, err = 0; | ||
673 | |||
674 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
675 | for (i = 0; i < ctrls->count; i++) { | ||
676 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
677 | |||
678 | err = saa7164_try_ctrl(ctrl, 0); | ||
679 | if (err) { | ||
680 | ctrls->error_idx = i; | ||
681 | break; | ||
682 | } | ||
683 | err = saa7164_set_ctrl(port, ctrl); | ||
684 | if (err) { | ||
685 | ctrls->error_idx = i; | ||
686 | break; | ||
687 | } | ||
688 | } | ||
689 | return err; | ||
690 | |||
691 | } | ||
692 | |||
693 | return -EINVAL; | ||
694 | } | ||
695 | |||
696 | static int vidioc_querycap(struct file *file, void *priv, | ||
697 | struct v4l2_capability *cap) | ||
698 | { | ||
699 | struct saa7164_encoder_fh *fh = file->private_data; | ||
700 | struct saa7164_port *port = fh->port; | ||
701 | struct saa7164_dev *dev = port->dev; | ||
702 | |||
703 | strcpy(cap->driver, dev->name); | ||
704 | strlcpy(cap->card, saa7164_boards[dev->board].name, | ||
705 | sizeof(cap->card)); | ||
706 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); | ||
707 | |||
708 | cap->capabilities = | ||
709 | V4L2_CAP_VIDEO_CAPTURE | | ||
710 | V4L2_CAP_READWRITE | | ||
711 | 0; | ||
712 | |||
713 | cap->capabilities |= V4L2_CAP_TUNER; | ||
714 | cap->version = 0; | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
720 | struct v4l2_fmtdesc *f) | ||
721 | { | ||
722 | if (f->index != 0) | ||
723 | return -EINVAL; | ||
724 | |||
725 | strlcpy(f->description, "MPEG", sizeof(f->description)); | ||
726 | f->pixelformat = V4L2_PIX_FMT_MPEG; | ||
727 | |||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
732 | struct v4l2_format *f) | ||
733 | { | ||
734 | struct saa7164_encoder_fh *fh = file->private_data; | ||
735 | struct saa7164_port *port = fh->port; | ||
736 | struct saa7164_dev *dev = port->dev; | ||
737 | |||
738 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
739 | f->fmt.pix.bytesperline = 0; | ||
740 | f->fmt.pix.sizeimage = | ||
741 | port->ts_packet_size * port->ts_packet_count; | ||
742 | f->fmt.pix.colorspace = 0; | ||
743 | f->fmt.pix.width = port->width; | ||
744 | f->fmt.pix.height = port->height; | ||
745 | |||
746 | dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n", | ||
747 | port->width, port->height); | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
753 | struct v4l2_format *f) | ||
754 | { | ||
755 | struct saa7164_encoder_fh *fh = file->private_data; | ||
756 | struct saa7164_port *port = fh->port; | ||
757 | struct saa7164_dev *dev = port->dev; | ||
758 | |||
759 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
760 | f->fmt.pix.bytesperline = 0; | ||
761 | f->fmt.pix.sizeimage = | ||
762 | port->ts_packet_size * port->ts_packet_count; | ||
763 | f->fmt.pix.colorspace = 0; | ||
764 | dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n", | ||
765 | port->width, port->height); | ||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
770 | struct v4l2_format *f) | ||
771 | { | ||
772 | struct saa7164_encoder_fh *fh = file->private_data; | ||
773 | struct saa7164_port *port = fh->port; | ||
774 | struct saa7164_dev *dev = port->dev; | ||
775 | |||
776 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
777 | f->fmt.pix.bytesperline = 0; | ||
778 | f->fmt.pix.sizeimage = | ||
779 | port->ts_packet_size * port->ts_packet_count; | ||
780 | f->fmt.pix.colorspace = 0; | ||
781 | |||
782 | dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", | ||
783 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); | ||
784 | |||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static int vidioc_log_status(struct file *file, void *priv) | ||
789 | { | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int fill_queryctrl(struct saa7164_encoder_params *params, | ||
794 | struct v4l2_queryctrl *c) | ||
795 | { | ||
796 | switch (c->id) { | ||
797 | case V4L2_CID_BRIGHTNESS: | ||
798 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127); | ||
799 | case V4L2_CID_CONTRAST: | ||
800 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66); | ||
801 | case V4L2_CID_SATURATION: | ||
802 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62); | ||
803 | case V4L2_CID_HUE: | ||
804 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128); | ||
805 | case V4L2_CID_SHARPNESS: | ||
806 | return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8); | ||
807 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
808 | return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0); | ||
809 | case V4L2_CID_AUDIO_VOLUME: | ||
810 | return v4l2_ctrl_query_fill(c, -83, 24, 1, 20); | ||
811 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
812 | return v4l2_ctrl_query_fill(c, | ||
813 | ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, | ||
814 | 100000, ENCODER_DEF_BITRATE); | ||
815 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
816 | return v4l2_ctrl_query_fill(c, | ||
817 | V4L2_MPEG_STREAM_TYPE_MPEG2_PS, | ||
818 | V4L2_MPEG_STREAM_TYPE_MPEG2_TS, | ||
819 | 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS); | ||
820 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
821 | return v4l2_ctrl_query_fill(c, | ||
822 | V4L2_MPEG_VIDEO_ASPECT_1x1, | ||
823 | V4L2_MPEG_VIDEO_ASPECT_221x100, | ||
824 | 1, V4L2_MPEG_VIDEO_ASPECT_4x3); | ||
825 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
826 | return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); | ||
827 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
828 | return v4l2_ctrl_query_fill(c, | ||
829 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, | ||
830 | 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); | ||
831 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
832 | return v4l2_ctrl_query_fill(c, | ||
833 | 1, 3, 1, 1); | ||
834 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
835 | return v4l2_ctrl_query_fill(c, | ||
836 | ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, | ||
837 | 100000, ENCODER_DEF_BITRATE); | ||
838 | default: | ||
839 | return -EINVAL; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
844 | struct v4l2_queryctrl *c) | ||
845 | { | ||
846 | struct saa7164_encoder_fh *fh = priv; | ||
847 | struct saa7164_port *port = fh->port; | ||
848 | int i, next; | ||
849 | u32 id = c->id; | ||
850 | |||
851 | memset(c, 0, sizeof(*c)); | ||
852 | |||
853 | next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); | ||
854 | c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; | ||
855 | |||
856 | for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) { | ||
857 | if (next) { | ||
858 | if (c->id < saa7164_v4l2_ctrls[i]) | ||
859 | c->id = saa7164_v4l2_ctrls[i]; | ||
860 | else | ||
861 | continue; | ||
862 | } | ||
863 | |||
864 | if (c->id == saa7164_v4l2_ctrls[i]) | ||
865 | return fill_queryctrl(&port->encoder_params, c); | ||
866 | |||
867 | if (c->id < saa7164_v4l2_ctrls[i]) | ||
868 | break; | ||
869 | } | ||
870 | |||
871 | return -EINVAL; | ||
872 | } | ||
873 | |||
874 | static int saa7164_encoder_stop_port(struct saa7164_port *port) | ||
875 | { | ||
876 | struct saa7164_dev *dev = port->dev; | ||
877 | int ret; | ||
878 | |||
879 | ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); | ||
880 | if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { | ||
881 | printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", | ||
882 | __func__, ret); | ||
883 | ret = -EIO; | ||
884 | } else { | ||
885 | dprintk(DBGLVL_ENC, "%s() Stopped\n", __func__); | ||
886 | ret = 0; | ||
887 | } | ||
888 | |||
889 | return ret; | ||
890 | } | ||
891 | |||
892 | static int saa7164_encoder_acquire_port(struct saa7164_port *port) | ||
893 | { | ||
894 | struct saa7164_dev *dev = port->dev; | ||
895 | int ret; | ||
896 | |||
897 | ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); | ||
898 | if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { | ||
899 | printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", | ||
900 | __func__, ret); | ||
901 | ret = -EIO; | ||
902 | } else { | ||
903 | dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__); | ||
904 | ret = 0; | ||
905 | } | ||
906 | |||
907 | return ret; | ||
908 | } | ||
909 | |||
910 | static int saa7164_encoder_pause_port(struct saa7164_port *port) | ||
911 | { | ||
912 | struct saa7164_dev *dev = port->dev; | ||
913 | int ret; | ||
914 | |||
915 | ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); | ||
916 | if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { | ||
917 | printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", | ||
918 | __func__, ret); | ||
919 | ret = -EIO; | ||
920 | } else { | ||
921 | dprintk(DBGLVL_ENC, "%s() Paused\n", __func__); | ||
922 | ret = 0; | ||
923 | } | ||
924 | |||
925 | return ret; | ||
926 | } | ||
927 | |||
928 | /* Firmware is very windows centric, meaning you have to transition | ||
929 | * the part through AVStream / KS Windows stages, forwards or backwards. | ||
930 | * States are: stopped, acquired (h/w), paused, started. | ||
931 | * We have to leave here will all of the soft buffers on the free list, | ||
932 | * else the cfg_post() func won't have soft buffers to correctly configure. | ||
933 | */ | ||
934 | static int saa7164_encoder_stop_streaming(struct saa7164_port *port) | ||
935 | { | ||
936 | struct saa7164_dev *dev = port->dev; | ||
937 | struct saa7164_buffer *buf; | ||
938 | struct saa7164_user_buffer *ubuf; | ||
939 | struct list_head *c, *n; | ||
940 | int ret; | ||
941 | |||
942 | dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); | ||
943 | |||
944 | ret = saa7164_encoder_pause_port(port); | ||
945 | ret = saa7164_encoder_acquire_port(port); | ||
946 | ret = saa7164_encoder_stop_port(port); | ||
947 | |||
948 | dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__, | ||
949 | port->nr); | ||
950 | |||
951 | /* Reset the state of any allocated buffer resources */ | ||
952 | mutex_lock(&port->dmaqueue_lock); | ||
953 | |||
954 | /* Reset the hard and soft buffer state */ | ||
955 | list_for_each_safe(c, n, &port->dmaqueue.list) { | ||
956 | buf = list_entry(c, struct saa7164_buffer, list); | ||
957 | buf->flags = SAA7164_BUFFER_FREE; | ||
958 | buf->pos = 0; | ||
959 | } | ||
960 | |||
961 | list_for_each_safe(c, n, &port->list_buf_used.list) { | ||
962 | ubuf = list_entry(c, struct saa7164_user_buffer, list); | ||
963 | ubuf->pos = 0; | ||
964 | list_move_tail(&ubuf->list, &port->list_buf_free.list); | ||
965 | } | ||
966 | |||
967 | mutex_unlock(&port->dmaqueue_lock); | ||
968 | |||
969 | /* Free any allocated resources */ | ||
970 | saa7164_encoder_buffers_dealloc(port); | ||
971 | |||
972 | dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr); | ||
973 | |||
974 | return ret; | ||
975 | } | ||
976 | |||
977 | static int saa7164_encoder_start_streaming(struct saa7164_port *port) | ||
978 | { | ||
979 | struct saa7164_dev *dev = port->dev; | ||
980 | int result, ret = 0; | ||
981 | |||
982 | dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); | ||
983 | |||
984 | port->done_first_interrupt = 0; | ||
985 | |||
986 | /* allocate all of the PCIe DMA buffer resources on the fly, | ||
987 | * allowing switching between TS and PS payloads without | ||
988 | * requiring a complete driver reload. | ||
989 | */ | ||
990 | saa7164_encoder_buffers_alloc(port); | ||
991 | |||
992 | /* Configure the encoder with any cache values */ | ||
993 | saa7164_api_set_encoder(port); | ||
994 | saa7164_api_get_encoder(port); | ||
995 | |||
996 | /* Place the empty buffers on the hardware */ | ||
997 | saa7164_buffer_cfg_port(port); | ||
998 | |||
999 | /* Acquire the hardware */ | ||
1000 | result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); | ||
1001 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
1002 | printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", | ||
1003 | __func__, result); | ||
1004 | |||
1005 | /* Stop the hardware, regardless */ | ||
1006 | result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); | ||
1007 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
1008 | printk(KERN_ERR "%s() acquire/forced stop transition " | ||
1009 | "failed, res = 0x%x\n", __func__, result); | ||
1010 | } | ||
1011 | ret = -EIO; | ||
1012 | goto out; | ||
1013 | } else | ||
1014 | dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__); | ||
1015 | |||
1016 | /* Pause the hardware */ | ||
1017 | result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); | ||
1018 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
1019 | printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", | ||
1020 | __func__, result); | ||
1021 | |||
1022 | /* Stop the hardware, regardless */ | ||
1023 | result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); | ||
1024 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
1025 | printk(KERN_ERR "%s() pause/forced stop transition " | ||
1026 | "failed, res = 0x%x\n", __func__, result); | ||
1027 | } | ||
1028 | |||
1029 | ret = -EIO; | ||
1030 | goto out; | ||
1031 | } else | ||
1032 | dprintk(DBGLVL_ENC, "%s() Paused\n", __func__); | ||
1033 | |||
1034 | /* Start the hardware */ | ||
1035 | result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); | ||
1036 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
1037 | printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", | ||
1038 | __func__, result); | ||
1039 | |||
1040 | /* Stop the hardware, regardless */ | ||
1041 | result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); | ||
1042 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
1043 | printk(KERN_ERR "%s() run/forced stop transition " | ||
1044 | "failed, res = 0x%x\n", __func__, result); | ||
1045 | } | ||
1046 | |||
1047 | ret = -EIO; | ||
1048 | } else | ||
1049 | dprintk(DBGLVL_ENC, "%s() Running\n", __func__); | ||
1050 | |||
1051 | out: | ||
1052 | return ret; | ||
1053 | } | ||
1054 | |||
1055 | static int fops_open(struct file *file) | ||
1056 | { | ||
1057 | struct saa7164_dev *dev; | ||
1058 | struct saa7164_port *port; | ||
1059 | struct saa7164_encoder_fh *fh; | ||
1060 | |||
1061 | port = (struct saa7164_port *)video_get_drvdata(video_devdata(file)); | ||
1062 | if (!port) | ||
1063 | return -ENODEV; | ||
1064 | |||
1065 | dev = port->dev; | ||
1066 | |||
1067 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1068 | |||
1069 | /* allocate + initialize per filehandle data */ | ||
1070 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1071 | if (NULL == fh) | ||
1072 | return -ENOMEM; | ||
1073 | |||
1074 | file->private_data = fh; | ||
1075 | fh->port = port; | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1080 | static int fops_release(struct file *file) | ||
1081 | { | ||
1082 | struct saa7164_encoder_fh *fh = file->private_data; | ||
1083 | struct saa7164_port *port = fh->port; | ||
1084 | struct saa7164_dev *dev = port->dev; | ||
1085 | |||
1086 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1087 | |||
1088 | /* Shut device down on last close */ | ||
1089 | if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { | ||
1090 | if (atomic_dec_return(&port->v4l_reader_count) == 0) { | ||
1091 | /* stop mpeg capture then cancel buffers */ | ||
1092 | saa7164_encoder_stop_streaming(port); | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | file->private_data = NULL; | ||
1097 | kfree(fh); | ||
1098 | |||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port) | ||
1103 | { | ||
1104 | struct saa7164_user_buffer *ubuf = 0; | ||
1105 | struct saa7164_dev *dev = port->dev; | ||
1106 | u32 crc; | ||
1107 | |||
1108 | mutex_lock(&port->dmaqueue_lock); | ||
1109 | if (!list_empty(&port->list_buf_used.list)) { | ||
1110 | ubuf = list_first_entry(&port->list_buf_used.list, | ||
1111 | struct saa7164_user_buffer, list); | ||
1112 | |||
1113 | if (crc_checking) { | ||
1114 | crc = crc32(0, ubuf->data, ubuf->actual_size); | ||
1115 | if (crc != ubuf->crc) { | ||
1116 | printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__, | ||
1117 | ubuf, ubuf->crc, crc); | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | } | ||
1122 | mutex_unlock(&port->dmaqueue_lock); | ||
1123 | |||
1124 | dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, ubuf); | ||
1125 | |||
1126 | return ubuf; | ||
1127 | } | ||
1128 | |||
1129 | static ssize_t fops_read(struct file *file, char __user *buffer, | ||
1130 | size_t count, loff_t *pos) | ||
1131 | { | ||
1132 | struct saa7164_encoder_fh *fh = file->private_data; | ||
1133 | struct saa7164_port *port = fh->port; | ||
1134 | struct saa7164_user_buffer *ubuf = NULL; | ||
1135 | struct saa7164_dev *dev = port->dev; | ||
1136 | int ret = 0; | ||
1137 | int rem, cnt; | ||
1138 | u8 *p; | ||
1139 | |||
1140 | port->last_read_msecs_diff = port->last_read_msecs; | ||
1141 | port->last_read_msecs = jiffies_to_msecs(jiffies); | ||
1142 | port->last_read_msecs_diff = port->last_read_msecs - | ||
1143 | port->last_read_msecs_diff; | ||
1144 | |||
1145 | saa7164_histogram_update(&port->read_interval, | ||
1146 | port->last_read_msecs_diff); | ||
1147 | |||
1148 | if (*pos) { | ||
1149 | printk(KERN_ERR "%s() ESPIPE\n", __func__); | ||
1150 | return -ESPIPE; | ||
1151 | } | ||
1152 | |||
1153 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
1154 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | ||
1155 | |||
1156 | if (saa7164_encoder_initialize(port) < 0) { | ||
1157 | printk(KERN_ERR "%s() EINVAL\n", __func__); | ||
1158 | return -EINVAL; | ||
1159 | } | ||
1160 | |||
1161 | saa7164_encoder_start_streaming(port); | ||
1162 | msleep(200); | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | /* blocking wait for buffer */ | ||
1167 | if ((file->f_flags & O_NONBLOCK) == 0) { | ||
1168 | if (wait_event_interruptible(port->wait_read, | ||
1169 | saa7164_enc_next_buf(port))) { | ||
1170 | printk(KERN_ERR "%s() ERESTARTSYS\n", __func__); | ||
1171 | return -ERESTARTSYS; | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | /* Pull the first buffer from the used list */ | ||
1176 | ubuf = saa7164_enc_next_buf(port); | ||
1177 | |||
1178 | while ((count > 0) && ubuf) { | ||
1179 | |||
1180 | /* set remaining bytes to copy */ | ||
1181 | rem = ubuf->actual_size - ubuf->pos; | ||
1182 | cnt = rem > count ? count : rem; | ||
1183 | |||
1184 | p = ubuf->data + ubuf->pos; | ||
1185 | |||
1186 | dprintk(DBGLVL_ENC, | ||
1187 | "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n", | ||
1188 | __func__, (int)count, cnt, rem, ubuf, ubuf->pos); | ||
1189 | |||
1190 | if (copy_to_user(buffer, p, cnt)) { | ||
1191 | printk(KERN_ERR "%s() copy_to_user failed\n", __func__); | ||
1192 | if (!ret) { | ||
1193 | printk(KERN_ERR "%s() EFAULT\n", __func__); | ||
1194 | ret = -EFAULT; | ||
1195 | } | ||
1196 | goto err; | ||
1197 | } | ||
1198 | |||
1199 | ubuf->pos += cnt; | ||
1200 | count -= cnt; | ||
1201 | buffer += cnt; | ||
1202 | ret += cnt; | ||
1203 | |||
1204 | if (ubuf->pos > ubuf->actual_size) { | ||
1205 | printk(KERN_ERR "read() pos > actual, huh?\n"); | ||
1206 | } | ||
1207 | |||
1208 | if (ubuf->pos == ubuf->actual_size) { | ||
1209 | |||
1210 | /* finished with current buffer, take next buffer */ | ||
1211 | |||
1212 | /* Requeue the buffer on the free list */ | ||
1213 | ubuf->pos = 0; | ||
1214 | |||
1215 | mutex_lock(&port->dmaqueue_lock); | ||
1216 | list_move_tail(&ubuf->list, &port->list_buf_free.list); | ||
1217 | mutex_unlock(&port->dmaqueue_lock); | ||
1218 | |||
1219 | /* Dequeue next */ | ||
1220 | if ((file->f_flags & O_NONBLOCK) == 0) { | ||
1221 | if (wait_event_interruptible(port->wait_read, | ||
1222 | saa7164_enc_next_buf(port))) { | ||
1223 | break; | ||
1224 | } | ||
1225 | } | ||
1226 | ubuf = saa7164_enc_next_buf(port); | ||
1227 | } | ||
1228 | } | ||
1229 | err: | ||
1230 | if (!ret && !ubuf) { | ||
1231 | ret = -EAGAIN; | ||
1232 | } | ||
1233 | |||
1234 | return ret; | ||
1235 | } | ||
1236 | |||
1237 | static unsigned int fops_poll(struct file *file, poll_table *wait) | ||
1238 | { | ||
1239 | struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data; | ||
1240 | struct saa7164_port *port = fh->port; | ||
1241 | struct saa7164_user_buffer *ubuf; | ||
1242 | unsigned int mask = 0; | ||
1243 | |||
1244 | port->last_poll_msecs_diff = port->last_poll_msecs; | ||
1245 | port->last_poll_msecs = jiffies_to_msecs(jiffies); | ||
1246 | port->last_poll_msecs_diff = port->last_poll_msecs - | ||
1247 | port->last_poll_msecs_diff; | ||
1248 | |||
1249 | saa7164_histogram_update(&port->poll_interval, | ||
1250 | port->last_poll_msecs_diff); | ||
1251 | |||
1252 | if (!video_is_registered(port->v4l_device)) { | ||
1253 | return -EIO; | ||
1254 | } | ||
1255 | |||
1256 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
1257 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | ||
1258 | if (saa7164_encoder_initialize(port) < 0) | ||
1259 | return -EINVAL; | ||
1260 | saa7164_encoder_start_streaming(port); | ||
1261 | msleep(200); | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | /* blocking wait for buffer */ | ||
1266 | if ((file->f_flags & O_NONBLOCK) == 0) { | ||
1267 | if (wait_event_interruptible(port->wait_read, | ||
1268 | saa7164_enc_next_buf(port))) { | ||
1269 | return -ERESTARTSYS; | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1273 | /* Pull the first buffer from the used list */ | ||
1274 | ubuf = list_first_entry(&port->list_buf_used.list, | ||
1275 | struct saa7164_user_buffer, list); | ||
1276 | |||
1277 | if (ubuf) | ||
1278 | mask |= POLLIN | POLLRDNORM; | ||
1279 | |||
1280 | return mask; | ||
1281 | } | ||
1282 | |||
1283 | static const struct v4l2_file_operations mpeg_fops = { | ||
1284 | .owner = THIS_MODULE, | ||
1285 | .open = fops_open, | ||
1286 | .release = fops_release, | ||
1287 | .read = fops_read, | ||
1288 | .poll = fops_poll, | ||
1289 | .unlocked_ioctl = video_ioctl2, | ||
1290 | }; | ||
1291 | |||
1292 | int saa7164_g_chip_ident(struct file *file, void *fh, | ||
1293 | struct v4l2_dbg_chip_ident *chip) | ||
1294 | { | ||
1295 | struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port; | ||
1296 | struct saa7164_dev *dev = port->dev; | ||
1297 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1298 | |||
1299 | return 0; | ||
1300 | } | ||
1301 | |||
1302 | int saa7164_g_register(struct file *file, void *fh, | ||
1303 | struct v4l2_dbg_register *reg) | ||
1304 | { | ||
1305 | struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port; | ||
1306 | struct saa7164_dev *dev = port->dev; | ||
1307 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1308 | |||
1309 | if (!capable(CAP_SYS_ADMIN)) | ||
1310 | return -EPERM; | ||
1311 | |||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | int saa7164_s_register(struct file *file, void *fh, | ||
1316 | struct v4l2_dbg_register *reg) | ||
1317 | { | ||
1318 | struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port; | ||
1319 | struct saa7164_dev *dev = port->dev; | ||
1320 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1321 | |||
1322 | if (!capable(CAP_SYS_ADMIN)) | ||
1323 | return -EPERM; | ||
1324 | |||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | ||
1329 | .vidioc_s_std = vidioc_s_std, | ||
1330 | .vidioc_enum_input = vidioc_enum_input, | ||
1331 | .vidioc_g_input = vidioc_g_input, | ||
1332 | .vidioc_s_input = vidioc_s_input, | ||
1333 | .vidioc_g_tuner = vidioc_g_tuner, | ||
1334 | .vidioc_s_tuner = vidioc_s_tuner, | ||
1335 | .vidioc_g_frequency = vidioc_g_frequency, | ||
1336 | .vidioc_s_frequency = vidioc_s_frequency, | ||
1337 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1338 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1339 | .vidioc_querycap = vidioc_querycap, | ||
1340 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1341 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1342 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1343 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1344 | .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, | ||
1345 | .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, | ||
1346 | .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, | ||
1347 | .vidioc_log_status = vidioc_log_status, | ||
1348 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1349 | .vidioc_g_chip_ident = saa7164_g_chip_ident, | ||
1350 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1351 | .vidioc_g_register = saa7164_g_register, | ||
1352 | .vidioc_s_register = saa7164_s_register, | ||
1353 | #endif | ||
1354 | }; | ||
1355 | |||
1356 | static struct video_device saa7164_mpeg_template = { | ||
1357 | .name = "saa7164", | ||
1358 | .fops = &mpeg_fops, | ||
1359 | .ioctl_ops = &mpeg_ioctl_ops, | ||
1360 | .minor = -1, | ||
1361 | .tvnorms = SAA7164_NORMS, | ||
1362 | .current_norm = V4L2_STD_NTSC_M, | ||
1363 | }; | ||
1364 | |||
1365 | static struct video_device *saa7164_encoder_alloc( | ||
1366 | struct saa7164_port *port, | ||
1367 | struct pci_dev *pci, | ||
1368 | struct video_device *template, | ||
1369 | char *type) | ||
1370 | { | ||
1371 | struct video_device *vfd; | ||
1372 | struct saa7164_dev *dev = port->dev; | ||
1373 | |||
1374 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1375 | |||
1376 | vfd = video_device_alloc(); | ||
1377 | if (NULL == vfd) | ||
1378 | return NULL; | ||
1379 | |||
1380 | *vfd = *template; | ||
1381 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | ||
1382 | type, saa7164_boards[dev->board].name); | ||
1383 | |||
1384 | vfd->parent = &pci->dev; | ||
1385 | vfd->release = video_device_release; | ||
1386 | return vfd; | ||
1387 | } | ||
1388 | |||
1389 | int saa7164_encoder_register(struct saa7164_port *port) | ||
1390 | { | ||
1391 | struct saa7164_dev *dev = port->dev; | ||
1392 | int result = -ENODEV; | ||
1393 | |||
1394 | dprintk(DBGLVL_ENC, "%s()\n", __func__); | ||
1395 | |||
1396 | if (port->type != SAA7164_MPEG_ENCODER) | ||
1397 | BUG(); | ||
1398 | |||
1399 | /* Sanity check that the PCI configuration space is active */ | ||
1400 | if (port->hwcfg.BARLocation == 0) { | ||
1401 | printk(KERN_ERR "%s() failed " | ||
1402 | "(errno = %d), NO PCI configuration\n", | ||
1403 | __func__, result); | ||
1404 | result = -ENOMEM; | ||
1405 | goto failed; | ||
1406 | } | ||
1407 | |||
1408 | /* Establish encoder defaults here */ | ||
1409 | /* Set default TV standard */ | ||
1410 | port->encodernorm = saa7164_tvnorms[0]; | ||
1411 | port->width = 720; | ||
1412 | port->mux_input = 1; /* Composite */ | ||
1413 | port->video_format = EU_VIDEO_FORMAT_MPEG_2; | ||
1414 | port->audio_format = 0; | ||
1415 | port->video_resolution = 0; | ||
1416 | port->ctl_brightness = 127; | ||
1417 | port->ctl_contrast = 66; | ||
1418 | port->ctl_hue = 128; | ||
1419 | port->ctl_saturation = 62; | ||
1420 | port->ctl_sharpness = 8; | ||
1421 | port->encoder_params.bitrate = ENCODER_DEF_BITRATE; | ||
1422 | port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE; | ||
1423 | port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; | ||
1424 | port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS; | ||
1425 | port->encoder_params.ctl_mute = 0; | ||
1426 | port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
1427 | port->encoder_params.refdist = 1; | ||
1428 | port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE; | ||
1429 | |||
1430 | if (port->encodernorm.id & V4L2_STD_525_60) | ||
1431 | port->height = 480; | ||
1432 | else | ||
1433 | port->height = 576; | ||
1434 | |||
1435 | /* Allocate and register the video device node */ | ||
1436 | port->v4l_device = saa7164_encoder_alloc(port, | ||
1437 | dev->pci, &saa7164_mpeg_template, "mpeg"); | ||
1438 | |||
1439 | if (port->v4l_device == NULL) { | ||
1440 | printk(KERN_INFO "%s: can't allocate mpeg device\n", | ||
1441 | dev->name); | ||
1442 | result = -ENOMEM; | ||
1443 | goto failed; | ||
1444 | } | ||
1445 | |||
1446 | video_set_drvdata(port->v4l_device, port); | ||
1447 | result = video_register_device(port->v4l_device, | ||
1448 | VFL_TYPE_GRABBER, -1); | ||
1449 | if (result < 0) { | ||
1450 | printk(KERN_INFO "%s: can't register mpeg device\n", | ||
1451 | dev->name); | ||
1452 | /* TODO: We're going to leak here if we don't dealloc | ||
1453 | The buffers above. The unreg function can't deal wit it. | ||
1454 | */ | ||
1455 | goto failed; | ||
1456 | } | ||
1457 | |||
1458 | printk(KERN_INFO "%s: registered device video%d [mpeg]\n", | ||
1459 | dev->name, port->v4l_device->num); | ||
1460 | |||
1461 | /* Configure the hardware defaults */ | ||
1462 | saa7164_api_set_videomux(port); | ||
1463 | saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL); | ||
1464 | saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); | ||
1465 | saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); | ||
1466 | saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL); | ||
1467 | saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); | ||
1468 | saa7164_api_audio_mute(port, 0); | ||
1469 | saa7164_api_set_audio_volume(port, 20); | ||
1470 | saa7164_api_set_aspect_ratio(port); | ||
1471 | |||
1472 | /* Disable audio standard detection, it's buggy */ | ||
1473 | saa7164_api_set_audio_detection(port, 0); | ||
1474 | |||
1475 | saa7164_api_set_encoder(port); | ||
1476 | saa7164_api_get_encoder(port); | ||
1477 | |||
1478 | result = 0; | ||
1479 | failed: | ||
1480 | return result; | ||
1481 | } | ||
1482 | |||
1483 | void saa7164_encoder_unregister(struct saa7164_port *port) | ||
1484 | { | ||
1485 | struct saa7164_dev *dev = port->dev; | ||
1486 | |||
1487 | dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr); | ||
1488 | |||
1489 | if (port->type != SAA7164_MPEG_ENCODER) | ||
1490 | BUG(); | ||
1491 | |||
1492 | if (port->v4l_device) { | ||
1493 | if (port->v4l_device->minor != -1) | ||
1494 | video_unregister_device(port->v4l_device); | ||
1495 | else | ||
1496 | video_device_release(port->v4l_device); | ||
1497 | |||
1498 | port->v4l_device = NULL; | ||
1499 | } | ||
1500 | |||
1501 | dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr); | ||
1502 | } | ||
1503 | |||
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c index 270245d275a..484533c32bb 100644 --- a/drivers/media/video/saa7164/saa7164-fw.c +++ b/drivers/media/video/saa7164/saa7164-fw.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -24,11 +24,11 @@ | |||
24 | 24 | ||
25 | #include "saa7164.h" | 25 | #include "saa7164.h" |
26 | 26 | ||
27 | #define SAA7164_REV2_FIRMWARE "v4l-saa7164-1.0.2.fw" | 27 | #define SAA7164_REV2_FIRMWARE "NXP7164-2010-03-10.1.fw" |
28 | #define SAA7164_REV2_FIRMWARE_SIZE 3978608 | 28 | #define SAA7164_REV2_FIRMWARE_SIZE 4019072 |
29 | 29 | ||
30 | #define SAA7164_REV3_FIRMWARE "v4l-saa7164-1.0.3.fw" | 30 | #define SAA7164_REV3_FIRMWARE "NXP7164-2010-03-10.1.fw" |
31 | #define SAA7164_REV3_FIRMWARE_SIZE 3978608 | 31 | #define SAA7164_REV3_FIRMWARE_SIZE 4019072 |
32 | 32 | ||
33 | struct fw_header { | 33 | struct fw_header { |
34 | u32 firmwaresize; | 34 | u32 firmwaresize; |
@@ -604,6 +604,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) | |||
604 | } | 604 | } |
605 | } | 605 | } |
606 | 606 | ||
607 | dev->firmwareloaded = 1; | ||
607 | ret = 0; | 608 | ret = 0; |
608 | 609 | ||
609 | out: | 610 | out: |
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c index e1ae9b01bf0..b5167d33650 100644 --- a/drivers/media/video/saa7164/saa7164-i2c.c +++ b/drivers/media/video/saa7164/saa7164-i2c.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h index 06be4c13d5b..2bbf81583d3 100644 --- a/drivers/media/video/saa7164/saa7164-reg.h +++ b/drivers/media/video/saa7164/saa7164-reg.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -60,6 +60,7 @@ | |||
60 | #define GET_STRING_CONTROL 0x03 | 60 | #define GET_STRING_CONTROL 0x03 |
61 | #define GET_LANGUAGE_CONTROL 0x05 | 61 | #define GET_LANGUAGE_CONTROL 0x05 |
62 | #define SET_POWER_CONTROL 0x07 | 62 | #define SET_POWER_CONTROL 0x07 |
63 | #define GET_FW_STATUS_CONTROL 0x08 | ||
63 | #define GET_FW_VERSION_CONTROL 0x09 | 64 | #define GET_FW_VERSION_CONTROL 0x09 |
64 | #define SET_DEBUG_LEVEL_CONTROL 0x0B | 65 | #define SET_DEBUG_LEVEL_CONTROL 0x0B |
65 | #define GET_DEBUG_DATA_CONTROL 0x0C | 66 | #define GET_DEBUG_DATA_CONTROL 0x0C |
@@ -156,11 +157,63 @@ | |||
156 | #define EXU_INTERRUPT_CONTROL 0x03 | 157 | #define EXU_INTERRUPT_CONTROL 0x03 |
157 | 158 | ||
158 | /* State Transition and args */ | 159 | /* State Transition and args */ |
160 | #define SAA_PROBE_CONTROL 0x01 | ||
161 | #define SAA_COMMIT_CONTROL 0x02 | ||
159 | #define SAA_STATE_CONTROL 0x03 | 162 | #define SAA_STATE_CONTROL 0x03 |
160 | #define SAA_DMASTATE_STOP 0x00 | 163 | #define SAA_DMASTATE_STOP 0x00 |
161 | #define SAA_DMASTATE_ACQUIRE 0x01 | 164 | #define SAA_DMASTATE_ACQUIRE 0x01 |
162 | #define SAA_DMASTATE_PAUSE 0x02 | 165 | #define SAA_DMASTATE_PAUSE 0x02 |
163 | #define SAA_DMASTATE_RUN 0x03 | 166 | #define SAA_DMASTATE_RUN 0x03 |
164 | 167 | ||
165 | /* Hardware registers */ | 168 | /* A/V Mux Input Selector */ |
166 | 169 | #define SU_INPUT_SELECT_CONTROL 0x01 | |
170 | |||
171 | /* Encoder Profiles */ | ||
172 | #define EU_PROFILE_PS_DVD 0x06 | ||
173 | #define EU_PROFILE_TS_HQ 0x09 | ||
174 | #define EU_VIDEO_FORMAT_MPEG_2 0x02 | ||
175 | |||
176 | /* Tuner */ | ||
177 | #define TU_AUDIO_MODE_CONTROL 0x17 | ||
178 | |||
179 | /* Video Formats */ | ||
180 | #define TU_STANDARD_CONTROL 0x00 | ||
181 | #define TU_STANDARD_AUTO_CONTROL 0x01 | ||
182 | #define TU_STANDARD_NONE 0x00 | ||
183 | #define TU_STANDARD_NTSC_M 0x01 | ||
184 | #define TU_STANDARD_PAL_I 0x08 | ||
185 | #define TU_STANDARD_MANUAL 0x00 | ||
186 | #define TU_STANDARD_AUTO 0x01 | ||
187 | |||
188 | /* Video Controls */ | ||
189 | #define PU_BRIGHTNESS_CONTROL 0x02 | ||
190 | #define PU_CONTRAST_CONTROL 0x03 | ||
191 | #define PU_HUE_CONTROL 0x06 | ||
192 | #define PU_SATURATION_CONTROL 0x07 | ||
193 | #define PU_SHARPNESS_CONTROL 0x08 | ||
194 | |||
195 | /* Audio Controls */ | ||
196 | #define MUTE_CONTROL 0x01 | ||
197 | #define VOLUME_CONTROL 0x02 | ||
198 | #define AUDIO_DEFAULT_CONTROL 0x0D | ||
199 | |||
200 | /* Default Volume Levels */ | ||
201 | #define TMHW_LEV_ADJ_DECLEV_DEFAULT 0x00 | ||
202 | #define TMHW_LEV_ADJ_MONOLEV_DEFAULT 0x00 | ||
203 | #define TMHW_LEV_ADJ_NICLEV_DEFAULT 0x00 | ||
204 | #define TMHW_LEV_ADJ_SAPLEV_DEFAULT 0x00 | ||
205 | #define TMHW_LEV_ADJ_ADCLEV_DEFAULT 0x00 | ||
206 | |||
207 | /* Encoder Related Commands */ | ||
208 | #define EU_PROFILE_CONTROL 0x00 | ||
209 | #define EU_VIDEO_FORMAT_CONTROL 0x01 | ||
210 | #define EU_VIDEO_BIT_RATE_CONTROL 0x02 | ||
211 | #define EU_VIDEO_RESOLUTION_CONTROL 0x03 | ||
212 | #define EU_VIDEO_GOP_STRUCTURE_CONTROL 0x04 | ||
213 | #define EU_VIDEO_INPUT_ASPECT_CONTROL 0x0A | ||
214 | #define EU_AUDIO_FORMAT_CONTROL 0x0C | ||
215 | #define EU_AUDIO_BIT_RATE_CONTROL 0x0D | ||
216 | |||
217 | /* Firmware Debugging */ | ||
218 | #define SET_DEBUG_LEVEL_CONTROL 0x0B | ||
219 | #define GET_DEBUG_DATA_CONTROL 0x0C | ||
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h index 99093f23aae..df1d2997fa6 100644 --- a/drivers/media/video/saa7164/saa7164-types.h +++ b/drivers/media/video/saa7164/saa7164-types.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -24,7 +24,7 @@ | |||
24 | /* Some structues are passed directly to/from the firmware and | 24 | /* Some structues are passed directly to/from the firmware and |
25 | * have strict alignment requirements. This is one of them. | 25 | * have strict alignment requirements. This is one of them. |
26 | */ | 26 | */ |
27 | typedef struct { | 27 | struct tmComResHWDescr { |
28 | u8 bLength; | 28 | u8 bLength; |
29 | u8 bDescriptorType; | 29 | u8 bDescriptorType; |
30 | u8 bDescriptorSubtype; | 30 | u8 bDescriptorSubtype; |
@@ -37,14 +37,14 @@ typedef struct { | |||
37 | u32 dwHostMemoryRegionSize; | 37 | u32 dwHostMemoryRegionSize; |
38 | u32 dwHostHibernatMemRegion; | 38 | u32 dwHostHibernatMemRegion; |
39 | u32 dwHostHibernatMemRegionSize; | 39 | u32 dwHostHibernatMemRegionSize; |
40 | } __attribute__((packed)) tmComResHWDescr_t; | 40 | } __attribute__((packed)); |
41 | 41 | ||
42 | /* This is DWORD aligned on windows but I can't find the right | 42 | /* This is DWORD aligned on windows but I can't find the right |
43 | * gcc syntax to match the binary data from the device. | 43 | * gcc syntax to match the binary data from the device. |
44 | * I've manually padded with Reserved[3] bytes to match the hardware, | 44 | * I've manually padded with Reserved[3] bytes to match the hardware, |
45 | * but this could break if GCC decies to pack in a different way. | 45 | * but this could break if GCC decies to pack in a different way. |
46 | */ | 46 | */ |
47 | typedef struct { | 47 | struct tmComResInterfaceDescr { |
48 | u8 bLength; | 48 | u8 bLength; |
49 | u8 bDescriptorType; | 49 | u8 bDescriptorType; |
50 | u8 bDescriptorSubtype; | 50 | u8 bDescriptorSubtype; |
@@ -56,52 +56,52 @@ typedef struct { | |||
56 | u8 bDebugInterruptId; | 56 | u8 bDebugInterruptId; |
57 | u8 BARLocation; | 57 | u8 BARLocation; |
58 | u8 Reserved[3]; | 58 | u8 Reserved[3]; |
59 | } tmComResInterfaceDescr_t; | 59 | }; |
60 | 60 | ||
61 | typedef struct { | 61 | struct tmComResBusDescr { |
62 | u64 CommandRing; | 62 | u64 CommandRing; |
63 | u64 ResponseRing; | 63 | u64 ResponseRing; |
64 | u32 CommandWrite; | 64 | u32 CommandWrite; |
65 | u32 CommandRead; | 65 | u32 CommandRead; |
66 | u32 ResponseWrite; | 66 | u32 ResponseWrite; |
67 | u32 ResponseRead; | 67 | u32 ResponseRead; |
68 | } tmComResBusDescr_t; | 68 | }; |
69 | 69 | ||
70 | typedef enum { | 70 | enum tmBusType { |
71 | NONE = 0, | 71 | NONE = 0, |
72 | TYPE_BUS_PCI = 1, | 72 | TYPE_BUS_PCI = 1, |
73 | TYPE_BUS_PCIe = 2, | 73 | TYPE_BUS_PCIe = 2, |
74 | TYPE_BUS_USB = 3, | 74 | TYPE_BUS_USB = 3, |
75 | TYPE_BUS_I2C = 4 | 75 | TYPE_BUS_I2C = 4 |
76 | } tmBusType_t; | 76 | }; |
77 | 77 | ||
78 | typedef struct { | 78 | struct tmComResBusInfo { |
79 | tmBusType_t Type; | 79 | enum tmBusType Type; |
80 | u16 m_wMaxReqSize; | 80 | u16 m_wMaxReqSize; |
81 | u8 *m_pdwSetRing; | 81 | u8 *m_pdwSetRing; |
82 | u32 m_dwSizeSetRing; | 82 | u32 m_dwSizeSetRing; |
83 | u8 *m_pdwGetRing; | 83 | u8 *m_pdwGetRing; |
84 | u32 m_dwSizeGetRing; | 84 | u32 m_dwSizeGetRing; |
85 | u32 *m_pdwSetWritePos; | 85 | u32 m_dwSetWritePos; |
86 | u32 *m_pdwSetReadPos; | 86 | u32 m_dwSetReadPos; |
87 | u32 *m_pdwGetWritePos; | 87 | u32 m_dwGetWritePos; |
88 | u32 *m_pdwGetReadPos; | 88 | u32 m_dwGetReadPos; |
89 | 89 | ||
90 | /* All access is protected */ | 90 | /* All access is protected */ |
91 | struct mutex lock; | 91 | struct mutex lock; |
92 | 92 | ||
93 | } tmComResBusInfo_t; | 93 | }; |
94 | 94 | ||
95 | typedef struct { | 95 | struct tmComResInfo { |
96 | u8 id; | 96 | u8 id; |
97 | u8 flags; | 97 | u8 flags; |
98 | u16 size; | 98 | u16 size; |
99 | u32 command; | 99 | u32 command; |
100 | u16 controlselector; | 100 | u16 controlselector; |
101 | u8 seqno; | 101 | u8 seqno; |
102 | } __attribute__((packed)) tmComResInfo_t; | 102 | } __attribute__((packed)); |
103 | 103 | ||
104 | typedef enum { | 104 | enum tmComResCmd { |
105 | SET_CUR = 0x01, | 105 | SET_CUR = 0x01, |
106 | GET_CUR = 0x81, | 106 | GET_CUR = 0x81, |
107 | GET_MIN = 0x82, | 107 | GET_MIN = 0x82, |
@@ -110,7 +110,7 @@ typedef enum { | |||
110 | GET_LEN = 0x85, | 110 | GET_LEN = 0x85, |
111 | GET_INFO = 0x86, | 111 | GET_INFO = 0x86, |
112 | GET_DEF = 0x87 | 112 | GET_DEF = 0x87 |
113 | } tmComResCmd_t; | 113 | }; |
114 | 114 | ||
115 | struct cmd { | 115 | struct cmd { |
116 | u8 seqno; | 116 | u8 seqno; |
@@ -121,20 +121,20 @@ struct cmd { | |||
121 | wait_queue_head_t wait; | 121 | wait_queue_head_t wait; |
122 | }; | 122 | }; |
123 | 123 | ||
124 | typedef struct { | 124 | struct tmDescriptor { |
125 | u32 pathid; | 125 | u32 pathid; |
126 | u32 size; | 126 | u32 size; |
127 | void *descriptor; | 127 | void *descriptor; |
128 | } tmDescriptor_t; | 128 | }; |
129 | 129 | ||
130 | typedef struct { | 130 | struct tmComResDescrHeader { |
131 | u8 len; | 131 | u8 len; |
132 | u8 type; | 132 | u8 type; |
133 | u8 subtype; | 133 | u8 subtype; |
134 | u8 unitid; | 134 | u8 unitid; |
135 | } __attribute__((packed)) tmComResDescrHeader_t; | 135 | } __attribute__((packed)); |
136 | 136 | ||
137 | typedef struct { | 137 | struct tmComResExtDevDescrHeader { |
138 | u8 len; | 138 | u8 len; |
139 | u8 type; | 139 | u8 type; |
140 | u8 subtype; | 140 | u8 subtype; |
@@ -144,22 +144,22 @@ typedef struct { | |||
144 | u32 numgpiopins; | 144 | u32 numgpiopins; |
145 | u8 numgpiogroups; | 145 | u8 numgpiogroups; |
146 | u8 controlsize; | 146 | u8 controlsize; |
147 | } __attribute__((packed)) tmComResExtDevDescrHeader_t; | 147 | } __attribute__((packed)); |
148 | 148 | ||
149 | typedef struct { | 149 | struct tmComResGPIO { |
150 | u32 pin; | 150 | u32 pin; |
151 | u8 state; | 151 | u8 state; |
152 | } __attribute__((packed)) tmComResGPIO_t; | 152 | } __attribute__((packed)); |
153 | 153 | ||
154 | typedef struct { | 154 | struct tmComResPathDescrHeader { |
155 | u8 len; | 155 | u8 len; |
156 | u8 type; | 156 | u8 type; |
157 | u8 subtype; | 157 | u8 subtype; |
158 | u8 pathid; | 158 | u8 pathid; |
159 | } __attribute__((packed)) tmComResPathDescrHeader_t; | 159 | } __attribute__((packed)); |
160 | 160 | ||
161 | /* terminaltype */ | 161 | /* terminaltype */ |
162 | typedef enum { | 162 | enum tmComResTermType { |
163 | ITT_ANTENNA = 0x0203, | 163 | ITT_ANTENNA = 0x0203, |
164 | LINE_CONNECTOR = 0x0603, | 164 | LINE_CONNECTOR = 0x0603, |
165 | SPDIF_CONNECTOR = 0x0605, | 165 | SPDIF_CONNECTOR = 0x0605, |
@@ -167,9 +167,9 @@ typedef enum { | |||
167 | SVIDEO_CONNECTOR = 0x0402, | 167 | SVIDEO_CONNECTOR = 0x0402, |
168 | COMPONENT_CONNECTOR = 0x0403, | 168 | COMPONENT_CONNECTOR = 0x0403, |
169 | STANDARD_DMA = 0xF101 | 169 | STANDARD_DMA = 0xF101 |
170 | } tmComResTermType_t; | 170 | }; |
171 | 171 | ||
172 | typedef struct { | 172 | struct tmComResAntTermDescrHeader { |
173 | u8 len; | 173 | u8 len; |
174 | u8 type; | 174 | u8 type; |
175 | u8 subtype; | 175 | u8 subtype; |
@@ -178,9 +178,9 @@ typedef struct { | |||
178 | u8 assocterminal; | 178 | u8 assocterminal; |
179 | u8 iterminal; | 179 | u8 iterminal; |
180 | u8 controlsize; | 180 | u8 controlsize; |
181 | } __attribute__((packed)) tmComResAntTermDescrHeader_t; | 181 | } __attribute__((packed)); |
182 | 182 | ||
183 | typedef struct { | 183 | struct tmComResTunerDescrHeader { |
184 | u8 len; | 184 | u8 len; |
185 | u8 type; | 185 | u8 type; |
186 | u8 subtype; | 186 | u8 subtype; |
@@ -190,9 +190,9 @@ typedef struct { | |||
190 | u32 tuningstandards; | 190 | u32 tuningstandards; |
191 | u8 controlsize; | 191 | u8 controlsize; |
192 | u32 controls; | 192 | u32 controls; |
193 | } __attribute__((packed)) tmComResTunerDescrHeader_t; | 193 | } __attribute__((packed)); |
194 | 194 | ||
195 | typedef enum { | 195 | enum tmBufferFlag { |
196 | /* the buffer does not contain any valid data */ | 196 | /* the buffer does not contain any valid data */ |
197 | TM_BUFFER_FLAG_EMPTY, | 197 | TM_BUFFER_FLAG_EMPTY, |
198 | 198 | ||
@@ -201,23 +201,23 @@ typedef enum { | |||
201 | 201 | ||
202 | /* the buffer is the dummy buffer - TODO??? */ | 202 | /* the buffer is the dummy buffer - TODO??? */ |
203 | TM_BUFFER_FLAG_DUMMY_BUFFER | 203 | TM_BUFFER_FLAG_DUMMY_BUFFER |
204 | } tmBufferFlag_t; | 204 | }; |
205 | 205 | ||
206 | typedef struct { | 206 | struct tmBuffer { |
207 | u64 *pagetablevirt; | 207 | u64 *pagetablevirt; |
208 | u64 pagetablephys; | 208 | u64 pagetablephys; |
209 | u16 offset; | 209 | u16 offset; |
210 | u8 *context; | 210 | u8 *context; |
211 | u64 timestamp; | 211 | u64 timestamp; |
212 | tmBufferFlag_t BufferFlag_t; | 212 | enum tmBufferFlag BufferFlag; |
213 | u32 lostbuffers; | 213 | u32 lostbuffers; |
214 | u32 validbuffers; | 214 | u32 validbuffers; |
215 | u64 *dummypagevirt; | 215 | u64 *dummypagevirt; |
216 | u64 dummypagephys; | 216 | u64 dummypagephys; |
217 | u64 *addressvirt; | 217 | u64 *addressvirt; |
218 | } tmBuffer_t; | 218 | }; |
219 | 219 | ||
220 | typedef struct { | 220 | struct tmHWStreamParameters { |
221 | u32 bitspersample; | 221 | u32 bitspersample; |
222 | u32 samplesperline; | 222 | u32 samplesperline; |
223 | u32 numberoflines; | 223 | u32 numberoflines; |
@@ -227,15 +227,15 @@ typedef struct { | |||
227 | u64 *pagetablelistphys; | 227 | u64 *pagetablelistphys; |
228 | u32 numpagetables; | 228 | u32 numpagetables; |
229 | u32 numpagetableentries; | 229 | u32 numpagetableentries; |
230 | } tmHWStreamParameters_t; | 230 | }; |
231 | 231 | ||
232 | typedef struct { | 232 | struct tmStreamParameters { |
233 | tmHWStreamParameters_t HWStreamParameters_t; | 233 | struct tmHWStreamParameters HWStreamParameters; |
234 | u64 qwDummyPageTablePhys; | 234 | u64 qwDummyPageTablePhys; |
235 | u64 *pDummyPageTableVirt; | 235 | u64 *pDummyPageTableVirt; |
236 | } tmStreamParameters_t; | 236 | }; |
237 | 237 | ||
238 | typedef struct { | 238 | struct tmComResDMATermDescrHeader { |
239 | u8 len; | 239 | u8 len; |
240 | u8 type; | 240 | u8 type; |
241 | u8 subtyle; | 241 | u8 subtyle; |
@@ -251,7 +251,7 @@ typedef struct { | |||
251 | u8 metadatasize; | 251 | u8 metadatasize; |
252 | u8 numformats; | 252 | u8 numformats; |
253 | u8 controlsize; | 253 | u8 controlsize; |
254 | } __attribute__((packed)) tmComResDMATermDescrHeader_t; | 254 | } __attribute__((packed)); |
255 | 255 | ||
256 | /* | 256 | /* |
257 | * | 257 | * |
@@ -274,7 +274,7 @@ typedef struct { | |||
274 | * Data is to be ignored by the application. | 274 | * Data is to be ignored by the application. |
275 | * | 275 | * |
276 | */ | 276 | */ |
277 | typedef struct { | 277 | struct tmComResTSFormatDescrHeader { |
278 | u8 len; | 278 | u8 len; |
279 | u8 type; | 279 | u8 type; |
280 | u8 subtype; | 280 | u8 subtype; |
@@ -283,5 +283,160 @@ typedef struct { | |||
283 | u8 bPacketLength; | 283 | u8 bPacketLength; |
284 | u8 bStrideLength; | 284 | u8 bStrideLength; |
285 | u8 guidStrideFormat[16]; | 285 | u8 guidStrideFormat[16]; |
286 | } __attribute__((packed)) tmComResTSFormatDescrHeader_t; | 286 | } __attribute__((packed)); |
287 | |||
288 | /* Encoder related structures */ | ||
289 | |||
290 | /* A/V Mux Selector */ | ||
291 | struct tmComResSelDescrHeader { | ||
292 | u8 len; | ||
293 | u8 type; | ||
294 | u8 subtype; | ||
295 | u8 unitid; | ||
296 | u8 nrinpins; | ||
297 | u8 sourceid; | ||
298 | } __attribute__((packed)); | ||
299 | |||
300 | /* A/V Audio processor definitions */ | ||
301 | struct tmComResProcDescrHeader { | ||
302 | u8 len; | ||
303 | u8 type; | ||
304 | u8 subtype; | ||
305 | u8 unitid; | ||
306 | u8 sourceid; | ||
307 | u16 wreserved; | ||
308 | u8 controlsize; | ||
309 | } __attribute__((packed)); | ||
310 | |||
311 | /* Video bitrate control message */ | ||
312 | #define EU_VIDEO_BIT_RATE_MODE_CONSTANT (0) | ||
313 | #define EU_VIDEO_BIT_RATE_MODE_VARIABLE_AVERAGE (1) | ||
314 | #define EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK (2) | ||
315 | struct tmComResEncVideoBitRate { | ||
316 | u8 ucVideoBitRateMode; | ||
317 | u32 dwVideoBitRate; | ||
318 | u32 dwVideoBitRatePeak; | ||
319 | } __attribute__((packed)); | ||
320 | |||
321 | /* Video Encoder Aspect Ratio message */ | ||
322 | struct tmComResEncVideoInputAspectRatio { | ||
323 | u8 width; | ||
324 | u8 height; | ||
325 | } __attribute__((packed)); | ||
326 | |||
327 | /* Video Encoder GOP IBP message */ | ||
328 | /* 1. IPPPPPPPPPPPPPP */ | ||
329 | /* 2. IBPBPBPBPBPBPBP */ | ||
330 | /* 3. IBBPBBPBBPBBP */ | ||
331 | #define SAA7164_ENCODER_DEFAULT_GOP_DIST (1) | ||
332 | #define SAA7164_ENCODER_DEFAULT_GOP_SIZE (15) | ||
333 | struct tmComResEncVideoGopStructure { | ||
334 | u8 ucGOPSize; /* GOP Size 12, 15 */ | ||
335 | u8 ucRefFrameDist; /* Reference Frame Distance */ | ||
336 | } __attribute__((packed)); | ||
337 | |||
338 | /* Encoder processor definition */ | ||
339 | struct tmComResEncoderDescrHeader { | ||
340 | u8 len; | ||
341 | u8 type; | ||
342 | u8 subtype; | ||
343 | u8 unitid; | ||
344 | u8 vsourceid; | ||
345 | u8 asourceid; | ||
346 | u8 iunit; | ||
347 | u32 dwmControlCap; | ||
348 | u32 dwmProfileCap; | ||
349 | u32 dwmVidFormatCap; | ||
350 | u8 bmVidBitrateCap; | ||
351 | u16 wmVidResolutionsCap; | ||
352 | u16 wmVidFrmRateCap; | ||
353 | u32 dwmAudFormatCap; | ||
354 | u8 bmAudBitrateCap; | ||
355 | } __attribute__((packed)); | ||
356 | |||
357 | /* Audio processor definition */ | ||
358 | struct tmComResAFeatureDescrHeader { | ||
359 | u8 len; | ||
360 | u8 type; | ||
361 | u8 subtype; | ||
362 | u8 unitid; | ||
363 | u8 sourceid; | ||
364 | u8 controlsize; | ||
365 | } __attribute__((packed)); | ||
366 | |||
367 | /* Audio control messages */ | ||
368 | struct tmComResAudioDefaults { | ||
369 | u8 ucDecoderLevel; | ||
370 | u8 ucDecoderFM_Level; | ||
371 | u8 ucMonoLevel; | ||
372 | u8 ucNICAM_Level; | ||
373 | u8 ucSAP_Level; | ||
374 | u8 ucADC_Level; | ||
375 | } __attribute__((packed)); | ||
376 | |||
377 | /* Audio bitrate control message */ | ||
378 | struct tmComResEncAudioBitRate { | ||
379 | u8 ucAudioBitRateMode; | ||
380 | u32 dwAudioBitRate; | ||
381 | u32 dwAudioBitRatePeak; | ||
382 | } __attribute__((packed)); | ||
383 | |||
384 | /* Tuner / AV Decoder messages */ | ||
385 | struct tmComResTunerStandard { | ||
386 | u8 std; | ||
387 | u32 country; | ||
388 | } __attribute__((packed)); | ||
389 | |||
390 | struct tmComResTunerStandardAuto { | ||
391 | u8 mode; | ||
392 | } __attribute__((packed)); | ||
393 | |||
394 | /* EEPROM definition for PS stream types */ | ||
395 | struct tmComResPSFormatDescrHeader { | ||
396 | u8 len; | ||
397 | u8 type; | ||
398 | u8 subtype; | ||
399 | u8 bFormatIndex; | ||
400 | u16 wPacketLength; | ||
401 | u16 wPackLength; | ||
402 | u8 bPackDataType; | ||
403 | } __attribute__((packed)); | ||
404 | |||
405 | /* VBI control structure */ | ||
406 | struct tmComResVBIFormatDescrHeader { | ||
407 | u8 len; | ||
408 | u8 type; | ||
409 | u8 subtype; /* VS_FORMAT_VBI */ | ||
410 | u8 bFormatIndex; | ||
411 | u32 VideoStandard; /* See KS_AnalogVideoStandard, NTSC = 1 */ | ||
412 | u8 StartLine; /* NTSC Start = 10 */ | ||
413 | u8 EndLine; /* NTSC = 21 */ | ||
414 | u8 FieldRate; /* 60 for NTSC */ | ||
415 | u8 bNumLines; /* Unsed - scheduled for removal */ | ||
416 | } __attribute__((packed)); | ||
417 | |||
418 | struct tmComResProbeCommit { | ||
419 | u16 bmHint; | ||
420 | u8 bFormatIndex; | ||
421 | u8 bFrameIndex; | ||
422 | } __attribute__((packed)); | ||
423 | |||
424 | struct tmComResDebugSetLevel { | ||
425 | u32 dwDebugLevel; | ||
426 | } __attribute__((packed)); | ||
427 | |||
428 | struct tmComResDebugGetData { | ||
429 | u32 dwResult; | ||
430 | u8 ucDebugData[256]; | ||
431 | } __attribute__((packed)); | ||
287 | 432 | ||
433 | struct tmFwInfoStruct { | ||
434 | u32 status; | ||
435 | u32 mode; | ||
436 | u32 devicespec; | ||
437 | u32 deviceinst; | ||
438 | u32 CPULoad; | ||
439 | u32 RemainHeap; | ||
440 | u32 CPUClock; | ||
441 | u32 RAMSpeed; | ||
442 | } __attribute__((packed)); | ||
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c new file mode 100644 index 00000000000..323c7cdca37 --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-vbi.c | |||
@@ -0,0 +1,1375 @@ | |||
1 | /* | ||
2 | * Driver for the NXP SAA7164 PCIe bridge | ||
3 | * | ||
4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include "saa7164.h" | ||
23 | |||
24 | static struct saa7164_tvnorm saa7164_tvnorms[] = { | ||
25 | { | ||
26 | .name = "NTSC-M", | ||
27 | .id = V4L2_STD_NTSC_M, | ||
28 | }, { | ||
29 | .name = "NTSC-JP", | ||
30 | .id = V4L2_STD_NTSC_M_JP, | ||
31 | } | ||
32 | }; | ||
33 | |||
34 | static const u32 saa7164_v4l2_ctrls[] = { | ||
35 | 0 | ||
36 | }; | ||
37 | |||
38 | /* Take the encoder configuration from the port struct and | ||
39 | * flush it to the hardware. | ||
40 | */ | ||
41 | static void saa7164_vbi_configure(struct saa7164_port *port) | ||
42 | { | ||
43 | struct saa7164_dev *dev = port->dev; | ||
44 | dprintk(DBGLVL_VBI, "%s()\n", __func__); | ||
45 | |||
46 | port->vbi_params.width = port->width; | ||
47 | port->vbi_params.height = port->height; | ||
48 | port->vbi_params.is_50hz = | ||
49 | (port->encodernorm.id & V4L2_STD_625_50) != 0; | ||
50 | |||
51 | /* Set up the DIF (enable it) for analog mode by default */ | ||
52 | saa7164_api_initialize_dif(port); | ||
53 | |||
54 | // /* Configure the correct video standard */ | ||
55 | // saa7164_api_configure_dif(port, port->encodernorm.id); | ||
56 | |||
57 | // /* Ensure the audio decoder is correct configured */ | ||
58 | // saa7164_api_set_audio_std(port); | ||
59 | dprintk(DBGLVL_VBI, "%s() ends\n", __func__); | ||
60 | } | ||
61 | |||
62 | static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port) | ||
63 | { | ||
64 | struct list_head *c, *n, *p, *q, *l, *v; | ||
65 | struct saa7164_dev *dev = port->dev; | ||
66 | struct saa7164_buffer *buf; | ||
67 | struct saa7164_user_buffer *ubuf; | ||
68 | |||
69 | /* Remove any allocated buffers */ | ||
70 | mutex_lock(&port->dmaqueue_lock); | ||
71 | |||
72 | dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr); | ||
73 | list_for_each_safe(c, n, &port->dmaqueue.list) { | ||
74 | buf = list_entry(c, struct saa7164_buffer, list); | ||
75 | list_del(c); | ||
76 | saa7164_buffer_dealloc(buf); | ||
77 | } | ||
78 | |||
79 | dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr); | ||
80 | list_for_each_safe(p, q, &port->list_buf_used.list) { | ||
81 | ubuf = list_entry(p, struct saa7164_user_buffer, list); | ||
82 | list_del(p); | ||
83 | saa7164_buffer_dealloc_user(ubuf); | ||
84 | } | ||
85 | |||
86 | dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr); | ||
87 | list_for_each_safe(l, v, &port->list_buf_free.list) { | ||
88 | ubuf = list_entry(l, struct saa7164_user_buffer, list); | ||
89 | list_del(l); | ||
90 | saa7164_buffer_dealloc_user(ubuf); | ||
91 | } | ||
92 | |||
93 | mutex_unlock(&port->dmaqueue_lock); | ||
94 | dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | /* Dynamic buffer switch at vbi start time */ | ||
100 | static int saa7164_vbi_buffers_alloc(struct saa7164_port *port) | ||
101 | { | ||
102 | struct saa7164_dev *dev = port->dev; | ||
103 | struct saa7164_buffer *buf; | ||
104 | struct saa7164_user_buffer *ubuf; | ||
105 | struct tmHWStreamParameters *params = &port->hw_streamingparams; | ||
106 | int result = -ENODEV, i; | ||
107 | int len = 0; | ||
108 | |||
109 | dprintk(DBGLVL_VBI, "%s()\n", __func__); | ||
110 | |||
111 | /* TODO: NTSC SPECIFIC */ | ||
112 | /* Init and establish defaults */ | ||
113 | params->samplesperline = 1440; | ||
114 | params->numberoflines = 12; | ||
115 | params->numberoflines = 18; | ||
116 | params->pitch = 1600; | ||
117 | params->pitch = 1440; | ||
118 | params->numpagetables = 2 + | ||
119 | ((params->numberoflines * params->pitch) / PAGE_SIZE); | ||
120 | params->bitspersample = 8; | ||
121 | params->linethreshold = 0; | ||
122 | params->pagetablelistvirt = 0; | ||
123 | params->pagetablelistphys = 0; | ||
124 | params->numpagetableentries = port->hwcfg.buffercount; | ||
125 | |||
126 | /* Allocate the PCI resources, buffers (hard) */ | ||
127 | for (i = 0; i < port->hwcfg.buffercount; i++) { | ||
128 | buf = saa7164_buffer_alloc(port, | ||
129 | params->numberoflines * | ||
130 | params->pitch); | ||
131 | |||
132 | if (!buf) { | ||
133 | printk(KERN_ERR "%s() failed " | ||
134 | "(errno = %d), unable to allocate buffer\n", | ||
135 | __func__, result); | ||
136 | result = -ENOMEM; | ||
137 | goto failed; | ||
138 | } else { | ||
139 | |||
140 | mutex_lock(&port->dmaqueue_lock); | ||
141 | list_add_tail(&buf->list, &port->dmaqueue.list); | ||
142 | mutex_unlock(&port->dmaqueue_lock); | ||
143 | |||
144 | } | ||
145 | } | ||
146 | |||
147 | /* Allocate some kenrel kernel buffers for copying | ||
148 | * to userpsace. | ||
149 | */ | ||
150 | len = params->numberoflines * params->pitch; | ||
151 | |||
152 | if (vbi_buffers < 16) | ||
153 | vbi_buffers = 16; | ||
154 | if (vbi_buffers > 512) | ||
155 | vbi_buffers = 512; | ||
156 | |||
157 | for (i = 0; i < vbi_buffers; i++) { | ||
158 | |||
159 | ubuf = saa7164_buffer_alloc_user(dev, len); | ||
160 | if (ubuf) { | ||
161 | mutex_lock(&port->dmaqueue_lock); | ||
162 | list_add_tail(&ubuf->list, &port->list_buf_free.list); | ||
163 | mutex_unlock(&port->dmaqueue_lock); | ||
164 | } | ||
165 | |||
166 | } | ||
167 | |||
168 | result = 0; | ||
169 | |||
170 | failed: | ||
171 | return result; | ||
172 | } | ||
173 | |||
174 | |||
175 | static int saa7164_vbi_initialize(struct saa7164_port *port) | ||
176 | { | ||
177 | saa7164_vbi_configure(port); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | /* -- V4L2 --------------------------------------------------------- */ | ||
182 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) | ||
183 | { | ||
184 | struct saa7164_vbi_fh *fh = file->private_data; | ||
185 | struct saa7164_port *port = fh->port; | ||
186 | struct saa7164_dev *dev = port->dev; | ||
187 | unsigned int i; | ||
188 | |||
189 | dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id); | ||
190 | |||
191 | for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) { | ||
192 | if (*id & saa7164_tvnorms[i].id) | ||
193 | break; | ||
194 | } | ||
195 | if (i == ARRAY_SIZE(saa7164_tvnorms)) | ||
196 | return -EINVAL; | ||
197 | |||
198 | port->encodernorm = saa7164_tvnorms[i]; | ||
199 | |||
200 | /* Update the audio decoder while is not running in | ||
201 | * auto detect mode. | ||
202 | */ | ||
203 | saa7164_api_set_audio_std(port); | ||
204 | |||
205 | dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static int vidioc_enum_input(struct file *file, void *priv, | ||
211 | struct v4l2_input *i) | ||
212 | { | ||
213 | int n; | ||
214 | |||
215 | char *inputs[] = { "tuner", "composite", "svideo", "aux", | ||
216 | "composite 2", "svideo 2", "aux 2" }; | ||
217 | |||
218 | if (i->index >= 7) | ||
219 | return -EINVAL; | ||
220 | |||
221 | strcpy(i->name, inputs[i->index]); | ||
222 | |||
223 | if (i->index == 0) | ||
224 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
225 | else | ||
226 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
227 | |||
228 | for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++) | ||
229 | i->std |= saa7164_tvnorms[n].id; | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
235 | { | ||
236 | struct saa7164_vbi_fh *fh = file->private_data; | ||
237 | struct saa7164_port *port = fh->port; | ||
238 | struct saa7164_dev *dev = port->dev; | ||
239 | |||
240 | if (saa7164_api_get_videomux(port) != SAA_OK) | ||
241 | return -EIO; | ||
242 | |||
243 | *i = (port->mux_input - 1); | ||
244 | |||
245 | dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
251 | { | ||
252 | struct saa7164_vbi_fh *fh = file->private_data; | ||
253 | struct saa7164_port *port = fh->port; | ||
254 | struct saa7164_dev *dev = port->dev; | ||
255 | |||
256 | dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i); | ||
257 | |||
258 | if (i >= 7) | ||
259 | return -EINVAL; | ||
260 | |||
261 | port->mux_input = i + 1; | ||
262 | |||
263 | if (saa7164_api_set_videomux(port) != SAA_OK) | ||
264 | return -EIO; | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
270 | struct v4l2_tuner *t) | ||
271 | { | ||
272 | struct saa7164_vbi_fh *fh = file->private_data; | ||
273 | struct saa7164_port *port = fh->port; | ||
274 | struct saa7164_dev *dev = port->dev; | ||
275 | |||
276 | if (0 != t->index) | ||
277 | return -EINVAL; | ||
278 | |||
279 | strcpy(t->name, "tuner"); | ||
280 | t->type = V4L2_TUNER_ANALOG_TV; | ||
281 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO; | ||
282 | |||
283 | dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
289 | struct v4l2_tuner *t) | ||
290 | { | ||
291 | /* Update the A/V core */ | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
296 | struct v4l2_frequency *f) | ||
297 | { | ||
298 | struct saa7164_vbi_fh *fh = file->private_data; | ||
299 | struct saa7164_port *port = fh->port; | ||
300 | |||
301 | f->type = V4L2_TUNER_ANALOG_TV; | ||
302 | f->frequency = port->freq; | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
308 | struct v4l2_frequency *f) | ||
309 | { | ||
310 | struct saa7164_vbi_fh *fh = file->private_data; | ||
311 | struct saa7164_port *port = fh->port; | ||
312 | struct saa7164_dev *dev = port->dev; | ||
313 | struct saa7164_port *tsport; | ||
314 | struct dvb_frontend *fe; | ||
315 | |||
316 | /* TODO: Pull this for the std */ | ||
317 | struct analog_parameters params = { | ||
318 | .mode = V4L2_TUNER_ANALOG_TV, | ||
319 | .audmode = V4L2_TUNER_MODE_STEREO, | ||
320 | .std = port->encodernorm.id, | ||
321 | .frequency = f->frequency | ||
322 | }; | ||
323 | |||
324 | /* Stop the encoder */ | ||
325 | dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__, | ||
326 | f->frequency, f->tuner); | ||
327 | |||
328 | if (f->tuner != 0) | ||
329 | return -EINVAL; | ||
330 | |||
331 | if (f->type != V4L2_TUNER_ANALOG_TV) | ||
332 | return -EINVAL; | ||
333 | |||
334 | port->freq = f->frequency; | ||
335 | |||
336 | /* Update the hardware */ | ||
337 | if (port->nr == SAA7164_PORT_VBI1) | ||
338 | tsport = &dev->ports[SAA7164_PORT_TS1]; | ||
339 | else | ||
340 | if (port->nr == SAA7164_PORT_VBI2) | ||
341 | tsport = &dev->ports[SAA7164_PORT_TS2]; | ||
342 | else | ||
343 | BUG(); | ||
344 | |||
345 | fe = tsport->dvb.frontend; | ||
346 | |||
347 | if (fe && fe->ops.tuner_ops.set_analog_params) | ||
348 | fe->ops.tuner_ops.set_analog_params(fe, ¶ms); | ||
349 | else | ||
350 | printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); | ||
351 | |||
352 | saa7164_vbi_initialize(port); | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
358 | struct v4l2_control *ctl) | ||
359 | { | ||
360 | struct saa7164_vbi_fh *fh = file->private_data; | ||
361 | struct saa7164_port *port = fh->port; | ||
362 | struct saa7164_dev *dev = port->dev; | ||
363 | |||
364 | dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__, | ||
365 | ctl->id, ctl->value); | ||
366 | |||
367 | switch (ctl->id) { | ||
368 | case V4L2_CID_BRIGHTNESS: | ||
369 | ctl->value = port->ctl_brightness; | ||
370 | break; | ||
371 | case V4L2_CID_CONTRAST: | ||
372 | ctl->value = port->ctl_contrast; | ||
373 | break; | ||
374 | case V4L2_CID_SATURATION: | ||
375 | ctl->value = port->ctl_saturation; | ||
376 | break; | ||
377 | case V4L2_CID_HUE: | ||
378 | ctl->value = port->ctl_hue; | ||
379 | break; | ||
380 | case V4L2_CID_SHARPNESS: | ||
381 | ctl->value = port->ctl_sharpness; | ||
382 | break; | ||
383 | case V4L2_CID_AUDIO_VOLUME: | ||
384 | ctl->value = port->ctl_volume; | ||
385 | break; | ||
386 | default: | ||
387 | return -EINVAL; | ||
388 | } | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
394 | struct v4l2_control *ctl) | ||
395 | { | ||
396 | struct saa7164_vbi_fh *fh = file->private_data; | ||
397 | struct saa7164_port *port = fh->port; | ||
398 | struct saa7164_dev *dev = port->dev; | ||
399 | int ret = 0; | ||
400 | |||
401 | dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__, | ||
402 | ctl->id, ctl->value); | ||
403 | |||
404 | switch (ctl->id) { | ||
405 | case V4L2_CID_BRIGHTNESS: | ||
406 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
407 | port->ctl_brightness = ctl->value; | ||
408 | saa7164_api_set_usercontrol(port, | ||
409 | PU_BRIGHTNESS_CONTROL); | ||
410 | } else | ||
411 | ret = -EINVAL; | ||
412 | break; | ||
413 | case V4L2_CID_CONTRAST: | ||
414 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
415 | port->ctl_contrast = ctl->value; | ||
416 | saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); | ||
417 | } else | ||
418 | ret = -EINVAL; | ||
419 | break; | ||
420 | case V4L2_CID_SATURATION: | ||
421 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
422 | port->ctl_saturation = ctl->value; | ||
423 | saa7164_api_set_usercontrol(port, | ||
424 | PU_SATURATION_CONTROL); | ||
425 | } else | ||
426 | ret = -EINVAL; | ||
427 | break; | ||
428 | case V4L2_CID_HUE: | ||
429 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
430 | port->ctl_hue = ctl->value; | ||
431 | saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); | ||
432 | } else | ||
433 | ret = -EINVAL; | ||
434 | break; | ||
435 | case V4L2_CID_SHARPNESS: | ||
436 | if ((ctl->value >= 0) && (ctl->value <= 255)) { | ||
437 | port->ctl_sharpness = ctl->value; | ||
438 | saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); | ||
439 | } else | ||
440 | ret = -EINVAL; | ||
441 | break; | ||
442 | case V4L2_CID_AUDIO_VOLUME: | ||
443 | if ((ctl->value >= -83) && (ctl->value <= 24)) { | ||
444 | port->ctl_volume = ctl->value; | ||
445 | saa7164_api_set_audio_volume(port, port->ctl_volume); | ||
446 | } else | ||
447 | ret = -EINVAL; | ||
448 | break; | ||
449 | default: | ||
450 | ret = -EINVAL; | ||
451 | } | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static int saa7164_get_ctrl(struct saa7164_port *port, | ||
457 | struct v4l2_ext_control *ctrl) | ||
458 | { | ||
459 | struct saa7164_vbi_params *params = &port->vbi_params; | ||
460 | |||
461 | switch (ctrl->id) { | ||
462 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
463 | ctrl->value = params->stream_type; | ||
464 | break; | ||
465 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
466 | ctrl->value = params->ctl_mute; | ||
467 | break; | ||
468 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
469 | ctrl->value = params->ctl_aspect; | ||
470 | break; | ||
471 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
472 | ctrl->value = params->refdist; | ||
473 | break; | ||
474 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
475 | ctrl->value = params->gop_size; | ||
476 | break; | ||
477 | default: | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static int vidioc_g_ext_ctrls(struct file *file, void *priv, | ||
484 | struct v4l2_ext_controls *ctrls) | ||
485 | { | ||
486 | struct saa7164_vbi_fh *fh = file->private_data; | ||
487 | struct saa7164_port *port = fh->port; | ||
488 | int i, err = 0; | ||
489 | |||
490 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
491 | for (i = 0; i < ctrls->count; i++) { | ||
492 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
493 | |||
494 | err = saa7164_get_ctrl(port, ctrl); | ||
495 | if (err) { | ||
496 | ctrls->error_idx = i; | ||
497 | break; | ||
498 | } | ||
499 | } | ||
500 | return err; | ||
501 | |||
502 | } | ||
503 | |||
504 | return -EINVAL; | ||
505 | } | ||
506 | |||
507 | static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) | ||
508 | { | ||
509 | int ret = -EINVAL; | ||
510 | |||
511 | switch (ctrl->id) { | ||
512 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
513 | if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) || | ||
514 | (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)) | ||
515 | ret = 0; | ||
516 | break; | ||
517 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
518 | if ((ctrl->value >= 0) && | ||
519 | (ctrl->value <= 1)) | ||
520 | ret = 0; | ||
521 | break; | ||
522 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
523 | if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) && | ||
524 | (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100)) | ||
525 | ret = 0; | ||
526 | break; | ||
527 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
528 | if ((ctrl->value >= 0) && | ||
529 | (ctrl->value <= 255)) | ||
530 | ret = 0; | ||
531 | break; | ||
532 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
533 | if ((ctrl->value >= 1) && | ||
534 | (ctrl->value <= 3)) | ||
535 | ret = 0; | ||
536 | break; | ||
537 | default: | ||
538 | ret = -EINVAL; | ||
539 | } | ||
540 | |||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | static int vidioc_try_ext_ctrls(struct file *file, void *priv, | ||
545 | struct v4l2_ext_controls *ctrls) | ||
546 | { | ||
547 | int i, err = 0; | ||
548 | |||
549 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
550 | for (i = 0; i < ctrls->count; i++) { | ||
551 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
552 | |||
553 | err = saa7164_try_ctrl(ctrl, 0); | ||
554 | if (err) { | ||
555 | ctrls->error_idx = i; | ||
556 | break; | ||
557 | } | ||
558 | } | ||
559 | return err; | ||
560 | } | ||
561 | |||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | static int saa7164_set_ctrl(struct saa7164_port *port, | ||
566 | struct v4l2_ext_control *ctrl) | ||
567 | { | ||
568 | struct saa7164_vbi_params *params = &port->vbi_params; | ||
569 | int ret = 0; | ||
570 | |||
571 | switch (ctrl->id) { | ||
572 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
573 | params->stream_type = ctrl->value; | ||
574 | break; | ||
575 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
576 | params->ctl_mute = ctrl->value; | ||
577 | ret = saa7164_api_audio_mute(port, params->ctl_mute); | ||
578 | if (ret != SAA_OK) { | ||
579 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, | ||
580 | ret); | ||
581 | ret = -EIO; | ||
582 | } | ||
583 | break; | ||
584 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
585 | params->ctl_aspect = ctrl->value; | ||
586 | ret = saa7164_api_set_aspect_ratio(port); | ||
587 | if (ret != SAA_OK) { | ||
588 | printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, | ||
589 | ret); | ||
590 | ret = -EIO; | ||
591 | } | ||
592 | break; | ||
593 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
594 | params->refdist = ctrl->value; | ||
595 | break; | ||
596 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
597 | params->gop_size = ctrl->value; | ||
598 | break; | ||
599 | default: | ||
600 | return -EINVAL; | ||
601 | } | ||
602 | |||
603 | /* TODO: Update the hardware */ | ||
604 | |||
605 | return ret; | ||
606 | } | ||
607 | |||
608 | static int vidioc_s_ext_ctrls(struct file *file, void *priv, | ||
609 | struct v4l2_ext_controls *ctrls) | ||
610 | { | ||
611 | struct saa7164_vbi_fh *fh = file->private_data; | ||
612 | struct saa7164_port *port = fh->port; | ||
613 | int i, err = 0; | ||
614 | |||
615 | if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
616 | for (i = 0; i < ctrls->count; i++) { | ||
617 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
618 | |||
619 | err = saa7164_try_ctrl(ctrl, 0); | ||
620 | if (err) { | ||
621 | ctrls->error_idx = i; | ||
622 | break; | ||
623 | } | ||
624 | err = saa7164_set_ctrl(port, ctrl); | ||
625 | if (err) { | ||
626 | ctrls->error_idx = i; | ||
627 | break; | ||
628 | } | ||
629 | } | ||
630 | return err; | ||
631 | |||
632 | } | ||
633 | |||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
637 | static int vidioc_querycap(struct file *file, void *priv, | ||
638 | struct v4l2_capability *cap) | ||
639 | { | ||
640 | struct saa7164_vbi_fh *fh = file->private_data; | ||
641 | struct saa7164_port *port = fh->port; | ||
642 | struct saa7164_dev *dev = port->dev; | ||
643 | |||
644 | strcpy(cap->driver, dev->name); | ||
645 | strlcpy(cap->card, saa7164_boards[dev->board].name, | ||
646 | sizeof(cap->card)); | ||
647 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); | ||
648 | |||
649 | cap->capabilities = | ||
650 | V4L2_CAP_VBI_CAPTURE | | ||
651 | V4L2_CAP_READWRITE | | ||
652 | 0; | ||
653 | |||
654 | cap->capabilities |= V4L2_CAP_TUNER; | ||
655 | cap->version = 0; | ||
656 | |||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
661 | struct v4l2_fmtdesc *f) | ||
662 | { | ||
663 | if (f->index != 0) | ||
664 | return -EINVAL; | ||
665 | |||
666 | strlcpy(f->description, "VBI", sizeof(f->description)); | ||
667 | f->pixelformat = V4L2_PIX_FMT_MPEG; | ||
668 | |||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
673 | struct v4l2_format *f) | ||
674 | { | ||
675 | struct saa7164_vbi_fh *fh = file->private_data; | ||
676 | struct saa7164_port *port = fh->port; | ||
677 | struct saa7164_dev *dev = port->dev; | ||
678 | |||
679 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
680 | f->fmt.pix.bytesperline = 0; | ||
681 | f->fmt.pix.sizeimage = | ||
682 | port->ts_packet_size * port->ts_packet_count; | ||
683 | f->fmt.pix.colorspace = 0; | ||
684 | f->fmt.pix.width = port->width; | ||
685 | f->fmt.pix.height = port->height; | ||
686 | |||
687 | dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n", | ||
688 | port->width, port->height); | ||
689 | |||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
694 | struct v4l2_format *f) | ||
695 | { | ||
696 | struct saa7164_vbi_fh *fh = file->private_data; | ||
697 | struct saa7164_port *port = fh->port; | ||
698 | struct saa7164_dev *dev = port->dev; | ||
699 | |||
700 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
701 | f->fmt.pix.bytesperline = 0; | ||
702 | f->fmt.pix.sizeimage = | ||
703 | port->ts_packet_size * port->ts_packet_count; | ||
704 | f->fmt.pix.colorspace = 0; | ||
705 | dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n", | ||
706 | port->width, port->height); | ||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
711 | struct v4l2_format *f) | ||
712 | { | ||
713 | struct saa7164_vbi_fh *fh = file->private_data; | ||
714 | struct saa7164_port *port = fh->port; | ||
715 | struct saa7164_dev *dev = port->dev; | ||
716 | |||
717 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
718 | f->fmt.pix.bytesperline = 0; | ||
719 | f->fmt.pix.sizeimage = | ||
720 | port->ts_packet_size * port->ts_packet_count; | ||
721 | f->fmt.pix.colorspace = 0; | ||
722 | |||
723 | dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", | ||
724 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static int vidioc_log_status(struct file *file, void *priv) | ||
730 | { | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static int fill_queryctrl(struct saa7164_vbi_params *params, | ||
735 | struct v4l2_queryctrl *c) | ||
736 | { | ||
737 | switch (c->id) { | ||
738 | case V4L2_CID_BRIGHTNESS: | ||
739 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127); | ||
740 | case V4L2_CID_CONTRAST: | ||
741 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66); | ||
742 | case V4L2_CID_SATURATION: | ||
743 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62); | ||
744 | case V4L2_CID_HUE: | ||
745 | return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128); | ||
746 | case V4L2_CID_SHARPNESS: | ||
747 | return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8); | ||
748 | case V4L2_CID_MPEG_AUDIO_MUTE: | ||
749 | return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0); | ||
750 | case V4L2_CID_AUDIO_VOLUME: | ||
751 | return v4l2_ctrl_query_fill(c, -83, 24, 1, 20); | ||
752 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
753 | return v4l2_ctrl_query_fill(c, | ||
754 | V4L2_MPEG_STREAM_TYPE_MPEG2_PS, | ||
755 | V4L2_MPEG_STREAM_TYPE_MPEG2_TS, | ||
756 | 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS); | ||
757 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
758 | return v4l2_ctrl_query_fill(c, | ||
759 | V4L2_MPEG_VIDEO_ASPECT_1x1, | ||
760 | V4L2_MPEG_VIDEO_ASPECT_221x100, | ||
761 | 1, V4L2_MPEG_VIDEO_ASPECT_4x3); | ||
762 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
763 | return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); | ||
764 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
765 | return v4l2_ctrl_query_fill(c, | ||
766 | 1, 3, 1, 1); | ||
767 | default: | ||
768 | return -EINVAL; | ||
769 | } | ||
770 | } | ||
771 | |||
772 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
773 | struct v4l2_queryctrl *c) | ||
774 | { | ||
775 | struct saa7164_vbi_fh *fh = priv; | ||
776 | struct saa7164_port *port = fh->port; | ||
777 | int i, next; | ||
778 | u32 id = c->id; | ||
779 | |||
780 | memset(c, 0, sizeof(*c)); | ||
781 | |||
782 | next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); | ||
783 | c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; | ||
784 | |||
785 | for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) { | ||
786 | if (next) { | ||
787 | if (c->id < saa7164_v4l2_ctrls[i]) | ||
788 | c->id = saa7164_v4l2_ctrls[i]; | ||
789 | else | ||
790 | continue; | ||
791 | } | ||
792 | |||
793 | if (c->id == saa7164_v4l2_ctrls[i]) | ||
794 | return fill_queryctrl(&port->vbi_params, c); | ||
795 | |||
796 | if (c->id < saa7164_v4l2_ctrls[i]) | ||
797 | break; | ||
798 | } | ||
799 | |||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | static int saa7164_vbi_stop_port(struct saa7164_port *port) | ||
804 | { | ||
805 | struct saa7164_dev *dev = port->dev; | ||
806 | int ret; | ||
807 | |||
808 | ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); | ||
809 | if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { | ||
810 | printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", | ||
811 | __func__, ret); | ||
812 | ret = -EIO; | ||
813 | } else { | ||
814 | dprintk(DBGLVL_VBI, "%s() Stopped\n", __func__); | ||
815 | ret = 0; | ||
816 | } | ||
817 | |||
818 | return ret; | ||
819 | } | ||
820 | |||
821 | static int saa7164_vbi_acquire_port(struct saa7164_port *port) | ||
822 | { | ||
823 | struct saa7164_dev *dev = port->dev; | ||
824 | int ret; | ||
825 | |||
826 | ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); | ||
827 | if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { | ||
828 | printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", | ||
829 | __func__, ret); | ||
830 | ret = -EIO; | ||
831 | } else { | ||
832 | dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__); | ||
833 | ret = 0; | ||
834 | } | ||
835 | |||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | static int saa7164_vbi_pause_port(struct saa7164_port *port) | ||
840 | { | ||
841 | struct saa7164_dev *dev = port->dev; | ||
842 | int ret; | ||
843 | |||
844 | ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); | ||
845 | if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { | ||
846 | printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", | ||
847 | __func__, ret); | ||
848 | ret = -EIO; | ||
849 | } else { | ||
850 | dprintk(DBGLVL_VBI, "%s() Paused\n", __func__); | ||
851 | ret = 0; | ||
852 | } | ||
853 | |||
854 | return ret; | ||
855 | } | ||
856 | |||
857 | /* Firmware is very windows centric, meaning you have to transition | ||
858 | * the part through AVStream / KS Windows stages, forwards or backwards. | ||
859 | * States are: stopped, acquired (h/w), paused, started. | ||
860 | * We have to leave here will all of the soft buffers on the free list, | ||
861 | * else the cfg_post() func won't have soft buffers to correctly configure. | ||
862 | */ | ||
863 | static int saa7164_vbi_stop_streaming(struct saa7164_port *port) | ||
864 | { | ||
865 | struct saa7164_dev *dev = port->dev; | ||
866 | struct saa7164_buffer *buf; | ||
867 | struct saa7164_user_buffer *ubuf; | ||
868 | struct list_head *c, *n; | ||
869 | int ret; | ||
870 | |||
871 | dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr); | ||
872 | |||
873 | ret = saa7164_vbi_pause_port(port); | ||
874 | ret = saa7164_vbi_acquire_port(port); | ||
875 | ret = saa7164_vbi_stop_port(port); | ||
876 | |||
877 | dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__, | ||
878 | port->nr); | ||
879 | |||
880 | /* Reset the state of any allocated buffer resources */ | ||
881 | mutex_lock(&port->dmaqueue_lock); | ||
882 | |||
883 | /* Reset the hard and soft buffer state */ | ||
884 | list_for_each_safe(c, n, &port->dmaqueue.list) { | ||
885 | buf = list_entry(c, struct saa7164_buffer, list); | ||
886 | buf->flags = SAA7164_BUFFER_FREE; | ||
887 | buf->pos = 0; | ||
888 | } | ||
889 | |||
890 | list_for_each_safe(c, n, &port->list_buf_used.list) { | ||
891 | ubuf = list_entry(c, struct saa7164_user_buffer, list); | ||
892 | ubuf->pos = 0; | ||
893 | list_move_tail(&ubuf->list, &port->list_buf_free.list); | ||
894 | } | ||
895 | |||
896 | mutex_unlock(&port->dmaqueue_lock); | ||
897 | |||
898 | /* Free any allocated resources */ | ||
899 | saa7164_vbi_buffers_dealloc(port); | ||
900 | |||
901 | dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr); | ||
902 | |||
903 | return ret; | ||
904 | } | ||
905 | |||
906 | static int saa7164_vbi_start_streaming(struct saa7164_port *port) | ||
907 | { | ||
908 | struct saa7164_dev *dev = port->dev; | ||
909 | int result, ret = 0; | ||
910 | |||
911 | dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr); | ||
912 | |||
913 | port->done_first_interrupt = 0; | ||
914 | |||
915 | /* allocate all of the PCIe DMA buffer resources on the fly, | ||
916 | * allowing switching between TS and PS payloads without | ||
917 | * requiring a complete driver reload. | ||
918 | */ | ||
919 | saa7164_vbi_buffers_alloc(port); | ||
920 | |||
921 | /* Configure the encoder with any cache values */ | ||
922 | // saa7164_api_set_encoder(port); | ||
923 | // saa7164_api_get_encoder(port); | ||
924 | |||
925 | /* Place the empty buffers on the hardware */ | ||
926 | saa7164_buffer_cfg_port(port); | ||
927 | |||
928 | /* Negotiate format */ | ||
929 | if (saa7164_api_set_vbi_format(port) != SAA_OK) { | ||
930 | printk(KERN_ERR "%s() No supported VBI format\n", __func__); | ||
931 | ret = -EIO; | ||
932 | goto out; | ||
933 | } | ||
934 | |||
935 | /* Acquire the hardware */ | ||
936 | result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); | ||
937 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
938 | printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", | ||
939 | __func__, result); | ||
940 | |||
941 | ret = -EIO; | ||
942 | goto out; | ||
943 | } else | ||
944 | dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__); | ||
945 | |||
946 | /* Pause the hardware */ | ||
947 | result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); | ||
948 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
949 | printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", | ||
950 | __func__, result); | ||
951 | |||
952 | /* Stop the hardware, regardless */ | ||
953 | result = saa7164_vbi_stop_port(port); | ||
954 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
955 | printk(KERN_ERR "%s() pause/forced stop transition " | ||
956 | "failed, res = 0x%x\n", __func__, result); | ||
957 | } | ||
958 | |||
959 | ret = -EIO; | ||
960 | goto out; | ||
961 | } else | ||
962 | dprintk(DBGLVL_VBI, "%s() Paused\n", __func__); | ||
963 | |||
964 | /* Start the hardware */ | ||
965 | result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); | ||
966 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
967 | printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", | ||
968 | __func__, result); | ||
969 | |||
970 | /* Stop the hardware, regardless */ | ||
971 | result = saa7164_vbi_acquire_port(port); | ||
972 | result = saa7164_vbi_stop_port(port); | ||
973 | if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { | ||
974 | printk(KERN_ERR "%s() run/forced stop transition " | ||
975 | "failed, res = 0x%x\n", __func__, result); | ||
976 | } | ||
977 | |||
978 | ret = -EIO; | ||
979 | } else | ||
980 | dprintk(DBGLVL_VBI, "%s() Running\n", __func__); | ||
981 | |||
982 | out: | ||
983 | return ret; | ||
984 | } | ||
985 | |||
986 | int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f) | ||
987 | { | ||
988 | /* ntsc */ | ||
989 | f->fmt.vbi.samples_per_line = 1600; | ||
990 | f->fmt.vbi.samples_per_line = 1440; | ||
991 | f->fmt.vbi.sampling_rate = 27000000; | ||
992 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
993 | f->fmt.vbi.offset = 0; | ||
994 | f->fmt.vbi.flags = 0; | ||
995 | f->fmt.vbi.start[0] = 10; | ||
996 | f->fmt.vbi.count[0] = 18; | ||
997 | f->fmt.vbi.start[1] = 263 + 10 + 1; | ||
998 | f->fmt.vbi.count[1] = 18; | ||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | static int fops_open(struct file *file) | ||
1003 | { | ||
1004 | struct saa7164_dev *dev; | ||
1005 | struct saa7164_port *port; | ||
1006 | struct saa7164_vbi_fh *fh; | ||
1007 | |||
1008 | port = (struct saa7164_port *)video_get_drvdata(video_devdata(file)); | ||
1009 | if (!port) | ||
1010 | return -ENODEV; | ||
1011 | |||
1012 | dev = port->dev; | ||
1013 | |||
1014 | dprintk(DBGLVL_VBI, "%s()\n", __func__); | ||
1015 | |||
1016 | /* allocate + initialize per filehandle data */ | ||
1017 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1018 | if (NULL == fh) | ||
1019 | return -ENOMEM; | ||
1020 | |||
1021 | file->private_data = fh; | ||
1022 | fh->port = port; | ||
1023 | |||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1027 | static int fops_release(struct file *file) | ||
1028 | { | ||
1029 | struct saa7164_vbi_fh *fh = file->private_data; | ||
1030 | struct saa7164_port *port = fh->port; | ||
1031 | struct saa7164_dev *dev = port->dev; | ||
1032 | |||
1033 | dprintk(DBGLVL_VBI, "%s()\n", __func__); | ||
1034 | |||
1035 | /* Shut device down on last close */ | ||
1036 | if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { | ||
1037 | if (atomic_dec_return(&port->v4l_reader_count) == 0) { | ||
1038 | /* stop vbi capture then cancel buffers */ | ||
1039 | saa7164_vbi_stop_streaming(port); | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | file->private_data = NULL; | ||
1044 | kfree(fh); | ||
1045 | |||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port) | ||
1050 | { | ||
1051 | struct saa7164_user_buffer *ubuf = 0; | ||
1052 | struct saa7164_dev *dev = port->dev; | ||
1053 | u32 crc; | ||
1054 | |||
1055 | mutex_lock(&port->dmaqueue_lock); | ||
1056 | if (!list_empty(&port->list_buf_used.list)) { | ||
1057 | ubuf = list_first_entry(&port->list_buf_used.list, | ||
1058 | struct saa7164_user_buffer, list); | ||
1059 | |||
1060 | if (crc_checking) { | ||
1061 | crc = crc32(0, ubuf->data, ubuf->actual_size); | ||
1062 | if (crc != ubuf->crc) { | ||
1063 | printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__, | ||
1064 | ubuf, ubuf->crc, crc); | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | } | ||
1069 | mutex_unlock(&port->dmaqueue_lock); | ||
1070 | |||
1071 | dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf); | ||
1072 | |||
1073 | return ubuf; | ||
1074 | } | ||
1075 | |||
1076 | static ssize_t fops_read(struct file *file, char __user *buffer, | ||
1077 | size_t count, loff_t *pos) | ||
1078 | { | ||
1079 | struct saa7164_vbi_fh *fh = file->private_data; | ||
1080 | struct saa7164_port *port = fh->port; | ||
1081 | struct saa7164_user_buffer *ubuf = NULL; | ||
1082 | struct saa7164_dev *dev = port->dev; | ||
1083 | int ret = 0; | ||
1084 | int rem, cnt; | ||
1085 | u8 *p; | ||
1086 | |||
1087 | port->last_read_msecs_diff = port->last_read_msecs; | ||
1088 | port->last_read_msecs = jiffies_to_msecs(jiffies); | ||
1089 | port->last_read_msecs_diff = port->last_read_msecs - | ||
1090 | port->last_read_msecs_diff; | ||
1091 | |||
1092 | saa7164_histogram_update(&port->read_interval, | ||
1093 | port->last_read_msecs_diff); | ||
1094 | |||
1095 | if (*pos) { | ||
1096 | printk(KERN_ERR "%s() ESPIPE\n", __func__); | ||
1097 | return -ESPIPE; | ||
1098 | } | ||
1099 | |||
1100 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
1101 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | ||
1102 | |||
1103 | if (saa7164_vbi_initialize(port) < 0) { | ||
1104 | printk(KERN_ERR "%s() EINVAL\n", __func__); | ||
1105 | return -EINVAL; | ||
1106 | } | ||
1107 | |||
1108 | saa7164_vbi_start_streaming(port); | ||
1109 | msleep(200); | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | /* blocking wait for buffer */ | ||
1114 | if ((file->f_flags & O_NONBLOCK) == 0) { | ||
1115 | if (wait_event_interruptible(port->wait_read, | ||
1116 | saa7164_vbi_next_buf(port))) { | ||
1117 | printk(KERN_ERR "%s() ERESTARTSYS\n", __func__); | ||
1118 | return -ERESTARTSYS; | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | /* Pull the first buffer from the used list */ | ||
1123 | ubuf = saa7164_vbi_next_buf(port); | ||
1124 | |||
1125 | while ((count > 0) && ubuf) { | ||
1126 | |||
1127 | /* set remaining bytes to copy */ | ||
1128 | rem = ubuf->actual_size - ubuf->pos; | ||
1129 | cnt = rem > count ? count : rem; | ||
1130 | |||
1131 | p = ubuf->data + ubuf->pos; | ||
1132 | |||
1133 | dprintk(DBGLVL_VBI, | ||
1134 | "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n", | ||
1135 | __func__, (int)count, cnt, rem, ubuf, ubuf->pos); | ||
1136 | |||
1137 | if (copy_to_user(buffer, p, cnt)) { | ||
1138 | printk(KERN_ERR "%s() copy_to_user failed\n", __func__); | ||
1139 | if (!ret) { | ||
1140 | printk(KERN_ERR "%s() EFAULT\n", __func__); | ||
1141 | ret = -EFAULT; | ||
1142 | } | ||
1143 | goto err; | ||
1144 | } | ||
1145 | |||
1146 | ubuf->pos += cnt; | ||
1147 | count -= cnt; | ||
1148 | buffer += cnt; | ||
1149 | ret += cnt; | ||
1150 | |||
1151 | if (ubuf->pos > ubuf->actual_size) { | ||
1152 | printk(KERN_ERR "read() pos > actual, huh?\n"); | ||
1153 | } | ||
1154 | |||
1155 | if (ubuf->pos == ubuf->actual_size) { | ||
1156 | |||
1157 | /* finished with current buffer, take next buffer */ | ||
1158 | |||
1159 | /* Requeue the buffer on the free list */ | ||
1160 | ubuf->pos = 0; | ||
1161 | |||
1162 | mutex_lock(&port->dmaqueue_lock); | ||
1163 | list_move_tail(&ubuf->list, &port->list_buf_free.list); | ||
1164 | mutex_unlock(&port->dmaqueue_lock); | ||
1165 | |||
1166 | /* Dequeue next */ | ||
1167 | if ((file->f_flags & O_NONBLOCK) == 0) { | ||
1168 | if (wait_event_interruptible(port->wait_read, | ||
1169 | saa7164_vbi_next_buf(port))) { | ||
1170 | break; | ||
1171 | } | ||
1172 | } | ||
1173 | ubuf = saa7164_vbi_next_buf(port); | ||
1174 | } | ||
1175 | } | ||
1176 | err: | ||
1177 | if (!ret && !ubuf) { | ||
1178 | printk(KERN_ERR "%s() EAGAIN\n", __func__); | ||
1179 | ret = -EAGAIN; | ||
1180 | } | ||
1181 | |||
1182 | return ret; | ||
1183 | } | ||
1184 | |||
1185 | static unsigned int fops_poll(struct file *file, poll_table *wait) | ||
1186 | { | ||
1187 | struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data; | ||
1188 | struct saa7164_port *port = fh->port; | ||
1189 | struct saa7164_user_buffer *ubuf; | ||
1190 | unsigned int mask = 0; | ||
1191 | |||
1192 | port->last_poll_msecs_diff = port->last_poll_msecs; | ||
1193 | port->last_poll_msecs = jiffies_to_msecs(jiffies); | ||
1194 | port->last_poll_msecs_diff = port->last_poll_msecs - | ||
1195 | port->last_poll_msecs_diff; | ||
1196 | |||
1197 | saa7164_histogram_update(&port->poll_interval, | ||
1198 | port->last_poll_msecs_diff); | ||
1199 | |||
1200 | if (!video_is_registered(port->v4l_device)) { | ||
1201 | return -EIO; | ||
1202 | } | ||
1203 | |||
1204 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
1205 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | ||
1206 | if (saa7164_vbi_initialize(port) < 0) | ||
1207 | return -EINVAL; | ||
1208 | saa7164_vbi_start_streaming(port); | ||
1209 | msleep(200); | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | /* blocking wait for buffer */ | ||
1214 | if ((file->f_flags & O_NONBLOCK) == 0) { | ||
1215 | if (wait_event_interruptible(port->wait_read, | ||
1216 | saa7164_vbi_next_buf(port))) { | ||
1217 | return -ERESTARTSYS; | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | /* Pull the first buffer from the used list */ | ||
1222 | ubuf = list_first_entry(&port->list_buf_used.list, | ||
1223 | struct saa7164_user_buffer, list); | ||
1224 | |||
1225 | if (ubuf) | ||
1226 | mask |= POLLIN | POLLRDNORM; | ||
1227 | |||
1228 | return mask; | ||
1229 | } | ||
1230 | static const struct v4l2_file_operations vbi_fops = { | ||
1231 | .owner = THIS_MODULE, | ||
1232 | .open = fops_open, | ||
1233 | .release = fops_release, | ||
1234 | .read = fops_read, | ||
1235 | .poll = fops_poll, | ||
1236 | .unlocked_ioctl = video_ioctl2, | ||
1237 | }; | ||
1238 | |||
1239 | static const struct v4l2_ioctl_ops vbi_ioctl_ops = { | ||
1240 | .vidioc_s_std = vidioc_s_std, | ||
1241 | .vidioc_enum_input = vidioc_enum_input, | ||
1242 | .vidioc_g_input = vidioc_g_input, | ||
1243 | .vidioc_s_input = vidioc_s_input, | ||
1244 | .vidioc_g_tuner = vidioc_g_tuner, | ||
1245 | .vidioc_s_tuner = vidioc_s_tuner, | ||
1246 | .vidioc_g_frequency = vidioc_g_frequency, | ||
1247 | .vidioc_s_frequency = vidioc_s_frequency, | ||
1248 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1249 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1250 | .vidioc_querycap = vidioc_querycap, | ||
1251 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1252 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1253 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1254 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1255 | .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, | ||
1256 | .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, | ||
1257 | .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, | ||
1258 | .vidioc_log_status = vidioc_log_status, | ||
1259 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1260 | // .vidioc_g_chip_ident = saa7164_g_chip_ident, | ||
1261 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1262 | // .vidioc_g_register = saa7164_g_register, | ||
1263 | // .vidioc_s_register = saa7164_s_register, | ||
1264 | #endif | ||
1265 | .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt, | ||
1266 | .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt, | ||
1267 | .vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt, | ||
1268 | }; | ||
1269 | |||
1270 | static struct video_device saa7164_vbi_template = { | ||
1271 | .name = "saa7164", | ||
1272 | .fops = &vbi_fops, | ||
1273 | .ioctl_ops = &vbi_ioctl_ops, | ||
1274 | .minor = -1, | ||
1275 | .tvnorms = SAA7164_NORMS, | ||
1276 | .current_norm = V4L2_STD_NTSC_M, | ||
1277 | }; | ||
1278 | |||
1279 | static struct video_device *saa7164_vbi_alloc( | ||
1280 | struct saa7164_port *port, | ||
1281 | struct pci_dev *pci, | ||
1282 | struct video_device *template, | ||
1283 | char *type) | ||
1284 | { | ||
1285 | struct video_device *vfd; | ||
1286 | struct saa7164_dev *dev = port->dev; | ||
1287 | |||
1288 | dprintk(DBGLVL_VBI, "%s()\n", __func__); | ||
1289 | |||
1290 | vfd = video_device_alloc(); | ||
1291 | if (NULL == vfd) | ||
1292 | return NULL; | ||
1293 | |||
1294 | *vfd = *template; | ||
1295 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | ||
1296 | type, saa7164_boards[dev->board].name); | ||
1297 | |||
1298 | vfd->parent = &pci->dev; | ||
1299 | vfd->release = video_device_release; | ||
1300 | return vfd; | ||
1301 | } | ||
1302 | |||
1303 | int saa7164_vbi_register(struct saa7164_port *port) | ||
1304 | { | ||
1305 | struct saa7164_dev *dev = port->dev; | ||
1306 | int result = -ENODEV; | ||
1307 | |||
1308 | dprintk(DBGLVL_VBI, "%s()\n", __func__); | ||
1309 | |||
1310 | if (port->type != SAA7164_MPEG_VBI) | ||
1311 | BUG(); | ||
1312 | |||
1313 | /* Sanity check that the PCI configuration space is active */ | ||
1314 | if (port->hwcfg.BARLocation == 0) { | ||
1315 | printk(KERN_ERR "%s() failed " | ||
1316 | "(errno = %d), NO PCI configuration\n", | ||
1317 | __func__, result); | ||
1318 | result = -ENOMEM; | ||
1319 | goto failed; | ||
1320 | } | ||
1321 | |||
1322 | /* Establish VBI defaults here */ | ||
1323 | |||
1324 | /* Allocate and register the video device node */ | ||
1325 | port->v4l_device = saa7164_vbi_alloc(port, | ||
1326 | dev->pci, &saa7164_vbi_template, "vbi"); | ||
1327 | |||
1328 | if (port->v4l_device == NULL) { | ||
1329 | printk(KERN_INFO "%s: can't allocate vbi device\n", | ||
1330 | dev->name); | ||
1331 | result = -ENOMEM; | ||
1332 | goto failed; | ||
1333 | } | ||
1334 | |||
1335 | video_set_drvdata(port->v4l_device, port); | ||
1336 | result = video_register_device(port->v4l_device, | ||
1337 | VFL_TYPE_VBI, -1); | ||
1338 | if (result < 0) { | ||
1339 | printk(KERN_INFO "%s: can't register vbi device\n", | ||
1340 | dev->name); | ||
1341 | /* TODO: We're going to leak here if we don't dealloc | ||
1342 | The buffers above. The unreg function can't deal wit it. | ||
1343 | */ | ||
1344 | goto failed; | ||
1345 | } | ||
1346 | |||
1347 | printk(KERN_INFO "%s: registered device vbi%d [vbi]\n", | ||
1348 | dev->name, port->v4l_device->num); | ||
1349 | |||
1350 | /* Configure the hardware defaults */ | ||
1351 | |||
1352 | result = 0; | ||
1353 | failed: | ||
1354 | return result; | ||
1355 | } | ||
1356 | |||
1357 | void saa7164_vbi_unregister(struct saa7164_port *port) | ||
1358 | { | ||
1359 | struct saa7164_dev *dev = port->dev; | ||
1360 | |||
1361 | dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr); | ||
1362 | |||
1363 | if (port->type != SAA7164_MPEG_VBI) | ||
1364 | BUG(); | ||
1365 | |||
1366 | if (port->v4l_device) { | ||
1367 | if (port->v4l_device->minor != -1) | ||
1368 | video_unregister_device(port->v4l_device); | ||
1369 | else | ||
1370 | video_device_release(port->v4l_device); | ||
1371 | |||
1372 | port->v4l_device = NULL; | ||
1373 | } | ||
1374 | |||
1375 | } | ||
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h index 42660b546f0..1d9c5cbbbc5 100644 --- a/drivers/media/video/saa7164/saa7164.h +++ b/drivers/media/video/saa7164/saa7164.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the NXP SAA7164 PCIe bridge | 2 | * Driver for the NXP SAA7164 PCIe bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> | 4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -48,18 +48,29 @@ | |||
48 | #include <linux/i2c.h> | 48 | #include <linux/i2c.h> |
49 | #include <linux/i2c-algo-bit.h> | 49 | #include <linux/i2c-algo-bit.h> |
50 | #include <linux/kdev_t.h> | 50 | #include <linux/kdev_t.h> |
51 | #include <linux/version.h> | ||
52 | #include <linux/mutex.h> | ||
53 | #include <linux/crc32.h> | ||
54 | #include <linux/kthread.h> | ||
55 | #include <linux/freezer.h> | ||
51 | 56 | ||
52 | #include <media/tuner.h> | 57 | #include <media/tuner.h> |
53 | #include <media/tveeprom.h> | 58 | #include <media/tveeprom.h> |
54 | #include <media/videobuf-dma-sg.h> | 59 | #include <media/videobuf-dma-sg.h> |
55 | #include <media/videobuf-dvb.h> | 60 | #include <media/videobuf-dvb.h> |
61 | #include <linux/smp_lock.h> | ||
62 | #include <dvb_demux.h> | ||
63 | #include <dvb_frontend.h> | ||
64 | #include <dvb_net.h> | ||
65 | #include <dvbdev.h> | ||
66 | #include <dmxdev.h> | ||
67 | #include <media/v4l2-common.h> | ||
68 | #include <media/v4l2-ioctl.h> | ||
69 | #include <media/v4l2-chip-ident.h> | ||
56 | 70 | ||
57 | #include "saa7164-reg.h" | 71 | #include "saa7164-reg.h" |
58 | #include "saa7164-types.h" | 72 | #include "saa7164-types.h" |
59 | 73 | ||
60 | #include <linux/version.h> | ||
61 | #include <linux/mutex.h> | ||
62 | |||
63 | #define SAA7164_MAXBOARDS 8 | 74 | #define SAA7164_MAXBOARDS 8 |
64 | 75 | ||
65 | #define UNSET (-1U) | 76 | #define UNSET (-1U) |
@@ -76,7 +87,19 @@ | |||
76 | 87 | ||
77 | #define SAA7164_MAX_UNITS 8 | 88 | #define SAA7164_MAX_UNITS 8 |
78 | #define SAA7164_TS_NUMBER_OF_LINES 312 | 89 | #define SAA7164_TS_NUMBER_OF_LINES 312 |
90 | #define SAA7164_PS_NUMBER_OF_LINES 256 | ||
79 | #define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */ | 91 | #define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */ |
92 | #define SAA7164_MAX_ENCODER_BUFFERS 64 /* max 5secs of latency at 6Mbps */ | ||
93 | #define SAA7164_MAX_VBI_BUFFERS 64 | ||
94 | |||
95 | /* Port related defines */ | ||
96 | #define SAA7164_PORT_TS1 (0) | ||
97 | #define SAA7164_PORT_TS2 (SAA7164_PORT_TS1 + 1) | ||
98 | #define SAA7164_PORT_ENC1 (SAA7164_PORT_TS2 + 1) | ||
99 | #define SAA7164_PORT_ENC2 (SAA7164_PORT_ENC1 + 1) | ||
100 | #define SAA7164_PORT_VBI1 (SAA7164_PORT_ENC2 + 1) | ||
101 | #define SAA7164_PORT_VBI2 (SAA7164_PORT_VBI1 + 1) | ||
102 | #define SAA7164_MAX_PORTS (SAA7164_PORT_VBI2 + 1) | ||
80 | 103 | ||
81 | #define DBGLVL_FW 4 | 104 | #define DBGLVL_FW 4 |
82 | #define DBGLVL_DVB 8 | 105 | #define DBGLVL_DVB 8 |
@@ -86,10 +109,18 @@ | |||
86 | #define DBGLVL_BUS 128 | 109 | #define DBGLVL_BUS 128 |
87 | #define DBGLVL_IRQ 256 | 110 | #define DBGLVL_IRQ 256 |
88 | #define DBGLVL_BUF 512 | 111 | #define DBGLVL_BUF 512 |
112 | #define DBGLVL_ENC 1024 | ||
113 | #define DBGLVL_VBI 2048 | ||
114 | #define DBGLVL_THR 4096 | ||
115 | #define DBGLVL_CPU 8192 | ||
116 | |||
117 | #define SAA7164_NORMS (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443) | ||
89 | 118 | ||
90 | enum port_t { | 119 | enum port_t { |
91 | SAA7164_MPEG_UNDEFINED = 0, | 120 | SAA7164_MPEG_UNDEFINED = 0, |
92 | SAA7164_MPEG_DVB, | 121 | SAA7164_MPEG_DVB, |
122 | SAA7164_MPEG_ENCODER, | ||
123 | SAA7164_MPEG_VBI, | ||
93 | }; | 124 | }; |
94 | 125 | ||
95 | enum saa7164_i2c_bus_nr { | 126 | enum saa7164_i2c_bus_nr { |
@@ -134,7 +165,8 @@ struct saa7164_unit { | |||
134 | 165 | ||
135 | struct saa7164_board { | 166 | struct saa7164_board { |
136 | char *name; | 167 | char *name; |
137 | enum port_t porta, portb; | 168 | enum port_t porta, portb, portc, |
169 | portd, porte, portf; | ||
138 | enum { | 170 | enum { |
139 | SAA7164_CHIP_UNDEFINED = 0, | 171 | SAA7164_CHIP_UNDEFINED = 0, |
140 | SAA7164_CHIP_REV2, | 172 | SAA7164_CHIP_REV2, |
@@ -149,6 +181,42 @@ struct saa7164_subid { | |||
149 | u32 card; | 181 | u32 card; |
150 | }; | 182 | }; |
151 | 183 | ||
184 | struct saa7164_encoder_fh { | ||
185 | struct saa7164_port *port; | ||
186 | // u32 freq; | ||
187 | // u32 tuner_type; | ||
188 | atomic_t v4l_reading; | ||
189 | }; | ||
190 | |||
191 | struct saa7164_vbi_fh { | ||
192 | struct saa7164_port *port; | ||
193 | // u32 freq; | ||
194 | // u32 tuner_type; | ||
195 | atomic_t v4l_reading; | ||
196 | }; | ||
197 | |||
198 | struct saa7164_histogram_bucket { | ||
199 | u32 val; | ||
200 | u32 count; | ||
201 | u64 update_time; | ||
202 | }; | ||
203 | |||
204 | struct saa7164_histogram { | ||
205 | char name[32]; | ||
206 | struct saa7164_histogram_bucket counter1[64]; | ||
207 | }; | ||
208 | |||
209 | struct saa7164_user_buffer { | ||
210 | struct list_head list; | ||
211 | |||
212 | /* Attributes */ | ||
213 | u8 *data; | ||
214 | u32 pos; | ||
215 | u32 actual_size; | ||
216 | |||
217 | u32 crc; | ||
218 | }; | ||
219 | |||
152 | struct saa7164_fw_status { | 220 | struct saa7164_fw_status { |
153 | 221 | ||
154 | /* RISC Core details */ | 222 | /* RISC Core details */ |
@@ -191,14 +259,60 @@ struct saa7164_i2c { | |||
191 | u32 i2c_rc; | 259 | u32 i2c_rc; |
192 | }; | 260 | }; |
193 | 261 | ||
194 | struct saa7164_tsport; | 262 | struct saa7164_ctrl { |
263 | struct v4l2_queryctrl v; | ||
264 | }; | ||
265 | |||
266 | struct saa7164_tvnorm { | ||
267 | char *name; | ||
268 | v4l2_std_id id; | ||
269 | // u32 cxiformat; | ||
270 | // u32 cxoformat; | ||
271 | }; | ||
272 | |||
273 | struct saa7164_encoder_params { | ||
274 | struct saa7164_tvnorm encodernorm; | ||
275 | u32 height; | ||
276 | u32 width; | ||
277 | u32 is_50hz; | ||
278 | u32 bitrate; /* bps */ | ||
279 | u32 bitrate_peak; /* bps */ | ||
280 | u32 bitrate_mode; | ||
281 | u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */ | ||
282 | |||
283 | u32 audio_sampling_freq; | ||
284 | u32 ctl_mute; | ||
285 | u32 ctl_aspect; | ||
286 | u32 refdist; | ||
287 | u32 gop_size; | ||
288 | }; | ||
289 | |||
290 | struct saa7164_vbi_params { | ||
291 | struct saa7164_tvnorm encodernorm; | ||
292 | u32 height; | ||
293 | u32 width; | ||
294 | u32 is_50hz; | ||
295 | u32 bitrate; /* bps */ | ||
296 | u32 bitrate_peak; /* bps */ | ||
297 | u32 bitrate_mode; | ||
298 | u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */ | ||
299 | |||
300 | u32 audio_sampling_freq; | ||
301 | u32 ctl_mute; | ||
302 | u32 ctl_aspect; | ||
303 | u32 refdist; | ||
304 | u32 gop_size; | ||
305 | }; | ||
306 | |||
307 | struct saa7164_port; | ||
195 | 308 | ||
196 | struct saa7164_buffer { | 309 | struct saa7164_buffer { |
197 | struct list_head list; | 310 | struct list_head list; |
198 | 311 | ||
199 | u32 nr; | 312 | /* Note of which h/w buffer list index position we occupy */ |
313 | int idx; | ||
200 | 314 | ||
201 | struct saa7164_tsport *port; | 315 | struct saa7164_port *port; |
202 | 316 | ||
203 | /* Hardware Specific */ | 317 | /* Hardware Specific */ |
204 | /* PCI Memory allocations */ | 318 | /* PCI Memory allocations */ |
@@ -206,28 +320,33 @@ struct saa7164_buffer { | |||
206 | 320 | ||
207 | /* A block of page align PCI memory */ | 321 | /* A block of page align PCI memory */ |
208 | u32 pci_size; /* PCI allocation size in bytes */ | 322 | u32 pci_size; /* PCI allocation size in bytes */ |
209 | u64 *cpu; /* Virtual address */ | 323 | u64 __iomem *cpu; /* Virtual address */ |
210 | dma_addr_t dma; /* Physical address */ | 324 | dma_addr_t dma; /* Physical address */ |
325 | u32 crc; /* Checksum for the entire buffer data */ | ||
211 | 326 | ||
212 | /* A page table that splits the block into a number of entries */ | 327 | /* A page table that splits the block into a number of entries */ |
213 | u32 pt_size; /* PCI allocation size in bytes */ | 328 | u32 pt_size; /* PCI allocation size in bytes */ |
214 | u64 *pt_cpu; /* Virtual address */ | 329 | u64 __iomem *pt_cpu; /* Virtual address */ |
215 | dma_addr_t pt_dma; /* Physical address */ | 330 | dma_addr_t pt_dma; /* Physical address */ |
331 | |||
332 | /* Encoder fops */ | ||
333 | u32 pos; | ||
334 | u32 actual_size; | ||
216 | }; | 335 | }; |
217 | 336 | ||
218 | struct saa7164_tsport { | 337 | struct saa7164_port { |
219 | 338 | ||
220 | struct saa7164_dev *dev; | 339 | struct saa7164_dev *dev; |
221 | int nr; | ||
222 | enum port_t type; | 340 | enum port_t type; |
341 | int nr; | ||
223 | 342 | ||
224 | struct saa7164_dvb dvb; | 343 | /* --- Generic port attributes --- */ |
225 | 344 | ||
226 | /* HW related stream parameters */ | 345 | /* HW stream parameters */ |
227 | tmHWStreamParameters_t hw_streamingparams; | 346 | struct tmHWStreamParameters hw_streamingparams; |
228 | 347 | ||
229 | /* DMA configuration values, is seeded during initialization */ | 348 | /* DMA configuration values, is seeded during initialization */ |
230 | tmComResDMATermDescrHeader_t hwcfg; | 349 | struct tmComResDMATermDescrHeader hwcfg; |
231 | 350 | ||
232 | /* hardware specific registers */ | 351 | /* hardware specific registers */ |
233 | u32 bufcounter; | 352 | u32 bufcounter; |
@@ -239,11 +358,76 @@ struct saa7164_tsport { | |||
239 | u64 bufptr64; | 358 | u64 bufptr64; |
240 | 359 | ||
241 | u32 numpte; /* Number of entries in array, only valid in head */ | 360 | u32 numpte; /* Number of entries in array, only valid in head */ |
361 | |||
242 | struct mutex dmaqueue_lock; | 362 | struct mutex dmaqueue_lock; |
243 | struct mutex dummy_dmaqueue_lock; | ||
244 | struct saa7164_buffer dmaqueue; | 363 | struct saa7164_buffer dmaqueue; |
245 | struct saa7164_buffer dummy_dmaqueue; | ||
246 | 364 | ||
365 | u64 last_irq_msecs, last_svc_msecs; | ||
366 | u64 last_irq_msecs_diff, last_svc_msecs_diff; | ||
367 | u32 last_svc_wp; | ||
368 | u32 last_svc_rp; | ||
369 | u64 last_irq_svc_msecs_diff; | ||
370 | u64 last_read_msecs, last_read_msecs_diff; | ||
371 | u64 last_poll_msecs, last_poll_msecs_diff; | ||
372 | |||
373 | struct saa7164_histogram irq_interval; | ||
374 | struct saa7164_histogram svc_interval; | ||
375 | struct saa7164_histogram irq_svc_interval; | ||
376 | struct saa7164_histogram read_interval; | ||
377 | struct saa7164_histogram poll_interval; | ||
378 | |||
379 | /* --- DVB Transport Specific --- */ | ||
380 | struct saa7164_dvb dvb; | ||
381 | |||
382 | /* --- Encoder/V4L related attributes --- */ | ||
383 | /* Encoder */ | ||
384 | /* Defaults established in saa7164-encoder.c */ | ||
385 | struct saa7164_tvnorm encodernorm; | ||
386 | u32 height; | ||
387 | u32 width; | ||
388 | u32 freq; | ||
389 | u32 ts_packet_size; | ||
390 | u32 ts_packet_count; | ||
391 | u8 mux_input; | ||
392 | u8 encoder_profile; | ||
393 | u8 video_format; | ||
394 | u8 audio_format; | ||
395 | u8 video_resolution; | ||
396 | u16 ctl_brightness; | ||
397 | u16 ctl_contrast; | ||
398 | u16 ctl_hue; | ||
399 | u16 ctl_saturation; | ||
400 | u16 ctl_sharpness; | ||
401 | s8 ctl_volume; | ||
402 | |||
403 | struct tmComResAFeatureDescrHeader audfeat; | ||
404 | struct tmComResEncoderDescrHeader encunit; | ||
405 | struct tmComResProcDescrHeader vidproc; | ||
406 | struct tmComResExtDevDescrHeader ifunit; | ||
407 | struct tmComResTunerDescrHeader tunerunit; | ||
408 | |||
409 | struct work_struct workenc; | ||
410 | |||
411 | /* V4L Encoder Video */ | ||
412 | struct saa7164_encoder_params encoder_params; | ||
413 | struct video_device *v4l_device; | ||
414 | atomic_t v4l_reader_count; | ||
415 | |||
416 | struct saa7164_buffer list_buf_used; | ||
417 | struct saa7164_buffer list_buf_free; | ||
418 | wait_queue_head_t wait_read; | ||
419 | |||
420 | /* V4L VBI */ | ||
421 | struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc; | ||
422 | struct saa7164_vbi_params vbi_params; | ||
423 | |||
424 | /* Debug */ | ||
425 | u32 sync_errors; | ||
426 | u32 v_cc_errors; | ||
427 | u32 a_cc_errors; | ||
428 | u8 last_v_cc; | ||
429 | u8 last_a_cc; | ||
430 | u32 done_first_interrupt; | ||
247 | }; | 431 | }; |
248 | 432 | ||
249 | struct saa7164_dev { | 433 | struct saa7164_dev { |
@@ -268,12 +452,13 @@ struct saa7164_dev { | |||
268 | 452 | ||
269 | /* firmware status */ | 453 | /* firmware status */ |
270 | struct saa7164_fw_status fw_status; | 454 | struct saa7164_fw_status fw_status; |
455 | u32 firmwareloaded; | ||
271 | 456 | ||
272 | tmComResHWDescr_t hwdesc; | 457 | struct tmComResHWDescr hwdesc; |
273 | tmComResInterfaceDescr_t intfdesc; | 458 | struct tmComResInterfaceDescr intfdesc; |
274 | tmComResBusDescr_t busdesc; | 459 | struct tmComResBusDescr busdesc; |
275 | 460 | ||
276 | tmComResBusInfo_t bus; | 461 | struct tmComResBusInfo bus; |
277 | 462 | ||
278 | /* Interrupt status and ack registers */ | 463 | /* Interrupt status and ack registers */ |
279 | u32 int_status; | 464 | u32 int_status; |
@@ -286,15 +471,22 @@ struct saa7164_dev { | |||
286 | struct saa7164_i2c i2c_bus[3]; | 471 | struct saa7164_i2c i2c_bus[3]; |
287 | 472 | ||
288 | /* Transport related */ | 473 | /* Transport related */ |
289 | struct saa7164_tsport ts1, ts2; | 474 | struct saa7164_port ports[SAA7164_MAX_PORTS]; |
290 | 475 | ||
291 | /* Deferred command/api interrupts handling */ | 476 | /* Deferred command/api interrupts handling */ |
292 | struct work_struct workcmd; | 477 | struct work_struct workcmd; |
293 | 478 | ||
479 | /* A kernel thread to monitor the firmware log, used | ||
480 | * only in debug mode. | ||
481 | */ | ||
482 | struct task_struct *kthread; | ||
483 | |||
294 | }; | 484 | }; |
295 | 485 | ||
296 | extern struct list_head saa7164_devlist; | 486 | extern struct list_head saa7164_devlist; |
297 | extern unsigned int waitsecs; | 487 | extern unsigned int waitsecs; |
488 | extern unsigned int encoder_buffers; | ||
489 | extern unsigned int vbi_buffers; | ||
298 | 490 | ||
299 | /* ----------------------------------------------------------- */ | 491 | /* ----------------------------------------------------------- */ |
300 | /* saa7164-core.c */ | 492 | /* saa7164-core.c */ |
@@ -302,6 +494,7 @@ void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr); | |||
302 | void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len); | 494 | void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len); |
303 | void saa7164_getfirmwarestatus(struct saa7164_dev *dev); | 495 | void saa7164_getfirmwarestatus(struct saa7164_dev *dev); |
304 | u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev); | 496 | u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev); |
497 | void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val); | ||
305 | 498 | ||
306 | /* ----------------------------------------------------------- */ | 499 | /* ----------------------------------------------------------- */ |
307 | /* saa7164-fw.c */ | 500 | /* saa7164-fw.c */ |
@@ -318,14 +511,14 @@ extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus, | |||
318 | /* saa7164-bus.c */ | 511 | /* saa7164-bus.c */ |
319 | int saa7164_bus_setup(struct saa7164_dev *dev); | 512 | int saa7164_bus_setup(struct saa7164_dev *dev); |
320 | void saa7164_bus_dump(struct saa7164_dev *dev); | 513 | void saa7164_bus_dump(struct saa7164_dev *dev); |
321 | int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf); | 514 | int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf); |
322 | int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, | 515 | int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, |
323 | void *buf, int peekonly); | 516 | void *buf, int peekonly); |
324 | 517 | ||
325 | /* ----------------------------------------------------------- */ | 518 | /* ----------------------------------------------------------- */ |
326 | /* saa7164-cmd.c */ | 519 | /* saa7164-cmd.c */ |
327 | int saa7164_cmd_send(struct saa7164_dev *dev, | 520 | int saa7164_cmd_send(struct saa7164_dev *dev, |
328 | u8 id, tmComResCmd_t command, u16 controlselector, | 521 | u8 id, enum tmComResCmd command, u16 controlselector, |
329 | u16 size, void *buf); | 522 | u16 size, void *buf); |
330 | void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno); | 523 | void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno); |
331 | int saa7164_irq_dequeue(struct saa7164_dev *dev); | 524 | int saa7164_irq_dequeue(struct saa7164_dev *dev); |
@@ -343,7 +536,24 @@ int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr, | |||
343 | int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen); | 536 | int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen); |
344 | int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); | 537 | int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); |
345 | int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); | 538 | int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin); |
346 | int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode); | 539 | int saa7164_api_transition_port(struct saa7164_port *port, u8 mode); |
540 | int saa7164_api_initialize_dif(struct saa7164_port *port); | ||
541 | int saa7164_api_configure_dif(struct saa7164_port *port, u32 std); | ||
542 | int saa7164_api_set_encoder(struct saa7164_port *port); | ||
543 | int saa7164_api_get_encoder(struct saa7164_port *port); | ||
544 | int saa7164_api_set_aspect_ratio(struct saa7164_port *port); | ||
545 | int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl); | ||
546 | int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl); | ||
547 | int saa7164_api_set_videomux(struct saa7164_port *port); | ||
548 | int saa7164_api_audio_mute(struct saa7164_port *port, int mute); | ||
549 | int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level); | ||
550 | int saa7164_api_set_audio_std(struct saa7164_port *port); | ||
551 | int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect); | ||
552 | int saa7164_api_get_videomux(struct saa7164_port *port); | ||
553 | int saa7164_api_set_vbi_format(struct saa7164_port *port); | ||
554 | int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level); | ||
555 | int saa7164_api_collect_debug(struct saa7164_dev *dev); | ||
556 | int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i); | ||
347 | 557 | ||
348 | /* ----------------------------------------------------------- */ | 558 | /* ----------------------------------------------------------- */ |
349 | /* saa7164-cards.c */ | 559 | /* saa7164-cards.c */ |
@@ -363,18 +573,36 @@ extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid); | |||
363 | 573 | ||
364 | /* ----------------------------------------------------------- */ | 574 | /* ----------------------------------------------------------- */ |
365 | /* saa7164-dvb.c */ | 575 | /* saa7164-dvb.c */ |
366 | extern int saa7164_dvb_register(struct saa7164_tsport *port); | 576 | extern int saa7164_dvb_register(struct saa7164_port *port); |
367 | extern int saa7164_dvb_unregister(struct saa7164_tsport *port); | 577 | extern int saa7164_dvb_unregister(struct saa7164_port *port); |
368 | 578 | ||
369 | /* ----------------------------------------------------------- */ | 579 | /* ----------------------------------------------------------- */ |
370 | /* saa7164-buffer.c */ | 580 | /* saa7164-buffer.c */ |
371 | extern struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port, | 581 | extern struct saa7164_buffer *saa7164_buffer_alloc( |
372 | u32 len); | 582 | struct saa7164_port *port, u32 len); |
373 | extern int saa7164_buffer_dealloc(struct saa7164_tsport *port, | 583 | extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf); |
374 | struct saa7164_buffer *buf); | 584 | extern void saa7164_buffer_display(struct saa7164_buffer *buf); |
585 | extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i); | ||
586 | extern int saa7164_buffer_cfg_port(struct saa7164_port *port); | ||
587 | extern struct saa7164_user_buffer *saa7164_buffer_alloc_user( | ||
588 | struct saa7164_dev *dev, u32 len); | ||
589 | extern void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf); | ||
590 | extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i); | ||
591 | |||
592 | /* ----------------------------------------------------------- */ | ||
593 | /* saa7164-encoder.c */ | ||
594 | int saa7164_encoder_register(struct saa7164_port *port); | ||
595 | void saa7164_encoder_unregister(struct saa7164_port *port); | ||
596 | |||
597 | /* ----------------------------------------------------------- */ | ||
598 | /* saa7164-vbi.c */ | ||
599 | int saa7164_vbi_register(struct saa7164_port *port); | ||
600 | void saa7164_vbi_unregister(struct saa7164_port *port); | ||
375 | 601 | ||
376 | /* ----------------------------------------------------------- */ | 602 | /* ----------------------------------------------------------- */ |
377 | 603 | ||
604 | extern unsigned int crc_checking; | ||
605 | |||
378 | extern unsigned int saa_debug; | 606 | extern unsigned int saa_debug; |
379 | #define dprintk(level, fmt, arg...)\ | 607 | #define dprintk(level, fmt, arg...)\ |
380 | do { if (saa_debug & level)\ | 608 | do { if (saa_debug & level)\ |
@@ -394,7 +622,6 @@ extern unsigned int saa_debug; | |||
394 | #define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2)) | 622 | #define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2)) |
395 | #define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2)) | 623 | #define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2)) |
396 | 624 | ||
397 | |||
398 | #define saa7164_readb(reg) readl(dev->bmmio + (reg)) | 625 | #define saa7164_readb(reg) readl(dev->bmmio + (reg)) |
399 | #define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg)) | 626 | #define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg)) |
400 | 627 | ||
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 45f8bfc1342..b6172c2c517 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/i2c.h> | 39 | #include <linux/i2c.h> |
40 | #include <media/v4l2-device.h> | 40 | #include <media/v4l2-device.h> |
41 | #include <media/v4l2-ctrls.h> | 41 | #include <media/v4l2-ctrls.h> |
42 | #include <media/v4l2-i2c-drv.h> | ||
43 | 42 | ||
44 | MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); | 43 | MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); |
45 | MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil"); | 44 | MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil"); |
@@ -1366,9 +1365,25 @@ static const struct i2c_device_id saa717x_id[] = { | |||
1366 | }; | 1365 | }; |
1367 | MODULE_DEVICE_TABLE(i2c, saa717x_id); | 1366 | MODULE_DEVICE_TABLE(i2c, saa717x_id); |
1368 | 1367 | ||
1369 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 1368 | static struct i2c_driver saa717x_driver = { |
1370 | .name = "saa717x", | 1369 | .driver = { |
1371 | .probe = saa717x_probe, | 1370 | .owner = THIS_MODULE, |
1372 | .remove = saa717x_remove, | 1371 | .name = "saa717x", |
1373 | .id_table = saa717x_id, | 1372 | }, |
1373 | .probe = saa717x_probe, | ||
1374 | .remove = saa717x_remove, | ||
1375 | .id_table = saa717x_id, | ||
1374 | }; | 1376 | }; |
1377 | |||
1378 | static __init int init_saa717x(void) | ||
1379 | { | ||
1380 | return i2c_add_driver(&saa717x_driver); | ||
1381 | } | ||
1382 | |||
1383 | static __exit void exit_saa717x(void) | ||
1384 | { | ||
1385 | i2c_del_driver(&saa717x_driver); | ||
1386 | } | ||
1387 | |||
1388 | module_init(init_saa717x); | ||
1389 | module_exit(exit_saa717x); | ||
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 77db2039291..96f56c2f11f 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c | |||
@@ -30,11 +30,9 @@ | |||
30 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/i2c-id.h> | ||
34 | #include <linux/videodev2.h> | 33 | #include <linux/videodev2.h> |
35 | #include <media/v4l2-device.h> | 34 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 35 | #include <media/v4l2-chip-ident.h> |
37 | #include <media/v4l2-i2c-drv.h> | ||
38 | 36 | ||
39 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); | 37 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); |
40 | MODULE_AUTHOR("Dave Perks"); | 38 | MODULE_AUTHOR("Dave Perks"); |
@@ -366,9 +364,25 @@ static const struct i2c_device_id saa7185_id[] = { | |||
366 | }; | 364 | }; |
367 | MODULE_DEVICE_TABLE(i2c, saa7185_id); | 365 | MODULE_DEVICE_TABLE(i2c, saa7185_id); |
368 | 366 | ||
369 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 367 | static struct i2c_driver saa7185_driver = { |
370 | .name = "saa7185", | 368 | .driver = { |
371 | .probe = saa7185_probe, | 369 | .owner = THIS_MODULE, |
372 | .remove = saa7185_remove, | 370 | .name = "saa7185", |
373 | .id_table = saa7185_id, | 371 | }, |
372 | .probe = saa7185_probe, | ||
373 | .remove = saa7185_remove, | ||
374 | .id_table = saa7185_id, | ||
374 | }; | 375 | }; |
376 | |||
377 | static __init int init_saa7185(void) | ||
378 | { | ||
379 | return i2c_add_driver(&saa7185_driver); | ||
380 | } | ||
381 | |||
382 | static __exit void exit_saa7185(void) | ||
383 | { | ||
384 | i2c_del_driver(&saa7185_driver); | ||
385 | } | ||
386 | |||
387 | module_init(init_saa7185); | ||
388 | module_exit(exit_saa7185); | ||
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c index a2513772196..211fa25a123 100644 --- a/drivers/media/video/saa7191.c +++ b/drivers/media/video/saa7191.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <media/v4l2-device.h> | 24 | #include <media/v4l2-device.h> |
25 | #include <media/v4l2-chip-ident.h> | 25 | #include <media/v4l2-chip-ident.h> |
26 | #include <media/v4l2-i2c-drv.h> | ||
27 | 26 | ||
28 | #include "saa7191.h" | 27 | #include "saa7191.h" |
29 | 28 | ||
@@ -647,9 +646,25 @@ static const struct i2c_device_id saa7191_id[] = { | |||
647 | }; | 646 | }; |
648 | MODULE_DEVICE_TABLE(i2c, saa7191_id); | 647 | MODULE_DEVICE_TABLE(i2c, saa7191_id); |
649 | 648 | ||
650 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 649 | static struct i2c_driver saa7191_driver = { |
651 | .name = "saa7191", | 650 | .driver = { |
652 | .probe = saa7191_probe, | 651 | .owner = THIS_MODULE, |
653 | .remove = saa7191_remove, | 652 | .name = "saa7191", |
654 | .id_table = saa7191_id, | 653 | }, |
654 | .probe = saa7191_probe, | ||
655 | .remove = saa7191_remove, | ||
656 | .id_table = saa7191_id, | ||
655 | }; | 657 | }; |
658 | |||
659 | static __init int init_saa7191(void) | ||
660 | { | ||
661 | return i2c_add_driver(&saa7191_driver); | ||
662 | } | ||
663 | |||
664 | static __exit void exit_saa7191(void) | ||
665 | { | ||
666 | i2c_del_driver(&saa7191_driver); | ||
667 | } | ||
668 | |||
669 | module_init(init_saa7191); | ||
670 | module_exit(exit_saa7191); | ||
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2b24bd0de3a..5c209afb0ac 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -245,7 +245,7 @@ static void free_buffer(struct videobuf_queue *vq, | |||
245 | if (in_interrupt()) | 245 | if (in_interrupt()) |
246 | BUG(); | 246 | BUG(); |
247 | 247 | ||
248 | videobuf_waiton(&buf->vb, 0, 0); | 248 | videobuf_waiton(vq, &buf->vb, 0, 0); |
249 | videobuf_dma_contig_free(vq, &buf->vb); | 249 | videobuf_dma_contig_free(vq, &buf->vb); |
250 | dev_dbg(dev, "%s freed\n", __func__); | 250 | dev_dbg(dev, "%s freed\n", __func__); |
251 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 251 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
@@ -1726,7 +1726,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1726 | return ret; | 1726 | return ret; |
1727 | } | 1727 | } |
1728 | 1728 | ||
1729 | static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, | 1729 | static int sh_mobile_ceu_reqbufs(struct soc_camera_device *icd, |
1730 | struct v4l2_requestbuffers *p) | 1730 | struct v4l2_requestbuffers *p) |
1731 | { | 1731 | { |
1732 | int i; | 1732 | int i; |
@@ -1740,7 +1740,7 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, | |||
1740 | for (i = 0; i < p->count; i++) { | 1740 | for (i = 0; i < p->count; i++) { |
1741 | struct sh_mobile_ceu_buffer *buf; | 1741 | struct sh_mobile_ceu_buffer *buf; |
1742 | 1742 | ||
1743 | buf = container_of(icf->vb_vidq.bufs[i], | 1743 | buf = container_of(icd->vb_vidq.bufs[i], |
1744 | struct sh_mobile_ceu_buffer, vb); | 1744 | struct sh_mobile_ceu_buffer, vb); |
1745 | INIT_LIST_HEAD(&buf->vb.queue); | 1745 | INIT_LIST_HEAD(&buf->vb.queue); |
1746 | } | 1746 | } |
@@ -1750,10 +1750,10 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, | |||
1750 | 1750 | ||
1751 | static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) | 1751 | static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) |
1752 | { | 1752 | { |
1753 | struct soc_camera_file *icf = file->private_data; | 1753 | struct soc_camera_device *icd = file->private_data; |
1754 | struct sh_mobile_ceu_buffer *buf; | 1754 | struct sh_mobile_ceu_buffer *buf; |
1755 | 1755 | ||
1756 | buf = list_entry(icf->vb_vidq.stream.next, | 1756 | buf = list_entry(icd->vb_vidq.stream.next, |
1757 | struct sh_mobile_ceu_buffer, vb.stream); | 1757 | struct sh_mobile_ceu_buffer, vb.stream); |
1758 | 1758 | ||
1759 | poll_wait(file, &buf->vb.done, pt); | 1759 | poll_wait(file, &buf->vb.done, pt); |
@@ -1786,23 +1786,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, | |||
1786 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1786 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1787 | pcdev->field, | 1787 | pcdev->field, |
1788 | sizeof(struct sh_mobile_ceu_buffer), | 1788 | sizeof(struct sh_mobile_ceu_buffer), |
1789 | icd); | 1789 | icd, NULL); |
1790 | } | ||
1791 | |||
1792 | static int sh_mobile_ceu_get_parm(struct soc_camera_device *icd, | ||
1793 | struct v4l2_streamparm *parm) | ||
1794 | { | ||
1795 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1796 | |||
1797 | return v4l2_subdev_call(sd, video, g_parm, parm); | ||
1798 | } | ||
1799 | |||
1800 | static int sh_mobile_ceu_set_parm(struct soc_camera_device *icd, | ||
1801 | struct v4l2_streamparm *parm) | ||
1802 | { | ||
1803 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1804 | |||
1805 | return v4l2_subdev_call(sd, video, s_parm, parm); | ||
1806 | } | 1790 | } |
1807 | 1791 | ||
1808 | static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, | 1792 | static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, |
@@ -1866,8 +1850,6 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { | |||
1866 | .try_fmt = sh_mobile_ceu_try_fmt, | 1850 | .try_fmt = sh_mobile_ceu_try_fmt, |
1867 | .set_ctrl = sh_mobile_ceu_set_ctrl, | 1851 | .set_ctrl = sh_mobile_ceu_set_ctrl, |
1868 | .get_ctrl = sh_mobile_ceu_get_ctrl, | 1852 | .get_ctrl = sh_mobile_ceu_get_ctrl, |
1869 | .set_parm = sh_mobile_ceu_set_parm, | ||
1870 | .get_parm = sh_mobile_ceu_get_parm, | ||
1871 | .reqbufs = sh_mobile_ceu_reqbufs, | 1853 | .reqbufs = sh_mobile_ceu_reqbufs, |
1872 | .poll = sh_mobile_ceu_poll, | 1854 | .poll = sh_mobile_ceu_poll, |
1873 | .querycap = sh_mobile_ceu_querycap, | 1855 | .querycap = sh_mobile_ceu_querycap, |
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index d394187eb70..0f4906136b8 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
@@ -230,7 +230,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
230 | BUG_ON(in_interrupt()); | 230 | BUG_ON(in_interrupt()); |
231 | 231 | ||
232 | /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */ | 232 | /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */ |
233 | videobuf_waiton(vb, 0, 0); | 233 | videobuf_waiton(vq, vb, 0, 0); |
234 | videobuf_dma_contig_free(vq, vb); | 234 | videobuf_dma_contig_free(vq, vb); |
235 | vb->state = VIDEOBUF_NEEDS_INIT; | 235 | vb->state = VIDEOBUF_NEEDS_INIT; |
236 | } | 236 | } |
@@ -1189,7 +1189,8 @@ static int sh_vou_open(struct file *file) | |||
1189 | vou_dev->v4l2_dev.dev, &vou_dev->lock, | 1189 | vou_dev->v4l2_dev.dev, &vou_dev->lock, |
1190 | V4L2_BUF_TYPE_VIDEO_OUTPUT, | 1190 | V4L2_BUF_TYPE_VIDEO_OUTPUT, |
1191 | V4L2_FIELD_NONE, | 1191 | V4L2_FIELD_NONE, |
1192 | sizeof(struct videobuf_buffer), vdev); | 1192 | sizeof(struct videobuf_buffer), vdev, |
1193 | NULL); | ||
1193 | 1194 | ||
1194 | return 0; | 1195 | return 0; |
1195 | } | 1196 | } |
@@ -1405,7 +1406,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
1405 | goto ereset; | 1406 | goto ereset; |
1406 | 1407 | ||
1407 | subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap, | 1408 | subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap, |
1408 | vou_pdata->module_name, vou_pdata->board_info, NULL); | 1409 | NULL, vou_pdata->board_info, NULL); |
1409 | if (!subdev) { | 1410 | if (!subdev) { |
1410 | ret = -ENOMEM; | 1411 | ret = -ENOMEM; |
1411 | goto ei2cnd; | 1412 | goto ei2cnd; |
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h index b6643ca7656..ccfa59c5455 100644 --- a/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/drivers/media/video/sn9c102/sn9c102_devtable.h | |||
@@ -116,10 +116,14 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
116 | { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, | 116 | { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, |
117 | /* SN9C120 */ | 117 | /* SN9C120 */ |
118 | { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), }, | 118 | { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), }, |
119 | #if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE | ||
119 | { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, | 120 | { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, |
121 | #endif | ||
120 | { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, | 122 | { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, |
121 | { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, | 123 | { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, |
124 | #if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE | ||
122 | { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, | 125 | { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, |
126 | #endif | ||
123 | /* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */ | 127 | /* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */ |
124 | #if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE | 128 | #if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE |
125 | { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, | 129 | { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index a499cacec1f..43848a751d1 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -92,8 +92,7 @@ EXPORT_SYMBOL(soc_camera_apply_sensor_flags); | |||
92 | static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, | 92 | static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, |
93 | struct v4l2_format *f) | 93 | struct v4l2_format *f) |
94 | { | 94 | { |
95 | struct soc_camera_file *icf = file->private_data; | 95 | struct soc_camera_device *icd = file->private_data; |
96 | struct soc_camera_device *icd = icf->icd; | ||
97 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 96 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
98 | 97 | ||
99 | WARN_ON(priv != file->private_data); | 98 | WARN_ON(priv != file->private_data); |
@@ -105,8 +104,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, | |||
105 | static int soc_camera_enum_input(struct file *file, void *priv, | 104 | static int soc_camera_enum_input(struct file *file, void *priv, |
106 | struct v4l2_input *inp) | 105 | struct v4l2_input *inp) |
107 | { | 106 | { |
108 | struct soc_camera_file *icf = file->private_data; | 107 | struct soc_camera_device *icd = file->private_data; |
109 | struct soc_camera_device *icd = icf->icd; | ||
110 | int ret = 0; | 108 | int ret = 0; |
111 | 109 | ||
112 | if (inp->index != 0) | 110 | if (inp->index != 0) |
@@ -141,8 +139,7 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i) | |||
141 | 139 | ||
142 | static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) | 140 | static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) |
143 | { | 141 | { |
144 | struct soc_camera_file *icf = file->private_data; | 142 | struct soc_camera_device *icd = file->private_data; |
145 | struct soc_camera_device *icd = icf->icd; | ||
146 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 143 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
147 | 144 | ||
148 | return v4l2_subdev_call(sd, core, s_std, *a); | 145 | return v4l2_subdev_call(sd, core, s_std, *a); |
@@ -152,47 +149,59 @@ static int soc_camera_reqbufs(struct file *file, void *priv, | |||
152 | struct v4l2_requestbuffers *p) | 149 | struct v4l2_requestbuffers *p) |
153 | { | 150 | { |
154 | int ret; | 151 | int ret; |
155 | struct soc_camera_file *icf = file->private_data; | 152 | struct soc_camera_device *icd = file->private_data; |
156 | struct soc_camera_device *icd = icf->icd; | ||
157 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 153 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
158 | 154 | ||
159 | WARN_ON(priv != file->private_data); | 155 | WARN_ON(priv != file->private_data); |
160 | 156 | ||
161 | ret = videobuf_reqbufs(&icf->vb_vidq, p); | 157 | if (icd->streamer && icd->streamer != file) |
158 | return -EBUSY; | ||
159 | |||
160 | ret = videobuf_reqbufs(&icd->vb_vidq, p); | ||
162 | if (ret < 0) | 161 | if (ret < 0) |
163 | return ret; | 162 | return ret; |
164 | 163 | ||
165 | return ici->ops->reqbufs(icf, p); | 164 | ret = ici->ops->reqbufs(icd, p); |
165 | if (!ret && !icd->streamer) | ||
166 | icd->streamer = file; | ||
167 | |||
168 | return ret; | ||
166 | } | 169 | } |
167 | 170 | ||
168 | static int soc_camera_querybuf(struct file *file, void *priv, | 171 | static int soc_camera_querybuf(struct file *file, void *priv, |
169 | struct v4l2_buffer *p) | 172 | struct v4l2_buffer *p) |
170 | { | 173 | { |
171 | struct soc_camera_file *icf = file->private_data; | 174 | struct soc_camera_device *icd = file->private_data; |
172 | 175 | ||
173 | WARN_ON(priv != file->private_data); | 176 | WARN_ON(priv != file->private_data); |
174 | 177 | ||
175 | return videobuf_querybuf(&icf->vb_vidq, p); | 178 | return videobuf_querybuf(&icd->vb_vidq, p); |
176 | } | 179 | } |
177 | 180 | ||
178 | static int soc_camera_qbuf(struct file *file, void *priv, | 181 | static int soc_camera_qbuf(struct file *file, void *priv, |
179 | struct v4l2_buffer *p) | 182 | struct v4l2_buffer *p) |
180 | { | 183 | { |
181 | struct soc_camera_file *icf = file->private_data; | 184 | struct soc_camera_device *icd = file->private_data; |
182 | 185 | ||
183 | WARN_ON(priv != file->private_data); | 186 | WARN_ON(priv != file->private_data); |
184 | 187 | ||
185 | return videobuf_qbuf(&icf->vb_vidq, p); | 188 | if (icd->streamer != file) |
189 | return -EBUSY; | ||
190 | |||
191 | return videobuf_qbuf(&icd->vb_vidq, p); | ||
186 | } | 192 | } |
187 | 193 | ||
188 | static int soc_camera_dqbuf(struct file *file, void *priv, | 194 | static int soc_camera_dqbuf(struct file *file, void *priv, |
189 | struct v4l2_buffer *p) | 195 | struct v4l2_buffer *p) |
190 | { | 196 | { |
191 | struct soc_camera_file *icf = file->private_data; | 197 | struct soc_camera_device *icd = file->private_data; |
192 | 198 | ||
193 | WARN_ON(priv != file->private_data); | 199 | WARN_ON(priv != file->private_data); |
194 | 200 | ||
195 | return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); | 201 | if (icd->streamer != file) |
202 | return -EBUSY; | ||
203 | |||
204 | return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK); | ||
196 | } | 205 | } |
197 | 206 | ||
198 | /* Always entered with .video_lock held */ | 207 | /* Always entered with .video_lock held */ |
@@ -280,10 +289,9 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) | |||
280 | ((x) >> 24) & 0xff | 289 | ((x) >> 24) & 0xff |
281 | 290 | ||
282 | /* Called with .vb_lock held, or from the first open(2), see comment there */ | 291 | /* Called with .vb_lock held, or from the first open(2), see comment there */ |
283 | static int soc_camera_set_fmt(struct soc_camera_file *icf, | 292 | static int soc_camera_set_fmt(struct soc_camera_device *icd, |
284 | struct v4l2_format *f) | 293 | struct v4l2_format *f) |
285 | { | 294 | { |
286 | struct soc_camera_device *icd = icf->icd; | ||
287 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 295 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
288 | struct v4l2_pix_format *pix = &f->fmt.pix; | 296 | struct v4l2_pix_format *pix = &f->fmt.pix; |
289 | int ret; | 297 | int ret; |
@@ -309,7 +317,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, | |||
309 | icd->user_width = pix->width; | 317 | icd->user_width = pix->width; |
310 | icd->user_height = pix->height; | 318 | icd->user_height = pix->height; |
311 | icd->colorspace = pix->colorspace; | 319 | icd->colorspace = pix->colorspace; |
312 | icf->vb_vidq.field = | 320 | icd->vb_vidq.field = |
313 | icd->field = pix->field; | 321 | icd->field = pix->field; |
314 | 322 | ||
315 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 323 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
@@ -331,7 +339,6 @@ static int soc_camera_open(struct file *file) | |||
331 | dev); | 339 | dev); |
332 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 340 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
333 | struct soc_camera_host *ici; | 341 | struct soc_camera_host *ici; |
334 | struct soc_camera_file *icf; | ||
335 | int ret; | 342 | int ret; |
336 | 343 | ||
337 | if (!icd->ops) | 344 | if (!icd->ops) |
@@ -340,14 +347,9 @@ static int soc_camera_open(struct file *file) | |||
340 | 347 | ||
341 | ici = to_soc_camera_host(icd->dev.parent); | 348 | ici = to_soc_camera_host(icd->dev.parent); |
342 | 349 | ||
343 | icf = vmalloc(sizeof(*icf)); | ||
344 | if (!icf) | ||
345 | return -ENOMEM; | ||
346 | |||
347 | if (!try_module_get(ici->ops->owner)) { | 350 | if (!try_module_get(ici->ops->owner)) { |
348 | dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); | 351 | dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); |
349 | ret = -EINVAL; | 352 | return -EINVAL; |
350 | goto emgi; | ||
351 | } | 353 | } |
352 | 354 | ||
353 | /* | 355 | /* |
@@ -356,7 +358,6 @@ static int soc_camera_open(struct file *file) | |||
356 | */ | 358 | */ |
357 | mutex_lock(&icd->video_lock); | 359 | mutex_lock(&icd->video_lock); |
358 | 360 | ||
359 | icf->icd = icd; | ||
360 | icd->use_count++; | 361 | icd->use_count++; |
361 | 362 | ||
362 | /* Now we really have to activate the camera */ | 363 | /* Now we really have to activate the camera */ |
@@ -401,15 +402,15 @@ static int soc_camera_open(struct file *file) | |||
401 | * apart from someone else calling open() simultaneously, but | 402 | * apart from someone else calling open() simultaneously, but |
402 | * .video_lock is protecting us against it. | 403 | * .video_lock is protecting us against it. |
403 | */ | 404 | */ |
404 | ret = soc_camera_set_fmt(icf, &f); | 405 | ret = soc_camera_set_fmt(icd, &f); |
405 | if (ret < 0) | 406 | if (ret < 0) |
406 | goto esfmt; | 407 | goto esfmt; |
407 | } | 408 | } |
408 | 409 | ||
409 | file->private_data = icf; | 410 | file->private_data = icd; |
410 | dev_dbg(&icd->dev, "camera device open\n"); | 411 | dev_dbg(&icd->dev, "camera device open\n"); |
411 | 412 | ||
412 | ici->ops->init_videobuf(&icf->vb_vidq, icd); | 413 | ici->ops->init_videobuf(&icd->vb_vidq, icd); |
413 | 414 | ||
414 | mutex_unlock(&icd->video_lock); | 415 | mutex_unlock(&icd->video_lock); |
415 | 416 | ||
@@ -430,15 +431,13 @@ epower: | |||
430 | icd->use_count--; | 431 | icd->use_count--; |
431 | mutex_unlock(&icd->video_lock); | 432 | mutex_unlock(&icd->video_lock); |
432 | module_put(ici->ops->owner); | 433 | module_put(ici->ops->owner); |
433 | emgi: | 434 | |
434 | vfree(icf); | ||
435 | return ret; | 435 | return ret; |
436 | } | 436 | } |
437 | 437 | ||
438 | static int soc_camera_close(struct file *file) | 438 | static int soc_camera_close(struct file *file) |
439 | { | 439 | { |
440 | struct soc_camera_file *icf = file->private_data; | 440 | struct soc_camera_device *icd = file->private_data; |
441 | struct soc_camera_device *icd = icf->icd; | ||
442 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 441 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
443 | 442 | ||
444 | mutex_lock(&icd->video_lock); | 443 | mutex_lock(&icd->video_lock); |
@@ -455,12 +454,13 @@ static int soc_camera_close(struct file *file) | |||
455 | icl->power(icd->pdev, 0); | 454 | icl->power(icd->pdev, 0); |
456 | } | 455 | } |
457 | 456 | ||
457 | if (icd->streamer == file) | ||
458 | icd->streamer = NULL; | ||
459 | |||
458 | mutex_unlock(&icd->video_lock); | 460 | mutex_unlock(&icd->video_lock); |
459 | 461 | ||
460 | module_put(ici->ops->owner); | 462 | module_put(ici->ops->owner); |
461 | 463 | ||
462 | vfree(icf); | ||
463 | |||
464 | dev_dbg(&icd->dev, "camera device close\n"); | 464 | dev_dbg(&icd->dev, "camera device close\n"); |
465 | 465 | ||
466 | return 0; | 466 | return 0; |
@@ -469,8 +469,7 @@ static int soc_camera_close(struct file *file) | |||
469 | static ssize_t soc_camera_read(struct file *file, char __user *buf, | 469 | static ssize_t soc_camera_read(struct file *file, char __user *buf, |
470 | size_t count, loff_t *ppos) | 470 | size_t count, loff_t *ppos) |
471 | { | 471 | { |
472 | struct soc_camera_file *icf = file->private_data; | 472 | struct soc_camera_device *icd = file->private_data; |
473 | struct soc_camera_device *icd = icf->icd; | ||
474 | int err = -EINVAL; | 473 | int err = -EINVAL; |
475 | 474 | ||
476 | dev_err(&icd->dev, "camera device read not implemented\n"); | 475 | dev_err(&icd->dev, "camera device read not implemented\n"); |
@@ -480,13 +479,15 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf, | |||
480 | 479 | ||
481 | static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) | 480 | static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) |
482 | { | 481 | { |
483 | struct soc_camera_file *icf = file->private_data; | 482 | struct soc_camera_device *icd = file->private_data; |
484 | struct soc_camera_device *icd = icf->icd; | ||
485 | int err; | 483 | int err; |
486 | 484 | ||
487 | dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); | 485 | dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); |
488 | 486 | ||
489 | err = videobuf_mmap_mapper(&icf->vb_vidq, vma); | 487 | if (icd->streamer != file) |
488 | return -EBUSY; | ||
489 | |||
490 | err = videobuf_mmap_mapper(&icd->vb_vidq, vma); | ||
490 | 491 | ||
491 | dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", | 492 | dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", |
492 | (unsigned long)vma->vm_start, | 493 | (unsigned long)vma->vm_start, |
@@ -498,11 +499,13 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) | |||
498 | 499 | ||
499 | static unsigned int soc_camera_poll(struct file *file, poll_table *pt) | 500 | static unsigned int soc_camera_poll(struct file *file, poll_table *pt) |
500 | { | 501 | { |
501 | struct soc_camera_file *icf = file->private_data; | 502 | struct soc_camera_device *icd = file->private_data; |
502 | struct soc_camera_device *icd = icf->icd; | ||
503 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 503 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
504 | 504 | ||
505 | if (list_empty(&icf->vb_vidq.stream)) { | 505 | if (icd->streamer != file) |
506 | return -EBUSY; | ||
507 | |||
508 | if (list_empty(&icd->vb_vidq.stream)) { | ||
506 | dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); | 509 | dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); |
507 | return POLLERR; | 510 | return POLLERR; |
508 | } | 511 | } |
@@ -523,24 +526,29 @@ static struct v4l2_file_operations soc_camera_fops = { | |||
523 | static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, | 526 | static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, |
524 | struct v4l2_format *f) | 527 | struct v4l2_format *f) |
525 | { | 528 | { |
526 | struct soc_camera_file *icf = file->private_data; | 529 | struct soc_camera_device *icd = file->private_data; |
527 | struct soc_camera_device *icd = icf->icd; | ||
528 | int ret; | 530 | int ret; |
529 | 531 | ||
530 | WARN_ON(priv != file->private_data); | 532 | WARN_ON(priv != file->private_data); |
531 | 533 | ||
532 | mutex_lock(&icf->vb_vidq.vb_lock); | 534 | if (icd->streamer && icd->streamer != file) |
535 | return -EBUSY; | ||
536 | |||
537 | mutex_lock(&icd->vb_vidq.vb_lock); | ||
533 | 538 | ||
534 | if (icf->vb_vidq.bufs[0]) { | 539 | if (icd->vb_vidq.bufs[0]) { |
535 | dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); | 540 | dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); |
536 | ret = -EBUSY; | 541 | ret = -EBUSY; |
537 | goto unlock; | 542 | goto unlock; |
538 | } | 543 | } |
539 | 544 | ||
540 | ret = soc_camera_set_fmt(icf, f); | 545 | ret = soc_camera_set_fmt(icd, f); |
546 | |||
547 | if (!ret && !icd->streamer) | ||
548 | icd->streamer = file; | ||
541 | 549 | ||
542 | unlock: | 550 | unlock: |
543 | mutex_unlock(&icf->vb_vidq.vb_lock); | 551 | mutex_unlock(&icd->vb_vidq.vb_lock); |
544 | 552 | ||
545 | return ret; | 553 | return ret; |
546 | } | 554 | } |
@@ -548,8 +556,7 @@ unlock: | |||
548 | static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, | 556 | static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, |
549 | struct v4l2_fmtdesc *f) | 557 | struct v4l2_fmtdesc *f) |
550 | { | 558 | { |
551 | struct soc_camera_file *icf = file->private_data; | 559 | struct soc_camera_device *icd = file->private_data; |
552 | struct soc_camera_device *icd = icf->icd; | ||
553 | const struct soc_mbus_pixelfmt *format; | 560 | const struct soc_mbus_pixelfmt *format; |
554 | 561 | ||
555 | WARN_ON(priv != file->private_data); | 562 | WARN_ON(priv != file->private_data); |
@@ -568,15 +575,14 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, | |||
568 | static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, | 575 | static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, |
569 | struct v4l2_format *f) | 576 | struct v4l2_format *f) |
570 | { | 577 | { |
571 | struct soc_camera_file *icf = file->private_data; | 578 | struct soc_camera_device *icd = file->private_data; |
572 | struct soc_camera_device *icd = icf->icd; | ||
573 | struct v4l2_pix_format *pix = &f->fmt.pix; | 579 | struct v4l2_pix_format *pix = &f->fmt.pix; |
574 | 580 | ||
575 | WARN_ON(priv != file->private_data); | 581 | WARN_ON(priv != file->private_data); |
576 | 582 | ||
577 | pix->width = icd->user_width; | 583 | pix->width = icd->user_width; |
578 | pix->height = icd->user_height; | 584 | pix->height = icd->user_height; |
579 | pix->field = icf->vb_vidq.field; | 585 | pix->field = icd->vb_vidq.field; |
580 | pix->pixelformat = icd->current_fmt->host_fmt->fourcc; | 586 | pix->pixelformat = icd->current_fmt->host_fmt->fourcc; |
581 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, | 587 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, |
582 | icd->current_fmt->host_fmt); | 588 | icd->current_fmt->host_fmt); |
@@ -592,8 +598,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, | |||
592 | static int soc_camera_querycap(struct file *file, void *priv, | 598 | static int soc_camera_querycap(struct file *file, void *priv, |
593 | struct v4l2_capability *cap) | 599 | struct v4l2_capability *cap) |
594 | { | 600 | { |
595 | struct soc_camera_file *icf = file->private_data; | 601 | struct soc_camera_device *icd = file->private_data; |
596 | struct soc_camera_device *icd = icf->icd; | ||
597 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 602 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
598 | 603 | ||
599 | WARN_ON(priv != file->private_data); | 604 | WARN_ON(priv != file->private_data); |
@@ -605,8 +610,7 @@ static int soc_camera_querycap(struct file *file, void *priv, | |||
605 | static int soc_camera_streamon(struct file *file, void *priv, | 610 | static int soc_camera_streamon(struct file *file, void *priv, |
606 | enum v4l2_buf_type i) | 611 | enum v4l2_buf_type i) |
607 | { | 612 | { |
608 | struct soc_camera_file *icf = file->private_data; | 613 | struct soc_camera_device *icd = file->private_data; |
609 | struct soc_camera_device *icd = icf->icd; | ||
610 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 614 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
611 | int ret; | 615 | int ret; |
612 | 616 | ||
@@ -615,12 +619,15 @@ static int soc_camera_streamon(struct file *file, void *priv, | |||
615 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 619 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
616 | return -EINVAL; | 620 | return -EINVAL; |
617 | 621 | ||
622 | if (icd->streamer != file) | ||
623 | return -EBUSY; | ||
624 | |||
618 | mutex_lock(&icd->video_lock); | 625 | mutex_lock(&icd->video_lock); |
619 | 626 | ||
620 | v4l2_subdev_call(sd, video, s_stream, 1); | 627 | v4l2_subdev_call(sd, video, s_stream, 1); |
621 | 628 | ||
622 | /* This calls buf_queue from host driver's videobuf_queue_ops */ | 629 | /* This calls buf_queue from host driver's videobuf_queue_ops */ |
623 | ret = videobuf_streamon(&icf->vb_vidq); | 630 | ret = videobuf_streamon(&icd->vb_vidq); |
624 | 631 | ||
625 | mutex_unlock(&icd->video_lock); | 632 | mutex_unlock(&icd->video_lock); |
626 | 633 | ||
@@ -630,8 +637,7 @@ static int soc_camera_streamon(struct file *file, void *priv, | |||
630 | static int soc_camera_streamoff(struct file *file, void *priv, | 637 | static int soc_camera_streamoff(struct file *file, void *priv, |
631 | enum v4l2_buf_type i) | 638 | enum v4l2_buf_type i) |
632 | { | 639 | { |
633 | struct soc_camera_file *icf = file->private_data; | 640 | struct soc_camera_device *icd = file->private_data; |
634 | struct soc_camera_device *icd = icf->icd; | ||
635 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 641 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
636 | 642 | ||
637 | WARN_ON(priv != file->private_data); | 643 | WARN_ON(priv != file->private_data); |
@@ -639,13 +645,16 @@ static int soc_camera_streamoff(struct file *file, void *priv, | |||
639 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 645 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
640 | return -EINVAL; | 646 | return -EINVAL; |
641 | 647 | ||
648 | if (icd->streamer != file) | ||
649 | return -EBUSY; | ||
650 | |||
642 | mutex_lock(&icd->video_lock); | 651 | mutex_lock(&icd->video_lock); |
643 | 652 | ||
644 | /* | 653 | /* |
645 | * This calls buf_release from host driver's videobuf_queue_ops for all | 654 | * This calls buf_release from host driver's videobuf_queue_ops for all |
646 | * remaining buffers. When the last buffer is freed, stop capture | 655 | * remaining buffers. When the last buffer is freed, stop capture |
647 | */ | 656 | */ |
648 | videobuf_streamoff(&icf->vb_vidq); | 657 | videobuf_streamoff(&icd->vb_vidq); |
649 | 658 | ||
650 | v4l2_subdev_call(sd, video, s_stream, 0); | 659 | v4l2_subdev_call(sd, video, s_stream, 0); |
651 | 660 | ||
@@ -657,8 +666,7 @@ static int soc_camera_streamoff(struct file *file, void *priv, | |||
657 | static int soc_camera_queryctrl(struct file *file, void *priv, | 666 | static int soc_camera_queryctrl(struct file *file, void *priv, |
658 | struct v4l2_queryctrl *qc) | 667 | struct v4l2_queryctrl *qc) |
659 | { | 668 | { |
660 | struct soc_camera_file *icf = file->private_data; | 669 | struct soc_camera_device *icd = file->private_data; |
661 | struct soc_camera_device *icd = icf->icd; | ||
662 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 670 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
663 | int i; | 671 | int i; |
664 | 672 | ||
@@ -689,8 +697,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv, | |||
689 | static int soc_camera_g_ctrl(struct file *file, void *priv, | 697 | static int soc_camera_g_ctrl(struct file *file, void *priv, |
690 | struct v4l2_control *ctrl) | 698 | struct v4l2_control *ctrl) |
691 | { | 699 | { |
692 | struct soc_camera_file *icf = file->private_data; | 700 | struct soc_camera_device *icd = file->private_data; |
693 | struct soc_camera_device *icd = icf->icd; | ||
694 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 701 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
695 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 702 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
696 | int ret; | 703 | int ret; |
@@ -709,8 +716,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv, | |||
709 | static int soc_camera_s_ctrl(struct file *file, void *priv, | 716 | static int soc_camera_s_ctrl(struct file *file, void *priv, |
710 | struct v4l2_control *ctrl) | 717 | struct v4l2_control *ctrl) |
711 | { | 718 | { |
712 | struct soc_camera_file *icf = file->private_data; | 719 | struct soc_camera_device *icd = file->private_data; |
713 | struct soc_camera_device *icd = icf->icd; | ||
714 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 720 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
715 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 721 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
716 | int ret; | 722 | int ret; |
@@ -729,8 +735,7 @@ static int soc_camera_s_ctrl(struct file *file, void *priv, | |||
729 | static int soc_camera_cropcap(struct file *file, void *fh, | 735 | static int soc_camera_cropcap(struct file *file, void *fh, |
730 | struct v4l2_cropcap *a) | 736 | struct v4l2_cropcap *a) |
731 | { | 737 | { |
732 | struct soc_camera_file *icf = file->private_data; | 738 | struct soc_camera_device *icd = file->private_data; |
733 | struct soc_camera_device *icd = icf->icd; | ||
734 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 739 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
735 | 740 | ||
736 | return ici->ops->cropcap(icd, a); | 741 | return ici->ops->cropcap(icd, a); |
@@ -739,14 +744,13 @@ static int soc_camera_cropcap(struct file *file, void *fh, | |||
739 | static int soc_camera_g_crop(struct file *file, void *fh, | 744 | static int soc_camera_g_crop(struct file *file, void *fh, |
740 | struct v4l2_crop *a) | 745 | struct v4l2_crop *a) |
741 | { | 746 | { |
742 | struct soc_camera_file *icf = file->private_data; | 747 | struct soc_camera_device *icd = file->private_data; |
743 | struct soc_camera_device *icd = icf->icd; | ||
744 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 748 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
745 | int ret; | 749 | int ret; |
746 | 750 | ||
747 | mutex_lock(&icf->vb_vidq.vb_lock); | 751 | mutex_lock(&icd->vb_vidq.vb_lock); |
748 | ret = ici->ops->get_crop(icd, a); | 752 | ret = ici->ops->get_crop(icd, a); |
749 | mutex_unlock(&icf->vb_vidq.vb_lock); | 753 | mutex_unlock(&icd->vb_vidq.vb_lock); |
750 | 754 | ||
751 | return ret; | 755 | return ret; |
752 | } | 756 | } |
@@ -759,8 +763,7 @@ static int soc_camera_g_crop(struct file *file, void *fh, | |||
759 | static int soc_camera_s_crop(struct file *file, void *fh, | 763 | static int soc_camera_s_crop(struct file *file, void *fh, |
760 | struct v4l2_crop *a) | 764 | struct v4l2_crop *a) |
761 | { | 765 | { |
762 | struct soc_camera_file *icf = file->private_data; | 766 | struct soc_camera_device *icd = file->private_data; |
763 | struct soc_camera_device *icd = icf->icd; | ||
764 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 767 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
765 | struct v4l2_rect *rect = &a->c; | 768 | struct v4l2_rect *rect = &a->c; |
766 | struct v4l2_crop current_crop; | 769 | struct v4l2_crop current_crop; |
@@ -773,7 +776,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
773 | rect->width, rect->height, rect->left, rect->top); | 776 | rect->width, rect->height, rect->left, rect->top); |
774 | 777 | ||
775 | /* Cropping is allowed during a running capture, guard consistency */ | 778 | /* Cropping is allowed during a running capture, guard consistency */ |
776 | mutex_lock(&icf->vb_vidq.vb_lock); | 779 | mutex_lock(&icd->vb_vidq.vb_lock); |
777 | 780 | ||
778 | /* If get_crop fails, we'll let host and / or client drivers decide */ | 781 | /* If get_crop fails, we'll let host and / or client drivers decide */ |
779 | ret = ici->ops->get_crop(icd, ¤t_crop); | 782 | ret = ici->ops->get_crop(icd, ¤t_crop); |
@@ -782,7 +785,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
782 | if (ret < 0) { | 785 | if (ret < 0) { |
783 | dev_err(&icd->dev, | 786 | dev_err(&icd->dev, |
784 | "S_CROP denied: getting current crop failed\n"); | 787 | "S_CROP denied: getting current crop failed\n"); |
785 | } else if (icf->vb_vidq.bufs[0] && | 788 | } else if (icd->vb_vidq.bufs[0] && |
786 | (a->c.width != current_crop.c.width || | 789 | (a->c.width != current_crop.c.width || |
787 | a->c.height != current_crop.c.height)) { | 790 | a->c.height != current_crop.c.height)) { |
788 | dev_err(&icd->dev, | 791 | dev_err(&icd->dev, |
@@ -792,7 +795,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
792 | ret = ici->ops->set_crop(icd, a); | 795 | ret = ici->ops->set_crop(icd, a); |
793 | } | 796 | } |
794 | 797 | ||
795 | mutex_unlock(&icf->vb_vidq.vb_lock); | 798 | mutex_unlock(&icd->vb_vidq.vb_lock); |
796 | 799 | ||
797 | return ret; | 800 | return ret; |
798 | } | 801 | } |
@@ -800,8 +803,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, | |||
800 | static int soc_camera_g_parm(struct file *file, void *fh, | 803 | static int soc_camera_g_parm(struct file *file, void *fh, |
801 | struct v4l2_streamparm *a) | 804 | struct v4l2_streamparm *a) |
802 | { | 805 | { |
803 | struct soc_camera_file *icf = file->private_data; | 806 | struct soc_camera_device *icd = file->private_data; |
804 | struct soc_camera_device *icd = icf->icd; | ||
805 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 807 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
806 | 808 | ||
807 | if (ici->ops->get_parm) | 809 | if (ici->ops->get_parm) |
@@ -813,8 +815,7 @@ static int soc_camera_g_parm(struct file *file, void *fh, | |||
813 | static int soc_camera_s_parm(struct file *file, void *fh, | 815 | static int soc_camera_s_parm(struct file *file, void *fh, |
814 | struct v4l2_streamparm *a) | 816 | struct v4l2_streamparm *a) |
815 | { | 817 | { |
816 | struct soc_camera_file *icf = file->private_data; | 818 | struct soc_camera_device *icd = file->private_data; |
817 | struct soc_camera_device *icd = icf->icd; | ||
818 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 819 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
819 | 820 | ||
820 | if (ici->ops->set_parm) | 821 | if (ici->ops->set_parm) |
@@ -826,8 +827,7 @@ static int soc_camera_s_parm(struct file *file, void *fh, | |||
826 | static int soc_camera_g_chip_ident(struct file *file, void *fh, | 827 | static int soc_camera_g_chip_ident(struct file *file, void *fh, |
827 | struct v4l2_dbg_chip_ident *id) | 828 | struct v4l2_dbg_chip_ident *id) |
828 | { | 829 | { |
829 | struct soc_camera_file *icf = file->private_data; | 830 | struct soc_camera_device *icd = file->private_data; |
830 | struct soc_camera_device *icd = icf->icd; | ||
831 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 831 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
832 | 832 | ||
833 | return v4l2_subdev_call(sd, core, g_chip_ident, id); | 833 | return v4l2_subdev_call(sd, core, g_chip_ident, id); |
@@ -837,8 +837,7 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh, | |||
837 | static int soc_camera_g_register(struct file *file, void *fh, | 837 | static int soc_camera_g_register(struct file *file, void *fh, |
838 | struct v4l2_dbg_register *reg) | 838 | struct v4l2_dbg_register *reg) |
839 | { | 839 | { |
840 | struct soc_camera_file *icf = file->private_data; | 840 | struct soc_camera_device *icd = file->private_data; |
841 | struct soc_camera_device *icd = icf->icd; | ||
842 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 841 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
843 | 842 | ||
844 | return v4l2_subdev_call(sd, core, g_register, reg); | 843 | return v4l2_subdev_call(sd, core, g_register, reg); |
@@ -847,8 +846,7 @@ static int soc_camera_g_register(struct file *file, void *fh, | |||
847 | static int soc_camera_s_register(struct file *file, void *fh, | 846 | static int soc_camera_s_register(struct file *file, void *fh, |
848 | struct v4l2_dbg_register *reg) | 847 | struct v4l2_dbg_register *reg) |
849 | { | 848 | { |
850 | struct soc_camera_file *icf = file->private_data; | 849 | struct soc_camera_device *icd = file->private_data; |
851 | struct soc_camera_device *icd = icf->icd; | ||
852 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 850 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
853 | 851 | ||
854 | return v4l2_subdev_call(sd, core, s_register, reg); | 852 | return v4l2_subdev_call(sd, core, s_register, reg); |
@@ -898,11 +896,11 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd, | |||
898 | icl->board_info->platform_data = icd; | 896 | icl->board_info->platform_data = icd; |
899 | 897 | ||
900 | subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, | 898 | subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, |
901 | icl->module_name, icl->board_info, NULL); | 899 | NULL, icl->board_info, NULL); |
902 | if (!subdev) | 900 | if (!subdev) |
903 | goto ei2cnd; | 901 | goto ei2cnd; |
904 | 902 | ||
905 | client = subdev->priv; | 903 | client = v4l2_get_subdevdata(subdev); |
906 | 904 | ||
907 | /* Use to_i2c_client(dev) to recover the i2c client */ | 905 | /* Use to_i2c_client(dev) to recover the i2c client */ |
908 | dev_set_drvdata(&icd->dev, &client->dev); | 906 | dev_set_drvdata(&icd->dev, &client->dev); |
@@ -1148,6 +1146,20 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a) | |||
1148 | return v4l2_subdev_call(sd, video, s_crop, a); | 1146 | return v4l2_subdev_call(sd, video, s_crop, a); |
1149 | } | 1147 | } |
1150 | 1148 | ||
1149 | static int default_g_parm(struct soc_camera_device *icd, | ||
1150 | struct v4l2_streamparm *parm) | ||
1151 | { | ||
1152 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1153 | return v4l2_subdev_call(sd, video, g_parm, parm); | ||
1154 | } | ||
1155 | |||
1156 | static int default_s_parm(struct soc_camera_device *icd, | ||
1157 | struct v4l2_streamparm *parm) | ||
1158 | { | ||
1159 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1160 | return v4l2_subdev_call(sd, video, s_parm, parm); | ||
1161 | } | ||
1162 | |||
1151 | static void soc_camera_device_init(struct device *dev, void *pdata) | 1163 | static void soc_camera_device_init(struct device *dev, void *pdata) |
1152 | { | 1164 | { |
1153 | dev->platform_data = pdata; | 1165 | dev->platform_data = pdata; |
@@ -1179,6 +1191,10 @@ int soc_camera_host_register(struct soc_camera_host *ici) | |||
1179 | ici->ops->get_crop = default_g_crop; | 1191 | ici->ops->get_crop = default_g_crop; |
1180 | if (!ici->ops->cropcap) | 1192 | if (!ici->ops->cropcap) |
1181 | ici->ops->cropcap = default_cropcap; | 1193 | ici->ops->cropcap = default_cropcap; |
1194 | if (!ici->ops->set_parm) | ||
1195 | ici->ops->set_parm = default_s_parm; | ||
1196 | if (!ici->ops->get_parm) | ||
1197 | ici->ops->get_parm = default_g_parm; | ||
1182 | 1198 | ||
1183 | mutex_lock(&list_lock); | 1199 | mutex_lock(&list_lock); |
1184 | list_for_each_entry(ix, &hosts, list) { | 1200 | list_for_each_entry(ix, &hosts, list) { |
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c new file mode 100644 index 00000000000..c9dc67aba98 --- /dev/null +++ b/drivers/media/video/sr030pc30.c | |||
@@ -0,0 +1,894 @@ | |||
1 | /* | ||
2 | * Driver for SiliconFile SR030PC30 VGA (1/10-Inch) Image Sensor with ISP | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co., Ltd | ||
5 | * Author: Sylwester Nawrocki, s.nawrocki@samsung.com | ||
6 | * | ||
7 | * Based on original driver authored by Dongsoo Nathaniel Kim | ||
8 | * and HeungJun Kim <riverful.kim@samsung.com>. | ||
9 | * | ||
10 | * Based on mt9v011 Micron Digital Image Sensor driver | ||
11 | * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <media/v4l2-device.h> | ||
23 | #include <media/v4l2-subdev.h> | ||
24 | #include <media/v4l2-mediabus.h> | ||
25 | #include <media/sr030pc30.h> | ||
26 | |||
27 | static int debug; | ||
28 | module_param(debug, int, 0644); | ||
29 | |||
30 | #define MODULE_NAME "SR030PC30" | ||
31 | |||
32 | /* | ||
33 | * Register offsets within a page | ||
34 | * b15..b8 - page id, b7..b0 - register address | ||
35 | */ | ||
36 | #define POWER_CTRL_REG 0x0001 | ||
37 | #define PAGEMODE_REG 0x03 | ||
38 | #define DEVICE_ID_REG 0x0004 | ||
39 | #define NOON010PC30_ID 0x86 | ||
40 | #define SR030PC30_ID 0x8C | ||
41 | #define VDO_CTL1_REG 0x0010 | ||
42 | #define SUBSAMPL_NONE_VGA 0 | ||
43 | #define SUBSAMPL_QVGA 0x10 | ||
44 | #define SUBSAMPL_QQVGA 0x20 | ||
45 | #define VDO_CTL2_REG 0x0011 | ||
46 | #define SYNC_CTL_REG 0x0012 | ||
47 | #define WIN_ROWH_REG 0x0020 | ||
48 | #define WIN_ROWL_REG 0x0021 | ||
49 | #define WIN_COLH_REG 0x0022 | ||
50 | #define WIN_COLL_REG 0x0023 | ||
51 | #define WIN_HEIGHTH_REG 0x0024 | ||
52 | #define WIN_HEIGHTL_REG 0x0025 | ||
53 | #define WIN_WIDTHH_REG 0x0026 | ||
54 | #define WIN_WIDTHL_REG 0x0027 | ||
55 | #define HBLANKH_REG 0x0040 | ||
56 | #define HBLANKL_REG 0x0041 | ||
57 | #define VSYNCH_REG 0x0042 | ||
58 | #define VSYNCL_REG 0x0043 | ||
59 | /* page 10 */ | ||
60 | #define ISP_CTL_REG(n) (0x1010 + (n)) | ||
61 | #define YOFS_REG 0x1040 | ||
62 | #define DARK_YOFS_REG 0x1041 | ||
63 | #define AG_ABRTH_REG 0x1050 | ||
64 | #define SAT_CTL_REG 0x1060 | ||
65 | #define BSAT_REG 0x1061 | ||
66 | #define RSAT_REG 0x1062 | ||
67 | #define AG_SAT_TH_REG 0x1063 | ||
68 | /* page 11 */ | ||
69 | #define ZLPF_CTRL_REG 0x1110 | ||
70 | #define ZLPF_CTRL2_REG 0x1112 | ||
71 | #define ZLPF_AGH_THR_REG 0x1121 | ||
72 | #define ZLPF_THR_REG 0x1160 | ||
73 | #define ZLPF_DYN_THR_REG 0x1160 | ||
74 | /* page 12 */ | ||
75 | #define YCLPF_CTL1_REG 0x1240 | ||
76 | #define YCLPF_CTL2_REG 0x1241 | ||
77 | #define YCLPF_THR_REG 0x1250 | ||
78 | #define BLPF_CTL_REG 0x1270 | ||
79 | #define BLPF_THR1_REG 0x1274 | ||
80 | #define BLPF_THR2_REG 0x1275 | ||
81 | /* page 14 - Lens Shading Compensation */ | ||
82 | #define LENS_CTRL_REG 0x1410 | ||
83 | #define LENS_XCEN_REG 0x1420 | ||
84 | #define LENS_YCEN_REG 0x1421 | ||
85 | #define LENS_R_COMP_REG 0x1422 | ||
86 | #define LENS_G_COMP_REG 0x1423 | ||
87 | #define LENS_B_COMP_REG 0x1424 | ||
88 | /* page 15 - Color correction */ | ||
89 | #define CMC_CTL_REG 0x1510 | ||
90 | #define CMC_OFSGH_REG 0x1514 | ||
91 | #define CMC_OFSGL_REG 0x1516 | ||
92 | #define CMC_SIGN_REG 0x1517 | ||
93 | /* Color correction coefficients */ | ||
94 | #define CMC_COEF_REG(n) (0x1530 + (n)) | ||
95 | /* Color correction offset coefficients */ | ||
96 | #define CMC_OFS_REG(n) (0x1540 + (n)) | ||
97 | /* page 16 - Gamma correction */ | ||
98 | #define GMA_CTL_REG 0x1610 | ||
99 | /* Gamma correction coefficients 0.14 */ | ||
100 | #define GMA_COEF_REG(n) (0x1630 + (n)) | ||
101 | /* page 20 - Auto Exposure */ | ||
102 | #define AE_CTL1_REG 0x2010 | ||
103 | #define AE_CTL2_REG 0x2011 | ||
104 | #define AE_FRM_CTL_REG 0x2020 | ||
105 | #define AE_FINE_CTL_REG(n) (0x2028 + (n)) | ||
106 | #define EXP_TIMEH_REG 0x2083 | ||
107 | #define EXP_TIMEM_REG 0x2084 | ||
108 | #define EXP_TIMEL_REG 0x2085 | ||
109 | #define EXP_MMINH_REG 0x2086 | ||
110 | #define EXP_MMINL_REG 0x2087 | ||
111 | #define EXP_MMAXH_REG 0x2088 | ||
112 | #define EXP_MMAXM_REG 0x2089 | ||
113 | #define EXP_MMAXL_REG 0x208A | ||
114 | /* page 22 - Auto White Balance */ | ||
115 | #define AWB_CTL1_REG 0x2210 | ||
116 | #define AWB_ENABLE 0x80 | ||
117 | #define AWB_CTL2_REG 0x2211 | ||
118 | #define MWB_ENABLE 0x01 | ||
119 | /* RGB gain control (manual WB) when AWB_CTL1[7]=0 */ | ||
120 | #define AWB_RGAIN_REG 0x2280 | ||
121 | #define AWB_GGAIN_REG 0x2281 | ||
122 | #define AWB_BGAIN_REG 0x2282 | ||
123 | #define AWB_RMAX_REG 0x2283 | ||
124 | #define AWB_RMIN_REG 0x2284 | ||
125 | #define AWB_BMAX_REG 0x2285 | ||
126 | #define AWB_BMIN_REG 0x2286 | ||
127 | /* R, B gain range in bright light conditions */ | ||
128 | #define AWB_RMAXB_REG 0x2287 | ||
129 | #define AWB_RMINB_REG 0x2288 | ||
130 | #define AWB_BMAXB_REG 0x2289 | ||
131 | #define AWB_BMINB_REG 0x228A | ||
132 | /* manual white balance, when AWB_CTL2[0]=1 */ | ||
133 | #define MWB_RGAIN_REG 0x22B2 | ||
134 | #define MWB_BGAIN_REG 0x22B3 | ||
135 | /* the token to mark an array end */ | ||
136 | #define REG_TERM 0xFFFF | ||
137 | |||
138 | /* Minimum and maximum exposure time in ms */ | ||
139 | #define EXPOS_MIN_MS 1 | ||
140 | #define EXPOS_MAX_MS 125 | ||
141 | |||
142 | struct sr030pc30_info { | ||
143 | struct v4l2_subdev sd; | ||
144 | const struct sr030pc30_platform_data *pdata; | ||
145 | const struct sr030pc30_format *curr_fmt; | ||
146 | const struct sr030pc30_frmsize *curr_win; | ||
147 | unsigned int auto_wb:1; | ||
148 | unsigned int auto_exp:1; | ||
149 | unsigned int hflip:1; | ||
150 | unsigned int vflip:1; | ||
151 | unsigned int sleep:1; | ||
152 | unsigned int exposure; | ||
153 | u8 blue_balance; | ||
154 | u8 red_balance; | ||
155 | u8 i2c_reg_page; | ||
156 | }; | ||
157 | |||
158 | struct sr030pc30_format { | ||
159 | enum v4l2_mbus_pixelcode code; | ||
160 | enum v4l2_colorspace colorspace; | ||
161 | u16 ispctl1_reg; | ||
162 | }; | ||
163 | |||
164 | struct sr030pc30_frmsize { | ||
165 | u16 width; | ||
166 | u16 height; | ||
167 | int vid_ctl1; | ||
168 | }; | ||
169 | |||
170 | struct i2c_regval { | ||
171 | u16 addr; | ||
172 | u16 val; | ||
173 | }; | ||
174 | |||
175 | static const struct v4l2_queryctrl sr030pc30_ctrl[] = { | ||
176 | { | ||
177 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
178 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
179 | .name = "Auto White Balance", | ||
180 | .minimum = 0, | ||
181 | .maximum = 1, | ||
182 | .step = 1, | ||
183 | .default_value = 1, | ||
184 | }, { | ||
185 | .id = V4L2_CID_RED_BALANCE, | ||
186 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
187 | .name = "Red Balance", | ||
188 | .minimum = 0, | ||
189 | .maximum = 127, | ||
190 | .step = 1, | ||
191 | .default_value = 64, | ||
192 | .flags = 0, | ||
193 | }, { | ||
194 | .id = V4L2_CID_BLUE_BALANCE, | ||
195 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
196 | .name = "Blue Balance", | ||
197 | .minimum = 0, | ||
198 | .maximum = 127, | ||
199 | .step = 1, | ||
200 | .default_value = 64, | ||
201 | }, { | ||
202 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
203 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
204 | .name = "Auto Exposure", | ||
205 | .minimum = 0, | ||
206 | .maximum = 1, | ||
207 | .step = 1, | ||
208 | .default_value = 1, | ||
209 | }, { | ||
210 | .id = V4L2_CID_EXPOSURE, | ||
211 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
212 | .name = "Exposure", | ||
213 | .minimum = EXPOS_MIN_MS, | ||
214 | .maximum = EXPOS_MAX_MS, | ||
215 | .step = 1, | ||
216 | .default_value = 1, | ||
217 | }, { | ||
218 | } | ||
219 | }; | ||
220 | |||
221 | /* supported resolutions */ | ||
222 | static const struct sr030pc30_frmsize sr030pc30_sizes[] = { | ||
223 | { | ||
224 | .width = 640, | ||
225 | .height = 480, | ||
226 | .vid_ctl1 = SUBSAMPL_NONE_VGA, | ||
227 | }, { | ||
228 | .width = 320, | ||
229 | .height = 240, | ||
230 | .vid_ctl1 = SUBSAMPL_QVGA, | ||
231 | }, { | ||
232 | .width = 160, | ||
233 | .height = 120, | ||
234 | .vid_ctl1 = SUBSAMPL_QQVGA, | ||
235 | }, | ||
236 | }; | ||
237 | |||
238 | /* supported pixel formats */ | ||
239 | static const struct sr030pc30_format sr030pc30_formats[] = { | ||
240 | { | ||
241 | .code = V4L2_MBUS_FMT_YUYV8_2X8, | ||
242 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
243 | .ispctl1_reg = 0x03, | ||
244 | }, { | ||
245 | .code = V4L2_MBUS_FMT_YVYU8_2X8, | ||
246 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
247 | .ispctl1_reg = 0x02, | ||
248 | }, { | ||
249 | .code = V4L2_MBUS_FMT_VYUY8_2X8, | ||
250 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
251 | .ispctl1_reg = 0, | ||
252 | }, { | ||
253 | .code = V4L2_MBUS_FMT_UYVY8_2X8, | ||
254 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
255 | .ispctl1_reg = 0x01, | ||
256 | }, { | ||
257 | .code = V4L2_MBUS_FMT_RGB565_2X8_BE, | ||
258 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
259 | .ispctl1_reg = 0x40, | ||
260 | }, | ||
261 | }; | ||
262 | |||
263 | static const struct i2c_regval sr030pc30_base_regs[] = { | ||
264 | /* Window size and position within pixel matrix */ | ||
265 | { WIN_ROWH_REG, 0x00 }, { WIN_ROWL_REG, 0x06 }, | ||
266 | { WIN_COLH_REG, 0x00 }, { WIN_COLL_REG, 0x06 }, | ||
267 | { WIN_HEIGHTH_REG, 0x01 }, { WIN_HEIGHTL_REG, 0xE0 }, | ||
268 | { WIN_WIDTHH_REG, 0x02 }, { WIN_WIDTHL_REG, 0x80 }, | ||
269 | { HBLANKH_REG, 0x01 }, { HBLANKL_REG, 0x50 }, | ||
270 | { VSYNCH_REG, 0x00 }, { VSYNCL_REG, 0x14 }, | ||
271 | { SYNC_CTL_REG, 0 }, | ||
272 | /* Color corection and saturation */ | ||
273 | { ISP_CTL_REG(0), 0x30 }, { YOFS_REG, 0x80 }, | ||
274 | { DARK_YOFS_REG, 0x04 }, { AG_ABRTH_REG, 0x78 }, | ||
275 | { SAT_CTL_REG, 0x1F }, { BSAT_REG, 0x90 }, | ||
276 | { AG_SAT_TH_REG, 0xF0 }, { 0x1064, 0x80 }, | ||
277 | { CMC_CTL_REG, 0x03 }, { CMC_OFSGH_REG, 0x3C }, | ||
278 | { CMC_OFSGL_REG, 0x2C }, { CMC_SIGN_REG, 0x2F }, | ||
279 | { CMC_COEF_REG(0), 0xCB }, { CMC_OFS_REG(0), 0x87 }, | ||
280 | { CMC_COEF_REG(1), 0x61 }, { CMC_OFS_REG(1), 0x18 }, | ||
281 | { CMC_COEF_REG(2), 0x16 }, { CMC_OFS_REG(2), 0x91 }, | ||
282 | { CMC_COEF_REG(3), 0x23 }, { CMC_OFS_REG(3), 0x94 }, | ||
283 | { CMC_COEF_REG(4), 0xCE }, { CMC_OFS_REG(4), 0x9f }, | ||
284 | { CMC_COEF_REG(5), 0x2B }, { CMC_OFS_REG(5), 0x33 }, | ||
285 | { CMC_COEF_REG(6), 0x01 }, { CMC_OFS_REG(6), 0x00 }, | ||
286 | { CMC_COEF_REG(7), 0x34 }, { CMC_OFS_REG(7), 0x94 }, | ||
287 | { CMC_COEF_REG(8), 0x75 }, { CMC_OFS_REG(8), 0x14 }, | ||
288 | /* Color corection coefficients */ | ||
289 | { GMA_CTL_REG, 0x03 }, { GMA_COEF_REG(0), 0x00 }, | ||
290 | { GMA_COEF_REG(1), 0x19 }, { GMA_COEF_REG(2), 0x26 }, | ||
291 | { GMA_COEF_REG(3), 0x3B }, { GMA_COEF_REG(4), 0x5D }, | ||
292 | { GMA_COEF_REG(5), 0x79 }, { GMA_COEF_REG(6), 0x8E }, | ||
293 | { GMA_COEF_REG(7), 0x9F }, { GMA_COEF_REG(8), 0xAF }, | ||
294 | { GMA_COEF_REG(9), 0xBD }, { GMA_COEF_REG(10), 0xCA }, | ||
295 | { GMA_COEF_REG(11), 0xDD }, { GMA_COEF_REG(12), 0xEC }, | ||
296 | { GMA_COEF_REG(13), 0xF7 }, { GMA_COEF_REG(14), 0xFF }, | ||
297 | /* Noise reduction, Z-LPF, YC-LPF and BLPF filters setup */ | ||
298 | { ZLPF_CTRL_REG, 0x99 }, { ZLPF_CTRL2_REG, 0x0E }, | ||
299 | { ZLPF_AGH_THR_REG, 0x29 }, { ZLPF_THR_REG, 0x0F }, | ||
300 | { ZLPF_DYN_THR_REG, 0x63 }, { YCLPF_CTL1_REG, 0x23 }, | ||
301 | { YCLPF_CTL2_REG, 0x3B }, { YCLPF_THR_REG, 0x05 }, | ||
302 | { BLPF_CTL_REG, 0x1D }, { BLPF_THR1_REG, 0x05 }, | ||
303 | { BLPF_THR2_REG, 0x04 }, | ||
304 | /* Automatic white balance */ | ||
305 | { AWB_CTL1_REG, 0xFB }, { AWB_CTL2_REG, 0x26 }, | ||
306 | { AWB_RMAX_REG, 0x54 }, { AWB_RMIN_REG, 0x2B }, | ||
307 | { AWB_BMAX_REG, 0x57 }, { AWB_BMIN_REG, 0x29 }, | ||
308 | { AWB_RMAXB_REG, 0x50 }, { AWB_RMINB_REG, 0x43 }, | ||
309 | { AWB_BMAXB_REG, 0x30 }, { AWB_BMINB_REG, 0x22 }, | ||
310 | /* Auto exposure */ | ||
311 | { AE_CTL1_REG, 0x8C }, { AE_CTL2_REG, 0x04 }, | ||
312 | { AE_FRM_CTL_REG, 0x01 }, { AE_FINE_CTL_REG(0), 0x3F }, | ||
313 | { AE_FINE_CTL_REG(1), 0xA3 }, { AE_FINE_CTL_REG(3), 0x34 }, | ||
314 | /* Lens shading compensation */ | ||
315 | { LENS_CTRL_REG, 0x01 }, { LENS_XCEN_REG, 0x80 }, | ||
316 | { LENS_YCEN_REG, 0x70 }, { LENS_R_COMP_REG, 0x53 }, | ||
317 | { LENS_G_COMP_REG, 0x40 }, { LENS_B_COMP_REG, 0x3e }, | ||
318 | { REG_TERM, 0 }, | ||
319 | }; | ||
320 | |||
321 | static inline struct sr030pc30_info *to_sr030pc30(struct v4l2_subdev *sd) | ||
322 | { | ||
323 | return container_of(sd, struct sr030pc30_info, sd); | ||
324 | } | ||
325 | |||
326 | static inline int set_i2c_page(struct sr030pc30_info *info, | ||
327 | struct i2c_client *client, unsigned int reg) | ||
328 | { | ||
329 | int ret = 0; | ||
330 | u32 page = reg >> 8 & 0xFF; | ||
331 | |||
332 | if (info->i2c_reg_page != page && (reg & 0xFF) != 0x03) { | ||
333 | ret = i2c_smbus_write_byte_data(client, PAGEMODE_REG, page); | ||
334 | if (!ret) | ||
335 | info->i2c_reg_page = page; | ||
336 | } | ||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | static int cam_i2c_read(struct v4l2_subdev *sd, u32 reg_addr) | ||
341 | { | ||
342 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
343 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
344 | |||
345 | int ret = set_i2c_page(info, client, reg_addr); | ||
346 | if (!ret) | ||
347 | ret = i2c_smbus_read_byte_data(client, reg_addr & 0xFF); | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static int cam_i2c_write(struct v4l2_subdev *sd, u32 reg_addr, u32 val) | ||
352 | { | ||
353 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
354 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
355 | |||
356 | int ret = set_i2c_page(info, client, reg_addr); | ||
357 | if (!ret) | ||
358 | ret = i2c_smbus_write_byte_data( | ||
359 | client, reg_addr & 0xFF, val); | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | static inline int sr030pc30_bulk_write_reg(struct v4l2_subdev *sd, | ||
364 | const struct i2c_regval *msg) | ||
365 | { | ||
366 | while (msg->addr != REG_TERM) { | ||
367 | int ret = cam_i2c_write(sd, msg->addr, msg->val); | ||
368 | if (ret) | ||
369 | return ret; | ||
370 | msg++; | ||
371 | } | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | /* Device reset and sleep mode control */ | ||
376 | static int sr030pc30_pwr_ctrl(struct v4l2_subdev *sd, | ||
377 | bool reset, bool sleep) | ||
378 | { | ||
379 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
380 | u8 reg = sleep ? 0xF1 : 0xF0; | ||
381 | int ret = 0; | ||
382 | |||
383 | if (reset) | ||
384 | ret = cam_i2c_write(sd, POWER_CTRL_REG, reg | 0x02); | ||
385 | if (!ret) { | ||
386 | ret = cam_i2c_write(sd, POWER_CTRL_REG, reg); | ||
387 | if (!ret) { | ||
388 | info->sleep = sleep; | ||
389 | if (reset) | ||
390 | info->i2c_reg_page = -1; | ||
391 | } | ||
392 | } | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static inline int sr030pc30_enable_autoexposure(struct v4l2_subdev *sd, int on) | ||
397 | { | ||
398 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
399 | /* auto anti-flicker is also enabled here */ | ||
400 | int ret = cam_i2c_write(sd, AE_CTL1_REG, on ? 0xDC : 0x0C); | ||
401 | if (!ret) | ||
402 | info->auto_exp = on; | ||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | static int sr030pc30_set_exposure(struct v4l2_subdev *sd, int value) | ||
407 | { | ||
408 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
409 | |||
410 | unsigned long expos = value * info->pdata->clk_rate / (8 * 1000); | ||
411 | |||
412 | int ret = cam_i2c_write(sd, EXP_TIMEH_REG, expos >> 16 & 0xFF); | ||
413 | if (!ret) | ||
414 | ret = cam_i2c_write(sd, EXP_TIMEM_REG, expos >> 8 & 0xFF); | ||
415 | if (!ret) | ||
416 | ret = cam_i2c_write(sd, EXP_TIMEL_REG, expos & 0xFF); | ||
417 | if (!ret) { /* Turn off AE */ | ||
418 | info->exposure = value; | ||
419 | ret = sr030pc30_enable_autoexposure(sd, 0); | ||
420 | } | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | /* Automatic white balance control */ | ||
425 | static int sr030pc30_enable_autowhitebalance(struct v4l2_subdev *sd, int on) | ||
426 | { | ||
427 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
428 | |||
429 | int ret = cam_i2c_write(sd, AWB_CTL2_REG, on ? 0x2E : 0x2F); | ||
430 | if (!ret) | ||
431 | ret = cam_i2c_write(sd, AWB_CTL1_REG, on ? 0xFB : 0x7B); | ||
432 | if (!ret) | ||
433 | info->auto_wb = on; | ||
434 | |||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static int sr030pc30_set_flip(struct v4l2_subdev *sd) | ||
439 | { | ||
440 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
441 | |||
442 | s32 reg = cam_i2c_read(sd, VDO_CTL2_REG); | ||
443 | if (reg < 0) | ||
444 | return reg; | ||
445 | |||
446 | reg &= 0x7C; | ||
447 | if (info->hflip) | ||
448 | reg |= 0x01; | ||
449 | if (info->vflip) | ||
450 | reg |= 0x02; | ||
451 | return cam_i2c_write(sd, VDO_CTL2_REG, reg | 0x80); | ||
452 | } | ||
453 | |||
454 | /* Configure resolution, color format and image flip */ | ||
455 | static int sr030pc30_set_params(struct v4l2_subdev *sd) | ||
456 | { | ||
457 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
458 | int ret; | ||
459 | |||
460 | if (!info->curr_win) | ||
461 | return -EINVAL; | ||
462 | |||
463 | /* Configure the resolution through subsampling */ | ||
464 | ret = cam_i2c_write(sd, VDO_CTL1_REG, | ||
465 | info->curr_win->vid_ctl1); | ||
466 | |||
467 | if (!ret && info->curr_fmt) | ||
468 | ret = cam_i2c_write(sd, ISP_CTL_REG(0), | ||
469 | info->curr_fmt->ispctl1_reg); | ||
470 | if (!ret) | ||
471 | ret = sr030pc30_set_flip(sd); | ||
472 | |||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | /* Find nearest matching image pixel size. */ | ||
477 | static int sr030pc30_try_frame_size(struct v4l2_mbus_framefmt *mf) | ||
478 | { | ||
479 | unsigned int min_err = ~0; | ||
480 | int i = ARRAY_SIZE(sr030pc30_sizes); | ||
481 | const struct sr030pc30_frmsize *fsize = &sr030pc30_sizes[0], | ||
482 | *match = NULL; | ||
483 | while (i--) { | ||
484 | int err = abs(fsize->width - mf->width) | ||
485 | + abs(fsize->height - mf->height); | ||
486 | if (err < min_err) { | ||
487 | min_err = err; | ||
488 | match = fsize; | ||
489 | } | ||
490 | fsize++; | ||
491 | } | ||
492 | if (match) { | ||
493 | mf->width = match->width; | ||
494 | mf->height = match->height; | ||
495 | return 0; | ||
496 | } | ||
497 | return -EINVAL; | ||
498 | } | ||
499 | |||
500 | static int sr030pc30_queryctrl(struct v4l2_subdev *sd, | ||
501 | struct v4l2_queryctrl *qc) | ||
502 | { | ||
503 | int i; | ||
504 | |||
505 | for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++) | ||
506 | if (qc->id == sr030pc30_ctrl[i].id) { | ||
507 | *qc = sr030pc30_ctrl[i]; | ||
508 | v4l2_dbg(1, debug, sd, "%s id: %d\n", | ||
509 | __func__, qc->id); | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | return -EINVAL; | ||
514 | } | ||
515 | |||
516 | static inline int sr030pc30_set_bluebalance(struct v4l2_subdev *sd, int value) | ||
517 | { | ||
518 | int ret = cam_i2c_write(sd, MWB_BGAIN_REG, value); | ||
519 | if (!ret) | ||
520 | to_sr030pc30(sd)->blue_balance = value; | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | static inline int sr030pc30_set_redbalance(struct v4l2_subdev *sd, int value) | ||
525 | { | ||
526 | int ret = cam_i2c_write(sd, MWB_RGAIN_REG, value); | ||
527 | if (!ret) | ||
528 | to_sr030pc30(sd)->red_balance = value; | ||
529 | return ret; | ||
530 | } | ||
531 | |||
532 | static int sr030pc30_s_ctrl(struct v4l2_subdev *sd, | ||
533 | struct v4l2_control *ctrl) | ||
534 | { | ||
535 | int i, ret = 0; | ||
536 | |||
537 | for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++) | ||
538 | if (ctrl->id == sr030pc30_ctrl[i].id) | ||
539 | break; | ||
540 | |||
541 | if (i == ARRAY_SIZE(sr030pc30_ctrl)) | ||
542 | return -EINVAL; | ||
543 | |||
544 | if (ctrl->value < sr030pc30_ctrl[i].minimum || | ||
545 | ctrl->value > sr030pc30_ctrl[i].maximum) | ||
546 | return -ERANGE; | ||
547 | |||
548 | v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n", | ||
549 | __func__, ctrl->id, ctrl->value); | ||
550 | |||
551 | switch (ctrl->id) { | ||
552 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
553 | sr030pc30_enable_autowhitebalance(sd, ctrl->value); | ||
554 | break; | ||
555 | case V4L2_CID_BLUE_BALANCE: | ||
556 | ret = sr030pc30_set_bluebalance(sd, ctrl->value); | ||
557 | break; | ||
558 | case V4L2_CID_RED_BALANCE: | ||
559 | ret = sr030pc30_set_redbalance(sd, ctrl->value); | ||
560 | break; | ||
561 | case V4L2_CID_EXPOSURE_AUTO: | ||
562 | sr030pc30_enable_autoexposure(sd, | ||
563 | ctrl->value == V4L2_EXPOSURE_AUTO); | ||
564 | break; | ||
565 | case V4L2_CID_EXPOSURE: | ||
566 | ret = sr030pc30_set_exposure(sd, ctrl->value); | ||
567 | break; | ||
568 | default: | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | |||
572 | return ret; | ||
573 | } | ||
574 | |||
575 | static int sr030pc30_g_ctrl(struct v4l2_subdev *sd, | ||
576 | struct v4l2_control *ctrl) | ||
577 | { | ||
578 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
579 | |||
580 | v4l2_dbg(1, debug, sd, "%s: id: %d\n", __func__, ctrl->id); | ||
581 | |||
582 | switch (ctrl->id) { | ||
583 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
584 | ctrl->value = info->auto_wb; | ||
585 | break; | ||
586 | case V4L2_CID_BLUE_BALANCE: | ||
587 | ctrl->value = info->blue_balance; | ||
588 | break; | ||
589 | case V4L2_CID_RED_BALANCE: | ||
590 | ctrl->value = info->red_balance; | ||
591 | break; | ||
592 | case V4L2_CID_EXPOSURE_AUTO: | ||
593 | ctrl->value = info->auto_exp; | ||
594 | break; | ||
595 | case V4L2_CID_EXPOSURE: | ||
596 | ctrl->value = info->exposure; | ||
597 | break; | ||
598 | default: | ||
599 | return -EINVAL; | ||
600 | } | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int sr030pc30_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | ||
605 | enum v4l2_mbus_pixelcode *code) | ||
606 | { | ||
607 | if (!code || index >= ARRAY_SIZE(sr030pc30_formats)) | ||
608 | return -EINVAL; | ||
609 | |||
610 | *code = sr030pc30_formats[index].code; | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int sr030pc30_g_fmt(struct v4l2_subdev *sd, | ||
615 | struct v4l2_mbus_framefmt *mf) | ||
616 | { | ||
617 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
618 | int ret; | ||
619 | |||
620 | if (!mf) | ||
621 | return -EINVAL; | ||
622 | |||
623 | if (!info->curr_win || !info->curr_fmt) { | ||
624 | ret = sr030pc30_set_params(sd); | ||
625 | if (ret) | ||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | mf->width = info->curr_win->width; | ||
630 | mf->height = info->curr_win->height; | ||
631 | mf->code = info->curr_fmt->code; | ||
632 | mf->colorspace = info->curr_fmt->colorspace; | ||
633 | mf->field = V4L2_FIELD_NONE; | ||
634 | |||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* Return nearest media bus frame format. */ | ||
639 | static const struct sr030pc30_format *try_fmt(struct v4l2_subdev *sd, | ||
640 | struct v4l2_mbus_framefmt *mf) | ||
641 | { | ||
642 | int i = ARRAY_SIZE(sr030pc30_formats); | ||
643 | |||
644 | sr030pc30_try_frame_size(mf); | ||
645 | |||
646 | while (i--) | ||
647 | if (mf->code == sr030pc30_formats[i].code) | ||
648 | break; | ||
649 | |||
650 | mf->code = sr030pc30_formats[i].code; | ||
651 | |||
652 | return &sr030pc30_formats[i]; | ||
653 | } | ||
654 | |||
655 | /* Return nearest media bus frame format. */ | ||
656 | static int sr030pc30_try_fmt(struct v4l2_subdev *sd, | ||
657 | struct v4l2_mbus_framefmt *mf) | ||
658 | { | ||
659 | if (!sd || !mf) | ||
660 | return -EINVAL; | ||
661 | |||
662 | try_fmt(sd, mf); | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static int sr030pc30_s_fmt(struct v4l2_subdev *sd, | ||
667 | struct v4l2_mbus_framefmt *mf) | ||
668 | { | ||
669 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
670 | |||
671 | if (!sd || !mf) | ||
672 | return -EINVAL; | ||
673 | |||
674 | info->curr_fmt = try_fmt(sd, mf); | ||
675 | |||
676 | return sr030pc30_set_params(sd); | ||
677 | } | ||
678 | |||
679 | static int sr030pc30_base_config(struct v4l2_subdev *sd) | ||
680 | { | ||
681 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
682 | int ret; | ||
683 | unsigned long expmin, expmax; | ||
684 | |||
685 | ret = sr030pc30_bulk_write_reg(sd, sr030pc30_base_regs); | ||
686 | if (!ret) { | ||
687 | info->curr_fmt = &sr030pc30_formats[0]; | ||
688 | info->curr_win = &sr030pc30_sizes[0]; | ||
689 | ret = sr030pc30_set_params(sd); | ||
690 | } | ||
691 | if (!ret) | ||
692 | ret = sr030pc30_pwr_ctrl(sd, false, false); | ||
693 | |||
694 | if (!ret && !info->pdata) | ||
695 | return ret; | ||
696 | |||
697 | expmin = EXPOS_MIN_MS * info->pdata->clk_rate / (8 * 1000); | ||
698 | expmax = EXPOS_MAX_MS * info->pdata->clk_rate / (8 * 1000); | ||
699 | |||
700 | v4l2_dbg(1, debug, sd, "%s: expmin= %lx, expmax= %lx", __func__, | ||
701 | expmin, expmax); | ||
702 | |||
703 | /* Setting up manual exposure time range */ | ||
704 | ret = cam_i2c_write(sd, EXP_MMINH_REG, expmin >> 8 & 0xFF); | ||
705 | if (!ret) | ||
706 | ret = cam_i2c_write(sd, EXP_MMINL_REG, expmin & 0xFF); | ||
707 | if (!ret) | ||
708 | ret = cam_i2c_write(sd, EXP_MMAXH_REG, expmax >> 16 & 0xFF); | ||
709 | if (!ret) | ||
710 | ret = cam_i2c_write(sd, EXP_MMAXM_REG, expmax >> 8 & 0xFF); | ||
711 | if (!ret) | ||
712 | ret = cam_i2c_write(sd, EXP_MMAXL_REG, expmax & 0xFF); | ||
713 | |||
714 | return ret; | ||
715 | } | ||
716 | |||
717 | static int sr030pc30_s_config(struct v4l2_subdev *sd, | ||
718 | int irq, void *platform_data) | ||
719 | { | ||
720 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
721 | |||
722 | info->pdata = platform_data; | ||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | static int sr030pc30_s_stream(struct v4l2_subdev *sd, int enable) | ||
727 | { | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static int sr030pc30_s_power(struct v4l2_subdev *sd, int on) | ||
732 | { | ||
733 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
734 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
735 | const struct sr030pc30_platform_data *pdata = info->pdata; | ||
736 | int ret; | ||
737 | |||
738 | if (WARN(pdata == NULL, "No platform data!")) | ||
739 | return -ENOMEM; | ||
740 | |||
741 | /* | ||
742 | * Put sensor into power sleep mode before switching off | ||
743 | * power and disabling MCLK. | ||
744 | */ | ||
745 | if (!on) | ||
746 | sr030pc30_pwr_ctrl(sd, false, true); | ||
747 | |||
748 | /* set_power controls sensor's power and clock */ | ||
749 | if (pdata->set_power) { | ||
750 | ret = pdata->set_power(&client->dev, on); | ||
751 | if (ret) | ||
752 | return ret; | ||
753 | } | ||
754 | |||
755 | if (on) { | ||
756 | ret = sr030pc30_base_config(sd); | ||
757 | } else { | ||
758 | info->curr_win = NULL; | ||
759 | info->curr_fmt = NULL; | ||
760 | } | ||
761 | |||
762 | return ret; | ||
763 | } | ||
764 | |||
765 | static const struct v4l2_subdev_core_ops sr030pc30_core_ops = { | ||
766 | .s_config = sr030pc30_s_config, | ||
767 | .s_power = sr030pc30_s_power, | ||
768 | .queryctrl = sr030pc30_queryctrl, | ||
769 | .s_ctrl = sr030pc30_s_ctrl, | ||
770 | .g_ctrl = sr030pc30_g_ctrl, | ||
771 | }; | ||
772 | |||
773 | static const struct v4l2_subdev_video_ops sr030pc30_video_ops = { | ||
774 | .s_stream = sr030pc30_s_stream, | ||
775 | .g_mbus_fmt = sr030pc30_g_fmt, | ||
776 | .s_mbus_fmt = sr030pc30_s_fmt, | ||
777 | .try_mbus_fmt = sr030pc30_try_fmt, | ||
778 | .enum_mbus_fmt = sr030pc30_enum_fmt, | ||
779 | }; | ||
780 | |||
781 | static const struct v4l2_subdev_ops sr030pc30_ops = { | ||
782 | .core = &sr030pc30_core_ops, | ||
783 | .video = &sr030pc30_video_ops, | ||
784 | }; | ||
785 | |||
786 | /* | ||
787 | * Detect sensor type. Return 0 if SR030PC30 was detected | ||
788 | * or -ENODEV otherwise. | ||
789 | */ | ||
790 | static int sr030pc30_detect(struct i2c_client *client) | ||
791 | { | ||
792 | const struct sr030pc30_platform_data *pdata | ||
793 | = client->dev.platform_data; | ||
794 | int ret; | ||
795 | |||
796 | /* Enable sensor's power and clock */ | ||
797 | if (pdata->set_power) { | ||
798 | ret = pdata->set_power(&client->dev, 1); | ||
799 | if (ret) | ||
800 | return ret; | ||
801 | } | ||
802 | |||
803 | ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG); | ||
804 | |||
805 | if (pdata->set_power) | ||
806 | pdata->set_power(&client->dev, 0); | ||
807 | |||
808 | if (ret < 0) { | ||
809 | dev_err(&client->dev, "%s: I2C read failed\n", __func__); | ||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | return ret == SR030PC30_ID ? 0 : -ENODEV; | ||
814 | } | ||
815 | |||
816 | |||
817 | static int sr030pc30_probe(struct i2c_client *client, | ||
818 | const struct i2c_device_id *id) | ||
819 | { | ||
820 | struct sr030pc30_info *info; | ||
821 | struct v4l2_subdev *sd; | ||
822 | const struct sr030pc30_platform_data *pdata | ||
823 | = client->dev.platform_data; | ||
824 | int ret; | ||
825 | |||
826 | if (!pdata) { | ||
827 | dev_err(&client->dev, "No platform data!"); | ||
828 | return -EIO; | ||
829 | } | ||
830 | |||
831 | ret = sr030pc30_detect(client); | ||
832 | if (ret) | ||
833 | return ret; | ||
834 | |||
835 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
836 | if (!info) | ||
837 | return -ENOMEM; | ||
838 | |||
839 | sd = &info->sd; | ||
840 | strcpy(sd->name, MODULE_NAME); | ||
841 | info->pdata = client->dev.platform_data; | ||
842 | |||
843 | v4l2_i2c_subdev_init(sd, client, &sr030pc30_ops); | ||
844 | |||
845 | info->i2c_reg_page = -1; | ||
846 | info->hflip = 1; | ||
847 | info->auto_exp = 1; | ||
848 | info->exposure = 30; | ||
849 | |||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | static int sr030pc30_remove(struct i2c_client *client) | ||
854 | { | ||
855 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
856 | struct sr030pc30_info *info = to_sr030pc30(sd); | ||
857 | |||
858 | v4l2_device_unregister_subdev(sd); | ||
859 | kfree(info); | ||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | static const struct i2c_device_id sr030pc30_id[] = { | ||
864 | { MODULE_NAME, 0 }, | ||
865 | { }, | ||
866 | }; | ||
867 | MODULE_DEVICE_TABLE(i2c, sr030pc30_id); | ||
868 | |||
869 | |||
870 | static struct i2c_driver sr030pc30_i2c_driver = { | ||
871 | .driver = { | ||
872 | .name = MODULE_NAME | ||
873 | }, | ||
874 | .probe = sr030pc30_probe, | ||
875 | .remove = sr030pc30_remove, | ||
876 | .id_table = sr030pc30_id, | ||
877 | }; | ||
878 | |||
879 | static int __init sr030pc30_init(void) | ||
880 | { | ||
881 | return i2c_add_driver(&sr030pc30_i2c_driver); | ||
882 | } | ||
883 | |||
884 | static void __exit sr030pc30_exit(void) | ||
885 | { | ||
886 | i2c_del_driver(&sr030pc30_i2c_driver); | ||
887 | } | ||
888 | |||
889 | module_init(sr030pc30_init); | ||
890 | module_exit(sr030pc30_exit); | ||
891 | |||
892 | MODULE_DESCRIPTION("Siliconfile SR030PC30 camera driver"); | ||
893 | MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); | ||
894 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 80f1cee23fa..3941f954daf 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <media/v4l2-device.h> | 36 | #include <media/v4l2-device.h> |
37 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
38 | #include <media/i2c-addr.h> | 38 | #include <media/i2c-addr.h> |
39 | #include <media/v4l2-i2c-drv.h> | ||
40 | 39 | ||
41 | #ifndef VIDEO_AUDIO_BALANCE | 40 | #ifndef VIDEO_AUDIO_BALANCE |
42 | # define VIDEO_AUDIO_BALANCE 32 | 41 | # define VIDEO_AUDIO_BALANCE 32 |
@@ -472,9 +471,25 @@ static const struct i2c_device_id tda7432_id[] = { | |||
472 | }; | 471 | }; |
473 | MODULE_DEVICE_TABLE(i2c, tda7432_id); | 472 | MODULE_DEVICE_TABLE(i2c, tda7432_id); |
474 | 473 | ||
475 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 474 | static struct i2c_driver tda7432_driver = { |
476 | .name = "tda7432", | 475 | .driver = { |
477 | .probe = tda7432_probe, | 476 | .owner = THIS_MODULE, |
478 | .remove = tda7432_remove, | 477 | .name = "tda7432", |
479 | .id_table = tda7432_id, | 478 | }, |
479 | .probe = tda7432_probe, | ||
480 | .remove = tda7432_remove, | ||
481 | .id_table = tda7432_id, | ||
480 | }; | 482 | }; |
483 | |||
484 | static __init int init_tda7432(void) | ||
485 | { | ||
486 | return i2c_add_driver(&tda7432_driver); | ||
487 | } | ||
488 | |||
489 | static __exit void exit_tda7432(void) | ||
490 | { | ||
491 | i2c_del_driver(&tda7432_driver); | ||
492 | } | ||
493 | |||
494 | module_init(init_tda7432); | ||
495 | module_exit(exit_tda7432); | ||
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 92d22d8931c..5d4cf3b3d43 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <media/v4l2-device.h> | 33 | #include <media/v4l2-device.h> |
34 | #include <media/v4l2-chip-ident.h> | 34 | #include <media/v4l2-chip-ident.h> |
35 | #include <media/v4l2-i2c-drv.h> | ||
36 | 35 | ||
37 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | 36 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
38 | MODULE_DESCRIPTION("tda9840 driver"); | 37 | MODULE_DESCRIPTION("tda9840 driver"); |
@@ -199,9 +198,25 @@ static const struct i2c_device_id tda9840_id[] = { | |||
199 | }; | 198 | }; |
200 | MODULE_DEVICE_TABLE(i2c, tda9840_id); | 199 | MODULE_DEVICE_TABLE(i2c, tda9840_id); |
201 | 200 | ||
202 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 201 | static struct i2c_driver tda9840_driver = { |
203 | .name = "tda9840", | 202 | .driver = { |
204 | .probe = tda9840_probe, | 203 | .owner = THIS_MODULE, |
205 | .remove = tda9840_remove, | 204 | .name = "tda9840", |
206 | .id_table = tda9840_id, | 205 | }, |
206 | .probe = tda9840_probe, | ||
207 | .remove = tda9840_remove, | ||
208 | .id_table = tda9840_id, | ||
207 | }; | 209 | }; |
210 | |||
211 | static __init int init_tda9840(void) | ||
212 | { | ||
213 | return i2c_add_driver(&tda9840_driver); | ||
214 | } | ||
215 | |||
216 | static __exit void exit_tda9840(void) | ||
217 | { | ||
218 | i2c_del_driver(&tda9840_driver); | ||
219 | } | ||
220 | |||
221 | module_init(init_tda9840); | ||
222 | module_exit(exit_tda9840); | ||
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 24e2b7d2ae5..35b6ff5db31 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
30 | #include <media/v4l2-device.h> | 30 | #include <media/v4l2-device.h> |
31 | #include <media/v4l2-i2c-drv.h> | ||
32 | #include <media/i2c-addr.h> | 31 | #include <media/i2c-addr.h> |
33 | 32 | ||
34 | static int debug; /* insmod parameter */ | 33 | static int debug; /* insmod parameter */ |
@@ -388,9 +387,25 @@ static const struct i2c_device_id tda9875_id[] = { | |||
388 | }; | 387 | }; |
389 | MODULE_DEVICE_TABLE(i2c, tda9875_id); | 388 | MODULE_DEVICE_TABLE(i2c, tda9875_id); |
390 | 389 | ||
391 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 390 | static struct i2c_driver tda9875_driver = { |
392 | .name = "tda9875", | 391 | .driver = { |
393 | .probe = tda9875_probe, | 392 | .owner = THIS_MODULE, |
394 | .remove = tda9875_remove, | 393 | .name = "tda9875", |
395 | .id_table = tda9875_id, | 394 | }, |
395 | .probe = tda9875_probe, | ||
396 | .remove = tda9875_remove, | ||
397 | .id_table = tda9875_id, | ||
396 | }; | 398 | }; |
399 | |||
400 | static __init int init_tda9875(void) | ||
401 | { | ||
402 | return i2c_add_driver(&tda9875_driver); | ||
403 | } | ||
404 | |||
405 | static __exit void exit_tda9875(void) | ||
406 | { | ||
407 | i2c_del_driver(&tda9875_driver); | ||
408 | } | ||
409 | |||
410 | module_init(init_tda9875); | ||
411 | module_exit(exit_tda9875); | ||
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 3021a1e6b7b..3e99cea8e4d 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 36 | #include <media/v4l2-chip-ident.h> |
37 | #include <media/v4l2-i2c-drv.h> | ||
38 | #include "tea6415c.h" | 37 | #include "tea6415c.h" |
39 | 38 | ||
40 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | 39 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
@@ -175,9 +174,25 @@ static const struct i2c_device_id tea6415c_id[] = { | |||
175 | }; | 174 | }; |
176 | MODULE_DEVICE_TABLE(i2c, tea6415c_id); | 175 | MODULE_DEVICE_TABLE(i2c, tea6415c_id); |
177 | 176 | ||
178 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 177 | static struct i2c_driver tea6415c_driver = { |
179 | .name = "tea6415c", | 178 | .driver = { |
180 | .probe = tea6415c_probe, | 179 | .owner = THIS_MODULE, |
181 | .remove = tea6415c_remove, | 180 | .name = "tea6415c", |
182 | .id_table = tea6415c_id, | 181 | }, |
182 | .probe = tea6415c_probe, | ||
183 | .remove = tea6415c_remove, | ||
184 | .id_table = tea6415c_id, | ||
183 | }; | 185 | }; |
186 | |||
187 | static __init int init_tea6415c(void) | ||
188 | { | ||
189 | return i2c_add_driver(&tea6415c_driver); | ||
190 | } | ||
191 | |||
192 | static __exit void exit_tea6415c(void) | ||
193 | { | ||
194 | i2c_del_driver(&tea6415c_driver); | ||
195 | } | ||
196 | |||
197 | module_init(init_tea6415c); | ||
198 | module_exit(exit_tea6415c); | ||
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 49dafc5e1e2..5ea840401f2 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 36 | #include <media/v4l2-chip-ident.h> |
37 | #include <media/v4l2-i2c-drv.h> | ||
38 | #include "tea6420.h" | 37 | #include "tea6420.h" |
39 | 38 | ||
40 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | 39 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
@@ -157,9 +156,25 @@ static const struct i2c_device_id tea6420_id[] = { | |||
157 | }; | 156 | }; |
158 | MODULE_DEVICE_TABLE(i2c, tea6420_id); | 157 | MODULE_DEVICE_TABLE(i2c, tea6420_id); |
159 | 158 | ||
160 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 159 | static struct i2c_driver tea6420_driver = { |
161 | .name = "tea6420", | 160 | .driver = { |
162 | .probe = tea6420_probe, | 161 | .owner = THIS_MODULE, |
163 | .remove = tea6420_remove, | 162 | .name = "tea6420", |
164 | .id_table = tea6420_id, | 163 | }, |
164 | .probe = tea6420_probe, | ||
165 | .remove = tea6420_remove, | ||
166 | .id_table = tea6420_id, | ||
165 | }; | 167 | }; |
168 | |||
169 | static __init int init_tea6420(void) | ||
170 | { | ||
171 | return i2c_add_driver(&tea6420_driver); | ||
172 | } | ||
173 | |||
174 | static __exit void exit_tea6420(void) | ||
175 | { | ||
176 | i2c_del_driver(&tea6420_driver); | ||
177 | } | ||
178 | |||
179 | module_init(init_tea6420); | ||
180 | module_exit(exit_tea6420); | ||
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c index d0cc012f7ae..a1ffe18640f 100644 --- a/drivers/media/video/tlg2300/pd-video.c +++ b/drivers/media/video/tlg2300/pd-video.c | |||
@@ -1434,7 +1434,7 @@ static int pd_video_open(struct file *file) | |||
1434 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1434 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1435 | V4L2_FIELD_INTERLACED,/* video is interlacd */ | 1435 | V4L2_FIELD_INTERLACED,/* video is interlacd */ |
1436 | sizeof(struct videobuf_buffer),/*it's enough*/ | 1436 | sizeof(struct videobuf_buffer),/*it's enough*/ |
1437 | front); | 1437 | front, NULL); |
1438 | } else if (vfd->vfl_type == VFL_TYPE_VBI | 1438 | } else if (vfd->vfl_type == VFL_TYPE_VBI |
1439 | && !(pd->state & POSEIDON_STATE_VBI)) { | 1439 | && !(pd->state & POSEIDON_STATE_VBI)) { |
1440 | front = kzalloc(sizeof(struct front_face), GFP_KERNEL); | 1440 | front = kzalloc(sizeof(struct front_face), GFP_KERNEL); |
@@ -1451,7 +1451,7 @@ static int pd_video_open(struct file *file) | |||
1451 | V4L2_BUF_TYPE_VBI_CAPTURE, | 1451 | V4L2_BUF_TYPE_VBI_CAPTURE, |
1452 | V4L2_FIELD_NONE, /* vbi is NONE mode */ | 1452 | V4L2_FIELD_NONE, /* vbi is NONE mode */ |
1453 | sizeof(struct videobuf_buffer), | 1453 | sizeof(struct videobuf_buffer), |
1454 | front); | 1454 | front, NULL); |
1455 | } else { | 1455 | } else { |
1456 | /* maybe add FM support here */ | 1456 | /* maybe add FM support here */ |
1457 | log("other "); | 1457 | log("other "); |
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c index 9ddb32bc7af..dfc4dd7c509 100644 --- a/drivers/media/video/tlv320aic23b.c +++ b/drivers/media/video/tlv320aic23b.c | |||
@@ -29,10 +29,8 @@ | |||
29 | #include <linux/ioctl.h> | 29 | #include <linux/ioctl.h> |
30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/i2c-id.h> | ||
33 | #include <linux/videodev2.h> | 32 | #include <linux/videodev2.h> |
34 | #include <media/v4l2-device.h> | 33 | #include <media/v4l2-device.h> |
35 | #include <media/v4l2-i2c-drv.h> | ||
36 | 34 | ||
37 | MODULE_DESCRIPTION("tlv320aic23b driver"); | 35 | MODULE_DESCRIPTION("tlv320aic23b driver"); |
38 | MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); | 36 | MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); |
@@ -199,9 +197,25 @@ static const struct i2c_device_id tlv320aic23b_id[] = { | |||
199 | }; | 197 | }; |
200 | MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id); | 198 | MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id); |
201 | 199 | ||
202 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 200 | static struct i2c_driver tlv320aic23b_driver = { |
203 | .name = "tlv320aic23b", | 201 | .driver = { |
204 | .probe = tlv320aic23b_probe, | 202 | .owner = THIS_MODULE, |
205 | .remove = tlv320aic23b_remove, | 203 | .name = "tlv320aic23b", |
206 | .id_table = tlv320aic23b_id, | 204 | }, |
205 | .probe = tlv320aic23b_probe, | ||
206 | .remove = tlv320aic23b_remove, | ||
207 | .id_table = tlv320aic23b_id, | ||
207 | }; | 208 | }; |
209 | |||
210 | static __init int init_tlv320aic23b(void) | ||
211 | { | ||
212 | return i2c_add_driver(&tlv320aic23b_driver); | ||
213 | } | ||
214 | |||
215 | static __exit void exit_tlv320aic23b(void) | ||
216 | { | ||
217 | i2c_del_driver(&tlv320aic23b_driver); | ||
218 | } | ||
219 | |||
220 | module_init(init_tlv320aic23b); | ||
221 | module_exit(exit_tlv320aic23b); | ||
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index c4dab6cfd94..1cec1224913 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <media/tuner-types.h> | 20 | #include <media/tuner-types.h> |
21 | #include <media/v4l2-device.h> | 21 | #include <media/v4l2-device.h> |
22 | #include <media/v4l2-ioctl.h> | 22 | #include <media/v4l2-ioctl.h> |
23 | #include <media/v4l2-i2c-drv.h> | ||
24 | #include "mt20xx.h" | 23 | #include "mt20xx.h" |
25 | #include "tda8290.h" | 24 | #include "tda8290.h" |
26 | #include "tea5761.h" | 25 | #include "tea5761.h" |
@@ -428,6 +427,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
428 | { | 427 | { |
429 | struct tda18271_config cfg = { | 428 | struct tda18271_config cfg = { |
430 | .config = t->config, | 429 | .config = t->config, |
430 | .small_i2c = TDA18271_03_BYTE_CHUNK_INIT, | ||
431 | }; | 431 | }; |
432 | 432 | ||
433 | if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr, | 433 | if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr, |
@@ -1053,12 +1053,6 @@ static int tuner_probe(struct i2c_client *client, | |||
1053 | printk(KERN_CONT "%02x ", buffer[i]); | 1053 | printk(KERN_CONT "%02x ", buffer[i]); |
1054 | printk("\n"); | 1054 | printk("\n"); |
1055 | } | 1055 | } |
1056 | /* HACK: This test was added to avoid tuner to probe tda9840 and | ||
1057 | tea6415c on the MXB card */ | ||
1058 | if (client->adapter->id == I2C_HW_SAA7146 && client->addr < 0x4a) { | ||
1059 | kfree(t); | ||
1060 | return -ENODEV; | ||
1061 | } | ||
1062 | 1056 | ||
1063 | /* autodetection code based on the i2c addr */ | 1057 | /* autodetection code based on the i2c addr */ |
1064 | if (!no_autodetect) { | 1058 | if (!no_autodetect) { |
@@ -1176,16 +1170,32 @@ static const struct i2c_device_id tuner_id[] = { | |||
1176 | }; | 1170 | }; |
1177 | MODULE_DEVICE_TABLE(i2c, tuner_id); | 1171 | MODULE_DEVICE_TABLE(i2c, tuner_id); |
1178 | 1172 | ||
1179 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 1173 | static struct i2c_driver tuner_driver = { |
1180 | .name = "tuner", | 1174 | .driver = { |
1181 | .probe = tuner_probe, | 1175 | .owner = THIS_MODULE, |
1182 | .remove = tuner_remove, | 1176 | .name = "tuner", |
1183 | .command = tuner_command, | 1177 | }, |
1184 | .suspend = tuner_suspend, | 1178 | .probe = tuner_probe, |
1185 | .resume = tuner_resume, | 1179 | .remove = tuner_remove, |
1186 | .id_table = tuner_id, | 1180 | .command = tuner_command, |
1181 | .suspend = tuner_suspend, | ||
1182 | .resume = tuner_resume, | ||
1183 | .id_table = tuner_id, | ||
1187 | }; | 1184 | }; |
1188 | 1185 | ||
1186 | static __init int init_tuner(void) | ||
1187 | { | ||
1188 | return i2c_add_driver(&tuner_driver); | ||
1189 | } | ||
1190 | |||
1191 | static __exit void exit_tuner(void) | ||
1192 | { | ||
1193 | i2c_del_driver(&tuner_driver); | ||
1194 | } | ||
1195 | |||
1196 | module_init(init_tuner); | ||
1197 | module_exit(exit_tuner); | ||
1198 | |||
1189 | /* | 1199 | /* |
1190 | * Overrides for Emacs so that we follow Linus's tabbing style. | 1200 | * Overrides for Emacs so that we follow Linus's tabbing style. |
1191 | * --------------------------------------------------------------------------- | 1201 | * --------------------------------------------------------------------------- |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 800fc1b111e..a25e2b5e194 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <media/tvaudio.h> | 35 | #include <media/tvaudio.h> |
36 | #include <media/v4l2-device.h> | 36 | #include <media/v4l2-device.h> |
37 | #include <media/v4l2-chip-ident.h> | 37 | #include <media/v4l2-chip-ident.h> |
38 | #include <media/v4l2-i2c-drv.h> | ||
39 | 38 | ||
40 | #include <media/i2c-addr.h> | 39 | #include <media/i2c-addr.h> |
41 | 40 | ||
@@ -1227,18 +1226,6 @@ static int tea6320_initialize(struct CHIPSTATE * chip) | |||
1227 | static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; } | 1226 | static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; } |
1228 | static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; } | 1227 | static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; } |
1229 | 1228 | ||
1230 | static int tda8425_initialize(struct CHIPSTATE *chip) | ||
1231 | { | ||
1232 | struct CHIPDESC *desc = chip->desc; | ||
1233 | struct i2c_client *c = v4l2_get_subdevdata(&chip->sd); | ||
1234 | int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, | ||
1235 | /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF}; | ||
1236 | |||
1237 | if (c->adapter->id == I2C_HW_B_RIVA) | ||
1238 | memcpy(desc->inputmap, inputmap, sizeof(inputmap)); | ||
1239 | return 0; | ||
1240 | } | ||
1241 | |||
1242 | static void tda8425_setmode(struct CHIPSTATE *chip, int mode) | 1229 | static void tda8425_setmode(struct CHIPSTATE *chip, int mode) |
1243 | { | 1230 | { |
1244 | int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1; | 1231 | int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1; |
@@ -1574,7 +1561,6 @@ static struct CHIPDESC chiplist[] = { | |||
1574 | .treblereg = TDA8425_TR, | 1561 | .treblereg = TDA8425_TR, |
1575 | 1562 | ||
1576 | /* callbacks */ | 1563 | /* callbacks */ |
1577 | .initialize = tda8425_initialize, | ||
1578 | .volfunc = tda8425_shift10, | 1564 | .volfunc = tda8425_shift10, |
1579 | .bassfunc = tda8425_shift12, | 1565 | .bassfunc = tda8425_shift12, |
1580 | .treblefunc = tda8425_shift12, | 1566 | .treblefunc = tda8425_shift12, |
@@ -2079,9 +2065,25 @@ static const struct i2c_device_id tvaudio_id[] = { | |||
2079 | }; | 2065 | }; |
2080 | MODULE_DEVICE_TABLE(i2c, tvaudio_id); | 2066 | MODULE_DEVICE_TABLE(i2c, tvaudio_id); |
2081 | 2067 | ||
2082 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 2068 | static struct i2c_driver tvaudio_driver = { |
2083 | .name = "tvaudio", | 2069 | .driver = { |
2084 | .probe = tvaudio_probe, | 2070 | .owner = THIS_MODULE, |
2085 | .remove = tvaudio_remove, | 2071 | .name = "tvaudio", |
2086 | .id_table = tvaudio_id, | 2072 | }, |
2073 | .probe = tvaudio_probe, | ||
2074 | .remove = tvaudio_remove, | ||
2075 | .id_table = tvaudio_id, | ||
2087 | }; | 2076 | }; |
2077 | |||
2078 | static __init int init_tvaudio(void) | ||
2079 | { | ||
2080 | return i2c_add_driver(&tvaudio_driver); | ||
2081 | } | ||
2082 | |||
2083 | static __exit void exit_tvaudio(void) | ||
2084 | { | ||
2085 | i2c_del_driver(&tvaudio_driver); | ||
2086 | } | ||
2087 | |||
2088 | module_init(init_tvaudio); | ||
2089 | module_exit(exit_tvaudio); | ||
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 71c73fa0d68..45bcf0358a1 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <media/v4l2-device.h> | 36 | #include <media/v4l2-device.h> |
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <media/v4l2-mediabus.h> | ||
38 | #include <media/v4l2-chip-ident.h> | 39 | #include <media/v4l2-chip-ident.h> |
39 | #include <media/tvp514x.h> | 40 | #include <media/tvp514x.h> |
40 | 41 | ||
@@ -929,69 +930,51 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
929 | } | 930 | } |
930 | 931 | ||
931 | /** | 932 | /** |
932 | * tvp514x_enum_fmt_cap() - V4L2 decoder interface handler for enum_fmt | 933 | * tvp514x_enum_mbus_fmt() - V4L2 decoder interface handler for enum_mbus_fmt |
933 | * @sd: pointer to standard V4L2 sub-device structure | 934 | * @sd: pointer to standard V4L2 sub-device structure |
934 | * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure | 935 | * @index: index of pixelcode to retrieve |
936 | * @code: receives the pixelcode | ||
935 | * | 937 | * |
936 | * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats | 938 | * Enumerates supported mediabus formats |
937 | */ | 939 | */ |
938 | static int | 940 | static int |
939 | tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) | 941 | tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, |
942 | enum v4l2_mbus_pixelcode *code) | ||
940 | { | 943 | { |
941 | if (fmt == NULL || fmt->index) | 944 | if (index) |
942 | return -EINVAL; | 945 | return -EINVAL; |
943 | 946 | ||
944 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 947 | *code = V4L2_MBUS_FMT_YUYV10_2X10; |
945 | /* only capture is supported */ | ||
946 | return -EINVAL; | ||
947 | |||
948 | /* only one format */ | ||
949 | fmt->flags = 0; | ||
950 | strlcpy(fmt->description, "8-bit UYVY 4:2:2 Format", | ||
951 | sizeof(fmt->description)); | ||
952 | fmt->pixelformat = V4L2_PIX_FMT_UYVY; | ||
953 | return 0; | 948 | return 0; |
954 | } | 949 | } |
955 | 950 | ||
956 | /** | 951 | /** |
957 | * tvp514x_fmt_cap() - V4L2 decoder interface handler for try/s/g_fmt | 952 | * tvp514x_mbus_fmt_cap() - V4L2 decoder interface handler for try/s/g_mbus_fmt |
958 | * @sd: pointer to standard V4L2 sub-device structure | 953 | * @sd: pointer to standard V4L2 sub-device structure |
959 | * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure | 954 | * @f: pointer to the mediabus format structure |
960 | * | 955 | * |
961 | * Implement the VIDIOC_TRY/S/G_FMT ioctl for the CAPTURE buffer type. This | 956 | * Negotiates the image capture size and mediabus format. |
962 | * ioctl is used to negotiate the image capture size and pixel format. | ||
963 | */ | 957 | */ |
964 | static int | 958 | static int |
965 | tvp514x_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) | 959 | tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) |
966 | { | 960 | { |
967 | struct tvp514x_decoder *decoder = to_decoder(sd); | 961 | struct tvp514x_decoder *decoder = to_decoder(sd); |
968 | struct v4l2_pix_format *pix; | ||
969 | enum tvp514x_std current_std; | 962 | enum tvp514x_std current_std; |
970 | 963 | ||
971 | if (f == NULL) | 964 | if (f == NULL) |
972 | return -EINVAL; | 965 | return -EINVAL; |
973 | 966 | ||
974 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
975 | return -EINVAL; | ||
976 | |||
977 | pix = &f->fmt.pix; | ||
978 | |||
979 | /* Calculate height and width based on current standard */ | 967 | /* Calculate height and width based on current standard */ |
980 | current_std = decoder->current_std; | 968 | current_std = decoder->current_std; |
981 | 969 | ||
982 | pix->pixelformat = V4L2_PIX_FMT_UYVY; | 970 | f->code = V4L2_MBUS_FMT_YUYV10_2X10; |
983 | pix->width = decoder->std_list[current_std].width; | 971 | f->width = decoder->std_list[current_std].width; |
984 | pix->height = decoder->std_list[current_std].height; | 972 | f->height = decoder->std_list[current_std].height; |
985 | pix->field = V4L2_FIELD_INTERLACED; | 973 | f->field = V4L2_FIELD_INTERLACED; |
986 | pix->bytesperline = pix->width * 2; | 974 | f->colorspace = V4L2_COLORSPACE_SMPTE170M; |
987 | pix->sizeimage = pix->bytesperline * pix->height; | 975 | |
988 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; | 976 | v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n", |
989 | pix->priv = 0; | 977 | f->width, f->height); |
990 | |||
991 | v4l2_dbg(1, debug, sd, "FMT: bytesperline - %d" | ||
992 | "Width - %d, Height - %d\n", | ||
993 | pix->bytesperline, | ||
994 | pix->width, pix->height); | ||
995 | return 0; | 978 | return 0; |
996 | } | 979 | } |
997 | 980 | ||
@@ -1131,10 +1114,10 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = { | |||
1131 | static const struct v4l2_subdev_video_ops tvp514x_video_ops = { | 1114 | static const struct v4l2_subdev_video_ops tvp514x_video_ops = { |
1132 | .s_routing = tvp514x_s_routing, | 1115 | .s_routing = tvp514x_s_routing, |
1133 | .querystd = tvp514x_querystd, | 1116 | .querystd = tvp514x_querystd, |
1134 | .enum_fmt = tvp514x_enum_fmt_cap, | 1117 | .enum_mbus_fmt = tvp514x_enum_mbus_fmt, |
1135 | .g_fmt = tvp514x_fmt_cap, | 1118 | .g_mbus_fmt = tvp514x_mbus_fmt, |
1136 | .try_fmt = tvp514x_fmt_cap, | 1119 | .try_mbus_fmt = tvp514x_mbus_fmt, |
1137 | .s_fmt = tvp514x_fmt_cap, | 1120 | .s_mbus_fmt = tvp514x_mbus_fmt, |
1138 | .g_parm = tvp514x_g_parm, | 1121 | .g_parm = tvp514x_g_parm, |
1139 | .s_parm = tvp514x_s_parm, | 1122 | .s_parm = tvp514x_s_parm, |
1140 | .s_stream = tvp514x_s_stream, | 1123 | .s_stream = tvp514x_s_stream, |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 1654f65cca7..58927664d3e 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <media/v4l2-device.h> | 12 | #include <media/v4l2-device.h> |
13 | #include <media/tvp5150.h> | 13 | #include <media/tvp5150.h> |
14 | #include <media/v4l2-i2c-drv.h> | ||
15 | #include <media/v4l2-chip-ident.h> | 14 | #include <media/v4l2-chip-ident.h> |
16 | 15 | ||
17 | #include "tvp5150_reg.h" | 16 | #include "tvp5150_reg.h" |
@@ -277,7 +276,7 @@ static int tvp5150_log_status(struct v4l2_subdev *sd) | |||
277 | 276 | ||
278 | static inline void tvp5150_selmux(struct v4l2_subdev *sd) | 277 | static inline void tvp5150_selmux(struct v4l2_subdev *sd) |
279 | { | 278 | { |
280 | int opmode=0; | 279 | int opmode = 0; |
281 | struct tvp5150 *decoder = to_tvp5150(sd); | 280 | struct tvp5150 *decoder = to_tvp5150(sd); |
282 | int input = 0; | 281 | int input = 0; |
283 | unsigned char val; | 282 | unsigned char val; |
@@ -290,12 +289,10 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd) | |||
290 | input |= 2; | 289 | input |= 2; |
291 | /* fall through */ | 290 | /* fall through */ |
292 | case TVP5150_COMPOSITE0: | 291 | case TVP5150_COMPOSITE0: |
293 | opmode=0x30; /* TV Mode */ | ||
294 | break; | 292 | break; |
295 | case TVP5150_SVIDEO: | 293 | case TVP5150_SVIDEO: |
296 | default: | 294 | default: |
297 | input |= 1; | 295 | input |= 1; |
298 | opmode=0; /* Auto Mode */ | ||
299 | break; | 296 | break; |
300 | } | 297 | } |
301 | 298 | ||
@@ -1111,9 +1108,25 @@ static const struct i2c_device_id tvp5150_id[] = { | |||
1111 | }; | 1108 | }; |
1112 | MODULE_DEVICE_TABLE(i2c, tvp5150_id); | 1109 | MODULE_DEVICE_TABLE(i2c, tvp5150_id); |
1113 | 1110 | ||
1114 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 1111 | static struct i2c_driver tvp5150_driver = { |
1115 | .name = "tvp5150", | 1112 | .driver = { |
1116 | .probe = tvp5150_probe, | 1113 | .owner = THIS_MODULE, |
1117 | .remove = tvp5150_remove, | 1114 | .name = "tvp5150", |
1118 | .id_table = tvp5150_id, | 1115 | }, |
1116 | .probe = tvp5150_probe, | ||
1117 | .remove = tvp5150_remove, | ||
1118 | .id_table = tvp5150_id, | ||
1119 | }; | 1119 | }; |
1120 | |||
1121 | static __init int init_tvp5150(void) | ||
1122 | { | ||
1123 | return i2c_add_driver(&tvp5150_driver); | ||
1124 | } | ||
1125 | |||
1126 | static __exit void exit_tvp5150(void) | ||
1127 | { | ||
1128 | i2c_del_driver(&tvp5150_driver); | ||
1129 | } | ||
1130 | |||
1131 | module_init(init_tvp5150); | ||
1132 | module_exit(exit_tvp5150); | ||
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c index 48f5c76ab52..e63b40f5a70 100644 --- a/drivers/media/video/tvp7002.c +++ b/drivers/media/video/tvp7002.c | |||
@@ -330,19 +330,6 @@ static const struct i2c_reg_value tvp7002_parms_720P50[] = { | |||
330 | { TVP7002_EOR, 0xff, TVP7002_RESERVED } | 330 | { TVP7002_EOR, 0xff, TVP7002_RESERVED } |
331 | }; | 331 | }; |
332 | 332 | ||
333 | /* Struct list for available formats */ | ||
334 | static const struct v4l2_fmtdesc tvp7002_fmt_list[] = { | ||
335 | { | ||
336 | .index = 0, | ||
337 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
338 | .flags = 0, | ||
339 | .description = "8-bit UYVY 4:2:2 Format", | ||
340 | .pixelformat = V4L2_PIX_FMT_UYVY, | ||
341 | }, | ||
342 | }; | ||
343 | |||
344 | #define NUM_FORMATS ARRAY_SIZE(tvp7002_fmt_list) | ||
345 | |||
346 | /* Preset definition for handling device operation */ | 333 | /* Preset definition for handling device operation */ |
347 | struct tvp7002_preset_definition { | 334 | struct tvp7002_preset_definition { |
348 | u32 preset; | 335 | u32 preset; |
@@ -439,7 +426,6 @@ struct tvp7002 { | |||
439 | int ver; | 426 | int ver; |
440 | int streaming; | 427 | int streaming; |
441 | 428 | ||
442 | struct v4l2_pix_format pix; | ||
443 | const struct tvp7002_preset_definition *current_preset; | 429 | const struct tvp7002_preset_definition *current_preset; |
444 | u8 gain; | 430 | u8 gain; |
445 | }; | 431 | }; |
@@ -695,81 +681,33 @@ static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | |||
695 | } | 681 | } |
696 | 682 | ||
697 | /* | 683 | /* |
698 | * tvp7002_try_fmt_cap() - V4L2 decoder interface handler for try_fmt | 684 | * tvp7002_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt |
699 | * @sd: pointer to standard V4L2 sub-device structure | 685 | * @sd: pointer to standard V4L2 sub-device structure |
700 | * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure | 686 | * @f: pointer to mediabus format structure |
701 | * | 687 | * |
702 | * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This | 688 | * Negotiate the image capture size and mediabus format. |
703 | * ioctl is used to negotiate the image capture size and pixel format | 689 | * There is only one possible format, so this single function works for |
704 | * without actually making it take effect. | 690 | * get, set and try. |
705 | */ | 691 | */ |
706 | static int tvp7002_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) | 692 | static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) |
707 | { | 693 | { |
708 | struct tvp7002 *device = to_tvp7002(sd); | 694 | struct tvp7002 *device = to_tvp7002(sd); |
709 | struct v4l2_dv_enum_preset e_preset; | 695 | struct v4l2_dv_enum_preset e_preset; |
710 | struct v4l2_pix_format *pix; | 696 | int error; |
711 | int error = 0; | ||
712 | |||
713 | pix = &f->fmt.pix; | ||
714 | 697 | ||
715 | /* Calculate height and width based on current standard */ | 698 | /* Calculate height and width based on current standard */ |
716 | error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset); | 699 | error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset); |
717 | if (error) | 700 | if (error) |
718 | return -EINVAL; | 701 | return error; |
719 | |||
720 | pix->width = e_preset.width; | ||
721 | pix->height = e_preset.height; | ||
722 | pix->pixelformat = V4L2_PIX_FMT_UYVY; | ||
723 | pix->field = device->current_preset->scanmode; | ||
724 | pix->bytesperline = pix->width * 2; | ||
725 | pix->sizeimage = pix->bytesperline * pix->height; | ||
726 | pix->colorspace = device->current_preset->color_space; | ||
727 | pix->priv = 0; | ||
728 | |||
729 | v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d" | ||
730 | "Width - %d, Height - %d", "8-bit UYVY 4:2:2 Format", | ||
731 | pix->bytesperline, pix->width, pix->height); | ||
732 | return error; | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * tvp7002_s_fmt() - V4L2 decoder interface handler for s_fmt | ||
737 | * @sd: pointer to standard V4L2 sub-device structure | ||
738 | * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure | ||
739 | * | ||
740 | * If the requested format is supported, configures the HW to use that | ||
741 | * format, returns error code if format not supported or HW can't be | ||
742 | * correctly configured. | ||
743 | */ | ||
744 | static int tvp7002_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | ||
745 | { | ||
746 | struct tvp7002 *decoder = to_tvp7002(sd); | ||
747 | int rval; | ||
748 | |||
749 | rval = tvp7002_try_fmt_cap(sd, f); | ||
750 | if (!rval) | ||
751 | decoder->pix = f->fmt.pix; | ||
752 | return rval; | ||
753 | } | ||
754 | |||
755 | /* | ||
756 | * tvp7002_g_fmt() - V4L2 decoder interface handler for tvp7002_g_fmt | ||
757 | * @sd: pointer to standard V4L2 sub-device structure | ||
758 | * @f: pointer to standard V4L2 v4l2_format structure | ||
759 | * | ||
760 | * Returns the decoder's current pixel format in the v4l2_format | ||
761 | * parameter. | ||
762 | */ | ||
763 | static int tvp7002_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | ||
764 | { | ||
765 | struct tvp7002 *decoder = to_tvp7002(sd); | ||
766 | 702 | ||
767 | f->fmt.pix = decoder->pix; | 703 | f->width = e_preset.width; |
704 | f->height = e_preset.height; | ||
705 | f->code = V4L2_MBUS_FMT_YUYV10_1X20; | ||
706 | f->field = device->current_preset->scanmode; | ||
707 | f->colorspace = device->current_preset->color_space; | ||
768 | 708 | ||
769 | v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d" | 709 | v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d", |
770 | "Width - %d, Height - %d", | 710 | f->width, f->height); |
771 | decoder->pix.bytesperline, | ||
772 | decoder->pix.width, decoder->pix.height); | ||
773 | return 0; | 711 | return 0; |
774 | } | 712 | } |
775 | 713 | ||
@@ -894,21 +832,21 @@ static int tvp7002_s_register(struct v4l2_subdev *sd, | |||
894 | #endif | 832 | #endif |
895 | 833 | ||
896 | /* | 834 | /* |
897 | * tvp7002_enum_fmt() - Enum supported formats | 835 | * tvp7002_enum_mbus_fmt() - Enum supported mediabus formats |
898 | * @sd: pointer to standard V4L2 sub-device structure | 836 | * @sd: pointer to standard V4L2 sub-device structure |
899 | * @fmtdesc: pointer to format struct | 837 | * @index: format index |
838 | * @code: pointer to mediabus format | ||
900 | * | 839 | * |
901 | * Enumerate supported formats. | 840 | * Enumerate supported mediabus formats. |
902 | */ | 841 | */ |
903 | 842 | ||
904 | static int tvp7002_enum_fmt(struct v4l2_subdev *sd, | 843 | static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, |
905 | struct v4l2_fmtdesc *fmtdesc) | 844 | enum v4l2_mbus_pixelcode *code) |
906 | { | 845 | { |
907 | /* Check requested format index is within range */ | 846 | /* Check requested format index is within range */ |
908 | if (fmtdesc->index < 0 || fmtdesc->index >= NUM_FORMATS) | 847 | if (index) |
909 | return -EINVAL; | 848 | return -EINVAL; |
910 | *fmtdesc = tvp7002_fmt_list[fmtdesc->index]; | 849 | *code = V4L2_MBUS_FMT_YUYV10_1X20; |
911 | |||
912 | return 0; | 850 | return 0; |
913 | } | 851 | } |
914 | 852 | ||
@@ -1027,9 +965,10 @@ static const struct v4l2_subdev_video_ops tvp7002_video_ops = { | |||
1027 | .s_dv_preset = tvp7002_s_dv_preset, | 965 | .s_dv_preset = tvp7002_s_dv_preset, |
1028 | .query_dv_preset = tvp7002_query_dv_preset, | 966 | .query_dv_preset = tvp7002_query_dv_preset, |
1029 | .s_stream = tvp7002_s_stream, | 967 | .s_stream = tvp7002_s_stream, |
1030 | .g_fmt = tvp7002_g_fmt, | 968 | .g_mbus_fmt = tvp7002_mbus_fmt, |
1031 | .s_fmt = tvp7002_s_fmt, | 969 | .try_mbus_fmt = tvp7002_mbus_fmt, |
1032 | .enum_fmt = tvp7002_enum_fmt, | 970 | .s_mbus_fmt = tvp7002_mbus_fmt, |
971 | .enum_mbus_fmt = tvp7002_enum_mbus_fmt, | ||
1033 | }; | 972 | }; |
1034 | 973 | ||
1035 | /* V4L2 top level operation handlers */ | 974 | /* V4L2 top level operation handlers */ |
@@ -1040,17 +979,6 @@ static const struct v4l2_subdev_ops tvp7002_ops = { | |||
1040 | 979 | ||
1041 | static struct tvp7002 tvp7002_dev = { | 980 | static struct tvp7002 tvp7002_dev = { |
1042 | .streaming = 0, | 981 | .streaming = 0, |
1043 | |||
1044 | .pix = { | ||
1045 | .width = 1280, | ||
1046 | .height = 720, | ||
1047 | .pixelformat = V4L2_PIX_FMT_UYVY, | ||
1048 | .field = V4L2_FIELD_NONE, | ||
1049 | .bytesperline = 1280 * 2, | ||
1050 | .sizeimage = 1280 * 2 * 720, | ||
1051 | .colorspace = V4L2_COLORSPACE_REC709, | ||
1052 | }, | ||
1053 | |||
1054 | .current_preset = tvp7002_presets, | 982 | .current_preset = tvp7002_presets, |
1055 | .gain = 0, | 983 | .gain = 0, |
1056 | }; | 984 | }; |
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index a727962781a..0347bbe3645 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c | |||
@@ -469,7 +469,7 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) | |||
469 | */ | 469 | */ |
470 | static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) | 470 | static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) |
471 | { | 471 | { |
472 | struct i2c_client *client = sd->priv; | 472 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
473 | struct tw9910_priv *priv = to_tw9910(client); | 473 | struct tw9910_priv *priv = to_tw9910(client); |
474 | u8 val; | 474 | u8 val; |
475 | int ret; | 475 | int ret; |
@@ -511,7 +511,7 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd, | |||
511 | unsigned long flags) | 511 | unsigned long flags) |
512 | { | 512 | { |
513 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 513 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
514 | struct i2c_client *client = sd->priv; | 514 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
515 | u8 val = VSSL_VVALID | HSSL_DVALID; | 515 | u8 val = VSSL_VVALID | HSSL_DVALID; |
516 | 516 | ||
517 | /* | 517 | /* |
@@ -565,7 +565,7 @@ static int tw9910_enum_input(struct soc_camera_device *icd, | |||
565 | static int tw9910_g_chip_ident(struct v4l2_subdev *sd, | 565 | static int tw9910_g_chip_ident(struct v4l2_subdev *sd, |
566 | struct v4l2_dbg_chip_ident *id) | 566 | struct v4l2_dbg_chip_ident *id) |
567 | { | 567 | { |
568 | struct i2c_client *client = sd->priv; | 568 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
569 | struct tw9910_priv *priv = to_tw9910(client); | 569 | struct tw9910_priv *priv = to_tw9910(client); |
570 | 570 | ||
571 | id->ident = V4L2_IDENT_TW9910; | 571 | id->ident = V4L2_IDENT_TW9910; |
@@ -578,7 +578,7 @@ static int tw9910_g_chip_ident(struct v4l2_subdev *sd, | |||
578 | static int tw9910_g_register(struct v4l2_subdev *sd, | 578 | static int tw9910_g_register(struct v4l2_subdev *sd, |
579 | struct v4l2_dbg_register *reg) | 579 | struct v4l2_dbg_register *reg) |
580 | { | 580 | { |
581 | struct i2c_client *client = sd->priv; | 581 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
582 | int ret; | 582 | int ret; |
583 | 583 | ||
584 | if (reg->reg > 0xff) | 584 | if (reg->reg > 0xff) |
@@ -600,7 +600,7 @@ static int tw9910_g_register(struct v4l2_subdev *sd, | |||
600 | static int tw9910_s_register(struct v4l2_subdev *sd, | 600 | static int tw9910_s_register(struct v4l2_subdev *sd, |
601 | struct v4l2_dbg_register *reg) | 601 | struct v4l2_dbg_register *reg) |
602 | { | 602 | { |
603 | struct i2c_client *client = sd->priv; | 603 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
604 | 604 | ||
605 | if (reg->reg > 0xff || | 605 | if (reg->reg > 0xff || |
606 | reg->val > 0xff) | 606 | reg->val > 0xff) |
@@ -613,7 +613,7 @@ static int tw9910_s_register(struct v4l2_subdev *sd, | |||
613 | static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 613 | static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
614 | { | 614 | { |
615 | struct v4l2_rect *rect = &a->c; | 615 | struct v4l2_rect *rect = &a->c; |
616 | struct i2c_client *client = sd->priv; | 616 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
617 | struct tw9910_priv *priv = to_tw9910(client); | 617 | struct tw9910_priv *priv = to_tw9910(client); |
618 | struct soc_camera_device *icd = client->dev.platform_data; | 618 | struct soc_camera_device *icd = client->dev.platform_data; |
619 | int ret = -EINVAL; | 619 | int ret = -EINVAL; |
@@ -701,7 +701,7 @@ tw9910_set_fmt_error: | |||
701 | 701 | ||
702 | static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 702 | static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
703 | { | 703 | { |
704 | struct i2c_client *client = sd->priv; | 704 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
705 | struct tw9910_priv *priv = to_tw9910(client); | 705 | struct tw9910_priv *priv = to_tw9910(client); |
706 | 706 | ||
707 | if (!priv->scale) { | 707 | if (!priv->scale) { |
@@ -748,7 +748,7 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
748 | static int tw9910_g_fmt(struct v4l2_subdev *sd, | 748 | static int tw9910_g_fmt(struct v4l2_subdev *sd, |
749 | struct v4l2_mbus_framefmt *mf) | 749 | struct v4l2_mbus_framefmt *mf) |
750 | { | 750 | { |
751 | struct i2c_client *client = sd->priv; | 751 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
752 | struct tw9910_priv *priv = to_tw9910(client); | 752 | struct tw9910_priv *priv = to_tw9910(client); |
753 | 753 | ||
754 | if (!priv->scale) { | 754 | if (!priv->scale) { |
@@ -778,7 +778,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd, | |||
778 | static int tw9910_s_fmt(struct v4l2_subdev *sd, | 778 | static int tw9910_s_fmt(struct v4l2_subdev *sd, |
779 | struct v4l2_mbus_framefmt *mf) | 779 | struct v4l2_mbus_framefmt *mf) |
780 | { | 780 | { |
781 | struct i2c_client *client = sd->priv; | 781 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
782 | struct tw9910_priv *priv = to_tw9910(client); | 782 | struct tw9910_priv *priv = to_tw9910(client); |
783 | /* See tw9910_s_crop() - no proper cropping support */ | 783 | /* See tw9910_s_crop() - no proper cropping support */ |
784 | struct v4l2_crop a = { | 784 | struct v4l2_crop a = { |
@@ -813,7 +813,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, | |||
813 | static int tw9910_try_fmt(struct v4l2_subdev *sd, | 813 | static int tw9910_try_fmt(struct v4l2_subdev *sd, |
814 | struct v4l2_mbus_framefmt *mf) | 814 | struct v4l2_mbus_framefmt *mf) |
815 | { | 815 | { |
816 | struct i2c_client *client = sd->priv; | 816 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
817 | struct soc_camera_device *icd = client->dev.platform_data; | 817 | struct soc_camera_device *icd = client->dev.platform_data; |
818 | const struct tw9910_scale_ctrl *scale; | 818 | const struct tw9910_scale_ctrl *scale; |
819 | 819 | ||
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index 36c0c461d8b..f8138c75be8 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <media/v4l2-device.h> | 29 | #include <media/v4l2-device.h> |
30 | #include <media/v4l2-chip-ident.h> | 30 | #include <media/v4l2-chip-ident.h> |
31 | #include <media/v4l2-i2c-drv.h> | ||
32 | #include <media/upd64031a.h> | 31 | #include <media/upd64031a.h> |
33 | 32 | ||
34 | /* --------------------- read registers functions define -------------------- */ | 33 | /* --------------------- read registers functions define -------------------- */ |
@@ -262,9 +261,25 @@ static const struct i2c_device_id upd64031a_id[] = { | |||
262 | }; | 261 | }; |
263 | MODULE_DEVICE_TABLE(i2c, upd64031a_id); | 262 | MODULE_DEVICE_TABLE(i2c, upd64031a_id); |
264 | 263 | ||
265 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 264 | static struct i2c_driver upd64031a_driver = { |
266 | .name = "upd64031a", | 265 | .driver = { |
267 | .probe = upd64031a_probe, | 266 | .owner = THIS_MODULE, |
268 | .remove = upd64031a_remove, | 267 | .name = "upd64031a", |
269 | .id_table = upd64031a_id, | 268 | }, |
269 | .probe = upd64031a_probe, | ||
270 | .remove = upd64031a_remove, | ||
271 | .id_table = upd64031a_id, | ||
270 | }; | 272 | }; |
273 | |||
274 | static __init int init_upd64031a(void) | ||
275 | { | ||
276 | return i2c_add_driver(&upd64031a_driver); | ||
277 | } | ||
278 | |||
279 | static __exit void exit_upd64031a(void) | ||
280 | { | ||
281 | i2c_del_driver(&upd64031a_driver); | ||
282 | } | ||
283 | |||
284 | module_init(init_upd64031a); | ||
285 | module_exit(exit_upd64031a); | ||
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index c5af93b30a2..28e0e6b6ca8 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <media/v4l2-device.h> | 29 | #include <media/v4l2-device.h> |
30 | #include <media/v4l2-chip-ident.h> | 30 | #include <media/v4l2-chip-ident.h> |
31 | #include <media/v4l2-i2c-drv.h> | ||
32 | #include <media/upd64083.h> | 31 | #include <media/upd64083.h> |
33 | 32 | ||
34 | MODULE_DESCRIPTION("uPD64083 driver"); | 33 | MODULE_DESCRIPTION("uPD64083 driver"); |
@@ -234,9 +233,25 @@ static const struct i2c_device_id upd64083_id[] = { | |||
234 | }; | 233 | }; |
235 | MODULE_DEVICE_TABLE(i2c, upd64083_id); | 234 | MODULE_DEVICE_TABLE(i2c, upd64083_id); |
236 | 235 | ||
237 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 236 | static struct i2c_driver upd64083_driver = { |
238 | .name = "upd64083", | 237 | .driver = { |
239 | .probe = upd64083_probe, | 238 | .owner = THIS_MODULE, |
240 | .remove = upd64083_remove, | 239 | .name = "upd64083", |
241 | .id_table = upd64083_id, | 240 | }, |
241 | .probe = upd64083_probe, | ||
242 | .remove = upd64083_remove, | ||
243 | .id_table = upd64083_id, | ||
242 | }; | 244 | }; |
245 | |||
246 | static __init int init_upd64083(void) | ||
247 | { | ||
248 | return i2c_add_driver(&upd64083_driver); | ||
249 | } | ||
250 | |||
251 | static __exit void exit_upd64083(void) | ||
252 | { | ||
253 | i2c_del_driver(&upd64083_driver); | ||
254 | } | ||
255 | |||
256 | module_init(init_upd64083); | ||
257 | module_exit(exit_upd64083); | ||
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig index d6e16959f78..dfa7fc68a65 100644 --- a/drivers/media/video/usbvideo/Kconfig +++ b/drivers/media/video/usbvideo/Kconfig | |||
@@ -12,10 +12,13 @@ config USB_VICAM | |||
12 | module will be called vicam. | 12 | module will be called vicam. |
13 | 13 | ||
14 | config USB_IBMCAM | 14 | config USB_IBMCAM |
15 | tristate "USB IBM (Xirlink) C-it Camera support" | 15 | tristate "USB IBM (Xirlink) C-it Camera support (DEPRECATED)" |
16 | depends on VIDEO_V4L1 | 16 | depends on VIDEO_V4L1 |
17 | select VIDEO_USBVIDEO | 17 | select VIDEO_USBVIDEO |
18 | ---help--- | 18 | ---help--- |
19 | This driver is DEPRECATED please use the gspca xirlink_cit module | ||
20 | instead. | ||
21 | |||
19 | Say Y here if you want to connect a IBM "C-It" camera, also known as | 22 | Say Y here if you want to connect a IBM "C-It" camera, also known as |
20 | "Xirlink PC Camera" to your computer's USB port. | 23 | "Xirlink PC Camera" to your computer's USB port. |
21 | 24 | ||
@@ -27,10 +30,13 @@ config USB_IBMCAM | |||
27 | <file:Documentation/video4linux/ibmcam.txt> to learn more. | 30 | <file:Documentation/video4linux/ibmcam.txt> to learn more. |
28 | 31 | ||
29 | config USB_KONICAWC | 32 | config USB_KONICAWC |
30 | tristate "USB Konica Webcam support" | 33 | tristate "USB Konica Webcam support (DEPRECATED)" |
31 | depends on VIDEO_V4L1 | 34 | depends on VIDEO_V4L1 |
32 | select VIDEO_USBVIDEO | 35 | select VIDEO_USBVIDEO |
33 | ---help--- | 36 | ---help--- |
37 | This driver is DEPRECATED (and known to crash) please use the | ||
38 | gspca konica module instead. | ||
39 | |||
34 | Say Y here if you want support for webcams based on a Konica | 40 | Say Y here if you want support for webcams based on a Konica |
35 | chipset. This is known to work with the Intel YC76 webcam. | 41 | chipset. This is known to work with the Intel YC76 webcam. |
36 | 42 | ||
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index 42ba2878575..e3bbae26e3c 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c | |||
@@ -211,6 +211,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
211 | 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ | 211 | 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ |
212 | I2C_CLIENT_END }; | 212 | I2C_CLIENT_END }; |
213 | 213 | ||
214 | if (usbvision->registered_i2c) | ||
215 | return 0; | ||
216 | |||
214 | memcpy(&usbvision->i2c_adap, &i2c_adap_template, | 217 | memcpy(&usbvision->i2c_adap, &i2c_adap_template, |
215 | sizeof(struct i2c_adapter)); | 218 | sizeof(struct i2c_adapter)); |
216 | 219 | ||
@@ -248,7 +251,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
248 | hit-and-miss. */ | 251 | hit-and-miss. */ |
249 | mdelay(10); | 252 | mdelay(10); |
250 | v4l2_i2c_new_subdev(&usbvision->v4l2_dev, | 253 | v4l2_i2c_new_subdev(&usbvision->v4l2_dev, |
251 | &usbvision->i2c_adap, "saa7115", | 254 | &usbvision->i2c_adap, NULL, |
252 | "saa7115_auto", 0, saa711x_addrs); | 255 | "saa7115_auto", 0, saa711x_addrs); |
253 | break; | 256 | break; |
254 | } | 257 | } |
@@ -258,16 +261,18 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
258 | struct tuner_setup tun_setup; | 261 | struct tuner_setup tun_setup; |
259 | 262 | ||
260 | sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, | 263 | sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, |
261 | &usbvision->i2c_adap, "tuner", | 264 | &usbvision->i2c_adap, NULL, |
262 | "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | 265 | "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); |
263 | /* depending on whether we found a demod or not, select | 266 | /* depending on whether we found a demod or not, select |
264 | the tuner type. */ | 267 | the tuner type. */ |
265 | type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; | 268 | type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; |
266 | 269 | ||
267 | sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, | 270 | sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, |
268 | &usbvision->i2c_adap, "tuner", | 271 | &usbvision->i2c_adap, NULL, |
269 | "tuner", 0, v4l2_i2c_tuner_addrs(type)); | 272 | "tuner", 0, v4l2_i2c_tuner_addrs(type)); |
270 | 273 | ||
274 | if (sd == NULL) | ||
275 | return -ENODEV; | ||
271 | if (usbvision->tuner_type != -1) { | 276 | if (usbvision->tuner_type != -1) { |
272 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | 277 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; |
273 | tun_setup.type = usbvision->tuner_type; | 278 | tun_setup.type = usbvision->tuner_type; |
@@ -275,14 +280,18 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
275 | call_all(usbvision, tuner, s_type_addr, &tun_setup); | 280 | call_all(usbvision, tuner, s_type_addr, &tun_setup); |
276 | } | 281 | } |
277 | } | 282 | } |
283 | usbvision->registered_i2c = 1; | ||
278 | 284 | ||
279 | return 0; | 285 | return 0; |
280 | } | 286 | } |
281 | 287 | ||
282 | int usbvision_i2c_unregister(struct usb_usbvision *usbvision) | 288 | int usbvision_i2c_unregister(struct usb_usbvision *usbvision) |
283 | { | 289 | { |
290 | if (!usbvision->registered_i2c) | ||
291 | return 0; | ||
284 | 292 | ||
285 | i2c_del_adapter(&(usbvision->i2c_adap)); | 293 | i2c_del_adapter(&(usbvision->i2c_adap)); |
294 | usbvision->registered_i2c = 0; | ||
286 | 295 | ||
287 | PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name); | 296 | PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name); |
288 | 297 | ||
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index c2690df3343..db6b828594f 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -357,7 +357,7 @@ static int usbvision_v4l2_open(struct file *file) | |||
357 | 357 | ||
358 | PDEBUG(DBG_IO, "open"); | 358 | PDEBUG(DBG_IO, "open"); |
359 | 359 | ||
360 | lock_kernel(); | 360 | mutex_lock(&usbvision->lock); |
361 | usbvision_reset_powerOffTimer(usbvision); | 361 | usbvision_reset_powerOffTimer(usbvision); |
362 | 362 | ||
363 | if (usbvision->user) | 363 | if (usbvision->user) |
@@ -379,7 +379,6 @@ static int usbvision_v4l2_open(struct file *file) | |||
379 | 379 | ||
380 | /* If so far no errors then we shall start the camera */ | 380 | /* If so far no errors then we shall start the camera */ |
381 | if (!errCode) { | 381 | if (!errCode) { |
382 | mutex_lock(&usbvision->lock); | ||
383 | if (usbvision->power == 0) { | 382 | if (usbvision->power == 0) { |
384 | usbvision_power_on(usbvision); | 383 | usbvision_power_on(usbvision); |
385 | usbvision_i2c_register(usbvision); | 384 | usbvision_i2c_register(usbvision); |
@@ -408,14 +407,13 @@ static int usbvision_v4l2_open(struct file *file) | |||
408 | usbvision->initialized = 0; | 407 | usbvision->initialized = 0; |
409 | } | 408 | } |
410 | } | 409 | } |
411 | mutex_unlock(&usbvision->lock); | ||
412 | } | 410 | } |
413 | 411 | ||
414 | /* prepare queues */ | 412 | /* prepare queues */ |
415 | usbvision_empty_framequeues(usbvision); | 413 | usbvision_empty_framequeues(usbvision); |
416 | 414 | ||
417 | PDEBUG(DBG_IO, "success"); | 415 | PDEBUG(DBG_IO, "success"); |
418 | unlock_kernel(); | 416 | mutex_unlock(&usbvision->lock); |
419 | return errCode; | 417 | return errCode; |
420 | } | 418 | } |
421 | 419 | ||
@@ -1645,8 +1643,8 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1645 | usbvision->usb_bandwidth = 0; | 1643 | usbvision->usb_bandwidth = 0; |
1646 | usbvision->user = 0; | 1644 | usbvision->user = 0; |
1647 | usbvision->streaming = Stream_Off; | 1645 | usbvision->streaming = Stream_Off; |
1648 | usbvision_register_video(usbvision); | ||
1649 | usbvision_configure_video(usbvision); | 1646 | usbvision_configure_video(usbvision); |
1647 | usbvision_register_video(usbvision); | ||
1650 | mutex_unlock(&usbvision->lock); | 1648 | mutex_unlock(&usbvision->lock); |
1651 | 1649 | ||
1652 | usbvision_create_sysfs(usbvision->vdev); | 1650 | usbvision_create_sysfs(usbvision->vdev); |
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index d1b3cc0cd87..cc4e96c8cd6 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h | |||
@@ -363,6 +363,7 @@ struct usb_usbvision { | |||
363 | 363 | ||
364 | /* i2c Declaration Section*/ | 364 | /* i2c Declaration Section*/ |
365 | struct i2c_adapter i2c_adap; | 365 | struct i2c_adapter i2c_adap; |
366 | int registered_i2c; | ||
366 | 367 | ||
367 | struct urb *ctrlUrb; | 368 | struct urb *ctrlUrb; |
368 | unsigned char ctrlUrbBuffer[8]; | 369 | unsigned char ctrlUrbBuffer[8]; |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index a350fad0db4..f169f773667 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * uvc_ctrl.c -- USB Video Class driver - Controls | 2 | * uvc_ctrl.c -- USB Video Class driver - Controls |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2009 | 4 | * Copyright (C) 2005-2010 |
5 | * Laurent Pinchart (laurent.pinchart@skynet.be) | 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License as published by |
@@ -643,7 +643,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { | |||
643 | 643 | ||
644 | static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) | 644 | static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) |
645 | { | 645 | { |
646 | return ctrl->uvc_data + id * ctrl->info->size; | 646 | return ctrl->uvc_data + id * ctrl->info.size; |
647 | } | 647 | } |
648 | 648 | ||
649 | static inline int uvc_test_bit(const __u8 *data, int bit) | 649 | static inline int uvc_test_bit(const __u8 *data, int bit) |
@@ -727,7 +727,8 @@ static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; | |||
727 | static const __u8 uvc_media_transport_input_guid[16] = | 727 | static const __u8 uvc_media_transport_input_guid[16] = |
728 | UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; | 728 | UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; |
729 | 729 | ||
730 | static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16]) | 730 | static int uvc_entity_match_guid(const struct uvc_entity *entity, |
731 | const __u8 guid[16]) | ||
731 | { | 732 | { |
732 | switch (UVC_ENTITY_TYPE(entity)) { | 733 | switch (UVC_ENTITY_TYPE(entity)) { |
733 | case UVC_ITT_CAMERA: | 734 | case UVC_ITT_CAMERA: |
@@ -765,10 +766,10 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
765 | 766 | ||
766 | for (i = 0; i < entity->ncontrols; ++i) { | 767 | for (i = 0; i < entity->ncontrols; ++i) { |
767 | ctrl = &entity->controls[i]; | 768 | ctrl = &entity->controls[i]; |
768 | if (ctrl->info == NULL) | 769 | if (!ctrl->initialized) |
769 | continue; | 770 | continue; |
770 | 771 | ||
771 | list_for_each_entry(map, &ctrl->info->mappings, list) { | 772 | list_for_each_entry(map, &ctrl->info.mappings, list) { |
772 | if ((map->id == v4l2_id) && !next) { | 773 | if ((map->id == v4l2_id) && !next) { |
773 | *control = ctrl; | 774 | *control = ctrl; |
774 | *mapping = map; | 775 | *mapping = map; |
@@ -815,36 +816,36 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, | |||
815 | { | 816 | { |
816 | int ret; | 817 | int ret; |
817 | 818 | ||
818 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 819 | if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { |
819 | ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, | 820 | ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, |
820 | chain->dev->intfnum, ctrl->info->selector, | 821 | chain->dev->intfnum, ctrl->info.selector, |
821 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), | 822 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), |
822 | ctrl->info->size); | 823 | ctrl->info.size); |
823 | if (ret < 0) | 824 | if (ret < 0) |
824 | return ret; | 825 | return ret; |
825 | } | 826 | } |
826 | 827 | ||
827 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { | 828 | if (ctrl->info.flags & UVC_CONTROL_GET_MIN) { |
828 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, | 829 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, |
829 | chain->dev->intfnum, ctrl->info->selector, | 830 | chain->dev->intfnum, ctrl->info.selector, |
830 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), | 831 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), |
831 | ctrl->info->size); | 832 | ctrl->info.size); |
832 | if (ret < 0) | 833 | if (ret < 0) |
833 | return ret; | 834 | return ret; |
834 | } | 835 | } |
835 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { | 836 | if (ctrl->info.flags & UVC_CONTROL_GET_MAX) { |
836 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, | 837 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, |
837 | chain->dev->intfnum, ctrl->info->selector, | 838 | chain->dev->intfnum, ctrl->info.selector, |
838 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), | 839 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), |
839 | ctrl->info->size); | 840 | ctrl->info.size); |
840 | if (ret < 0) | 841 | if (ret < 0) |
841 | return ret; | 842 | return ret; |
842 | } | 843 | } |
843 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { | 844 | if (ctrl->info.flags & UVC_CONTROL_GET_RES) { |
844 | ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, | 845 | ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, |
845 | chain->dev->intfnum, ctrl->info->selector, | 846 | chain->dev->intfnum, ctrl->info.selector, |
846 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), | 847 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), |
847 | ctrl->info->size); | 848 | ctrl->info.size); |
848 | if (ret < 0) | 849 | if (ret < 0) |
849 | return ret; | 850 | return ret; |
850 | } | 851 | } |
@@ -862,9 +863,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
862 | unsigned int i; | 863 | unsigned int i; |
863 | int ret; | 864 | int ret; |
864 | 865 | ||
866 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
867 | if (ret < 0) | ||
868 | return -ERESTARTSYS; | ||
869 | |||
865 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); | 870 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); |
866 | if (ctrl == NULL) | 871 | if (ctrl == NULL) { |
867 | return -EINVAL; | 872 | ret = -EINVAL; |
873 | goto done; | ||
874 | } | ||
868 | 875 | ||
869 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 876 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); |
870 | v4l2_ctrl->id = mapping->id; | 877 | v4l2_ctrl->id = mapping->id; |
@@ -872,18 +879,18 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
872 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); | 879 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); |
873 | v4l2_ctrl->flags = 0; | 880 | v4l2_ctrl->flags = 0; |
874 | 881 | ||
875 | if (!(ctrl->info->flags & UVC_CONTROL_GET_CUR)) | 882 | if (!(ctrl->info.flags & UVC_CONTROL_GET_CUR)) |
876 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; | 883 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; |
877 | if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) | 884 | if (!(ctrl->info.flags & UVC_CONTROL_SET_CUR)) |
878 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | 885 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
879 | 886 | ||
880 | if (!ctrl->cached) { | 887 | if (!ctrl->cached) { |
881 | ret = uvc_ctrl_populate_cache(chain, ctrl); | 888 | ret = uvc_ctrl_populate_cache(chain, ctrl); |
882 | if (ret < 0) | 889 | if (ret < 0) |
883 | return ret; | 890 | goto done; |
884 | } | 891 | } |
885 | 892 | ||
886 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 893 | if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { |
887 | v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, | 894 | v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, |
888 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); | 895 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); |
889 | } | 896 | } |
@@ -902,37 +909,39 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
902 | } | 909 | } |
903 | } | 910 | } |
904 | 911 | ||
905 | return 0; | 912 | goto done; |
906 | 913 | ||
907 | case V4L2_CTRL_TYPE_BOOLEAN: | 914 | case V4L2_CTRL_TYPE_BOOLEAN: |
908 | v4l2_ctrl->minimum = 0; | 915 | v4l2_ctrl->minimum = 0; |
909 | v4l2_ctrl->maximum = 1; | 916 | v4l2_ctrl->maximum = 1; |
910 | v4l2_ctrl->step = 1; | 917 | v4l2_ctrl->step = 1; |
911 | return 0; | 918 | goto done; |
912 | 919 | ||
913 | case V4L2_CTRL_TYPE_BUTTON: | 920 | case V4L2_CTRL_TYPE_BUTTON: |
914 | v4l2_ctrl->minimum = 0; | 921 | v4l2_ctrl->minimum = 0; |
915 | v4l2_ctrl->maximum = 0; | 922 | v4l2_ctrl->maximum = 0; |
916 | v4l2_ctrl->step = 0; | 923 | v4l2_ctrl->step = 0; |
917 | return 0; | 924 | goto done; |
918 | 925 | ||
919 | default: | 926 | default: |
920 | break; | 927 | break; |
921 | } | 928 | } |
922 | 929 | ||
923 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) | 930 | if (ctrl->info.flags & UVC_CONTROL_GET_MIN) |
924 | v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, | 931 | v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, |
925 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); | 932 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); |
926 | 933 | ||
927 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) | 934 | if (ctrl->info.flags & UVC_CONTROL_GET_MAX) |
928 | v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, | 935 | v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, |
929 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); | 936 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); |
930 | 937 | ||
931 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) | 938 | if (ctrl->info.flags & UVC_CONTROL_GET_RES) |
932 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, | 939 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, |
933 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); | 940 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); |
934 | 941 | ||
935 | return 0; | 942 | done: |
943 | mutex_unlock(&chain->ctrl_mutex); | ||
944 | return ret; | ||
936 | } | 945 | } |
937 | 946 | ||
938 | 947 | ||
@@ -977,14 +986,14 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, | |||
977 | 986 | ||
978 | for (i = 0; i < entity->ncontrols; ++i) { | 987 | for (i = 0; i < entity->ncontrols; ++i) { |
979 | ctrl = &entity->controls[i]; | 988 | ctrl = &entity->controls[i]; |
980 | if (ctrl->info == NULL) | 989 | if (!ctrl->initialized) |
981 | continue; | 990 | continue; |
982 | 991 | ||
983 | /* Reset the loaded flag for auto-update controls that were | 992 | /* Reset the loaded flag for auto-update controls that were |
984 | * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent | 993 | * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent |
985 | * uvc_ctrl_get from using the cached value. | 994 | * uvc_ctrl_get from using the cached value. |
986 | */ | 995 | */ |
987 | if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) | 996 | if (ctrl->info.flags & UVC_CONTROL_AUTO_UPDATE) |
988 | ctrl->loaded = 0; | 997 | ctrl->loaded = 0; |
989 | 998 | ||
990 | if (!ctrl->dirty) | 999 | if (!ctrl->dirty) |
@@ -992,16 +1001,16 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, | |||
992 | 1001 | ||
993 | if (!rollback) | 1002 | if (!rollback) |
994 | ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, | 1003 | ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, |
995 | dev->intfnum, ctrl->info->selector, | 1004 | dev->intfnum, ctrl->info.selector, |
996 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1005 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
997 | ctrl->info->size); | 1006 | ctrl->info.size); |
998 | else | 1007 | else |
999 | ret = 0; | 1008 | ret = 0; |
1000 | 1009 | ||
1001 | if (rollback || ret < 0) | 1010 | if (rollback || ret < 0) |
1002 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1011 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1003 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1012 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1004 | ctrl->info->size); | 1013 | ctrl->info.size); |
1005 | 1014 | ||
1006 | ctrl->dirty = 0; | 1015 | ctrl->dirty = 0; |
1007 | 1016 | ||
@@ -1039,14 +1048,14 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, | |||
1039 | int ret; | 1048 | int ret; |
1040 | 1049 | ||
1041 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1050 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1042 | if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) | 1051 | if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) |
1043 | return -EINVAL; | 1052 | return -EINVAL; |
1044 | 1053 | ||
1045 | if (!ctrl->loaded) { | 1054 | if (!ctrl->loaded) { |
1046 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, | 1055 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, |
1047 | chain->dev->intfnum, ctrl->info->selector, | 1056 | chain->dev->intfnum, ctrl->info.selector, |
1048 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1057 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1049 | ctrl->info->size); | 1058 | ctrl->info.size); |
1050 | if (ret < 0) | 1059 | if (ret < 0) |
1051 | return ret; | 1060 | return ret; |
1052 | 1061 | ||
@@ -1081,7 +1090,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1081 | int ret; | 1090 | int ret; |
1082 | 1091 | ||
1083 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1092 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1084 | if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) | 1093 | if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_SET_CUR) == 0) |
1085 | return -EINVAL; | 1094 | return -EINVAL; |
1086 | 1095 | ||
1087 | /* Clamp out of range values. */ | 1096 | /* Clamp out of range values. */ |
@@ -1127,16 +1136,16 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1127 | * needs to be loaded from the device to perform the read-modify-write | 1136 | * needs to be loaded from the device to perform the read-modify-write |
1128 | * operation. | 1137 | * operation. |
1129 | */ | 1138 | */ |
1130 | if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { | 1139 | if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { |
1131 | if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { | 1140 | if ((ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) { |
1132 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1141 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1133 | 0, ctrl->info->size); | 1142 | 0, ctrl->info.size); |
1134 | } else { | 1143 | } else { |
1135 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, | 1144 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, |
1136 | ctrl->entity->id, chain->dev->intfnum, | 1145 | ctrl->entity->id, chain->dev->intfnum, |
1137 | ctrl->info->selector, | 1146 | ctrl->info.selector, |
1138 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1147 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1139 | ctrl->info->size); | 1148 | ctrl->info.size); |
1140 | if (ret < 0) | 1149 | if (ret < 0) |
1141 | return ret; | 1150 | return ret; |
1142 | } | 1151 | } |
@@ -1148,7 +1157,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1148 | if (!ctrl->dirty) { | 1157 | if (!ctrl->dirty) { |
1149 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1158 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1150 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1159 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1151 | ctrl->info->size); | 1160 | ctrl->info.size); |
1152 | } | 1161 | } |
1153 | 1162 | ||
1154 | mapping->set(mapping, value, | 1163 | mapping->set(mapping, value, |
@@ -1163,12 +1172,138 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1163 | * Dynamic controls | 1172 | * Dynamic controls |
1164 | */ | 1173 | */ |
1165 | 1174 | ||
1175 | static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev, | ||
1176 | const struct uvc_control *ctrl, struct uvc_control_info *info) | ||
1177 | { | ||
1178 | struct uvc_ctrl_fixup { | ||
1179 | struct usb_device_id id; | ||
1180 | u8 entity; | ||
1181 | u8 selector; | ||
1182 | u8 flags; | ||
1183 | }; | ||
1184 | |||
1185 | static const struct uvc_ctrl_fixup fixups[] = { | ||
1186 | { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1, | ||
1187 | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | | ||
1188 | UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | | ||
1189 | UVC_CONTROL_AUTO_UPDATE }, | ||
1190 | { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1, | ||
1191 | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | | ||
1192 | UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | | ||
1193 | UVC_CONTROL_AUTO_UPDATE }, | ||
1194 | { { USB_DEVICE(0x046d, 0x0994) }, 9, 1, | ||
1195 | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | | ||
1196 | UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | | ||
1197 | UVC_CONTROL_AUTO_UPDATE }, | ||
1198 | }; | ||
1199 | |||
1200 | unsigned int i; | ||
1201 | |||
1202 | for (i = 0; i < ARRAY_SIZE(fixups); ++i) { | ||
1203 | if (!usb_match_one_id(dev->intf, &fixups[i].id)) | ||
1204 | continue; | ||
1205 | |||
1206 | if (fixups[i].entity == ctrl->entity->id && | ||
1207 | fixups[i].selector == info->selector) { | ||
1208 | info->flags = fixups[i].flags; | ||
1209 | return; | ||
1210 | } | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | /* | ||
1215 | * Query control information (size and flags) for XU controls. | ||
1216 | */ | ||
1217 | static int uvc_ctrl_fill_xu_info(struct uvc_device *dev, | ||
1218 | const struct uvc_control *ctrl, struct uvc_control_info *info) | ||
1219 | { | ||
1220 | u8 *data; | ||
1221 | int ret; | ||
1222 | |||
1223 | data = kmalloc(2, GFP_KERNEL); | ||
1224 | if (data == NULL) | ||
1225 | return -ENOMEM; | ||
1226 | |||
1227 | memcpy(info->entity, ctrl->entity->extension.guidExtensionCode, | ||
1228 | sizeof(info->entity)); | ||
1229 | info->index = ctrl->index; | ||
1230 | info->selector = ctrl->index + 1; | ||
1231 | |||
1232 | /* Query and verify the control length (GET_LEN) */ | ||
1233 | ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, dev->intfnum, | ||
1234 | info->selector, data, 2); | ||
1235 | if (ret < 0) { | ||
1236 | uvc_trace(UVC_TRACE_CONTROL, | ||
1237 | "GET_LEN failed on control %pUl/%u (%d).\n", | ||
1238 | info->entity, info->selector, ret); | ||
1239 | goto done; | ||
1240 | } | ||
1241 | |||
1242 | info->size = le16_to_cpup((__le16 *)data); | ||
1243 | |||
1244 | /* Query the control information (GET_INFO) */ | ||
1245 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, | ||
1246 | info->selector, data, 1); | ||
1247 | if (ret < 0) { | ||
1248 | uvc_trace(UVC_TRACE_CONTROL, | ||
1249 | "GET_INFO failed on control %pUl/%u (%d).\n", | ||
1250 | info->entity, info->selector, ret); | ||
1251 | goto done; | ||
1252 | } | ||
1253 | |||
1254 | info->flags = UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | ||
1255 | | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | ||
1256 | | (data[0] & UVC_CONTROL_CAP_GET ? UVC_CONTROL_GET_CUR : 0) | ||
1257 | | (data[0] & UVC_CONTROL_CAP_SET ? UVC_CONTROL_SET_CUR : 0) | ||
1258 | | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? | ||
1259 | UVC_CONTROL_AUTO_UPDATE : 0); | ||
1260 | |||
1261 | uvc_ctrl_fixup_xu_info(dev, ctrl, info); | ||
1262 | |||
1263 | uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " | ||
1264 | "flags { get %u set %u auto %u }.\n", | ||
1265 | info->entity, info->selector, info->size, | ||
1266 | (info->flags & UVC_CONTROL_GET_CUR) ? 1 : 0, | ||
1267 | (info->flags & UVC_CONTROL_SET_CUR) ? 1 : 0, | ||
1268 | (info->flags & UVC_CONTROL_AUTO_UPDATE) ? 1 : 0); | ||
1269 | |||
1270 | done: | ||
1271 | kfree(data); | ||
1272 | return ret; | ||
1273 | } | ||
1274 | |||
1275 | static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, | ||
1276 | const struct uvc_control_info *info); | ||
1277 | |||
1278 | static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev, | ||
1279 | struct uvc_control *ctrl) | ||
1280 | { | ||
1281 | struct uvc_control_info info; | ||
1282 | int ret; | ||
1283 | |||
1284 | if (ctrl->initialized) | ||
1285 | return 0; | ||
1286 | |||
1287 | ret = uvc_ctrl_fill_xu_info(dev, ctrl, &info); | ||
1288 | if (ret < 0) | ||
1289 | return ret; | ||
1290 | |||
1291 | ret = uvc_ctrl_add_info(dev, ctrl, &info); | ||
1292 | if (ret < 0) | ||
1293 | uvc_trace(UVC_TRACE_CONTROL, "Failed to initialize control " | ||
1294 | "%pUl/%u on device %s entity %u\n", info.entity, | ||
1295 | info.selector, dev->udev->devpath, ctrl->entity->id); | ||
1296 | |||
1297 | return ret; | ||
1298 | } | ||
1299 | |||
1166 | int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | 1300 | int uvc_xu_ctrl_query(struct uvc_video_chain *chain, |
1167 | struct uvc_xu_control *xctrl, int set) | 1301 | struct uvc_xu_control *xctrl, int set) |
1168 | { | 1302 | { |
1169 | struct uvc_entity *entity; | 1303 | struct uvc_entity *entity; |
1170 | struct uvc_control *ctrl = NULL; | 1304 | struct uvc_control *ctrl = NULL; |
1171 | unsigned int i, found = 0; | 1305 | unsigned int i, found = 0; |
1306 | int restore = 0; | ||
1172 | __u8 *data; | 1307 | __u8 *data; |
1173 | int ret; | 1308 | int ret; |
1174 | 1309 | ||
@@ -1185,13 +1320,10 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1185 | return -EINVAL; | 1320 | return -EINVAL; |
1186 | } | 1321 | } |
1187 | 1322 | ||
1188 | /* Find the control. */ | 1323 | /* Find the control and perform delayed initialization if needed. */ |
1189 | for (i = 0; i < entity->ncontrols; ++i) { | 1324 | for (i = 0; i < entity->ncontrols; ++i) { |
1190 | ctrl = &entity->controls[i]; | 1325 | ctrl = &entity->controls[i]; |
1191 | if (ctrl->info == NULL) | 1326 | if (ctrl->index == xctrl->selector - 1) { |
1192 | continue; | ||
1193 | |||
1194 | if (ctrl->info->selector == xctrl->selector) { | ||
1195 | found = 1; | 1327 | found = 1; |
1196 | break; | 1328 | break; |
1197 | } | 1329 | } |
@@ -1203,40 +1335,48 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1203 | return -EINVAL; | 1335 | return -EINVAL; |
1204 | } | 1336 | } |
1205 | 1337 | ||
1206 | /* Validate control data size. */ | ||
1207 | if (ctrl->info->size != xctrl->size) | ||
1208 | return -EINVAL; | ||
1209 | |||
1210 | if ((set && !(ctrl->info->flags & UVC_CONTROL_SET_CUR)) || | ||
1211 | (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR))) | ||
1212 | return -EINVAL; | ||
1213 | |||
1214 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) | 1338 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) |
1215 | return -ERESTARTSYS; | 1339 | return -ERESTARTSYS; |
1216 | 1340 | ||
1341 | ret = uvc_ctrl_init_xu_ctrl(chain->dev, ctrl); | ||
1342 | if (ret < 0) { | ||
1343 | ret = -ENOENT; | ||
1344 | goto done; | ||
1345 | } | ||
1346 | |||
1347 | /* Validate control data size. */ | ||
1348 | if (ctrl->info.size != xctrl->size) { | ||
1349 | ret = -EINVAL; | ||
1350 | goto done; | ||
1351 | } | ||
1352 | |||
1353 | if ((set && !(ctrl->info.flags & UVC_CONTROL_SET_CUR)) || | ||
1354 | (!set && !(ctrl->info.flags & UVC_CONTROL_GET_CUR))) { | ||
1355 | ret = -EINVAL; | ||
1356 | goto done; | ||
1357 | } | ||
1358 | |||
1217 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1359 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1218 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1360 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1219 | xctrl->size); | 1361 | ctrl->info.size); |
1220 | data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); | 1362 | data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); |
1363 | restore = set; | ||
1221 | 1364 | ||
1222 | if (set && copy_from_user(data, xctrl->data, xctrl->size)) { | 1365 | if (set && copy_from_user(data, xctrl->data, xctrl->size)) { |
1223 | ret = -EFAULT; | 1366 | ret = -EFAULT; |
1224 | goto out; | 1367 | goto done; |
1225 | } | 1368 | } |
1226 | 1369 | ||
1227 | ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR, | 1370 | ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR, |
1228 | xctrl->unit, chain->dev->intfnum, xctrl->selector, | 1371 | xctrl->unit, chain->dev->intfnum, xctrl->selector, |
1229 | data, xctrl->size); | 1372 | data, xctrl->size); |
1230 | if (ret < 0) | 1373 | if (ret < 0) |
1231 | goto out; | 1374 | goto done; |
1232 | 1375 | ||
1233 | if (!set && copy_to_user(xctrl->data, data, xctrl->size)) { | 1376 | if (!set && copy_to_user(xctrl->data, data, xctrl->size)) |
1234 | ret = -EFAULT; | 1377 | ret = -EFAULT; |
1235 | goto out; | 1378 | done: |
1236 | } | 1379 | if (ret && restore) |
1237 | |||
1238 | out: | ||
1239 | if (ret) | ||
1240 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1380 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1241 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1381 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1242 | xctrl->size); | 1382 | xctrl->size); |
@@ -1271,13 +1411,13 @@ int uvc_ctrl_resume_device(struct uvc_device *dev) | |||
1271 | for (i = 0; i < entity->ncontrols; ++i) { | 1411 | for (i = 0; i < entity->ncontrols; ++i) { |
1272 | ctrl = &entity->controls[i]; | 1412 | ctrl = &entity->controls[i]; |
1273 | 1413 | ||
1274 | if (ctrl->info == NULL || !ctrl->modified || | 1414 | if (!ctrl->initialized || !ctrl->modified || |
1275 | (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) | 1415 | (ctrl->info.flags & UVC_CONTROL_RESTORE) == 0) |
1276 | continue; | 1416 | continue; |
1277 | 1417 | ||
1278 | printk(KERN_INFO "restoring control %pUl/%u/%u\n", | 1418 | printk(KERN_INFO "restoring control %pUl/%u/%u\n", |
1279 | ctrl->info->entity, ctrl->info->index, | 1419 | ctrl->info.entity, ctrl->info.index, |
1280 | ctrl->info->selector); | 1420 | ctrl->info.selector); |
1281 | ctrl->dirty = 1; | 1421 | ctrl->dirty = 1; |
1282 | } | 1422 | } |
1283 | 1423 | ||
@@ -1293,201 +1433,150 @@ int uvc_ctrl_resume_device(struct uvc_device *dev) | |||
1293 | * Control and mapping handling | 1433 | * Control and mapping handling |
1294 | */ | 1434 | */ |
1295 | 1435 | ||
1296 | static int uvc_ctrl_add_ctrl(struct uvc_device *dev, | 1436 | /* |
1297 | struct uvc_control_info *info) | 1437 | * Add control information to a given control. |
1438 | */ | ||
1439 | static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, | ||
1440 | const struct uvc_control_info *info) | ||
1298 | { | 1441 | { |
1299 | struct uvc_entity *entity; | 1442 | int ret = 0; |
1300 | struct uvc_control *ctrl = NULL; | ||
1301 | int ret = 0, found = 0; | ||
1302 | unsigned int i; | ||
1303 | u8 *uvc_info; | ||
1304 | u8 *uvc_data; | ||
1305 | |||
1306 | list_for_each_entry(entity, &dev->entities, list) { | ||
1307 | if (!uvc_entity_match_guid(entity, info->entity)) | ||
1308 | continue; | ||
1309 | |||
1310 | for (i = 0; i < entity->ncontrols; ++i) { | ||
1311 | ctrl = &entity->controls[i]; | ||
1312 | if (ctrl->index == info->index) { | ||
1313 | found = 1; | ||
1314 | break; | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | if (found) | ||
1319 | break; | ||
1320 | } | ||
1321 | |||
1322 | if (!found) | ||
1323 | return 0; | ||
1324 | |||
1325 | uvc_data = kmalloc(info->size * UVC_CTRL_DATA_LAST + 1, GFP_KERNEL); | ||
1326 | if (uvc_data == NULL) | ||
1327 | return -ENOMEM; | ||
1328 | |||
1329 | uvc_info = uvc_data + info->size * UVC_CTRL_DATA_LAST; | ||
1330 | |||
1331 | if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { | ||
1332 | /* Check if the device control information and length match | ||
1333 | * the user supplied information. | ||
1334 | */ | ||
1335 | ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, | ||
1336 | dev->intfnum, info->selector, uvc_data, 2); | ||
1337 | if (ret < 0) { | ||
1338 | uvc_trace(UVC_TRACE_CONTROL, | ||
1339 | "GET_LEN failed on control %pUl/%u (%d).\n", | ||
1340 | info->entity, info->selector, ret); | ||
1341 | goto done; | ||
1342 | } | ||
1343 | |||
1344 | if (info->size != le16_to_cpu(*(__le16 *)uvc_data)) { | ||
1345 | uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size " | ||
1346 | "doesn't match user supplied value.\n", | ||
1347 | info->entity, info->selector); | ||
1348 | ret = -EINVAL; | ||
1349 | goto done; | ||
1350 | } | ||
1351 | 1443 | ||
1352 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, | 1444 | memcpy(&ctrl->info, info, sizeof(*info)); |
1353 | dev->intfnum, info->selector, uvc_info, 1); | 1445 | INIT_LIST_HEAD(&ctrl->info.mappings); |
1354 | if (ret < 0) { | ||
1355 | uvc_trace(UVC_TRACE_CONTROL, | ||
1356 | "GET_INFO failed on control %pUl/%u (%d).\n", | ||
1357 | info->entity, info->selector, ret); | ||
1358 | goto done; | ||
1359 | } | ||
1360 | 1446 | ||
1361 | if (((info->flags & UVC_CONTROL_GET_CUR) && | 1447 | /* Allocate an array to save control values (cur, def, max, etc.) */ |
1362 | !(*uvc_info & UVC_CONTROL_CAP_GET)) || | 1448 | ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1, |
1363 | ((info->flags & UVC_CONTROL_SET_CUR) && | 1449 | GFP_KERNEL); |
1364 | !(*uvc_info & UVC_CONTROL_CAP_SET))) { | 1450 | if (ctrl->uvc_data == NULL) { |
1365 | uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags " | 1451 | ret = -ENOMEM; |
1366 | "don't match supported operations.\n", | 1452 | goto done; |
1367 | info->entity, info->selector); | ||
1368 | ret = -EINVAL; | ||
1369 | goto done; | ||
1370 | } | ||
1371 | } | 1453 | } |
1372 | 1454 | ||
1373 | ctrl->info = info; | 1455 | ctrl->initialized = 1; |
1374 | ctrl->uvc_data = uvc_data; | ||
1375 | ctrl->uvc_info = uvc_info; | ||
1376 | 1456 | ||
1377 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " | 1457 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " |
1378 | "entity %u\n", ctrl->info->entity, ctrl->info->selector, | 1458 | "entity %u\n", ctrl->info.entity, ctrl->info.selector, |
1379 | dev->udev->devpath, entity->id); | 1459 | dev->udev->devpath, ctrl->entity->id); |
1380 | 1460 | ||
1381 | done: | 1461 | done: |
1382 | if (ret < 0) | 1462 | if (ret < 0) |
1383 | kfree(uvc_data); | 1463 | kfree(ctrl->uvc_data); |
1384 | |||
1385 | return ret; | 1464 | return ret; |
1386 | } | 1465 | } |
1387 | 1466 | ||
1388 | /* | 1467 | /* |
1389 | * Add an item to the UVC control information list, and instantiate a control | 1468 | * Add a control mapping to a given control. |
1390 | * structure for each device that supports the control. | ||
1391 | */ | 1469 | */ |
1392 | int uvc_ctrl_add_info(struct uvc_control_info *info) | 1470 | static int __uvc_ctrl_add_mapping(struct uvc_device *dev, |
1471 | struct uvc_control *ctrl, const struct uvc_control_mapping *mapping) | ||
1393 | { | 1472 | { |
1394 | struct uvc_control_info *ctrl; | 1473 | struct uvc_control_mapping *map; |
1395 | struct uvc_device *dev; | 1474 | unsigned int size; |
1396 | int ret = 0; | ||
1397 | |||
1398 | /* Find matching controls by walking the devices, entities and | ||
1399 | * controls list. | ||
1400 | */ | ||
1401 | mutex_lock(&uvc_driver.ctrl_mutex); | ||
1402 | 1475 | ||
1403 | /* First check if the list contains a control matching the new one. | 1476 | /* Most mappings come from static kernel data and need to be duplicated. |
1404 | * Bail out if it does. | 1477 | * Mappings that come from userspace will be unnecessarily duplicated, |
1478 | * this could be optimized. | ||
1405 | */ | 1479 | */ |
1406 | list_for_each_entry(ctrl, &uvc_driver.controls, list) { | 1480 | map = kmemdup(mapping, sizeof(*mapping), GFP_KERNEL); |
1407 | if (memcmp(ctrl->entity, info->entity, 16)) | 1481 | if (map == NULL) |
1408 | continue; | 1482 | return -ENOMEM; |
1409 | 1483 | ||
1410 | if (ctrl->selector == info->selector) { | 1484 | size = sizeof(*mapping->menu_info) * mapping->menu_count; |
1411 | uvc_trace(UVC_TRACE_CONTROL, | 1485 | map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL); |
1412 | "Control %pUl/%u is already defined.\n", | 1486 | if (map->menu_info == NULL) { |
1413 | info->entity, info->selector); | 1487 | kfree(map); |
1414 | ret = -EEXIST; | 1488 | return -ENOMEM; |
1415 | goto end; | ||
1416 | } | ||
1417 | if (ctrl->index == info->index) { | ||
1418 | uvc_trace(UVC_TRACE_CONTROL, | ||
1419 | "Control %pUl/%u would overwrite index %d.\n", | ||
1420 | info->entity, info->selector, info->index); | ||
1421 | ret = -EEXIST; | ||
1422 | goto end; | ||
1423 | } | ||
1424 | } | 1489 | } |
1425 | 1490 | ||
1426 | list_for_each_entry(dev, &uvc_driver.devices, list) | 1491 | if (map->get == NULL) |
1427 | uvc_ctrl_add_ctrl(dev, info); | 1492 | map->get = uvc_get_le_value; |
1493 | if (map->set == NULL) | ||
1494 | map->set = uvc_set_le_value; | ||
1428 | 1495 | ||
1429 | INIT_LIST_HEAD(&info->mappings); | 1496 | map->ctrl = &ctrl->info; |
1430 | list_add_tail(&info->list, &uvc_driver.controls); | 1497 | list_add_tail(&map->list, &ctrl->info.mappings); |
1431 | end: | 1498 | uvc_trace(UVC_TRACE_CONTROL, |
1432 | mutex_unlock(&uvc_driver.ctrl_mutex); | 1499 | "Adding mapping '%s' to control %pUl/%u.\n", |
1433 | return ret; | 1500 | map->name, ctrl->info.entity, ctrl->info.selector); |
1501 | |||
1502 | return 0; | ||
1434 | } | 1503 | } |
1435 | 1504 | ||
1436 | int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping) | 1505 | int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
1506 | const struct uvc_control_mapping *mapping) | ||
1437 | { | 1507 | { |
1438 | struct uvc_control_info *info; | 1508 | struct uvc_device *dev = chain->dev; |
1439 | struct uvc_control_mapping *map; | 1509 | struct uvc_control_mapping *map; |
1440 | int ret = -EINVAL; | 1510 | struct uvc_entity *entity; |
1441 | 1511 | struct uvc_control *ctrl; | |
1442 | if (mapping->get == NULL) | 1512 | int found = 0; |
1443 | mapping->get = uvc_get_le_value; | 1513 | int ret; |
1444 | if (mapping->set == NULL) | ||
1445 | mapping->set = uvc_set_le_value; | ||
1446 | 1514 | ||
1447 | if (mapping->id & ~V4L2_CTRL_ID_MASK) { | 1515 | if (mapping->id & ~V4L2_CTRL_ID_MASK) { |
1448 | uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s' with " | 1516 | uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', control " |
1449 | "invalid control id 0x%08x\n", mapping->name, | 1517 | "id 0x%08x is invalid.\n", mapping->name, |
1450 | mapping->id); | 1518 | mapping->id); |
1451 | return -EINVAL; | 1519 | return -EINVAL; |
1452 | } | 1520 | } |
1453 | 1521 | ||
1454 | mutex_lock(&uvc_driver.ctrl_mutex); | 1522 | /* Search for the matching (GUID/CS) control in the given device */ |
1455 | list_for_each_entry(info, &uvc_driver.controls, list) { | 1523 | list_for_each_entry(entity, &dev->entities, list) { |
1456 | if (memcmp(info->entity, mapping->entity, 16) || | 1524 | unsigned int i; |
1457 | info->selector != mapping->selector) | ||
1458 | continue; | ||
1459 | 1525 | ||
1460 | if (info->size * 8 < mapping->size + mapping->offset) { | 1526 | if (UVC_ENTITY_TYPE(entity) != UVC_VC_EXTENSION_UNIT || |
1461 | uvc_trace(UVC_TRACE_CONTROL, | 1527 | !uvc_entity_match_guid(entity, mapping->entity)) |
1462 | "Mapping '%s' would overflow control %pUl/%u\n", | 1528 | continue; |
1463 | mapping->name, info->entity, info->selector); | ||
1464 | ret = -EOVERFLOW; | ||
1465 | goto end; | ||
1466 | } | ||
1467 | 1529 | ||
1468 | /* Check if the list contains a mapping matching the new one. | 1530 | for (i = 0; i < entity->ncontrols; ++i) { |
1469 | * Bail out if it does. | 1531 | ctrl = &entity->controls[i]; |
1470 | */ | 1532 | if (ctrl->index == mapping->selector - 1) { |
1471 | list_for_each_entry(map, &info->mappings, list) { | 1533 | found = 1; |
1472 | if (map->id == mapping->id) { | 1534 | break; |
1473 | uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' is " | ||
1474 | "already defined.\n", mapping->name); | ||
1475 | ret = -EEXIST; | ||
1476 | goto end; | ||
1477 | } | 1535 | } |
1478 | } | 1536 | } |
1479 | 1537 | ||
1480 | mapping->ctrl = info; | 1538 | if (found) |
1481 | list_add_tail(&mapping->list, &info->mappings); | 1539 | break; |
1482 | uvc_trace(UVC_TRACE_CONTROL, | 1540 | } |
1483 | "Adding mapping %s to control %pUl/%u.\n", | 1541 | if (!found) |
1484 | mapping->name, info->entity, info->selector); | 1542 | return -ENOENT; |
1485 | 1543 | ||
1486 | ret = 0; | 1544 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) |
1487 | break; | 1545 | return -ERESTARTSYS; |
1546 | |||
1547 | /* Perform delayed initialization of XU controls */ | ||
1548 | ret = uvc_ctrl_init_xu_ctrl(dev, ctrl); | ||
1549 | if (ret < 0) { | ||
1550 | ret = -ENOENT; | ||
1551 | goto done; | ||
1488 | } | 1552 | } |
1489 | end: | 1553 | |
1490 | mutex_unlock(&uvc_driver.ctrl_mutex); | 1554 | list_for_each_entry(map, &ctrl->info.mappings, list) { |
1555 | if (mapping->id == map->id) { | ||
1556 | uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " | ||
1557 | "control id 0x%08x already exists.\n", | ||
1558 | mapping->name, mapping->id); | ||
1559 | ret = -EEXIST; | ||
1560 | goto done; | ||
1561 | } | ||
1562 | } | ||
1563 | |||
1564 | /* Prevent excess memory consumption */ | ||
1565 | if (atomic_inc_return(&dev->nmappings) > UVC_MAX_CONTROL_MAPPINGS) { | ||
1566 | atomic_dec(&dev->nmappings); | ||
1567 | uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', maximum " | ||
1568 | "mappings count (%u) exceeded.\n", mapping->name, | ||
1569 | UVC_MAX_CONTROL_MAPPINGS); | ||
1570 | ret = -ENOMEM; | ||
1571 | goto done; | ||
1572 | } | ||
1573 | |||
1574 | ret = __uvc_ctrl_add_mapping(dev, ctrl, mapping); | ||
1575 | if (ret < 0) | ||
1576 | atomic_dec(&dev->nmappings); | ||
1577 | |||
1578 | done: | ||
1579 | mutex_unlock(&chain->ctrl_mutex); | ||
1491 | return ret; | 1580 | return ret; |
1492 | } | 1581 | } |
1493 | 1582 | ||
@@ -1496,29 +1585,49 @@ end: | |||
1496 | * are currently the ones that crash the camera or unconditionally return an | 1585 | * are currently the ones that crash the camera or unconditionally return an |
1497 | * error when queried. | 1586 | * error when queried. |
1498 | */ | 1587 | */ |
1499 | static void | 1588 | static void uvc_ctrl_prune_entity(struct uvc_device *dev, |
1500 | uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) | 1589 | struct uvc_entity *entity) |
1501 | { | 1590 | { |
1502 | static const struct { | 1591 | struct uvc_ctrl_blacklist { |
1503 | struct usb_device_id id; | 1592 | struct usb_device_id id; |
1504 | u8 index; | 1593 | u8 index; |
1505 | } blacklist[] = { | 1594 | }; |
1595 | |||
1596 | static const struct uvc_ctrl_blacklist processing_blacklist[] = { | ||
1506 | { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */ | 1597 | { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */ |
1507 | { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ | 1598 | { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ |
1508 | { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ | 1599 | { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ |
1509 | }; | 1600 | }; |
1601 | static const struct uvc_ctrl_blacklist camera_blacklist[] = { | ||
1602 | { { USB_DEVICE(0x06f8, 0x3005) }, 9 }, /* Zoom, Absolute */ | ||
1603 | }; | ||
1510 | 1604 | ||
1511 | u8 *controls; | 1605 | const struct uvc_ctrl_blacklist *blacklist; |
1512 | unsigned int size; | 1606 | unsigned int size; |
1607 | unsigned int count; | ||
1513 | unsigned int i; | 1608 | unsigned int i; |
1609 | u8 *controls; | ||
1514 | 1610 | ||
1515 | if (UVC_ENTITY_TYPE(entity) != UVC_VC_PROCESSING_UNIT) | 1611 | switch (UVC_ENTITY_TYPE(entity)) { |
1516 | return; | 1612 | case UVC_VC_PROCESSING_UNIT: |
1613 | blacklist = processing_blacklist; | ||
1614 | count = ARRAY_SIZE(processing_blacklist); | ||
1615 | controls = entity->processing.bmControls; | ||
1616 | size = entity->processing.bControlSize; | ||
1617 | break; | ||
1517 | 1618 | ||
1518 | controls = entity->processing.bmControls; | 1619 | case UVC_ITT_CAMERA: |
1519 | size = entity->processing.bControlSize; | 1620 | blacklist = camera_blacklist; |
1621 | count = ARRAY_SIZE(camera_blacklist); | ||
1622 | controls = entity->camera.bmControls; | ||
1623 | size = entity->camera.bControlSize; | ||
1624 | break; | ||
1520 | 1625 | ||
1521 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { | 1626 | default: |
1627 | return; | ||
1628 | } | ||
1629 | |||
1630 | for (i = 0; i < count; ++i) { | ||
1522 | if (!usb_match_one_id(dev->intf, &blacklist[i].id)) | 1631 | if (!usb_match_one_id(dev->intf, &blacklist[i].id)) |
1523 | continue; | 1632 | continue; |
1524 | 1633 | ||
@@ -1534,17 +1643,54 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) | |||
1534 | } | 1643 | } |
1535 | 1644 | ||
1536 | /* | 1645 | /* |
1646 | * Add control information and hardcoded stock control mappings to the given | ||
1647 | * device. | ||
1648 | */ | ||
1649 | static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl) | ||
1650 | { | ||
1651 | const struct uvc_control_info *info = uvc_ctrls; | ||
1652 | const struct uvc_control_info *iend = info + ARRAY_SIZE(uvc_ctrls); | ||
1653 | const struct uvc_control_mapping *mapping = uvc_ctrl_mappings; | ||
1654 | const struct uvc_control_mapping *mend = | ||
1655 | mapping + ARRAY_SIZE(uvc_ctrl_mappings); | ||
1656 | |||
1657 | /* XU controls initialization requires querying the device for control | ||
1658 | * information. As some buggy UVC devices will crash when queried | ||
1659 | * repeatedly in a tight loop, delay XU controls initialization until | ||
1660 | * first use. | ||
1661 | */ | ||
1662 | if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT) | ||
1663 | return; | ||
1664 | |||
1665 | for (; info < iend; ++info) { | ||
1666 | if (uvc_entity_match_guid(ctrl->entity, info->entity) && | ||
1667 | ctrl->index == info->index) { | ||
1668 | uvc_ctrl_add_info(dev, ctrl, info); | ||
1669 | break; | ||
1670 | } | ||
1671 | } | ||
1672 | |||
1673 | if (!ctrl->initialized) | ||
1674 | return; | ||
1675 | |||
1676 | for (; mapping < mend; ++mapping) { | ||
1677 | if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && | ||
1678 | ctrl->info.selector == mapping->selector) | ||
1679 | __uvc_ctrl_add_mapping(dev, ctrl, mapping); | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1683 | /* | ||
1537 | * Initialize device controls. | 1684 | * Initialize device controls. |
1538 | */ | 1685 | */ |
1539 | int uvc_ctrl_init_device(struct uvc_device *dev) | 1686 | int uvc_ctrl_init_device(struct uvc_device *dev) |
1540 | { | 1687 | { |
1541 | struct uvc_control_info *info; | ||
1542 | struct uvc_control *ctrl; | ||
1543 | struct uvc_entity *entity; | 1688 | struct uvc_entity *entity; |
1544 | unsigned int i; | 1689 | unsigned int i; |
1545 | 1690 | ||
1546 | /* Walk the entities list and instantiate controls */ | 1691 | /* Walk the entities list and instantiate controls */ |
1547 | list_for_each_entry(entity, &dev->entities, list) { | 1692 | list_for_each_entry(entity, &dev->entities, list) { |
1693 | struct uvc_control *ctrl; | ||
1548 | unsigned int bControlSize = 0, ncontrols = 0; | 1694 | unsigned int bControlSize = 0, ncontrols = 0; |
1549 | __u8 *bmControls = NULL; | 1695 | __u8 *bmControls = NULL; |
1550 | 1696 | ||
@@ -1559,20 +1705,22 @@ int uvc_ctrl_init_device(struct uvc_device *dev) | |||
1559 | bControlSize = entity->camera.bControlSize; | 1705 | bControlSize = entity->camera.bControlSize; |
1560 | } | 1706 | } |
1561 | 1707 | ||
1708 | /* Remove bogus/blacklisted controls */ | ||
1562 | uvc_ctrl_prune_entity(dev, entity); | 1709 | uvc_ctrl_prune_entity(dev, entity); |
1563 | 1710 | ||
1711 | /* Count supported controls and allocate the controls array */ | ||
1564 | for (i = 0; i < bControlSize; ++i) | 1712 | for (i = 0; i < bControlSize; ++i) |
1565 | ncontrols += hweight8(bmControls[i]); | 1713 | ncontrols += hweight8(bmControls[i]); |
1566 | |||
1567 | if (ncontrols == 0) | 1714 | if (ncontrols == 0) |
1568 | continue; | 1715 | continue; |
1569 | 1716 | ||
1570 | entity->controls = kzalloc(ncontrols*sizeof *ctrl, GFP_KERNEL); | 1717 | entity->controls = kzalloc(ncontrols * sizeof(*ctrl), |
1718 | GFP_KERNEL); | ||
1571 | if (entity->controls == NULL) | 1719 | if (entity->controls == NULL) |
1572 | return -ENOMEM; | 1720 | return -ENOMEM; |
1573 | |||
1574 | entity->ncontrols = ncontrols; | 1721 | entity->ncontrols = ncontrols; |
1575 | 1722 | ||
1723 | /* Initialize all supported controls */ | ||
1576 | ctrl = entity->controls; | 1724 | ctrl = entity->controls; |
1577 | for (i = 0; i < bControlSize * 8; ++i) { | 1725 | for (i = 0; i < bControlSize * 8; ++i) { |
1578 | if (uvc_test_bit(bmControls, i) == 0) | 1726 | if (uvc_test_bit(bmControls, i) == 0) |
@@ -1580,81 +1728,47 @@ int uvc_ctrl_init_device(struct uvc_device *dev) | |||
1580 | 1728 | ||
1581 | ctrl->entity = entity; | 1729 | ctrl->entity = entity; |
1582 | ctrl->index = i; | 1730 | ctrl->index = i; |
1731 | |||
1732 | uvc_ctrl_init_ctrl(dev, ctrl); | ||
1583 | ctrl++; | 1733 | ctrl++; |
1584 | } | 1734 | } |
1585 | } | 1735 | } |
1586 | 1736 | ||
1587 | /* Walk the controls info list and associate them with the device | ||
1588 | * controls, then add the device to the global device list. This has | ||
1589 | * to be done while holding the controls lock, to make sure | ||
1590 | * uvc_ctrl_add_info() will not get called in-between. | ||
1591 | */ | ||
1592 | mutex_lock(&uvc_driver.ctrl_mutex); | ||
1593 | list_for_each_entry(info, &uvc_driver.controls, list) | ||
1594 | uvc_ctrl_add_ctrl(dev, info); | ||
1595 | |||
1596 | list_add_tail(&dev->list, &uvc_driver.devices); | ||
1597 | mutex_unlock(&uvc_driver.ctrl_mutex); | ||
1598 | |||
1599 | return 0; | 1737 | return 0; |
1600 | } | 1738 | } |
1601 | 1739 | ||
1602 | /* | 1740 | /* |
1603 | * Cleanup device controls. | 1741 | * Cleanup device controls. |
1604 | */ | 1742 | */ |
1605 | void uvc_ctrl_cleanup_device(struct uvc_device *dev) | 1743 | static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev, |
1744 | struct uvc_control *ctrl) | ||
1606 | { | 1745 | { |
1607 | struct uvc_entity *entity; | 1746 | struct uvc_control_mapping *mapping, *nm; |
1608 | unsigned int i; | ||
1609 | 1747 | ||
1610 | /* Remove the device from the global devices list */ | 1748 | list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) { |
1611 | mutex_lock(&uvc_driver.ctrl_mutex); | 1749 | list_del(&mapping->list); |
1612 | if (dev->list.next != NULL) | 1750 | kfree(mapping->menu_info); |
1613 | list_del(&dev->list); | 1751 | kfree(mapping); |
1614 | mutex_unlock(&uvc_driver.ctrl_mutex); | ||
1615 | |||
1616 | list_for_each_entry(entity, &dev->entities, list) { | ||
1617 | for (i = 0; i < entity->ncontrols; ++i) | ||
1618 | kfree(entity->controls[i].uvc_data); | ||
1619 | |||
1620 | kfree(entity->controls); | ||
1621 | } | 1752 | } |
1622 | } | 1753 | } |
1623 | 1754 | ||
1624 | void uvc_ctrl_cleanup(void) | 1755 | void uvc_ctrl_cleanup_device(struct uvc_device *dev) |
1625 | { | 1756 | { |
1626 | struct uvc_control_info *info; | 1757 | struct uvc_entity *entity; |
1627 | struct uvc_control_info *ni; | 1758 | unsigned int i; |
1628 | struct uvc_control_mapping *mapping; | ||
1629 | struct uvc_control_mapping *nm; | ||
1630 | 1759 | ||
1631 | list_for_each_entry_safe(info, ni, &uvc_driver.controls, list) { | 1760 | /* Free controls and control mappings for all entities. */ |
1632 | if (!(info->flags & UVC_CONTROL_EXTENSION)) | 1761 | list_for_each_entry(entity, &dev->entities, list) { |
1633 | continue; | 1762 | for (i = 0; i < entity->ncontrols; ++i) { |
1763 | struct uvc_control *ctrl = &entity->controls[i]; | ||
1634 | 1764 | ||
1635 | list_for_each_entry_safe(mapping, nm, &info->mappings, list) { | 1765 | if (!ctrl->initialized) |
1636 | list_del(&mapping->list); | 1766 | continue; |
1637 | kfree(mapping->menu_info); | 1767 | |
1638 | kfree(mapping); | 1768 | uvc_ctrl_cleanup_mappings(dev, ctrl); |
1769 | kfree(ctrl->uvc_data); | ||
1639 | } | 1770 | } |
1640 | 1771 | ||
1641 | list_del(&info->list); | 1772 | kfree(entity->controls); |
1642 | kfree(info); | ||
1643 | } | 1773 | } |
1644 | } | 1774 | } |
1645 | |||
1646 | void uvc_ctrl_init(void) | ||
1647 | { | ||
1648 | struct uvc_control_info *ctrl = uvc_ctrls; | ||
1649 | struct uvc_control_info *cend = ctrl + ARRAY_SIZE(uvc_ctrls); | ||
1650 | struct uvc_control_mapping *mapping = uvc_ctrl_mappings; | ||
1651 | struct uvc_control_mapping *mend = | ||
1652 | mapping + ARRAY_SIZE(uvc_ctrl_mappings); | ||
1653 | |||
1654 | for (; ctrl < cend; ++ctrl) | ||
1655 | uvc_ctrl_add_info(ctrl); | ||
1656 | |||
1657 | for (; mapping < mend; ++mapping) | ||
1658 | uvc_ctrl_add_mapping(mapping); | ||
1659 | } | ||
1660 | |||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 2ac85d8984f..a1e9dfb52f6 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * uvc_driver.c -- USB Video Class driver | 2 | * uvc_driver.c -- USB Video Class driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2009 | 4 | * Copyright (C) 2005-2010 |
5 | * Laurent Pinchart (laurent.pinchart@skynet.be) | 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License as published by |
@@ -38,11 +38,9 @@ | |||
38 | 38 | ||
39 | #include "uvcvideo.h" | 39 | #include "uvcvideo.h" |
40 | 40 | ||
41 | #define DRIVER_AUTHOR "Laurent Pinchart <laurent.pinchart@skynet.be>" | 41 | #define DRIVER_AUTHOR "Laurent Pinchart " \ |
42 | "<laurent.pinchart@ideasonboard.com>" | ||
42 | #define DRIVER_DESC "USB Video Class driver" | 43 | #define DRIVER_DESC "USB Video Class driver" |
43 | #ifndef DRIVER_VERSION | ||
44 | #define DRIVER_VERSION "v0.1.0" | ||
45 | #endif | ||
46 | 44 | ||
47 | unsigned int uvc_clock_param = CLOCK_MONOTONIC; | 45 | unsigned int uvc_clock_param = CLOCK_MONOTONIC; |
48 | unsigned int uvc_no_drop_param; | 46 | unsigned int uvc_no_drop_param; |
@@ -1762,6 +1760,7 @@ static int uvc_probe(struct usb_interface *intf, | |||
1762 | INIT_LIST_HEAD(&dev->streams); | 1760 | INIT_LIST_HEAD(&dev->streams); |
1763 | atomic_set(&dev->nstreams, 0); | 1761 | atomic_set(&dev->nstreams, 0); |
1764 | atomic_set(&dev->users, 0); | 1762 | atomic_set(&dev->users, 0); |
1763 | atomic_set(&dev->nmappings, 0); | ||
1765 | 1764 | ||
1766 | dev->udev = usb_get_dev(udev); | 1765 | dev->udev = usb_get_dev(udev); |
1767 | dev->intf = usb_get_intf(intf); | 1766 | dev->intf = usb_get_intf(intf); |
@@ -1820,6 +1819,7 @@ static int uvc_probe(struct usb_interface *intf, | |||
1820 | } | 1819 | } |
1821 | 1820 | ||
1822 | uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n"); | 1821 | uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n"); |
1822 | usb_enable_autosuspend(udev); | ||
1823 | return 0; | 1823 | return 0; |
1824 | 1824 | ||
1825 | error: | 1825 | error: |
@@ -2287,12 +2287,6 @@ static int __init uvc_init(void) | |||
2287 | { | 2287 | { |
2288 | int result; | 2288 | int result; |
2289 | 2289 | ||
2290 | INIT_LIST_HEAD(&uvc_driver.devices); | ||
2291 | INIT_LIST_HEAD(&uvc_driver.controls); | ||
2292 | mutex_init(&uvc_driver.ctrl_mutex); | ||
2293 | |||
2294 | uvc_ctrl_init(); | ||
2295 | |||
2296 | result = usb_register(&uvc_driver.driver); | 2290 | result = usb_register(&uvc_driver.driver); |
2297 | if (result == 0) | 2291 | if (result == 0) |
2298 | printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n"); | 2292 | printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n"); |
@@ -2302,7 +2296,6 @@ static int __init uvc_init(void) | |||
2302 | static void __exit uvc_cleanup(void) | 2296 | static void __exit uvc_cleanup(void) |
2303 | { | 2297 | { |
2304 | usb_deregister(&uvc_driver.driver); | 2298 | usb_deregister(&uvc_driver.driver); |
2305 | uvc_ctrl_cleanup(); | ||
2306 | } | 2299 | } |
2307 | 2300 | ||
2308 | module_init(uvc_init); | 2301 | module_init(uvc_init); |
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c index a9285b570db..74bbe8f18f3 100644 --- a/drivers/media/video/uvc/uvc_isight.c +++ b/drivers/media/video/uvc/uvc_isight.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2006-2007 | 4 | * Copyright (C) 2006-2007 |
5 | * Ivan N. Zlatev <contact@i-nz.net> | 5 | * Ivan N. Zlatev <contact@i-nz.net> |
6 | * Copyright (C) 2008-2009 | 6 | * Copyright (C) 2008-2009 |
7 | * Laurent Pinchart <laurent.pinchart@skynet.be> | 7 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index e9928a41508..ed6d5449741 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * uvc_queue.c -- USB Video Class driver - Buffers management | 2 | * uvc_queue.c -- USB Video Class driver - Buffers management |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2009 | 4 | * Copyright (C) 2005-2010 |
5 | * Laurent Pinchart (laurent.pinchart@skynet.be) | 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License as published by |
@@ -135,7 +135,6 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | |||
135 | queue->buffer[i].buf.m.offset = i * bufsize; | 135 | queue->buffer[i].buf.m.offset = i * bufsize; |
136 | queue->buffer[i].buf.length = buflength; | 136 | queue->buffer[i].buf.length = buflength; |
137 | queue->buffer[i].buf.type = queue->type; | 137 | queue->buffer[i].buf.type = queue->type; |
138 | queue->buffer[i].buf.sequence = 0; | ||
139 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; | 138 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; |
140 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; | 139 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; |
141 | queue->buffer[i].buf.flags = 0; | 140 | queue->buffer[i].buf.flags = 0; |
@@ -410,8 +409,7 @@ done: | |||
410 | * state can be properly initialized before buffers are accessed from the | 409 | * state can be properly initialized before buffers are accessed from the |
411 | * interrupt handler. | 410 | * interrupt handler. |
412 | * | 411 | * |
413 | * Enabling the video queue initializes parameters (such as sequence number, | 412 | * Enabling the video queue returns -EBUSY if the queue is already enabled. |
414 | * sync pattern, ...). If the queue is already enabled, return -EBUSY. | ||
415 | * | 413 | * |
416 | * Disabling the video queue cancels the queue and removes all buffers from | 414 | * Disabling the video queue cancels the queue and removes all buffers from |
417 | * the main queue. | 415 | * the main queue. |
@@ -430,7 +428,6 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable) | |||
430 | ret = -EBUSY; | 428 | ret = -EBUSY; |
431 | goto done; | 429 | goto done; |
432 | } | 430 | } |
433 | queue->sequence = 0; | ||
434 | queue->flags |= UVC_QUEUE_STREAMING; | 431 | queue->flags |= UVC_QUEUE_STREAMING; |
435 | queue->buf_used = 0; | 432 | queue->buf_used = 0; |
436 | } else { | 433 | } else { |
@@ -510,8 +507,6 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
510 | nextbuf = NULL; | 507 | nextbuf = NULL; |
511 | spin_unlock_irqrestore(&queue->irqlock, flags); | 508 | spin_unlock_irqrestore(&queue->irqlock, flags); |
512 | 509 | ||
513 | buf->buf.sequence = queue->sequence++; | ||
514 | |||
515 | wake_up(&buf->wait); | 510 | wake_up(&buf->wait); |
516 | return nextbuf; | 511 | return nextbuf; |
517 | } | 512 | } |
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 85019bdacdf..b7492775e6a 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * uvc_status.c -- USB Video Class driver - Status endpoint | 2 | * uvc_status.c -- USB Video Class driver - Status endpoint |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2009 | 4 | * Copyright (C) 2005-2009 |
5 | * Laurent Pinchart (laurent.pinchart@skynet.be) | 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 86db32697b8..6d15de9b520 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * uvc_v4l2.c -- USB Video Class driver - V4L2 API | 2 | * uvc_v4l2.c -- USB Video Class driver - V4L2 API |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2009 | 4 | * Copyright (C) 2005-2010 |
5 | * Laurent Pinchart (laurent.pinchart@skynet.be) | 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License as published by |
@@ -31,7 +31,8 @@ | |||
31 | /* ------------------------------------------------------------------------ | 31 | /* ------------------------------------------------------------------------ |
32 | * UVC ioctls | 32 | * UVC ioctls |
33 | */ | 33 | */ |
34 | static int uvc_ioctl_ctrl_map(struct uvc_xu_control_mapping *xmap, int old) | 34 | static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, |
35 | struct uvc_xu_control_mapping *xmap, int old) | ||
35 | { | 36 | { |
36 | struct uvc_control_mapping *map; | 37 | struct uvc_control_mapping *map; |
37 | unsigned int size; | 38 | unsigned int size; |
@@ -58,6 +59,8 @@ static int uvc_ioctl_ctrl_map(struct uvc_xu_control_mapping *xmap, int old) | |||
58 | 59 | ||
59 | case V4L2_CTRL_TYPE_MENU: | 60 | case V4L2_CTRL_TYPE_MENU: |
60 | if (old) { | 61 | if (old) { |
62 | uvc_trace(UVC_TRACE_CONTROL, "V4L2_CTRL_TYPE_MENU not " | ||
63 | "supported for UVCIOC_CTRL_MAP_OLD.\n"); | ||
61 | ret = -EINVAL; | 64 | ret = -EINVAL; |
62 | goto done; | 65 | goto done; |
63 | } | 66 | } |
@@ -78,17 +81,17 @@ static int uvc_ioctl_ctrl_map(struct uvc_xu_control_mapping *xmap, int old) | |||
78 | break; | 81 | break; |
79 | 82 | ||
80 | default: | 83 | default: |
84 | uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type " | ||
85 | "%u.\n", xmap->v4l2_type); | ||
81 | ret = -EINVAL; | 86 | ret = -EINVAL; |
82 | goto done; | 87 | goto done; |
83 | } | 88 | } |
84 | 89 | ||
85 | ret = uvc_ctrl_add_mapping(map); | 90 | ret = uvc_ctrl_add_mapping(chain, map); |
86 | 91 | ||
87 | done: | 92 | done: |
88 | if (ret < 0) { | 93 | kfree(map->menu_info); |
89 | kfree(map->menu_info); | 94 | kfree(map); |
90 | kfree(map); | ||
91 | } | ||
92 | 95 | ||
93 | return ret; | 96 | return ret; |
94 | } | 97 | } |
@@ -1021,42 +1024,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1021 | 1024 | ||
1022 | /* Dynamic controls. */ | 1025 | /* Dynamic controls. */ |
1023 | case UVCIOC_CTRL_ADD: | 1026 | case UVCIOC_CTRL_ADD: |
1024 | { | 1027 | /* Legacy ioctl, kept for API compatibility reasons */ |
1025 | struct uvc_xu_control_info *xinfo = arg; | 1028 | return -EEXIST; |
1026 | struct uvc_control_info *info; | ||
1027 | |||
1028 | if (!capable(CAP_SYS_ADMIN)) | ||
1029 | return -EPERM; | ||
1030 | |||
1031 | if (xinfo->size == 0) | ||
1032 | return -EINVAL; | ||
1033 | |||
1034 | info = kzalloc(sizeof *info, GFP_KERNEL); | ||
1035 | if (info == NULL) | ||
1036 | return -ENOMEM; | ||
1037 | |||
1038 | memcpy(info->entity, xinfo->entity, sizeof info->entity); | ||
1039 | info->index = xinfo->index; | ||
1040 | info->selector = xinfo->selector; | ||
1041 | info->size = xinfo->size; | ||
1042 | info->flags = xinfo->flags; | ||
1043 | |||
1044 | info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | | ||
1045 | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | | ||
1046 | UVC_CONTROL_EXTENSION; | ||
1047 | |||
1048 | ret = uvc_ctrl_add_info(info); | ||
1049 | if (ret < 0) | ||
1050 | kfree(info); | ||
1051 | break; | ||
1052 | } | ||
1053 | 1029 | ||
1054 | case UVCIOC_CTRL_MAP_OLD: | 1030 | case UVCIOC_CTRL_MAP_OLD: |
1055 | case UVCIOC_CTRL_MAP: | 1031 | case UVCIOC_CTRL_MAP: |
1056 | if (!capable(CAP_SYS_ADMIN)) | 1032 | return uvc_ioctl_ctrl_map(chain, arg, |
1057 | return -EPERM; | 1033 | cmd == UVCIOC_CTRL_MAP_OLD); |
1058 | |||
1059 | return uvc_ioctl_ctrl_map(arg, cmd == UVCIOC_CTRL_MAP_OLD); | ||
1060 | 1034 | ||
1061 | case UVCIOC_CTRL_GET: | 1035 | case UVCIOC_CTRL_GET: |
1062 | return uvc_xu_ctrl_query(chain, arg, 0); | 1036 | return uvc_xu_ctrl_query(chain, arg, 0); |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index e27cf0d3b6d..5555f010283 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * uvc_video.c -- USB Video Class driver - Video handling | 2 | * uvc_video.c -- USB Video Class driver - Video handling |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2009 | 4 | * Copyright (C) 2005-2010 |
5 | * Laurent Pinchart (laurent.pinchart@skynet.be) | 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License as published by |
@@ -45,6 +45,30 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
45 | unit << 8 | intfnum, data, size, timeout); | 45 | unit << 8 | intfnum, data, size, timeout); |
46 | } | 46 | } |
47 | 47 | ||
48 | static const char *uvc_query_name(__u8 query) | ||
49 | { | ||
50 | switch (query) { | ||
51 | case UVC_SET_CUR: | ||
52 | return "SET_CUR"; | ||
53 | case UVC_GET_CUR: | ||
54 | return "GET_CUR"; | ||
55 | case UVC_GET_MIN: | ||
56 | return "GET_MIN"; | ||
57 | case UVC_GET_MAX: | ||
58 | return "GET_MAX"; | ||
59 | case UVC_GET_RES: | ||
60 | return "GET_RES"; | ||
61 | case UVC_GET_LEN: | ||
62 | return "GET_LEN"; | ||
63 | case UVC_GET_INFO: | ||
64 | return "GET_INFO"; | ||
65 | case UVC_GET_DEF: | ||
66 | return "GET_DEF"; | ||
67 | default: | ||
68 | return "<invalid>"; | ||
69 | } | ||
70 | } | ||
71 | |||
48 | int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 72 | int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, |
49 | __u8 intfnum, __u8 cs, void *data, __u16 size) | 73 | __u8 intfnum, __u8 cs, void *data, __u16 size) |
50 | { | 74 | { |
@@ -53,9 +77,9 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
53 | ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size, | 77 | ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size, |
54 | UVC_CTRL_CONTROL_TIMEOUT); | 78 | UVC_CTRL_CONTROL_TIMEOUT); |
55 | if (ret != size) { | 79 | if (ret != size) { |
56 | uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " | 80 | uvc_printk(KERN_ERR, "Failed to query (%s) UVC control %u on " |
57 | "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, | 81 | "unit %u: %d (exp. %u).\n", uvc_query_name(query), cs, |
58 | size); | 82 | unit, ret, size); |
59 | return -EIO; | 83 | return -EIO; |
60 | } | 84 | } |
61 | 85 | ||
@@ -114,6 +138,15 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, | |||
114 | bandwidth /= 8; | 138 | bandwidth /= 8; |
115 | bandwidth += 12; | 139 | bandwidth += 12; |
116 | 140 | ||
141 | /* The bandwidth estimate is too low for many cameras. Don't use | ||
142 | * maximum packet sizes lower than 1024 bytes to try and work | ||
143 | * around the problem. According to measurements done on two | ||
144 | * different camera models, the value is high enough to get most | ||
145 | * resolutions working while not preventing two simultaneous | ||
146 | * VGA streams at 15 fps. | ||
147 | */ | ||
148 | bandwidth = max_t(u32, bandwidth, 1024); | ||
149 | |||
117 | ctrl->dwMaxPayloadTransferSize = bandwidth; | 150 | ctrl->dwMaxPayloadTransferSize = bandwidth; |
118 | } | 151 | } |
119 | } | 152 | } |
@@ -394,6 +427,12 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
394 | 427 | ||
395 | fid = data[1] & UVC_STREAM_FID; | 428 | fid = data[1] & UVC_STREAM_FID; |
396 | 429 | ||
430 | /* Increase the sequence number regardless of any buffer states, so | ||
431 | * that discontinuous sequence numbers always indicate lost frames. | ||
432 | */ | ||
433 | if (stream->last_fid != fid) | ||
434 | stream->sequence++; | ||
435 | |||
397 | /* Store the payload FID bit and return immediately when the buffer is | 436 | /* Store the payload FID bit and return immediately when the buffer is |
398 | * NULL. | 437 | * NULL. |
399 | */ | 438 | */ |
@@ -427,6 +466,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
427 | else | 466 | else |
428 | ktime_get_real_ts(&ts); | 467 | ktime_get_real_ts(&ts); |
429 | 468 | ||
469 | buf->buf.sequence = stream->sequence; | ||
430 | buf->buf.timestamp.tv_sec = ts.tv_sec; | 470 | buf->buf.timestamp.tv_sec = ts.tv_sec; |
431 | buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; | 471 | buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; |
432 | 472 | ||
@@ -688,6 +728,7 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, | |||
688 | if (buf->buf.bytesused == stream->queue.buf_used) { | 728 | if (buf->buf.bytesused == stream->queue.buf_used) { |
689 | stream->queue.buf_used = 0; | 729 | stream->queue.buf_used = 0; |
690 | buf->state = UVC_BUF_STATE_READY; | 730 | buf->state = UVC_BUF_STATE_READY; |
731 | buf->buf.sequence = ++stream->sequence; | ||
691 | uvc_queue_next_buffer(&stream->queue, buf); | 732 | uvc_queue_next_buffer(&stream->queue, buf); |
692 | stream->last_fid ^= UVC_STREAM_FID; | 733 | stream->last_fid ^= UVC_STREAM_FID; |
693 | } | 734 | } |
@@ -946,6 +987,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
946 | unsigned int i; | 987 | unsigned int i; |
947 | int ret; | 988 | int ret; |
948 | 989 | ||
990 | stream->sequence = -1; | ||
949 | stream->last_fid = -1; | 991 | stream->last_fid = -1; |
950 | stream->bulk.header_size = 0; | 992 | stream->bulk.header_size = 0; |
951 | stream->bulk.skip_payload = 0; | 993 | stream->bulk.skip_payload = 0; |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 892e0e51916..d97cf6d6a4f 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #define UVC_CONTROL_RESTORE (1 << 6) | 27 | #define UVC_CONTROL_RESTORE (1 << 6) |
28 | /* Control can be updated by the camera. */ | 28 | /* Control can be updated by the camera. */ |
29 | #define UVC_CONTROL_AUTO_UPDATE (1 << 7) | 29 | #define UVC_CONTROL_AUTO_UPDATE (1 << 7) |
30 | /* Control is an extension unit control. */ | ||
31 | #define UVC_CONTROL_EXTENSION (1 << 8) | ||
32 | 30 | ||
33 | #define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ | 31 | #define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ |
34 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ | 32 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ |
@@ -159,7 +157,8 @@ struct uvc_xu_control { | |||
159 | * Driver specific constants. | 157 | * Driver specific constants. |
160 | */ | 158 | */ |
161 | 159 | ||
162 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) | 160 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 0, 0) |
161 | #define DRIVER_VERSION "v1.0.0" | ||
163 | 162 | ||
164 | /* Number of isochronous URBs. */ | 163 | /* Number of isochronous URBs. */ |
165 | #define UVC_URBS 5 | 164 | #define UVC_URBS 5 |
@@ -173,6 +172,9 @@ struct uvc_xu_control { | |||
173 | #define UVC_CTRL_CONTROL_TIMEOUT 300 | 172 | #define UVC_CTRL_CONTROL_TIMEOUT 300 |
174 | #define UVC_CTRL_STREAMING_TIMEOUT 5000 | 173 | #define UVC_CTRL_STREAMING_TIMEOUT 5000 |
175 | 174 | ||
175 | /* Maximum allowed number of control mappings per device */ | ||
176 | #define UVC_MAX_CONTROL_MAPPINGS 1024 | ||
177 | |||
176 | /* Devices quirks */ | 178 | /* Devices quirks */ |
177 | #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 | 179 | #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 |
178 | #define UVC_QUIRK_PROBE_MINMAX 0x00000002 | 180 | #define UVC_QUIRK_PROBE_MINMAX 0x00000002 |
@@ -198,11 +200,10 @@ struct uvc_device; | |||
198 | * structures to maximize cache efficiency. | 200 | * structures to maximize cache efficiency. |
199 | */ | 201 | */ |
200 | struct uvc_control_info { | 202 | struct uvc_control_info { |
201 | struct list_head list; | ||
202 | struct list_head mappings; | 203 | struct list_head mappings; |
203 | 204 | ||
204 | __u8 entity[16]; | 205 | __u8 entity[16]; |
205 | __u8 index; | 206 | __u8 index; /* Bit index in bmControls */ |
206 | __u8 selector; | 207 | __u8 selector; |
207 | 208 | ||
208 | __u16 size; | 209 | __u16 size; |
@@ -235,17 +236,17 @@ struct uvc_control_mapping { | |||
235 | 236 | ||
236 | struct uvc_control { | 237 | struct uvc_control { |
237 | struct uvc_entity *entity; | 238 | struct uvc_entity *entity; |
238 | struct uvc_control_info *info; | 239 | struct uvc_control_info info; |
239 | 240 | ||
240 | __u8 index; /* Used to match the uvc_control entry with a | 241 | __u8 index; /* Used to match the uvc_control entry with a |
241 | uvc_control_info. */ | 242 | uvc_control_info. */ |
242 | __u8 dirty : 1, | 243 | __u8 dirty:1, |
243 | loaded : 1, | 244 | loaded:1, |
244 | modified : 1, | 245 | modified:1, |
245 | cached : 1; | 246 | cached:1, |
247 | initialized:1; | ||
246 | 248 | ||
247 | __u8 *uvc_data; | 249 | __u8 *uvc_data; |
248 | __u8 *uvc_info; | ||
249 | }; | 250 | }; |
250 | 251 | ||
251 | struct uvc_format_desc { | 252 | struct uvc_format_desc { |
@@ -392,7 +393,6 @@ struct uvc_video_queue { | |||
392 | 393 | ||
393 | void *mem; | 394 | void *mem; |
394 | unsigned int flags; | 395 | unsigned int flags; |
395 | __u32 sequence; | ||
396 | 396 | ||
397 | unsigned int count; | 397 | unsigned int count; |
398 | unsigned int buf_size; | 398 | unsigned int buf_size; |
@@ -413,7 +413,7 @@ struct uvc_video_chain { | |||
413 | struct uvc_entity *processing; /* Processing unit */ | 413 | struct uvc_entity *processing; /* Processing unit */ |
414 | struct uvc_entity *selector; /* Selector unit */ | 414 | struct uvc_entity *selector; /* Selector unit */ |
415 | 415 | ||
416 | struct mutex ctrl_mutex; | 416 | struct mutex ctrl_mutex; /* Protects ctrl.info */ |
417 | }; | 417 | }; |
418 | 418 | ||
419 | struct uvc_streaming { | 419 | struct uvc_streaming { |
@@ -458,6 +458,7 @@ struct uvc_streaming { | |||
458 | dma_addr_t urb_dma[UVC_URBS]; | 458 | dma_addr_t urb_dma[UVC_URBS]; |
459 | unsigned int urb_size; | 459 | unsigned int urb_size; |
460 | 460 | ||
461 | __u32 sequence; | ||
461 | __u8 last_fid; | 462 | __u8 last_fid; |
462 | }; | 463 | }; |
463 | 464 | ||
@@ -474,8 +475,8 @@ struct uvc_device { | |||
474 | char name[32]; | 475 | char name[32]; |
475 | 476 | ||
476 | enum uvc_device_state state; | 477 | enum uvc_device_state state; |
477 | struct list_head list; | ||
478 | atomic_t users; | 478 | atomic_t users; |
479 | atomic_t nmappings; | ||
479 | 480 | ||
480 | /* Video control interface */ | 481 | /* Video control interface */ |
481 | __u16 uvc_version; | 482 | __u16 uvc_version; |
@@ -509,11 +510,6 @@ struct uvc_fh { | |||
509 | 510 | ||
510 | struct uvc_driver { | 511 | struct uvc_driver { |
511 | struct usb_driver driver; | 512 | struct usb_driver driver; |
512 | |||
513 | struct list_head devices; /* struct uvc_device list */ | ||
514 | struct list_head controls; /* struct uvc_control_info list */ | ||
515 | struct mutex ctrl_mutex; /* protects controls and devices | ||
516 | lists */ | ||
517 | }; | 513 | }; |
518 | 514 | ||
519 | /* ------------------------------------------------------------------------ | 515 | /* ------------------------------------------------------------------------ |
@@ -615,13 +611,11 @@ extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | |||
615 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 611 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
616 | struct v4l2_queryctrl *v4l2_ctrl); | 612 | struct v4l2_queryctrl *v4l2_ctrl); |
617 | 613 | ||
618 | extern int uvc_ctrl_add_info(struct uvc_control_info *info); | 614 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
619 | extern int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping); | 615 | const struct uvc_control_mapping *mapping); |
620 | extern int uvc_ctrl_init_device(struct uvc_device *dev); | 616 | extern int uvc_ctrl_init_device(struct uvc_device *dev); |
621 | extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); | 617 | extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); |
622 | extern int uvc_ctrl_resume_device(struct uvc_device *dev); | 618 | extern int uvc_ctrl_resume_device(struct uvc_device *dev); |
623 | extern void uvc_ctrl_init(void); | ||
624 | extern void uvc_ctrl_cleanup(void); | ||
625 | 619 | ||
626 | extern int uvc_ctrl_begin(struct uvc_video_chain *chain); | 620 | extern int uvc_ctrl_begin(struct uvc_video_chain *chain); |
627 | extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback); | 621 | extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback); |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index 0c2105ca611..d4ac751036a 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -645,9 +645,16 @@ static noinline long v4l1_compat_get_picture( | |||
645 | goto done; | 645 | goto done; |
646 | } | 646 | } |
647 | 647 | ||
648 | pict->depth = ((fmt->fmt.pix.bytesperline << 3) | 648 | if (fmt->fmt.pix.width) |
649 | + (fmt->fmt.pix.width - 1)) | 649 | { |
650 | / fmt->fmt.pix.width; | 650 | pict->depth = ((fmt->fmt.pix.bytesperline << 3) |
651 | + (fmt->fmt.pix.width - 1)) | ||
652 | / fmt->fmt.pix.width; | ||
653 | } else { | ||
654 | err = -EINVAL; | ||
655 | goto done; | ||
656 | } | ||
657 | |||
651 | pict->palette = pixelformat_to_palette( | 658 | pict->palette = pixelformat_to_palette( |
652 | fmt->fmt.pix.pixelformat); | 659 | fmt->fmt.pix.pixelformat); |
653 | done: | 660 | done: |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 8ee1179be92..9294282b5ad 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -378,6 +378,8 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, | |||
378 | 378 | ||
379 | if (module_name) | 379 | if (module_name) |
380 | request_module(module_name); | 380 | request_module(module_name); |
381 | else | ||
382 | request_module(I2C_MODULE_PREFIX "%s", info->type); | ||
381 | 383 | ||
382 | /* Create the i2c client */ | 384 | /* Create the i2c client */ |
383 | if (info->addr == 0 && probe_addrs) | 385 | if (info->addr == 0 && probe_addrs) |
@@ -676,3 +678,28 @@ int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info) | |||
676 | return 0; | 678 | return 0; |
677 | } | 679 | } |
678 | EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info); | 680 | EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info); |
681 | |||
682 | const struct v4l2_frmsize_discrete *v4l2_find_nearest_format( | ||
683 | const struct v4l2_discrete_probe *probe, | ||
684 | s32 width, s32 height) | ||
685 | { | ||
686 | int i; | ||
687 | u32 error, min_error = UINT_MAX; | ||
688 | const struct v4l2_frmsize_discrete *size, *best = NULL; | ||
689 | |||
690 | if (!probe) | ||
691 | return best; | ||
692 | |||
693 | for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) { | ||
694 | error = abs(size->width - width) + abs(size->height - height); | ||
695 | if (error < min_error) { | ||
696 | min_error = error; | ||
697 | best = size; | ||
698 | } | ||
699 | if (!error) | ||
700 | break; | ||
701 | } | ||
702 | |||
703 | return best; | ||
704 | } | ||
705 | EXPORT_SYMBOL_GPL(v4l2_find_nearest_format); | ||
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index ea8d32cd425..9d2502cd03f 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c | |||
@@ -305,6 +305,8 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
305 | case V4L2_CID_ROTATE: return "Rotate"; | 305 | case V4L2_CID_ROTATE: return "Rotate"; |
306 | case V4L2_CID_BG_COLOR: return "Background Color"; | 306 | case V4L2_CID_BG_COLOR: return "Background Color"; |
307 | case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; | 307 | case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; |
308 | case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; | ||
309 | case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; | ||
308 | 310 | ||
309 | /* MPEG controls */ | 311 | /* MPEG controls */ |
310 | /* Keep the order of the 'case's the same as in videodev2.h! */ | 312 | /* Keep the order of the 'case's the same as in videodev2.h! */ |
@@ -419,6 +421,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, | |||
419 | case V4L2_CID_AUDIO_LIMITER_ENABLED: | 421 | case V4L2_CID_AUDIO_LIMITER_ENABLED: |
420 | case V4L2_CID_AUDIO_COMPRESSION_ENABLED: | 422 | case V4L2_CID_AUDIO_COMPRESSION_ENABLED: |
421 | case V4L2_CID_PILOT_TONE_ENABLED: | 423 | case V4L2_CID_PILOT_TONE_ENABLED: |
424 | case V4L2_CID_ILLUMINATORS_1: | ||
425 | case V4L2_CID_ILLUMINATORS_2: | ||
422 | *type = V4L2_CTRL_TYPE_BOOLEAN; | 426 | *type = V4L2_CTRL_TYPE_BOOLEAN; |
423 | *min = 0; | 427 | *min = 0; |
424 | *max = *step = 1; | 428 | *max = *step = 1; |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index cb77197d480..0ca7978654b 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -81,7 +81,7 @@ static inline unsigned long *devnode_bits(int vfl_type) | |||
81 | /* Any types not assigned to fixed minor ranges must be mapped to | 81 | /* Any types not assigned to fixed minor ranges must be mapped to |
82 | one single bitmap for the purposes of finding a free node number | 82 | one single bitmap for the purposes of finding a free node number |
83 | since all those unassigned types use the same minor range. */ | 83 | since all those unassigned types use the same minor range. */ |
84 | int idx = (vfl_type > VFL_TYPE_VTX) ? VFL_TYPE_MAX - 1 : vfl_type; | 84 | int idx = (vfl_type > VFL_TYPE_RADIO) ? VFL_TYPE_MAX - 1 : vfl_type; |
85 | 85 | ||
86 | return devnode_nums[idx]; | 86 | return devnode_nums[idx]; |
87 | } | 87 | } |
@@ -187,48 +187,69 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
187 | size_t sz, loff_t *off) | 187 | size_t sz, loff_t *off) |
188 | { | 188 | { |
189 | struct video_device *vdev = video_devdata(filp); | 189 | struct video_device *vdev = video_devdata(filp); |
190 | int ret = -EIO; | ||
190 | 191 | ||
191 | if (!vdev->fops->read) | 192 | if (!vdev->fops->read) |
192 | return -EINVAL; | 193 | return -EINVAL; |
193 | if (!video_is_registered(vdev)) | 194 | if (vdev->lock) |
194 | return -EIO; | 195 | mutex_lock(vdev->lock); |
195 | return vdev->fops->read(filp, buf, sz, off); | 196 | if (video_is_registered(vdev)) |
197 | ret = vdev->fops->read(filp, buf, sz, off); | ||
198 | if (vdev->lock) | ||
199 | mutex_unlock(vdev->lock); | ||
200 | return ret; | ||
196 | } | 201 | } |
197 | 202 | ||
198 | static ssize_t v4l2_write(struct file *filp, const char __user *buf, | 203 | static ssize_t v4l2_write(struct file *filp, const char __user *buf, |
199 | size_t sz, loff_t *off) | 204 | size_t sz, loff_t *off) |
200 | { | 205 | { |
201 | struct video_device *vdev = video_devdata(filp); | 206 | struct video_device *vdev = video_devdata(filp); |
207 | int ret = -EIO; | ||
202 | 208 | ||
203 | if (!vdev->fops->write) | 209 | if (!vdev->fops->write) |
204 | return -EINVAL; | 210 | return -EINVAL; |
205 | if (!video_is_registered(vdev)) | 211 | if (vdev->lock) |
206 | return -EIO; | 212 | mutex_lock(vdev->lock); |
207 | return vdev->fops->write(filp, buf, sz, off); | 213 | if (video_is_registered(vdev)) |
214 | ret = vdev->fops->write(filp, buf, sz, off); | ||
215 | if (vdev->lock) | ||
216 | mutex_unlock(vdev->lock); | ||
217 | return ret; | ||
208 | } | 218 | } |
209 | 219 | ||
210 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | 220 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) |
211 | { | 221 | { |
212 | struct video_device *vdev = video_devdata(filp); | 222 | struct video_device *vdev = video_devdata(filp); |
223 | int ret = DEFAULT_POLLMASK; | ||
213 | 224 | ||
214 | if (!vdev->fops->poll || !video_is_registered(vdev)) | 225 | if (!vdev->fops->poll) |
215 | return DEFAULT_POLLMASK; | 226 | return ret; |
216 | return vdev->fops->poll(filp, poll); | 227 | if (vdev->lock) |
228 | mutex_lock(vdev->lock); | ||
229 | if (video_is_registered(vdev)) | ||
230 | ret = vdev->fops->poll(filp, poll); | ||
231 | if (vdev->lock) | ||
232 | mutex_unlock(vdev->lock); | ||
233 | return ret; | ||
217 | } | 234 | } |
218 | 235 | ||
219 | static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 236 | static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
220 | { | 237 | { |
221 | struct video_device *vdev = video_devdata(filp); | 238 | struct video_device *vdev = video_devdata(filp); |
222 | int ret; | 239 | int ret = -ENODEV; |
223 | 240 | ||
224 | /* Allow ioctl to continue even if the device was unregistered. | ||
225 | Things like dequeueing buffers might still be useful. */ | ||
226 | if (vdev->fops->unlocked_ioctl) { | 241 | if (vdev->fops->unlocked_ioctl) { |
227 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 242 | if (vdev->lock) |
243 | mutex_lock(vdev->lock); | ||
244 | if (video_is_registered(vdev)) | ||
245 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | ||
246 | if (vdev->lock) | ||
247 | mutex_unlock(vdev->lock); | ||
228 | } else if (vdev->fops->ioctl) { | 248 | } else if (vdev->fops->ioctl) { |
229 | /* TODO: convert all drivers to unlocked_ioctl */ | 249 | /* TODO: convert all drivers to unlocked_ioctl */ |
230 | lock_kernel(); | 250 | lock_kernel(); |
231 | ret = vdev->fops->ioctl(filp, cmd, arg); | 251 | if (video_is_registered(vdev)) |
252 | ret = vdev->fops->ioctl(filp, cmd, arg); | ||
232 | unlock_kernel(); | 253 | unlock_kernel(); |
233 | } else | 254 | } else |
234 | ret = -ENOTTY; | 255 | ret = -ENOTTY; |
@@ -236,30 +257,20 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
236 | return ret; | 257 | return ret; |
237 | } | 258 | } |
238 | 259 | ||
239 | #ifdef CONFIG_MMU | ||
240 | #define v4l2_get_unmapped_area NULL | ||
241 | #else | ||
242 | static unsigned long v4l2_get_unmapped_area(struct file *filp, | ||
243 | unsigned long addr, unsigned long len, unsigned long pgoff, | ||
244 | unsigned long flags) | ||
245 | { | ||
246 | struct video_device *vdev = video_devdata(filp); | ||
247 | |||
248 | if (!vdev->fops->get_unmapped_area) | ||
249 | return -ENOSYS; | ||
250 | if (!video_is_registered(vdev)) | ||
251 | return -ENODEV; | ||
252 | return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); | ||
253 | } | ||
254 | #endif | ||
255 | |||
256 | static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | 260 | static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) |
257 | { | 261 | { |
258 | struct video_device *vdev = video_devdata(filp); | 262 | struct video_device *vdev = video_devdata(filp); |
263 | int ret = -ENODEV; | ||
259 | 264 | ||
260 | if (!vdev->fops->mmap || !video_is_registered(vdev)) | 265 | if (!vdev->fops->mmap) |
261 | return -ENODEV; | 266 | return ret; |
262 | return vdev->fops->mmap(filp, vm); | 267 | if (vdev->lock) |
268 | mutex_lock(vdev->lock); | ||
269 | if (video_is_registered(vdev)) | ||
270 | ret = vdev->fops->mmap(filp, vm); | ||
271 | if (vdev->lock) | ||
272 | mutex_unlock(vdev->lock); | ||
273 | return ret; | ||
263 | } | 274 | } |
264 | 275 | ||
265 | /* Override for the open function */ | 276 | /* Override for the open function */ |
@@ -271,17 +282,24 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
271 | /* Check if the video device is available */ | 282 | /* Check if the video device is available */ |
272 | mutex_lock(&videodev_lock); | 283 | mutex_lock(&videodev_lock); |
273 | vdev = video_devdata(filp); | 284 | vdev = video_devdata(filp); |
274 | /* return ENODEV if the video device has been removed | 285 | /* return ENODEV if the video device has already been removed. */ |
275 | already or if it is not registered anymore. */ | 286 | if (vdev == NULL) { |
276 | if (vdev == NULL || !video_is_registered(vdev)) { | ||
277 | mutex_unlock(&videodev_lock); | 287 | mutex_unlock(&videodev_lock); |
278 | return -ENODEV; | 288 | return -ENODEV; |
279 | } | 289 | } |
280 | /* and increase the device refcount */ | 290 | /* and increase the device refcount */ |
281 | video_get(vdev); | 291 | video_get(vdev); |
282 | mutex_unlock(&videodev_lock); | 292 | mutex_unlock(&videodev_lock); |
283 | if (vdev->fops->open) | 293 | if (vdev->fops->open) { |
284 | ret = vdev->fops->open(filp); | 294 | if (vdev->lock) |
295 | mutex_lock(vdev->lock); | ||
296 | if (video_is_registered(vdev)) | ||
297 | ret = vdev->fops->open(filp); | ||
298 | else | ||
299 | ret = -ENODEV; | ||
300 | if (vdev->lock) | ||
301 | mutex_unlock(vdev->lock); | ||
302 | } | ||
285 | 303 | ||
286 | /* decrease the refcount in case of an error */ | 304 | /* decrease the refcount in case of an error */ |
287 | if (ret) | 305 | if (ret) |
@@ -295,8 +313,13 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
295 | struct video_device *vdev = video_devdata(filp); | 313 | struct video_device *vdev = video_devdata(filp); |
296 | int ret = 0; | 314 | int ret = 0; |
297 | 315 | ||
298 | if (vdev->fops->release) | 316 | if (vdev->fops->release) { |
317 | if (vdev->lock) | ||
318 | mutex_lock(vdev->lock); | ||
299 | vdev->fops->release(filp); | 319 | vdev->fops->release(filp); |
320 | if (vdev->lock) | ||
321 | mutex_unlock(vdev->lock); | ||
322 | } | ||
300 | 323 | ||
301 | /* decrease the refcount unconditionally since the release() | 324 | /* decrease the refcount unconditionally since the release() |
302 | return value is ignored. */ | 325 | return value is ignored. */ |
@@ -309,7 +332,6 @@ static const struct file_operations v4l2_fops = { | |||
309 | .read = v4l2_read, | 332 | .read = v4l2_read, |
310 | .write = v4l2_write, | 333 | .write = v4l2_write, |
311 | .open = v4l2_open, | 334 | .open = v4l2_open, |
312 | .get_unmapped_area = v4l2_get_unmapped_area, | ||
313 | .mmap = v4l2_mmap, | 335 | .mmap = v4l2_mmap, |
314 | .unlocked_ioctl = v4l2_ioctl, | 336 | .unlocked_ioctl = v4l2_ioctl, |
315 | #ifdef CONFIG_COMPAT | 337 | #ifdef CONFIG_COMPAT |
@@ -377,8 +399,6 @@ static int get_index(struct video_device *vdev) | |||
377 | * | 399 | * |
378 | * %VFL_TYPE_GRABBER - A frame grabber | 400 | * %VFL_TYPE_GRABBER - A frame grabber |
379 | * | 401 | * |
380 | * %VFL_TYPE_VTX - A teletext device | ||
381 | * | ||
382 | * %VFL_TYPE_VBI - Vertical blank data (undecoded) | 402 | * %VFL_TYPE_VBI - Vertical blank data (undecoded) |
383 | * | 403 | * |
384 | * %VFL_TYPE_RADIO - A radio card | 404 | * %VFL_TYPE_RADIO - A radio card |
@@ -411,9 +431,6 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, | |||
411 | case VFL_TYPE_GRABBER: | 431 | case VFL_TYPE_GRABBER: |
412 | name_base = "video"; | 432 | name_base = "video"; |
413 | break; | 433 | break; |
414 | case VFL_TYPE_VTX: | ||
415 | name_base = "vtx"; | ||
416 | break; | ||
417 | case VFL_TYPE_VBI: | 434 | case VFL_TYPE_VBI: |
418 | name_base = "vbi"; | 435 | name_base = "vbi"; |
419 | break; | 436 | break; |
@@ -451,10 +468,6 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, | |||
451 | minor_offset = 64; | 468 | minor_offset = 64; |
452 | minor_cnt = 64; | 469 | minor_cnt = 64; |
453 | break; | 470 | break; |
454 | case VFL_TYPE_VTX: | ||
455 | minor_offset = 192; | ||
456 | minor_cnt = 32; | ||
457 | break; | ||
458 | case VFL_TYPE_VBI: | 471 | case VFL_TYPE_VBI: |
459 | minor_offset = 224; | 472 | minor_offset = 224; |
460 | minor_cnt = 32; | 473 | minor_cnt = 32; |
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index de74ce07b5e..69fd343d477 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c | |||
@@ -134,15 +134,22 @@ int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event, | |||
134 | if (nonblocking) | 134 | if (nonblocking) |
135 | return __v4l2_event_dequeue(fh, event); | 135 | return __v4l2_event_dequeue(fh, event); |
136 | 136 | ||
137 | /* Release the vdev lock while waiting */ | ||
138 | if (fh->vdev->lock) | ||
139 | mutex_unlock(fh->vdev->lock); | ||
140 | |||
137 | do { | 141 | do { |
138 | ret = wait_event_interruptible(events->wait, | 142 | ret = wait_event_interruptible(events->wait, |
139 | events->navailable != 0); | 143 | events->navailable != 0); |
140 | if (ret < 0) | 144 | if (ret < 0) |
141 | return ret; | 145 | break; |
142 | 146 | ||
143 | ret = __v4l2_event_dequeue(fh, event); | 147 | ret = __v4l2_event_dequeue(fh, event); |
144 | } while (ret == -ENOENT); | 148 | } while (ret == -ENOENT); |
145 | 149 | ||
150 | if (fh->vdev->lock) | ||
151 | mutex_lock(fh->vdev->lock); | ||
152 | |||
146 | return ret; | 153 | return ret; |
147 | } | 154 | } |
148 | EXPORT_SYMBOL_GPL(v4l2_event_dequeue); | 155 | EXPORT_SYMBOL_GPL(v4l2_event_dequeue); |
diff --git a/drivers/media/video/v4l2-mem2mem.c b/drivers/media/video/v4l2-mem2mem.c index f45f9405ea3..ac832a28e18 100644 --- a/drivers/media/video/v4l2-mem2mem.c +++ b/drivers/media/video/v4l2-mem2mem.c | |||
@@ -421,8 +421,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | |||
421 | src_q = v4l2_m2m_get_src_vq(m2m_ctx); | 421 | src_q = v4l2_m2m_get_src_vq(m2m_ctx); |
422 | dst_q = v4l2_m2m_get_dst_vq(m2m_ctx); | 422 | dst_q = v4l2_m2m_get_dst_vq(m2m_ctx); |
423 | 423 | ||
424 | mutex_lock(&src_q->vb_lock); | 424 | videobuf_queue_lock(src_q); |
425 | mutex_lock(&dst_q->vb_lock); | 425 | videobuf_queue_lock(dst_q); |
426 | 426 | ||
427 | if (src_q->streaming && !list_empty(&src_q->stream)) | 427 | if (src_q->streaming && !list_empty(&src_q->stream)) |
428 | src_vb = list_first_entry(&src_q->stream, | 428 | src_vb = list_first_entry(&src_q->stream, |
@@ -450,8 +450,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | |||
450 | } | 450 | } |
451 | 451 | ||
452 | end: | 452 | end: |
453 | mutex_unlock(&dst_q->vb_lock); | 453 | videobuf_queue_unlock(dst_q); |
454 | mutex_unlock(&src_q->vb_lock); | 454 | videobuf_queue_unlock(src_q); |
455 | return rc; | 455 | return rc; |
456 | } | 456 | } |
457 | EXPORT_SYMBOL_GPL(v4l2_m2m_poll); | 457 | EXPORT_SYMBOL_GPL(v4l2_m2m_poll); |
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c new file mode 100644 index 00000000000..02a21bccae1 --- /dev/null +++ b/drivers/media/video/via-camera.c | |||
@@ -0,0 +1,1474 @@ | |||
1 | /* | ||
2 | * Driver for the VIA Chrome integrated camera controller. | ||
3 | * | ||
4 | * Copyright 2009,2010 Jonathan Corbet <corbet@lwn.net> | ||
5 | * Distributable under the terms of the GNU General Public License, version 2 | ||
6 | * | ||
7 | * This work was supported by the One Laptop Per Child project | ||
8 | */ | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/list.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/videodev2.h> | ||
19 | #include <media/v4l2-device.h> | ||
20 | #include <media/v4l2-ioctl.h> | ||
21 | #include <media/v4l2-chip-ident.h> | ||
22 | #include <media/videobuf-dma-sg.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | #include <linux/pm_qos_params.h> | ||
27 | #include <linux/via-core.h> | ||
28 | #include <linux/via-gpio.h> | ||
29 | #include <linux/via_i2c.h> | ||
30 | |||
31 | #include "via-camera.h" | ||
32 | |||
33 | MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); | ||
34 | MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | static int flip_image; | ||
38 | module_param(flip_image, bool, 0444); | ||
39 | MODULE_PARM_DESC(flip_image, | ||
40 | "If set, the sensor will be instructed to flip the image " | ||
41 | "vertically."); | ||
42 | |||
43 | #ifdef CONFIG_OLPC_XO_1_5 | ||
44 | static int override_serial; | ||
45 | module_param(override_serial, bool, 0444); | ||
46 | MODULE_PARM_DESC(override_serial, | ||
47 | "The camera driver will normally refuse to load if " | ||
48 | "the XO 1.5 serial port is enabled. Set this option " | ||
49 | "to force the issue."); | ||
50 | #endif | ||
51 | |||
52 | /* | ||
53 | * Basic window sizes. | ||
54 | */ | ||
55 | #define VGA_WIDTH 640 | ||
56 | #define VGA_HEIGHT 480 | ||
57 | #define QCIF_WIDTH 176 | ||
58 | #define QCIF_HEIGHT 144 | ||
59 | |||
60 | /* | ||
61 | * The structure describing our camera. | ||
62 | */ | ||
63 | enum viacam_opstate { S_IDLE = 0, S_RUNNING = 1 }; | ||
64 | |||
65 | struct via_camera { | ||
66 | struct v4l2_device v4l2_dev; | ||
67 | struct video_device vdev; | ||
68 | struct v4l2_subdev *sensor; | ||
69 | struct platform_device *platdev; | ||
70 | struct viafb_dev *viadev; | ||
71 | struct mutex lock; | ||
72 | enum viacam_opstate opstate; | ||
73 | unsigned long flags; | ||
74 | struct pm_qos_request_list qos_request; | ||
75 | /* | ||
76 | * GPIO info for power/reset management | ||
77 | */ | ||
78 | int power_gpio; | ||
79 | int reset_gpio; | ||
80 | /* | ||
81 | * I/O memory stuff. | ||
82 | */ | ||
83 | void __iomem *mmio; /* Where the registers live */ | ||
84 | void __iomem *fbmem; /* Frame buffer memory */ | ||
85 | u32 fb_offset; /* Reserved memory offset (FB) */ | ||
86 | /* | ||
87 | * Capture buffers and related. The controller supports | ||
88 | * up to three, so that's what we have here. These buffers | ||
89 | * live in frame buffer memory, so we don't call them "DMA". | ||
90 | */ | ||
91 | unsigned int cb_offsets[3]; /* offsets into fb mem */ | ||
92 | u8 *cb_addrs[3]; /* Kernel-space addresses */ | ||
93 | int n_cap_bufs; /* How many are we using? */ | ||
94 | int next_buf; | ||
95 | struct videobuf_queue vb_queue; | ||
96 | struct list_head buffer_queue; /* prot. by reg_lock */ | ||
97 | /* | ||
98 | * User tracking. | ||
99 | */ | ||
100 | int users; | ||
101 | struct file *owner; | ||
102 | /* | ||
103 | * Video format information. sensor_format is kept in a form | ||
104 | * that we can use to pass to the sensor. We always run the | ||
105 | * sensor in VGA resolution, though, and let the controller | ||
106 | * downscale things if need be. So we keep the "real* | ||
107 | * dimensions separately. | ||
108 | */ | ||
109 | struct v4l2_pix_format sensor_format; | ||
110 | struct v4l2_pix_format user_format; | ||
111 | enum v4l2_mbus_pixelcode mbus_code; | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Yes, this is a hack, but there's only going to be one of these | ||
116 | * on any system we know of. | ||
117 | */ | ||
118 | static struct via_camera *via_cam_info; | ||
119 | |||
120 | /* | ||
121 | * Flag values, manipulated with bitops | ||
122 | */ | ||
123 | #define CF_DMA_ACTIVE 0 /* A frame is incoming */ | ||
124 | #define CF_CONFIG_NEEDED 1 /* Must configure hardware */ | ||
125 | |||
126 | |||
127 | /* | ||
128 | * Nasty ugly v4l2 boilerplate. | ||
129 | */ | ||
130 | #define sensor_call(cam, optype, func, args...) \ | ||
131 | v4l2_subdev_call(cam->sensor, optype, func, ##args) | ||
132 | |||
133 | /* | ||
134 | * Debugging and related. | ||
135 | */ | ||
136 | #define cam_err(cam, fmt, arg...) \ | ||
137 | dev_err(&(cam)->platdev->dev, fmt, ##arg); | ||
138 | #define cam_warn(cam, fmt, arg...) \ | ||
139 | dev_warn(&(cam)->platdev->dev, fmt, ##arg); | ||
140 | #define cam_dbg(cam, fmt, arg...) \ | ||
141 | dev_dbg(&(cam)->platdev->dev, fmt, ##arg); | ||
142 | |||
143 | /* | ||
144 | * Format handling. This is ripped almost directly from Hans's changes | ||
145 | * to cafe_ccic.c. It's a little unfortunate; until this change, we | ||
146 | * didn't need to know anything about the format except its byte depth; | ||
147 | * now this information must be managed at this level too. | ||
148 | */ | ||
149 | static struct via_format { | ||
150 | __u8 *desc; | ||
151 | __u32 pixelformat; | ||
152 | int bpp; /* Bytes per pixel */ | ||
153 | enum v4l2_mbus_pixelcode mbus_code; | ||
154 | } via_formats[] = { | ||
155 | { | ||
156 | .desc = "YUYV 4:2:2", | ||
157 | .pixelformat = V4L2_PIX_FMT_YUYV, | ||
158 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, | ||
159 | .bpp = 2, | ||
160 | }, | ||
161 | { | ||
162 | .desc = "RGB 565", | ||
163 | .pixelformat = V4L2_PIX_FMT_RGB565, | ||
164 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
165 | .bpp = 2, | ||
166 | }, | ||
167 | /* RGB444 and Bayer should be doable, but have never been | ||
168 | tested with this driver. */ | ||
169 | }; | ||
170 | #define N_VIA_FMTS ARRAY_SIZE(via_formats) | ||
171 | |||
172 | static struct via_format *via_find_format(u32 pixelformat) | ||
173 | { | ||
174 | unsigned i; | ||
175 | |||
176 | for (i = 0; i < N_VIA_FMTS; i++) | ||
177 | if (via_formats[i].pixelformat == pixelformat) | ||
178 | return via_formats + i; | ||
179 | /* Not found? Then return the first format. */ | ||
180 | return via_formats; | ||
181 | } | ||
182 | |||
183 | |||
184 | /*--------------------------------------------------------------------------*/ | ||
185 | /* | ||
186 | * Sensor power/reset management. This piece is OLPC-specific for | ||
187 | * sure; other configurations will have things connected differently. | ||
188 | */ | ||
189 | static int via_sensor_power_setup(struct via_camera *cam) | ||
190 | { | ||
191 | int ret; | ||
192 | |||
193 | cam->power_gpio = viafb_gpio_lookup("VGPIO3"); | ||
194 | cam->reset_gpio = viafb_gpio_lookup("VGPIO2"); | ||
195 | if (cam->power_gpio < 0 || cam->reset_gpio < 0) { | ||
196 | dev_err(&cam->platdev->dev, "Unable to find GPIO lines\n"); | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | ret = gpio_request(cam->power_gpio, "viafb-camera"); | ||
200 | if (ret) { | ||
201 | dev_err(&cam->platdev->dev, "Unable to request power GPIO\n"); | ||
202 | return ret; | ||
203 | } | ||
204 | ret = gpio_request(cam->reset_gpio, "viafb-camera"); | ||
205 | if (ret) { | ||
206 | dev_err(&cam->platdev->dev, "Unable to request reset GPIO\n"); | ||
207 | gpio_free(cam->power_gpio); | ||
208 | return ret; | ||
209 | } | ||
210 | gpio_direction_output(cam->power_gpio, 0); | ||
211 | gpio_direction_output(cam->reset_gpio, 0); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * Power up the sensor and perform the reset dance. | ||
217 | */ | ||
218 | static void via_sensor_power_up(struct via_camera *cam) | ||
219 | { | ||
220 | gpio_set_value(cam->power_gpio, 1); | ||
221 | gpio_set_value(cam->reset_gpio, 0); | ||
222 | msleep(20); /* Probably excessive */ | ||
223 | gpio_set_value(cam->reset_gpio, 1); | ||
224 | msleep(20); | ||
225 | } | ||
226 | |||
227 | static void via_sensor_power_down(struct via_camera *cam) | ||
228 | { | ||
229 | gpio_set_value(cam->power_gpio, 0); | ||
230 | gpio_set_value(cam->reset_gpio, 0); | ||
231 | } | ||
232 | |||
233 | |||
234 | static void via_sensor_power_release(struct via_camera *cam) | ||
235 | { | ||
236 | via_sensor_power_down(cam); | ||
237 | gpio_free(cam->power_gpio); | ||
238 | gpio_free(cam->reset_gpio); | ||
239 | } | ||
240 | |||
241 | /* --------------------------------------------------------------------------*/ | ||
242 | /* Sensor ops */ | ||
243 | |||
244 | /* | ||
245 | * Manage the ov7670 "flip" bit, which needs special help. | ||
246 | */ | ||
247 | static int viacam_set_flip(struct via_camera *cam) | ||
248 | { | ||
249 | struct v4l2_control ctrl; | ||
250 | |||
251 | memset(&ctrl, 0, sizeof(ctrl)); | ||
252 | ctrl.id = V4L2_CID_VFLIP; | ||
253 | ctrl.value = flip_image; | ||
254 | return sensor_call(cam, core, s_ctrl, &ctrl); | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Configure the sensor. It's up to the caller to ensure | ||
259 | * that the camera is in the correct operating state. | ||
260 | */ | ||
261 | static int viacam_configure_sensor(struct via_camera *cam) | ||
262 | { | ||
263 | struct v4l2_mbus_framefmt mbus_fmt; | ||
264 | int ret; | ||
265 | |||
266 | v4l2_fill_mbus_format(&mbus_fmt, &cam->sensor_format, cam->mbus_code); | ||
267 | ret = sensor_call(cam, core, init, 0); | ||
268 | if (ret == 0) | ||
269 | ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt); | ||
270 | /* | ||
271 | * OV7670 does weird things if flip is set *before* format... | ||
272 | */ | ||
273 | if (ret == 0) | ||
274 | ret = viacam_set_flip(cam); | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | |||
279 | |||
280 | /* --------------------------------------------------------------------------*/ | ||
281 | /* | ||
282 | * Some simple register accessors; they assume that the lock is held. | ||
283 | * | ||
284 | * Should we want to support the second capture engine, we could | ||
285 | * hide the register difference by adding 0x1000 to registers in the | ||
286 | * 0x300-350 range. | ||
287 | */ | ||
288 | static inline void viacam_write_reg(struct via_camera *cam, | ||
289 | int reg, int value) | ||
290 | { | ||
291 | iowrite32(value, cam->mmio + reg); | ||
292 | } | ||
293 | |||
294 | static inline int viacam_read_reg(struct via_camera *cam, int reg) | ||
295 | { | ||
296 | return ioread32(cam->mmio + reg); | ||
297 | } | ||
298 | |||
299 | static inline void viacam_write_reg_mask(struct via_camera *cam, | ||
300 | int reg, int value, int mask) | ||
301 | { | ||
302 | int tmp = viacam_read_reg(cam, reg); | ||
303 | |||
304 | tmp = (tmp & ~mask) | (value & mask); | ||
305 | viacam_write_reg(cam, reg, tmp); | ||
306 | } | ||
307 | |||
308 | |||
309 | /* --------------------------------------------------------------------------*/ | ||
310 | /* Interrupt management and handling */ | ||
311 | |||
312 | static irqreturn_t viacam_quick_irq(int irq, void *data) | ||
313 | { | ||
314 | struct via_camera *cam = data; | ||
315 | irqreturn_t ret = IRQ_NONE; | ||
316 | int icv; | ||
317 | |||
318 | /* | ||
319 | * All we do here is to clear the interrupts and tell | ||
320 | * the handler thread to wake up. | ||
321 | */ | ||
322 | spin_lock(&cam->viadev->reg_lock); | ||
323 | icv = viacam_read_reg(cam, VCR_INTCTRL); | ||
324 | if (icv & VCR_IC_EAV) { | ||
325 | icv |= VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL; | ||
326 | viacam_write_reg(cam, VCR_INTCTRL, icv); | ||
327 | ret = IRQ_WAKE_THREAD; | ||
328 | } | ||
329 | spin_unlock(&cam->viadev->reg_lock); | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * Find the next videobuf buffer which has somebody waiting on it. | ||
335 | */ | ||
336 | static struct videobuf_buffer *viacam_next_buffer(struct via_camera *cam) | ||
337 | { | ||
338 | unsigned long flags; | ||
339 | struct videobuf_buffer *buf = NULL; | ||
340 | |||
341 | spin_lock_irqsave(&cam->viadev->reg_lock, flags); | ||
342 | if (cam->opstate != S_RUNNING) | ||
343 | goto out; | ||
344 | if (list_empty(&cam->buffer_queue)) | ||
345 | goto out; | ||
346 | buf = list_entry(cam->buffer_queue.next, struct videobuf_buffer, queue); | ||
347 | if (!waitqueue_active(&buf->done)) {/* Nobody waiting */ | ||
348 | buf = NULL; | ||
349 | goto out; | ||
350 | } | ||
351 | list_del(&buf->queue); | ||
352 | buf->state = VIDEOBUF_ACTIVE; | ||
353 | out: | ||
354 | spin_unlock_irqrestore(&cam->viadev->reg_lock, flags); | ||
355 | return buf; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * The threaded IRQ handler. | ||
360 | */ | ||
361 | static irqreturn_t viacam_irq(int irq, void *data) | ||
362 | { | ||
363 | int bufn; | ||
364 | struct videobuf_buffer *vb; | ||
365 | struct via_camera *cam = data; | ||
366 | struct videobuf_dmabuf *vdma; | ||
367 | |||
368 | /* | ||
369 | * If there is no place to put the data frame, don't bother | ||
370 | * with anything else. | ||
371 | */ | ||
372 | vb = viacam_next_buffer(cam); | ||
373 | if (vb == NULL) | ||
374 | goto done; | ||
375 | /* | ||
376 | * Figure out which buffer we just completed. | ||
377 | */ | ||
378 | bufn = (viacam_read_reg(cam, VCR_INTCTRL) & VCR_IC_ACTBUF) >> 3; | ||
379 | bufn -= 1; | ||
380 | if (bufn < 0) | ||
381 | bufn = cam->n_cap_bufs - 1; | ||
382 | /* | ||
383 | * Copy over the data and let any waiters know. | ||
384 | */ | ||
385 | vdma = videobuf_to_dma(vb); | ||
386 | viafb_dma_copy_out_sg(cam->cb_offsets[bufn], vdma->sglist, vdma->sglen); | ||
387 | vb->state = VIDEOBUF_DONE; | ||
388 | vb->size = cam->user_format.sizeimage; | ||
389 | wake_up(&vb->done); | ||
390 | done: | ||
391 | return IRQ_HANDLED; | ||
392 | } | ||
393 | |||
394 | |||
395 | /* | ||
396 | * These functions must mess around with the general interrupt | ||
397 | * control register, which is relevant to much more than just the | ||
398 | * camera. Nothing else uses interrupts, though, as of this writing. | ||
399 | * Should that situation change, we'll have to improve support at | ||
400 | * the via-core level. | ||
401 | */ | ||
402 | static void viacam_int_enable(struct via_camera *cam) | ||
403 | { | ||
404 | viacam_write_reg(cam, VCR_INTCTRL, | ||
405 | VCR_IC_INTEN|VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL); | ||
406 | viafb_irq_enable(VDE_I_C0AVEN); | ||
407 | } | ||
408 | |||
409 | static void viacam_int_disable(struct via_camera *cam) | ||
410 | { | ||
411 | viafb_irq_disable(VDE_I_C0AVEN); | ||
412 | viacam_write_reg(cam, VCR_INTCTRL, 0); | ||
413 | } | ||
414 | |||
415 | |||
416 | |||
417 | /* --------------------------------------------------------------------------*/ | ||
418 | /* Controller operations */ | ||
419 | |||
420 | /* | ||
421 | * Set up our capture buffers in framebuffer memory. | ||
422 | */ | ||
423 | static int viacam_ctlr_cbufs(struct via_camera *cam) | ||
424 | { | ||
425 | int nbuf = cam->viadev->camera_fbmem_size/cam->sensor_format.sizeimage; | ||
426 | int i; | ||
427 | unsigned int offset; | ||
428 | |||
429 | /* | ||
430 | * See how many buffers we can work with. | ||
431 | */ | ||
432 | if (nbuf >= 3) { | ||
433 | cam->n_cap_bufs = 3; | ||
434 | viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_3BUFS, | ||
435 | VCR_CI_3BUFS); | ||
436 | } else if (nbuf == 2) { | ||
437 | cam->n_cap_bufs = 2; | ||
438 | viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_3BUFS); | ||
439 | } else { | ||
440 | cam_warn(cam, "Insufficient frame buffer memory\n"); | ||
441 | return -ENOMEM; | ||
442 | } | ||
443 | /* | ||
444 | * Set them up. | ||
445 | */ | ||
446 | offset = cam->fb_offset; | ||
447 | for (i = 0; i < cam->n_cap_bufs; i++) { | ||
448 | cam->cb_offsets[i] = offset; | ||
449 | cam->cb_addrs[i] = cam->fbmem + offset; | ||
450 | viacam_write_reg(cam, VCR_VBUF1 + i*4, offset & VCR_VBUF_MASK); | ||
451 | offset += cam->sensor_format.sizeimage; | ||
452 | } | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * Set the scaling register for downscaling the image. | ||
458 | * | ||
459 | * This register works like this... Vertical scaling is enabled | ||
460 | * by bit 26; if that bit is set, downscaling is controlled by the | ||
461 | * value in bits 16:25. Those bits are divided by 1024 to get | ||
462 | * the scaling factor; setting just bit 25 thus cuts the height | ||
463 | * in half. | ||
464 | * | ||
465 | * Horizontal scaling works about the same, but it's enabled by | ||
466 | * bit 11, with bits 0:10 giving the numerator of a fraction | ||
467 | * (over 2048) for the scaling value. | ||
468 | * | ||
469 | * This function is naive in that, if the user departs from | ||
470 | * the 3x4 VGA scaling factor, the image will distort. We | ||
471 | * could work around that if it really seemed important. | ||
472 | */ | ||
473 | static void viacam_set_scale(struct via_camera *cam) | ||
474 | { | ||
475 | unsigned int avscale; | ||
476 | int sf; | ||
477 | |||
478 | if (cam->user_format.width == VGA_WIDTH) | ||
479 | avscale = 0; | ||
480 | else { | ||
481 | sf = (cam->user_format.width*2048)/VGA_WIDTH; | ||
482 | avscale = VCR_AVS_HEN | sf; | ||
483 | } | ||
484 | if (cam->user_format.height < VGA_HEIGHT) { | ||
485 | sf = (1024*cam->user_format.height)/VGA_HEIGHT; | ||
486 | avscale |= VCR_AVS_VEN | (sf << 16); | ||
487 | } | ||
488 | viacam_write_reg(cam, VCR_AVSCALE, avscale); | ||
489 | } | ||
490 | |||
491 | |||
492 | /* | ||
493 | * Configure image-related information into the capture engine. | ||
494 | */ | ||
495 | static void viacam_ctlr_image(struct via_camera *cam) | ||
496 | { | ||
497 | int cicreg; | ||
498 | |||
499 | /* | ||
500 | * Disable clock before messing with stuff - from the via | ||
501 | * sample driver. | ||
502 | */ | ||
503 | viacam_write_reg(cam, VCR_CAPINTC, ~(VCR_CI_ENABLE|VCR_CI_CLKEN)); | ||
504 | /* | ||
505 | * Set up the controller for VGA resolution, modulo magic | ||
506 | * offsets from the via sample driver. | ||
507 | */ | ||
508 | viacam_write_reg(cam, VCR_HORRANGE, 0x06200120); | ||
509 | viacam_write_reg(cam, VCR_VERTRANGE, 0x01de0000); | ||
510 | viacam_set_scale(cam); | ||
511 | /* | ||
512 | * Image size info. | ||
513 | */ | ||
514 | viacam_write_reg(cam, VCR_MAXDATA, | ||
515 | (cam->sensor_format.height << 16) | | ||
516 | (cam->sensor_format.bytesperline >> 3)); | ||
517 | viacam_write_reg(cam, VCR_MAXVBI, 0); | ||
518 | viacam_write_reg(cam, VCR_VSTRIDE, | ||
519 | cam->user_format.bytesperline & VCR_VS_STRIDE); | ||
520 | /* | ||
521 | * Set up the capture interface control register, | ||
522 | * everything but the "go" bit. | ||
523 | * | ||
524 | * The FIFO threshold is a bit of a magic number; 8 is what | ||
525 | * VIA's sample code uses. | ||
526 | */ | ||
527 | cicreg = VCR_CI_CLKEN | | ||
528 | 0x08000000 | /* FIFO threshold */ | ||
529 | VCR_CI_FLDINV | /* OLPC-specific? */ | ||
530 | VCR_CI_VREFINV | /* OLPC-specific? */ | ||
531 | VCR_CI_DIBOTH | /* Capture both fields */ | ||
532 | VCR_CI_CCIR601_8; | ||
533 | if (cam->n_cap_bufs == 3) | ||
534 | cicreg |= VCR_CI_3BUFS; | ||
535 | /* | ||
536 | * YUV formats need different byte swapping than RGB. | ||
537 | */ | ||
538 | if (cam->user_format.pixelformat == V4L2_PIX_FMT_YUYV) | ||
539 | cicreg |= VCR_CI_YUYV; | ||
540 | else | ||
541 | cicreg |= VCR_CI_UYVY; | ||
542 | viacam_write_reg(cam, VCR_CAPINTC, cicreg); | ||
543 | } | ||
544 | |||
545 | |||
546 | static int viacam_config_controller(struct via_camera *cam) | ||
547 | { | ||
548 | int ret; | ||
549 | unsigned long flags; | ||
550 | |||
551 | spin_lock_irqsave(&cam->viadev->reg_lock, flags); | ||
552 | ret = viacam_ctlr_cbufs(cam); | ||
553 | if (!ret) | ||
554 | viacam_ctlr_image(cam); | ||
555 | spin_unlock_irqrestore(&cam->viadev->reg_lock, flags); | ||
556 | clear_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
557 | return ret; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Make it start grabbing data. | ||
562 | */ | ||
563 | static void viacam_start_engine(struct via_camera *cam) | ||
564 | { | ||
565 | spin_lock_irq(&cam->viadev->reg_lock); | ||
566 | cam->next_buf = 0; | ||
567 | viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE); | ||
568 | viacam_int_enable(cam); | ||
569 | (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */ | ||
570 | cam->opstate = S_RUNNING; | ||
571 | spin_unlock_irq(&cam->viadev->reg_lock); | ||
572 | } | ||
573 | |||
574 | |||
575 | static void viacam_stop_engine(struct via_camera *cam) | ||
576 | { | ||
577 | spin_lock_irq(&cam->viadev->reg_lock); | ||
578 | viacam_int_disable(cam); | ||
579 | viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_ENABLE); | ||
580 | (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */ | ||
581 | cam->opstate = S_IDLE; | ||
582 | spin_unlock_irq(&cam->viadev->reg_lock); | ||
583 | } | ||
584 | |||
585 | |||
586 | /* --------------------------------------------------------------------------*/ | ||
587 | /* Videobuf callback ops */ | ||
588 | |||
589 | /* | ||
590 | * buffer_setup. The purpose of this one would appear to be to tell | ||
591 | * videobuf how big a single image is. It's also evidently up to us | ||
592 | * to put some sort of limit on the maximum number of buffers allowed. | ||
593 | */ | ||
594 | static int viacam_vb_buf_setup(struct videobuf_queue *q, | ||
595 | unsigned int *count, unsigned int *size) | ||
596 | { | ||
597 | struct via_camera *cam = q->priv_data; | ||
598 | |||
599 | *size = cam->user_format.sizeimage; | ||
600 | if (*count == 0 || *count > 6) /* Arbitrary number */ | ||
601 | *count = 6; | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | /* | ||
606 | * Prepare a buffer. | ||
607 | */ | ||
608 | static int viacam_vb_buf_prepare(struct videobuf_queue *q, | ||
609 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
610 | { | ||
611 | struct via_camera *cam = q->priv_data; | ||
612 | |||
613 | vb->size = cam->user_format.sizeimage; | ||
614 | vb->width = cam->user_format.width; /* bytesperline???? */ | ||
615 | vb->height = cam->user_format.height; | ||
616 | vb->field = field; | ||
617 | if (vb->state == VIDEOBUF_NEEDS_INIT) { | ||
618 | int ret = videobuf_iolock(q, vb, NULL); | ||
619 | if (ret) | ||
620 | return ret; | ||
621 | } | ||
622 | vb->state = VIDEOBUF_PREPARED; | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | /* | ||
627 | * We've got a buffer to put data into. | ||
628 | * | ||
629 | * FIXME: check for a running engine and valid buffers? | ||
630 | */ | ||
631 | static void viacam_vb_buf_queue(struct videobuf_queue *q, | ||
632 | struct videobuf_buffer *vb) | ||
633 | { | ||
634 | struct via_camera *cam = q->priv_data; | ||
635 | |||
636 | /* | ||
637 | * Note that videobuf holds the lock when it calls | ||
638 | * us, so we need not (indeed, cannot) take it here. | ||
639 | */ | ||
640 | vb->state = VIDEOBUF_QUEUED; | ||
641 | list_add_tail(&vb->queue, &cam->buffer_queue); | ||
642 | } | ||
643 | |||
644 | /* | ||
645 | * Free a buffer. | ||
646 | */ | ||
647 | static void viacam_vb_buf_release(struct videobuf_queue *q, | ||
648 | struct videobuf_buffer *vb) | ||
649 | { | ||
650 | struct via_camera *cam = q->priv_data; | ||
651 | |||
652 | videobuf_dma_unmap(&cam->platdev->dev, videobuf_to_dma(vb)); | ||
653 | videobuf_dma_free(videobuf_to_dma(vb)); | ||
654 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
655 | } | ||
656 | |||
657 | static const struct videobuf_queue_ops viacam_vb_ops = { | ||
658 | .buf_setup = viacam_vb_buf_setup, | ||
659 | .buf_prepare = viacam_vb_buf_prepare, | ||
660 | .buf_queue = viacam_vb_buf_queue, | ||
661 | .buf_release = viacam_vb_buf_release, | ||
662 | }; | ||
663 | |||
664 | /* --------------------------------------------------------------------------*/ | ||
665 | /* File operations */ | ||
666 | |||
667 | static int viacam_open(struct file *filp) | ||
668 | { | ||
669 | struct via_camera *cam = video_drvdata(filp); | ||
670 | |||
671 | filp->private_data = cam; | ||
672 | /* | ||
673 | * Note the new user. If this is the first one, we'll also | ||
674 | * need to power up the sensor. | ||
675 | */ | ||
676 | mutex_lock(&cam->lock); | ||
677 | if (cam->users == 0) { | ||
678 | int ret = viafb_request_dma(); | ||
679 | |||
680 | if (ret) { | ||
681 | mutex_unlock(&cam->lock); | ||
682 | return ret; | ||
683 | } | ||
684 | via_sensor_power_up(cam); | ||
685 | set_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
686 | /* | ||
687 | * Hook into videobuf. Evidently this cannot fail. | ||
688 | */ | ||
689 | videobuf_queue_sg_init(&cam->vb_queue, &viacam_vb_ops, | ||
690 | &cam->platdev->dev, &cam->viadev->reg_lock, | ||
691 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | ||
692 | sizeof(struct videobuf_buffer), cam, NULL); | ||
693 | } | ||
694 | (cam->users)++; | ||
695 | mutex_unlock(&cam->lock); | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static int viacam_release(struct file *filp) | ||
700 | { | ||
701 | struct via_camera *cam = video_drvdata(filp); | ||
702 | |||
703 | mutex_lock(&cam->lock); | ||
704 | (cam->users)--; | ||
705 | /* | ||
706 | * If the "owner" is closing, shut down any ongoing | ||
707 | * operations. | ||
708 | */ | ||
709 | if (filp == cam->owner) { | ||
710 | videobuf_stop(&cam->vb_queue); | ||
711 | /* | ||
712 | * We don't hold the spinlock here, but, if release() | ||
713 | * is being called by the owner, nobody else will | ||
714 | * be changing the state. And an extra stop would | ||
715 | * not hurt anyway. | ||
716 | */ | ||
717 | if (cam->opstate != S_IDLE) | ||
718 | viacam_stop_engine(cam); | ||
719 | cam->owner = NULL; | ||
720 | } | ||
721 | /* | ||
722 | * Last one out needs to turn out the lights. | ||
723 | */ | ||
724 | if (cam->users == 0) { | ||
725 | videobuf_mmap_free(&cam->vb_queue); | ||
726 | via_sensor_power_down(cam); | ||
727 | viafb_release_dma(); | ||
728 | } | ||
729 | mutex_unlock(&cam->lock); | ||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * Read a frame from the device. | ||
735 | */ | ||
736 | static ssize_t viacam_read(struct file *filp, char __user *buffer, | ||
737 | size_t len, loff_t *pos) | ||
738 | { | ||
739 | struct via_camera *cam = video_drvdata(filp); | ||
740 | int ret; | ||
741 | |||
742 | mutex_lock(&cam->lock); | ||
743 | /* | ||
744 | * Enforce the V4l2 "only one owner gets to read data" rule. | ||
745 | */ | ||
746 | if (cam->owner && cam->owner != filp) { | ||
747 | ret = -EBUSY; | ||
748 | goto out_unlock; | ||
749 | } | ||
750 | cam->owner = filp; | ||
751 | /* | ||
752 | * Do we need to configure the hardware? | ||
753 | */ | ||
754 | if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) { | ||
755 | ret = viacam_configure_sensor(cam); | ||
756 | if (!ret) | ||
757 | ret = viacam_config_controller(cam); | ||
758 | if (ret) | ||
759 | goto out_unlock; | ||
760 | } | ||
761 | /* | ||
762 | * Fire up the capture engine, then have videobuf do | ||
763 | * the heavy lifting. Someday it would be good to avoid | ||
764 | * stopping and restarting the engine each time. | ||
765 | */ | ||
766 | INIT_LIST_HEAD(&cam->buffer_queue); | ||
767 | viacam_start_engine(cam); | ||
768 | ret = videobuf_read_stream(&cam->vb_queue, buffer, len, pos, 0, | ||
769 | filp->f_flags & O_NONBLOCK); | ||
770 | viacam_stop_engine(cam); | ||
771 | /* videobuf_stop() ?? */ | ||
772 | |||
773 | out_unlock: | ||
774 | mutex_unlock(&cam->lock); | ||
775 | return ret; | ||
776 | } | ||
777 | |||
778 | |||
779 | static unsigned int viacam_poll(struct file *filp, struct poll_table_struct *pt) | ||
780 | { | ||
781 | struct via_camera *cam = video_drvdata(filp); | ||
782 | |||
783 | return videobuf_poll_stream(filp, &cam->vb_queue, pt); | ||
784 | } | ||
785 | |||
786 | |||
787 | static int viacam_mmap(struct file *filp, struct vm_area_struct *vma) | ||
788 | { | ||
789 | struct via_camera *cam = video_drvdata(filp); | ||
790 | |||
791 | return videobuf_mmap_mapper(&cam->vb_queue, vma); | ||
792 | } | ||
793 | |||
794 | |||
795 | |||
796 | static const struct v4l2_file_operations viacam_fops = { | ||
797 | .owner = THIS_MODULE, | ||
798 | .open = viacam_open, | ||
799 | .release = viacam_release, | ||
800 | .read = viacam_read, | ||
801 | .poll = viacam_poll, | ||
802 | .mmap = viacam_mmap, | ||
803 | .unlocked_ioctl = video_ioctl2, | ||
804 | }; | ||
805 | |||
806 | /*----------------------------------------------------------------------------*/ | ||
807 | /* | ||
808 | * The long list of v4l2 ioctl ops | ||
809 | */ | ||
810 | |||
811 | static int viacam_g_chip_ident(struct file *file, void *priv, | ||
812 | struct v4l2_dbg_chip_ident *ident) | ||
813 | { | ||
814 | struct via_camera *cam = priv; | ||
815 | |||
816 | ident->ident = V4L2_IDENT_NONE; | ||
817 | ident->revision = 0; | ||
818 | if (v4l2_chip_match_host(&ident->match)) { | ||
819 | ident->ident = V4L2_IDENT_VIA_VX855; | ||
820 | return 0; | ||
821 | } | ||
822 | return sensor_call(cam, core, g_chip_ident, ident); | ||
823 | } | ||
824 | |||
825 | /* | ||
826 | * Control ops are passed through to the sensor. | ||
827 | */ | ||
828 | static int viacam_queryctrl(struct file *filp, void *priv, | ||
829 | struct v4l2_queryctrl *qc) | ||
830 | { | ||
831 | struct via_camera *cam = priv; | ||
832 | int ret; | ||
833 | |||
834 | mutex_lock(&cam->lock); | ||
835 | ret = sensor_call(cam, core, queryctrl, qc); | ||
836 | mutex_unlock(&cam->lock); | ||
837 | return ret; | ||
838 | } | ||
839 | |||
840 | |||
841 | static int viacam_g_ctrl(struct file *filp, void *priv, | ||
842 | struct v4l2_control *ctrl) | ||
843 | { | ||
844 | struct via_camera *cam = priv; | ||
845 | int ret; | ||
846 | |||
847 | mutex_lock(&cam->lock); | ||
848 | ret = sensor_call(cam, core, g_ctrl, ctrl); | ||
849 | mutex_unlock(&cam->lock); | ||
850 | return ret; | ||
851 | } | ||
852 | |||
853 | |||
854 | static int viacam_s_ctrl(struct file *filp, void *priv, | ||
855 | struct v4l2_control *ctrl) | ||
856 | { | ||
857 | struct via_camera *cam = priv; | ||
858 | int ret; | ||
859 | |||
860 | mutex_lock(&cam->lock); | ||
861 | ret = sensor_call(cam, core, s_ctrl, ctrl); | ||
862 | mutex_unlock(&cam->lock); | ||
863 | return ret; | ||
864 | } | ||
865 | |||
866 | /* | ||
867 | * Only one input. | ||
868 | */ | ||
869 | static int viacam_enum_input(struct file *filp, void *priv, | ||
870 | struct v4l2_input *input) | ||
871 | { | ||
872 | if (input->index != 0) | ||
873 | return -EINVAL; | ||
874 | |||
875 | input->type = V4L2_INPUT_TYPE_CAMERA; | ||
876 | input->std = V4L2_STD_ALL; /* Not sure what should go here */ | ||
877 | strcpy(input->name, "Camera"); | ||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static int viacam_g_input(struct file *filp, void *priv, unsigned int *i) | ||
882 | { | ||
883 | *i = 0; | ||
884 | return 0; | ||
885 | } | ||
886 | |||
887 | static int viacam_s_input(struct file *filp, void *priv, unsigned int i) | ||
888 | { | ||
889 | if (i != 0) | ||
890 | return -EINVAL; | ||
891 | return 0; | ||
892 | } | ||
893 | |||
894 | static int viacam_s_std(struct file *filp, void *priv, v4l2_std_id *std) | ||
895 | { | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | /* | ||
900 | * Video format stuff. Here is our default format until | ||
901 | * user space messes with things. | ||
902 | */ | ||
903 | static const struct v4l2_pix_format viacam_def_pix_format = { | ||
904 | .width = VGA_WIDTH, | ||
905 | .height = VGA_HEIGHT, | ||
906 | .pixelformat = V4L2_PIX_FMT_YUYV, | ||
907 | .field = V4L2_FIELD_NONE, | ||
908 | .bytesperline = VGA_WIDTH * 2, | ||
909 | .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2, | ||
910 | }; | ||
911 | |||
912 | static const enum v4l2_mbus_pixelcode via_def_mbus_code = V4L2_MBUS_FMT_YUYV8_2X8; | ||
913 | |||
914 | static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv, | ||
915 | struct v4l2_fmtdesc *fmt) | ||
916 | { | ||
917 | if (fmt->index >= N_VIA_FMTS) | ||
918 | return -EINVAL; | ||
919 | strlcpy(fmt->description, via_formats[fmt->index].desc, | ||
920 | sizeof(fmt->description)); | ||
921 | fmt->pixelformat = via_formats[fmt->index].pixelformat; | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | /* | ||
926 | * Figure out proper image dimensions, but always force the | ||
927 | * sensor to VGA. | ||
928 | */ | ||
929 | static void viacam_fmt_pre(struct v4l2_pix_format *userfmt, | ||
930 | struct v4l2_pix_format *sensorfmt) | ||
931 | { | ||
932 | *sensorfmt = *userfmt; | ||
933 | if (userfmt->width < QCIF_WIDTH || userfmt->height < QCIF_HEIGHT) { | ||
934 | userfmt->width = QCIF_WIDTH; | ||
935 | userfmt->height = QCIF_HEIGHT; | ||
936 | } | ||
937 | if (userfmt->width > VGA_WIDTH || userfmt->height > VGA_HEIGHT) { | ||
938 | userfmt->width = VGA_WIDTH; | ||
939 | userfmt->height = VGA_HEIGHT; | ||
940 | } | ||
941 | sensorfmt->width = VGA_WIDTH; | ||
942 | sensorfmt->height = VGA_HEIGHT; | ||
943 | } | ||
944 | |||
945 | static void viacam_fmt_post(struct v4l2_pix_format *userfmt, | ||
946 | struct v4l2_pix_format *sensorfmt) | ||
947 | { | ||
948 | struct via_format *f = via_find_format(userfmt->pixelformat); | ||
949 | |||
950 | sensorfmt->bytesperline = sensorfmt->width * f->bpp; | ||
951 | sensorfmt->sizeimage = sensorfmt->height * sensorfmt->bytesperline; | ||
952 | userfmt->pixelformat = sensorfmt->pixelformat; | ||
953 | userfmt->field = sensorfmt->field; | ||
954 | userfmt->bytesperline = 2 * userfmt->width; | ||
955 | userfmt->sizeimage = userfmt->bytesperline * userfmt->height; | ||
956 | } | ||
957 | |||
958 | |||
959 | /* | ||
960 | * The real work of figuring out a workable format. | ||
961 | */ | ||
962 | static int viacam_do_try_fmt(struct via_camera *cam, | ||
963 | struct v4l2_pix_format *upix, struct v4l2_pix_format *spix) | ||
964 | { | ||
965 | int ret; | ||
966 | struct v4l2_mbus_framefmt mbus_fmt; | ||
967 | struct via_format *f = via_find_format(upix->pixelformat); | ||
968 | |||
969 | upix->pixelformat = f->pixelformat; | ||
970 | viacam_fmt_pre(upix, spix); | ||
971 | v4l2_fill_mbus_format(&mbus_fmt, upix, f->mbus_code); | ||
972 | ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt); | ||
973 | v4l2_fill_pix_format(spix, &mbus_fmt); | ||
974 | viacam_fmt_post(upix, spix); | ||
975 | return ret; | ||
976 | } | ||
977 | |||
978 | |||
979 | |||
980 | static int viacam_try_fmt_vid_cap(struct file *filp, void *priv, | ||
981 | struct v4l2_format *fmt) | ||
982 | { | ||
983 | struct via_camera *cam = priv; | ||
984 | struct v4l2_format sfmt; | ||
985 | int ret; | ||
986 | |||
987 | mutex_lock(&cam->lock); | ||
988 | ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); | ||
989 | mutex_unlock(&cam->lock); | ||
990 | return ret; | ||
991 | } | ||
992 | |||
993 | |||
994 | static int viacam_g_fmt_vid_cap(struct file *filp, void *priv, | ||
995 | struct v4l2_format *fmt) | ||
996 | { | ||
997 | struct via_camera *cam = priv; | ||
998 | |||
999 | mutex_lock(&cam->lock); | ||
1000 | fmt->fmt.pix = cam->user_format; | ||
1001 | mutex_unlock(&cam->lock); | ||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static int viacam_s_fmt_vid_cap(struct file *filp, void *priv, | ||
1006 | struct v4l2_format *fmt) | ||
1007 | { | ||
1008 | struct via_camera *cam = priv; | ||
1009 | int ret; | ||
1010 | struct v4l2_format sfmt; | ||
1011 | struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat); | ||
1012 | |||
1013 | /* | ||
1014 | * Camera must be idle or we can't mess with the | ||
1015 | * video setup. | ||
1016 | */ | ||
1017 | mutex_lock(&cam->lock); | ||
1018 | if (cam->opstate != S_IDLE) { | ||
1019 | ret = -EBUSY; | ||
1020 | goto out; | ||
1021 | } | ||
1022 | /* | ||
1023 | * Let the sensor code look over and tweak the | ||
1024 | * requested formatting. | ||
1025 | */ | ||
1026 | ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); | ||
1027 | if (ret) | ||
1028 | goto out; | ||
1029 | /* | ||
1030 | * OK, let's commit to the new format. | ||
1031 | */ | ||
1032 | cam->user_format = fmt->fmt.pix; | ||
1033 | cam->sensor_format = sfmt.fmt.pix; | ||
1034 | cam->mbus_code = f->mbus_code; | ||
1035 | ret = viacam_configure_sensor(cam); | ||
1036 | if (!ret) | ||
1037 | ret = viacam_config_controller(cam); | ||
1038 | out: | ||
1039 | mutex_unlock(&cam->lock); | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | static int viacam_querycap(struct file *filp, void *priv, | ||
1044 | struct v4l2_capability *cap) | ||
1045 | { | ||
1046 | strcpy(cap->driver, "via-camera"); | ||
1047 | strcpy(cap->card, "via-camera"); | ||
1048 | cap->version = 1; | ||
1049 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | ||
1050 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | ||
1051 | return 0; | ||
1052 | } | ||
1053 | |||
1054 | /* | ||
1055 | * Streaming operations - pure videobuf stuff. | ||
1056 | */ | ||
1057 | static int viacam_reqbufs(struct file *filp, void *priv, | ||
1058 | struct v4l2_requestbuffers *rb) | ||
1059 | { | ||
1060 | struct via_camera *cam = priv; | ||
1061 | |||
1062 | return videobuf_reqbufs(&cam->vb_queue, rb); | ||
1063 | } | ||
1064 | |||
1065 | static int viacam_querybuf(struct file *filp, void *priv, | ||
1066 | struct v4l2_buffer *buf) | ||
1067 | { | ||
1068 | struct via_camera *cam = priv; | ||
1069 | |||
1070 | return videobuf_querybuf(&cam->vb_queue, buf); | ||
1071 | } | ||
1072 | |||
1073 | static int viacam_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) | ||
1074 | { | ||
1075 | struct via_camera *cam = priv; | ||
1076 | |||
1077 | return videobuf_qbuf(&cam->vb_queue, buf); | ||
1078 | } | ||
1079 | |||
1080 | static int viacam_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) | ||
1081 | { | ||
1082 | struct via_camera *cam = priv; | ||
1083 | |||
1084 | return videobuf_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK); | ||
1085 | } | ||
1086 | |||
1087 | static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t) | ||
1088 | { | ||
1089 | struct via_camera *cam = priv; | ||
1090 | int ret = 0; | ||
1091 | |||
1092 | if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1093 | return -EINVAL; | ||
1094 | |||
1095 | mutex_lock(&cam->lock); | ||
1096 | if (cam->opstate != S_IDLE) { | ||
1097 | ret = -EBUSY; | ||
1098 | goto out; | ||
1099 | } | ||
1100 | /* | ||
1101 | * Enforce the V4l2 "only one owner gets to read data" rule. | ||
1102 | */ | ||
1103 | if (cam->owner && cam->owner != filp) { | ||
1104 | ret = -EBUSY; | ||
1105 | goto out; | ||
1106 | } | ||
1107 | cam->owner = filp; | ||
1108 | /* | ||
1109 | * Configure things if need be. | ||
1110 | */ | ||
1111 | if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) { | ||
1112 | ret = viacam_configure_sensor(cam); | ||
1113 | if (ret) | ||
1114 | goto out; | ||
1115 | ret = viacam_config_controller(cam); | ||
1116 | if (ret) | ||
1117 | goto out; | ||
1118 | } | ||
1119 | /* | ||
1120 | * If the CPU goes into C3, the DMA transfer gets corrupted and | ||
1121 | * users start filing unsightly bug reports. Put in a "latency" | ||
1122 | * requirement which will keep the CPU out of the deeper sleep | ||
1123 | * states. | ||
1124 | */ | ||
1125 | pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50); | ||
1126 | /* | ||
1127 | * Fire things up. | ||
1128 | */ | ||
1129 | INIT_LIST_HEAD(&cam->buffer_queue); | ||
1130 | ret = videobuf_streamon(&cam->vb_queue); | ||
1131 | if (!ret) | ||
1132 | viacam_start_engine(cam); | ||
1133 | out: | ||
1134 | mutex_unlock(&cam->lock); | ||
1135 | return ret; | ||
1136 | } | ||
1137 | |||
1138 | static int viacam_streamoff(struct file *filp, void *priv, enum v4l2_buf_type t) | ||
1139 | { | ||
1140 | struct via_camera *cam = priv; | ||
1141 | int ret; | ||
1142 | |||
1143 | if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1144 | return -EINVAL; | ||
1145 | mutex_lock(&cam->lock); | ||
1146 | if (cam->opstate != S_RUNNING) { | ||
1147 | ret = -EINVAL; | ||
1148 | goto out; | ||
1149 | } | ||
1150 | pm_qos_remove_request(&cam->qos_request); | ||
1151 | viacam_stop_engine(cam); | ||
1152 | /* | ||
1153 | * Videobuf will recycle all of the outstanding buffers, but | ||
1154 | * we should be sure we don't retain any references to | ||
1155 | * any of them. | ||
1156 | */ | ||
1157 | ret = videobuf_streamoff(&cam->vb_queue); | ||
1158 | INIT_LIST_HEAD(&cam->buffer_queue); | ||
1159 | out: | ||
1160 | mutex_unlock(&cam->lock); | ||
1161 | return ret; | ||
1162 | } | ||
1163 | |||
1164 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1165 | static int viacam_vidiocgmbuf(struct file *filp, void *priv, | ||
1166 | struct video_mbuf *mbuf) | ||
1167 | { | ||
1168 | struct via_camera *cam = priv; | ||
1169 | |||
1170 | return videobuf_cgmbuf(&cam->vb_queue, mbuf, 6); | ||
1171 | } | ||
1172 | #endif | ||
1173 | |||
1174 | /* G/S_PARM */ | ||
1175 | |||
1176 | static int viacam_g_parm(struct file *filp, void *priv, | ||
1177 | struct v4l2_streamparm *parm) | ||
1178 | { | ||
1179 | struct via_camera *cam = priv; | ||
1180 | int ret; | ||
1181 | |||
1182 | mutex_lock(&cam->lock); | ||
1183 | ret = sensor_call(cam, video, g_parm, parm); | ||
1184 | mutex_unlock(&cam->lock); | ||
1185 | parm->parm.capture.readbuffers = cam->n_cap_bufs; | ||
1186 | return ret; | ||
1187 | } | ||
1188 | |||
1189 | static int viacam_s_parm(struct file *filp, void *priv, | ||
1190 | struct v4l2_streamparm *parm) | ||
1191 | { | ||
1192 | struct via_camera *cam = priv; | ||
1193 | int ret; | ||
1194 | |||
1195 | mutex_lock(&cam->lock); | ||
1196 | ret = sensor_call(cam, video, s_parm, parm); | ||
1197 | mutex_unlock(&cam->lock); | ||
1198 | parm->parm.capture.readbuffers = cam->n_cap_bufs; | ||
1199 | return ret; | ||
1200 | } | ||
1201 | |||
1202 | static int viacam_enum_framesizes(struct file *filp, void *priv, | ||
1203 | struct v4l2_frmsizeenum *sizes) | ||
1204 | { | ||
1205 | if (sizes->index != 0) | ||
1206 | return -EINVAL; | ||
1207 | sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | ||
1208 | sizes->stepwise.min_width = QCIF_WIDTH; | ||
1209 | sizes->stepwise.min_height = QCIF_HEIGHT; | ||
1210 | sizes->stepwise.max_width = VGA_WIDTH; | ||
1211 | sizes->stepwise.max_height = VGA_HEIGHT; | ||
1212 | sizes->stepwise.step_width = sizes->stepwise.step_height = 1; | ||
1213 | return 0; | ||
1214 | } | ||
1215 | |||
1216 | static int viacam_enum_frameintervals(struct file *filp, void *priv, | ||
1217 | struct v4l2_frmivalenum *interval) | ||
1218 | { | ||
1219 | struct via_camera *cam = priv; | ||
1220 | int ret; | ||
1221 | |||
1222 | mutex_lock(&cam->lock); | ||
1223 | ret = sensor_call(cam, video, enum_frameintervals, interval); | ||
1224 | mutex_unlock(&cam->lock); | ||
1225 | return ret; | ||
1226 | } | ||
1227 | |||
1228 | |||
1229 | |||
1230 | static const struct v4l2_ioctl_ops viacam_ioctl_ops = { | ||
1231 | .vidioc_g_chip_ident = viacam_g_chip_ident, | ||
1232 | .vidioc_queryctrl = viacam_queryctrl, | ||
1233 | .vidioc_g_ctrl = viacam_g_ctrl, | ||
1234 | .vidioc_s_ctrl = viacam_s_ctrl, | ||
1235 | .vidioc_enum_input = viacam_enum_input, | ||
1236 | .vidioc_g_input = viacam_g_input, | ||
1237 | .vidioc_s_input = viacam_s_input, | ||
1238 | .vidioc_s_std = viacam_s_std, | ||
1239 | .vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap, | ||
1240 | .vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap, | ||
1241 | .vidioc_g_fmt_vid_cap = viacam_g_fmt_vid_cap, | ||
1242 | .vidioc_s_fmt_vid_cap = viacam_s_fmt_vid_cap, | ||
1243 | .vidioc_querycap = viacam_querycap, | ||
1244 | .vidioc_reqbufs = viacam_reqbufs, | ||
1245 | .vidioc_querybuf = viacam_querybuf, | ||
1246 | .vidioc_qbuf = viacam_qbuf, | ||
1247 | .vidioc_dqbuf = viacam_dqbuf, | ||
1248 | .vidioc_streamon = viacam_streamon, | ||
1249 | .vidioc_streamoff = viacam_streamoff, | ||
1250 | .vidioc_g_parm = viacam_g_parm, | ||
1251 | .vidioc_s_parm = viacam_s_parm, | ||
1252 | .vidioc_enum_framesizes = viacam_enum_framesizes, | ||
1253 | .vidioc_enum_frameintervals = viacam_enum_frameintervals, | ||
1254 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1255 | .vidiocgmbuf = viacam_vidiocgmbuf, | ||
1256 | #endif | ||
1257 | }; | ||
1258 | |||
1259 | /*----------------------------------------------------------------------------*/ | ||
1260 | |||
1261 | /* | ||
1262 | * Power management. | ||
1263 | */ | ||
1264 | |||
1265 | /* | ||
1266 | * Setup stuff. | ||
1267 | */ | ||
1268 | |||
1269 | static struct video_device viacam_v4l_template = { | ||
1270 | .name = "via-camera", | ||
1271 | .minor = -1, | ||
1272 | .tvnorms = V4L2_STD_NTSC_M, | ||
1273 | .current_norm = V4L2_STD_NTSC_M, | ||
1274 | .fops = &viacam_fops, | ||
1275 | .ioctl_ops = &viacam_ioctl_ops, | ||
1276 | .release = video_device_release_empty, /* Check this */ | ||
1277 | }; | ||
1278 | |||
1279 | |||
1280 | static __devinit int viacam_probe(struct platform_device *pdev) | ||
1281 | { | ||
1282 | int ret; | ||
1283 | struct i2c_adapter *sensor_adapter; | ||
1284 | struct viafb_dev *viadev = pdev->dev.platform_data; | ||
1285 | |||
1286 | /* | ||
1287 | * Note that there are actually two capture channels on | ||
1288 | * the device. We only deal with one for now. That | ||
1289 | * is encoded here; nothing else assumes it's dealing with | ||
1290 | * a unique capture device. | ||
1291 | */ | ||
1292 | struct via_camera *cam; | ||
1293 | |||
1294 | /* | ||
1295 | * Ensure that frame buffer memory has been set aside for | ||
1296 | * this purpose. As an arbitrary limit, refuse to work | ||
1297 | * with less than two frames of VGA 16-bit data. | ||
1298 | * | ||
1299 | * If we ever support the second port, we'll need to set | ||
1300 | * aside more memory. | ||
1301 | */ | ||
1302 | if (viadev->camera_fbmem_size < (VGA_HEIGHT*VGA_WIDTH*4)) { | ||
1303 | printk(KERN_ERR "viacam: insufficient FB memory reserved\n"); | ||
1304 | return -ENOMEM; | ||
1305 | } | ||
1306 | if (viadev->engine_mmio == NULL) { | ||
1307 | printk(KERN_ERR "viacam: No I/O memory, so no pictures\n"); | ||
1308 | return -ENOMEM; | ||
1309 | } | ||
1310 | /* | ||
1311 | * Basic structure initialization. | ||
1312 | */ | ||
1313 | cam = kzalloc (sizeof(struct via_camera), GFP_KERNEL); | ||
1314 | if (cam == NULL) | ||
1315 | return -ENOMEM; | ||
1316 | via_cam_info = cam; | ||
1317 | cam->platdev = pdev; | ||
1318 | cam->viadev = viadev; | ||
1319 | cam->users = 0; | ||
1320 | cam->owner = NULL; | ||
1321 | cam->opstate = S_IDLE; | ||
1322 | cam->user_format = cam->sensor_format = viacam_def_pix_format; | ||
1323 | mutex_init(&cam->lock); | ||
1324 | INIT_LIST_HEAD(&cam->buffer_queue); | ||
1325 | cam->mmio = viadev->engine_mmio; | ||
1326 | cam->fbmem = viadev->fbmem; | ||
1327 | cam->fb_offset = viadev->camera_fbmem_offset; | ||
1328 | cam->flags = 1 << CF_CONFIG_NEEDED; | ||
1329 | cam->mbus_code = via_def_mbus_code; | ||
1330 | /* | ||
1331 | * Tell V4L that we exist. | ||
1332 | */ | ||
1333 | ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev); | ||
1334 | if (ret) { | ||
1335 | dev_err(&pdev->dev, "Unable to register v4l2 device\n"); | ||
1336 | return ret; | ||
1337 | } | ||
1338 | /* | ||
1339 | * Convince the system that we can do DMA. | ||
1340 | */ | ||
1341 | pdev->dev.dma_mask = &viadev->pdev->dma_mask; | ||
1342 | dma_set_mask(&pdev->dev, 0xffffffff); | ||
1343 | /* | ||
1344 | * Fire up the capture port. The write to 0x78 looks purely | ||
1345 | * OLPCish; any system will need to tweak 0x1e. | ||
1346 | */ | ||
1347 | via_write_reg_mask(VIASR, 0x78, 0, 0x80); | ||
1348 | via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0); | ||
1349 | /* | ||
1350 | * Get the sensor powered up. | ||
1351 | */ | ||
1352 | ret = via_sensor_power_setup(cam); | ||
1353 | if (ret) | ||
1354 | goto out_unregister; | ||
1355 | via_sensor_power_up(cam); | ||
1356 | |||
1357 | /* | ||
1358 | * See if we can't find it on the bus. The VIA_PORT_31 assumption | ||
1359 | * is OLPC-specific. 0x42 assumption is ov7670-specific. | ||
1360 | */ | ||
1361 | sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31); | ||
1362 | cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter, | ||
1363 | "ov7670", "ov7670", 0x42 >> 1, NULL); | ||
1364 | if (cam->sensor == NULL) { | ||
1365 | dev_err(&pdev->dev, "Unable to find the sensor!\n"); | ||
1366 | ret = -ENODEV; | ||
1367 | goto out_power_down; | ||
1368 | } | ||
1369 | /* | ||
1370 | * Get the IRQ. | ||
1371 | */ | ||
1372 | viacam_int_disable(cam); | ||
1373 | ret = request_threaded_irq(viadev->pdev->irq, viacam_quick_irq, | ||
1374 | viacam_irq, IRQF_SHARED, "via-camera", cam); | ||
1375 | if (ret) | ||
1376 | goto out_power_down; | ||
1377 | /* | ||
1378 | * Tell V4l2 that we exist. | ||
1379 | */ | ||
1380 | cam->vdev = viacam_v4l_template; | ||
1381 | cam->vdev.v4l2_dev = &cam->v4l2_dev; | ||
1382 | ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); | ||
1383 | if (ret) | ||
1384 | goto out_irq; | ||
1385 | video_set_drvdata(&cam->vdev, cam); | ||
1386 | |||
1387 | /* Power the sensor down until somebody opens the device */ | ||
1388 | via_sensor_power_down(cam); | ||
1389 | return 0; | ||
1390 | |||
1391 | out_irq: | ||
1392 | free_irq(viadev->pdev->irq, cam); | ||
1393 | out_power_down: | ||
1394 | via_sensor_power_release(cam); | ||
1395 | out_unregister: | ||
1396 | v4l2_device_unregister(&cam->v4l2_dev); | ||
1397 | return ret; | ||
1398 | } | ||
1399 | |||
1400 | static __devexit int viacam_remove(struct platform_device *pdev) | ||
1401 | { | ||
1402 | struct via_camera *cam = via_cam_info; | ||
1403 | struct viafb_dev *viadev = pdev->dev.platform_data; | ||
1404 | |||
1405 | video_unregister_device(&cam->vdev); | ||
1406 | v4l2_device_unregister(&cam->v4l2_dev); | ||
1407 | free_irq(viadev->pdev->irq, cam); | ||
1408 | via_sensor_power_release(cam); | ||
1409 | via_cam_info = NULL; | ||
1410 | return 0; | ||
1411 | } | ||
1412 | |||
1413 | |||
1414 | static struct platform_driver viacam_driver = { | ||
1415 | .driver = { | ||
1416 | .name = "viafb-camera", | ||
1417 | }, | ||
1418 | .probe = viacam_probe, | ||
1419 | .remove = viacam_remove, | ||
1420 | }; | ||
1421 | |||
1422 | |||
1423 | #ifdef CONFIG_OLPC_XO_1_5 | ||
1424 | /* | ||
1425 | * The OLPC folks put the serial port on the same pin as | ||
1426 | * the camera. They also get grumpy if we break the | ||
1427 | * serial port and keep them from using it. So we have | ||
1428 | * to check the serial enable bit and not step on it. | ||
1429 | */ | ||
1430 | #define VIACAM_SERIAL_DEVFN 0x88 | ||
1431 | #define VIACAM_SERIAL_CREG 0x46 | ||
1432 | #define VIACAM_SERIAL_BIT 0x40 | ||
1433 | |||
1434 | static __devinit int viacam_check_serial_port(void) | ||
1435 | { | ||
1436 | struct pci_bus *pbus = pci_find_bus(0, 0); | ||
1437 | u8 cbyte; | ||
1438 | |||
1439 | pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN, | ||
1440 | VIACAM_SERIAL_CREG, &cbyte); | ||
1441 | if ((cbyte & VIACAM_SERIAL_BIT) == 0) | ||
1442 | return 0; /* Not enabled */ | ||
1443 | if (override_serial == 0) { | ||
1444 | printk(KERN_NOTICE "Via camera: serial port is enabled, " \ | ||
1445 | "refusing to load.\n"); | ||
1446 | printk(KERN_NOTICE "Specify override_serial=1 to force " \ | ||
1447 | "module loading.\n"); | ||
1448 | return -EBUSY; | ||
1449 | } | ||
1450 | printk(KERN_NOTICE "Via camera: overriding serial port\n"); | ||
1451 | pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN, | ||
1452 | VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT); | ||
1453 | return 0; | ||
1454 | } | ||
1455 | #endif | ||
1456 | |||
1457 | |||
1458 | |||
1459 | |||
1460 | static int viacam_init(void) | ||
1461 | { | ||
1462 | #ifdef CONFIG_OLPC_XO_1_5 | ||
1463 | if (viacam_check_serial_port()) | ||
1464 | return -EBUSY; | ||
1465 | #endif | ||
1466 | return platform_driver_register(&viacam_driver); | ||
1467 | } | ||
1468 | module_init(viacam_init); | ||
1469 | |||
1470 | static void viacam_exit(void) | ||
1471 | { | ||
1472 | platform_driver_unregister(&viacam_driver); | ||
1473 | } | ||
1474 | module_exit(viacam_exit); | ||
diff --git a/drivers/media/video/via-camera.h b/drivers/media/video/via-camera.h new file mode 100644 index 00000000000..b12a4b3d616 --- /dev/null +++ b/drivers/media/video/via-camera.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * VIA Camera register definitions. | ||
3 | */ | ||
4 | #define VCR_INTCTRL 0x300 /* Capture interrupt control */ | ||
5 | #define VCR_IC_EAV 0x0001 /* End of active video status */ | ||
6 | #define VCR_IC_EVBI 0x0002 /* End of VBI status */ | ||
7 | #define VCR_IC_FBOTFLD 0x0004 /* "flipping" Bottom field is active */ | ||
8 | #define VCR_IC_ACTBUF 0x0018 /* Active video buffer */ | ||
9 | #define VCR_IC_VSYNC 0x0020 /* 0 = VB, 1 = active video */ | ||
10 | #define VCR_IC_BOTFLD 0x0040 /* Bottom field is active */ | ||
11 | #define VCR_IC_FFULL 0x0080 /* FIFO full */ | ||
12 | #define VCR_IC_INTEN 0x0100 /* End of active video int. enable */ | ||
13 | #define VCR_IC_VBIINT 0x0200 /* End of VBI int enable */ | ||
14 | #define VCR_IC_VBIBUF 0x0400 /* Current VBI buffer */ | ||
15 | |||
16 | #define VCR_TSC 0x308 /* Transport stream control */ | ||
17 | #define VCR_TSC_ENABLE 0x000001 /* Transport stream input enable */ | ||
18 | #define VCR_TSC_DROPERR 0x000002 /* Drop error packets */ | ||
19 | #define VCR_TSC_METHOD 0x00000c /* DMA method (non-functional) */ | ||
20 | #define VCR_TSC_COUNT 0x07fff0 /* KByte or packet count */ | ||
21 | #define VCR_TSC_CBMODE 0x080000 /* Change buffer by byte count */ | ||
22 | #define VCR_TSC_PSSIG 0x100000 /* Packet starting signal disable */ | ||
23 | #define VCR_TSC_BE 0x200000 /* MSB first (serial mode) */ | ||
24 | #define VCR_TSC_SERIAL 0x400000 /* Serial input (0 = parallel) */ | ||
25 | |||
26 | #define VCR_CAPINTC 0x310 /* Capture interface control */ | ||
27 | #define VCR_CI_ENABLE 0x00000001 /* Capture enable */ | ||
28 | #define VCR_CI_BSS 0x00000002 /* WTF "bit stream selection" */ | ||
29 | #define VCR_CI_3BUFS 0x00000004 /* 1 = 3 buffers, 0 = 2 buffers */ | ||
30 | #define VCR_CI_VIPEN 0x00000008 /* VIP enable */ | ||
31 | #define VCR_CI_CCIR601_8 0 /* CCIR601 input stream, 8 bit */ | ||
32 | #define VCR_CI_CCIR656_8 0x00000010 /* ... CCIR656, 8 bit */ | ||
33 | #define VCR_CI_CCIR601_16 0x00000020 /* ... CCIR601, 16 bit */ | ||
34 | #define VCR_CI_CCIR656_16 0x00000030 /* ... CCIR656, 16 bit */ | ||
35 | #define VCR_CI_HDMODE 0x00000040 /* CCIR656-16 hdr decode mode; 1=16b */ | ||
36 | #define VCR_CI_BSWAP 0x00000080 /* Swap bytes (16-bit) */ | ||
37 | #define VCR_CI_YUYV 0 /* Byte order 0123 */ | ||
38 | #define VCR_CI_UYVY 0x00000100 /* Byte order 1032 */ | ||
39 | #define VCR_CI_YVYU 0x00000200 /* Byte order 0321 */ | ||
40 | #define VCR_CI_VYUY 0x00000300 /* Byte order 3012 */ | ||
41 | #define VCR_CI_VIPTYPE 0x00000400 /* VIP type */ | ||
42 | #define VCR_CI_IFSEN 0x00000800 /* Input field signal enable */ | ||
43 | #define VCR_CI_DIODD 0 /* De-interlace odd, 30fps */ | ||
44 | #define VCR_CI_DIEVEN 0x00001000 /* ...even field, 30fps */ | ||
45 | #define VCR_CI_DIBOTH 0x00002000 /* ...both fields, 60fps */ | ||
46 | #define VCR_CI_DIBOTH30 0x00003000 /* ...both fields, 30fps interlace */ | ||
47 | #define VCR_CI_CONVTYPE 0x00004000 /* 4:2:2 to 4:4:4; 1 = interpolate */ | ||
48 | #define VCR_CI_CFC 0x00008000 /* Capture flipping control */ | ||
49 | #define VCR_CI_FILTER 0x00070000 /* Horiz filter mode select | ||
50 | 000 = none | ||
51 | 001 = 2 tap | ||
52 | 010 = 3 tap | ||
53 | 011 = 4 tap | ||
54 | 100 = 5 tap */ | ||
55 | #define VCR_CI_CLKINV 0x00080000 /* Input CLK inverted */ | ||
56 | #define VCR_CI_VREFINV 0x00100000 /* VREF inverted */ | ||
57 | #define VCR_CI_HREFINV 0x00200000 /* HREF inverted */ | ||
58 | #define VCR_CI_FLDINV 0x00400000 /* Field inverted */ | ||
59 | #define VCR_CI_CLKPIN 0x00800000 /* Capture clock pin */ | ||
60 | #define VCR_CI_THRESH 0x0f000000 /* Capture fifo threshold */ | ||
61 | #define VCR_CI_HRLE 0x10000000 /* Positive edge of HREF */ | ||
62 | #define VCR_CI_VRLE 0x20000000 /* Positive edge of VREF */ | ||
63 | #define VCR_CI_OFLDINV 0x40000000 /* Field output inverted */ | ||
64 | #define VCR_CI_CLKEN 0x80000000 /* Capture clock enable */ | ||
65 | |||
66 | #define VCR_HORRANGE 0x314 /* Active video horizontal range */ | ||
67 | #define VCR_VERTRANGE 0x318 /* Active video vertical range */ | ||
68 | #define VCR_AVSCALE 0x31c /* Active video scaling control */ | ||
69 | #define VCR_AVS_HEN 0x00000800 /* Horizontal scale enable */ | ||
70 | #define VCR_AVS_VEN 0x04000000 /* Vertical enable */ | ||
71 | #define VCR_VBIHOR 0x320 /* VBI Data horizontal range */ | ||
72 | #define VCR_VBIVERT 0x324 /* VBI data vertical range */ | ||
73 | #define VCR_VBIBUF1 0x328 /* First VBI buffer */ | ||
74 | #define VCR_VBISTRIDE 0x32c /* VBI stride */ | ||
75 | #define VCR_ANCDATACNT 0x330 /* Ancillary data count setting */ | ||
76 | #define VCR_MAXDATA 0x334 /* Active data count of active video */ | ||
77 | #define VCR_MAXVBI 0x338 /* Maximum data count of VBI */ | ||
78 | #define VCR_CAPDATA 0x33c /* Capture data count */ | ||
79 | #define VCR_VBUF1 0x340 /* First video buffer */ | ||
80 | #define VCR_VBUF2 0x344 /* Second video buffer */ | ||
81 | #define VCR_VBUF3 0x348 /* Third video buffer */ | ||
82 | #define VCR_VBUF_MASK 0x1ffffff0 /* Bits 28:4 */ | ||
83 | #define VCR_VBIBUF2 0x34c /* Second VBI buffer */ | ||
84 | #define VCR_VSTRIDE 0x350 /* Stride of video + coring control */ | ||
85 | #define VCR_VS_STRIDE_SHIFT 4 | ||
86 | #define VCR_VS_STRIDE 0x00001ff0 /* Stride (8-byte units) */ | ||
87 | #define VCR_VS_CCD 0x007f0000 /* Coring compare data */ | ||
88 | #define VCR_VS_COREEN 0x00800000 /* Coring enable */ | ||
89 | #define VCR_TS0ERR 0x354 /* TS buffer 0 error indicator */ | ||
90 | #define VCR_TS1ERR 0x358 /* TS buffer 0 error indicator */ | ||
91 | #define VCR_TS2ERR 0x35c /* TS buffer 0 error indicator */ | ||
92 | |||
93 | /* Add 0x1000 for the second capture engine registers */ | ||
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index ce1595bef62..8979f91fa8e 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -73,25 +73,46 @@ struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q) | |||
73 | } | 73 | } |
74 | EXPORT_SYMBOL_GPL(videobuf_alloc_vb); | 74 | EXPORT_SYMBOL_GPL(videobuf_alloc_vb); |
75 | 75 | ||
76 | #define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\ | 76 | static int is_state_active_or_queued(struct videobuf_queue *q, struct videobuf_buffer *vb) |
77 | vb->state != VIDEOBUF_QUEUED) | ||
78 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) | ||
79 | { | 77 | { |
78 | unsigned long flags; | ||
79 | bool rc; | ||
80 | |||
81 | spin_lock_irqsave(q->irqlock, flags); | ||
82 | rc = vb->state != VIDEOBUF_ACTIVE && vb->state != VIDEOBUF_QUEUED; | ||
83 | spin_unlock_irqrestore(q->irqlock, flags); | ||
84 | return rc; | ||
85 | }; | ||
86 | |||
87 | int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
88 | int non_blocking, int intr) | ||
89 | { | ||
90 | bool is_ext_locked; | ||
91 | int ret = 0; | ||
92 | |||
80 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); | 93 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); |
81 | 94 | ||
82 | if (non_blocking) { | 95 | if (non_blocking) { |
83 | if (WAITON_CONDITION) | 96 | if (is_state_active_or_queued(q, vb)) |
84 | return 0; | 97 | return 0; |
85 | else | 98 | return -EAGAIN; |
86 | return -EAGAIN; | ||
87 | } | 99 | } |
88 | 100 | ||
101 | is_ext_locked = q->ext_lock && mutex_is_locked(q->ext_lock); | ||
102 | |||
103 | /* Release vdev lock to prevent this wait from blocking outside access to | ||
104 | the device. */ | ||
105 | if (is_ext_locked) | ||
106 | mutex_unlock(q->ext_lock); | ||
89 | if (intr) | 107 | if (intr) |
90 | return wait_event_interruptible(vb->done, WAITON_CONDITION); | 108 | ret = wait_event_interruptible(vb->done, is_state_active_or_queued(q, vb)); |
91 | else | 109 | else |
92 | wait_event(vb->done, WAITON_CONDITION); | 110 | wait_event(vb->done, is_state_active_or_queued(q, vb)); |
111 | /* Relock */ | ||
112 | if (is_ext_locked) | ||
113 | mutex_lock(q->ext_lock); | ||
93 | 114 | ||
94 | return 0; | 115 | return ret; |
95 | } | 116 | } |
96 | EXPORT_SYMBOL_GPL(videobuf_waiton); | 117 | EXPORT_SYMBOL_GPL(videobuf_waiton); |
97 | 118 | ||
@@ -125,11 +146,13 @@ void videobuf_queue_core_init(struct videobuf_queue *q, | |||
125 | enum v4l2_field field, | 146 | enum v4l2_field field, |
126 | unsigned int msize, | 147 | unsigned int msize, |
127 | void *priv, | 148 | void *priv, |
128 | struct videobuf_qtype_ops *int_ops) | 149 | struct videobuf_qtype_ops *int_ops, |
150 | struct mutex *ext_lock) | ||
129 | { | 151 | { |
130 | BUG_ON(!q); | 152 | BUG_ON(!q); |
131 | memset(q, 0, sizeof(*q)); | 153 | memset(q, 0, sizeof(*q)); |
132 | q->irqlock = irqlock; | 154 | q->irqlock = irqlock; |
155 | q->ext_lock = ext_lock; | ||
133 | q->dev = dev; | 156 | q->dev = dev; |
134 | q->type = type; | 157 | q->type = type; |
135 | q->field = field; | 158 | q->field = field; |
@@ -350,9 +373,9 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, | |||
350 | int videobuf_mmap_free(struct videobuf_queue *q) | 373 | int videobuf_mmap_free(struct videobuf_queue *q) |
351 | { | 374 | { |
352 | int ret; | 375 | int ret; |
353 | mutex_lock(&q->vb_lock); | 376 | videobuf_queue_lock(q); |
354 | ret = __videobuf_free(q); | 377 | ret = __videobuf_free(q); |
355 | mutex_unlock(&q->vb_lock); | 378 | videobuf_queue_unlock(q); |
356 | return ret; | 379 | return ret; |
357 | } | 380 | } |
358 | EXPORT_SYMBOL_GPL(videobuf_mmap_free); | 381 | EXPORT_SYMBOL_GPL(videobuf_mmap_free); |
@@ -407,9 +430,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q, | |||
407 | enum v4l2_memory memory) | 430 | enum v4l2_memory memory) |
408 | { | 431 | { |
409 | int ret; | 432 | int ret; |
410 | mutex_lock(&q->vb_lock); | 433 | videobuf_queue_lock(q); |
411 | ret = __videobuf_mmap_setup(q, bcount, bsize, memory); | 434 | ret = __videobuf_mmap_setup(q, bcount, bsize, memory); |
412 | mutex_unlock(&q->vb_lock); | 435 | videobuf_queue_unlock(q); |
413 | return ret; | 436 | return ret; |
414 | } | 437 | } |
415 | EXPORT_SYMBOL_GPL(videobuf_mmap_setup); | 438 | EXPORT_SYMBOL_GPL(videobuf_mmap_setup); |
@@ -432,7 +455,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
432 | return -EINVAL; | 455 | return -EINVAL; |
433 | } | 456 | } |
434 | 457 | ||
435 | mutex_lock(&q->vb_lock); | 458 | videobuf_queue_lock(q); |
436 | if (req->type != q->type) { | 459 | if (req->type != q->type) { |
437 | dprintk(1, "reqbufs: queue type invalid\n"); | 460 | dprintk(1, "reqbufs: queue type invalid\n"); |
438 | retval = -EINVAL; | 461 | retval = -EINVAL; |
@@ -469,7 +492,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
469 | retval = 0; | 492 | retval = 0; |
470 | 493 | ||
471 | done: | 494 | done: |
472 | mutex_unlock(&q->vb_lock); | 495 | videobuf_queue_unlock(q); |
473 | return retval; | 496 | return retval; |
474 | } | 497 | } |
475 | EXPORT_SYMBOL_GPL(videobuf_reqbufs); | 498 | EXPORT_SYMBOL_GPL(videobuf_reqbufs); |
@@ -478,7 +501,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) | |||
478 | { | 501 | { |
479 | int ret = -EINVAL; | 502 | int ret = -EINVAL; |
480 | 503 | ||
481 | mutex_lock(&q->vb_lock); | 504 | videobuf_queue_lock(q); |
482 | if (unlikely(b->type != q->type)) { | 505 | if (unlikely(b->type != q->type)) { |
483 | dprintk(1, "querybuf: Wrong type.\n"); | 506 | dprintk(1, "querybuf: Wrong type.\n"); |
484 | goto done; | 507 | goto done; |
@@ -496,7 +519,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) | |||
496 | 519 | ||
497 | ret = 0; | 520 | ret = 0; |
498 | done: | 521 | done: |
499 | mutex_unlock(&q->vb_lock); | 522 | videobuf_queue_unlock(q); |
500 | return ret; | 523 | return ret; |
501 | } | 524 | } |
502 | EXPORT_SYMBOL_GPL(videobuf_querybuf); | 525 | EXPORT_SYMBOL_GPL(videobuf_querybuf); |
@@ -513,7 +536,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) | |||
513 | if (b->memory == V4L2_MEMORY_MMAP) | 536 | if (b->memory == V4L2_MEMORY_MMAP) |
514 | down_read(¤t->mm->mmap_sem); | 537 | down_read(¤t->mm->mmap_sem); |
515 | 538 | ||
516 | mutex_lock(&q->vb_lock); | 539 | videobuf_queue_lock(q); |
517 | retval = -EBUSY; | 540 | retval = -EBUSY; |
518 | if (q->reading) { | 541 | if (q->reading) { |
519 | dprintk(1, "qbuf: Reading running...\n"); | 542 | dprintk(1, "qbuf: Reading running...\n"); |
@@ -605,7 +628,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) | |||
605 | wake_up_interruptible_sync(&q->wait); | 628 | wake_up_interruptible_sync(&q->wait); |
606 | 629 | ||
607 | done: | 630 | done: |
608 | mutex_unlock(&q->vb_lock); | 631 | videobuf_queue_unlock(q); |
609 | 632 | ||
610 | if (b->memory == V4L2_MEMORY_MMAP) | 633 | if (b->memory == V4L2_MEMORY_MMAP) |
611 | up_read(¤t->mm->mmap_sem); | 634 | up_read(¤t->mm->mmap_sem); |
@@ -635,14 +658,14 @@ checks: | |||
635 | dprintk(2, "next_buffer: waiting on buffer\n"); | 658 | dprintk(2, "next_buffer: waiting on buffer\n"); |
636 | 659 | ||
637 | /* Drop lock to avoid deadlock with qbuf */ | 660 | /* Drop lock to avoid deadlock with qbuf */ |
638 | mutex_unlock(&q->vb_lock); | 661 | videobuf_queue_unlock(q); |
639 | 662 | ||
640 | /* Checking list_empty and streaming is safe without | 663 | /* Checking list_empty and streaming is safe without |
641 | * locks because we goto checks to validate while | 664 | * locks because we goto checks to validate while |
642 | * holding locks before proceeding */ | 665 | * holding locks before proceeding */ |
643 | retval = wait_event_interruptible(q->wait, | 666 | retval = wait_event_interruptible(q->wait, |
644 | !list_empty(&q->stream) || !q->streaming); | 667 | !list_empty(&q->stream) || !q->streaming); |
645 | mutex_lock(&q->vb_lock); | 668 | videobuf_queue_lock(q); |
646 | 669 | ||
647 | if (retval) | 670 | if (retval) |
648 | goto done; | 671 | goto done; |
@@ -669,7 +692,7 @@ static int stream_next_buffer(struct videobuf_queue *q, | |||
669 | goto done; | 692 | goto done; |
670 | 693 | ||
671 | buf = list_entry(q->stream.next, struct videobuf_buffer, stream); | 694 | buf = list_entry(q->stream.next, struct videobuf_buffer, stream); |
672 | retval = videobuf_waiton(buf, nonblocking, 1); | 695 | retval = videobuf_waiton(q, buf, nonblocking, 1); |
673 | if (retval < 0) | 696 | if (retval < 0) |
674 | goto done; | 697 | goto done; |
675 | 698 | ||
@@ -687,7 +710,7 @@ int videobuf_dqbuf(struct videobuf_queue *q, | |||
687 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 710 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
688 | 711 | ||
689 | memset(b, 0, sizeof(*b)); | 712 | memset(b, 0, sizeof(*b)); |
690 | mutex_lock(&q->vb_lock); | 713 | videobuf_queue_lock(q); |
691 | 714 | ||
692 | retval = stream_next_buffer(q, &buf, nonblocking); | 715 | retval = stream_next_buffer(q, &buf, nonblocking); |
693 | if (retval < 0) { | 716 | if (retval < 0) { |
@@ -713,7 +736,7 @@ int videobuf_dqbuf(struct videobuf_queue *q, | |||
713 | buf->state = VIDEOBUF_IDLE; | 736 | buf->state = VIDEOBUF_IDLE; |
714 | b->flags &= ~V4L2_BUF_FLAG_DONE; | 737 | b->flags &= ~V4L2_BUF_FLAG_DONE; |
715 | done: | 738 | done: |
716 | mutex_unlock(&q->vb_lock); | 739 | videobuf_queue_unlock(q); |
717 | return retval; | 740 | return retval; |
718 | } | 741 | } |
719 | EXPORT_SYMBOL_GPL(videobuf_dqbuf); | 742 | EXPORT_SYMBOL_GPL(videobuf_dqbuf); |
@@ -724,7 +747,7 @@ int videobuf_streamon(struct videobuf_queue *q) | |||
724 | unsigned long flags = 0; | 747 | unsigned long flags = 0; |
725 | int retval; | 748 | int retval; |
726 | 749 | ||
727 | mutex_lock(&q->vb_lock); | 750 | videobuf_queue_lock(q); |
728 | retval = -EBUSY; | 751 | retval = -EBUSY; |
729 | if (q->reading) | 752 | if (q->reading) |
730 | goto done; | 753 | goto done; |
@@ -740,7 +763,7 @@ int videobuf_streamon(struct videobuf_queue *q) | |||
740 | 763 | ||
741 | wake_up_interruptible_sync(&q->wait); | 764 | wake_up_interruptible_sync(&q->wait); |
742 | done: | 765 | done: |
743 | mutex_unlock(&q->vb_lock); | 766 | videobuf_queue_unlock(q); |
744 | return retval; | 767 | return retval; |
745 | } | 768 | } |
746 | EXPORT_SYMBOL_GPL(videobuf_streamon); | 769 | EXPORT_SYMBOL_GPL(videobuf_streamon); |
@@ -760,9 +783,9 @@ int videobuf_streamoff(struct videobuf_queue *q) | |||
760 | { | 783 | { |
761 | int retval; | 784 | int retval; |
762 | 785 | ||
763 | mutex_lock(&q->vb_lock); | 786 | videobuf_queue_lock(q); |
764 | retval = __videobuf_streamoff(q); | 787 | retval = __videobuf_streamoff(q); |
765 | mutex_unlock(&q->vb_lock); | 788 | videobuf_queue_unlock(q); |
766 | 789 | ||
767 | return retval; | 790 | return retval; |
768 | } | 791 | } |
@@ -797,7 +820,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, | |||
797 | spin_lock_irqsave(q->irqlock, flags); | 820 | spin_lock_irqsave(q->irqlock, flags); |
798 | q->ops->buf_queue(q, q->read_buf); | 821 | q->ops->buf_queue(q, q->read_buf); |
799 | spin_unlock_irqrestore(q->irqlock, flags); | 822 | spin_unlock_irqrestore(q->irqlock, flags); |
800 | retval = videobuf_waiton(q->read_buf, 0, 0); | 823 | retval = videobuf_waiton(q, q->read_buf, 0, 0); |
801 | if (0 == retval) { | 824 | if (0 == retval) { |
802 | CALL(q, sync, q, q->read_buf); | 825 | CALL(q, sync, q, q->read_buf); |
803 | if (VIDEOBUF_ERROR == q->read_buf->state) | 826 | if (VIDEOBUF_ERROR == q->read_buf->state) |
@@ -868,7 +891,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
868 | 891 | ||
869 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 892 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
870 | 893 | ||
871 | mutex_lock(&q->vb_lock); | 894 | videobuf_queue_lock(q); |
872 | 895 | ||
873 | q->ops->buf_setup(q, &nbufs, &size); | 896 | q->ops->buf_setup(q, &nbufs, &size); |
874 | 897 | ||
@@ -909,7 +932,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
909 | } | 932 | } |
910 | 933 | ||
911 | /* wait until capture is done */ | 934 | /* wait until capture is done */ |
912 | retval = videobuf_waiton(q->read_buf, nonblocking, 1); | 935 | retval = videobuf_waiton(q, q->read_buf, nonblocking, 1); |
913 | if (0 != retval) | 936 | if (0 != retval) |
914 | goto done; | 937 | goto done; |
915 | 938 | ||
@@ -938,7 +961,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
938 | } | 961 | } |
939 | 962 | ||
940 | done: | 963 | done: |
941 | mutex_unlock(&q->vb_lock); | 964 | videobuf_queue_unlock(q); |
942 | return retval; | 965 | return retval; |
943 | } | 966 | } |
944 | EXPORT_SYMBOL_GPL(videobuf_read_one); | 967 | EXPORT_SYMBOL_GPL(videobuf_read_one); |
@@ -999,9 +1022,9 @@ int videobuf_read_start(struct videobuf_queue *q) | |||
999 | { | 1022 | { |
1000 | int rc; | 1023 | int rc; |
1001 | 1024 | ||
1002 | mutex_lock(&q->vb_lock); | 1025 | videobuf_queue_lock(q); |
1003 | rc = __videobuf_read_start(q); | 1026 | rc = __videobuf_read_start(q); |
1004 | mutex_unlock(&q->vb_lock); | 1027 | videobuf_queue_unlock(q); |
1005 | 1028 | ||
1006 | return rc; | 1029 | return rc; |
1007 | } | 1030 | } |
@@ -1009,15 +1032,15 @@ EXPORT_SYMBOL_GPL(videobuf_read_start); | |||
1009 | 1032 | ||
1010 | void videobuf_read_stop(struct videobuf_queue *q) | 1033 | void videobuf_read_stop(struct videobuf_queue *q) |
1011 | { | 1034 | { |
1012 | mutex_lock(&q->vb_lock); | 1035 | videobuf_queue_lock(q); |
1013 | __videobuf_read_stop(q); | 1036 | __videobuf_read_stop(q); |
1014 | mutex_unlock(&q->vb_lock); | 1037 | videobuf_queue_unlock(q); |
1015 | } | 1038 | } |
1016 | EXPORT_SYMBOL_GPL(videobuf_read_stop); | 1039 | EXPORT_SYMBOL_GPL(videobuf_read_stop); |
1017 | 1040 | ||
1018 | void videobuf_stop(struct videobuf_queue *q) | 1041 | void videobuf_stop(struct videobuf_queue *q) |
1019 | { | 1042 | { |
1020 | mutex_lock(&q->vb_lock); | 1043 | videobuf_queue_lock(q); |
1021 | 1044 | ||
1022 | if (q->streaming) | 1045 | if (q->streaming) |
1023 | __videobuf_streamoff(q); | 1046 | __videobuf_streamoff(q); |
@@ -1025,7 +1048,7 @@ void videobuf_stop(struct videobuf_queue *q) | |||
1025 | if (q->reading) | 1048 | if (q->reading) |
1026 | __videobuf_read_stop(q); | 1049 | __videobuf_read_stop(q); |
1027 | 1050 | ||
1028 | mutex_unlock(&q->vb_lock); | 1051 | videobuf_queue_unlock(q); |
1029 | } | 1052 | } |
1030 | EXPORT_SYMBOL_GPL(videobuf_stop); | 1053 | EXPORT_SYMBOL_GPL(videobuf_stop); |
1031 | 1054 | ||
@@ -1039,7 +1062,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
1039 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 1062 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
1040 | 1063 | ||
1041 | dprintk(2, "%s\n", __func__); | 1064 | dprintk(2, "%s\n", __func__); |
1042 | mutex_lock(&q->vb_lock); | 1065 | videobuf_queue_lock(q); |
1043 | retval = -EBUSY; | 1066 | retval = -EBUSY; |
1044 | if (q->streaming) | 1067 | if (q->streaming) |
1045 | goto done; | 1068 | goto done; |
@@ -1059,7 +1082,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
1059 | list_del(&q->read_buf->stream); | 1082 | list_del(&q->read_buf->stream); |
1060 | q->read_off = 0; | 1083 | q->read_off = 0; |
1061 | } | 1084 | } |
1062 | rc = videobuf_waiton(q->read_buf, nonblocking, 1); | 1085 | rc = videobuf_waiton(q, q->read_buf, nonblocking, 1); |
1063 | if (rc < 0) { | 1086 | if (rc < 0) { |
1064 | if (0 == retval) | 1087 | if (0 == retval) |
1065 | retval = rc; | 1088 | retval = rc; |
@@ -1097,7 +1120,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, | |||
1097 | } | 1120 | } |
1098 | 1121 | ||
1099 | done: | 1122 | done: |
1100 | mutex_unlock(&q->vb_lock); | 1123 | videobuf_queue_unlock(q); |
1101 | return retval; | 1124 | return retval; |
1102 | } | 1125 | } |
1103 | EXPORT_SYMBOL_GPL(videobuf_read_stream); | 1126 | EXPORT_SYMBOL_GPL(videobuf_read_stream); |
@@ -1109,7 +1132,7 @@ unsigned int videobuf_poll_stream(struct file *file, | |||
1109 | struct videobuf_buffer *buf = NULL; | 1132 | struct videobuf_buffer *buf = NULL; |
1110 | unsigned int rc = 0; | 1133 | unsigned int rc = 0; |
1111 | 1134 | ||
1112 | mutex_lock(&q->vb_lock); | 1135 | videobuf_queue_lock(q); |
1113 | if (q->streaming) { | 1136 | if (q->streaming) { |
1114 | if (!list_empty(&q->stream)) | 1137 | if (!list_empty(&q->stream)) |
1115 | buf = list_entry(q->stream.next, | 1138 | buf = list_entry(q->stream.next, |
@@ -1147,7 +1170,7 @@ unsigned int videobuf_poll_stream(struct file *file, | |||
1147 | } | 1170 | } |
1148 | } | 1171 | } |
1149 | } | 1172 | } |
1150 | mutex_unlock(&q->vb_lock); | 1173 | videobuf_queue_unlock(q); |
1151 | return rc; | 1174 | return rc; |
1152 | } | 1175 | } |
1153 | EXPORT_SYMBOL_GPL(videobuf_poll_stream); | 1176 | EXPORT_SYMBOL_GPL(videobuf_poll_stream); |
@@ -1164,7 +1187,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) | |||
1164 | return -EINVAL; | 1187 | return -EINVAL; |
1165 | } | 1188 | } |
1166 | 1189 | ||
1167 | mutex_lock(&q->vb_lock); | 1190 | videobuf_queue_lock(q); |
1168 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 1191 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
1169 | struct videobuf_buffer *buf = q->bufs[i]; | 1192 | struct videobuf_buffer *buf = q->bufs[i]; |
1170 | 1193 | ||
@@ -1174,7 +1197,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) | |||
1174 | break; | 1197 | break; |
1175 | } | 1198 | } |
1176 | } | 1199 | } |
1177 | mutex_unlock(&q->vb_lock); | 1200 | videobuf_queue_unlock(q); |
1178 | 1201 | ||
1179 | return rc; | 1202 | return rc; |
1180 | } | 1203 | } |
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 6ff9e4bac3e..c9691115f2d 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -28,7 +28,6 @@ struct videobuf_dma_contig_memory { | |||
28 | void *vaddr; | 28 | void *vaddr; |
29 | dma_addr_t dma_handle; | 29 | dma_addr_t dma_handle; |
30 | unsigned long size; | 30 | unsigned long size; |
31 | int is_userptr; | ||
32 | }; | 31 | }; |
33 | 32 | ||
34 | #define MAGIC_DC_MEM 0x0733ac61 | 33 | #define MAGIC_DC_MEM 0x0733ac61 |
@@ -63,7 +62,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
63 | struct videobuf_dma_contig_memory *mem; | 62 | struct videobuf_dma_contig_memory *mem; |
64 | 63 | ||
65 | dev_dbg(q->dev, "munmap %p q=%p\n", map, q); | 64 | dev_dbg(q->dev, "munmap %p q=%p\n", map, q); |
66 | mutex_lock(&q->vb_lock); | 65 | videobuf_queue_lock(q); |
67 | 66 | ||
68 | /* We need first to cancel streams, before unmapping */ | 67 | /* We need first to cancel streams, before unmapping */ |
69 | if (q->streaming) | 68 | if (q->streaming) |
@@ -103,7 +102,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
103 | 102 | ||
104 | kfree(map); | 103 | kfree(map); |
105 | 104 | ||
106 | mutex_unlock(&q->vb_lock); | 105 | videobuf_queue_unlock(q); |
107 | } | 106 | } |
108 | } | 107 | } |
109 | 108 | ||
@@ -120,7 +119,6 @@ static const struct vm_operations_struct videobuf_vm_ops = { | |||
120 | */ | 119 | */ |
121 | static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem) | 120 | static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem) |
122 | { | 121 | { |
123 | mem->is_userptr = 0; | ||
124 | mem->dma_handle = 0; | 122 | mem->dma_handle = 0; |
125 | mem->size = 0; | 123 | mem->size = 0; |
126 | } | 124 | } |
@@ -147,7 +145,6 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, | |||
147 | 145 | ||
148 | offset = vb->baddr & ~PAGE_MASK; | 146 | offset = vb->baddr & ~PAGE_MASK; |
149 | mem->size = PAGE_ALIGN(vb->size + offset); | 147 | mem->size = PAGE_ALIGN(vb->size + offset); |
150 | mem->is_userptr = 0; | ||
151 | ret = -EINVAL; | 148 | ret = -EINVAL; |
152 | 149 | ||
153 | down_read(&mm->mmap_sem); | 150 | down_read(&mm->mmap_sem); |
@@ -181,9 +178,6 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, | |||
181 | pages_done++; | 178 | pages_done++; |
182 | } | 179 | } |
183 | 180 | ||
184 | if (!ret) | ||
185 | mem->is_userptr = 1; | ||
186 | |||
187 | out_up: | 181 | out_up: |
188 | up_read(¤t->mm->mmap_sem); | 182 | up_read(¤t->mm->mmap_sem); |
189 | 183 | ||
@@ -349,10 +343,11 @@ void videobuf_queue_dma_contig_init(struct videobuf_queue *q, | |||
349 | enum v4l2_buf_type type, | 343 | enum v4l2_buf_type type, |
350 | enum v4l2_field field, | 344 | enum v4l2_field field, |
351 | unsigned int msize, | 345 | unsigned int msize, |
352 | void *priv) | 346 | void *priv, |
347 | struct mutex *ext_lock) | ||
353 | { | 348 | { |
354 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, | 349 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, |
355 | priv, &qops); | 350 | priv, &qops, ext_lock); |
356 | } | 351 | } |
357 | EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init); | 352 | EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init); |
358 | 353 | ||
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 2ad0bc252b0..20f227ee2b3 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -116,8 +116,8 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, | |||
116 | goto nopage; | 116 | goto nopage; |
117 | if (PageHighMem(pages[i])) | 117 | if (PageHighMem(pages[i])) |
118 | goto highmem; | 118 | goto highmem; |
119 | sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0); | 119 | sg_set_page(&sglist[i], pages[i], min_t(size_t, PAGE_SIZE, size), 0); |
120 | size -= min(PAGE_SIZE, size); | 120 | size -= min_t(size_t, PAGE_SIZE, size); |
121 | } | 121 | } |
122 | return sglist; | 122 | return sglist; |
123 | 123 | ||
@@ -358,7 +358,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
358 | map->count--; | 358 | map->count--; |
359 | if (0 == map->count) { | 359 | if (0 == map->count) { |
360 | dprintk(1, "munmap %p q=%p\n", map, q); | 360 | dprintk(1, "munmap %p q=%p\n", map, q); |
361 | mutex_lock(&q->vb_lock); | 361 | videobuf_queue_lock(q); |
362 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 362 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
363 | if (NULL == q->bufs[i]) | 363 | if (NULL == q->bufs[i]) |
364 | continue; | 364 | continue; |
@@ -374,7 +374,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
374 | q->bufs[i]->baddr = 0; | 374 | q->bufs[i]->baddr = 0; |
375 | q->ops->buf_release(q, q->bufs[i]); | 375 | q->ops->buf_release(q, q->bufs[i]); |
376 | } | 376 | } |
377 | mutex_unlock(&q->vb_lock); | 377 | videobuf_queue_unlock(q); |
378 | kfree(map); | 378 | kfree(map); |
379 | } | 379 | } |
380 | return; | 380 | return; |
@@ -654,10 +654,11 @@ void videobuf_queue_sg_init(struct videobuf_queue *q, | |||
654 | enum v4l2_buf_type type, | 654 | enum v4l2_buf_type type, |
655 | enum v4l2_field field, | 655 | enum v4l2_field field, |
656 | unsigned int msize, | 656 | unsigned int msize, |
657 | void *priv) | 657 | void *priv, |
658 | struct mutex *ext_lock) | ||
658 | { | 659 | { |
659 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, | 660 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, |
660 | priv, &sg_ops); | 661 | priv, &sg_ops, ext_lock); |
661 | } | 662 | } |
662 | EXPORT_SYMBOL_GPL(videobuf_queue_sg_init); | 663 | EXPORT_SYMBOL_GPL(videobuf_queue_sg_init); |
663 | 664 | ||
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index 3f76398968b..3de7c7e4402 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c | |||
@@ -57,7 +57,7 @@ static int videobuf_dvb_thread(void *data) | |||
57 | buf = list_entry(dvb->dvbq.stream.next, | 57 | buf = list_entry(dvb->dvbq.stream.next, |
58 | struct videobuf_buffer, stream); | 58 | struct videobuf_buffer, stream); |
59 | list_del(&buf->stream); | 59 | list_del(&buf->stream); |
60 | err = videobuf_waiton(buf,0,1); | 60 | err = videobuf_waiton(&dvb->dvbq, buf, 0, 1); |
61 | 61 | ||
62 | /* no more feeds left or stop_feed() asked us to quit */ | 62 | /* no more feeds left or stop_feed() asked us to quit */ |
63 | if (0 == dvb->nfeeds) | 63 | if (0 == dvb->nfeeds) |
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index e7fe31d54f0..df142580e44 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c | |||
@@ -75,7 +75,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
75 | struct videobuf_vmalloc_memory *mem; | 75 | struct videobuf_vmalloc_memory *mem; |
76 | 76 | ||
77 | dprintk(1, "munmap %p q=%p\n", map, q); | 77 | dprintk(1, "munmap %p q=%p\n", map, q); |
78 | mutex_lock(&q->vb_lock); | 78 | videobuf_queue_lock(q); |
79 | 79 | ||
80 | /* We need first to cancel streams, before unmapping */ | 80 | /* We need first to cancel streams, before unmapping */ |
81 | if (q->streaming) | 81 | if (q->streaming) |
@@ -114,7 +114,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
114 | 114 | ||
115 | kfree(map); | 115 | kfree(map); |
116 | 116 | ||
117 | mutex_unlock(&q->vb_lock); | 117 | videobuf_queue_unlock(q); |
118 | } | 118 | } |
119 | 119 | ||
120 | return; | 120 | return; |
@@ -304,10 +304,11 @@ void videobuf_queue_vmalloc_init(struct videobuf_queue *q, | |||
304 | enum v4l2_buf_type type, | 304 | enum v4l2_buf_type type, |
305 | enum v4l2_field field, | 305 | enum v4l2_field field, |
306 | unsigned int msize, | 306 | unsigned int msize, |
307 | void *priv) | 307 | void *priv, |
308 | struct mutex *ext_lock) | ||
308 | { | 309 | { |
309 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, | 310 | videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, |
310 | priv, &qops); | 311 | priv, &qops, ext_lock); |
311 | } | 312 | } |
312 | EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init); | 313 | EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init); |
313 | 314 | ||
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 3eb15f72ac0..e5e005dc155 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -4334,10 +4334,10 @@ static int __init vino_module_init(void) | |||
4334 | 4334 | ||
4335 | vino_drvdata->decoder = | 4335 | vino_drvdata->decoder = |
4336 | v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter, | 4336 | v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter, |
4337 | "saa7191", "saa7191", 0, I2C_ADDRS(0x45)); | 4337 | NULL, "saa7191", 0, I2C_ADDRS(0x45)); |
4338 | vino_drvdata->camera = | 4338 | vino_drvdata->camera = |
4339 | v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter, | 4339 | v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter, |
4340 | "indycam", "indycam", 0, I2C_ADDRS(0x2b)); | 4340 | NULL, "indycam", 0, I2C_ADDRS(0x2b)); |
4341 | 4341 | ||
4342 | dprintk("init complete!\n"); | 4342 | dprintk("init complete!\n"); |
4343 | 4343 | ||
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index e17b6fee046..9797e5a6926 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -820,14 +820,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
820 | struct v4l2_format *f) | 820 | struct v4l2_format *f) |
821 | { | 821 | { |
822 | struct vivi_dev *dev = video_drvdata(file); | 822 | struct vivi_dev *dev = video_drvdata(file); |
823 | struct videobuf_queue *q = &dev->vb_vidq; | ||
824 | 823 | ||
825 | int ret = vidioc_try_fmt_vid_cap(file, priv, f); | 824 | int ret = vidioc_try_fmt_vid_cap(file, priv, f); |
826 | if (ret < 0) | 825 | if (ret < 0) |
827 | return ret; | 826 | return ret; |
828 | 827 | ||
829 | mutex_lock(&q->vb_lock); | ||
830 | |||
831 | if (vivi_is_generating(dev)) { | 828 | if (vivi_is_generating(dev)) { |
832 | dprintk(dev, 1, "%s device busy\n", __func__); | 829 | dprintk(dev, 1, "%s device busy\n", __func__); |
833 | ret = -EBUSY; | 830 | ret = -EBUSY; |
@@ -840,7 +837,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
840 | dev->vb_vidq.field = f->fmt.pix.field; | 837 | dev->vb_vidq.field = f->fmt.pix.field; |
841 | ret = 0; | 838 | ret = 0; |
842 | out: | 839 | out: |
843 | mutex_unlock(&q->vb_lock); | ||
844 | return ret; | 840 | return ret; |
845 | } | 841 | } |
846 | 842 | ||
@@ -1086,7 +1082,7 @@ static const struct v4l2_file_operations vivi_fops = { | |||
1086 | .release = vivi_close, | 1082 | .release = vivi_close, |
1087 | .read = vivi_read, | 1083 | .read = vivi_read, |
1088 | .poll = vivi_poll, | 1084 | .poll = vivi_poll, |
1089 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1085 | .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1090 | .mmap = vivi_mmap, | 1086 | .mmap = vivi_mmap, |
1091 | }; | 1087 | }; |
1092 | 1088 | ||
@@ -1173,19 +1169,19 @@ static int __init vivi_create_instance(int inst) | |||
1173 | dev->saturation = 127; | 1169 | dev->saturation = 127; |
1174 | dev->hue = 0; | 1170 | dev->hue = 0; |
1175 | 1171 | ||
1172 | /* initialize locks */ | ||
1173 | spin_lock_init(&dev->slock); | ||
1174 | mutex_init(&dev->mutex); | ||
1175 | |||
1176 | videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops, | 1176 | videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops, |
1177 | NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1177 | NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1178 | V4L2_FIELD_INTERLACED, | 1178 | V4L2_FIELD_INTERLACED, |
1179 | sizeof(struct vivi_buffer), dev); | 1179 | sizeof(struct vivi_buffer), dev, &dev->mutex); |
1180 | 1180 | ||
1181 | /* init video dma queues */ | 1181 | /* init video dma queues */ |
1182 | INIT_LIST_HEAD(&dev->vidq.active); | 1182 | INIT_LIST_HEAD(&dev->vidq.active); |
1183 | init_waitqueue_head(&dev->vidq.wq); | 1183 | init_waitqueue_head(&dev->vidq.wq); |
1184 | 1184 | ||
1185 | /* initialize locks */ | ||
1186 | spin_lock_init(&dev->slock); | ||
1187 | mutex_init(&dev->mutex); | ||
1188 | |||
1189 | ret = -ENOMEM; | 1185 | ret = -ENOMEM; |
1190 | vfd = video_device_alloc(); | 1186 | vfd = video_device_alloc(); |
1191 | if (!vfd) | 1187 | if (!vfd) |
@@ -1194,6 +1190,7 @@ static int __init vivi_create_instance(int inst) | |||
1194 | *vfd = vivi_template; | 1190 | *vfd = vivi_template; |
1195 | vfd->debug = debug; | 1191 | vfd->debug = debug; |
1196 | vfd->v4l2_dev = &dev->v4l2_dev; | 1192 | vfd->v4l2_dev = &dev->v4l2_dev; |
1193 | vfd->lock = &dev->mutex; | ||
1197 | 1194 | ||
1198 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | 1195 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); |
1199 | if (ret < 0) | 1196 | if (ret < 0) |
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index ca8303bd240..c15efb6e777 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c | |||
@@ -27,11 +27,9 @@ | |||
27 | #include <linux/ioctl.h> | 27 | #include <linux/ioctl.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/i2c-id.h> | ||
31 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
32 | #include <media/v4l2-device.h> | 31 | #include <media/v4l2-device.h> |
33 | #include <media/v4l2-chip-ident.h> | 32 | #include <media/v4l2-chip-ident.h> |
34 | #include <media/v4l2-i2c-drv.h> | ||
35 | 33 | ||
36 | MODULE_DESCRIPTION("vp27smpx driver"); | 34 | MODULE_DESCRIPTION("vp27smpx driver"); |
37 | MODULE_AUTHOR("Hans Verkuil"); | 35 | MODULE_AUTHOR("Hans Verkuil"); |
@@ -200,9 +198,25 @@ static const struct i2c_device_id vp27smpx_id[] = { | |||
200 | }; | 198 | }; |
201 | MODULE_DEVICE_TABLE(i2c, vp27smpx_id); | 199 | MODULE_DEVICE_TABLE(i2c, vp27smpx_id); |
202 | 200 | ||
203 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 201 | static struct i2c_driver vp27smpx_driver = { |
204 | .name = "vp27smpx", | 202 | .driver = { |
205 | .probe = vp27smpx_probe, | 203 | .owner = THIS_MODULE, |
206 | .remove = vp27smpx_remove, | 204 | .name = "vp27smpx", |
207 | .id_table = vp27smpx_id, | 205 | }, |
206 | .probe = vp27smpx_probe, | ||
207 | .remove = vp27smpx_remove, | ||
208 | .id_table = vp27smpx_id, | ||
208 | }; | 209 | }; |
210 | |||
211 | static __init int init_vp27smpx(void) | ||
212 | { | ||
213 | return i2c_add_driver(&vp27smpx_driver); | ||
214 | } | ||
215 | |||
216 | static __exit void exit_vp27smpx(void) | ||
217 | { | ||
218 | i2c_del_driver(&vp27smpx_driver); | ||
219 | } | ||
220 | |||
221 | module_init(init_vp27smpx); | ||
222 | module_exit(exit_vp27smpx); | ||
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 77ebcea7c3d..91a01b3cdf8 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/videodev2.h> | 28 | #include <linux/videodev2.h> |
29 | #include <media/v4l2-device.h> | 29 | #include <media/v4l2-device.h> |
30 | #include <media/v4l2-chip-ident.h> | 30 | #include <media/v4l2-chip-ident.h> |
31 | #include <media/v4l2-i2c-drv.h> | ||
32 | 31 | ||
33 | MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); | 32 | MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); |
34 | MODULE_AUTHOR("Laurent Pinchart"); | 33 | MODULE_AUTHOR("Laurent Pinchart"); |
@@ -614,9 +613,25 @@ static const struct i2c_device_id vpx3220_id[] = { | |||
614 | }; | 613 | }; |
615 | MODULE_DEVICE_TABLE(i2c, vpx3220_id); | 614 | MODULE_DEVICE_TABLE(i2c, vpx3220_id); |
616 | 615 | ||
617 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 616 | static struct i2c_driver vpx3220_driver = { |
618 | .name = "vpx3220", | 617 | .driver = { |
619 | .probe = vpx3220_probe, | 618 | .owner = THIS_MODULE, |
620 | .remove = vpx3220_remove, | 619 | .name = "vpx3220", |
621 | .id_table = vpx3220_id, | 620 | }, |
621 | .probe = vpx3220_probe, | ||
622 | .remove = vpx3220_remove, | ||
623 | .id_table = vpx3220_id, | ||
622 | }; | 624 | }; |
625 | |||
626 | static __init int init_vpx3220(void) | ||
627 | { | ||
628 | return i2c_add_driver(&vpx3220_driver); | ||
629 | } | ||
630 | |||
631 | static __exit void exit_vpx3220(void) | ||
632 | { | ||
633 | i2c_del_driver(&vpx3220_driver); | ||
634 | } | ||
635 | |||
636 | module_init(init_vpx3220); | ||
637 | module_exit(exit_vpx3220); | ||
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index d5965543eca..a22f765e968 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
31 | #include <media/v4l2-device.h> | 31 | #include <media/v4l2-device.h> |
32 | #include <media/v4l2-chip-ident.h> | 32 | #include <media/v4l2-chip-ident.h> |
33 | #include <media/v4l2-i2c-drv.h> | ||
34 | #include <media/v4l2-ctrls.h> | 33 | #include <media/v4l2-ctrls.h> |
35 | 34 | ||
36 | MODULE_DESCRIPTION("wm8739 driver"); | 35 | MODULE_DESCRIPTION("wm8739 driver"); |
@@ -282,9 +281,25 @@ static const struct i2c_device_id wm8739_id[] = { | |||
282 | }; | 281 | }; |
283 | MODULE_DEVICE_TABLE(i2c, wm8739_id); | 282 | MODULE_DEVICE_TABLE(i2c, wm8739_id); |
284 | 283 | ||
285 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 284 | static struct i2c_driver wm8739_driver = { |
286 | .name = "wm8739", | 285 | .driver = { |
287 | .probe = wm8739_probe, | 286 | .owner = THIS_MODULE, |
288 | .remove = wm8739_remove, | 287 | .name = "wm8739", |
289 | .id_table = wm8739_id, | 288 | }, |
289 | .probe = wm8739_probe, | ||
290 | .remove = wm8739_remove, | ||
291 | .id_table = wm8739_id, | ||
290 | }; | 292 | }; |
293 | |||
294 | static __init int init_wm8739(void) | ||
295 | { | ||
296 | return i2c_add_driver(&wm8739_driver); | ||
297 | } | ||
298 | |||
299 | static __exit void exit_wm8739(void) | ||
300 | { | ||
301 | i2c_del_driver(&wm8739_driver); | ||
302 | } | ||
303 | |||
304 | module_init(init_wm8739); | ||
305 | module_exit(exit_wm8739); | ||
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index 23bad3fd6dc..13552564908 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c | |||
@@ -31,12 +31,11 @@ | |||
31 | #include <linux/ioctl.h> | 31 | #include <linux/ioctl.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
34 | #include <linux/i2c-id.h> | ||
35 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
36 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
37 | #include <media/v4l2-chip-ident.h> | 36 | #include <media/v4l2-chip-ident.h> |
38 | #include <media/v4l2-ctrls.h> | 37 | #include <media/v4l2-ctrls.h> |
39 | #include <media/v4l2-i2c-drv.h> | 38 | #include <media/wm8775.h> |
40 | 39 | ||
41 | MODULE_DESCRIPTION("wm8775 driver"); | 40 | MODULE_DESCRIPTION("wm8775 driver"); |
42 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); | 41 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); |
@@ -52,10 +51,16 @@ enum { | |||
52 | TOT_REGS | 51 | TOT_REGS |
53 | }; | 52 | }; |
54 | 53 | ||
54 | #define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */ | ||
55 | #define ALC_EN 0x100 /* R17: ALC enable */ | ||
56 | |||
55 | struct wm8775_state { | 57 | struct wm8775_state { |
56 | struct v4l2_subdev sd; | 58 | struct v4l2_subdev sd; |
57 | struct v4l2_ctrl_handler hdl; | 59 | struct v4l2_ctrl_handler hdl; |
58 | struct v4l2_ctrl *mute; | 60 | struct v4l2_ctrl *mute; |
61 | struct v4l2_ctrl *vol; | ||
62 | struct v4l2_ctrl *bal; | ||
63 | struct v4l2_ctrl *loud; | ||
59 | u8 input; /* Last selected input (0-0xf) */ | 64 | u8 input; /* Last selected input (0-0xf) */ |
60 | }; | 65 | }; |
61 | 66 | ||
@@ -87,6 +92,30 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val) | |||
87 | return -1; | 92 | return -1; |
88 | } | 93 | } |
89 | 94 | ||
95 | static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly) | ||
96 | { | ||
97 | struct wm8775_state *state = to_state(sd); | ||
98 | u8 vol_l, vol_r; | ||
99 | int muted = 0 != state->mute->val; | ||
100 | u16 volume = (u16)state->vol->val; | ||
101 | u16 balance = (u16)state->bal->val; | ||
102 | |||
103 | /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */ | ||
104 | vol_l = (min(65536 - balance, 32768) * volume) >> 23; | ||
105 | vol_r = (min(balance, (u16)32768) * volume) >> 23; | ||
106 | |||
107 | /* Mute */ | ||
108 | if (muted || quietly) | ||
109 | wm8775_write(sd, R21, 0x0c0 | state->input); | ||
110 | |||
111 | wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */ | ||
112 | wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */ | ||
113 | |||
114 | /* Un-mute */ | ||
115 | if (!muted) | ||
116 | wm8775_write(sd, R21, state->input); | ||
117 | } | ||
118 | |||
90 | static int wm8775_s_routing(struct v4l2_subdev *sd, | 119 | static int wm8775_s_routing(struct v4l2_subdev *sd, |
91 | u32 input, u32 output, u32 config) | 120 | u32 input, u32 output, u32 config) |
92 | { | 121 | { |
@@ -104,25 +133,26 @@ static int wm8775_s_routing(struct v4l2_subdev *sd, | |||
104 | state->input = input; | 133 | state->input = input; |
105 | if (!v4l2_ctrl_g_ctrl(state->mute)) | 134 | if (!v4l2_ctrl_g_ctrl(state->mute)) |
106 | return 0; | 135 | return 0; |
107 | wm8775_write(sd, R21, 0x0c0); | 136 | if (!v4l2_ctrl_g_ctrl(state->vol)) |
108 | wm8775_write(sd, R14, 0x1d4); | 137 | return 0; |
109 | wm8775_write(sd, R15, 0x1d4); | 138 | if (!v4l2_ctrl_g_ctrl(state->bal)) |
110 | wm8775_write(sd, R21, 0x100 + state->input); | 139 | return 0; |
140 | wm8775_set_audio(sd, 1); | ||
111 | return 0; | 141 | return 0; |
112 | } | 142 | } |
113 | 143 | ||
114 | static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) | 144 | static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) |
115 | { | 145 | { |
116 | struct v4l2_subdev *sd = to_sd(ctrl); | 146 | struct v4l2_subdev *sd = to_sd(ctrl); |
117 | struct wm8775_state *state = to_state(sd); | ||
118 | 147 | ||
119 | switch (ctrl->id) { | 148 | switch (ctrl->id) { |
120 | case V4L2_CID_AUDIO_MUTE: | 149 | case V4L2_CID_AUDIO_MUTE: |
121 | wm8775_write(sd, R21, 0x0c0); | 150 | case V4L2_CID_AUDIO_VOLUME: |
122 | wm8775_write(sd, R14, 0x1d4); | 151 | case V4L2_CID_AUDIO_BALANCE: |
123 | wm8775_write(sd, R15, 0x1d4); | 152 | wm8775_set_audio(sd, 0); |
124 | if (!ctrl->val) | 153 | return 0; |
125 | wm8775_write(sd, R21, 0x100 + state->input); | 154 | case V4L2_CID_AUDIO_LOUDNESS: |
155 | wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD); | ||
126 | return 0; | 156 | return 0; |
127 | } | 157 | } |
128 | return -EINVAL; | 158 | return -EINVAL; |
@@ -146,16 +176,7 @@ static int wm8775_log_status(struct v4l2_subdev *sd) | |||
146 | 176 | ||
147 | static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) | 177 | static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) |
148 | { | 178 | { |
149 | struct wm8775_state *state = to_state(sd); | 179 | wm8775_set_audio(sd, 0); |
150 | |||
151 | /* If I remove this, then it can happen that I have no | ||
152 | sound the first time I tune from static to a valid channel. | ||
153 | It's difficult to reproduce and is almost certainly related | ||
154 | to the zero cross detect circuit. */ | ||
155 | wm8775_write(sd, R21, 0x0c0); | ||
156 | wm8775_write(sd, R14, 0x1d4); | ||
157 | wm8775_write(sd, R15, 0x1d4); | ||
158 | wm8775_write(sd, R21, 0x100 + state->input); | ||
159 | return 0; | 180 | return 0; |
160 | } | 181 | } |
161 | 182 | ||
@@ -205,6 +226,7 @@ static int wm8775_probe(struct i2c_client *client, | |||
205 | { | 226 | { |
206 | struct wm8775_state *state; | 227 | struct wm8775_state *state; |
207 | struct v4l2_subdev *sd; | 228 | struct v4l2_subdev *sd; |
229 | int err; | ||
208 | 230 | ||
209 | /* Check if the adapter supports the needed features */ | 231 | /* Check if the adapter supports the needed features */ |
210 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 232 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
@@ -218,15 +240,21 @@ static int wm8775_probe(struct i2c_client *client, | |||
218 | return -ENOMEM; | 240 | return -ENOMEM; |
219 | sd = &state->sd; | 241 | sd = &state->sd; |
220 | v4l2_i2c_subdev_init(sd, client, &wm8775_ops); | 242 | v4l2_i2c_subdev_init(sd, client, &wm8775_ops); |
243 | sd->grp_id = WM8775_GID; /* subdev group id */ | ||
221 | state->input = 2; | 244 | state->input = 2; |
222 | 245 | ||
223 | v4l2_ctrl_handler_init(&state->hdl, 1); | 246 | v4l2_ctrl_handler_init(&state->hdl, 4); |
224 | state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | 247 | state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, |
225 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | 248 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); |
249 | state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | ||
250 | V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/ | ||
251 | state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | ||
252 | V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768); | ||
253 | state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | ||
254 | V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1); | ||
226 | sd->ctrl_handler = &state->hdl; | 255 | sd->ctrl_handler = &state->hdl; |
227 | if (state->hdl.error) { | 256 | err = state->hdl.error; |
228 | int err = state->hdl.error; | 257 | if (err) { |
229 | |||
230 | v4l2_ctrl_handler_free(&state->hdl); | 258 | v4l2_ctrl_handler_free(&state->hdl); |
231 | kfree(state); | 259 | kfree(state); |
232 | return err; | 260 | return err; |
@@ -238,29 +266,25 @@ static int wm8775_probe(struct i2c_client *client, | |||
238 | wm8775_write(sd, R23, 0x000); | 266 | wm8775_write(sd, R23, 0x000); |
239 | /* Disable zero cross detect timeout */ | 267 | /* Disable zero cross detect timeout */ |
240 | wm8775_write(sd, R7, 0x000); | 268 | wm8775_write(sd, R7, 0x000); |
241 | /* Left justified, 24-bit mode */ | 269 | /* HPF enable, I2S mode, 24-bit */ |
242 | wm8775_write(sd, R11, 0x021); | 270 | wm8775_write(sd, R11, 0x022); |
243 | /* Master mode, clock ratio 256fs */ | 271 | /* Master mode, clock ratio 256fs */ |
244 | wm8775_write(sd, R12, 0x102); | 272 | wm8775_write(sd, R12, 0x102); |
245 | /* Powered up */ | 273 | /* Powered up */ |
246 | wm8775_write(sd, R13, 0x000); | 274 | wm8775_write(sd, R13, 0x000); |
247 | /* ADC gain +2.5dB, enable zero cross */ | 275 | /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */ |
248 | wm8775_write(sd, R14, 0x1d4); | 276 | wm8775_write(sd, R16, 0x1bb); |
249 | /* ADC gain +2.5dB, enable zero cross */ | 277 | /* Set ALC mode and hold time */ |
250 | wm8775_write(sd, R15, 0x1d4); | 278 | wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD); |
251 | /* ALC Stereo, ALC target level -1dB FS max gain +8dB */ | ||
252 | wm8775_write(sd, R16, 0x1bf); | ||
253 | /* Enable gain control, use zero cross detection, | ||
254 | ALC hold time 42.6 ms */ | ||
255 | wm8775_write(sd, R17, 0x185); | ||
256 | /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ | 279 | /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ |
257 | wm8775_write(sd, R18, 0x0a2); | 280 | wm8775_write(sd, R18, 0x0a2); |
258 | /* Enable noise gate, threshold -72dBfs */ | 281 | /* Enable noise gate, threshold -72dBfs */ |
259 | wm8775_write(sd, R19, 0x005); | 282 | wm8775_write(sd, R19, 0x005); |
260 | /* Transient window 4ms, lower PGA gain limit -1dB */ | 283 | /* Transient window 4ms, ALC min gain -5dB */ |
261 | wm8775_write(sd, R20, 0x07a); | 284 | wm8775_write(sd, R20, 0x0fb); |
262 | /* LRBOTH = 1, use input 2. */ | 285 | |
263 | wm8775_write(sd, R21, 0x102); | 286 | wm8775_set_audio(sd, 1); /* set volume/mute/mux */ |
287 | |||
264 | return 0; | 288 | return 0; |
265 | } | 289 | } |
266 | 290 | ||
@@ -281,9 +305,25 @@ static const struct i2c_device_id wm8775_id[] = { | |||
281 | }; | 305 | }; |
282 | MODULE_DEVICE_TABLE(i2c, wm8775_id); | 306 | MODULE_DEVICE_TABLE(i2c, wm8775_id); |
283 | 307 | ||
284 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 308 | static struct i2c_driver wm8775_driver = { |
285 | .name = "wm8775", | 309 | .driver = { |
286 | .probe = wm8775_probe, | 310 | .owner = THIS_MODULE, |
287 | .remove = wm8775_remove, | 311 | .name = "wm8775", |
288 | .id_table = wm8775_id, | 312 | }, |
313 | .probe = wm8775_probe, | ||
314 | .remove = wm8775_remove, | ||
315 | .id_table = wm8775_id, | ||
289 | }; | 316 | }; |
317 | |||
318 | static __init int init_wm8775(void) | ||
319 | { | ||
320 | return i2c_add_driver(&wm8775_driver); | ||
321 | } | ||
322 | |||
323 | static __exit void exit_wm8775(void) | ||
324 | { | ||
325 | i2c_del_driver(&wm8775_driver); | ||
326 | } | ||
327 | |||
328 | module_init(init_wm8775); | ||
329 | module_exit(exit_wm8775); | ||
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 307e847fe1c..37fe16181e3 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h | |||
@@ -341,10 +341,8 @@ struct card_info { | |||
341 | enum card_type type; | 341 | enum card_type type; |
342 | char name[32]; | 342 | char name[32]; |
343 | const char *i2c_decoder; /* i2c decoder device */ | 343 | const char *i2c_decoder; /* i2c decoder device */ |
344 | const char *mod_decoder; /* i2c decoder module */ | ||
345 | const unsigned short *addrs_decoder; | 344 | const unsigned short *addrs_decoder; |
346 | const char *i2c_encoder; /* i2c encoder device */ | 345 | const char *i2c_encoder; /* i2c encoder device */ |
347 | const char *mod_encoder; /* i2c encoder module */ | ||
348 | const unsigned short *addrs_encoder; | 346 | const unsigned short *addrs_encoder; |
349 | u16 video_vfe, video_codec; /* videocodec types */ | 347 | u16 video_vfe, video_codec; /* videocodec types */ |
350 | u16 audio_chip; /* audio type */ | 348 | u16 audio_chip; /* audio type */ |
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index bfcd3aef50f..0aac376c3f7 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c | |||
@@ -379,7 +379,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
379 | .type = DC10_old, | 379 | .type = DC10_old, |
380 | .name = "DC10(old)", | 380 | .name = "DC10(old)", |
381 | .i2c_decoder = "vpx3220a", | 381 | .i2c_decoder = "vpx3220a", |
382 | .mod_decoder = "vpx3220", | ||
383 | .addrs_decoder = vpx3220_addrs, | 382 | .addrs_decoder = vpx3220_addrs, |
384 | .video_codec = CODEC_TYPE_ZR36050, | 383 | .video_codec = CODEC_TYPE_ZR36050, |
385 | .video_vfe = CODEC_TYPE_ZR36016, | 384 | .video_vfe = CODEC_TYPE_ZR36016, |
@@ -409,10 +408,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
409 | .type = DC10_new, | 408 | .type = DC10_new, |
410 | .name = "DC10(new)", | 409 | .name = "DC10(new)", |
411 | .i2c_decoder = "saa7110", | 410 | .i2c_decoder = "saa7110", |
412 | .mod_decoder = "saa7110", | ||
413 | .addrs_decoder = saa7110_addrs, | 411 | .addrs_decoder = saa7110_addrs, |
414 | .i2c_encoder = "adv7175", | 412 | .i2c_encoder = "adv7175", |
415 | .mod_encoder = "adv7175", | ||
416 | .addrs_encoder = adv717x_addrs, | 413 | .addrs_encoder = adv717x_addrs, |
417 | .video_codec = CODEC_TYPE_ZR36060, | 414 | .video_codec = CODEC_TYPE_ZR36060, |
418 | 415 | ||
@@ -440,10 +437,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
440 | .type = DC10plus, | 437 | .type = DC10plus, |
441 | .name = "DC10plus", | 438 | .name = "DC10plus", |
442 | .i2c_decoder = "saa7110", | 439 | .i2c_decoder = "saa7110", |
443 | .mod_decoder = "saa7110", | ||
444 | .addrs_decoder = saa7110_addrs, | 440 | .addrs_decoder = saa7110_addrs, |
445 | .i2c_encoder = "adv7175", | 441 | .i2c_encoder = "adv7175", |
446 | .mod_encoder = "adv7175", | ||
447 | .addrs_encoder = adv717x_addrs, | 442 | .addrs_encoder = adv717x_addrs, |
448 | .video_codec = CODEC_TYPE_ZR36060, | 443 | .video_codec = CODEC_TYPE_ZR36060, |
449 | 444 | ||
@@ -472,10 +467,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
472 | .type = DC30, | 467 | .type = DC30, |
473 | .name = "DC30", | 468 | .name = "DC30", |
474 | .i2c_decoder = "vpx3220a", | 469 | .i2c_decoder = "vpx3220a", |
475 | .mod_decoder = "vpx3220", | ||
476 | .addrs_decoder = vpx3220_addrs, | 470 | .addrs_decoder = vpx3220_addrs, |
477 | .i2c_encoder = "adv7175", | 471 | .i2c_encoder = "adv7175", |
478 | .mod_encoder = "adv7175", | ||
479 | .addrs_encoder = adv717x_addrs, | 472 | .addrs_encoder = adv717x_addrs, |
480 | .video_codec = CODEC_TYPE_ZR36050, | 473 | .video_codec = CODEC_TYPE_ZR36050, |
481 | .video_vfe = CODEC_TYPE_ZR36016, | 474 | .video_vfe = CODEC_TYPE_ZR36016, |
@@ -505,10 +498,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
505 | .type = DC30plus, | 498 | .type = DC30plus, |
506 | .name = "DC30plus", | 499 | .name = "DC30plus", |
507 | .i2c_decoder = "vpx3220a", | 500 | .i2c_decoder = "vpx3220a", |
508 | .mod_decoder = "vpx3220", | ||
509 | .addrs_decoder = vpx3220_addrs, | 501 | .addrs_decoder = vpx3220_addrs, |
510 | .i2c_encoder = "adv7175", | 502 | .i2c_encoder = "adv7175", |
511 | .mod_encoder = "adv7175", | ||
512 | .addrs_encoder = adv717x_addrs, | 503 | .addrs_encoder = adv717x_addrs, |
513 | .video_codec = CODEC_TYPE_ZR36050, | 504 | .video_codec = CODEC_TYPE_ZR36050, |
514 | .video_vfe = CODEC_TYPE_ZR36016, | 505 | .video_vfe = CODEC_TYPE_ZR36016, |
@@ -538,10 +529,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
538 | .type = LML33, | 529 | .type = LML33, |
539 | .name = "LML33", | 530 | .name = "LML33", |
540 | .i2c_decoder = "bt819a", | 531 | .i2c_decoder = "bt819a", |
541 | .mod_decoder = "bt819", | ||
542 | .addrs_decoder = bt819_addrs, | 532 | .addrs_decoder = bt819_addrs, |
543 | .i2c_encoder = "bt856", | 533 | .i2c_encoder = "bt856", |
544 | .mod_encoder = "bt856", | ||
545 | .addrs_encoder = bt856_addrs, | 534 | .addrs_encoder = bt856_addrs, |
546 | .video_codec = CODEC_TYPE_ZR36060, | 535 | .video_codec = CODEC_TYPE_ZR36060, |
547 | 536 | ||
@@ -569,10 +558,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
569 | .type = LML33R10, | 558 | .type = LML33R10, |
570 | .name = "LML33R10", | 559 | .name = "LML33R10", |
571 | .i2c_decoder = "saa7114", | 560 | .i2c_decoder = "saa7114", |
572 | .mod_decoder = "saa7115", | ||
573 | .addrs_decoder = saa7114_addrs, | 561 | .addrs_decoder = saa7114_addrs, |
574 | .i2c_encoder = "adv7170", | 562 | .i2c_encoder = "adv7170", |
575 | .mod_encoder = "adv7170", | ||
576 | .addrs_encoder = adv717x_addrs, | 563 | .addrs_encoder = adv717x_addrs, |
577 | .video_codec = CODEC_TYPE_ZR36060, | 564 | .video_codec = CODEC_TYPE_ZR36060, |
578 | 565 | ||
@@ -600,10 +587,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
600 | .type = BUZ, | 587 | .type = BUZ, |
601 | .name = "Buz", | 588 | .name = "Buz", |
602 | .i2c_decoder = "saa7111", | 589 | .i2c_decoder = "saa7111", |
603 | .mod_decoder = "saa7115", | ||
604 | .addrs_decoder = saa7111_addrs, | 590 | .addrs_decoder = saa7111_addrs, |
605 | .i2c_encoder = "saa7185", | 591 | .i2c_encoder = "saa7185", |
606 | .mod_encoder = "saa7185", | ||
607 | .addrs_encoder = saa7185_addrs, | 592 | .addrs_encoder = saa7185_addrs, |
608 | .video_codec = CODEC_TYPE_ZR36060, | 593 | .video_codec = CODEC_TYPE_ZR36060, |
609 | 594 | ||
@@ -633,10 +618,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
633 | /* AverMedia chose not to brand the 6-Eyes. Thus it | 618 | /* AverMedia chose not to brand the 6-Eyes. Thus it |
634 | can't be autodetected, and requires card=x. */ | 619 | can't be autodetected, and requires card=x. */ |
635 | .i2c_decoder = "ks0127", | 620 | .i2c_decoder = "ks0127", |
636 | .mod_decoder = "ks0127", | ||
637 | .addrs_decoder = ks0127_addrs, | 621 | .addrs_decoder = ks0127_addrs, |
638 | .i2c_encoder = "bt866", | 622 | .i2c_encoder = "bt866", |
639 | .mod_encoder = "bt866", | ||
640 | .addrs_encoder = bt866_addrs, | 623 | .addrs_encoder = bt866_addrs, |
641 | .video_codec = CODEC_TYPE_ZR36060, | 624 | .video_codec = CODEC_TYPE_ZR36060, |
642 | 625 | ||
@@ -1359,13 +1342,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev, | |||
1359 | } | 1342 | } |
1360 | 1343 | ||
1361 | zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, | 1344 | zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, |
1362 | &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder, | 1345 | &zr->i2c_adapter, NULL, zr->card.i2c_decoder, |
1363 | 0, zr->card.addrs_decoder); | 1346 | 0, zr->card.addrs_decoder); |
1364 | 1347 | ||
1365 | if (zr->card.mod_encoder) | 1348 | if (zr->card.i2c_encoder) |
1366 | zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, | 1349 | zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, |
1367 | &zr->i2c_adapter, | 1350 | &zr->i2c_adapter, |
1368 | zr->card.mod_encoder, zr->card.i2c_encoder, | 1351 | NULL, zr->card.i2c_encoder, |
1369 | 0, zr->card.addrs_encoder); | 1352 | 0, zr->card.addrs_encoder); |
1370 | 1353 | ||
1371 | dprintk(2, | 1354 | dprintk(2, |
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c index 6f846abee3e..b02007e4215 100644 --- a/drivers/media/video/zoran/zoran_device.c +++ b/drivers/media/video/zoran/zoran_device.c | |||
@@ -1470,8 +1470,7 @@ zoran_irq (int irq, | |||
1470 | (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | 1470 | (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || |
1471 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { | 1471 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { |
1472 | if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { | 1472 | if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { |
1473 | char sc[] = "0000"; | 1473 | char sv[BUZ_NUM_STAT_COM + 1]; |
1474 | char sv[5]; | ||
1475 | int i; | 1474 | int i; |
1476 | 1475 | ||
1477 | printk(KERN_INFO | 1476 | printk(KERN_INFO |
@@ -1481,12 +1480,9 @@ zoran_irq (int irq, | |||
1481 | zr->jpg_settings.field_per_buff, | 1480 | zr->jpg_settings.field_per_buff, |
1482 | zr->JPEG_missed); | 1481 | zr->JPEG_missed); |
1483 | 1482 | ||
1484 | strcpy(sv, sc); | 1483 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) |
1485 | for (i = 0; i < 4; i++) { | 1484 | sv[i] = le32_to_cpu(zr->stat_com[i]) & 1 ? '1' : '0'; |
1486 | if (le32_to_cpu(zr->stat_com[i]) & 1) | 1485 | sv[BUZ_NUM_STAT_COM] = 0; |
1487 | sv[i] = '1'; | ||
1488 | } | ||
1489 | sv[4] = 0; | ||
1490 | printk(KERN_INFO | 1486 | printk(KERN_INFO |
1491 | "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", | 1487 | "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", |
1492 | ZR_DEVNAME(zr), sv, | 1488 | ZR_DEVNAME(zr), sv, |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 3c471a4e3e4..401082b853f 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -3322,7 +3322,7 @@ zoran_mmap (struct file *file, | |||
3322 | mmap_unlock_and_return: | 3322 | mmap_unlock_and_return: |
3323 | mutex_unlock(&zr->resource_lock); | 3323 | mutex_unlock(&zr->resource_lock); |
3324 | 3324 | ||
3325 | return 0; | 3325 | return res; |
3326 | } | 3326 | } |
3327 | 3327 | ||
3328 | static const struct v4l2_ioctl_ops zoran_ioctl_ops = { | 3328 | static const struct v4l2_ioctl_ops zoran_ioctl_ops = { |
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index a82b5bd18d2..7dfb01e9930 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
@@ -572,7 +572,7 @@ static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize) | |||
572 | DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); | 572 | DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); |
573 | unlock: | 573 | unlock: |
574 | spin_unlock_irqrestore(&cam->slock, flags); | 574 | spin_unlock_irqrestore(&cam->slock, flags); |
575 | return 0; | 575 | return rc; |
576 | } | 576 | } |
577 | 577 | ||
578 | /* this function moves the usb stream read pipe data | 578 | /* this function moves the usb stream read pipe data |
@@ -1304,7 +1304,7 @@ static int zr364xx_open(struct file *file) | |||
1304 | NULL, &cam->slock, | 1304 | NULL, &cam->slock, |
1305 | cam->type, | 1305 | cam->type, |
1306 | V4L2_FIELD_NONE, | 1306 | V4L2_FIELD_NONE, |
1307 | sizeof(struct zr364xx_buffer), cam); | 1307 | sizeof(struct zr364xx_buffer), cam, NULL); |
1308 | 1308 | ||
1309 | /* Added some delay here, since opening/closing the camera quickly, | 1309 | /* Added some delay here, since opening/closing the camera quickly, |
1310 | * like Ekiga does during its startup, can crash the webcam | 1310 | * like Ekiga does during its startup, can crash the webcam |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 8e03e760023..2ea91e04925 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -51,6 +51,10 @@ source "drivers/staging/cx25821/Kconfig" | |||
51 | 51 | ||
52 | source "drivers/staging/tm6000/Kconfig" | 52 | source "drivers/staging/tm6000/Kconfig" |
53 | 53 | ||
54 | source "drivers/staging/cpia/Kconfig" | ||
55 | |||
56 | source "drivers/staging/stradis/Kconfig" | ||
57 | |||
54 | source "drivers/staging/usbip/Kconfig" | 58 | source "drivers/staging/usbip/Kconfig" |
55 | 59 | ||
56 | source "drivers/staging/winbond/Kconfig" | 60 | source "drivers/staging/winbond/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 0e7d7559d37..c359fbb0e04 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -8,6 +8,8 @@ obj-$(CONFIG_SLICOSS) += slicoss/ | |||
8 | obj-$(CONFIG_VIDEO_GO7007) += go7007/ | 8 | obj-$(CONFIG_VIDEO_GO7007) += go7007/ |
9 | obj-$(CONFIG_VIDEO_CX25821) += cx25821/ | 9 | obj-$(CONFIG_VIDEO_CX25821) += cx25821/ |
10 | obj-$(CONFIG_VIDEO_TM6000) += tm6000/ | 10 | obj-$(CONFIG_VIDEO_TM6000) += tm6000/ |
11 | obj-$(CONFIG_VIDEO_CPIA) += cpia/ | ||
12 | obj-$(CONFIG_VIDEO_STRADIS) += stradis/ | ||
11 | obj-$(CONFIG_LIRC_STAGING) += lirc/ | 13 | obj-$(CONFIG_LIRC_STAGING) += lirc/ |
12 | obj-$(CONFIG_USB_IP_COMMON) += usbip/ | 14 | obj-$(CONFIG_USB_IP_COMMON) += usbip/ |
13 | obj-$(CONFIG_W35UND) += winbond/ | 15 | obj-$(CONFIG_W35UND) += winbond/ |
diff --git a/drivers/staging/cpia/Kconfig b/drivers/staging/cpia/Kconfig new file mode 100644 index 00000000000..205d247ad37 --- /dev/null +++ b/drivers/staging/cpia/Kconfig | |||
@@ -0,0 +1,39 @@ | |||
1 | config VIDEO_CPIA | ||
2 | tristate "CPiA Video For Linux (DEPRECATED)" | ||
3 | depends on VIDEO_V4L1 | ||
4 | default n | ||
5 | ---help--- | ||
6 | This driver is DEPRECATED please use the gspca cpia1 module | ||
7 | instead. Note that you need atleast version 0.6.4 of libv4l for | ||
8 | the cpia1 gspca module. | ||
9 | |||
10 | This is the video4linux driver for cameras based on Vision's CPiA | ||
11 | (Colour Processor Interface ASIC), such as the Creative Labs Video | ||
12 | Blaster Webcam II. If you have one of these cameras, say Y here | ||
13 | and select parallel port and/or USB lowlevel support below, | ||
14 | otherwise say N. This will not work with the Creative Webcam III. | ||
15 | |||
16 | Please read <file:Documentation/video4linux/README.cpia> for more | ||
17 | information. | ||
18 | |||
19 | This driver is also available as a module (cpia). | ||
20 | |||
21 | config VIDEO_CPIA_PP | ||
22 | tristate "CPiA Parallel Port Lowlevel Support" | ||
23 | depends on PARPORT_1284 && VIDEO_CPIA && PARPORT | ||
24 | help | ||
25 | This is the lowlevel parallel port support for cameras based on | ||
26 | Vision's CPiA (Colour Processor Interface ASIC), such as the | ||
27 | Creative Webcam II. If you have the parallel port version of one | ||
28 | of these cameras, say Y here, otherwise say N. It is also available | ||
29 | as a module (cpia_pp). | ||
30 | |||
31 | config VIDEO_CPIA_USB | ||
32 | tristate "CPiA USB Lowlevel Support" | ||
33 | depends on VIDEO_CPIA && USB | ||
34 | help | ||
35 | This is the lowlevel USB support for cameras based on Vision's CPiA | ||
36 | (Colour Processor Interface ASIC), such as the Creative Webcam II. | ||
37 | If you have the USB version of one of these cameras, say Y here, | ||
38 | otherwise say N. This will not work with the Creative Webcam III. | ||
39 | It is also available as a module (cpia_usb). | ||
diff --git a/drivers/staging/cpia/Makefile b/drivers/staging/cpia/Makefile new file mode 100644 index 00000000000..89e52f10d73 --- /dev/null +++ b/drivers/staging/cpia/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-$(CONFIG_VIDEO_CPIA) += cpia.o | ||
2 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o | ||
3 | obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o | ||
4 | |||
5 | EXTRA_CFLAGS += -Idrivers/media/video | ||
diff --git a/drivers/staging/cpia/TODO b/drivers/staging/cpia/TODO new file mode 100644 index 00000000000..ccb1c0775ee --- /dev/null +++ b/drivers/staging/cpia/TODO | |||
@@ -0,0 +1,8 @@ | |||
1 | This is an obsolete driver for some cpia-based webcams that use the parallel port. | ||
2 | We couldn't find anyone with this hardware in order to port it to use V4L2. | ||
3 | |||
4 | Also, parallel-port webcams are obsolete nowadays. | ||
5 | |||
6 | If nobody take care on it, the driver will be removed for 2.6.38. | ||
7 | |||
8 | Please send patches to linux-media@vger.kernel.org | ||
diff --git a/drivers/media/video/cpia.c b/drivers/staging/cpia/cpia.c index 933ae4c8cb9..933ae4c8cb9 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/staging/cpia/cpia.c | |||
diff --git a/drivers/media/video/cpia.h b/drivers/staging/cpia/cpia.h index 8f0cfee4b8a..8f0cfee4b8a 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/staging/cpia/cpia.h | |||
diff --git a/drivers/media/video/cpia_pp.c b/drivers/staging/cpia/cpia_pp.c index f5604c16a09..f5604c16a09 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/staging/cpia/cpia_pp.c | |||
diff --git a/drivers/media/video/cpia_usb.c b/drivers/staging/cpia/cpia_usb.c index 58d193ff591..58d193ff591 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/staging/cpia/cpia_usb.c | |||
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig index 813cb355ac0..1d73334d2a4 100644 --- a/drivers/staging/cx25821/Kconfig +++ b/drivers/staging/cx25821/Kconfig | |||
@@ -5,7 +5,7 @@ config VIDEO_CX25821 | |||
5 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
6 | select VIDEO_BTCX | 6 | select VIDEO_BTCX |
7 | select VIDEO_TVEEPROM | 7 | select VIDEO_TVEEPROM |
8 | select VIDEO_IR | 8 | depends on VIDEO_IR |
9 | select VIDEOBUF_DVB | 9 | select VIDEOBUF_DVB |
10 | select VIDEOBUF_DMA_SG | 10 | select VIDEOBUF_DMA_SG |
11 | select VIDEO_CX25840 | 11 | select VIDEO_CX25840 |
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c index bbe36437ac1..2a01dc057b2 100644 --- a/drivers/staging/cx25821/cx25821-alsa.c +++ b/drivers/staging/cx25821/cx25821-alsa.c | |||
@@ -629,7 +629,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device, | |||
629 | * Only boards with eeprom and byte 1 at eeprom=1 have it | 629 | * Only boards with eeprom and byte 1 at eeprom=1 have it |
630 | */ | 630 | */ |
631 | 631 | ||
632 | static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = { | 632 | static const struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = { |
633 | {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 633 | {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
634 | {0,} | 634 | {0,} |
635 | }; | 635 | }; |
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c index cdff49f409f..6f3200666c9 100644 --- a/drivers/staging/cx25821/cx25821-audio-upstream.c +++ b/drivers/staging/cx25821/cx25821-audio-upstream.c | |||
@@ -40,8 +40,8 @@ MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | |||
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | 41 | ||
42 | static int _intr_msk = | 42 | static int _intr_msk = |
43 | FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC | | 43 | FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC | |
44 | FLD_AUD_SRC_OPC_ERR; | 44 | FLD_AUD_SRC_OPC_ERR; |
45 | 45 | ||
46 | int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev, | 46 | int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev, |
47 | struct sram_channel *ch, | 47 | struct sram_channel *ch, |
@@ -506,7 +506,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
506 | { | 506 | { |
507 | int i = 0; | 507 | int i = 0; |
508 | u32 int_msk_tmp; | 508 | u32 int_msk_tmp; |
509 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | 509 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; |
510 | dma_addr_t risc_phys_jump_addr; | 510 | dma_addr_t risc_phys_jump_addr; |
511 | __le32 *rp; | 511 | __le32 *rp; |
512 | 512 | ||
@@ -608,7 +608,7 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) | |||
608 | if (!dev) | 608 | if (!dev) |
609 | return -1; | 609 | return -1; |
610 | 610 | ||
611 | sram_ch = dev->channels[dev->_audio_upstream_channel_select]. | 611 | sram_ch = dev->channels[dev->_audio_upstream_channel_select]. |
612 | sram_channels; | 612 | sram_channels; |
613 | 613 | ||
614 | msk_stat = cx_read(sram_ch->int_mstat); | 614 | msk_stat = cx_read(sram_ch->int_mstat); |
@@ -733,7 +733,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) | |||
733 | } | 733 | } |
734 | 734 | ||
735 | dev->_audio_upstream_channel_select = channel_select; | 735 | dev->_audio_upstream_channel_select = channel_select; |
736 | sram_ch = dev->channels[channel_select].sram_channels; | 736 | sram_ch = dev->channels[channel_select].sram_channels; |
737 | 737 | ||
738 | /* Work queue */ | 738 | /* Work queue */ |
739 | INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler); | 739 | INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler); |
@@ -764,9 +764,8 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) | |||
764 | str_length + 1); | 764 | str_length + 1); |
765 | 765 | ||
766 | /* Default if filename is empty string */ | 766 | /* Default if filename is empty string */ |
767 | if (strcmp(dev->input_audiofilename, "") == 0) { | 767 | if (strcmp(dev->input_audiofilename, "") == 0) |
768 | dev->_audiofilename = "/root/audioGOOD.wav"; | 768 | dev->_audiofilename = "/root/audioGOOD.wav"; |
769 | } | ||
770 | } else { | 769 | } else { |
771 | str_length = strlen(_defaultAudioName); | 770 | str_length = strlen(_defaultAudioName); |
772 | dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); | 771 | dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); |
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/staging/cx25821/cx25821-audio-upstream.h index ca987addf81..668a4f11e80 100644 --- a/drivers/staging/cx25821/cx25821-audio-upstream.h +++ b/drivers/staging/cx25821/cx25821-audio-upstream.h | |||
@@ -46,11 +46,11 @@ | |||
46 | #define USE_RISC_NOOP_AUDIO 1 | 46 | #define USE_RISC_NOOP_AUDIO 1 |
47 | 47 | ||
48 | #ifdef USE_RISC_NOOP_AUDIO | 48 | #ifdef USE_RISC_NOOP_AUDIO |
49 | #define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE + RISC_JUMP_INSTRUCTION_SIZE) | 49 | #define AUDIO_RISC_DMA_BUF_SIZE (LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE + RISC_JUMP_INSTRUCTION_SIZE) |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #ifndef USE_RISC_NOOP_AUDIO | 52 | #ifndef USE_RISC_NOOP_AUDIO |
53 | #define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE) | 53 | #define AUDIO_RISC_DMA_BUF_SIZE (LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE) |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | static int _line_size; | 56 | static int _line_size; |
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h index 434b2a312a8..a702a0db21d 100644 --- a/drivers/staging/cx25821/cx25821-audio.h +++ b/drivers/staging/cx25821/cx25821-audio.h | |||
@@ -31,18 +31,18 @@ | |||
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 + RISC_WRITECR_INSTRUCTION_SIZE*4) | 39 | (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */ | 42 | /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */ |
43 | #ifdef USE_RISC_NOOP | 43 | #ifdef USE_RISC_NOOP |
44 | #define MAX_BUFFER_PROGRAM_SIZE \ | 44 | #define MAX_BUFFER_PROGRAM_SIZE \ |
45 | (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4) | 45 | (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4) |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | /* Sizes of various instructions in bytes. Used when adding instructions. */ | 48 | /* Sizes of various instructions in bytes. Used when adding instructions. */ |
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c index c487c19256b..ca1eece3df0 100644 --- a/drivers/staging/cx25821/cx25821-core.c +++ b/drivers/staging/cx25821/cx25821-core.c | |||
@@ -42,7 +42,7 @@ static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; | |||
42 | module_param_array(card, int, NULL, 0444); | 42 | module_param_array(card, int, NULL, 0444); |
43 | MODULE_PARM_DESC(card, "card type"); | 43 | MODULE_PARM_DESC(card, "card type"); |
44 | 44 | ||
45 | static unsigned int cx25821_devcount = 0; | 45 | static unsigned int cx25821_devcount; |
46 | 46 | ||
47 | static DEFINE_MUTEX(devlist); | 47 | static DEFINE_MUTEX(devlist); |
48 | LIST_HEAD(cx25821_devlist); | 48 | LIST_HEAD(cx25821_devlist); |
@@ -781,14 +781,14 @@ static void cx25821_shutdown(struct cx25821_dev *dev) | |||
781 | 781 | ||
782 | /* Disable Video A/B activity */ | 782 | /* Disable Video A/B activity */ |
783 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | 783 | for (i = 0; i < VID_CHANNEL_NUM; i++) { |
784 | cx_write(dev->channels[i].sram_channels->dma_ctl, 0); | 784 | cx_write(dev->channels[i].sram_channels->dma_ctl, 0); |
785 | cx_write(dev->channels[i].sram_channels->int_msk, 0); | 785 | cx_write(dev->channels[i].sram_channels->int_msk, 0); |
786 | } | 786 | } |
787 | 787 | ||
788 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J; | 788 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; |
789 | i++) { | 789 | i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { |
790 | cx_write(dev->channels[i].sram_channels->dma_ctl, 0); | 790 | cx_write(dev->channels[i].sram_channels->dma_ctl, 0); |
791 | cx_write(dev->channels[i].sram_channels->int_msk, 0); | 791 | cx_write(dev->channels[i].sram_channels->int_msk, 0); |
792 | } | 792 | } |
793 | 793 | ||
794 | /* Disable Audio activity */ | 794 | /* Disable Audio activity */ |
@@ -806,9 +806,9 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, | |||
806 | u32 format) | 806 | u32 format) |
807 | { | 807 | { |
808 | if (channel_select <= 7 && channel_select >= 0) { | 808 | if (channel_select <= 7 && channel_select >= 0) { |
809 | cx_write(dev->channels[channel_select]. | 809 | cx_write(dev->channels[channel_select]. |
810 | sram_channels->pix_frmt, format); | 810 | sram_channels->pix_frmt, format); |
811 | dev->channels[channel_select].pixel_formats = format; | 811 | dev->channels[channel_select].pixel_formats = format; |
812 | } | 812 | } |
813 | } | 813 | } |
814 | 814 | ||
@@ -829,7 +829,7 @@ static void cx25821_initialize(struct cx25821_dev *dev) | |||
829 | cx_write(PCI_INT_STAT, 0xffffffff); | 829 | cx_write(PCI_INT_STAT, 0xffffffff); |
830 | 830 | ||
831 | for (i = 0; i < VID_CHANNEL_NUM; i++) | 831 | for (i = 0; i < VID_CHANNEL_NUM; i++) |
832 | cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); | 832 | cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); |
833 | 833 | ||
834 | cx_write(AUD_A_INT_STAT, 0xffffffff); | 834 | cx_write(AUD_A_INT_STAT, 0xffffffff); |
835 | cx_write(AUD_B_INT_STAT, 0xffffffff); | 835 | cx_write(AUD_B_INT_STAT, 0xffffffff); |
@@ -843,22 +843,22 @@ static void cx25821_initialize(struct cx25821_dev *dev) | |||
843 | mdelay(100); | 843 | mdelay(100); |
844 | 844 | ||
845 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | 845 | for (i = 0; i < VID_CHANNEL_NUM; i++) { |
846 | cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); | 846 | cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); |
847 | cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels, | 847 | cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels, |
848 | 1440, 0); | 848 | 1440, 0); |
849 | dev->channels[i].pixel_formats = PIXEL_FRMT_422; | 849 | dev->channels[i].pixel_formats = PIXEL_FRMT_422; |
850 | dev->channels[i].use_cif_resolution = FALSE; | 850 | dev->channels[i].use_cif_resolution = FALSE; |
851 | } | 851 | } |
852 | 852 | ||
853 | /* Probably only affect Downstream */ | 853 | /* Probably only affect Downstream */ |
854 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J; | 854 | for (i = VID_UPSTREAM_SRAM_CHANNEL_I; |
855 | i++) { | 855 | i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { |
856 | cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); | 856 | cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); |
857 | } | 857 | } |
858 | 858 | ||
859 | cx25821_sram_channel_setup_audio(dev, | 859 | cx25821_sram_channel_setup_audio(dev, |
860 | dev->channels[SRAM_CH08].sram_channels, | 860 | dev->channels[SRAM_CH08].sram_channels, |
861 | 128, 0); | 861 | 128, 0); |
862 | 862 | ||
863 | cx25821_gpio_init(dev); | 863 | cx25821_gpio_init(dev); |
864 | } | 864 | } |
@@ -931,8 +931,8 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
931 | 931 | ||
932 | /* Apply a sensible clock frequency for the PCIe bridge */ | 932 | /* Apply a sensible clock frequency for the PCIe bridge */ |
933 | dev->clk_freq = 28000000; | 933 | dev->clk_freq = 28000000; |
934 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) | 934 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) |
935 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; | 935 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; |
936 | 936 | ||
937 | if (dev->nr > 1) | 937 | if (dev->nr > 1) |
938 | CX25821_INFO("dev->nr > 1!"); | 938 | CX25821_INFO("dev->nr > 1!"); |
@@ -1003,11 +1003,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
1003 | 1003 | ||
1004 | cx25821_card_setup(dev); | 1004 | cx25821_card_setup(dev); |
1005 | 1005 | ||
1006 | if (medusa_video_init(dev) < 0) | 1006 | if (medusa_video_init(dev) < 0) |
1007 | CX25821_ERR("%s() Failed to initialize medusa!\n" | 1007 | CX25821_ERR("%s() Failed to initialize medusa!\n" |
1008 | , __func__); | 1008 | , __func__); |
1009 | 1009 | ||
1010 | cx25821_video_register(dev); | 1010 | cx25821_video_register(dev); |
1011 | 1011 | ||
1012 | /* register IOCTL device */ | 1012 | /* register IOCTL device */ |
1013 | dev->ioctl_dev = | 1013 | dev->ioctl_dev = |
@@ -1319,7 +1319,7 @@ void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf) | |||
1319 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 1319 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
1320 | 1320 | ||
1321 | BUG_ON(in_interrupt()); | 1321 | BUG_ON(in_interrupt()); |
1322 | videobuf_waiton(&buf->vb, 0, 0); | 1322 | videobuf_waiton(q, &buf->vb, 0, 0); |
1323 | videobuf_dma_unmap(q->dev, dma); | 1323 | videobuf_dma_unmap(q->dev, dma); |
1324 | videobuf_dma_free(dma); | 1324 | videobuf_dma_free(dma); |
1325 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); | 1325 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); |
@@ -1342,12 +1342,12 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id) | |||
1342 | 1342 | ||
1343 | for (i = 0; i < VID_CHANNEL_NUM; i++) { | 1343 | for (i = 0; i < VID_CHANNEL_NUM; i++) { |
1344 | if (pci_status & mask[i]) { | 1344 | if (pci_status & mask[i]) { |
1345 | vid_status = cx_read(dev->channels[i]. | 1345 | vid_status = cx_read(dev->channels[i]. |
1346 | sram_channels->int_stat); | 1346 | sram_channels->int_stat); |
1347 | 1347 | ||
1348 | if (vid_status) | 1348 | if (vid_status) |
1349 | handled += | 1349 | handled += |
1350 | cx25821_video_irq(dev, i, vid_status); | 1350 | cx25821_video_irq(dev, i, vid_status); |
1351 | 1351 | ||
1352 | cx_write(PCI_INT_STAT, mask[i]); | 1352 | cx_write(PCI_INT_STAT, mask[i]); |
1353 | } | 1353 | } |
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c index e43572e61ec..2b14bcca689 100644 --- a/drivers/staging/cx25821/cx25821-i2c.c +++ b/drivers/staging/cx25821/cx25821-i2c.c | |||
@@ -283,7 +283,7 @@ static struct i2c_algorithm cx25821_i2c_algo_template = { | |||
283 | .master_xfer = i2c_xfer, | 283 | .master_xfer = i2c_xfer, |
284 | .functionality = cx25821_functionality, | 284 | .functionality = cx25821_functionality, |
285 | #ifdef NEED_ALGO_CONTROL | 285 | #ifdef NEED_ALGO_CONTROL |
286 | .algo_control = dummy_algo_control, | 286 | .algo_control = dummy_algo_control, |
287 | #endif | 287 | #endif |
288 | }; | 288 | }; |
289 | 289 | ||
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/staging/cx25821/cx25821-medusa-reg.h index f7f33b3e705..1c1c228352d 100644 --- a/drivers/staging/cx25821/cx25821-medusa-reg.h +++ b/drivers/staging/cx25821/cx25821-medusa-reg.h | |||
@@ -443,13 +443,13 @@ | |||
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 | ||
449 | /*****************************************************************************/ | 449 | /*****************************************************************************/ |
450 | /* CHROMA_CTRL register fields */ | 450 | /* CHROMA_CTRL register fields */ |
451 | #define VDEC_A_USAT_CTRL 0x1018 | 451 | #define VDEC_A_USAT_CTRL 0x1018 |
452 | #define VDEC_A_VSAT_CTRL 0x1019 | 452 | #define VDEC_A_VSAT_CTRL 0x1019 |
453 | #define VDEC_A_HUE_CTRL 0x101A | 453 | #define VDEC_A_HUE_CTRL 0x101A |
454 | 454 | ||
455 | #endif | 455 | #endif |
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c index ef9f2b82a86..1e11e0ce2d0 100644 --- a/drivers/staging/cx25821/cx25821-medusa-video.c +++ b/drivers/staging/cx25821/cx25821-medusa-video.c | |||
@@ -778,9 +778,9 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) | |||
778 | 778 | ||
779 | int medusa_video_init(struct cx25821_dev *dev) | 779 | int medusa_video_init(struct cx25821_dev *dev) |
780 | { | 780 | { |
781 | u32 value = 0, tmp = 0; | 781 | u32 value = 0, tmp = 0; |
782 | int ret_val = 0; | 782 | int ret_val = 0; |
783 | int i = 0; | 783 | int i = 0; |
784 | 784 | ||
785 | mutex_lock(&dev->lock); | 785 | mutex_lock(&dev->lock); |
786 | 786 | ||
@@ -829,7 +829,7 @@ int medusa_video_init(struct cx25821_dev *dev) | |||
829 | /* select AFE clock to output mode */ | 829 | /* select AFE clock to output mode */ |
830 | value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); | 830 | value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); |
831 | value &= 0x83FFFFFF; | 831 | value &= 0x83FFFFFF; |
832 | ret_val = | 832 | ret_val = |
833 | cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, | 833 | cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, |
834 | value | 0x10000000); | 834 | value | 0x10000000); |
835 | 835 | ||
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h index cfe0f32db37..a3fc25a4dc0 100644 --- a/drivers/staging/cx25821/cx25821-reg.h +++ b/drivers/staging/cx25821/cx25821-reg.h | |||
@@ -163,8 +163,8 @@ | |||
163 | #define FLD_VID_DST_RISC2 0x00000010 | 163 | #define FLD_VID_DST_RISC2 0x00000010 |
164 | #define FLD_VID_SRC_RISC1 0x00000002 | 164 | #define FLD_VID_SRC_RISC1 0x00000002 |
165 | #define FLD_VID_DST_RISC1 0x00000001 | 165 | #define FLD_VID_DST_RISC1 0x00000001 |
166 | #define FLD_VID_SRC_ERRORS FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF | 166 | #define FLD_VID_SRC_ERRORS (FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF) |
167 | #define FLD_VID_DST_ERRORS FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF | 167 | #define FLD_VID_DST_ERRORS (FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF) |
168 | 168 | ||
169 | /* ***************************************************************************** */ | 169 | /* ***************************************************************************** */ |
170 | #define AUD_A_INT_MSK 0x0400C0 /* Audio Int interrupt mask */ | 170 | #define AUD_A_INT_MSK 0x0400C0 /* Audio Int interrupt mask */ |
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c index d12dbb572e8..405e2db72b0 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c | |||
@@ -32,17 +32,17 @@ | |||
32 | #include <linux/file.h> | 32 | #include <linux/file.h> |
33 | #include <linux/fcntl.h> | 33 | #include <linux/fcntl.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <asm/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | 36 | ||
37 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); | 37 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); |
38 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | 38 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); |
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | 40 | ||
41 | static int _intr_msk = | 41 | static int _intr_msk = |
42 | FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR; | 42 | FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR; |
43 | 43 | ||
44 | static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, | 44 | static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, |
45 | __le32 * rp, unsigned int offset, | 45 | __le32 *rp, unsigned int offset, |
46 | unsigned int bpl, u32 sync_line, | 46 | unsigned int bpl, u32 sync_line, |
47 | unsigned int lines, | 47 | unsigned int lines, |
48 | int fifo_enable, int field_type) | 48 | int fifo_enable, int field_type) |
@@ -53,9 +53,8 @@ static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, | |||
53 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | 53 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); |
54 | 54 | ||
55 | if (USE_RISC_NOOP_VIDEO) { | 55 | if (USE_RISC_NOOP_VIDEO) { |
56 | for (i = 0; i < NUM_NO_OPS; i++) { | 56 | for (i = 0; i < NUM_NO_OPS; i++) |
57 | *(rp++) = cpu_to_le32(RISC_NOOP); | 57 | *(rp++) = cpu_to_le32(RISC_NOOP); |
58 | } | ||
59 | } | 58 | } |
60 | 59 | ||
61 | /* scan lines */ | 60 | /* scan lines */ |
@@ -75,7 +74,7 @@ static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, | |||
75 | } | 74 | } |
76 | 75 | ||
77 | static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, | 76 | static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, |
78 | __le32 * rp, | 77 | __le32 *rp, |
79 | dma_addr_t databuf_phys_addr, | 78 | dma_addr_t databuf_phys_addr, |
80 | unsigned int offset, | 79 | unsigned int offset, |
81 | u32 sync_line, unsigned int bpl, | 80 | u32 sync_line, unsigned int bpl, |
@@ -88,14 +87,12 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, | |||
88 | int dist_betwn_starts = bpl * 2; | 87 | int dist_betwn_starts = bpl * 2; |
89 | 88 | ||
90 | /* sync instruction */ | 89 | /* sync instruction */ |
91 | if (sync_line != NO_SYNC_LINE) { | 90 | if (sync_line != NO_SYNC_LINE) |
92 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | 91 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); |
93 | } | ||
94 | 92 | ||
95 | if (USE_RISC_NOOP_VIDEO) { | 93 | if (USE_RISC_NOOP_VIDEO) { |
96 | for (i = 0; i < NUM_NO_OPS; i++) { | 94 | for (i = 0; i < NUM_NO_OPS; i++) |
97 | *(rp++) = cpu_to_le32(RISC_NOOP); | 95 | *(rp++) = cpu_to_le32(RISC_NOOP); |
98 | } | ||
99 | } | 96 | } |
100 | 97 | ||
101 | /* scan lines */ | 98 | /* scan lines */ |
@@ -133,7 +130,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, | |||
133 | { | 130 | { |
134 | __le32 *rp; | 131 | __le32 *rp; |
135 | int fifo_enable = 0; | 132 | int fifo_enable = 0; |
136 | int singlefield_lines = lines >> 1; /*get line count for single field */ | 133 | int singlefield_lines = lines >> 1; /*get line count for single field */ |
137 | int odd_num_lines = singlefield_lines; | 134 | int odd_num_lines = singlefield_lines; |
138 | int frame = 0; | 135 | int frame = 0; |
139 | int frame_size = 0; | 136 | int frame_size = 0; |
@@ -218,15 +215,15 @@ void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) | |||
218 | ("cx25821: No video file is currently running so return!\n"); | 215 | ("cx25821: No video file is currently running so return!\n"); |
219 | return; | 216 | return; |
220 | } | 217 | } |
221 | /* Disable RISC interrupts */ | 218 | /* Disable RISC interrupts */ |
222 | tmp = cx_read(sram_ch->int_msk); | 219 | tmp = cx_read(sram_ch->int_msk); |
223 | cx_write(sram_ch->int_msk, tmp & ~_intr_msk); | 220 | cx_write(sram_ch->int_msk, tmp & ~_intr_msk); |
224 | 221 | ||
225 | /* Turn OFF risc and fifo */ | 222 | /* Turn OFF risc and fifo */ |
226 | tmp = cx_read(sram_ch->dma_ctl); | 223 | tmp = cx_read(sram_ch->dma_ctl); |
227 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); | 224 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); |
228 | 225 | ||
229 | /* Clear data buffer memory */ | 226 | /* Clear data buffer memory */ |
230 | if (dev->_data_buf_virt_addr_ch2) | 227 | if (dev->_data_buf_virt_addr_ch2) |
231 | memset(dev->_data_buf_virt_addr_ch2, 0, | 228 | memset(dev->_data_buf_virt_addr_ch2, 0, |
232 | dev->_data_buf_size_ch2); | 229 | dev->_data_buf_size_ch2); |
@@ -250,9 +247,8 @@ void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) | |||
250 | 247 | ||
251 | void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) | 248 | void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) |
252 | { | 249 | { |
253 | if (dev->_is_running_ch2) { | 250 | if (dev->_is_running_ch2) |
254 | cx25821_stop_upstream_video_ch2(dev); | 251 | cx25821_stop_upstream_video_ch2(dev); |
255 | } | ||
256 | 252 | ||
257 | if (dev->_dma_virt_addr_ch2) { | 253 | if (dev->_dma_virt_addr_ch2) { |
258 | pci_free_consistent(dev->pci, dev->_risc_size_ch2, | 254 | pci_free_consistent(dev->pci, dev->_risc_size_ch2, |
@@ -303,11 +299,10 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
303 | file_offset = dev->_frame_count_ch2 * frame_size; | 299 | file_offset = dev->_frame_count_ch2 * frame_size; |
304 | 300 | ||
305 | myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); | 301 | myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); |
306 | |||
307 | if (IS_ERR(myfile)) { | 302 | if (IS_ERR(myfile)) { |
308 | const int open_errno = -PTR_ERR(myfile); | 303 | const int open_errno = -PTR_ERR(myfile); |
309 | printk("%s(): ERROR opening file(%s) with errno = %d! \n", | 304 | printk("%s(): ERROR opening file(%s) with errno = %d!\n", |
310 | __func__, dev->_filename_ch2, open_errno); | 305 | __func__, dev->_filename_ch2, open_errno); |
311 | return PTR_ERR(myfile); | 306 | return PTR_ERR(myfile); |
312 | } else { | 307 | } else { |
313 | if (!(myfile->f_op)) { | 308 | if (!(myfile->f_op)) { |
@@ -371,8 +366,8 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work) | |||
371 | container_of(work, struct cx25821_dev, _irq_work_entry_ch2); | 366 | container_of(work, struct cx25821_dev, _irq_work_entry_ch2); |
372 | 367 | ||
373 | if (!dev) { | 368 | if (!dev) { |
374 | printk("ERROR %s(): since container_of(work_struct) FAILED! \n", | 369 | printk("ERROR %s(): since container_of(work_struct) FAILED!\n", |
375 | __func__); | 370 | __func__); |
376 | return; | 371 | return; |
377 | } | 372 | } |
378 | 373 | ||
@@ -398,8 +393,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
398 | 393 | ||
399 | if (IS_ERR(myfile)) { | 394 | if (IS_ERR(myfile)) { |
400 | const int open_errno = -PTR_ERR(myfile); | 395 | const int open_errno = -PTR_ERR(myfile); |
401 | printk("%s(): ERROR opening file(%s) with errno = %d! \n", | 396 | printk("%s(): ERROR opening file(%s) with errno = %d!\n", |
402 | __func__, dev->_filename_ch2, open_errno); | 397 | __func__, dev->_filename_ch2, open_errno); |
403 | return PTR_ERR(myfile); | 398 | return PTR_ERR(myfile); |
404 | } else { | 399 | } else { |
405 | if (!(myfile->f_op)) { | 400 | if (!(myfile->f_op)) { |
@@ -450,9 +445,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
450 | if (i > 0) | 445 | if (i > 0) |
451 | dev->_frame_count_ch2++; | 446 | dev->_frame_count_ch2++; |
452 | 447 | ||
453 | if (vfs_read_retval < line_size) { | 448 | if (vfs_read_retval < line_size) |
454 | break; | 449 | break; |
455 | } | ||
456 | } | 450 | } |
457 | 451 | ||
458 | dev->_file_status_ch2 = | 452 | dev->_file_status_ch2 = |
@@ -494,7 +488,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | |||
494 | return -ENOMEM; | 488 | return -ENOMEM; |
495 | } | 489 | } |
496 | 490 | ||
497 | /* Iniitize at this address until n bytes to 0 */ | 491 | /* Iniitize at this address until n bytes to 0 */ |
498 | memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2); | 492 | memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2); |
499 | 493 | ||
500 | if (dev->_data_buf_virt_addr_ch2 != NULL) { | 494 | if (dev->_data_buf_virt_addr_ch2 != NULL) { |
@@ -502,7 +496,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | |||
502 | dev->_data_buf_virt_addr_ch2, | 496 | dev->_data_buf_virt_addr_ch2, |
503 | dev->_data_buf_phys_addr_ch2); | 497 | dev->_data_buf_phys_addr_ch2); |
504 | } | 498 | } |
505 | /* For Video Data buffer allocation */ | 499 | /* For Video Data buffer allocation */ |
506 | dev->_data_buf_virt_addr_ch2 = | 500 | dev->_data_buf_virt_addr_ch2 = |
507 | pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2, | 501 | pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2, |
508 | &data_dma_addr); | 502 | &data_dma_addr); |
@@ -515,26 +509,26 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | |||
515 | return -ENOMEM; | 509 | return -ENOMEM; |
516 | } | 510 | } |
517 | 511 | ||
518 | /* Initialize at this address until n bytes to 0 */ | 512 | /* Initialize at this address until n bytes to 0 */ |
519 | memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); | 513 | memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); |
520 | 514 | ||
521 | ret = cx25821_openfile_ch2(dev, sram_ch); | 515 | ret = cx25821_openfile_ch2(dev, sram_ch); |
522 | if (ret < 0) | 516 | if (ret < 0) |
523 | return ret; | 517 | return ret; |
524 | 518 | ||
525 | /* Creating RISC programs */ | 519 | /* Creating RISC programs */ |
526 | ret = | 520 | ret = |
527 | cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, | 521 | cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, |
528 | dev->_lines_count_ch2); | 522 | dev->_lines_count_ch2); |
529 | if (ret < 0) { | 523 | if (ret < 0) { |
530 | printk(KERN_INFO | 524 | printk(KERN_INFO |
531 | "cx25821: Failed creating Video Upstream Risc programs! \n"); | 525 | "cx25821: Failed creating Video Upstream Risc programs!\n"); |
532 | goto error; | 526 | goto error; |
533 | } | 527 | } |
534 | 528 | ||
535 | return 0; | 529 | return 0; |
536 | 530 | ||
537 | error: | 531 | error: |
538 | return ret; | 532 | return ret; |
539 | } | 533 | } |
540 | 534 | ||
@@ -542,7 +536,7 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, | |||
542 | u32 status) | 536 | u32 status) |
543 | { | 537 | { |
544 | u32 int_msk_tmp; | 538 | u32 int_msk_tmp; |
545 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | 539 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; |
546 | int singlefield_lines = NTSC_FIELD_HEIGHT; | 540 | int singlefield_lines = NTSC_FIELD_HEIGHT; |
547 | int line_size_in_bytes = Y422_LINE_SZ; | 541 | int line_size_in_bytes = Y422_LINE_SZ; |
548 | int odd_risc_prog_size = 0; | 542 | int odd_risc_prog_size = 0; |
@@ -550,13 +544,13 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, | |||
550 | __le32 *rp; | 544 | __le32 *rp; |
551 | 545 | ||
552 | if (status & FLD_VID_SRC_RISC1) { | 546 | if (status & FLD_VID_SRC_RISC1) { |
553 | /* We should only process one program per call */ | 547 | /* We should only process one program per call */ |
554 | u32 prog_cnt = cx_read(channel->gpcnt); | 548 | u32 prog_cnt = cx_read(channel->gpcnt); |
555 | 549 | ||
556 | /* | 550 | /* |
557 | Since we've identified our IRQ, clear our bits from the | 551 | * Since we've identified our IRQ, clear our bits from the |
558 | interrupt mask and interrupt status registers | 552 | * interrupt mask and interrupt status registers |
559 | */ | 553 | */ |
560 | int_msk_tmp = cx_read(channel->int_msk); | 554 | int_msk_tmp = cx_read(channel->int_msk); |
561 | cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); | 555 | cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); |
562 | cx_write(channel->int_stat, _intr_msk); | 556 | cx_write(channel->int_stat, _intr_msk); |
@@ -612,7 +606,7 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, | |||
612 | dev->_frame_count_ch2); | 606 | dev->_frame_count_ch2); |
613 | return -1; | 607 | return -1; |
614 | } | 608 | } |
615 | /* ElSE, set the interrupt mask register, re-enable irq. */ | 609 | /* ElSE, set the interrupt mask register, re-enable irq. */ |
616 | int_msk_tmp = cx_read(channel->int_msk); | 610 | int_msk_tmp = cx_read(channel->int_msk); |
617 | cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); | 611 | cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); |
618 | 612 | ||
@@ -631,24 +625,22 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) | |||
631 | return -1; | 625 | return -1; |
632 | 626 | ||
633 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; | 627 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; |
634 | 628 | sram_ch = dev->channels[channel_num].sram_channels; | |
635 | sram_ch = dev->channels[channel_num].sram_channels; | ||
636 | 629 | ||
637 | msk_stat = cx_read(sram_ch->int_mstat); | 630 | msk_stat = cx_read(sram_ch->int_mstat); |
638 | vid_status = cx_read(sram_ch->int_stat); | 631 | vid_status = cx_read(sram_ch->int_stat); |
639 | 632 | ||
640 | /* Only deal with our interrupt */ | 633 | /* Only deal with our interrupt */ |
641 | if (vid_status) { | 634 | if (vid_status) { |
642 | handled = | 635 | handled = |
643 | cx25821_video_upstream_irq_ch2(dev, channel_num, | 636 | cx25821_video_upstream_irq_ch2(dev, channel_num, |
644 | vid_status); | 637 | vid_status); |
645 | } | 638 | } |
646 | 639 | ||
647 | if (handled < 0) { | 640 | if (handled < 0) |
648 | cx25821_stop_upstream_video_ch2(dev); | 641 | cx25821_stop_upstream_video_ch2(dev); |
649 | } else { | 642 | else |
650 | handled += handled; | 643 | handled += handled; |
651 | } | ||
652 | 644 | ||
653 | return IRQ_RETVAL(handled); | 645 | return IRQ_RETVAL(handled); |
654 | } | 646 | } |
@@ -667,22 +659,21 @@ static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, | |||
667 | value |= dev->_isNTSC_ch2 ? 0 : 0x10; | 659 | value |= dev->_isNTSC_ch2 ? 0 : 0x10; |
668 | cx_write(ch->vid_fmt_ctl, value); | 660 | cx_write(ch->vid_fmt_ctl, value); |
669 | 661 | ||
670 | /* | 662 | /* |
671 | set number of active pixels in each line. Default is 720 | 663 | * set number of active pixels in each line. Default is 720 |
672 | pixels in both NTSC and PAL format | 664 | * pixels in both NTSC and PAL format |
673 | */ | 665 | */ |
674 | cx_write(ch->vid_active_ctl1, width); | 666 | cx_write(ch->vid_active_ctl1, width); |
675 | 667 | ||
676 | num_lines = (height / 2) & 0x3FF; | 668 | num_lines = (height / 2) & 0x3FF; |
677 | odd_num_lines = num_lines; | 669 | odd_num_lines = num_lines; |
678 | 670 | ||
679 | if (dev->_isNTSC_ch2) { | 671 | if (dev->_isNTSC_ch2) |
680 | odd_num_lines += 1; | 672 | odd_num_lines += 1; |
681 | } | ||
682 | 673 | ||
683 | value = (num_lines << 16) | odd_num_lines; | 674 | value = (num_lines << 16) | odd_num_lines; |
684 | 675 | ||
685 | /* set number of active lines in field 0 (top) and field 1 (bottom) */ | 676 | /* set number of active lines in field 0 (top) and field 1 (bottom) */ |
686 | cx_write(ch->vid_active_ctl2, value); | 677 | cx_write(ch->vid_active_ctl2, value); |
687 | 678 | ||
688 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); | 679 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); |
@@ -694,27 +685,27 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, | |||
694 | u32 tmp = 0; | 685 | u32 tmp = 0; |
695 | int err = 0; | 686 | int err = 0; |
696 | 687 | ||
697 | /* | 688 | /* |
698 | 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface | 689 | * 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface |
699 | for channel A-C | 690 | * for channel A-C |
700 | */ | 691 | */ |
701 | tmp = cx_read(VID_CH_MODE_SEL); | 692 | tmp = cx_read(VID_CH_MODE_SEL); |
702 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | 693 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); |
703 | 694 | ||
704 | /* | 695 | /* |
705 | Set the physical start address of the RISC program in the initial | 696 | * Set the physical start address of the RISC program in the initial |
706 | program counter(IPC) member of the cmds. | 697 | * program counter(IPC) member of the cmds. |
707 | */ | 698 | */ |
708 | cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); | 699 | cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); |
709 | cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ | 700 | cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ |
710 | 701 | ||
711 | /* reset counter */ | 702 | /* reset counter */ |
712 | cx_write(sram_ch->gpcnt_ctl, 3); | 703 | cx_write(sram_ch->gpcnt_ctl, 3); |
713 | 704 | ||
714 | /* Clear our bits from the interrupt status register. */ | 705 | /* Clear our bits from the interrupt status register. */ |
715 | cx_write(sram_ch->int_stat, _intr_msk); | 706 | cx_write(sram_ch->int_stat, _intr_msk); |
716 | 707 | ||
717 | /* Set the interrupt mask register, enable irq. */ | 708 | /* Set the interrupt mask register, enable irq. */ |
718 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); | 709 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); |
719 | tmp = cx_read(sram_ch->int_msk); | 710 | tmp = cx_read(sram_ch->int_msk); |
720 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | 711 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); |
@@ -727,7 +718,7 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, | |||
727 | dev->pci->irq); | 718 | dev->pci->irq); |
728 | goto fail_irq; | 719 | goto fail_irq; |
729 | } | 720 | } |
730 | /* Start the DMA engine */ | 721 | /* Start the DMA engine */ |
731 | tmp = cx_read(sram_ch->dma_ctl); | 722 | tmp = cx_read(sram_ch->dma_ctl); |
732 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); | 723 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); |
733 | 724 | ||
@@ -736,7 +727,7 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, | |||
736 | 727 | ||
737 | return 0; | 728 | return 0; |
738 | 729 | ||
739 | fail_irq: | 730 | fail_irq: |
740 | cx25821_dev_unregister(dev); | 731 | cx25821_dev_unregister(dev); |
741 | return err; | 732 | return err; |
742 | } | 733 | } |
@@ -758,7 +749,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | |||
758 | } | 749 | } |
759 | 750 | ||
760 | dev->_channel2_upstream_select = channel_select; | 751 | dev->_channel2_upstream_select = channel_select; |
761 | sram_ch = dev->channels[channel_select].sram_channels; | 752 | sram_ch = dev->channels[channel_select].sram_channels; |
762 | 753 | ||
763 | INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); | 754 | INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); |
764 | dev->_irq_queues_ch2 = | 755 | dev->_irq_queues_ch2 = |
@@ -769,10 +760,10 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | |||
769 | ("cx25821: create_singlethread_workqueue() for Video FAILED!\n"); | 760 | ("cx25821: create_singlethread_workqueue() for Video FAILED!\n"); |
770 | return -ENOMEM; | 761 | return -ENOMEM; |
771 | } | 762 | } |
772 | /* | 763 | /* |
773 | 656/VIP SRC Upstream Channel I & J and 7 - | 764 | * 656/VIP SRC Upstream Channel I & J and 7 - |
774 | Host Bus Interface for channel A-C | 765 | * Host Bus Interface for channel A-C |
775 | */ | 766 | */ |
776 | tmp = cx_read(VID_CH_MODE_SEL); | 767 | tmp = cx_read(VID_CH_MODE_SEL); |
777 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | 768 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); |
778 | 769 | ||
@@ -808,7 +799,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | |||
808 | str_length + 1); | 799 | str_length + 1); |
809 | } | 800 | } |
810 | 801 | ||
811 | /* Default if filename is empty string */ | 802 | /* Default if filename is empty string */ |
812 | if (strcmp(dev->input_filename_ch2, "") == 0) { | 803 | if (strcmp(dev->input_filename_ch2, "") == 0) { |
813 | if (dev->_isNTSC_ch2) { | 804 | if (dev->_isNTSC_ch2) { |
814 | dev->_filename_ch2 = | 805 | dev->_filename_ch2 = |
@@ -833,7 +824,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | |||
833 | dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; | 824 | dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; |
834 | dev->upstream_databuf_size_ch2 = data_frame_size * 2; | 825 | dev->upstream_databuf_size_ch2 = data_frame_size * 2; |
835 | 826 | ||
836 | /* Allocating buffers and prepare RISC program */ | 827 | /* Allocating buffers and prepare RISC program */ |
837 | retval = | 828 | retval = |
838 | cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, | 829 | cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, |
839 | dev->_line_size_ch2); | 830 | dev->_line_size_ch2); |
@@ -848,7 +839,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | |||
848 | 839 | ||
849 | return 0; | 840 | return 0; |
850 | 841 | ||
851 | error: | 842 | error: |
852 | cx25821_dev_unregister(dev); | 843 | cx25821_dev_unregister(dev); |
853 | 844 | ||
854 | return err; | 845 | return err; |
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h index 62340636c91..029e8305724 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h +++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h | |||
@@ -88,14 +88,14 @@ | |||
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | #ifndef USE_RISC_NOOP_VIDEO | 90 | #ifndef USE_RISC_NOOP_VIDEO |
91 | #define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE ) | 91 | #define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) |
92 | #define PAL_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE) ) | 92 | #define PAL_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE)) |
93 | #define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ | 93 | #define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ |
94 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE ) | 94 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) |
95 | #define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE ) | 95 | #define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) |
96 | #define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE ) | 96 | #define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) |
97 | #define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | 97 | #define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) |
98 | #define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) ) | 98 | #define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) |
99 | #define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ | 99 | #define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ |
100 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE ) | 100 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) |
101 | #endif | 101 | #endif |
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c index 756a820a76c..16bf74d6591 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream.c +++ b/drivers/staging/cx25821/cx25821-video-upstream.c | |||
@@ -39,7 +39,7 @@ MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | |||
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | 40 | ||
41 | static int _intr_msk = | 41 | static int _intr_msk = |
42 | FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR; | 42 | FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR; |
43 | 43 | ||
44 | int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, | 44 | int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, |
45 | struct sram_channel *ch, | 45 | struct sram_channel *ch, |
@@ -346,13 +346,13 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
346 | 346 | ||
347 | if (IS_ERR(myfile)) { | 347 | if (IS_ERR(myfile)) { |
348 | const int open_errno = -PTR_ERR(myfile); | 348 | const int open_errno = -PTR_ERR(myfile); |
349 | printk(KERN_ERR | 349 | printk(KERN_ERR |
350 | "%s(): ERROR opening file(%s) with errno = %d!\n", | 350 | "%s(): ERROR opening file(%s) with errno = %d!\n", |
351 | __func__, dev->_filename, open_errno); | 351 | __func__, dev->_filename, open_errno); |
352 | return PTR_ERR(myfile); | 352 | return PTR_ERR(myfile); |
353 | } else { | 353 | } else { |
354 | if (!(myfile->f_op)) { | 354 | if (!(myfile->f_op)) { |
355 | printk(KERN_ERR | 355 | printk(KERN_ERR |
356 | "%s: File has no file operations registered!", | 356 | "%s: File has no file operations registered!", |
357 | __func__); | 357 | __func__); |
358 | filp_close(myfile, NULL); | 358 | filp_close(myfile, NULL); |
@@ -360,7 +360,7 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
360 | } | 360 | } |
361 | 361 | ||
362 | if (!myfile->f_op->read) { | 362 | if (!myfile->f_op->read) { |
363 | printk(KERN_ERR | 363 | printk(KERN_ERR |
364 | "%s: File has no READ operations registered!", | 364 | "%s: File has no READ operations registered!", |
365 | __func__); | 365 | __func__); |
366 | filp_close(myfile, NULL); | 366 | filp_close(myfile, NULL); |
@@ -415,7 +415,7 @@ static void cx25821_vidups_handler(struct work_struct *work) | |||
415 | container_of(work, struct cx25821_dev, _irq_work_entry); | 415 | container_of(work, struct cx25821_dev, _irq_work_entry); |
416 | 416 | ||
417 | if (!dev) { | 417 | if (!dev) { |
418 | printk(KERN_ERR | 418 | printk(KERN_ERR |
419 | "ERROR %s(): since container_of(work_struct) FAILED!\n", | 419 | "ERROR %s(): since container_of(work_struct) FAILED!\n", |
420 | __func__); | 420 | __func__); |
421 | return; | 421 | return; |
@@ -448,7 +448,7 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
448 | return PTR_ERR(myfile); | 448 | return PTR_ERR(myfile); |
449 | } else { | 449 | } else { |
450 | if (!(myfile->f_op)) { | 450 | if (!(myfile->f_op)) { |
451 | printk(KERN_ERR | 451 | printk(KERN_ERR |
452 | "%s: File has no file operations registered!", | 452 | "%s: File has no file operations registered!", |
453 | __func__); | 453 | __func__); |
454 | filp_close(myfile, NULL); | 454 | filp_close(myfile, NULL); |
@@ -456,7 +456,7 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) | |||
456 | } | 456 | } |
457 | 457 | ||
458 | if (!myfile->f_op->read) { | 458 | if (!myfile->f_op->read) { |
459 | printk(KERN_ERR | 459 | printk(KERN_ERR |
460 | "%s: File has no READ operations registered! \ | 460 | "%s: File has no READ operations registered! \ |
461 | Returning.", | 461 | Returning.", |
462 | __func__); | 462 | __func__); |
@@ -589,7 +589,7 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
589 | u32 status) | 589 | u32 status) |
590 | { | 590 | { |
591 | u32 int_msk_tmp; | 591 | u32 int_msk_tmp; |
592 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; | 592 | struct sram_channel *channel = dev->channels[chan_num].sram_channels; |
593 | int singlefield_lines = NTSC_FIELD_HEIGHT; | 593 | int singlefield_lines = NTSC_FIELD_HEIGHT; |
594 | int line_size_in_bytes = Y422_LINE_SZ; | 594 | int line_size_in_bytes = Y422_LINE_SZ; |
595 | int odd_risc_prog_size = 0; | 595 | int odd_risc_prog_size = 0; |
@@ -657,12 +657,12 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
657 | Interrupt!\n", __func__); | 657 | Interrupt!\n", __func__); |
658 | 658 | ||
659 | if (status & FLD_VID_SRC_SYNC) | 659 | if (status & FLD_VID_SRC_SYNC) |
660 | printk(KERN_ERR "%s: Video Received Sync Error \ | 660 | printk(KERN_ERR "%s: Video Received Sync Error \ |
661 | Interrupt!\n", __func__); | 661 | Interrupt!\n", __func__); |
662 | 662 | ||
663 | if (status & FLD_VID_SRC_OPC_ERR) | 663 | if (status & FLD_VID_SRC_OPC_ERR) |
664 | printk(KERN_ERR "%s: Video Received OpCode Error \ | 664 | printk(KERN_ERR "%s: Video Received OpCode Error \ |
665 | Interrupt!\n", __func__); | 665 | Interrupt!\n", __func__); |
666 | } | 666 | } |
667 | 667 | ||
668 | if (dev->_file_status == END_OF_FILE) { | 668 | if (dev->_file_status == END_OF_FILE) { |
@@ -690,7 +690,7 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) | |||
690 | 690 | ||
691 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_I; | 691 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_I; |
692 | 692 | ||
693 | sram_ch = dev->channels[channel_num].sram_channels; | 693 | sram_ch = dev->channels[channel_num].sram_channels; |
694 | 694 | ||
695 | msk_stat = cx_read(sram_ch->int_mstat); | 695 | msk_stat = cx_read(sram_ch->int_mstat); |
696 | vid_status = cx_read(sram_ch->int_stat); | 696 | vid_status = cx_read(sram_ch->int_stat); |
@@ -811,7 +811,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | |||
811 | } | 811 | } |
812 | 812 | ||
813 | dev->_channel_upstream_select = channel_select; | 813 | dev->_channel_upstream_select = channel_select; |
814 | sram_ch = dev->channels[channel_select].sram_channels; | 814 | sram_ch = dev->channels[channel_select].sram_channels; |
815 | 815 | ||
816 | INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler); | 816 | INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler); |
817 | dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); | 817 | dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); |
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h index 10dee5c24a8..f0b3ac0880a 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream.h +++ b/drivers/staging/cx25821/cx25821-video-upstream.h | |||
@@ -97,13 +97,13 @@ | |||
97 | #define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) | 97 | #define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) |
98 | 98 | ||
99 | #define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ | 99 | #define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ |
100 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE ) | 100 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) |
101 | 101 | ||
102 | #define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE ) | 102 | #define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) |
103 | #define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE ) | 103 | #define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) |
104 | 104 | ||
105 | #define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | 105 | #define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) |
106 | #define NTSC_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) ) | 106 | #define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) |
107 | #define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ | 107 | #define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \ |
108 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE ) | 108 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) |
109 | #endif | 109 | #endif |
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index 1d5e8796d38..e7f1d5778ce 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c | |||
@@ -856,7 +856,7 @@ static int video_open(struct file *file) | |||
856 | &dev->pci->dev, &dev->slock, | 856 | &dev->pci->dev, &dev->slock, |
857 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 857 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
858 | V4L2_FIELD_INTERLACED, | 858 | V4L2_FIELD_INTERLACED, |
859 | sizeof(struct cx25821_buffer), fh); | 859 | sizeof(struct cx25821_buffer), fh, NULL); |
860 | 860 | ||
861 | dprintk(1, "post videobuf_queue_init()\n"); | 861 | dprintk(1, "post videobuf_queue_init()\n"); |
862 | unlock_kernel(); | 862 | unlock_kernel(); |
@@ -993,6 +993,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
993 | { | 993 | { |
994 | struct cx25821_fh *fh = priv; | 994 | struct cx25821_fh *fh = priv; |
995 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | 995 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; |
996 | struct v4l2_mbus_framefmt mbus_fmt; | ||
996 | int err; | 997 | int err; |
997 | int pix_format = PIXEL_FRMT_422; | 998 | int pix_format = PIXEL_FRMT_422; |
998 | 999 | ||
@@ -1039,7 +1040,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1039 | 1040 | ||
1040 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, | 1041 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, |
1041 | fh->height, fh->vidq.field); | 1042 | fh->height, fh->vidq.field); |
1042 | cx25821_call_all(dev, video, s_fmt, f); | 1043 | v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); |
1044 | cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt); | ||
1043 | 1045 | ||
1044 | return 0; | 1046 | return 0; |
1045 | } | 1047 | } |
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h index 1b628f61578..c9400012578 100644 --- a/drivers/staging/cx25821/cx25821.h +++ b/drivers/staging/cx25821/cx25821.h | |||
@@ -91,10 +91,10 @@ | |||
91 | 91 | ||
92 | /* Currently supported by the driver */ | 92 | /* Currently supported by the driver */ |
93 | #define CX25821_NORMS (\ | 93 | #define CX25821_NORMS (\ |
94 | V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \ | 94 | V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \ |
95 | V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ | 95 | V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ |
96 | V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \ | 96 | V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \ |
97 | V4L2_STD_PAL_Nc ) | 97 | V4L2_STD_PAL_Nc) |
98 | 98 | ||
99 | #define CX25821_BOARD_CONEXANT_ATHENA10 1 | 99 | #define CX25821_BOARD_CONEXANT_ATHENA10 1 |
100 | #define MAX_VID_CHANNEL_NUM 12 | 100 | #define MAX_VID_CHANNEL_NUM 12 |
@@ -139,7 +139,7 @@ struct cx25821_fh { | |||
139 | /* video capture */ | 139 | /* video capture */ |
140 | struct cx25821_fmt *fmt; | 140 | struct cx25821_fmt *fmt; |
141 | unsigned int width, height; | 141 | unsigned int width, height; |
142 | int channel_id; | 142 | int channel_id; |
143 | 143 | ||
144 | /* vbi capture */ | 144 | /* vbi capture */ |
145 | struct videobuf_queue vidq; | 145 | struct videobuf_queue vidq; |
@@ -238,26 +238,25 @@ struct cx25821_data { | |||
238 | }; | 238 | }; |
239 | 239 | ||
240 | struct cx25821_channel { | 240 | struct cx25821_channel { |
241 | struct v4l2_prio_state prio; | 241 | struct v4l2_prio_state prio; |
242 | 242 | ||
243 | int ctl_bright; | 243 | int ctl_bright; |
244 | int ctl_contrast; | 244 | int ctl_contrast; |
245 | int ctl_hue; | 245 | int ctl_hue; |
246 | int ctl_saturation; | 246 | int ctl_saturation; |
247 | struct cx25821_data timeout_data; | ||
247 | 248 | ||
248 | struct cx25821_data timeout_data; | 249 | struct video_device *video_dev; |
250 | struct cx25821_dmaqueue vidq; | ||
249 | 251 | ||
250 | struct video_device *video_dev; | 252 | struct sram_channel *sram_channels; |
251 | struct cx25821_dmaqueue vidq; | ||
252 | 253 | ||
253 | struct sram_channel *sram_channels; | 254 | struct mutex lock; |
254 | 255 | int resources; | |
255 | struct mutex lock; | ||
256 | int resources; | ||
257 | 256 | ||
258 | int pixel_formats; | 257 | int pixel_formats; |
259 | int use_cif_resolution; | 258 | int use_cif_resolution; |
260 | int cif_width; | 259 | int cif_width; |
261 | }; | 260 | }; |
262 | 261 | ||
263 | struct cx25821_dev { | 262 | struct cx25821_dev { |
@@ -283,7 +282,7 @@ struct cx25821_dev { | |||
283 | int nr; | 282 | int nr; |
284 | struct mutex lock; | 283 | struct mutex lock; |
285 | 284 | ||
286 | struct cx25821_channel channels[MAX_VID_CHANNEL_NUM]; | 285 | struct cx25821_channel channels[MAX_VID_CHANNEL_NUM]; |
287 | 286 | ||
288 | /* board details */ | 287 | /* board details */ |
289 | unsigned int board; | 288 | unsigned int board; |
@@ -311,7 +310,7 @@ struct cx25821_dev { | |||
311 | int _audio_lines_count; | 310 | int _audio_lines_count; |
312 | int _audioframe_count; | 311 | int _audioframe_count; |
313 | int _audio_upstream_channel_select; | 312 | int _audio_upstream_channel_select; |
314 | int _last_index_irq; /* The last interrupt index processed. */ | 313 | int _last_index_irq; /* The last interrupt index processed. */ |
315 | 314 | ||
316 | __le32 *_risc_audio_jmp_addr; | 315 | __le32 *_risc_audio_jmp_addr; |
317 | __le32 *_risc_virt_start_addr; | 316 | __le32 *_risc_virt_start_addr; |
@@ -443,7 +442,7 @@ static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) | |||
443 | } | 442 | } |
444 | 443 | ||
445 | #define cx25821_call_all(dev, o, f, args...) \ | 444 | #define cx25821_call_all(dev, o, f, args...) \ |
446 | v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) | 445 | v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) |
447 | 446 | ||
448 | extern struct list_head cx25821_devlist; | 447 | extern struct list_head cx25821_devlist; |
449 | extern struct cx25821_board cx25821_boards[]; | 448 | extern struct cx25821_board cx25821_boards[]; |
@@ -491,7 +490,7 @@ struct sram_channel { | |||
491 | u32 fld_aud_fifo_en; | 490 | u32 fld_aud_fifo_en; |
492 | u32 fld_aud_risc_en; | 491 | u32 fld_aud_risc_en; |
493 | 492 | ||
494 | /* For Upstream Video */ | 493 | /* For Upstream Video */ |
495 | u32 vid_fmt_ctl; | 494 | u32 vid_fmt_ctl; |
496 | u32 vid_active_ctl1; | 495 | u32 vid_active_ctl1; |
497 | u32 vid_active_ctl2; | 496 | u32 vid_active_ctl2; |
@@ -511,8 +510,8 @@ extern struct sram_channel cx25821_sram_channels[]; | |||
511 | #define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) | 510 | #define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) |
512 | 511 | ||
513 | #define cx_andor(reg, mask, value) \ | 512 | #define cx_andor(reg, mask, value) \ |
514 | writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ | 513 | writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ |
515 | ((value) & (mask)), dev->lmmio+((reg)>>2)) | 514 | ((value) & (mask)), dev->lmmio+((reg)>>2)) |
516 | 515 | ||
517 | #define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) | 516 | #define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) |
518 | #define cx_clear(reg, bit) cx_andor((reg), (bit), 0) | 517 | #define cx_clear(reg, bit) cx_andor((reg), (bit), 0) |
diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index fd48b38e797..b996697e7eb 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c | |||
@@ -293,7 +293,7 @@ static void | |||
293 | dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 293 | dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) |
294 | { | 294 | { |
295 | if (vb->state == VIDEOBUF_ACTIVE) | 295 | if (vb->state == VIDEOBUF_ACTIVE) |
296 | videobuf_waiton(vb, 0, 0); /* FIXME: cannot be interrupted */ | 296 | videobuf_waiton(q, vb, 0, 0); /* FIXME: cannot be interrupted */ |
297 | videobuf_dma_contig_free(q, vb); | 297 | videobuf_dma_contig_free(q, vb); |
298 | vb->state = VIDEOBUF_NEEDS_INIT; | 298 | vb->state = VIDEOBUF_NEEDS_INIT; |
299 | } | 299 | } |
@@ -440,7 +440,7 @@ dt3155_open(struct file *filp) | |||
440 | videobuf_queue_dma_contig_init(pd->vidq, &vbq_ops, | 440 | videobuf_queue_dma_contig_init(pd->vidq, &vbq_ops, |
441 | &pd->pdev->dev, &pd->lock, | 441 | &pd->pdev->dev, &pd->lock, |
442 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 442 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
443 | sizeof(struct videobuf_buffer), pd); | 443 | sizeof(struct videobuf_buffer), pd, NULL); |
444 | /* disable all irqs, clear all irq flags */ | 444 | /* disable all irqs, clear all irq flags */ |
445 | iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, | 445 | iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, |
446 | pd->regs + INT_CSR); | 446 | pd->regs + INT_CSR); |
@@ -494,7 +494,7 @@ dt3155_release(struct file *filp) | |||
494 | tmp = pd->curr_buf; | 494 | tmp = pd->curr_buf; |
495 | spin_unlock_irqrestore(&pd->lock, flags); | 495 | spin_unlock_irqrestore(&pd->lock, flags); |
496 | if (tmp) | 496 | if (tmp) |
497 | videobuf_waiton(tmp, 0, 1); /* block, interruptible */ | 497 | videobuf_waiton(pd->vidq, tmp, 0, 1); /* block, interruptible */ |
498 | dt3155_stop_acq(pd); | 498 | dt3155_stop_acq(pd); |
499 | videobuf_stop(pd->vidq); | 499 | videobuf_stop(pd->vidq); |
500 | pd->acq_fp = NULL; | 500 | pd->acq_fp = NULL; |
@@ -603,7 +603,7 @@ dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type) | |||
603 | tmp = pd->curr_buf; | 603 | tmp = pd->curr_buf; |
604 | spin_unlock_irqrestore(&pd->lock, flags); | 604 | spin_unlock_irqrestore(&pd->lock, flags); |
605 | if (tmp) | 605 | if (tmp) |
606 | videobuf_waiton(tmp, 0, 1); /* block, interruptible */ | 606 | videobuf_waiton(pd->vidq, tmp, 0, 1); /* block, interruptible */ |
607 | return ret; | 607 | return ret; |
608 | } | 608 | } |
609 | 609 | ||
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig index 75fa4680552..3aecd30f0d1 100644 --- a/drivers/staging/go7007/Kconfig +++ b/drivers/staging/go7007/Kconfig | |||
@@ -4,7 +4,7 @@ config VIDEO_GO7007 | |||
4 | depends on BKL # please fix | 4 | depends on BKL # please fix |
5 | depends on SND | 5 | depends on SND |
6 | select VIDEOBUF_DMA_SG | 6 | select VIDEOBUF_DMA_SG |
7 | select VIDEO_IR | 7 | depends on VIDEO_IR |
8 | select VIDEO_TUNER | 8 | select VIDEO_TUNER |
9 | select VIDEO_TVEEPROM | 9 | select VIDEO_TVEEPROM |
10 | select SND_PCM | 10 | select SND_PCM |
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index 372a7c6791c..b3f42f37a31 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c | |||
@@ -194,51 +194,15 @@ int go7007_reset_encoder(struct go7007 *go) | |||
194 | * Attempt to instantiate an I2C client by ID, probably loading a module. | 194 | * Attempt to instantiate an I2C client by ID, probably loading a module. |
195 | */ | 195 | */ |
196 | static int init_i2c_module(struct i2c_adapter *adapter, const char *type, | 196 | static int init_i2c_module(struct i2c_adapter *adapter, const char *type, |
197 | int id, int addr) | 197 | int addr) |
198 | { | 198 | { |
199 | struct go7007 *go = i2c_get_adapdata(adapter); | 199 | struct go7007 *go = i2c_get_adapdata(adapter); |
200 | struct v4l2_device *v4l2_dev = &go->v4l2_dev; | 200 | struct v4l2_device *v4l2_dev = &go->v4l2_dev; |
201 | char *modname; | ||
202 | 201 | ||
203 | switch (id) { | 202 | if (v4l2_i2c_new_subdev(v4l2_dev, adapter, NULL, type, addr, NULL)) |
204 | case I2C_DRIVERID_WIS_SAA7115: | ||
205 | modname = "wis-saa7115"; | ||
206 | break; | ||
207 | case I2C_DRIVERID_WIS_SAA7113: | ||
208 | modname = "wis-saa7113"; | ||
209 | break; | ||
210 | case I2C_DRIVERID_WIS_UDA1342: | ||
211 | modname = "wis-uda1342"; | ||
212 | break; | ||
213 | case I2C_DRIVERID_WIS_SONY_TUNER: | ||
214 | modname = "wis-sony-tuner"; | ||
215 | break; | ||
216 | case I2C_DRIVERID_WIS_TW9903: | ||
217 | modname = "wis-tw9903"; | ||
218 | break; | ||
219 | case I2C_DRIVERID_WIS_TW2804: | ||
220 | modname = "wis-tw2804"; | ||
221 | break; | ||
222 | case I2C_DRIVERID_WIS_OV7640: | ||
223 | modname = "wis-ov7640"; | ||
224 | break; | ||
225 | case I2C_DRIVERID_S2250: | ||
226 | modname = "s2250"; | ||
227 | break; | ||
228 | default: | ||
229 | modname = NULL; | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | if (v4l2_i2c_new_subdev(v4l2_dev, adapter, modname, type, addr, NULL)) | ||
234 | return 0; | 203 | return 0; |
235 | 204 | ||
236 | if (modname != NULL) | 205 | printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type); |
237 | printk(KERN_INFO | ||
238 | "go7007: probing for module %s failed\n", modname); | ||
239 | else | ||
240 | printk(KERN_INFO | ||
241 | "go7007: sensor %u seems to be unsupported!\n", id); | ||
242 | return -1; | 206 | return -1; |
243 | } | 207 | } |
244 | 208 | ||
@@ -277,7 +241,6 @@ int go7007_register_encoder(struct go7007 *go) | |||
277 | for (i = 0; i < go->board_info->num_i2c_devs; ++i) | 241 | for (i = 0; i < go->board_info->num_i2c_devs; ++i) |
278 | init_i2c_module(&go->i2c_adapter, | 242 | init_i2c_module(&go->i2c_adapter, |
279 | go->board_info->i2c_devs[i].type, | 243 | go->board_info->i2c_devs[i].type, |
280 | go->board_info->i2c_devs[i].id, | ||
281 | go->board_info->i2c_devs[i].addr); | 244 | go->board_info->i2c_devs[i].addr); |
282 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) | 245 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) |
283 | i2c_clients_command(&go->i2c_adapter, | 246 | i2c_clients_command(&go->i2c_adapter, |
@@ -393,7 +356,8 @@ static void write_bitmap_word(struct go7007 *go) | |||
393 | for (i = 0; i < 16; ++i) { | 356 | for (i = 0; i < 16; ++i) { |
394 | y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4); | 357 | y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4); |
395 | x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4); | 358 | x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4); |
396 | go->active_map[stride * y + (x >> 3)] |= | 359 | if (stride * y + (x >> 3) < sizeof(go->active_map)) |
360 | go->active_map[stride * y + (x >> 3)] |= | ||
397 | (go->modet_word & 1) << (x & 0x7); | 361 | (go->modet_word & 1) << (x & 0x7); |
398 | go->modet_word >>= 1; | 362 | go->modet_word >>= 1; |
399 | } | 363 | } |
@@ -485,6 +449,15 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length) | |||
485 | } | 449 | } |
486 | break; | 450 | break; |
487 | case STATE_00_00_01: | 451 | case STATE_00_00_01: |
452 | if (buf[i] == 0xF8 && go->modet_enable == 0) { | ||
453 | /* MODET start code, but MODET not enabled */ | ||
454 | store_byte(go->active_buf, 0x00); | ||
455 | store_byte(go->active_buf, 0x00); | ||
456 | store_byte(go->active_buf, 0x01); | ||
457 | store_byte(go->active_buf, 0xF8); | ||
458 | go->state = STATE_DATA; | ||
459 | break; | ||
460 | } | ||
488 | /* If this is the start of a new MPEG frame, | 461 | /* If this is the start of a new MPEG frame, |
489 | * get a new buffer */ | 462 | * get a new buffer */ |
490 | if ((go->format == GO7007_FORMAT_MPEG1 || | 463 | if ((go->format == GO7007_FORMAT_MPEG1 || |
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c index 20ed930b588..bea9f4d5bc3 100644 --- a/drivers/staging/go7007/go7007-usb.c +++ b/drivers/staging/go7007/go7007-usb.c | |||
@@ -394,7 +394,7 @@ static struct go7007_usb_board board_adlink_mpg24 = { | |||
394 | .num_i2c_devs = 1, | 394 | .num_i2c_devs = 1, |
395 | .i2c_devs = { | 395 | .i2c_devs = { |
396 | { | 396 | { |
397 | .type = "wis_twTW2804", | 397 | .type = "wis_tw2804", |
398 | .id = I2C_DRIVERID_WIS_TW2804, | 398 | .id = I2C_DRIVERID_WIS_TW2804, |
399 | .addr = 0x00, /* yes, really */ | 399 | .addr = 0x00, /* yes, really */ |
400 | }, | 400 | }, |
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index 46b4b9f6855..2b27d8da70a 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c | |||
@@ -252,23 +252,22 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) | |||
252 | go->modet_map[i] = 0; | 252 | go->modet_map[i] = 0; |
253 | 253 | ||
254 | if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { | 254 | if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { |
255 | struct v4l2_format res; | 255 | struct v4l2_mbus_framefmt mbus_fmt; |
256 | 256 | ||
257 | if (fmt != NULL) { | 257 | mbus_fmt.code = V4L2_MBUS_FMT_FIXED; |
258 | res = *fmt; | 258 | if (fmt != NULL) |
259 | } else { | 259 | mbus_fmt.width = fmt->fmt.pix.width; |
260 | res.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 260 | else |
261 | res.fmt.pix.width = width; | 261 | mbus_fmt.width = width; |
262 | } | ||
263 | 262 | ||
264 | if (height > sensor_height / 2) { | 263 | if (height > sensor_height / 2) { |
265 | res.fmt.pix.height = height / 2; | 264 | mbus_fmt.height = height / 2; |
266 | go->encoder_v_halve = 0; | 265 | go->encoder_v_halve = 0; |
267 | } else { | 266 | } else { |
268 | res.fmt.pix.height = height; | 267 | mbus_fmt.height = height; |
269 | go->encoder_v_halve = 1; | 268 | go->encoder_v_halve = 1; |
270 | } | 269 | } |
271 | call_all(&go->v4l2_dev, video, s_fmt, &res); | 270 | call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt); |
272 | } else { | 271 | } else { |
273 | if (width <= sensor_width / 4) { | 272 | if (width <= sensor_width / 4) { |
274 | go->encoder_h_halve = 1; | 273 | go->encoder_h_halve = 1; |
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index 93f26048e3b..e7736a91553 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <media/v4l2-device.h> | 24 | #include <media/v4l2-device.h> |
25 | #include <media/v4l2-common.h> | 25 | #include <media/v4l2-common.h> |
26 | #include <media/v4l2-i2c-drv.h> | ||
27 | #include <media/v4l2-subdev.h> | 26 | #include <media/v4l2-subdev.h> |
28 | #include "go7007-priv.h" | 27 | #include "go7007-priv.h" |
29 | 28 | ||
@@ -479,12 +478,13 @@ static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
479 | return 0; | 478 | return 0; |
480 | } | 479 | } |
481 | 480 | ||
482 | static int s2250_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | 481 | static int s2250_s_mbus_fmt(struct v4l2_subdev *sd, |
482 | struct v4l2_mbus_framefmt *fmt) | ||
483 | { | 483 | { |
484 | struct s2250 *state = to_state(sd); | 484 | struct s2250 *state = to_state(sd); |
485 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 485 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
486 | 486 | ||
487 | if (fmt->fmt.pix.height < 640) { | 487 | if (fmt->height < 640) { |
488 | write_reg_fp(client, 0x12b, state->reg12b_val | 0x400); | 488 | write_reg_fp(client, 0x12b, state->reg12b_val | 0x400); |
489 | write_reg_fp(client, 0x140, 0x060); | 489 | write_reg_fp(client, 0x140, 0x060); |
490 | } else { | 490 | } else { |
@@ -555,7 +555,7 @@ static const struct v4l2_subdev_audio_ops s2250_audio_ops = { | |||
555 | 555 | ||
556 | static const struct v4l2_subdev_video_ops s2250_video_ops = { | 556 | static const struct v4l2_subdev_video_ops s2250_video_ops = { |
557 | .s_routing = s2250_s_video_routing, | 557 | .s_routing = s2250_s_video_routing, |
558 | .s_fmt = s2250_s_fmt, | 558 | .s_mbus_fmt = s2250_s_mbus_fmt, |
559 | }; | 559 | }; |
560 | 560 | ||
561 | static const struct v4l2_subdev_ops s2250_ops = { | 561 | static const struct v4l2_subdev_ops s2250_ops = { |
@@ -674,9 +674,25 @@ static const struct i2c_device_id s2250_id[] = { | |||
674 | }; | 674 | }; |
675 | MODULE_DEVICE_TABLE(i2c, s2250_id); | 675 | MODULE_DEVICE_TABLE(i2c, s2250_id); |
676 | 676 | ||
677 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | 677 | static struct i2c_driver s2250_driver = { |
678 | .name = "s2250", | 678 | .driver = { |
679 | .probe = s2250_probe, | 679 | .owner = THIS_MODULE, |
680 | .remove = s2250_remove, | 680 | .name = "s2250", |
681 | .id_table = s2250_id, | 681 | }, |
682 | .probe = s2250_probe, | ||
683 | .remove = s2250_remove, | ||
684 | .id_table = s2250_id, | ||
682 | }; | 685 | }; |
686 | |||
687 | static __init int init_s2250(void) | ||
688 | { | ||
689 | return i2c_add_driver(&s2250_driver); | ||
690 | } | ||
691 | |||
692 | static __exit void exit_s2250(void) | ||
693 | { | ||
694 | i2c_del_driver(&s2250_driver); | ||
695 | } | ||
696 | |||
697 | module_init(init_s2250); | ||
698 | module_exit(exit_s2250); | ||
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c index 4f0cbdde276..6bc9470fecb 100644 --- a/drivers/staging/go7007/wis-ov7640.c +++ b/drivers/staging/go7007/wis-ov7640.c | |||
@@ -81,6 +81,7 @@ static const struct i2c_device_id wis_ov7640_id[] = { | |||
81 | { "wis_ov7640", 0 }, | 81 | { "wis_ov7640", 0 }, |
82 | { } | 82 | { } |
83 | }; | 83 | }; |
84 | MODULE_DEVICE_TABLE(i2c, wis_ov7640_id); | ||
84 | 85 | ||
85 | static struct i2c_driver wis_ov7640_driver = { | 86 | static struct i2c_driver wis_ov7640_driver = { |
86 | .driver = { | 87 | .driver = { |
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c index 72f5c1f56d1..05e0e108386 100644 --- a/drivers/staging/go7007/wis-saa7113.c +++ b/drivers/staging/go7007/wis-saa7113.c | |||
@@ -308,6 +308,7 @@ static const struct i2c_device_id wis_saa7113_id[] = { | |||
308 | { "wis_saa7113", 0 }, | 308 | { "wis_saa7113", 0 }, |
309 | { } | 309 | { } |
310 | }; | 310 | }; |
311 | MODULE_DEVICE_TABLE(i2c, wis_saa7113_id); | ||
311 | 312 | ||
312 | static struct i2c_driver wis_saa7113_driver = { | 313 | static struct i2c_driver wis_saa7113_driver = { |
313 | .driver = { | 314 | .driver = { |
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c index cd950b61cf7..46cff59e28b 100644 --- a/drivers/staging/go7007/wis-saa7115.c +++ b/drivers/staging/go7007/wis-saa7115.c | |||
@@ -441,6 +441,7 @@ static const struct i2c_device_id wis_saa7115_id[] = { | |||
441 | { "wis_saa7115", 0 }, | 441 | { "wis_saa7115", 0 }, |
442 | { } | 442 | { } |
443 | }; | 443 | }; |
444 | MODULE_DEVICE_TABLE(i2c, wis_saa7115_id); | ||
444 | 445 | ||
445 | static struct i2c_driver wis_saa7115_driver = { | 446 | static struct i2c_driver wis_saa7115_driver = { |
446 | .driver = { | 447 | .driver = { |
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index 981c9b311b8..8f1b7d4f6a2 100644 --- a/drivers/staging/go7007/wis-sony-tuner.c +++ b/drivers/staging/go7007/wis-sony-tuner.c | |||
@@ -692,6 +692,7 @@ static const struct i2c_device_id wis_sony_tuner_id[] = { | |||
692 | { "wis_sony_tuner", 0 }, | 692 | { "wis_sony_tuner", 0 }, |
693 | { } | 693 | { } |
694 | }; | 694 | }; |
695 | MODULE_DEVICE_TABLE(i2c, wis_sony_tuner_id); | ||
695 | 696 | ||
696 | static struct i2c_driver wis_sony_tuner_driver = { | 697 | static struct i2c_driver wis_sony_tuner_driver = { |
697 | .driver = { | 698 | .driver = { |
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c index ee28a99dc38..5b218c55842 100644 --- a/drivers/staging/go7007/wis-tw2804.c +++ b/drivers/staging/go7007/wis-tw2804.c | |||
@@ -331,6 +331,7 @@ static const struct i2c_device_id wis_tw2804_id[] = { | |||
331 | { "wis_tw2804", 0 }, | 331 | { "wis_tw2804", 0 }, |
332 | { } | 332 | { } |
333 | }; | 333 | }; |
334 | MODULE_DEVICE_TABLE(i2c, wis_tw2804_id); | ||
334 | 335 | ||
335 | static struct i2c_driver wis_tw2804_driver = { | 336 | static struct i2c_driver wis_tw2804_driver = { |
336 | .driver = { | 337 | .driver = { |
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c index 80d47269b1c..9230f4a8052 100644 --- a/drivers/staging/go7007/wis-tw9903.c +++ b/drivers/staging/go7007/wis-tw9903.c | |||
@@ -313,6 +313,7 @@ static const struct i2c_device_id wis_tw9903_id[] = { | |||
313 | { "wis_tw9903", 0 }, | 313 | { "wis_tw9903", 0 }, |
314 | { } | 314 | { } |
315 | }; | 315 | }; |
316 | MODULE_DEVICE_TABLE(i2c, wis_tw9903_id); | ||
316 | 317 | ||
317 | static struct i2c_driver wis_tw9903_driver = { | 318 | static struct i2c_driver wis_tw9903_driver = { |
318 | .driver = { | 319 | .driver = { |
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c index 5c4eb49d735..0127be2f3be 100644 --- a/drivers/staging/go7007/wis-uda1342.c +++ b/drivers/staging/go7007/wis-uda1342.c | |||
@@ -86,6 +86,7 @@ static const struct i2c_device_id wis_uda1342_id[] = { | |||
86 | { "wis_uda1342", 0 }, | 86 | { "wis_uda1342", 0 }, |
87 | { } | 87 | { } |
88 | }; | 88 | }; |
89 | MODULE_DEVICE_TABLE(i2c, wis_uda1342_id); | ||
89 | 90 | ||
90 | static struct i2c_driver wis_uda1342_driver = { | 91 | static struct i2c_driver wis_uda1342_driver = { |
91 | .driver = { | 92 | .driver = { |
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig index 100c4d4b812..fa790db75d7 100644 --- a/drivers/staging/lirc/Kconfig +++ b/drivers/staging/lirc/Kconfig | |||
@@ -53,7 +53,7 @@ config LIRC_ITE8709 | |||
53 | 53 | ||
54 | config LIRC_PARALLEL | 54 | config LIRC_PARALLEL |
55 | tristate "Homebrew Parallel Port Receiver" | 55 | tristate "Homebrew Parallel Port Receiver" |
56 | depends on LIRC_STAGING && PARPORT && !SMP | 56 | depends on LIRC_STAGING && PARPORT |
57 | help | 57 | help |
58 | Driver for Homebrew Parallel Port Receivers | 58 | Driver for Homebrew Parallel Port Receivers |
59 | 59 | ||
diff --git a/drivers/staging/lirc/lirc_igorplugusb.c b/drivers/staging/lirc/lirc_igorplugusb.c index bce600ede26..0dc2c2b22c2 100644 --- a/drivers/staging/lirc/lirc_igorplugusb.c +++ b/drivers/staging/lirc/lirc_igorplugusb.c | |||
@@ -54,10 +54,10 @@ | |||
54 | 54 | ||
55 | 55 | ||
56 | /* module identification */ | 56 | /* module identification */ |
57 | #define DRIVER_VERSION "0.1" | 57 | #define DRIVER_VERSION "0.2" |
58 | #define DRIVER_AUTHOR \ | 58 | #define DRIVER_AUTHOR \ |
59 | "Jan M. Hochstein <hochstein@algo.informatik.tu-darmstadt.de>" | 59 | "Jan M. Hochstein <hochstein@algo.informatik.tu-darmstadt.de>" |
60 | #define DRIVER_DESC "USB remote driver for LIRC" | 60 | #define DRIVER_DESC "Igorplug USB remote driver for LIRC" |
61 | #define DRIVER_NAME "lirc_igorplugusb" | 61 | #define DRIVER_NAME "lirc_igorplugusb" |
62 | 62 | ||
63 | /* debugging support */ | 63 | /* debugging support */ |
@@ -201,7 +201,6 @@ struct igorplug { | |||
201 | 201 | ||
202 | /* usb */ | 202 | /* usb */ |
203 | struct usb_device *usbdev; | 203 | struct usb_device *usbdev; |
204 | struct urb *urb_in; | ||
205 | int devnum; | 204 | int devnum; |
206 | 205 | ||
207 | unsigned char *buf_in; | 206 | unsigned char *buf_in; |
@@ -216,28 +215,36 @@ struct igorplug { | |||
216 | 215 | ||
217 | /* handle sending (init strings) */ | 216 | /* handle sending (init strings) */ |
218 | int send_flags; | 217 | int send_flags; |
219 | wait_queue_head_t wait_out; | ||
220 | }; | 218 | }; |
221 | 219 | ||
222 | static int unregister_from_lirc(struct igorplug *ir) | 220 | static int unregister_from_lirc(struct igorplug *ir) |
223 | { | 221 | { |
224 | struct lirc_driver *d = ir->d; | 222 | struct lirc_driver *d; |
225 | int devnum; | 223 | int devnum; |
226 | 224 | ||
227 | if (!ir->d) | 225 | if (!ir) { |
226 | printk(KERN_ERR "%s: called with NULL device struct!\n", | ||
227 | __func__); | ||
228 | return -EINVAL; | 228 | return -EINVAL; |
229 | } | ||
229 | 230 | ||
230 | devnum = ir->devnum; | 231 | devnum = ir->devnum; |
231 | dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); | 232 | d = ir->d; |
232 | 233 | ||
233 | lirc_unregister_driver(d->minor); | 234 | if (!d) { |
235 | printk(KERN_ERR "%s: called with NULL lirc driver struct!\n", | ||
236 | __func__); | ||
237 | return -EINVAL; | ||
238 | } | ||
234 | 239 | ||
235 | printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); | 240 | dprintk(DRIVER_NAME "[%d]: calling lirc_unregister_driver\n", devnum); |
241 | lirc_unregister_driver(d->minor); | ||
236 | 242 | ||
237 | kfree(d); | 243 | kfree(d); |
238 | ir->d = NULL; | 244 | ir->d = NULL; |
239 | kfree(ir); | 245 | kfree(ir); |
240 | return 0; | 246 | |
247 | return devnum; | ||
241 | } | 248 | } |
242 | 249 | ||
243 | static int set_use_inc(void *data) | 250 | static int set_use_inc(void *data) |
@@ -248,6 +255,7 @@ static int set_use_inc(void *data) | |||
248 | printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); | 255 | printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); |
249 | return -EIO; | 256 | return -EIO; |
250 | } | 257 | } |
258 | |||
251 | dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); | 259 | dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); |
252 | 260 | ||
253 | if (!ir->usbdev) | 261 | if (!ir->usbdev) |
@@ -264,9 +272,29 @@ static void set_use_dec(void *data) | |||
264 | printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); | 272 | printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); |
265 | return; | 273 | return; |
266 | } | 274 | } |
275 | |||
267 | dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); | 276 | dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); |
268 | } | 277 | } |
269 | 278 | ||
279 | static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf, | ||
280 | int i, int max) | ||
281 | { | ||
282 | int code; | ||
283 | |||
284 | /* MODE2: pulse/space (PULSE_BIT) in 1us units */ | ||
285 | while (i < max) { | ||
286 | /* 1 Igor-tick = 85.333333 us */ | ||
287 | code = (unsigned int)ir->buf_in[i] * 85 + | ||
288 | (unsigned int)ir->buf_in[i] / 3; | ||
289 | ir->last_time.tv_usec += code; | ||
290 | if (ir->in_space) | ||
291 | code |= PULSE_BIT; | ||
292 | lirc_buffer_write(buf, (unsigned char *)&code); | ||
293 | /* 1 chunk = CODE_LENGTH bytes */ | ||
294 | ir->in_space ^= 1; | ||
295 | ++i; | ||
296 | } | ||
297 | } | ||
270 | 298 | ||
271 | /** | 299 | /** |
272 | * Called in user context. | 300 | * Called in user context. |
@@ -274,41 +302,32 @@ static void set_use_dec(void *data) | |||
274 | * -ENODATA if none was available. This should add some number of bits | 302 | * -ENODATA if none was available. This should add some number of bits |
275 | * evenly divisible by code_length to the buffer | 303 | * evenly divisible by code_length to the buffer |
276 | */ | 304 | */ |
277 | static int usb_remote_poll(void *data, struct lirc_buffer *buf) | 305 | static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) |
278 | { | 306 | { |
279 | int ret; | 307 | int ret; |
280 | struct igorplug *ir = (struct igorplug *)data; | 308 | struct igorplug *ir = (struct igorplug *)data; |
281 | 309 | ||
282 | if (!ir->usbdev) /* Has the device been removed? */ | 310 | if (!ir || !ir->usbdev) /* Has the device been removed? */ |
283 | return -ENODEV; | 311 | return -ENODEV; |
284 | 312 | ||
285 | memset(ir->buf_in, 0, ir->len_in); | 313 | memset(ir->buf_in, 0, ir->len_in); |
286 | 314 | ||
287 | ret = usb_control_msg( | 315 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), |
288 | ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | 316 | GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN, |
289 | GET_INFRACODE, USB_TYPE_VENDOR|USB_DIR_IN, | 317 | 0/* offset */, /*unused*/0, |
290 | 0/* offset */, /*unused*/0, | 318 | ir->buf_in, ir->len_in, |
291 | ir->buf_in, ir->len_in, | 319 | /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); |
292 | /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); | ||
293 | if (ret > 0) { | 320 | if (ret > 0) { |
294 | int i = DEVICE_HEADERLEN; | ||
295 | int code, timediff; | 321 | int code, timediff; |
296 | struct timeval now; | 322 | struct timeval now; |
297 | 323 | ||
298 | if (ret <= 1) /* ACK packet has 1 byte --> ignore */ | 324 | /* ACK packet has 1 byte --> ignore */ |
325 | if (ret < DEVICE_HEADERLEN) | ||
299 | return -ENODATA; | 326 | return -ENODATA; |
300 | 327 | ||
301 | dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", | 328 | dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", |
302 | ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); | 329 | ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); |
303 | 330 | ||
304 | if (ir->buf_in[2] != 0) { | ||
305 | printk(DRIVER_NAME "[%d]: Device buffer overrun.\n", | ||
306 | ir->devnum); | ||
307 | /* start at earliest byte */ | ||
308 | i = DEVICE_HEADERLEN + ir->buf_in[2]; | ||
309 | /* where are we now? space, gap or pulse? */ | ||
310 | } | ||
311 | |||
312 | do_gettimeofday(&now); | 331 | do_gettimeofday(&now); |
313 | timediff = now.tv_sec - ir->last_time.tv_sec; | 332 | timediff = now.tv_sec - ir->last_time.tv_sec; |
314 | if (timediff + 1 > PULSE_MASK / 1000000) | 333 | if (timediff + 1 > PULSE_MASK / 1000000) |
@@ -325,18 +344,20 @@ static int usb_remote_poll(void *data, struct lirc_buffer *buf) | |||
325 | lirc_buffer_write(buf, (unsigned char *)&code); | 344 | lirc_buffer_write(buf, (unsigned char *)&code); |
326 | ir->in_space = 1; /* next comes a pulse */ | 345 | ir->in_space = 1; /* next comes a pulse */ |
327 | 346 | ||
328 | /* MODE2: pulse/space (PULSE_BIT) in 1us units */ | 347 | if (ir->buf_in[2] == 0) |
329 | 348 | send_fragment(ir, buf, DEVICE_HEADERLEN, ret); | |
330 | while (i < ret) { | 349 | else { |
331 | /* 1 Igor-tick = 85.333333 us */ | 350 | printk(KERN_WARNING DRIVER_NAME |
332 | code = (unsigned int)ir->buf_in[i] * 85 | 351 | "[%d]: Device buffer overrun.\n", ir->devnum); |
333 | + (unsigned int)ir->buf_in[i] / 3; | 352 | /* HHHNNNNNNNNNNNOOOOOOOO H = header |
334 | if (ir->in_space) | 353 | <---[2]---> N = newer |
335 | code |= PULSE_BIT; | 354 | <---------ret--------> O = older */ |
336 | lirc_buffer_write(buf, (unsigned char *)&code); | 355 | ir->buf_in[2] %= ret - DEVICE_HEADERLEN; /* sanitize */ |
337 | /* 1 chunk = CODE_LENGTH bytes */ | 356 | /* keep even-ness to not desync pulse/pause */ |
338 | ir->in_space ^= 1; | 357 | send_fragment(ir, buf, DEVICE_HEADERLEN + |
339 | ++i; | 358 | ir->buf_in[2] - (ir->buf_in[2] & 1), ret); |
359 | send_fragment(ir, buf, DEVICE_HEADERLEN, | ||
360 | DEVICE_HEADERLEN + ir->buf_in[2]); | ||
340 | } | 361 | } |
341 | 362 | ||
342 | ret = usb_control_msg( | 363 | ret = usb_control_msg( |
@@ -358,12 +379,12 @@ static int usb_remote_poll(void *data, struct lirc_buffer *buf) | |||
358 | 379 | ||
359 | 380 | ||
360 | 381 | ||
361 | static int usb_remote_probe(struct usb_interface *intf, | 382 | static int igorplugusb_remote_probe(struct usb_interface *intf, |
362 | const struct usb_device_id *id) | 383 | const struct usb_device_id *id) |
363 | { | 384 | { |
364 | struct usb_device *dev = NULL; | 385 | struct usb_device *dev = NULL; |
365 | struct usb_host_interface *idesc = NULL; | 386 | struct usb_host_interface *idesc = NULL; |
366 | struct usb_host_endpoint *ep_ctl2; | 387 | struct usb_endpoint_descriptor *ep; |
367 | struct igorplug *ir = NULL; | 388 | struct igorplug *ir = NULL; |
368 | struct lirc_driver *driver = NULL; | 389 | struct lirc_driver *driver = NULL; |
369 | int devnum, pipe, maxp; | 390 | int devnum, pipe, maxp; |
@@ -380,20 +401,21 @@ static int usb_remote_probe(struct usb_interface *intf, | |||
380 | 401 | ||
381 | if (idesc->desc.bNumEndpoints != 1) | 402 | if (idesc->desc.bNumEndpoints != 1) |
382 | return -ENODEV; | 403 | return -ENODEV; |
383 | ep_ctl2 = idesc->endpoint; | 404 | |
384 | if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 405 | ep = &idesc->endpoint->desc; |
406 | if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
385 | != USB_DIR_IN) | 407 | != USB_DIR_IN) |
386 | || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 408 | || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) |
387 | != USB_ENDPOINT_XFER_CONTROL) | 409 | != USB_ENDPOINT_XFER_CONTROL) |
388 | return -ENODEV; | 410 | return -ENODEV; |
389 | pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); | 411 | |
412 | pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress); | ||
390 | devnum = dev->devnum; | 413 | devnum = dev->devnum; |
391 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 414 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
392 | 415 | ||
393 | dprintk(DRIVER_NAME "[%d]: bytes_in_key=%lu maxp=%d\n", | 416 | dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n", |
394 | devnum, CODE_LENGTH, maxp); | 417 | devnum, CODE_LENGTH, maxp); |
395 | 418 | ||
396 | |||
397 | mem_failure = 0; | 419 | mem_failure = 0; |
398 | ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); | 420 | ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); |
399 | if (!ir) { | 421 | if (!ir) { |
@@ -406,9 +428,8 @@ static int usb_remote_probe(struct usb_interface *intf, | |||
406 | goto mem_failure_switch; | 428 | goto mem_failure_switch; |
407 | } | 429 | } |
408 | 430 | ||
409 | ir->buf_in = usb_alloc_coherent(dev, | 431 | ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, |
410 | DEVICE_BUFLEN+DEVICE_HEADERLEN, | 432 | GFP_ATOMIC, &ir->dma_in); |
411 | GFP_ATOMIC, &ir->dma_in); | ||
412 | if (!ir->buf_in) { | 433 | if (!ir->buf_in) { |
413 | mem_failure = 3; | 434 | mem_failure = 3; |
414 | goto mem_failure_switch; | 435 | goto mem_failure_switch; |
@@ -424,12 +445,10 @@ static int usb_remote_probe(struct usb_interface *intf, | |||
424 | driver->set_use_inc = &set_use_inc; | 445 | driver->set_use_inc = &set_use_inc; |
425 | driver->set_use_dec = &set_use_dec; | 446 | driver->set_use_dec = &set_use_dec; |
426 | driver->sample_rate = sample_rate; /* per second */ | 447 | driver->sample_rate = sample_rate; /* per second */ |
427 | driver->add_to_buf = &usb_remote_poll; | 448 | driver->add_to_buf = &igorplugusb_remote_poll; |
428 | driver->dev = &intf->dev; | 449 | driver->dev = &intf->dev; |
429 | driver->owner = THIS_MODULE; | 450 | driver->owner = THIS_MODULE; |
430 | 451 | ||
431 | init_waitqueue_head(&ir->wait_out); | ||
432 | |||
433 | minor = lirc_register_driver(driver); | 452 | minor = lirc_register_driver(driver); |
434 | if (minor < 0) | 453 | if (minor < 0) |
435 | mem_failure = 9; | 454 | mem_failure = 9; |
@@ -438,7 +457,7 @@ mem_failure_switch: | |||
438 | 457 | ||
439 | switch (mem_failure) { | 458 | switch (mem_failure) { |
440 | case 9: | 459 | case 9: |
441 | usb_free_coherent(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, | 460 | usb_free_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, |
442 | ir->buf_in, ir->dma_in); | 461 | ir->buf_in, ir->dma_in); |
443 | case 3: | 462 | case 3: |
444 | kfree(driver); | 463 | kfree(driver); |
@@ -454,7 +473,7 @@ mem_failure_switch: | |||
454 | ir->d = driver; | 473 | ir->d = driver; |
455 | ir->devnum = devnum; | 474 | ir->devnum = devnum; |
456 | ir->usbdev = dev; | 475 | ir->usbdev = dev; |
457 | ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN; | 476 | ir->len_in = DEVICE_BUFLEN + DEVICE_HEADERLEN; |
458 | ir->in_space = 1; /* First mode2 event is a space. */ | 477 | ir->in_space = 1; /* First mode2 event is a space. */ |
459 | do_gettimeofday(&ir->last_time); | 478 | do_gettimeofday(&ir->last_time); |
460 | 479 | ||
@@ -484,63 +503,64 @@ mem_failure_switch: | |||
484 | } | 503 | } |
485 | 504 | ||
486 | 505 | ||
487 | static void usb_remote_disconnect(struct usb_interface *intf) | 506 | static void igorplugusb_remote_disconnect(struct usb_interface *intf) |
488 | { | 507 | { |
489 | struct usb_device *dev = interface_to_usbdev(intf); | 508 | struct usb_device *usbdev = interface_to_usbdev(intf); |
490 | struct igorplug *ir = usb_get_intfdata(intf); | 509 | struct igorplug *ir = usb_get_intfdata(intf); |
510 | struct device *dev = &intf->dev; | ||
511 | int devnum; | ||
512 | |||
491 | usb_set_intfdata(intf, NULL); | 513 | usb_set_intfdata(intf, NULL); |
492 | 514 | ||
493 | if (!ir || !ir->d) | 515 | if (!ir || !ir->d) |
494 | return; | 516 | return; |
495 | 517 | ||
496 | ir->usbdev = NULL; | 518 | ir->usbdev = NULL; |
497 | wake_up_all(&ir->wait_out); | ||
498 | 519 | ||
499 | usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); | 520 | usb_free_coherent(usbdev, ir->len_in, ir->buf_in, ir->dma_in); |
521 | |||
522 | devnum = unregister_from_lirc(ir); | ||
500 | 523 | ||
501 | unregister_from_lirc(ir); | 524 | dev_info(dev, DRIVER_NAME "[%d]: %s done\n", devnum, __func__); |
502 | } | 525 | } |
503 | 526 | ||
504 | static struct usb_device_id usb_remote_id_table[] = { | 527 | static struct usb_device_id igorplugusb_remote_id_table[] = { |
505 | /* Igor Plug USB (Atmel's Manufact. ID) */ | 528 | /* Igor Plug USB (Atmel's Manufact. ID) */ |
506 | { USB_DEVICE(0x03eb, 0x0002) }, | 529 | { USB_DEVICE(0x03eb, 0x0002) }, |
530 | /* Fit PC2 Infrared Adapter */ | ||
531 | { USB_DEVICE(0x03eb, 0x21fe) }, | ||
507 | 532 | ||
508 | /* Terminating entry */ | 533 | /* Terminating entry */ |
509 | { } | 534 | { } |
510 | }; | 535 | }; |
511 | 536 | ||
512 | static struct usb_driver usb_remote_driver = { | 537 | static struct usb_driver igorplugusb_remote_driver = { |
513 | .name = DRIVER_NAME, | 538 | .name = DRIVER_NAME, |
514 | .probe = usb_remote_probe, | 539 | .probe = igorplugusb_remote_probe, |
515 | .disconnect = usb_remote_disconnect, | 540 | .disconnect = igorplugusb_remote_disconnect, |
516 | .id_table = usb_remote_id_table | 541 | .id_table = igorplugusb_remote_id_table |
517 | }; | 542 | }; |
518 | 543 | ||
519 | static int __init usb_remote_init(void) | 544 | static int __init igorplugusb_remote_init(void) |
520 | { | 545 | { |
521 | int i; | 546 | int ret = 0; |
522 | 547 | ||
523 | printk(KERN_INFO "\n" | 548 | dprintk(DRIVER_NAME ": loaded, debug mode enabled\n"); |
524 | DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); | ||
525 | printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); | ||
526 | dprintk(DRIVER_NAME ": debug mode enabled\n"); | ||
527 | 549 | ||
528 | i = usb_register(&usb_remote_driver); | 550 | ret = usb_register(&igorplugusb_remote_driver); |
529 | if (i < 0) { | 551 | if (ret) |
530 | printk(DRIVER_NAME ": usb register failed, result = %d\n", i); | 552 | printk(KERN_ERR DRIVER_NAME ": usb register failed!\n"); |
531 | return -ENODEV; | ||
532 | } | ||
533 | 553 | ||
534 | return 0; | 554 | return ret; |
535 | } | 555 | } |
536 | 556 | ||
537 | static void __exit usb_remote_exit(void) | 557 | static void __exit igorplugusb_remote_exit(void) |
538 | { | 558 | { |
539 | usb_deregister(&usb_remote_driver); | 559 | usb_deregister(&igorplugusb_remote_driver); |
540 | } | 560 | } |
541 | 561 | ||
542 | module_init(usb_remote_init); | 562 | module_init(igorplugusb_remote_init); |
543 | module_exit(usb_remote_exit); | 563 | module_exit(igorplugusb_remote_exit); |
544 | 564 | ||
545 | #include <linux/vermagic.h> | 565 | #include <linux/vermagic.h> |
546 | MODULE_INFO(vermagic, VERMAGIC_STRING); | 566 | MODULE_INFO(vermagic, VERMAGIC_STRING); |
@@ -548,8 +568,10 @@ MODULE_INFO(vermagic, VERMAGIC_STRING); | |||
548 | MODULE_DESCRIPTION(DRIVER_DESC); | 568 | MODULE_DESCRIPTION(DRIVER_DESC); |
549 | MODULE_AUTHOR(DRIVER_AUTHOR); | 569 | MODULE_AUTHOR(DRIVER_AUTHOR); |
550 | MODULE_LICENSE("GPL"); | 570 | MODULE_LICENSE("GPL"); |
551 | MODULE_DEVICE_TABLE(usb, usb_remote_id_table); | 571 | MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table); |
552 | 572 | ||
553 | module_param(sample_rate, int, S_IRUGO | S_IWUSR); | 573 | module_param(sample_rate, int, S_IRUGO | S_IWUSR); |
554 | MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); | 574 | MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); |
555 | 575 | ||
576 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
577 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c index 543c5c3bf90..929ae579546 100644 --- a/drivers/staging/lirc/lirc_it87.c +++ b/drivers/staging/lirc/lirc_it87.c | |||
@@ -239,8 +239,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, | |||
239 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 239 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
240 | { | 240 | { |
241 | int retval = 0; | 241 | int retval = 0; |
242 | unsigned long value = 0; | 242 | __u32 value = 0; |
243 | unsigned int ivalue; | ||
244 | unsigned long hw_flags; | 243 | unsigned long hw_flags; |
245 | 244 | ||
246 | if (cmd == LIRC_GET_FEATURES) | 245 | if (cmd == LIRC_GET_FEATURES) |
@@ -256,24 +255,24 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
256 | case LIRC_GET_FEATURES: | 255 | case LIRC_GET_FEATURES: |
257 | case LIRC_GET_SEND_MODE: | 256 | case LIRC_GET_SEND_MODE: |
258 | case LIRC_GET_REC_MODE: | 257 | case LIRC_GET_REC_MODE: |
259 | retval = put_user(value, (unsigned long *) arg); | 258 | retval = put_user(value, (__u32 *) arg); |
260 | break; | 259 | break; |
261 | 260 | ||
262 | case LIRC_SET_SEND_MODE: | 261 | case LIRC_SET_SEND_MODE: |
263 | case LIRC_SET_REC_MODE: | 262 | case LIRC_SET_REC_MODE: |
264 | retval = get_user(value, (unsigned long *) arg); | 263 | retval = get_user(value, (__u32 *) arg); |
265 | break; | 264 | break; |
266 | 265 | ||
267 | case LIRC_SET_SEND_CARRIER: | 266 | case LIRC_SET_SEND_CARRIER: |
268 | retval = get_user(ivalue, (unsigned int *) arg); | 267 | retval = get_user(value, (__u32 *) arg); |
269 | if (retval) | 268 | if (retval) |
270 | return retval; | 269 | return retval; |
271 | ivalue /= 1000; | 270 | value /= 1000; |
272 | if (ivalue > IT87_CIR_FREQ_MAX || | 271 | if (value > IT87_CIR_FREQ_MAX || |
273 | ivalue < IT87_CIR_FREQ_MIN) | 272 | value < IT87_CIR_FREQ_MIN) |
274 | return -EINVAL; | 273 | return -EINVAL; |
275 | 274 | ||
276 | it87_freq = ivalue; | 275 | it87_freq = value; |
277 | 276 | ||
278 | spin_lock_irqsave(&hardware_lock, hw_flags); | 277 | spin_lock_irqsave(&hardware_lock, hw_flags); |
279 | outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) | | 278 | outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) | |
@@ -340,6 +339,9 @@ static const struct file_operations lirc_fops = { | |||
340 | .write = lirc_write, | 339 | .write = lirc_write, |
341 | .poll = lirc_poll, | 340 | .poll = lirc_poll, |
342 | .unlocked_ioctl = lirc_ioctl, | 341 | .unlocked_ioctl = lirc_ioctl, |
342 | #ifdef CONFIG_COMPAT | ||
343 | .compat_ioctl = lirc_ioctl, | ||
344 | #endif | ||
343 | .open = lirc_open, | 345 | .open = lirc_open, |
344 | .release = lirc_close, | 346 | .release = lirc_close, |
345 | .llseek = noop_llseek, | 347 | .llseek = noop_llseek, |
@@ -964,10 +966,11 @@ static void __exit lirc_it87_exit(void) | |||
964 | printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); | 966 | printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); |
965 | } | 967 | } |
966 | 968 | ||
967 | /* SECTION: PNP for ITE8704/18 */ | 969 | /* SECTION: PNP for ITE8704/13/18 */ |
968 | 970 | ||
969 | static const struct pnp_device_id pnp_dev_table[] = { | 971 | static const struct pnp_device_id pnp_dev_table[] = { |
970 | {"ITE8704", 0}, | 972 | {"ITE8704", 0}, |
973 | {"ITE8713", 0}, | ||
971 | {} | 974 | {} |
972 | }; | 975 | }; |
973 | 976 | ||
diff --git a/drivers/staging/lirc/lirc_ite8709.c b/drivers/staging/lirc/lirc_ite8709.c index 9352f45bbec..cb20cfdcfad 100644 --- a/drivers/staging/lirc/lirc_ite8709.c +++ b/drivers/staging/lirc/lirc_ite8709.c | |||
@@ -102,8 +102,8 @@ struct ite8709_device { | |||
102 | int io; | 102 | int io; |
103 | int irq; | 103 | int irq; |
104 | spinlock_t hardware_lock; | 104 | spinlock_t hardware_lock; |
105 | unsigned long long acc_pulse; | 105 | __u64 acc_pulse; |
106 | unsigned long long acc_space; | 106 | __u64 acc_space; |
107 | char lastbit; | 107 | char lastbit; |
108 | struct timeval last_tv; | 108 | struct timeval last_tv; |
109 | struct lirc_driver driver; | 109 | struct lirc_driver driver; |
@@ -220,7 +220,7 @@ static void ite8709_set_use_dec(void *data) | |||
220 | } | 220 | } |
221 | 221 | ||
222 | static void ite8709_add_read_queue(struct ite8709_device *dev, int flag, | 222 | static void ite8709_add_read_queue(struct ite8709_device *dev, int flag, |
223 | unsigned long long val) | 223 | __u64 val) |
224 | { | 224 | { |
225 | int value; | 225 | int value; |
226 | 226 | ||
diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c index 6da4a8c6ebc..884904c782d 100644 --- a/drivers/staging/lirc/lirc_parallel.c +++ b/drivers/staging/lirc/lirc_parallel.c | |||
@@ -24,10 +24,6 @@ | |||
24 | 24 | ||
25 | /*** Includes ***/ | 25 | /*** Includes ***/ |
26 | 26 | ||
27 | #ifdef CONFIG_SMP | ||
28 | #error "--- Sorry, this driver is not SMP safe. ---" | ||
29 | #endif | ||
30 | |||
31 | #include <linux/module.h> | 27 | #include <linux/module.h> |
32 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
33 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
@@ -301,9 +297,9 @@ static void irq_handler(void *blah) | |||
301 | 297 | ||
302 | if (signal != 0) { | 298 | if (signal != 0) { |
303 | /* ajust value to usecs */ | 299 | /* ajust value to usecs */ |
304 | unsigned long long helper; | 300 | __u64 helper; |
305 | 301 | ||
306 | helper = ((unsigned long long) signal)*1000000; | 302 | helper = ((__u64) signal)*1000000; |
307 | do_div(helper, timer); | 303 | do_div(helper, timer); |
308 | signal = (long) helper; | 304 | signal = (long) helper; |
309 | 305 | ||
@@ -404,9 +400,9 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, | |||
404 | 400 | ||
405 | /* adjust values from usecs */ | 401 | /* adjust values from usecs */ |
406 | for (i = 0; i < count; i++) { | 402 | for (i = 0; i < count; i++) { |
407 | unsigned long long helper; | 403 | __u64 helper; |
408 | 404 | ||
409 | helper = ((unsigned long long) wbuf[i])*timer; | 405 | helper = ((__u64) wbuf[i])*timer; |
410 | do_div(helper, 1000000); | 406 | do_div(helper, 1000000); |
411 | wbuf[i] = (int) helper; | 407 | wbuf[i] = (int) helper; |
412 | } | 408 | } |
@@ -464,48 +460,48 @@ static unsigned int lirc_poll(struct file *file, poll_table *wait) | |||
464 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 460 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
465 | { | 461 | { |
466 | int result; | 462 | int result; |
467 | unsigned long features = LIRC_CAN_SET_TRANSMITTER_MASK | | 463 | __u32 features = LIRC_CAN_SET_TRANSMITTER_MASK | |
468 | LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; | 464 | LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; |
469 | unsigned long mode; | 465 | __u32 mode; |
470 | unsigned int ivalue; | 466 | __u32 value; |
471 | 467 | ||
472 | switch (cmd) { | 468 | switch (cmd) { |
473 | case LIRC_GET_FEATURES: | 469 | case LIRC_GET_FEATURES: |
474 | result = put_user(features, (unsigned long *) arg); | 470 | result = put_user(features, (__u32 *) arg); |
475 | if (result) | 471 | if (result) |
476 | return result; | 472 | return result; |
477 | break; | 473 | break; |
478 | case LIRC_GET_SEND_MODE: | 474 | case LIRC_GET_SEND_MODE: |
479 | result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); | 475 | result = put_user(LIRC_MODE_PULSE, (__u32 *) arg); |
480 | if (result) | 476 | if (result) |
481 | return result; | 477 | return result; |
482 | break; | 478 | break; |
483 | case LIRC_GET_REC_MODE: | 479 | case LIRC_GET_REC_MODE: |
484 | result = put_user(LIRC_MODE_MODE2, (unsigned long *) arg); | 480 | result = put_user(LIRC_MODE_MODE2, (__u32 *) arg); |
485 | if (result) | 481 | if (result) |
486 | return result; | 482 | return result; |
487 | break; | 483 | break; |
488 | case LIRC_SET_SEND_MODE: | 484 | case LIRC_SET_SEND_MODE: |
489 | result = get_user(mode, (unsigned long *) arg); | 485 | result = get_user(mode, (__u32 *) arg); |
490 | if (result) | 486 | if (result) |
491 | return result; | 487 | return result; |
492 | if (mode != LIRC_MODE_PULSE) | 488 | if (mode != LIRC_MODE_PULSE) |
493 | return -EINVAL; | 489 | return -EINVAL; |
494 | break; | 490 | break; |
495 | case LIRC_SET_REC_MODE: | 491 | case LIRC_SET_REC_MODE: |
496 | result = get_user(mode, (unsigned long *) arg); | 492 | result = get_user(mode, (__u32 *) arg); |
497 | if (result) | 493 | if (result) |
498 | return result; | 494 | return result; |
499 | if (mode != LIRC_MODE_MODE2) | 495 | if (mode != LIRC_MODE_MODE2) |
500 | return -ENOSYS; | 496 | return -ENOSYS; |
501 | break; | 497 | break; |
502 | case LIRC_SET_TRANSMITTER_MASK: | 498 | case LIRC_SET_TRANSMITTER_MASK: |
503 | result = get_user(ivalue, (unsigned int *) arg); | 499 | result = get_user(value, (__u32 *) arg); |
504 | if (result) | 500 | if (result) |
505 | return result; | 501 | return result; |
506 | if ((ivalue & LIRC_PARALLEL_TRANSMITTER_MASK) != ivalue) | 502 | if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value) |
507 | return LIRC_PARALLEL_MAX_TRANSMITTERS; | 503 | return LIRC_PARALLEL_MAX_TRANSMITTERS; |
508 | tx_mask = ivalue; | 504 | tx_mask = value; |
509 | break; | 505 | break; |
510 | default: | 506 | default: |
511 | return -ENOIOCTLCMD; | 507 | return -ENOIOCTLCMD; |
@@ -546,6 +542,9 @@ static const struct file_operations lirc_fops = { | |||
546 | .write = lirc_write, | 542 | .write = lirc_write, |
547 | .poll = lirc_poll, | 543 | .poll = lirc_poll, |
548 | .unlocked_ioctl = lirc_ioctl, | 544 | .unlocked_ioctl = lirc_ioctl, |
545 | #ifdef CONFIG_COMPAT | ||
546 | .compat_ioctl = lirc_ioctl, | ||
547 | #endif | ||
549 | .open = lirc_open, | 548 | .open = lirc_open, |
550 | .release = lirc_close | 549 | .release = lirc_close |
551 | }; | 550 | }; |
@@ -576,28 +575,6 @@ static struct lirc_driver driver = { | |||
576 | static int pf(void *handle); | 575 | static int pf(void *handle); |
577 | static void kf(void *handle); | 576 | static void kf(void *handle); |
578 | 577 | ||
579 | static struct timer_list poll_timer; | ||
580 | static void poll_state(unsigned long ignored); | ||
581 | |||
582 | static void poll_state(unsigned long ignored) | ||
583 | { | ||
584 | printk(KERN_NOTICE "%s: time\n", | ||
585 | LIRC_DRIVER_NAME); | ||
586 | del_timer(&poll_timer); | ||
587 | if (is_claimed) | ||
588 | return; | ||
589 | kf(NULL); | ||
590 | if (!is_claimed) { | ||
591 | printk(KERN_NOTICE "%s: could not claim port, giving up\n", | ||
592 | LIRC_DRIVER_NAME); | ||
593 | init_timer(&poll_timer); | ||
594 | poll_timer.expires = jiffies + HZ; | ||
595 | poll_timer.data = (unsigned long)current; | ||
596 | poll_timer.function = poll_state; | ||
597 | add_timer(&poll_timer); | ||
598 | } | ||
599 | } | ||
600 | |||
601 | static int pf(void *handle) | 578 | static int pf(void *handle) |
602 | { | 579 | { |
603 | parport_disable_irq(pport); | 580 | parport_disable_irq(pport); |
diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c index 8da38249261..971844bbee2 100644 --- a/drivers/staging/lirc/lirc_serial.c +++ b/drivers/staging/lirc/lirc_serial.c | |||
@@ -372,7 +372,7 @@ static unsigned long conv_us_to_clocks; | |||
372 | static int init_timing_params(unsigned int new_duty_cycle, | 372 | static int init_timing_params(unsigned int new_duty_cycle, |
373 | unsigned int new_freq) | 373 | unsigned int new_freq) |
374 | { | 374 | { |
375 | unsigned long long loops_per_sec, work; | 375 | __u64 loops_per_sec, work; |
376 | 376 | ||
377 | duty_cycle = new_duty_cycle; | 377 | duty_cycle = new_duty_cycle; |
378 | freq = new_freq; | 378 | freq = new_freq; |
@@ -987,8 +987,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, | |||
987 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 987 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
988 | { | 988 | { |
989 | int result; | 989 | int result; |
990 | unsigned long value; | 990 | __u32 value; |
991 | unsigned int ivalue; | ||
992 | 991 | ||
993 | switch (cmd) { | 992 | switch (cmd) { |
994 | case LIRC_GET_SEND_MODE: | 993 | case LIRC_GET_SEND_MODE: |
@@ -997,7 +996,7 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
997 | 996 | ||
998 | result = put_user(LIRC_SEND2MODE | 997 | result = put_user(LIRC_SEND2MODE |
999 | (hardware[type].features&LIRC_CAN_SEND_MASK), | 998 | (hardware[type].features&LIRC_CAN_SEND_MASK), |
1000 | (unsigned long *) arg); | 999 | (__u32 *) arg); |
1001 | if (result) | 1000 | if (result) |
1002 | return result; | 1001 | return result; |
1003 | break; | 1002 | break; |
@@ -1006,7 +1005,7 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
1006 | if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) | 1005 | if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) |
1007 | return -ENOIOCTLCMD; | 1006 | return -ENOIOCTLCMD; |
1008 | 1007 | ||
1009 | result = get_user(value, (unsigned long *) arg); | 1008 | result = get_user(value, (__u32 *) arg); |
1010 | if (result) | 1009 | if (result) |
1011 | return result; | 1010 | return result; |
1012 | /* only LIRC_MODE_PULSE supported */ | 1011 | /* only LIRC_MODE_PULSE supported */ |
@@ -1023,12 +1022,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
1023 | if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) | 1022 | if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) |
1024 | return -ENOIOCTLCMD; | 1023 | return -ENOIOCTLCMD; |
1025 | 1024 | ||
1026 | result = get_user(ivalue, (unsigned int *) arg); | 1025 | result = get_user(value, (__u32 *) arg); |
1027 | if (result) | 1026 | if (result) |
1028 | return result; | 1027 | return result; |
1029 | if (ivalue <= 0 || ivalue > 100) | 1028 | if (value <= 0 || value > 100) |
1030 | return -EINVAL; | 1029 | return -EINVAL; |
1031 | return init_timing_params(ivalue, freq); | 1030 | return init_timing_params(value, freq); |
1032 | break; | 1031 | break; |
1033 | 1032 | ||
1034 | case LIRC_SET_SEND_CARRIER: | 1033 | case LIRC_SET_SEND_CARRIER: |
@@ -1036,12 +1035,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
1036 | if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) | 1035 | if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) |
1037 | return -ENOIOCTLCMD; | 1036 | return -ENOIOCTLCMD; |
1038 | 1037 | ||
1039 | result = get_user(ivalue, (unsigned int *) arg); | 1038 | result = get_user(value, (__u32 *) arg); |
1040 | if (result) | 1039 | if (result) |
1041 | return result; | 1040 | return result; |
1042 | if (ivalue > 500000 || ivalue < 20000) | 1041 | if (value > 500000 || value < 20000) |
1043 | return -EINVAL; | 1042 | return -EINVAL; |
1044 | return init_timing_params(duty_cycle, ivalue); | 1043 | return init_timing_params(duty_cycle, value); |
1045 | break; | 1044 | break; |
1046 | 1045 | ||
1047 | default: | 1046 | default: |
@@ -1054,6 +1053,9 @@ static const struct file_operations lirc_fops = { | |||
1054 | .owner = THIS_MODULE, | 1053 | .owner = THIS_MODULE, |
1055 | .write = lirc_write, | 1054 | .write = lirc_write, |
1056 | .unlocked_ioctl = lirc_ioctl, | 1055 | .unlocked_ioctl = lirc_ioctl, |
1056 | #ifdef CONFIG_COMPAT | ||
1057 | .compat_ioctl = lirc_ioctl, | ||
1058 | #endif | ||
1057 | .read = lirc_dev_fop_read, | 1059 | .read = lirc_dev_fop_read, |
1058 | .poll = lirc_dev_fop_poll, | 1060 | .poll = lirc_dev_fop_poll, |
1059 | .open = lirc_dev_fop_open, | 1061 | .open = lirc_dev_fop_open, |
diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c index 2478871bd95..c553ab62623 100644 --- a/drivers/staging/lirc/lirc_sir.c +++ b/drivers/staging/lirc/lirc_sir.c | |||
@@ -336,9 +336,8 @@ static ssize_t lirc_write(struct file *file, const char *buf, size_t n, | |||
336 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 336 | static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
337 | { | 337 | { |
338 | int retval = 0; | 338 | int retval = 0; |
339 | unsigned long value = 0; | 339 | __u32 value = 0; |
340 | #ifdef LIRC_ON_SA1100 | 340 | #ifdef LIRC_ON_SA1100 |
341 | unsigned int ivalue; | ||
342 | 341 | ||
343 | if (cmd == LIRC_GET_FEATURES) | 342 | if (cmd == LIRC_GET_FEATURES) |
344 | value = LIRC_CAN_SEND_PULSE | | 343 | value = LIRC_CAN_SEND_PULSE | |
@@ -362,22 +361,22 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
362 | case LIRC_GET_FEATURES: | 361 | case LIRC_GET_FEATURES: |
363 | case LIRC_GET_SEND_MODE: | 362 | case LIRC_GET_SEND_MODE: |
364 | case LIRC_GET_REC_MODE: | 363 | case LIRC_GET_REC_MODE: |
365 | retval = put_user(value, (unsigned long *) arg); | 364 | retval = put_user(value, (__u32 *) arg); |
366 | break; | 365 | break; |
367 | 366 | ||
368 | case LIRC_SET_SEND_MODE: | 367 | case LIRC_SET_SEND_MODE: |
369 | case LIRC_SET_REC_MODE: | 368 | case LIRC_SET_REC_MODE: |
370 | retval = get_user(value, (unsigned long *) arg); | 369 | retval = get_user(value, (__u32 *) arg); |
371 | break; | 370 | break; |
372 | #ifdef LIRC_ON_SA1100 | 371 | #ifdef LIRC_ON_SA1100 |
373 | case LIRC_SET_SEND_DUTY_CYCLE: | 372 | case LIRC_SET_SEND_DUTY_CYCLE: |
374 | retval = get_user(ivalue, (unsigned int *) arg); | 373 | retval = get_user(value, (__u32 *) arg); |
375 | if (retval) | 374 | if (retval) |
376 | return retval; | 375 | return retval; |
377 | if (ivalue <= 0 || ivalue > 100) | 376 | if (value <= 0 || value > 100) |
378 | return -EINVAL; | 377 | return -EINVAL; |
379 | /* (ivalue/100)*(1000000/freq) */ | 378 | /* (value/100)*(1000000/freq) */ |
380 | duty_cycle = ivalue; | 379 | duty_cycle = value; |
381 | pulse_width = (unsigned long) duty_cycle*10000/freq; | 380 | pulse_width = (unsigned long) duty_cycle*10000/freq; |
382 | space_width = (unsigned long) 1000000L/freq-pulse_width; | 381 | space_width = (unsigned long) 1000000L/freq-pulse_width; |
383 | if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) | 382 | if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) |
@@ -386,12 +385,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
386 | space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; | 385 | space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; |
387 | break; | 386 | break; |
388 | case LIRC_SET_SEND_CARRIER: | 387 | case LIRC_SET_SEND_CARRIER: |
389 | retval = get_user(ivalue, (unsigned int *) arg); | 388 | retval = get_user(value, (__u32 *) arg); |
390 | if (retval) | 389 | if (retval) |
391 | return retval; | 390 | return retval; |
392 | if (ivalue > 500000 || ivalue < 20000) | 391 | if (value > 500000 || value < 20000) |
393 | return -EINVAL; | 392 | return -EINVAL; |
394 | freq = ivalue; | 393 | freq = value; |
395 | pulse_width = (unsigned long) duty_cycle*10000/freq; | 394 | pulse_width = (unsigned long) duty_cycle*10000/freq; |
396 | space_width = (unsigned long) 1000000L/freq-pulse_width; | 395 | space_width = (unsigned long) 1000000L/freq-pulse_width; |
397 | if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) | 396 | if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) |
@@ -457,6 +456,9 @@ static const struct file_operations lirc_fops = { | |||
457 | .write = lirc_write, | 456 | .write = lirc_write, |
458 | .poll = lirc_poll, | 457 | .poll = lirc_poll, |
459 | .unlocked_ioctl = lirc_ioctl, | 458 | .unlocked_ioctl = lirc_ioctl, |
459 | #ifdef CONFIG_COMPAT | ||
460 | .compat_ioctl = lirc_ioctl, | ||
461 | #endif | ||
460 | .open = lirc_dev_fop_open, | 462 | .open = lirc_dev_fop_open, |
461 | .release = lirc_dev_fop_close, | 463 | .release = lirc_dev_fop_close, |
462 | .llseek = no_llseek, | 464 | .llseek = no_llseek, |
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c index 100caab1045..d9206449852 100644 --- a/drivers/staging/lirc/lirc_zilog.c +++ b/drivers/staging/lirc/lirc_zilog.c | |||
@@ -1139,6 +1139,9 @@ static const struct file_operations lirc_fops = { | |||
1139 | .write = write, | 1139 | .write = write, |
1140 | .poll = poll, | 1140 | .poll = poll, |
1141 | .unlocked_ioctl = ioctl, | 1141 | .unlocked_ioctl = ioctl, |
1142 | #ifdef CONFIG_COMPAT | ||
1143 | .compat_ioctl = ioctl, | ||
1144 | #endif | ||
1142 | .open = open, | 1145 | .open = open, |
1143 | .release = close | 1146 | .release = close |
1144 | }; | 1147 | }; |
diff --git a/drivers/staging/stradis/Kconfig b/drivers/staging/stradis/Kconfig new file mode 100644 index 00000000000..92e89114189 --- /dev/null +++ b/drivers/staging/stradis/Kconfig | |||
@@ -0,0 +1,7 @@ | |||
1 | config VIDEO_STRADIS | ||
2 | tristate "Stradis 4:2:2 MPEG-2 video driver (DEPRECATED)" | ||
3 | depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS | ||
4 | help | ||
5 | Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video | ||
6 | driver for PCI. There is a product page at | ||
7 | <http://www.stradis.com/>. | ||
diff --git a/drivers/staging/stradis/Makefile b/drivers/staging/stradis/Makefile new file mode 100644 index 00000000000..0f1feab59e3 --- /dev/null +++ b/drivers/staging/stradis/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_VIDEO_STRADIS) += stradis.o | ||
2 | |||
3 | EXTRA_CFLAGS += -Idrivers/media/video | ||
diff --git a/drivers/staging/stradis/TODO b/drivers/staging/stradis/TODO new file mode 100644 index 00000000000..f48150fe2fa --- /dev/null +++ b/drivers/staging/stradis/TODO | |||
@@ -0,0 +1,6 @@ | |||
1 | This is an obsolete driver for ancient stradis hardware. | ||
2 | We couldn't find anyone with this hardware in order to port it to use V4L2. | ||
3 | |||
4 | If nobody take care on it, the driver will be removed for 2.6.38. | ||
5 | |||
6 | Please send patches to linux-media@vger.kernel.org | ||
diff --git a/drivers/media/video/stradis.c b/drivers/staging/stradis/stradis.c index a057824e7eb..a057824e7eb 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/staging/stradis/stradis.c | |||
diff --git a/drivers/staging/tm6000/TODO b/drivers/staging/tm6000/TODO new file mode 100644 index 00000000000..34780fc17b1 --- /dev/null +++ b/drivers/staging/tm6000/TODO | |||
@@ -0,0 +1,6 @@ | |||
1 | There a few things to do before putting this driver in production: | ||
2 | - CodingStyle; | ||
3 | - Fix audio; | ||
4 | - Fix some panic/OOPS conditions. | ||
5 | |||
6 | Please send patches to linux-media@vger.kernel.org | ||
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c index 087137d9164..e379e3ec444 100644 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ b/drivers/staging/tm6000/tm6000-alsa.c | |||
@@ -160,15 +160,15 @@ static struct snd_pcm_hardware snd_tm6000_digital_hw = { | |||
160 | SNDRV_PCM_INFO_MMAP_VALID, | 160 | SNDRV_PCM_INFO_MMAP_VALID, |
161 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 161 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
162 | 162 | ||
163 | .rates = SNDRV_PCM_RATE_48000, | 163 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
164 | .rate_min = 48000, | 164 | .rate_min = 48000, |
165 | .rate_max = 48000, | 165 | .rate_max = 48000, |
166 | .channels_min = 2, | 166 | .channels_min = 2, |
167 | .channels_max = 2, | 167 | .channels_max = 2, |
168 | .period_bytes_min = 62720, | 168 | .period_bytes_min = 64, |
169 | .period_bytes_max = 62720, | 169 | .period_bytes_max = 12544, |
170 | .periods_min = 1, | 170 | .periods_min = 1, |
171 | .periods_max = 1024, | 171 | .periods_max = 98, |
172 | .buffer_bytes_max = 62720 * 8, | 172 | .buffer_bytes_max = 62720 * 8, |
173 | }; | 173 | }; |
174 | 174 | ||
@@ -201,6 +201,14 @@ _error: | |||
201 | */ | 201 | */ |
202 | static int snd_tm6000_close(struct snd_pcm_substream *substream) | 202 | static int snd_tm6000_close(struct snd_pcm_substream *substream) |
203 | { | 203 | { |
204 | struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); | ||
205 | struct tm6000_core *core = chip->core; | ||
206 | |||
207 | if (atomic_read(&core->stream_started) > 0) { | ||
208 | atomic_set(&core->stream_started, 0); | ||
209 | schedule_work(&core->wq_trigger); | ||
210 | } | ||
211 | |||
204 | return 0; | 212 | return 0; |
205 | } | 213 | } |
206 | 214 | ||
@@ -211,38 +219,67 @@ static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size) | |||
211 | struct snd_pcm_runtime *runtime; | 219 | struct snd_pcm_runtime *runtime; |
212 | int period_elapsed = 0; | 220 | int period_elapsed = 0; |
213 | unsigned int stride, buf_pos; | 221 | unsigned int stride, buf_pos; |
222 | int length; | ||
223 | |||
224 | if (atomic_read(&core->stream_started) == 0) | ||
225 | return 0; | ||
214 | 226 | ||
215 | if (!size || !substream) | 227 | if (!size || !substream) { |
228 | dprintk(1, "substream was NULL\n"); | ||
216 | return -EINVAL; | 229 | return -EINVAL; |
230 | } | ||
217 | 231 | ||
218 | runtime = substream->runtime; | 232 | runtime = substream->runtime; |
219 | if (!runtime || !runtime->dma_area) | 233 | if (!runtime || !runtime->dma_area) { |
234 | dprintk(1, "runtime was NULL\n"); | ||
220 | return -EINVAL; | 235 | return -EINVAL; |
236 | } | ||
221 | 237 | ||
222 | buf_pos = chip->buf_pos; | 238 | buf_pos = chip->buf_pos; |
223 | stride = runtime->frame_bits >> 3; | 239 | stride = runtime->frame_bits >> 3; |
224 | 240 | ||
241 | if (stride == 0) { | ||
242 | dprintk(1, "stride is zero\n"); | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | |||
246 | length = size / stride; | ||
247 | if (length == 0) { | ||
248 | dprintk(1, "%s: length was zero\n", __func__); | ||
249 | return -EINVAL; | ||
250 | } | ||
251 | |||
225 | dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size, | 252 | dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size, |
226 | runtime->dma_area, buf_pos, | 253 | runtime->dma_area, buf_pos, |
227 | (unsigned int)runtime->buffer_size, stride); | 254 | (unsigned int)runtime->buffer_size, stride); |
228 | 255 | ||
229 | if (buf_pos + size >= runtime->buffer_size * stride) { | 256 | if (buf_pos + length >= runtime->buffer_size) { |
230 | unsigned int cnt = runtime->buffer_size * stride - buf_pos; | 257 | unsigned int cnt = runtime->buffer_size - buf_pos; |
231 | memcpy(runtime->dma_area + buf_pos, buf, cnt); | 258 | memcpy(runtime->dma_area + buf_pos * stride, buf, cnt * stride); |
232 | memcpy(runtime->dma_area, buf + cnt, size - cnt); | 259 | memcpy(runtime->dma_area, buf + cnt * stride, |
260 | length * stride - cnt * stride); | ||
233 | } else | 261 | } else |
234 | memcpy(runtime->dma_area + buf_pos, buf, size); | 262 | memcpy(runtime->dma_area + buf_pos * stride, buf, |
263 | length * stride); | ||
235 | 264 | ||
236 | chip->buf_pos += size; | 265 | #ifndef NO_PCM_LOCK |
237 | if (chip->buf_pos >= runtime->buffer_size * stride) | 266 | snd_pcm_stream_lock(substream); |
238 | chip->buf_pos -= runtime->buffer_size * stride; | 267 | #endif |
239 | 268 | ||
240 | chip->period_pos += size; | 269 | chip->buf_pos += length; |
270 | if (chip->buf_pos >= runtime->buffer_size) | ||
271 | chip->buf_pos -= runtime->buffer_size; | ||
272 | |||
273 | chip->period_pos += length; | ||
241 | if (chip->period_pos >= runtime->period_size) { | 274 | if (chip->period_pos >= runtime->period_size) { |
242 | chip->period_pos -= runtime->period_size; | 275 | chip->period_pos -= runtime->period_size; |
243 | period_elapsed = 1; | 276 | period_elapsed = 1; |
244 | } | 277 | } |
245 | 278 | ||
279 | #ifndef NO_PCM_LOCK | ||
280 | snd_pcm_stream_unlock(substream); | ||
281 | #endif | ||
282 | |||
246 | if (period_elapsed) | 283 | if (period_elapsed) |
247 | snd_pcm_period_elapsed(substream); | 284 | snd_pcm_period_elapsed(substream); |
248 | 285 | ||
@@ -272,8 +309,12 @@ static int snd_tm6000_hw_params(struct snd_pcm_substream *substream, | |||
272 | static int snd_tm6000_hw_free(struct snd_pcm_substream *substream) | 309 | static int snd_tm6000_hw_free(struct snd_pcm_substream *substream) |
273 | { | 310 | { |
274 | struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); | 311 | struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); |
312 | struct tm6000_core *core = chip->core; | ||
275 | 313 | ||
276 | _tm6000_stop_audio_dma(chip); | 314 | if (atomic_read(&core->stream_started) > 0) { |
315 | atomic_set(&core->stream_started, 0); | ||
316 | schedule_work(&core->wq_trigger); | ||
317 | } | ||
277 | 318 | ||
278 | return 0; | 319 | return 0; |
279 | } | 320 | } |
@@ -295,30 +336,42 @@ static int snd_tm6000_prepare(struct snd_pcm_substream *substream) | |||
295 | /* | 336 | /* |
296 | * trigger callback | 337 | * trigger callback |
297 | */ | 338 | */ |
339 | static void audio_trigger(struct work_struct *work) | ||
340 | { | ||
341 | struct tm6000_core *core = container_of(work, struct tm6000_core, | ||
342 | wq_trigger); | ||
343 | struct snd_tm6000_card *chip = core->adev; | ||
344 | |||
345 | if (atomic_read(&core->stream_started)) { | ||
346 | dprintk(1, "starting capture"); | ||
347 | _tm6000_start_audio_dma(chip); | ||
348 | } else { | ||
349 | dprintk(1, "stopping capture"); | ||
350 | _tm6000_stop_audio_dma(chip); | ||
351 | } | ||
352 | } | ||
353 | |||
298 | static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd) | 354 | static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd) |
299 | { | 355 | { |
300 | struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); | 356 | struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); |
301 | int err; | 357 | struct tm6000_core *core = chip->core; |
302 | 358 | int err = 0; | |
303 | spin_lock(&chip->reg_lock); | ||
304 | 359 | ||
305 | switch (cmd) { | 360 | switch (cmd) { |
306 | case SNDRV_PCM_TRIGGER_START: | 361 | case SNDRV_PCM_TRIGGER_START: |
307 | err = _tm6000_start_audio_dma(chip); | 362 | atomic_set(&core->stream_started, 1); |
308 | break; | 363 | break; |
309 | case SNDRV_PCM_TRIGGER_STOP: | 364 | case SNDRV_PCM_TRIGGER_STOP: |
310 | err = _tm6000_stop_audio_dma(chip); | 365 | atomic_set(&core->stream_started, 0); |
311 | break; | 366 | break; |
312 | default: | 367 | default: |
313 | err = -EINVAL; | 368 | err = -EINVAL; |
314 | break; | 369 | break; |
315 | } | 370 | } |
316 | 371 | schedule_work(&core->wq_trigger); | |
317 | spin_unlock(&chip->reg_lock); | ||
318 | 372 | ||
319 | return err; | 373 | return err; |
320 | } | 374 | } |
321 | |||
322 | /* | 375 | /* |
323 | * pointer callback | 376 | * pointer callback |
324 | */ | 377 | */ |
@@ -411,6 +464,7 @@ int tm6000_audio_init(struct tm6000_core *dev) | |||
411 | 464 | ||
412 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops); | 465 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops); |
413 | 466 | ||
467 | INIT_WORK(&dev->wq_trigger, audio_trigger); | ||
414 | rc = snd_card_register(card); | 468 | rc = snd_card_register(card); |
415 | if (rc < 0) | 469 | if (rc < 0) |
416 | goto error; | 470 | goto error; |
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 9d091c34991..664e6038090 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c | |||
@@ -1,20 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 8 | * the Free Software Foundation version 2 |
9 | 9 | * | |
10 | This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | 14 | * | |
15 | You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
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 | #include <linux/init.h> | 20 | #include <linux/init.h> |
@@ -349,7 +349,7 @@ int tm6000_xc5000_callback(void *ptr, int component, int command, int arg) | |||
349 | dev->gpio.tuner_reset, 0x01); | 349 | dev->gpio.tuner_reset, 0x01); |
350 | break; | 350 | break; |
351 | } | 351 | } |
352 | return (rc); | 352 | return rc; |
353 | } | 353 | } |
354 | EXPORT_SYMBOL_GPL(tm6000_xc5000_callback); | 354 | EXPORT_SYMBOL_GPL(tm6000_xc5000_callback); |
355 | 355 | ||
@@ -545,7 +545,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev) | |||
545 | 545 | ||
546 | /* Load tuner module */ | 546 | /* Load tuner module */ |
547 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 547 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
548 | "tuner", "tuner", dev->tuner_addr, NULL); | 548 | NULL, "tuner", dev->tuner_addr, NULL); |
549 | 549 | ||
550 | memset(&tun_setup, 0, sizeof(tun_setup)); | 550 | memset(&tun_setup, 0, sizeof(tun_setup)); |
551 | tun_setup.type = dev->tuner_type; | 551 | tun_setup.type = dev->tuner_type; |
@@ -683,7 +683,7 @@ static int tm6000_init_dev(struct tm6000_core *dev) | |||
683 | 683 | ||
684 | if (dev->caps.has_tda9874) | 684 | if (dev->caps.has_tda9874) |
685 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 685 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
686 | "tvaudio", "tvaudio", I2C_ADDR_TDA9874, NULL); | 686 | NULL, "tvaudio", I2C_ADDR_TDA9874, NULL); |
687 | 687 | ||
688 | /* register and initialize V4L2 */ | 688 | /* register and initialize V4L2 */ |
689 | rc = tm6000_v4l2_register(dev); | 689 | rc = tm6000_v4l2_register(dev); |
@@ -909,8 +909,6 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) | |||
909 | 909 | ||
910 | printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name); | 910 | printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name); |
911 | 911 | ||
912 | mutex_lock(&dev->lock); | ||
913 | |||
914 | tm6000_ir_fini(dev); | 912 | tm6000_ir_fini(dev); |
915 | 913 | ||
916 | if (dev->gpio.power_led) { | 914 | if (dev->gpio.power_led) { |
@@ -945,7 +943,6 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) | |||
945 | tm6000_close_extension(dev); | 943 | tm6000_close_extension(dev); |
946 | tm6000_remove_from_devlist(dev); | 944 | tm6000_remove_from_devlist(dev); |
947 | 945 | ||
948 | mutex_unlock(&dev->lock); | ||
949 | kfree(dev); | 946 | kfree(dev); |
950 | } | 947 | } |
951 | 948 | ||
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index cded411d8bb..df3f187959b 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c | |||
@@ -1,23 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
7 | - DVB-T support | 7 | * - DVB-T support |
8 | 8 | * | |
9 | This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation version 2 | 11 | * the Free Software Foundation version 2 |
12 | 12 | * | |
13 | This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | 17 | * | |
18 | You should have received a copy of the GNU General Public License | 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 | 19 | * along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -30,14 +30,13 @@ | |||
30 | #include <media/v4l2-common.h> | 30 | #include <media/v4l2-common.h> |
31 | #include <media/tuner.h> | 31 | #include <media/tuner.h> |
32 | 32 | ||
33 | #define USB_TIMEOUT 5*HZ /* ms */ | 33 | #define USB_TIMEOUT (5 * HZ) /* ms */ |
34 | 34 | ||
35 | int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req, | 35 | int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req, |
36 | u16 value, u16 index, u8 *buf, u16 len) | 36 | u16 value, u16 index, u8 *buf, u16 len) |
37 | { | 37 | { |
38 | int ret, i; | 38 | int ret, i; |
39 | unsigned int pipe; | 39 | unsigned int pipe; |
40 | static int ini = 0, last = 0, n = 0; | ||
41 | u8 *data = NULL; | 40 | u8 *data = NULL; |
42 | 41 | ||
43 | if (len) | 42 | if (len) |
@@ -52,19 +51,12 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req, | |||
52 | } | 51 | } |
53 | 52 | ||
54 | if (tm6000_debug & V4L2_DEBUG_I2C) { | 53 | if (tm6000_debug & V4L2_DEBUG_I2C) { |
55 | if (!ini) | 54 | printk("(dev %p, pipe %08x): ", dev->udev, pipe); |
56 | last = ini = jiffies; | ||
57 | |||
58 | printk("%06i (dev %p, pipe %08x): ", n, dev->udev, pipe); | ||
59 | 55 | ||
60 | printk("%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ", | 56 | printk("%s: %02x %02x %02x %02x %02x %02x %02x %02x ", |
61 | (req_type & USB_DIR_IN) ? " IN" : "OUT", | 57 | (req_type & USB_DIR_IN) ? " IN" : "OUT", |
62 | jiffies_to_msecs(jiffies-last), | ||
63 | jiffies_to_msecs(jiffies-ini), | ||
64 | req_type, req, value&0xff, value>>8, index&0xff, | 58 | req_type, req, value&0xff, value>>8, index&0xff, |
65 | index>>8, len&0xff, len>>8); | 59 | index>>8, len&0xff, len>>8); |
66 | last = jiffies; | ||
67 | n++; | ||
68 | 60 | ||
69 | if (!(req_type & USB_DIR_IN)) { | 61 | if (!(req_type & USB_DIR_IN)) { |
70 | printk(">>> "); | 62 | printk(">>> "); |
@@ -186,21 +178,17 @@ void tm6000_set_fourcc_format(struct tm6000_core *dev) | |||
186 | } | 178 | } |
187 | } | 179 | } |
188 | 180 | ||
189 | int tm6000_init_analog_mode(struct tm6000_core *dev) | 181 | static void tm6000_set_vbi(struct tm6000_core *dev) |
190 | { | 182 | { |
191 | if (dev->dev_type == TM6010) { | 183 | /* |
192 | int val; | 184 | * FIXME: |
185 | * VBI lines and start/end are different between 60Hz and 50Hz | ||
186 | * So, it is very likely that we need to change the config to | ||
187 | * something that takes it into account, doing something different | ||
188 | * if (dev->norm & V4L2_STD_525_60) | ||
189 | */ | ||
193 | 190 | ||
194 | /* Enable video */ | 191 | if (dev->dev_type == TM6010) { |
195 | val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0); | ||
196 | val |= 0x60; | ||
197 | tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val); | ||
198 | val = tm6000_get_reg(dev, | ||
199 | TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0); | ||
200 | val &= ~0x40; | ||
201 | tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val); | ||
202 | |||
203 | /* Init teletext */ | ||
204 | tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); | 192 | tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); |
205 | tm6000_set_reg(dev, TM6010_REQ07_R41_TELETEXT_VBI_CODE1, 0x27); | 193 | tm6000_set_reg(dev, TM6010_REQ07_R41_TELETEXT_VBI_CODE1, 0x27); |
206 | tm6000_set_reg(dev, TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55); | 194 | tm6000_set_reg(dev, TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55); |
@@ -249,44 +237,26 @@ int tm6000_init_analog_mode(struct tm6000_core *dev) | |||
249 | tm6000_set_reg(dev, TM6010_REQ07_R5B_VBI_TELETEXT_DTO0, 0x4c); | 237 | tm6000_set_reg(dev, TM6010_REQ07_R5B_VBI_TELETEXT_DTO0, 0x4c); |
250 | tm6000_set_reg(dev, TM6010_REQ07_R40_TELETEXT_VBI_CODE0, 0x01); | 238 | tm6000_set_reg(dev, TM6010_REQ07_R40_TELETEXT_VBI_CODE0, 0x01); |
251 | tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); | 239 | tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); |
240 | } | ||
241 | } | ||
252 | 242 | ||
243 | int tm6000_init_analog_mode(struct tm6000_core *dev) | ||
244 | { | ||
245 | struct v4l2_frequency f; | ||
246 | |||
247 | if (dev->dev_type == TM6010) { | ||
248 | int val; | ||
249 | |||
250 | /* Enable video */ | ||
251 | val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0); | ||
252 | val |= 0x60; | ||
253 | tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val); | ||
254 | val = tm6000_get_reg(dev, | ||
255 | TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0); | ||
256 | val &= ~0x40; | ||
257 | tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val); | ||
253 | 258 | ||
254 | /* Init audio */ | 259 | tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc); |
255 | tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); | ||
256 | tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04); | ||
257 | tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00); | ||
258 | tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0); | ||
259 | tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x05); | ||
260 | tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x06); | ||
261 | tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00); | ||
262 | tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00); | ||
263 | tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08); | ||
264 | tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91); | ||
265 | tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20); | ||
266 | tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12); | ||
267 | tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20); | ||
268 | tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0); | ||
269 | tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80); | ||
270 | tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0); | ||
271 | tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80); | ||
272 | tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12); | ||
273 | tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe); | ||
274 | tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20); | ||
275 | tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14); | ||
276 | tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe); | ||
277 | tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01); | ||
278 | tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0); | ||
279 | tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32); | ||
280 | tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64); | ||
281 | tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20); | ||
282 | tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00); | ||
283 | tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00); | ||
284 | tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); | ||
285 | tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00); | ||
286 | tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00); | ||
287 | tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3); | ||
288 | tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00); | ||
289 | tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); | ||
290 | 260 | ||
291 | } else { | 261 | } else { |
292 | /* Enables soft reset */ | 262 | /* Enables soft reset */ |
@@ -325,15 +295,22 @@ int tm6000_init_analog_mode(struct tm6000_core *dev) | |||
325 | 295 | ||
326 | /* Tuner firmware can now be loaded */ | 296 | /* Tuner firmware can now be loaded */ |
327 | 297 | ||
328 | /*FIXME: Hack!!! */ | 298 | /* |
329 | struct v4l2_frequency f; | 299 | * FIXME: This is a hack! xc3028 "sleeps" when no channel is detected |
330 | mutex_lock(&dev->lock); | 300 | * for more than a few seconds. Not sure why, as this behavior does |
301 | * not happen on other devices with xc3028. So, I suspect that it | ||
302 | * is yet another bug at tm6000. After start sleeping, decoding | ||
303 | * doesn't start automatically. Instead, it requires some | ||
304 | * I2C commands to wake it up. As we want to have image at the | ||
305 | * beginning, we needed to add this hack. The better would be to | ||
306 | * discover some way to make tm6000 to wake up without this hack. | ||
307 | */ | ||
331 | f.frequency = dev->freq; | 308 | f.frequency = dev->freq; |
332 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 309 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); |
333 | mutex_unlock(&dev->lock); | ||
334 | 310 | ||
335 | msleep(100); | 311 | msleep(100); |
336 | tm6000_set_standard(dev, &dev->norm); | 312 | tm6000_set_standard(dev, &dev->norm); |
313 | tm6000_set_vbi(dev); | ||
337 | tm6000_set_audio_bitrate(dev, 48000); | 314 | tm6000_set_audio_bitrate(dev, 48000); |
338 | 315 | ||
339 | /* switch dvb led off */ | 316 | /* switch dvb led off */ |
@@ -361,7 +338,6 @@ int tm6000_init_digital_mode(struct tm6000_core *dev) | |||
361 | tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28); | 338 | tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28); |
362 | tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc); | 339 | tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc); |
363 | tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff); | 340 | tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff); |
364 | tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe); | ||
365 | tm6000_read_write_usb(dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2); | 341 | tm6000_read_write_usb(dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2); |
366 | printk(KERN_INFO"buf %#x %#x\n", buf[0], buf[1]); | 342 | printk(KERN_INFO"buf %#x %#x\n", buf[0], buf[1]); |
367 | } else { | 343 | } else { |
@@ -660,7 +636,6 @@ void tm6000_add_into_devlist(struct tm6000_core *dev) | |||
660 | */ | 636 | */ |
661 | 637 | ||
662 | static LIST_HEAD(tm6000_extension_devlist); | 638 | static LIST_HEAD(tm6000_extension_devlist); |
663 | static DEFINE_MUTEX(tm6000_extension_devlist_lock); | ||
664 | 639 | ||
665 | int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type, | 640 | int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type, |
666 | char *buf, int size) | 641 | char *buf, int size) |
@@ -684,14 +659,12 @@ int tm6000_register_extension(struct tm6000_ops *ops) | |||
684 | struct tm6000_core *dev = NULL; | 659 | struct tm6000_core *dev = NULL; |
685 | 660 | ||
686 | mutex_lock(&tm6000_devlist_mutex); | 661 | mutex_lock(&tm6000_devlist_mutex); |
687 | mutex_lock(&tm6000_extension_devlist_lock); | ||
688 | list_add_tail(&ops->next, &tm6000_extension_devlist); | 662 | list_add_tail(&ops->next, &tm6000_extension_devlist); |
689 | list_for_each_entry(dev, &tm6000_devlist, devlist) { | 663 | list_for_each_entry(dev, &tm6000_devlist, devlist) { |
690 | ops->init(dev); | 664 | ops->init(dev); |
691 | printk(KERN_INFO "%s: Initialized (%s) extension\n", | 665 | printk(KERN_INFO "%s: Initialized (%s) extension\n", |
692 | dev->name, ops->name); | 666 | dev->name, ops->name); |
693 | } | 667 | } |
694 | mutex_unlock(&tm6000_extension_devlist_lock); | ||
695 | mutex_unlock(&tm6000_devlist_mutex); | 668 | mutex_unlock(&tm6000_devlist_mutex); |
696 | return 0; | 669 | return 0; |
697 | } | 670 | } |
@@ -707,10 +680,8 @@ void tm6000_unregister_extension(struct tm6000_ops *ops) | |||
707 | ops->fini(dev); | 680 | ops->fini(dev); |
708 | } | 681 | } |
709 | 682 | ||
710 | mutex_lock(&tm6000_extension_devlist_lock); | ||
711 | printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name); | 683 | printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name); |
712 | list_del(&ops->next); | 684 | list_del(&ops->next); |
713 | mutex_unlock(&tm6000_extension_devlist_lock); | ||
714 | mutex_unlock(&tm6000_devlist_mutex); | 685 | mutex_unlock(&tm6000_devlist_mutex); |
715 | } | 686 | } |
716 | EXPORT_SYMBOL(tm6000_unregister_extension); | 687 | EXPORT_SYMBOL(tm6000_unregister_extension); |
@@ -719,26 +690,26 @@ void tm6000_init_extension(struct tm6000_core *dev) | |||
719 | { | 690 | { |
720 | struct tm6000_ops *ops = NULL; | 691 | struct tm6000_ops *ops = NULL; |
721 | 692 | ||
722 | mutex_lock(&tm6000_extension_devlist_lock); | 693 | mutex_lock(&tm6000_devlist_mutex); |
723 | if (!list_empty(&tm6000_extension_devlist)) { | 694 | if (!list_empty(&tm6000_extension_devlist)) { |
724 | list_for_each_entry(ops, &tm6000_extension_devlist, next) { | 695 | list_for_each_entry(ops, &tm6000_extension_devlist, next) { |
725 | if (ops->init) | 696 | if (ops->init) |
726 | ops->init(dev); | 697 | ops->init(dev); |
727 | } | 698 | } |
728 | } | 699 | } |
729 | mutex_unlock(&tm6000_extension_devlist_lock); | 700 | mutex_unlock(&tm6000_devlist_mutex); |
730 | } | 701 | } |
731 | 702 | ||
732 | void tm6000_close_extension(struct tm6000_core *dev) | 703 | void tm6000_close_extension(struct tm6000_core *dev) |
733 | { | 704 | { |
734 | struct tm6000_ops *ops = NULL; | 705 | struct tm6000_ops *ops = NULL; |
735 | 706 | ||
736 | mutex_lock(&tm6000_extension_devlist_lock); | 707 | mutex_lock(&tm6000_devlist_mutex); |
737 | if (!list_empty(&tm6000_extension_devlist)) { | 708 | if (!list_empty(&tm6000_extension_devlist)) { |
738 | list_for_each_entry(ops, &tm6000_extension_devlist, next) { | 709 | list_for_each_entry(ops, &tm6000_extension_devlist, next) { |
739 | if (ops->fini) | 710 | if (ops->fini) |
740 | ops->fini(dev); | 711 | ops->fini(dev); |
741 | } | 712 | } |
742 | } | 713 | } |
743 | mutex_unlock(&tm6000_extension_devlist_lock); | 714 | mutex_lock(&tm6000_devlist_mutex); |
744 | } | 715 | } |
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c index f501edccf9c..ff04c89e45a 100644 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ b/drivers/staging/tm6000/tm6000-dvb.c | |||
@@ -1,20 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 4 | * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 8 | * the Free Software Foundation version 2 |
9 | 9 | * | |
10 | This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | 14 | * | |
15 | You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
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 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c index 79bc67f0311..3e46866dd27 100644 --- a/drivers/staging/tm6000/tm6000-i2c.c +++ b/drivers/staging/tm6000/tm6000-i2c.c | |||
@@ -1,23 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
7 | - Fix SMBus Read Byte command | 7 | * - Fix SMBus Read Byte command |
8 | 8 | * | |
9 | This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation version 2 | 11 | * the Free Software Foundation version 2 |
12 | 12 | * | |
13 | This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | 17 | * | |
18 | You should have received a copy of the GNU General Public License | 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 | 19 | * along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -32,11 +32,9 @@ | |||
32 | #include "tuner-xc2028.h" | 32 | #include "tuner-xc2028.h" |
33 | 33 | ||
34 | 34 | ||
35 | /*FIXME: Hack to avoid needing to patch i2c-id.h */ | ||
36 | #define I2C_HW_B_TM6000 I2C_HW_B_EM28XX | ||
37 | /* ----------------------------------------------------------- */ | 35 | /* ----------------------------------------------------------- */ |
38 | 36 | ||
39 | static unsigned int i2c_debug = 0; | 37 | static unsigned int i2c_debug; |
40 | module_param(i2c_debug, int, 0644); | 38 | module_param(i2c_debug, int, 0644); |
41 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | 39 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); |
42 | 40 | ||
@@ -324,7 +322,6 @@ static struct i2c_adapter tm6000_adap_template = { | |||
324 | .owner = THIS_MODULE, | 322 | .owner = THIS_MODULE, |
325 | .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, | 323 | .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, |
326 | .name = "tm6000", | 324 | .name = "tm6000", |
327 | .id = I2C_HW_B_TM6000, | ||
328 | .algo = &tm6000_algo, | 325 | .algo = &tm6000_algo, |
329 | }; | 326 | }; |
330 | 327 | ||
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index 54f7667cc70..6022caaa739 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c | |||
@@ -1,20 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de> | 4 | * Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de> |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 8 | * the Free Software Foundation version 2 |
9 | 9 | * | |
10 | This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | 14 | * | |
15 | You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
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 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug message [IR]"); | |||
36 | 36 | ||
37 | static unsigned int enable_ir = 1; | 37 | static unsigned int enable_ir = 1; |
38 | module_param(enable_ir, int, 0644); | 38 | module_param(enable_ir, int, 0644); |
39 | MODULE_PARM_DESC(enable_ir, "enable ir (default is enable"); | 39 | MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)"); |
40 | 40 | ||
41 | #undef dprintk | 41 | #undef dprintk |
42 | 42 | ||
diff --git a/drivers/staging/tm6000/tm6000-regs.h b/drivers/staging/tm6000/tm6000-regs.h index 1c5289c971f..1f0ced8fa20 100644 --- a/drivers/staging/tm6000/tm6000-regs.h +++ b/drivers/staging/tm6000/tm6000-regs.h | |||
@@ -1,20 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 8 | * the Free Software Foundation version 2 |
9 | 9 | * | |
10 | This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | 14 | * | |
15 | You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
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 | /* | 20 | /* |
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c index 6bf4a73b320..cc7b8664fc2 100644 --- a/drivers/staging/tm6000/tm6000-stds.c +++ b/drivers/staging/tm6000/tm6000-stds.c | |||
@@ -1,20 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@redhat.com> | 4 | * Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@redhat.com> |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 8 | * the Free Software Foundation version 2 |
9 | 9 | * | |
10 | This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | 14 | * | |
15 | You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
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 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -28,21 +28,37 @@ struct tm6000_reg_settings { | |||
28 | unsigned char value; | 28 | unsigned char value; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | enum tm6000_audio_std { | ||
32 | BG_NICAM, | ||
33 | BTSC, | ||
34 | BG_A2, | ||
35 | DK_NICAM, | ||
36 | EIAJ, | ||
37 | FM_RADIO, | ||
38 | I_NICAM, | ||
39 | KOREA_A2, | ||
40 | L_NICAM, | ||
41 | }; | ||
42 | |||
31 | struct tm6000_std_tv_settings { | 43 | struct tm6000_std_tv_settings { |
32 | v4l2_std_id id; | 44 | v4l2_std_id id; |
45 | enum tm6000_audio_std audio_default_std; | ||
46 | |||
33 | struct tm6000_reg_settings sif[12]; | 47 | struct tm6000_reg_settings sif[12]; |
34 | struct tm6000_reg_settings nosif[12]; | 48 | struct tm6000_reg_settings nosif[12]; |
35 | struct tm6000_reg_settings common[25]; | 49 | struct tm6000_reg_settings common[26]; |
36 | }; | 50 | }; |
37 | 51 | ||
38 | struct tm6000_std_settings { | 52 | struct tm6000_std_settings { |
39 | v4l2_std_id id; | 53 | v4l2_std_id id; |
54 | enum tm6000_audio_std audio_default_std; | ||
40 | struct tm6000_reg_settings common[37]; | 55 | struct tm6000_reg_settings common[37]; |
41 | }; | 56 | }; |
42 | 57 | ||
43 | static struct tm6000_std_tv_settings tv_stds[] = { | 58 | static struct tm6000_std_tv_settings tv_stds[] = { |
44 | { | 59 | { |
45 | .id = V4L2_STD_PAL_M, | 60 | .id = V4L2_STD_PAL_M, |
61 | .audio_default_std = BTSC, | ||
46 | .sif = { | 62 | .sif = { |
47 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, | 63 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, |
48 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | 64 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, |
@@ -96,11 +112,14 @@ static struct tm6000_std_tv_settings tv_stds[] = { | |||
96 | 112 | ||
97 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, | 113 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, |
98 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | 114 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, |
115 | |||
99 | {TM6010_REQ07_R3F_RESET, 0x00}, | 116 | {TM6010_REQ07_R3F_RESET, 0x00}, |
117 | |||
100 | {0, 0, 0}, | 118 | {0, 0, 0}, |
101 | }, | 119 | }, |
102 | }, { | 120 | }, { |
103 | .id = V4L2_STD_PAL_Nc, | 121 | .id = V4L2_STD_PAL_Nc, |
122 | .audio_default_std = BTSC, | ||
104 | .sif = { | 123 | .sif = { |
105 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, | 124 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, |
106 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | 125 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, |
@@ -154,11 +173,14 @@ static struct tm6000_std_tv_settings tv_stds[] = { | |||
154 | 173 | ||
155 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, | 174 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, |
156 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | 175 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, |
176 | |||
157 | {TM6010_REQ07_R3F_RESET, 0x00}, | 177 | {TM6010_REQ07_R3F_RESET, 0x00}, |
178 | |||
158 | {0, 0, 0}, | 179 | {0, 0, 0}, |
159 | }, | 180 | }, |
160 | }, { | 181 | }, { |
161 | .id = V4L2_STD_PAL, | 182 | .id = V4L2_STD_PAL, |
183 | .audio_default_std = BG_A2, | ||
162 | .sif = { | 184 | .sif = { |
163 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, | 185 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, |
164 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | 186 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, |
@@ -212,11 +234,73 @@ static struct tm6000_std_tv_settings tv_stds[] = { | |||
212 | 234 | ||
213 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, | 235 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, |
214 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | 236 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, |
237 | |||
215 | {TM6010_REQ07_R3F_RESET, 0x00}, | 238 | {TM6010_REQ07_R3F_RESET, 0x00}, |
239 | |||
216 | {0, 0, 0}, | 240 | {0, 0, 0}, |
217 | }, | 241 | }, |
218 | }, { | 242 | }, { |
219 | .id = V4L2_STD_SECAM, | 243 | .id = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G, |
244 | .audio_default_std = BG_NICAM, | ||
245 | .sif = { | ||
246 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, | ||
247 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | ||
248 | {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3}, | ||
249 | {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08}, | ||
250 | {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1}, | ||
251 | {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0}, | ||
252 | {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2}, | ||
253 | {TM6010_REQ08_RED_GAIN_SEL, 0xe8}, | ||
254 | {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62}, | ||
255 | {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe}, | ||
256 | {TM6010_REQ07_RFE_POWER_DOWN, 0xcb}, | ||
257 | {0, 0, 0}, | ||
258 | }, | ||
259 | .nosif = { | ||
260 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | ||
261 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | ||
262 | {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3}, | ||
263 | {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f}, | ||
264 | {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1}, | ||
265 | {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0}, | ||
266 | {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2}, | ||
267 | {TM6010_REQ08_RED_GAIN_SEL, 0xe8}, | ||
268 | {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60}, | ||
269 | {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc}, | ||
270 | {TM6010_REQ07_RFE_POWER_DOWN, 0x8b}, | ||
271 | {0, 0, 0}, | ||
272 | }, | ||
273 | .common = { | ||
274 | {TM6010_REQ07_R3F_RESET, 0x01}, | ||
275 | {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38}, | ||
276 | {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, | ||
277 | {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, | ||
278 | {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02}, | ||
279 | {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, | ||
280 | {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24}, | ||
281 | {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92}, | ||
282 | {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8}, | ||
283 | {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed}, | ||
284 | {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, | ||
285 | {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, | ||
286 | {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, | ||
287 | {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, | ||
288 | {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, | ||
289 | {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c}, | ||
290 | {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, | ||
291 | {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c}, | ||
292 | {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18}, | ||
293 | {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, | ||
294 | {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, | ||
295 | |||
296 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | ||
297 | |||
298 | {TM6010_REQ07_R3F_RESET, 0x00}, | ||
299 | {0, 0, 0}, | ||
300 | }, | ||
301 | }, { | ||
302 | .id = V4L2_STD_SECAM_DK, | ||
303 | .audio_default_std = DK_NICAM, | ||
220 | .sif = { | 304 | .sif = { |
221 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, | 305 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, |
222 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | 306 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, |
@@ -269,11 +353,13 @@ static struct tm6000_std_tv_settings tv_stds[] = { | |||
269 | {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, | 353 | {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, |
270 | 354 | ||
271 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | 355 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, |
356 | |||
272 | {TM6010_REQ07_R3F_RESET, 0x00}, | 357 | {TM6010_REQ07_R3F_RESET, 0x00}, |
273 | {0, 0, 0}, | 358 | {0, 0, 0}, |
274 | }, | 359 | }, |
275 | }, { | 360 | }, { |
276 | .id = V4L2_STD_NTSC, | 361 | .id = V4L2_STD_NTSC, |
362 | .audio_default_std = BTSC, | ||
277 | .sif = { | 363 | .sif = { |
278 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, | 364 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2}, |
279 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, | 365 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8}, |
@@ -327,7 +413,9 @@ static struct tm6000_std_tv_settings tv_stds[] = { | |||
327 | 413 | ||
328 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd}, | 414 | {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd}, |
329 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | 415 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, |
416 | |||
330 | {TM6010_REQ07_R3F_RESET, 0x00}, | 417 | {TM6010_REQ07_R3F_RESET, 0x00}, |
418 | |||
331 | {0, 0, 0}, | 419 | {0, 0, 0}, |
332 | }, | 420 | }, |
333 | }, | 421 | }, |
@@ -336,6 +424,7 @@ static struct tm6000_std_tv_settings tv_stds[] = { | |||
336 | static struct tm6000_std_settings composite_stds[] = { | 424 | static struct tm6000_std_settings composite_stds[] = { |
337 | { | 425 | { |
338 | .id = V4L2_STD_PAL_M, | 426 | .id = V4L2_STD_PAL_M, |
427 | .audio_default_std = BTSC, | ||
339 | .common = { | 428 | .common = { |
340 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 429 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
341 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, | 430 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, |
@@ -378,6 +467,7 @@ static struct tm6000_std_settings composite_stds[] = { | |||
378 | }, | 467 | }, |
379 | }, { | 468 | }, { |
380 | .id = V4L2_STD_PAL_Nc, | 469 | .id = V4L2_STD_PAL_Nc, |
470 | .audio_default_std = BTSC, | ||
381 | .common = { | 471 | .common = { |
382 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 472 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
383 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, | 473 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, |
@@ -420,6 +510,7 @@ static struct tm6000_std_settings composite_stds[] = { | |||
420 | }, | 510 | }, |
421 | }, { | 511 | }, { |
422 | .id = V4L2_STD_PAL, | 512 | .id = V4L2_STD_PAL, |
513 | .audio_default_std = BG_A2, | ||
423 | .common = { | 514 | .common = { |
424 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 515 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
425 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, | 516 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, |
@@ -462,6 +553,49 @@ static struct tm6000_std_settings composite_stds[] = { | |||
462 | }, | 553 | }, |
463 | }, { | 554 | }, { |
464 | .id = V4L2_STD_SECAM, | 555 | .id = V4L2_STD_SECAM, |
556 | .audio_default_std = BG_NICAM, | ||
557 | .common = { | ||
558 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | ||
559 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, | ||
560 | {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3}, | ||
561 | {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f}, | ||
562 | {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1}, | ||
563 | {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0}, | ||
564 | {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2}, | ||
565 | {TM6010_REQ08_RED_GAIN_SEL, 0xe8}, | ||
566 | {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68}, | ||
567 | {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc}, | ||
568 | {TM6010_REQ07_RFE_POWER_DOWN, 0x8b}, | ||
569 | |||
570 | {TM6010_REQ07_R3F_RESET, 0x01}, | ||
571 | {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38}, | ||
572 | {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, | ||
573 | {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, | ||
574 | {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02}, | ||
575 | {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, | ||
576 | {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24}, | ||
577 | {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92}, | ||
578 | {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8}, | ||
579 | {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed}, | ||
580 | {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, | ||
581 | {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, | ||
582 | {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, | ||
583 | {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, | ||
584 | {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, | ||
585 | {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c}, | ||
586 | {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, | ||
587 | {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c}, | ||
588 | {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18}, | ||
589 | {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, | ||
590 | {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, | ||
591 | |||
592 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | ||
593 | {TM6010_REQ07_R3F_RESET, 0x00}, | ||
594 | {0, 0, 0}, | ||
595 | }, | ||
596 | }, { | ||
597 | .id = V4L2_STD_SECAM_DK, | ||
598 | .audio_default_std = DK_NICAM, | ||
465 | .common = { | 599 | .common = { |
466 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 600 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
467 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, | 601 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, |
@@ -503,6 +637,7 @@ static struct tm6000_std_settings composite_stds[] = { | |||
503 | }, | 637 | }, |
504 | }, { | 638 | }, { |
505 | .id = V4L2_STD_NTSC, | 639 | .id = V4L2_STD_NTSC, |
640 | .audio_default_std = BTSC, | ||
506 | .common = { | 641 | .common = { |
507 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 642 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
508 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, | 643 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4}, |
@@ -549,6 +684,7 @@ static struct tm6000_std_settings composite_stds[] = { | |||
549 | static struct tm6000_std_settings svideo_stds[] = { | 684 | static struct tm6000_std_settings svideo_stds[] = { |
550 | { | 685 | { |
551 | .id = V4L2_STD_PAL_M, | 686 | .id = V4L2_STD_PAL_M, |
687 | .audio_default_std = BTSC, | ||
552 | .common = { | 688 | .common = { |
553 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 689 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
554 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, | 690 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, |
@@ -591,6 +727,7 @@ static struct tm6000_std_settings svideo_stds[] = { | |||
591 | }, | 727 | }, |
592 | }, { | 728 | }, { |
593 | .id = V4L2_STD_PAL_Nc, | 729 | .id = V4L2_STD_PAL_Nc, |
730 | .audio_default_std = BTSC, | ||
594 | .common = { | 731 | .common = { |
595 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 732 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
596 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, | 733 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, |
@@ -633,6 +770,7 @@ static struct tm6000_std_settings svideo_stds[] = { | |||
633 | }, | 770 | }, |
634 | }, { | 771 | }, { |
635 | .id = V4L2_STD_PAL, | 772 | .id = V4L2_STD_PAL, |
773 | .audio_default_std = BG_A2, | ||
636 | .common = { | 774 | .common = { |
637 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 775 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
638 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, | 776 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, |
@@ -675,6 +813,49 @@ static struct tm6000_std_settings svideo_stds[] = { | |||
675 | }, | 813 | }, |
676 | }, { | 814 | }, { |
677 | .id = V4L2_STD_SECAM, | 815 | .id = V4L2_STD_SECAM, |
816 | .audio_default_std = BG_NICAM, | ||
817 | .common = { | ||
818 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | ||
819 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, | ||
820 | {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8}, | ||
821 | {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00}, | ||
822 | {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2}, | ||
823 | {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0}, | ||
824 | {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2}, | ||
825 | {TM6010_REQ08_RED_GAIN_SEL, 0xe0}, | ||
826 | {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68}, | ||
827 | {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc}, | ||
828 | {TM6010_REQ07_RFE_POWER_DOWN, 0x8a}, | ||
829 | |||
830 | {TM6010_REQ07_R3F_RESET, 0x01}, | ||
831 | {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39}, | ||
832 | {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, | ||
833 | {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, | ||
834 | {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03}, | ||
835 | {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, | ||
836 | {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24}, | ||
837 | {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92}, | ||
838 | {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8}, | ||
839 | {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed}, | ||
840 | {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, | ||
841 | {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, | ||
842 | {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, | ||
843 | {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, | ||
844 | {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, | ||
845 | {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a}, | ||
846 | {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, | ||
847 | {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c}, | ||
848 | {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18}, | ||
849 | {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, | ||
850 | {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, | ||
851 | |||
852 | {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, | ||
853 | {TM6010_REQ07_R3F_RESET, 0x00}, | ||
854 | {0, 0, 0}, | ||
855 | }, | ||
856 | }, { | ||
857 | .id = V4L2_STD_SECAM_DK, | ||
858 | .audio_default_std = DK_NICAM, | ||
678 | .common = { | 859 | .common = { |
679 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 860 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
680 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, | 861 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, |
@@ -716,6 +897,7 @@ static struct tm6000_std_settings svideo_stds[] = { | |||
716 | }, | 897 | }, |
717 | }, { | 898 | }, { |
718 | .id = V4L2_STD_NTSC, | 899 | .id = V4L2_STD_NTSC, |
900 | .audio_default_std = BTSC, | ||
719 | .common = { | 901 | .common = { |
720 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, | 902 | {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0}, |
721 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, | 903 | {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc}, |
@@ -760,6 +942,133 @@ static struct tm6000_std_settings svideo_stds[] = { | |||
760 | }, | 942 | }, |
761 | }; | 943 | }; |
762 | 944 | ||
945 | |||
946 | static int tm6000_set_audio_std(struct tm6000_core *dev, | ||
947 | enum tm6000_audio_std std) | ||
948 | { | ||
949 | uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */ | ||
950 | uint8_t areg_05 = 0x09; /* Auto 4.5 = M Japan, Auto 6.5 = DK */ | ||
951 | uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */ | ||
952 | uint8_t mono_flag = 0; /* No mono */ | ||
953 | uint8_t nicam_flag = 0; /* No NICAM */ | ||
954 | |||
955 | switch (std) { | ||
956 | #if 0 | ||
957 | case DK_MONO: | ||
958 | mono_flag = 1; | ||
959 | break; | ||
960 | case DK_A2_1: | ||
961 | break; | ||
962 | case DK_A2_3: | ||
963 | areg_05 = 0x0b; | ||
964 | break; | ||
965 | case BG_MONO: | ||
966 | mono_flag = 1; | ||
967 | areg_05 = 0x05; | ||
968 | break; | ||
969 | #endif | ||
970 | case BG_NICAM: | ||
971 | areg_05 = 0x07; | ||
972 | nicam_flag = 1; | ||
973 | break; | ||
974 | case BTSC: | ||
975 | areg_05 = 0x02; | ||
976 | break; | ||
977 | case BG_A2: | ||
978 | areg_05 = 0x05; | ||
979 | break; | ||
980 | case DK_NICAM: | ||
981 | areg_05 = 0x06; | ||
982 | nicam_flag = 1; | ||
983 | break; | ||
984 | case EIAJ: | ||
985 | areg_05 = 0x02; | ||
986 | break; | ||
987 | case FM_RADIO: | ||
988 | tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); | ||
989 | tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04); | ||
990 | tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00); | ||
991 | tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c); | ||
992 | tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00); | ||
993 | tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18); | ||
994 | tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91); | ||
995 | tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe); | ||
996 | tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01); | ||
997 | tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); | ||
998 | tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); | ||
999 | return 0; | ||
1000 | break; | ||
1001 | case I_NICAM: | ||
1002 | areg_05 = 0x08; | ||
1003 | nicam_flag = 1; | ||
1004 | break; | ||
1005 | case KOREA_A2: | ||
1006 | areg_05 = 0x04; | ||
1007 | break; | ||
1008 | case L_NICAM: | ||
1009 | areg_02 = 0x02; /* GC1 Fixed gain +12dB */ | ||
1010 | areg_05 = 0x0a; | ||
1011 | nicam_flag = 1; | ||
1012 | break; | ||
1013 | } | ||
1014 | |||
1015 | #if 0 | ||
1016 | switch (tv_audio_mode) { | ||
1017 | case TV_MONO: | ||
1018 | areg_06 = (nicam_flag) ? 0x03 : 0x00; | ||
1019 | break; | ||
1020 | case TV_LANG_A: | ||
1021 | areg_06 = 0x00; | ||
1022 | break; | ||
1023 | case TV_LANG_B: | ||
1024 | areg_06 = 0x01; | ||
1025 | break; | ||
1026 | } | ||
1027 | #endif | ||
1028 | |||
1029 | if (mono_flag) | ||
1030 | areg_06 = 0x00; | ||
1031 | |||
1032 | tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); | ||
1033 | tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02); | ||
1034 | tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00); | ||
1035 | tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0); | ||
1036 | tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, areg_05); | ||
1037 | tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, areg_06); | ||
1038 | tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00); | ||
1039 | tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00); | ||
1040 | tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08); | ||
1041 | tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91); | ||
1042 | tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20); | ||
1043 | tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12); | ||
1044 | tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20); | ||
1045 | tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0); | ||
1046 | tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80); | ||
1047 | tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0); | ||
1048 | tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80); | ||
1049 | tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12); | ||
1050 | tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe); | ||
1051 | tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20); | ||
1052 | tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14); | ||
1053 | tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe); | ||
1054 | tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01); | ||
1055 | tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0); | ||
1056 | tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32); | ||
1057 | tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64); | ||
1058 | tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20); | ||
1059 | tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00); | ||
1060 | tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00); | ||
1061 | tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); | ||
1062 | tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00); | ||
1063 | tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00); | ||
1064 | tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3); | ||
1065 | tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00); | ||
1066 | tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc); | ||
1067 | tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); | ||
1068 | |||
1069 | return 0; | ||
1070 | } | ||
1071 | |||
763 | void tm6000_get_std_res(struct tm6000_core *dev) | 1072 | void tm6000_get_std_res(struct tm6000_core *dev) |
764 | { | 1073 | { |
765 | /* Currently, those are the only supported resoltions */ | 1074 | /* Currently, those are the only supported resoltions */ |
@@ -820,6 +1129,8 @@ static int tm6000_set_tv(struct tm6000_core *dev, int pos) | |||
820 | rc = tm6000_load_std(dev, tv_stds[pos].common, | 1129 | rc = tm6000_load_std(dev, tv_stds[pos].common, |
821 | sizeof(tv_stds[pos].common)); | 1130 | sizeof(tv_stds[pos].common)); |
822 | 1131 | ||
1132 | tm6000_set_audio_std(dev, tv_stds[pos].audio_default_std); | ||
1133 | |||
823 | return rc; | 1134 | return rc; |
824 | } | 1135 | } |
825 | 1136 | ||
@@ -845,6 +1156,8 @@ int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm) | |||
845 | rc = tm6000_load_std(dev, svideo_stds[i].common, | 1156 | rc = tm6000_load_std(dev, svideo_stds[i].common, |
846 | sizeof(svideo_stds[i]. | 1157 | sizeof(svideo_stds[i]. |
847 | common)); | 1158 | common)); |
1159 | tm6000_set_audio_std(dev, svideo_stds[i].audio_default_std); | ||
1160 | |||
848 | goto ret; | 1161 | goto ret; |
849 | } | 1162 | } |
850 | } | 1163 | } |
@@ -856,6 +1169,7 @@ int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm) | |||
856 | composite_stds[i].common, | 1169 | composite_stds[i].common, |
857 | sizeof(composite_stds[i]. | 1170 | sizeof(composite_stds[i]. |
858 | common)); | 1171 | common)); |
1172 | tm6000_set_audio_std(dev, composite_stds[i].audio_default_std); | ||
859 | goto ret; | 1173 | goto ret; |
860 | } | 1174 | } |
861 | } | 1175 | } |
diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h index 138716a8f05..a9e61d95a9b 100644 --- a/drivers/staging/tm6000/tm6000-usb-isoc.h +++ b/drivers/staging/tm6000/tm6000-usb-isoc.h | |||
@@ -1,20 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 8 | * the Free Software Foundation version 2 |
9 | 9 | * | |
10 | This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | 14 | * | |
15 | You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
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 | #include <linux/videodev2.h> | 20 | #include <linux/videodev2.h> |
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index ce0a089a077..9ec82796634 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c | |||
@@ -1,23 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
7 | - Fixed module load/unload | 7 | * - Fixed module load/unload |
8 | 8 | * | |
9 | This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation version 2 | 11 | * the Free Software Foundation version 2 |
12 | 12 | * | |
13 | This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | 17 | * | |
18 | You should have received a copy of the GNU General Public License | 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 | 19 | * along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 | */ | 21 | */ |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
@@ -118,8 +118,9 @@ static struct tm6000_fmt format[] = { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | /* ------------------------------------------------------------------ | 120 | /* ------------------------------------------------------------------ |
121 | DMA and thread functions | 121 | * DMA and thread functions |
122 | ------------------------------------------------------------------*/ | 122 | * ------------------------------------------------------------------ |
123 | */ | ||
123 | 124 | ||
124 | #define norm_maxw(a) 720 | 125 | #define norm_maxw(a) 720 |
125 | #define norm_maxh(a) 576 | 126 | #define norm_maxh(a) 576 |
@@ -189,17 +190,17 @@ static int copy_streams(u8 *data, unsigned long len, | |||
189 | struct urb *urb) | 190 | struct urb *urb) |
190 | { | 191 | { |
191 | struct tm6000_dmaqueue *dma_q = urb->context; | 192 | struct tm6000_dmaqueue *dma_q = urb->context; |
192 | struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); | 193 | struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); |
193 | u8 *ptr=data, *endp=data+len, c; | 194 | u8 *ptr = data, *endp = data+len, c; |
194 | unsigned long header=0; | 195 | unsigned long header = 0; |
195 | int rc=0; | 196 | int rc = 0; |
196 | unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0; | 197 | unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0; |
197 | struct tm6000_buffer *vbuf; | 198 | struct tm6000_buffer *vbuf; |
198 | char *voutp = NULL; | 199 | char *voutp = NULL; |
199 | unsigned int linewidth; | 200 | unsigned int linewidth; |
200 | 201 | ||
201 | /* get video buffer */ | 202 | /* get video buffer */ |
202 | get_next_buf (dma_q, &vbuf); | 203 | get_next_buf(dma_q, &vbuf); |
203 | if (!vbuf) | 204 | if (!vbuf) |
204 | return rc; | 205 | return rc; |
205 | voutp = videobuf_to_vmalloc(&vbuf->vb); | 206 | voutp = videobuf_to_vmalloc(&vbuf->vb); |
@@ -213,7 +214,7 @@ static int copy_streams(u8 *data, unsigned long len, | |||
213 | /* from last urb or packet */ | 214 | /* from last urb or packet */ |
214 | header = dev->isoc_ctl.tmp_buf; | 215 | header = dev->isoc_ctl.tmp_buf; |
215 | if (4 - dev->isoc_ctl.tmp_buf_len > 0) { | 216 | if (4 - dev->isoc_ctl.tmp_buf_len > 0) { |
216 | memcpy ((u8 *)&header + | 217 | memcpy((u8 *)&header + |
217 | dev->isoc_ctl.tmp_buf_len, | 218 | dev->isoc_ctl.tmp_buf_len, |
218 | ptr, | 219 | ptr, |
219 | 4 - dev->isoc_ctl.tmp_buf_len); | 220 | 4 - dev->isoc_ctl.tmp_buf_len); |
@@ -224,7 +225,7 @@ static int copy_streams(u8 *data, unsigned long len, | |||
224 | if (ptr + 3 >= endp) { | 225 | if (ptr + 3 >= endp) { |
225 | /* have incomplete header */ | 226 | /* have incomplete header */ |
226 | dev->isoc_ctl.tmp_buf_len = endp - ptr; | 227 | dev->isoc_ctl.tmp_buf_len = endp - ptr; |
227 | memcpy (&dev->isoc_ctl.tmp_buf, ptr, | 228 | memcpy(&dev->isoc_ctl.tmp_buf, ptr, |
228 | dev->isoc_ctl.tmp_buf_len); | 229 | dev->isoc_ctl.tmp_buf_len); |
229 | return rc; | 230 | return rc; |
230 | } | 231 | } |
@@ -261,13 +262,13 @@ static int copy_streams(u8 *data, unsigned long len, | |||
261 | /* Announces that a new buffer | 262 | /* Announces that a new buffer |
262 | * were filled | 263 | * were filled |
263 | */ | 264 | */ |
264 | buffer_filled (dev, dma_q, vbuf); | 265 | buffer_filled(dev, dma_q, vbuf); |
265 | dprintk (dev, V4L2_DEBUG_ISOC, | 266 | dprintk(dev, V4L2_DEBUG_ISOC, |
266 | "new buffer filled\n"); | 267 | "new buffer filled\n"); |
267 | get_next_buf (dma_q, &vbuf); | 268 | get_next_buf(dma_q, &vbuf); |
268 | if (!vbuf) | 269 | if (!vbuf) |
269 | return rc; | 270 | return rc; |
270 | voutp = videobuf_to_vmalloc (&vbuf->vb); | 271 | voutp = videobuf_to_vmalloc(&vbuf->vb); |
271 | if (!voutp) | 272 | if (!voutp) |
272 | return rc; | 273 | return rc; |
273 | memset(voutp, 0, vbuf->vb.size); | 274 | memset(voutp, 0, vbuf->vb.size); |
@@ -301,9 +302,17 @@ static int copy_streams(u8 *data, unsigned long len, | |||
301 | case TM6000_URB_MSG_VIDEO: | 302 | case TM6000_URB_MSG_VIDEO: |
302 | /* Fills video buffer */ | 303 | /* Fills video buffer */ |
303 | if (vbuf) | 304 | if (vbuf) |
304 | memcpy (&voutp[pos], ptr, cpysize); | 305 | memcpy(&voutp[pos], ptr, cpysize); |
305 | break; | 306 | break; |
306 | case TM6000_URB_MSG_AUDIO: | 307 | case TM6000_URB_MSG_AUDIO: |
308 | /* Need some code to copy audio buffer */ | ||
309 | if (dev->fourcc == V4L2_PIX_FMT_YUYV) { | ||
310 | /* Swap word bytes */ | ||
311 | int i; | ||
312 | |||
313 | for (i = 0; i < cpysize; i += 2) | ||
314 | swab16s((u16 *)(ptr + i)); | ||
315 | } | ||
307 | tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize); | 316 | tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize); |
308 | break; | 317 | break; |
309 | case TM6000_URB_MSG_VBI: | 318 | case TM6000_URB_MSG_VBI: |
@@ -338,9 +347,9 @@ static int copy_multiplexed(u8 *ptr, unsigned long len, | |||
338 | struct urb *urb) | 347 | struct urb *urb) |
339 | { | 348 | { |
340 | struct tm6000_dmaqueue *dma_q = urb->context; | 349 | struct tm6000_dmaqueue *dma_q = urb->context; |
341 | struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); | 350 | struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); |
342 | unsigned int pos=dev->isoc_ctl.pos,cpysize; | 351 | unsigned int pos = dev->isoc_ctl.pos, cpysize; |
343 | int rc=1; | 352 | int rc = 1; |
344 | struct tm6000_buffer *buf; | 353 | struct tm6000_buffer *buf; |
345 | char *outp = NULL; | 354 | char *outp = NULL; |
346 | 355 | ||
@@ -351,19 +360,18 @@ static int copy_multiplexed(u8 *ptr, unsigned long len, | |||
351 | if (!outp) | 360 | if (!outp) |
352 | return 0; | 361 | return 0; |
353 | 362 | ||
354 | while (len>0) { | 363 | while (len > 0) { |
355 | cpysize=min(len,buf->vb.size-pos); | 364 | cpysize = min(len, buf->vb.size-pos); |
356 | //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); | ||
357 | memcpy(&outp[pos], ptr, cpysize); | 365 | memcpy(&outp[pos], ptr, cpysize); |
358 | pos+=cpysize; | 366 | pos += cpysize; |
359 | ptr+=cpysize; | 367 | ptr += cpysize; |
360 | len-=cpysize; | 368 | len -= cpysize; |
361 | if (pos >= buf->vb.size) { | 369 | if (pos >= buf->vb.size) { |
362 | pos=0; | 370 | pos = 0; |
363 | /* Announces that a new buffer were filled */ | 371 | /* Announces that a new buffer were filled */ |
364 | buffer_filled (dev, dma_q, buf); | 372 | buffer_filled(dev, dma_q, buf); |
365 | dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); | 373 | dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); |
366 | get_next_buf (dma_q, &buf); | 374 | get_next_buf(dma_q, &buf); |
367 | if (!buf) | 375 | if (!buf) |
368 | break; | 376 | break; |
369 | outp = videobuf_to_vmalloc(&(buf->vb)); | 377 | outp = videobuf_to_vmalloc(&(buf->vb)); |
@@ -373,16 +381,16 @@ static int copy_multiplexed(u8 *ptr, unsigned long len, | |||
373 | } | 381 | } |
374 | } | 382 | } |
375 | 383 | ||
376 | dev->isoc_ctl.pos=pos; | 384 | dev->isoc_ctl.pos = pos; |
377 | return rc; | 385 | return rc; |
378 | } | 386 | } |
379 | 387 | ||
380 | static void inline print_err_status (struct tm6000_core *dev, | 388 | static inline void print_err_status(struct tm6000_core *dev, |
381 | int packet, int status) | 389 | int packet, int status) |
382 | { | 390 | { |
383 | char *errmsg = "Unknown"; | 391 | char *errmsg = "Unknown"; |
384 | 392 | ||
385 | switch(status) { | 393 | switch (status) { |
386 | case -ENOENT: | 394 | case -ENOENT: |
387 | errmsg = "unlinked synchronuously"; | 395 | errmsg = "unlinked synchronuously"; |
388 | break; | 396 | break; |
@@ -408,7 +416,7 @@ static void inline print_err_status (struct tm6000_core *dev, | |||
408 | errmsg = "Device does not respond"; | 416 | errmsg = "Device does not respond"; |
409 | break; | 417 | break; |
410 | } | 418 | } |
411 | if (packet<0) { | 419 | if (packet < 0) { |
412 | dprintk(dev, V4L2_DEBUG_QUEUE, "URB status %d [%s].\n", | 420 | dprintk(dev, V4L2_DEBUG_QUEUE, "URB status %d [%s].\n", |
413 | status, errmsg); | 421 | status, errmsg); |
414 | } else { | 422 | } else { |
@@ -424,20 +432,20 @@ static void inline print_err_status (struct tm6000_core *dev, | |||
424 | static inline int tm6000_isoc_copy(struct urb *urb) | 432 | static inline int tm6000_isoc_copy(struct urb *urb) |
425 | { | 433 | { |
426 | struct tm6000_dmaqueue *dma_q = urb->context; | 434 | struct tm6000_dmaqueue *dma_q = urb->context; |
427 | struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); | 435 | struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); |
428 | int i, len=0, rc=1, status; | 436 | int i, len = 0, rc = 1, status; |
429 | char *p; | 437 | char *p; |
430 | 438 | ||
431 | if (urb->status < 0) { | 439 | if (urb->status < 0) { |
432 | print_err_status (dev, -1, urb->status); | 440 | print_err_status(dev, -1, urb->status); |
433 | return 0; | 441 | return 0; |
434 | } | 442 | } |
435 | 443 | ||
436 | for (i = 0; i < urb->number_of_packets; i++) { | 444 | for (i = 0; i < urb->number_of_packets; i++) { |
437 | status = urb->iso_frame_desc[i].status; | 445 | status = urb->iso_frame_desc[i].status; |
438 | 446 | ||
439 | if (status<0) { | 447 | if (status < 0) { |
440 | print_err_status (dev,i,status); | 448 | print_err_status(dev, i, status); |
441 | continue; | 449 | continue; |
442 | } | 450 | } |
443 | 451 | ||
@@ -446,9 +454,9 @@ static inline int tm6000_isoc_copy(struct urb *urb) | |||
446 | if (len > 0) { | 454 | if (len > 0) { |
447 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 455 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
448 | if (!urb->iso_frame_desc[i].status) { | 456 | if (!urb->iso_frame_desc[i].status) { |
449 | if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) { | 457 | if ((dev->fourcc) == V4L2_PIX_FMT_TM6000) { |
450 | rc=copy_multiplexed(p, len, urb); | 458 | rc = copy_multiplexed(p, len, urb); |
451 | if (rc<=0) | 459 | if (rc <= 0) |
452 | return rc; | 460 | return rc; |
453 | } else { | 461 | } else { |
454 | copy_streams(p, len, urb); | 462 | copy_streams(p, len, urb); |
@@ -460,8 +468,9 @@ static inline int tm6000_isoc_copy(struct urb *urb) | |||
460 | } | 468 | } |
461 | 469 | ||
462 | /* ------------------------------------------------------------------ | 470 | /* ------------------------------------------------------------------ |
463 | URB control | 471 | * URB control |
464 | ------------------------------------------------------------------*/ | 472 | * ------------------------------------------------------------------ |
473 | */ | ||
465 | 474 | ||
466 | /* | 475 | /* |
467 | * IRQ callback, called by URB callback | 476 | * IRQ callback, called by URB callback |
@@ -501,7 +510,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev) | |||
501 | 510 | ||
502 | dev->isoc_ctl.buf = NULL; | 511 | dev->isoc_ctl.buf = NULL; |
503 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | 512 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
504 | urb=dev->isoc_ctl.urb[i]; | 513 | urb = dev->isoc_ctl.urb[i]; |
505 | if (urb) { | 514 | if (urb) { |
506 | usb_kill_urb(urb); | 515 | usb_kill_urb(urb); |
507 | usb_unlink_urb(urb); | 516 | usb_unlink_urb(urb); |
@@ -517,11 +526,11 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev) | |||
517 | dev->isoc_ctl.transfer_buffer[i] = NULL; | 526 | dev->isoc_ctl.transfer_buffer[i] = NULL; |
518 | } | 527 | } |
519 | 528 | ||
520 | kfree (dev->isoc_ctl.urb); | 529 | kfree(dev->isoc_ctl.urb); |
521 | kfree (dev->isoc_ctl.transfer_buffer); | 530 | kfree(dev->isoc_ctl.transfer_buffer); |
522 | 531 | ||
523 | dev->isoc_ctl.urb=NULL; | 532 | dev->isoc_ctl.urb = NULL; |
524 | dev->isoc_ctl.transfer_buffer=NULL; | 533 | dev->isoc_ctl.transfer_buffer = NULL; |
525 | dev->isoc_ctl.num_bufs = 0; | 534 | dev->isoc_ctl.num_bufs = 0; |
526 | } | 535 | } |
527 | 536 | ||
@@ -552,7 +561,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) | |||
552 | 561 | ||
553 | dev->isoc_ctl.max_pkt_size = size; | 562 | dev->isoc_ctl.max_pkt_size = size; |
554 | 563 | ||
555 | max_packets = ( framesize + size - 1) / size; | 564 | max_packets = (framesize + size - 1) / size; |
556 | 565 | ||
557 | if (max_packets > TM6000_MAX_ISO_PACKETS) | 566 | if (max_packets > TM6000_MAX_ISO_PACKETS) |
558 | max_packets = TM6000_MAX_ISO_PACKETS; | 567 | max_packets = TM6000_MAX_ISO_PACKETS; |
@@ -594,10 +603,10 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) | |||
594 | dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev, | 603 | dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev, |
595 | sb_size, GFP_KERNEL, &urb->transfer_dma); | 604 | sb_size, GFP_KERNEL, &urb->transfer_dma); |
596 | if (!dev->isoc_ctl.transfer_buffer[i]) { | 605 | if (!dev->isoc_ctl.transfer_buffer[i]) { |
597 | tm6000_err ("unable to allocate %i bytes for transfer" | 606 | tm6000_err("unable to allocate %i bytes for transfer" |
598 | " buffer %i%s\n", | 607 | " buffer %i%s\n", |
599 | sb_size, i, | 608 | sb_size, i, |
600 | in_interrupt()?" while in int":""); | 609 | in_interrupt() ? " while in int" : ""); |
601 | tm6000_uninit_isoc(dev); | 610 | tm6000_uninit_isoc(dev); |
602 | return -ENOMEM; | 611 | return -ENOMEM; |
603 | } | 612 | } |
@@ -619,13 +628,13 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) | |||
619 | return 0; | 628 | return 0; |
620 | } | 629 | } |
621 | 630 | ||
622 | static int tm6000_start_thread( struct tm6000_core *dev) | 631 | static int tm6000_start_thread(struct tm6000_core *dev) |
623 | { | 632 | { |
624 | struct tm6000_dmaqueue *dma_q = &dev->vidq; | 633 | struct tm6000_dmaqueue *dma_q = &dev->vidq; |
625 | int i; | 634 | int i; |
626 | 635 | ||
627 | dma_q->frame=0; | 636 | dma_q->frame = 0; |
628 | dma_q->ini_jiffies=jiffies; | 637 | dma_q->ini_jiffies = jiffies; |
629 | 638 | ||
630 | init_waitqueue_head(&dma_q->wq); | 639 | init_waitqueue_head(&dma_q->wq); |
631 | 640 | ||
@@ -644,8 +653,9 @@ static int tm6000_start_thread( struct tm6000_core *dev) | |||
644 | } | 653 | } |
645 | 654 | ||
646 | /* ------------------------------------------------------------------ | 655 | /* ------------------------------------------------------------------ |
647 | Videobuf operations | 656 | * Videobuf operations |
648 | ------------------------------------------------------------------*/ | 657 | * ------------------------------------------------------------------ |
658 | */ | ||
649 | 659 | ||
650 | static int | 660 | static int |
651 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | 661 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) |
@@ -656,9 +666,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
656 | if (0 == *count) | 666 | if (0 == *count) |
657 | *count = TM6000_DEF_BUF; | 667 | *count = TM6000_DEF_BUF; |
658 | 668 | ||
659 | if (*count < TM6000_MIN_BUF) { | 669 | if (*count < TM6000_MIN_BUF) |
660 | *count=TM6000_MIN_BUF; | 670 | *count = TM6000_MIN_BUF; |
661 | } | ||
662 | 671 | ||
663 | while (*size * *count > vid_limit * 1024 * 1024) | 672 | while (*size * *count > vid_limit * 1024 * 1024) |
664 | (*count)--; | 673 | (*count)--; |
@@ -698,7 +707,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
698 | enum v4l2_field field) | 707 | enum v4l2_field field) |
699 | { | 708 | { |
700 | struct tm6000_fh *fh = vq->priv_data; | 709 | struct tm6000_fh *fh = vq->priv_data; |
701 | struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb); | 710 | struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb); |
702 | struct tm6000_core *dev = fh->dev; | 711 | struct tm6000_core *dev = fh->dev; |
703 | int rc = 0, urb_init = 0; | 712 | int rc = 0, urb_init = 0; |
704 | 713 | ||
@@ -753,7 +762,7 @@ fail: | |||
753 | static void | 762 | static void |
754 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 763 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) |
755 | { | 764 | { |
756 | struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb); | 765 | struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb); |
757 | struct tm6000_fh *fh = vq->priv_data; | 766 | struct tm6000_fh *fh = vq->priv_data; |
758 | struct tm6000_core *dev = fh->dev; | 767 | struct tm6000_core *dev = fh->dev; |
759 | struct tm6000_dmaqueue *vidq = &dev->vidq; | 768 | struct tm6000_dmaqueue *vidq = &dev->vidq; |
@@ -764,9 +773,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
764 | 773 | ||
765 | static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 774 | static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) |
766 | { | 775 | { |
767 | struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb); | 776 | struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb); |
768 | 777 | ||
769 | free_buffer(vq,buf); | 778 | free_buffer(vq, buf); |
770 | } | 779 | } |
771 | 780 | ||
772 | static struct videobuf_queue_ops tm6000_video_qops = { | 781 | static struct videobuf_queue_ops tm6000_video_qops = { |
@@ -777,49 +786,66 @@ static struct videobuf_queue_ops tm6000_video_qops = { | |||
777 | }; | 786 | }; |
778 | 787 | ||
779 | /* ------------------------------------------------------------------ | 788 | /* ------------------------------------------------------------------ |
780 | IOCTL handling | 789 | * IOCTL handling |
781 | ------------------------------------------------------------------*/ | 790 | * ------------------------------------------------------------------ |
791 | */ | ||
782 | 792 | ||
783 | static int res_get(struct tm6000_core *dev, struct tm6000_fh *fh) | 793 | static bool is_res_read(struct tm6000_core *dev, struct tm6000_fh *fh) |
784 | { | 794 | { |
785 | /* is it free? */ | 795 | /* Is the current fh handling it? if so, that's OK */ |
786 | mutex_lock(&dev->lock); | 796 | if (dev->resources == fh && dev->is_res_read) |
787 | if (dev->resources) { | 797 | return true; |
788 | /* no, someone else uses it */ | 798 | |
789 | mutex_unlock(&dev->lock); | 799 | return false; |
790 | return 0; | 800 | } |
791 | } | 801 | |
792 | /* it's free, grab it */ | 802 | static bool is_res_streaming(struct tm6000_core *dev, struct tm6000_fh *fh) |
793 | dev->resources =1; | 803 | { |
794 | dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n"); | 804 | /* Is the current fh handling it? if so, that's OK */ |
795 | mutex_unlock(&dev->lock); | 805 | if (dev->resources == fh) |
796 | return 1; | 806 | return true; |
807 | |||
808 | return false; | ||
797 | } | 809 | } |
798 | 810 | ||
799 | static int res_locked(struct tm6000_core *dev) | 811 | static bool res_get(struct tm6000_core *dev, struct tm6000_fh *fh, |
812 | bool is_res_read) | ||
800 | { | 813 | { |
801 | return (dev->resources); | 814 | /* Is the current fh handling it? if so, that's OK */ |
815 | if (dev->resources == fh && dev->is_res_read == is_res_read) | ||
816 | return true; | ||
817 | |||
818 | /* is it free? */ | ||
819 | if (dev->resources) | ||
820 | return false; | ||
821 | |||
822 | /* grab it */ | ||
823 | dev->resources = fh; | ||
824 | dev->is_res_read = is_res_read; | ||
825 | dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n"); | ||
826 | return true; | ||
802 | } | 827 | } |
803 | 828 | ||
804 | static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh) | 829 | static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh) |
805 | { | 830 | { |
806 | mutex_lock(&dev->lock); | 831 | /* Is the current fh handling it? if so, that's OK */ |
807 | dev->resources = 0; | 832 | if (dev->resources != fh) |
833 | return; | ||
834 | |||
835 | dev->resources = NULL; | ||
808 | dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n"); | 836 | dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n"); |
809 | mutex_unlock(&dev->lock); | ||
810 | } | 837 | } |
811 | 838 | ||
812 | /* ------------------------------------------------------------------ | 839 | /* ------------------------------------------------------------------ |
813 | IOCTL vidioc handling | 840 | * IOCTL vidioc handling |
814 | ------------------------------------------------------------------*/ | 841 | * ------------------------------------------------------------------ |
815 | static int vidioc_querycap (struct file *file, void *priv, | 842 | */ |
843 | static int vidioc_querycap(struct file *file, void *priv, | ||
816 | struct v4l2_capability *cap) | 844 | struct v4l2_capability *cap) |
817 | { | 845 | { |
818 | // struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev; | ||
819 | 846 | ||
820 | strlcpy(cap->driver, "tm6000", sizeof(cap->driver)); | 847 | strlcpy(cap->driver, "tm6000", sizeof(cap->driver)); |
821 | strlcpy(cap->card,"Trident TVMaster TM5600/6000/6010", sizeof(cap->card)); | 848 | strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card)); |
822 | // strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); | ||
823 | cap->version = TM6000_VERSION; | 849 | cap->version = TM6000_VERSION; |
824 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 850 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | |
825 | V4L2_CAP_STREAMING | | 851 | V4L2_CAP_STREAMING | |
@@ -828,21 +854,21 @@ static int vidioc_querycap (struct file *file, void *priv, | |||
828 | return 0; | 854 | return 0; |
829 | } | 855 | } |
830 | 856 | ||
831 | static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, | 857 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
832 | struct v4l2_fmtdesc *f) | 858 | struct v4l2_fmtdesc *f) |
833 | { | 859 | { |
834 | if (unlikely(f->index >= ARRAY_SIZE(format))) | 860 | if (unlikely(f->index >= ARRAY_SIZE(format))) |
835 | return -EINVAL; | 861 | return -EINVAL; |
836 | 862 | ||
837 | strlcpy(f->description,format[f->index].name,sizeof(f->description)); | 863 | strlcpy(f->description, format[f->index].name, sizeof(f->description)); |
838 | f->pixelformat = format[f->index].fourcc; | 864 | f->pixelformat = format[f->index].fourcc; |
839 | return 0; | 865 | return 0; |
840 | } | 866 | } |
841 | 867 | ||
842 | static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, | 868 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, |
843 | struct v4l2_format *f) | 869 | struct v4l2_format *f) |
844 | { | 870 | { |
845 | struct tm6000_fh *fh=priv; | 871 | struct tm6000_fh *fh = priv; |
846 | 872 | ||
847 | f->fmt.pix.width = fh->width; | 873 | f->fmt.pix.width = fh->width; |
848 | f->fmt.pix.height = fh->height; | 874 | f->fmt.pix.height = fh->height; |
@@ -853,10 +879,10 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, | |||
853 | f->fmt.pix.sizeimage = | 879 | f->fmt.pix.sizeimage = |
854 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 880 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
855 | 881 | ||
856 | return (0); | 882 | return 0; |
857 | } | 883 | } |
858 | 884 | ||
859 | static struct tm6000_fmt* format_by_fourcc(unsigned int fourcc) | 885 | static struct tm6000_fmt *format_by_fourcc(unsigned int fourcc) |
860 | { | 886 | { |
861 | unsigned int i; | 887 | unsigned int i; |
862 | 888 | ||
@@ -866,7 +892,7 @@ static struct tm6000_fmt* format_by_fourcc(unsigned int fourcc) | |||
866 | return NULL; | 892 | return NULL; |
867 | } | 893 | } |
868 | 894 | ||
869 | static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, | 895 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, |
870 | struct v4l2_format *f) | 896 | struct v4l2_format *f) |
871 | { | 897 | { |
872 | struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev; | 898 | struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev; |
@@ -882,15 +908,14 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, | |||
882 | 908 | ||
883 | field = f->fmt.pix.field; | 909 | field = f->fmt.pix.field; |
884 | 910 | ||
885 | if (field == V4L2_FIELD_ANY) { | 911 | if (field == V4L2_FIELD_ANY) |
886 | // field=V4L2_FIELD_INTERLACED; | 912 | field = V4L2_FIELD_SEQ_TB; |
887 | field=V4L2_FIELD_SEQ_TB; | 913 | else if (V4L2_FIELD_INTERLACED != field) { |
888 | } else if (V4L2_FIELD_INTERLACED != field) { | ||
889 | dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Field type invalid.\n"); | 914 | dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Field type invalid.\n"); |
890 | return -EINVAL; | 915 | return -EINVAL; |
891 | } | 916 | } |
892 | 917 | ||
893 | tm6000_get_std_res (dev); | 918 | tm6000_get_std_res(dev); |
894 | 919 | ||
895 | f->fmt.pix.width = dev->width; | 920 | f->fmt.pix.width = dev->width; |
896 | f->fmt.pix.height = dev->height; | 921 | f->fmt.pix.height = dev->height; |
@@ -908,14 +933,14 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, | |||
908 | } | 933 | } |
909 | 934 | ||
910 | /*FIXME: This seems to be generic enough to be at videodev2 */ | 935 | /*FIXME: This seems to be generic enough to be at videodev2 */ |
911 | static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, | 936 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, |
912 | struct v4l2_format *f) | 937 | struct v4l2_format *f) |
913 | { | 938 | { |
914 | struct tm6000_fh *fh=priv; | 939 | struct tm6000_fh *fh = priv; |
915 | struct tm6000_core *dev = fh->dev; | 940 | struct tm6000_core *dev = fh->dev; |
916 | int ret = vidioc_try_fmt_vid_cap(file,fh,f); | 941 | int ret = vidioc_try_fmt_vid_cap(file, fh, f); |
917 | if (ret < 0) | 942 | if (ret < 0) |
918 | return (ret); | 943 | return ret; |
919 | 944 | ||
920 | fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 945 | fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
921 | fh->width = f->fmt.pix.width; | 946 | fh->width = f->fmt.pix.width; |
@@ -927,52 +952,52 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, | |||
927 | 952 | ||
928 | tm6000_set_fourcc_format(dev); | 953 | tm6000_set_fourcc_format(dev); |
929 | 954 | ||
930 | return (0); | 955 | return 0; |
931 | } | 956 | } |
932 | 957 | ||
933 | static int vidioc_reqbufs (struct file *file, void *priv, | 958 | static int vidioc_reqbufs(struct file *file, void *priv, |
934 | struct v4l2_requestbuffers *p) | 959 | struct v4l2_requestbuffers *p) |
935 | { | 960 | { |
936 | struct tm6000_fh *fh=priv; | 961 | struct tm6000_fh *fh = priv; |
937 | 962 | ||
938 | return (videobuf_reqbufs(&fh->vb_vidq, p)); | 963 | return videobuf_reqbufs(&fh->vb_vidq, p); |
939 | } | 964 | } |
940 | 965 | ||
941 | static int vidioc_querybuf (struct file *file, void *priv, | 966 | static int vidioc_querybuf(struct file *file, void *priv, |
942 | struct v4l2_buffer *p) | 967 | struct v4l2_buffer *p) |
943 | { | 968 | { |
944 | struct tm6000_fh *fh=priv; | 969 | struct tm6000_fh *fh = priv; |
945 | 970 | ||
946 | return (videobuf_querybuf(&fh->vb_vidq, p)); | 971 | return videobuf_querybuf(&fh->vb_vidq, p); |
947 | } | 972 | } |
948 | 973 | ||
949 | static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p) | 974 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) |
950 | { | 975 | { |
951 | struct tm6000_fh *fh=priv; | 976 | struct tm6000_fh *fh = priv; |
952 | 977 | ||
953 | return (videobuf_qbuf(&fh->vb_vidq, p)); | 978 | return videobuf_qbuf(&fh->vb_vidq, p); |
954 | } | 979 | } |
955 | 980 | ||
956 | static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) | 981 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) |
957 | { | 982 | { |
958 | struct tm6000_fh *fh=priv; | 983 | struct tm6000_fh *fh = priv; |
959 | 984 | ||
960 | return (videobuf_dqbuf(&fh->vb_vidq, p, | 985 | return videobuf_dqbuf(&fh->vb_vidq, p, |
961 | file->f_flags & O_NONBLOCK)); | 986 | file->f_flags & O_NONBLOCK); |
962 | } | 987 | } |
963 | 988 | ||
964 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 989 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
965 | static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) | 990 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) |
966 | { | 991 | { |
967 | struct tm6000_fh *fh=priv; | 992 | struct tm6000_fh *fh = priv; |
968 | 993 | ||
969 | return videobuf_cgmbuf (&fh->vb_vidq, mbuf, 8); | 994 | return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); |
970 | } | 995 | } |
971 | #endif | 996 | #endif |
972 | 997 | ||
973 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | 998 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) |
974 | { | 999 | { |
975 | struct tm6000_fh *fh=priv; | 1000 | struct tm6000_fh *fh = priv; |
976 | struct tm6000_core *dev = fh->dev; | 1001 | struct tm6000_core *dev = fh->dev; |
977 | 1002 | ||
978 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1003 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
@@ -980,7 +1005,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
980 | if (i != fh->type) | 1005 | if (i != fh->type) |
981 | return -EINVAL; | 1006 | return -EINVAL; |
982 | 1007 | ||
983 | if (!res_get(dev,fh)) | 1008 | if (!res_get(dev, fh, false)) |
984 | return -EBUSY; | 1009 | return -EBUSY; |
985 | return (videobuf_streamon(&fh->vb_vidq)); | 1010 | return (videobuf_streamon(&fh->vb_vidq)); |
986 | } | 1011 | } |
@@ -1007,7 +1032,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm) | |||
1007 | struct tm6000_fh *fh=priv; | 1032 | struct tm6000_fh *fh=priv; |
1008 | struct tm6000_core *dev = fh->dev; | 1033 | struct tm6000_core *dev = fh->dev; |
1009 | 1034 | ||
1010 | rc=tm6000_set_standard (dev, norm); | 1035 | rc = tm6000_init_analog_mode(dev); |
1011 | 1036 | ||
1012 | fh->width = dev->width; | 1037 | fh->width = dev->width; |
1013 | fh->height = dev->height; | 1038 | fh->height = dev->height; |
@@ -1020,21 +1045,21 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm) | |||
1020 | return 0; | 1045 | return 0; |
1021 | } | 1046 | } |
1022 | 1047 | ||
1023 | static int vidioc_enum_input (struct file *file, void *priv, | 1048 | static int vidioc_enum_input(struct file *file, void *priv, |
1024 | struct v4l2_input *inp) | 1049 | struct v4l2_input *inp) |
1025 | { | 1050 | { |
1026 | switch (inp->index) { | 1051 | switch (inp->index) { |
1027 | case TM6000_INPUT_TV: | 1052 | case TM6000_INPUT_TV: |
1028 | inp->type = V4L2_INPUT_TYPE_TUNER; | 1053 | inp->type = V4L2_INPUT_TYPE_TUNER; |
1029 | strcpy(inp->name,"Television"); | 1054 | strcpy(inp->name, "Television"); |
1030 | break; | 1055 | break; |
1031 | case TM6000_INPUT_COMPOSITE: | 1056 | case TM6000_INPUT_COMPOSITE: |
1032 | inp->type = V4L2_INPUT_TYPE_CAMERA; | 1057 | inp->type = V4L2_INPUT_TYPE_CAMERA; |
1033 | strcpy(inp->name,"Composite"); | 1058 | strcpy(inp->name, "Composite"); |
1034 | break; | 1059 | break; |
1035 | case TM6000_INPUT_SVIDEO: | 1060 | case TM6000_INPUT_SVIDEO: |
1036 | inp->type = V4L2_INPUT_TYPE_CAMERA; | 1061 | inp->type = V4L2_INPUT_TYPE_CAMERA; |
1037 | strcpy(inp->name,"S-Video"); | 1062 | strcpy(inp->name, "S-Video"); |
1038 | break; | 1063 | break; |
1039 | default: | 1064 | default: |
1040 | return -EINVAL; | 1065 | return -EINVAL; |
@@ -1044,48 +1069,48 @@ static int vidioc_enum_input (struct file *file, void *priv, | |||
1044 | return 0; | 1069 | return 0; |
1045 | } | 1070 | } |
1046 | 1071 | ||
1047 | static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) | 1072 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) |
1048 | { | 1073 | { |
1049 | struct tm6000_fh *fh=priv; | 1074 | struct tm6000_fh *fh = priv; |
1050 | struct tm6000_core *dev = fh->dev; | 1075 | struct tm6000_core *dev = fh->dev; |
1051 | 1076 | ||
1052 | *i=dev->input; | 1077 | *i = dev->input; |
1053 | 1078 | ||
1054 | return 0; | 1079 | return 0; |
1055 | } | 1080 | } |
1056 | static int vidioc_s_input (struct file *file, void *priv, unsigned int i) | 1081 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) |
1057 | { | 1082 | { |
1058 | struct tm6000_fh *fh=priv; | 1083 | struct tm6000_fh *fh = priv; |
1059 | struct tm6000_core *dev = fh->dev; | 1084 | struct tm6000_core *dev = fh->dev; |
1060 | int rc=0; | 1085 | int rc = 0; |
1061 | char buf[1]; | 1086 | char buf[1]; |
1062 | 1087 | ||
1063 | switch (i) { | 1088 | switch (i) { |
1064 | case TM6000_INPUT_TV: | 1089 | case TM6000_INPUT_TV: |
1065 | dev->input=i; | 1090 | dev->input = i; |
1066 | *buf=0; | 1091 | *buf = 0; |
1067 | break; | 1092 | break; |
1068 | case TM6000_INPUT_COMPOSITE: | 1093 | case TM6000_INPUT_COMPOSITE: |
1069 | case TM6000_INPUT_SVIDEO: | 1094 | case TM6000_INPUT_SVIDEO: |
1070 | dev->input=i; | 1095 | dev->input = i; |
1071 | *buf=1; | 1096 | *buf = 1; |
1072 | break; | 1097 | break; |
1073 | default: | 1098 | default: |
1074 | return -EINVAL; | 1099 | return -EINVAL; |
1075 | } | 1100 | } |
1076 | rc=tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR, | 1101 | rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, |
1077 | REQ_03_SET_GET_MCU_PIN, 0x03, 1, buf, 1); | 1102 | REQ_03_SET_GET_MCU_PIN, 0x03, 1, buf, 1); |
1078 | 1103 | ||
1079 | if (!rc) { | 1104 | if (!rc) { |
1080 | dev->input=i; | 1105 | dev->input = i; |
1081 | rc=vidioc_s_std (file, priv, &dev->vfd->current_norm); | 1106 | rc = vidioc_s_std(file, priv, &dev->vfd->current_norm); |
1082 | } | 1107 | } |
1083 | 1108 | ||
1084 | return (rc); | 1109 | return rc; |
1085 | } | 1110 | } |
1086 | 1111 | ||
1087 | /* --- controls ---------------------------------------------- */ | 1112 | /* --- controls ---------------------------------------------- */ |
1088 | static int vidioc_queryctrl (struct file *file, void *priv, | 1113 | static int vidioc_queryctrl(struct file *file, void *priv, |
1089 | struct v4l2_queryctrl *qc) | 1114 | struct v4l2_queryctrl *qc) |
1090 | { | 1115 | { |
1091 | int i; | 1116 | int i; |
@@ -1094,16 +1119,16 @@ static int vidioc_queryctrl (struct file *file, void *priv, | |||
1094 | if (qc->id && qc->id == tm6000_qctrl[i].id) { | 1119 | if (qc->id && qc->id == tm6000_qctrl[i].id) { |
1095 | memcpy(qc, &(tm6000_qctrl[i]), | 1120 | memcpy(qc, &(tm6000_qctrl[i]), |
1096 | sizeof(*qc)); | 1121 | sizeof(*qc)); |
1097 | return (0); | 1122 | return 0; |
1098 | } | 1123 | } |
1099 | 1124 | ||
1100 | return -EINVAL; | 1125 | return -EINVAL; |
1101 | } | 1126 | } |
1102 | 1127 | ||
1103 | static int vidioc_g_ctrl (struct file *file, void *priv, | 1128 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1104 | struct v4l2_control *ctrl) | 1129 | struct v4l2_control *ctrl) |
1105 | { | 1130 | { |
1106 | struct tm6000_fh *fh=priv; | 1131 | struct tm6000_fh *fh = priv; |
1107 | struct tm6000_core *dev = fh->dev; | 1132 | struct tm6000_core *dev = fh->dev; |
1108 | int val; | 1133 | int val; |
1109 | 1134 | ||
@@ -1125,41 +1150,41 @@ static int vidioc_g_ctrl (struct file *file, void *priv, | |||
1125 | return -EINVAL; | 1150 | return -EINVAL; |
1126 | } | 1151 | } |
1127 | 1152 | ||
1128 | if (val<0) | 1153 | if (val < 0) |
1129 | return val; | 1154 | return val; |
1130 | 1155 | ||
1131 | ctrl->value=val; | 1156 | ctrl->value = val; |
1132 | 1157 | ||
1133 | return 0; | 1158 | return 0; |
1134 | } | 1159 | } |
1135 | static int vidioc_s_ctrl (struct file *file, void *priv, | 1160 | static int vidioc_s_ctrl(struct file *file, void *priv, |
1136 | struct v4l2_control *ctrl) | 1161 | struct v4l2_control *ctrl) |
1137 | { | 1162 | { |
1138 | struct tm6000_fh *fh =priv; | 1163 | struct tm6000_fh *fh = priv; |
1139 | struct tm6000_core *dev = fh->dev; | 1164 | struct tm6000_core *dev = fh->dev; |
1140 | u8 val=ctrl->value; | 1165 | u8 val = ctrl->value; |
1141 | 1166 | ||
1142 | switch (ctrl->id) { | 1167 | switch (ctrl->id) { |
1143 | case V4L2_CID_CONTRAST: | 1168 | case V4L2_CID_CONTRAST: |
1144 | tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val); | 1169 | tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val); |
1145 | return 0; | 1170 | return 0; |
1146 | case V4L2_CID_BRIGHTNESS: | 1171 | case V4L2_CID_BRIGHTNESS: |
1147 | tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val); | 1172 | tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val); |
1148 | return 0; | 1173 | return 0; |
1149 | case V4L2_CID_SATURATION: | 1174 | case V4L2_CID_SATURATION: |
1150 | tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val); | 1175 | tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val); |
1151 | return 0; | 1176 | return 0; |
1152 | case V4L2_CID_HUE: | 1177 | case V4L2_CID_HUE: |
1153 | tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); | 1178 | tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); |
1154 | return 0; | 1179 | return 0; |
1155 | } | 1180 | } |
1156 | return -EINVAL; | 1181 | return -EINVAL; |
1157 | } | 1182 | } |
1158 | 1183 | ||
1159 | static int vidioc_g_tuner (struct file *file, void *priv, | 1184 | static int vidioc_g_tuner(struct file *file, void *priv, |
1160 | struct v4l2_tuner *t) | 1185 | struct v4l2_tuner *t) |
1161 | { | 1186 | { |
1162 | struct tm6000_fh *fh =priv; | 1187 | struct tm6000_fh *fh = priv; |
1163 | struct tm6000_core *dev = fh->dev; | 1188 | struct tm6000_core *dev = fh->dev; |
1164 | 1189 | ||
1165 | if (unlikely(UNSET == dev->tuner_type)) | 1190 | if (unlikely(UNSET == dev->tuner_type)) |
@@ -1176,10 +1201,10 @@ static int vidioc_g_tuner (struct file *file, void *priv, | |||
1176 | return 0; | 1201 | return 0; |
1177 | } | 1202 | } |
1178 | 1203 | ||
1179 | static int vidioc_s_tuner (struct file *file, void *priv, | 1204 | static int vidioc_s_tuner(struct file *file, void *priv, |
1180 | struct v4l2_tuner *t) | 1205 | struct v4l2_tuner *t) |
1181 | { | 1206 | { |
1182 | struct tm6000_fh *fh =priv; | 1207 | struct tm6000_fh *fh = priv; |
1183 | struct tm6000_core *dev = fh->dev; | 1208 | struct tm6000_core *dev = fh->dev; |
1184 | 1209 | ||
1185 | if (UNSET == dev->tuner_type) | 1210 | if (UNSET == dev->tuner_type) |
@@ -1190,10 +1215,10 @@ static int vidioc_s_tuner (struct file *file, void *priv, | |||
1190 | return 0; | 1215 | return 0; |
1191 | } | 1216 | } |
1192 | 1217 | ||
1193 | static int vidioc_g_frequency (struct file *file, void *priv, | 1218 | static int vidioc_g_frequency(struct file *file, void *priv, |
1194 | struct v4l2_frequency *f) | 1219 | struct v4l2_frequency *f) |
1195 | { | 1220 | { |
1196 | struct tm6000_fh *fh =priv; | 1221 | struct tm6000_fh *fh = priv; |
1197 | struct tm6000_core *dev = fh->dev; | 1222 | struct tm6000_core *dev = fh->dev; |
1198 | 1223 | ||
1199 | if (unlikely(UNSET == dev->tuner_type)) | 1224 | if (unlikely(UNSET == dev->tuner_type)) |
@@ -1207,10 +1232,10 @@ static int vidioc_g_frequency (struct file *file, void *priv, | |||
1207 | return 0; | 1232 | return 0; |
1208 | } | 1233 | } |
1209 | 1234 | ||
1210 | static int vidioc_s_frequency (struct file *file, void *priv, | 1235 | static int vidioc_s_frequency(struct file *file, void *priv, |
1211 | struct v4l2_frequency *f) | 1236 | struct v4l2_frequency *f) |
1212 | { | 1237 | { |
1213 | struct tm6000_fh *fh =priv; | 1238 | struct tm6000_fh *fh = priv; |
1214 | struct tm6000_core *dev = fh->dev; | 1239 | struct tm6000_core *dev = fh->dev; |
1215 | 1240 | ||
1216 | if (unlikely(f->type != V4L2_TUNER_ANALOG_TV)) | 1241 | if (unlikely(f->type != V4L2_TUNER_ANALOG_TV)) |
@@ -1221,10 +1246,8 @@ static int vidioc_s_frequency (struct file *file, void *priv, | |||
1221 | if (unlikely(f->tuner != 0)) | 1246 | if (unlikely(f->tuner != 0)) |
1222 | return -EINVAL; | 1247 | return -EINVAL; |
1223 | 1248 | ||
1224 | // mutex_lock(&dev->lock); | ||
1225 | dev->freq = f->frequency; | 1249 | dev->freq = f->frequency; |
1226 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); | 1250 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); |
1227 | // mutex_unlock(&dev->lock); | ||
1228 | 1251 | ||
1229 | return 0; | 1252 | return 0; |
1230 | } | 1253 | } |
@@ -1239,7 +1262,7 @@ static int tm6000_open(struct file *file) | |||
1239 | struct tm6000_core *dev = video_drvdata(file); | 1262 | struct tm6000_core *dev = video_drvdata(file); |
1240 | struct tm6000_fh *fh; | 1263 | struct tm6000_fh *fh; |
1241 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1264 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1242 | int i,rc; | 1265 | int i, rc; |
1243 | 1266 | ||
1244 | printk(KERN_INFO "tm6000: open called (dev=%s)\n", | 1267 | printk(KERN_INFO "tm6000: open called (dev=%s)\n", |
1245 | video_device_node_name(vdev)); | 1268 | video_device_node_name(vdev)); |
@@ -1256,7 +1279,7 @@ static int tm6000_open(struct file *file) | |||
1256 | dev->users); | 1279 | dev->users); |
1257 | 1280 | ||
1258 | /* allocate + initialize per filehandle data */ | 1281 | /* allocate + initialize per filehandle data */ |
1259 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | 1282 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1260 | if (NULL == fh) { | 1283 | if (NULL == fh) { |
1261 | dev->users--; | 1284 | dev->users--; |
1262 | return -ENOMEM; | 1285 | return -ENOMEM; |
@@ -1284,23 +1307,23 @@ static int tm6000_open(struct file *file) | |||
1284 | "active=%d\n",list_empty(&dev->vidq.active)); | 1307 | "active=%d\n",list_empty(&dev->vidq.active)); |
1285 | 1308 | ||
1286 | /* initialize hardware on analog mode */ | 1309 | /* initialize hardware on analog mode */ |
1287 | if (dev->mode!=TM6000_MODE_ANALOG) { | 1310 | rc = tm6000_init_analog_mode(dev); |
1288 | rc=tm6000_init_analog_mode (dev); | 1311 | if (rc < 0) |
1289 | if (rc<0) | 1312 | return rc; |
1290 | return rc; | ||
1291 | 1313 | ||
1314 | if (dev->mode != TM6000_MODE_ANALOG) { | ||
1292 | /* Put all controls at a sane state */ | 1315 | /* Put all controls at a sane state */ |
1293 | for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++) | 1316 | for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++) |
1294 | qctl_regs[i] =tm6000_qctrl[i].default_value; | 1317 | qctl_regs[i] = tm6000_qctrl[i].default_value; |
1295 | 1318 | ||
1296 | dev->mode=TM6000_MODE_ANALOG; | 1319 | dev->mode = TM6000_MODE_ANALOG; |
1297 | } | 1320 | } |
1298 | 1321 | ||
1299 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops, | 1322 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops, |
1300 | NULL, &dev->slock, | 1323 | NULL, &dev->slock, |
1301 | fh->type, | 1324 | fh->type, |
1302 | V4L2_FIELD_INTERLACED, | 1325 | V4L2_FIELD_INTERLACED, |
1303 | sizeof(struct tm6000_buffer),fh); | 1326 | sizeof(struct tm6000_buffer), fh, &dev->lock); |
1304 | 1327 | ||
1305 | return 0; | 1328 | return 0; |
1306 | } | 1329 | } |
@@ -1311,7 +1334,7 @@ tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos) | |||
1311 | struct tm6000_fh *fh = file->private_data; | 1334 | struct tm6000_fh *fh = file->private_data; |
1312 | 1335 | ||
1313 | if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1336 | if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1314 | if (res_locked(fh->dev)) | 1337 | if (!res_get(fh->dev, fh, true)) |
1315 | return -EBUSY; | 1338 | return -EBUSY; |
1316 | 1339 | ||
1317 | return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0, | 1340 | return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0, |
@@ -1329,7 +1352,10 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait) | |||
1329 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 1352 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
1330 | return POLLERR; | 1353 | return POLLERR; |
1331 | 1354 | ||
1332 | if (res_get(fh->dev,fh)) { | 1355 | if (!!is_res_streaming(fh->dev, fh)) |
1356 | return POLLERR; | ||
1357 | |||
1358 | if (!is_res_read(fh->dev, fh)) { | ||
1333 | /* streaming capture */ | 1359 | /* streaming capture */ |
1334 | if (list_empty(&fh->vb_vidq.stream)) | 1360 | if (list_empty(&fh->vb_vidq.stream)) |
1335 | return POLLERR; | 1361 | return POLLERR; |
@@ -1342,7 +1368,7 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait) | |||
1342 | poll_wait(file, &buf->vb.done, wait); | 1368 | poll_wait(file, &buf->vb.done, wait); |
1343 | if (buf->vb.state == VIDEOBUF_DONE || | 1369 | if (buf->vb.state == VIDEOBUF_DONE || |
1344 | buf->vb.state == VIDEOBUF_ERROR) | 1370 | buf->vb.state == VIDEOBUF_ERROR) |
1345 | return POLLIN|POLLRDNORM; | 1371 | return POLLIN | POLLRDNORM; |
1346 | return 0; | 1372 | return 0; |
1347 | } | 1373 | } |
1348 | 1374 | ||
@@ -1357,12 +1383,13 @@ static int tm6000_release(struct file *file) | |||
1357 | 1383 | ||
1358 | dev->users--; | 1384 | dev->users--; |
1359 | 1385 | ||
1386 | res_free(dev, fh); | ||
1360 | if (!dev->users) { | 1387 | if (!dev->users) { |
1361 | tm6000_uninit_isoc(dev); | 1388 | tm6000_uninit_isoc(dev); |
1362 | videobuf_mmap_free(&fh->vb_vidq); | 1389 | videobuf_mmap_free(&fh->vb_vidq); |
1363 | } | 1390 | } |
1364 | 1391 | ||
1365 | kfree (fh); | 1392 | kfree(fh); |
1366 | 1393 | ||
1367 | return 0; | 1394 | return 0; |
1368 | } | 1395 | } |
@@ -1372,7 +1399,7 @@ static int tm6000_mmap(struct file *file, struct vm_area_struct * vma) | |||
1372 | struct tm6000_fh *fh = file->private_data; | 1399 | struct tm6000_fh *fh = file->private_data; |
1373 | int ret; | 1400 | int ret; |
1374 | 1401 | ||
1375 | ret=videobuf_mmap_mapper(&fh->vb_vidq, vma); | 1402 | ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
1376 | 1403 | ||
1377 | return ret; | 1404 | return ret; |
1378 | } | 1405 | } |
@@ -1381,7 +1408,7 @@ static struct v4l2_file_operations tm6000_fops = { | |||
1381 | .owner = THIS_MODULE, | 1408 | .owner = THIS_MODULE, |
1382 | .open = tm6000_open, | 1409 | .open = tm6000_open, |
1383 | .release = tm6000_release, | 1410 | .release = tm6000_release, |
1384 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1411 | .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1385 | .read = tm6000_read, | 1412 | .read = tm6000_read, |
1386 | .poll = tm6000_poll, | 1413 | .poll = tm6000_poll, |
1387 | .mmap = tm6000_mmap, | 1414 | .mmap = tm6000_mmap, |
@@ -1425,8 +1452,9 @@ static struct video_device tm6000_template = { | |||
1425 | }; | 1452 | }; |
1426 | 1453 | ||
1427 | /* ----------------------------------------------------------------- | 1454 | /* ----------------------------------------------------------------- |
1428 | Initialization and module stuff | 1455 | * Initialization and module stuff |
1429 | ------------------------------------------------------------------*/ | 1456 | * ------------------------------------------------------------------ |
1457 | */ | ||
1430 | 1458 | ||
1431 | int tm6000_v4l2_register(struct tm6000_core *dev) | 1459 | int tm6000_v4l2_register(struct tm6000_core *dev) |
1432 | { | 1460 | { |
@@ -1443,8 +1471,10 @@ int tm6000_v4l2_register(struct tm6000_core *dev) | |||
1443 | INIT_LIST_HEAD(&dev->vidq.active); | 1471 | INIT_LIST_HEAD(&dev->vidq.active); |
1444 | INIT_LIST_HEAD(&dev->vidq.queued); | 1472 | INIT_LIST_HEAD(&dev->vidq.queued); |
1445 | 1473 | ||
1446 | memcpy (dev->vfd, &tm6000_template, sizeof(*(dev->vfd))); | 1474 | memcpy(dev->vfd, &tm6000_template, sizeof(*(dev->vfd))); |
1447 | dev->vfd->debug=tm6000_debug; | 1475 | dev->vfd->debug = tm6000_debug; |
1476 | dev->vfd->lock = &dev->lock; | ||
1477 | |||
1448 | vfd->v4l2_dev = &dev->v4l2_dev; | 1478 | vfd->v4l2_dev = &dev->v4l2_dev; |
1449 | video_set_drvdata(vfd, dev); | 1479 | video_set_drvdata(vfd, dev); |
1450 | 1480 | ||
@@ -1466,11 +1496,11 @@ int tm6000_v4l2_exit(void) | |||
1466 | } | 1496 | } |
1467 | 1497 | ||
1468 | module_param(video_nr, int, 0); | 1498 | module_param(video_nr, int, 0); |
1469 | MODULE_PARM_DESC(video_nr,"Allow changing video device number"); | 1499 | MODULE_PARM_DESC(video_nr, "Allow changing video device number"); |
1470 | 1500 | ||
1471 | module_param_named (debug, tm6000_debug, int, 0444); | 1501 | module_param_named(debug, tm6000_debug, int, 0444); |
1472 | MODULE_PARM_DESC(debug,"activates debug info"); | 1502 | MODULE_PARM_DESC(debug, "activates debug info"); |
1473 | 1503 | ||
1474 | module_param(vid_limit,int,0644); | 1504 | module_param(vid_limit, int, 0644); |
1475 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | 1505 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); |
1476 | 1506 | ||
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h index 1ec1bff9b29..46017b60319 100644 --- a/drivers/staging/tm6000/tm6000.h +++ b/drivers/staging/tm6000/tm6000.h | |||
@@ -1,23 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices |
3 | 3 | * | |
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | * | |
6 | Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
7 | - DVB-T support | 7 | * - DVB-T support |
8 | 8 | * | |
9 | This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation version 2 | 11 | * the Free Software Foundation version 2 |
12 | 12 | * | |
13 | This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | 17 | * | |
18 | You should have received a copy of the GNU General Public License | 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 | 19 | * along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* Use the tm6000-hack, instead of the proper initialization code i*/ | 23 | /* Use the tm6000-hack, instead of the proper initialization code i*/ |
@@ -54,8 +54,9 @@ enum tm6000_devtype { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | /* ------------------------------------------------------------------ | 56 | /* ------------------------------------------------------------------ |
57 | Basic structures | 57 | * Basic structures |
58 | ------------------------------------------------------------------*/ | 58 | * ------------------------------------------------------------------ |
59 | */ | ||
59 | 60 | ||
60 | struct tm6000_fmt { | 61 | struct tm6000_fmt { |
61 | char *name; | 62 | char *name; |
@@ -189,7 +190,9 @@ struct tm6000_core { | |||
189 | int users; | 190 | int users; |
190 | 191 | ||
191 | /* various device info */ | 192 | /* various device info */ |
192 | unsigned int resources; | 193 | struct tm6000_fh *resources; /* Points to fh that is streaming */ |
194 | bool is_res_read; | ||
195 | |||
193 | struct video_device *vfd; | 196 | struct video_device *vfd; |
194 | struct tm6000_dmaqueue vidq; | 197 | struct tm6000_dmaqueue vidq; |
195 | struct v4l2_device v4l2_dev; | 198 | struct v4l2_device v4l2_dev; |
@@ -205,6 +208,9 @@ struct tm6000_core { | |||
205 | 208 | ||
206 | /* audio support */ | 209 | /* audio support */ |
207 | struct snd_tm6000_card *adev; | 210 | struct snd_tm6000_card *adev; |
211 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ | ||
212 | atomic_t stream_started; /* stream should be running if true */ | ||
213 | |||
208 | 214 | ||
209 | struct tm6000_IR *ir; | 215 | struct tm6000_IR *ir; |
210 | 216 | ||
@@ -251,9 +257,9 @@ struct tm6000_fh { | |||
251 | enum v4l2_buf_type type; | 257 | enum v4l2_buf_type type; |
252 | }; | 258 | }; |
253 | 259 | ||
254 | #define TM6000_STD V4L2_STD_PAL|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc| \ | 260 | #define TM6000_STD (V4L2_STD_PAL|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc| \ |
255 | V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \ | 261 | V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \ |
256 | V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM | 262 | V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM) |
257 | 263 | ||
258 | /* In tm6000-cards.c */ | 264 | /* In tm6000-cards.c */ |
259 | 265 | ||
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index 3c969cdef0a..4b67b8e6030 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c | |||
@@ -358,7 +358,7 @@ int viafb_setup_engine(struct fb_info *info) | |||
358 | viapar->shared->vq_vram_addr = viapar->fbmem_free; | 358 | viapar->shared->vq_vram_addr = viapar->fbmem_free; |
359 | viapar->fbmem_used += VQ_SIZE; | 359 | viapar->fbmem_used += VQ_SIZE; |
360 | 360 | ||
361 | #if defined(CONFIG_FB_VIA_CAMERA) || defined(CONFIG_FB_VIA_CAMERA_MODULE) | 361 | #if defined(CONFIG_VIDEO_VIA_CAMERA) || defined(CONFIG_VIDEO_VIA_CAMERA_MODULE) |
362 | /* | 362 | /* |
363 | * Set aside a chunk of framebuffer memory for the camera | 363 | * Set aside a chunk of framebuffer memory for the camera |
364 | * driver. Someday this driver probably needs a proper allocator | 364 | * driver. Someday this driver probably needs a proper allocator |
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 31e30338e89..a3aa9170950 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c | |||
@@ -95,6 +95,13 @@ EXPORT_SYMBOL_GPL(viafb_irq_disable); | |||
95 | 95 | ||
96 | /* ---------------------------------------------------------------------- */ | 96 | /* ---------------------------------------------------------------------- */ |
97 | /* | 97 | /* |
98 | * Currently, the camera driver is the only user of the DMA code, so we | ||
99 | * only compile it in if the camera driver is being built. Chances are, | ||
100 | * most viafb systems will not need to have this extra code for a while. | ||
101 | * As soon as another user comes long, the ifdef can be removed. | ||
102 | */ | ||
103 | #if defined(CONFIG_VIDEO_VIA_CAMERA) || defined(CONFIG_VIDEO_VIA_CAMERA_MODULE) | ||
104 | /* | ||
98 | * Access to the DMA engine. This currently provides what the camera | 105 | * Access to the DMA engine. This currently provides what the camera |
99 | * driver needs (i.e. outgoing only) but is easily expandable if need | 106 | * driver needs (i.e. outgoing only) but is easily expandable if need |
100 | * be. | 107 | * be. |
@@ -322,7 +329,7 @@ int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg) | |||
322 | return 0; | 329 | return 0; |
323 | } | 330 | } |
324 | EXPORT_SYMBOL_GPL(viafb_dma_copy_out_sg); | 331 | EXPORT_SYMBOL_GPL(viafb_dma_copy_out_sg); |
325 | 332 | #endif /* CONFIG_VIDEO_VIA_CAMERA */ | |
326 | 333 | ||
327 | /* ---------------------------------------------------------------------- */ | 334 | /* ---------------------------------------------------------------------- */ |
328 | /* | 335 | /* |
@@ -511,7 +518,12 @@ static struct viafb_subdev_info { | |||
511 | }, | 518 | }, |
512 | { | 519 | { |
513 | .name = "viafb-i2c", | 520 | .name = "viafb-i2c", |
514 | } | 521 | }, |
522 | #if defined(CONFIG_VIDEO_VIA_CAMERA) || defined(CONFIG_VIDEO_VIA_CAMERA_MODULE) | ||
523 | { | ||
524 | .name = "viafb-camera", | ||
525 | }, | ||
526 | #endif | ||
515 | }; | 527 | }; |
516 | #define N_SUBDEVS ARRAY_SIZE(viafb_subdevs) | 528 | #define N_SUBDEVS ARRAY_SIZE(viafb_subdevs) |
517 | 529 | ||
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 831c4634162..05a59f0ce37 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -372,7 +372,6 @@ header-y += veth.h | |||
372 | header-y += vhost.h | 372 | header-y += vhost.h |
373 | header-y += videodev.h | 373 | header-y += videodev.h |
374 | header-y += videodev2.h | 374 | header-y += videodev2.h |
375 | header-y += videotext.h | ||
376 | header-y += virtio_9p.h | 375 | header-y += virtio_9p.h |
377 | header-y += virtio_balloon.h | 376 | header-y += virtio_balloon.h |
378 | header-y += virtio_blk.h | 377 | header-y += virtio_blk.h |
diff --git a/include/linux/via-core.h b/include/linux/via-core.h index 7ffb521e1a7..38bffd8ccca 100644 --- a/include/linux/via-core.h +++ b/include/linux/via-core.h | |||
@@ -81,7 +81,7 @@ struct viafb_dev { | |||
81 | unsigned long fbmem_start; | 81 | unsigned long fbmem_start; |
82 | long fbmem_len; | 82 | long fbmem_len; |
83 | void __iomem *fbmem; | 83 | void __iomem *fbmem; |
84 | #if defined(CONFIG_FB_VIA_CAMERA) || defined(CONFIG_FB_VIA_CAMERA_MODULE) | 84 | #if defined(CONFIG_VIDEO_VIA_CAMERA) || defined(CONFIG_VIDEO_VIA_CAMERA_MODULE) |
85 | long camera_fbmem_offset; | 85 | long camera_fbmem_offset; |
86 | long camera_fbmem_size; | 86 | long camera_fbmem_size; |
87 | #endif | 87 | #endif |
@@ -138,6 +138,7 @@ void viafb_irq_disable(u32 mask); | |||
138 | #define VDE_I_LVDSSIEN 0x40000000 /* LVDS Sense enable */ | 138 | #define VDE_I_LVDSSIEN 0x40000000 /* LVDS Sense enable */ |
139 | #define VDE_I_ENABLE 0x80000000 /* Global interrupt enable */ | 139 | #define VDE_I_ENABLE 0x80000000 /* Global interrupt enable */ |
140 | 140 | ||
141 | #if defined(CONFIG_VIDEO_VIA_CAMERA) || defined(CONFIG_VIDEO_VIA_CAMERA_MODULE) | ||
141 | /* | 142 | /* |
142 | * DMA management. | 143 | * DMA management. |
143 | */ | 144 | */ |
@@ -172,6 +173,7 @@ int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg); | |||
172 | */ | 173 | */ |
173 | #define VGA_WIDTH 640 | 174 | #define VGA_WIDTH 640 |
174 | #define VGA_HEIGHT 480 | 175 | #define VGA_HEIGHT 480 |
176 | #endif /* CONFIG_VIDEO_VIA_CAMERA */ | ||
175 | 177 | ||
176 | /* | 178 | /* |
177 | * Indexed port operations. Note that these are all multi-op | 179 | * Indexed port operations. Note that these are all multi-op |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 61490c6dcdb..5f6f47044ab 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
@@ -363,6 +363,8 @@ struct v4l2_pix_format { | |||
363 | #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ | 363 | #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ |
364 | #define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ | 364 | #define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ |
365 | #define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ | 365 | #define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ |
366 | #define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ | ||
367 | #define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ | ||
366 | 368 | ||
367 | /* | 369 | /* |
368 | * F O R M A T E N U M E R A T I O N | 370 | * F O R M A T E N U M E R A T I O N |
@@ -1045,8 +1047,11 @@ enum v4l2_colorfx { | |||
1045 | 1047 | ||
1046 | #define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) | 1048 | #define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) |
1047 | 1049 | ||
1050 | #define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) | ||
1051 | #define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) | ||
1052 | |||
1048 | /* last CID + 1 */ | 1053 | /* last CID + 1 */ |
1049 | #define V4L2_CID_LASTP1 (V4L2_CID_BASE+37) | 1054 | #define V4L2_CID_LASTP1 (V4L2_CID_BASE+39) |
1050 | 1055 | ||
1051 | /* MPEG-class control IDs defined by V4L2 */ | 1056 | /* MPEG-class control IDs defined by V4L2 */ |
1052 | #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) | 1057 | #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) |
@@ -1363,6 +1368,8 @@ struct v4l2_modulator { | |||
1363 | #define V4L2_TUNER_CAP_SAP 0x0020 | 1368 | #define V4L2_TUNER_CAP_SAP 0x0020 |
1364 | #define V4L2_TUNER_CAP_LANG1 0x0040 | 1369 | #define V4L2_TUNER_CAP_LANG1 0x0040 |
1365 | #define V4L2_TUNER_CAP_RDS 0x0080 | 1370 | #define V4L2_TUNER_CAP_RDS 0x0080 |
1371 | #define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 | ||
1372 | #define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 | ||
1366 | 1373 | ||
1367 | /* Flags for the 'rxsubchans' field */ | 1374 | /* Flags for the 'rxsubchans' field */ |
1368 | #define V4L2_TUNER_SUB_MONO 0x0001 | 1375 | #define V4L2_TUNER_SUB_MONO 0x0001 |
@@ -1392,7 +1399,8 @@ struct v4l2_hw_freq_seek { | |||
1392 | enum v4l2_tuner_type type; | 1399 | enum v4l2_tuner_type type; |
1393 | __u32 seek_upward; | 1400 | __u32 seek_upward; |
1394 | __u32 wrap_around; | 1401 | __u32 wrap_around; |
1395 | __u32 reserved[8]; | 1402 | __u32 spacing; |
1403 | __u32 reserved[7]; | ||
1396 | }; | 1404 | }; |
1397 | 1405 | ||
1398 | /* | 1406 | /* |
diff --git a/include/linux/videotext.h b/include/linux/videotext.h deleted file mode 100644 index 3e68c8d1c7f..00000000000 --- a/include/linux/videotext.h +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | #ifndef _VTX_H | ||
2 | #define _VTX_H | ||
3 | |||
4 | /* | ||
5 | * Teletext (=Videotext) hardware decoders using interface /dev/vtx | ||
6 | * Do not confuse with drivers using /dev/vbi which decode videotext by software | ||
7 | * | ||
8 | * Videotext IOCTLs changed in order to use _IO() macros defined in <linux/ioctl.h>, | ||
9 | * unused tuner IOCTLs cleaned up by | ||
10 | * Michael Geng <linux@MichaelGeng.de> | ||
11 | * | ||
12 | * Copyright (c) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de> | ||
13 | * Read COPYING for more information | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | |||
18 | /* | ||
19 | * Videotext ioctls | ||
20 | */ | ||
21 | #define VTXIOCGETINFO _IOR (0x81, 1, vtx_info_t) | ||
22 | #define VTXIOCCLRPAGE _IOW (0x81, 2, vtx_pagereq_t) | ||
23 | #define VTXIOCCLRFOUND _IOW (0x81, 3, vtx_pagereq_t) | ||
24 | #define VTXIOCPAGEREQ _IOW (0x81, 4, vtx_pagereq_t) | ||
25 | #define VTXIOCGETSTAT _IOW (0x81, 5, vtx_pagereq_t) | ||
26 | #define VTXIOCGETPAGE _IOW (0x81, 6, vtx_pagereq_t) | ||
27 | #define VTXIOCSTOPDAU _IOW (0x81, 7, vtx_pagereq_t) | ||
28 | #define VTXIOCPUTPAGE _IO (0x81, 8) | ||
29 | #define VTXIOCSETDISP _IO (0x81, 9) | ||
30 | #define VTXIOCPUTSTAT _IO (0x81, 10) | ||
31 | #define VTXIOCCLRCACHE _IO (0x81, 11) | ||
32 | #define VTXIOCSETVIRT _IOW (0x81, 12, long) | ||
33 | |||
34 | /* for compatibility, will go away some day */ | ||
35 | #define VTXIOCGETINFO_OLD 0x7101 /* get version of driver & capabilities of vtx-chipset */ | ||
36 | #define VTXIOCCLRPAGE_OLD 0x7102 /* clear page-buffer */ | ||
37 | #define VTXIOCCLRFOUND_OLD 0x7103 /* clear bits indicating that page was found */ | ||
38 | #define VTXIOCPAGEREQ_OLD 0x7104 /* search for page */ | ||
39 | #define VTXIOCGETSTAT_OLD 0x7105 /* get status of page-buffer */ | ||
40 | #define VTXIOCGETPAGE_OLD 0x7106 /* get contents of page-buffer */ | ||
41 | #define VTXIOCSTOPDAU_OLD 0x7107 /* stop data acquisition unit */ | ||
42 | #define VTXIOCPUTPAGE_OLD 0x7108 /* display page on TV-screen */ | ||
43 | #define VTXIOCSETDISP_OLD 0x7109 /* set TV-mode */ | ||
44 | #define VTXIOCPUTSTAT_OLD 0x710a /* set status of TV-output-buffer */ | ||
45 | #define VTXIOCCLRCACHE_OLD 0x710b /* clear cache on VTX-interface (if avail.) */ | ||
46 | #define VTXIOCSETVIRT_OLD 0x710c /* turn on virtual mode (this disables TV-display) */ | ||
47 | |||
48 | /* | ||
49 | * Definitions for VTXIOCGETINFO | ||
50 | */ | ||
51 | |||
52 | #define SAA5243 0 | ||
53 | #define SAA5246 1 | ||
54 | #define SAA5249 2 | ||
55 | #define SAA5248 3 | ||
56 | #define XSTV5346 4 | ||
57 | |||
58 | typedef struct { | ||
59 | int version_major, version_minor; /* version of driver; if version_major changes, driver */ | ||
60 | /* is not backward compatible!!! CHECK THIS!!! */ | ||
61 | int numpages; /* number of page-buffers of vtx-chipset */ | ||
62 | int cct_type; /* type of vtx-chipset (SAA5243, SAA5246, SAA5248 or | ||
63 | * SAA5249) */ | ||
64 | } | ||
65 | vtx_info_t; | ||
66 | |||
67 | |||
68 | /* | ||
69 | * Definitions for VTXIOC{CLRPAGE,CLRFOUND,PAGEREQ,GETSTAT,GETPAGE,STOPDAU,PUTPAGE,SETDISP} | ||
70 | */ | ||
71 | |||
72 | #define MIN_UNIT (1<<0) | ||
73 | #define MIN_TEN (1<<1) | ||
74 | #define HR_UNIT (1<<2) | ||
75 | #define HR_TEN (1<<3) | ||
76 | #define PG_UNIT (1<<4) | ||
77 | #define PG_TEN (1<<5) | ||
78 | #define PG_HUND (1<<6) | ||
79 | #define PGMASK_MAX (1<<7) | ||
80 | #define PGMASK_PAGE (PG_HUND | PG_TEN | PG_UNIT) | ||
81 | #define PGMASK_HOUR (HR_TEN | HR_UNIT) | ||
82 | #define PGMASK_MINUTE (MIN_TEN | MIN_UNIT) | ||
83 | |||
84 | typedef struct | ||
85 | { | ||
86 | int page; /* number of requested page (hexadecimal) */ | ||
87 | int hour; /* requested hour (hexadecimal) */ | ||
88 | int minute; /* requested minute (hexadecimal) */ | ||
89 | int pagemask; /* mask defining which values of the above are set */ | ||
90 | int pgbuf; /* buffer where page will be stored */ | ||
91 | int start; /* start of requested part of page */ | ||
92 | int end; /* end of requested part of page */ | ||
93 | void __user *buffer; /* pointer to beginning of destination buffer */ | ||
94 | } | ||
95 | vtx_pagereq_t; | ||
96 | |||
97 | |||
98 | /* | ||
99 | * Definitions for VTXIOC{GETSTAT,PUTSTAT} | ||
100 | */ | ||
101 | |||
102 | #define VTX_PAGESIZE (40 * 24) | ||
103 | #define VTX_VIRTUALSIZE (40 * 49) | ||
104 | |||
105 | typedef struct | ||
106 | { | ||
107 | int pagenum; /* number of page (hexadecimal) */ | ||
108 | int hour; /* hour (hexadecimal) */ | ||
109 | int minute; /* minute (hexadecimal) */ | ||
110 | int charset; /* national charset */ | ||
111 | unsigned delete : 1; /* delete page (C4) */ | ||
112 | unsigned headline : 1; /* insert headline (C5) */ | ||
113 | unsigned subtitle : 1; /* insert subtitle (C6) */ | ||
114 | unsigned supp_header : 1; /* suppress header (C7) */ | ||
115 | unsigned update : 1; /* update page (C8) */ | ||
116 | unsigned inter_seq : 1; /* interrupted sequence (C9) */ | ||
117 | unsigned dis_disp : 1; /* disable/suppress display (C10) */ | ||
118 | unsigned serial : 1; /* serial mode (C11) */ | ||
119 | unsigned notfound : 1; /* /FOUND */ | ||
120 | unsigned pblf : 1; /* PBLF */ | ||
121 | unsigned hamming : 1; /* hamming-error occurred */ | ||
122 | } | ||
123 | vtx_pageinfo_t; | ||
124 | |||
125 | #endif /* _VTX_H */ | ||
diff --git a/include/media/ir-core.h b/include/media/ir-core.h index eb7fddf8f60..6dc37fae660 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h | |||
@@ -60,6 +60,7 @@ enum rc_driver_type { | |||
60 | * @s_idle: optional: enable/disable hardware idle mode, upon which, | 60 | * @s_idle: optional: enable/disable hardware idle mode, upon which, |
61 | device doesn't interrupt host until it sees IR pulses | 61 | device doesn't interrupt host until it sees IR pulses |
62 | * @s_learning_mode: enable wide band receiver used for learning | 62 | * @s_learning_mode: enable wide band receiver used for learning |
63 | * @s_carrier_report: enable carrier reports | ||
63 | */ | 64 | */ |
64 | struct ir_dev_props { | 65 | struct ir_dev_props { |
65 | enum rc_driver_type driver_type; | 66 | enum rc_driver_type driver_type; |
@@ -82,8 +83,9 @@ struct ir_dev_props { | |||
82 | int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle); | 83 | int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle); |
83 | int (*s_rx_carrier_range)(void *priv, u32 min, u32 max); | 84 | int (*s_rx_carrier_range)(void *priv, u32 min, u32 max); |
84 | int (*tx_ir)(void *priv, int *txbuf, u32 n); | 85 | int (*tx_ir)(void *priv, int *txbuf, u32 n); |
85 | void (*s_idle)(void *priv, int enable); | 86 | void (*s_idle)(void *priv, bool enable); |
86 | int (*s_learning_mode)(void *priv, int enable); | 87 | int (*s_learning_mode)(void *priv, int enable); |
88 | int (*s_carrier_report) (void *priv, int enable); | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | struct ir_input_dev { | 91 | struct ir_input_dev { |
@@ -157,27 +159,54 @@ void ir_input_unregister(struct input_dev *input_dev); | |||
157 | 159 | ||
158 | void ir_repeat(struct input_dev *dev); | 160 | void ir_repeat(struct input_dev *dev); |
159 | void ir_keydown(struct input_dev *dev, int scancode, u8 toggle); | 161 | void ir_keydown(struct input_dev *dev, int scancode, u8 toggle); |
162 | void ir_keyup(struct ir_input_dev *ir); | ||
160 | u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode); | 163 | u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode); |
161 | 164 | ||
162 | /* From ir-raw-event.c */ | 165 | /* From ir-raw-event.c */ |
163 | 166 | ||
164 | struct ir_raw_event { | 167 | struct ir_raw_event { |
165 | unsigned pulse:1; | 168 | union { |
166 | unsigned duration:31; | 169 | u32 duration; |
170 | |||
171 | struct { | ||
172 | u32 carrier; | ||
173 | u8 duty_cycle; | ||
174 | }; | ||
175 | }; | ||
176 | |||
177 | unsigned pulse:1; | ||
178 | unsigned reset:1; | ||
179 | unsigned timeout:1; | ||
180 | unsigned carrier_report:1; | ||
167 | }; | 181 | }; |
168 | 182 | ||
169 | #define IR_MAX_DURATION 0x7FFFFFFF /* a bit more than 2 seconds */ | 183 | #define DEFINE_IR_RAW_EVENT(event) \ |
184 | struct ir_raw_event event = { \ | ||
185 | { .duration = 0 } , \ | ||
186 | .pulse = 0, \ | ||
187 | .reset = 0, \ | ||
188 | .timeout = 0, \ | ||
189 | .carrier_report = 0 } | ||
190 | |||
191 | static inline void init_ir_raw_event(struct ir_raw_event *ev) | ||
192 | { | ||
193 | memset(ev, 0, sizeof(*ev)); | ||
194 | } | ||
195 | |||
196 | #define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */ | ||
170 | 197 | ||
171 | void ir_raw_event_handle(struct input_dev *input_dev); | 198 | void ir_raw_event_handle(struct input_dev *input_dev); |
172 | int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); | 199 | int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); |
173 | int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); | 200 | int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); |
174 | int ir_raw_event_store_with_filter(struct input_dev *input_dev, | 201 | int ir_raw_event_store_with_filter(struct input_dev *input_dev, |
175 | struct ir_raw_event *ev); | 202 | struct ir_raw_event *ev); |
176 | void ir_raw_event_set_idle(struct input_dev *input_dev, int idle); | 203 | void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle); |
177 | 204 | ||
178 | static inline void ir_raw_event_reset(struct input_dev *input_dev) | 205 | static inline void ir_raw_event_reset(struct input_dev *input_dev) |
179 | { | 206 | { |
180 | struct ir_raw_event ev = { .pulse = false, .duration = 0 }; | 207 | DEFINE_IR_RAW_EVENT(ev); |
208 | ev.reset = true; | ||
209 | |||
181 | ir_raw_event_store(input_dev, &ev); | 210 | ir_raw_event_store(input_dev, &ev); |
182 | ir_raw_event_handle(input_dev); | 211 | ir_raw_event_handle(input_dev); |
183 | } | 212 | } |
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h index 5e96d7a430b..557c676ab7d 100644 --- a/include/media/ir-kbd-i2c.h +++ b/include/media/ir-kbd-i2c.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <media/ir-common.h> | 4 | #include <media/ir-common.h> |
5 | 5 | ||
6 | #define DEFAULT_POLLING_INTERVAL 100 /* ms */ | ||
7 | |||
6 | struct IR_i2c; | 8 | struct IR_i2c; |
7 | 9 | ||
8 | struct IR_i2c { | 10 | struct IR_i2c { |
@@ -15,6 +17,8 @@ struct IR_i2c { | |||
15 | /* Used to avoid fast repeating */ | 17 | /* Used to avoid fast repeating */ |
16 | unsigned char old; | 18 | unsigned char old; |
17 | 19 | ||
20 | u32 polling_interval; /* in ms */ | ||
21 | |||
18 | struct delayed_work work; | 22 | struct delayed_work work; |
19 | char name[32]; | 23 | char name[32]; |
20 | char phys[32]; | 24 | char phys[32]; |
@@ -24,7 +28,6 @@ struct IR_i2c { | |||
24 | enum ir_kbd_get_key_fn { | 28 | enum ir_kbd_get_key_fn { |
25 | IR_KBD_GET_KEY_CUSTOM = 0, | 29 | IR_KBD_GET_KEY_CUSTOM = 0, |
26 | IR_KBD_GET_KEY_PIXELVIEW, | 30 | IR_KBD_GET_KEY_PIXELVIEW, |
27 | IR_KBD_GET_KEY_PV951, | ||
28 | IR_KBD_GET_KEY_HAUP, | 31 | IR_KBD_GET_KEY_HAUP, |
29 | IR_KBD_GET_KEY_KNC1, | 32 | IR_KBD_GET_KEY_KNC1, |
30 | IR_KBD_GET_KEY_FUSIONHDTV, | 33 | IR_KBD_GET_KEY_FUSIONHDTV, |
@@ -35,8 +38,9 @@ enum ir_kbd_get_key_fn { | |||
35 | /* Can be passed when instantiating an ir_video i2c device */ | 38 | /* Can be passed when instantiating an ir_video i2c device */ |
36 | struct IR_i2c_init_data { | 39 | struct IR_i2c_init_data { |
37 | char *ir_codes; | 40 | char *ir_codes; |
38 | const char *name; | 41 | const char *name; |
39 | u64 type; /* IR_TYPE_RC5, etc */ | 42 | u64 type; /* IR_TYPE_RC5, etc */ |
43 | u32 polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */ | ||
40 | /* | 44 | /* |
41 | * Specify either a function pointer or a value indicating one of | 45 | * Specify either a function pointer or a value indicating one of |
42 | * ir_kbd_i2c's internal get_key functions | 46 | * ir_kbd_i2c's internal get_key functions |
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index b1f60663cb3..54780a560d0 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h | |||
@@ -125,10 +125,10 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, | |||
125 | struct lirc_driver { | 125 | struct lirc_driver { |
126 | char name[40]; | 126 | char name[40]; |
127 | int minor; | 127 | int minor; |
128 | unsigned long code_length; | 128 | __u32 code_length; |
129 | unsigned int buffer_size; /* in chunks holding one code each */ | 129 | unsigned int buffer_size; /* in chunks holding one code each */ |
130 | int sample_rate; | 130 | int sample_rate; |
131 | unsigned long features; | 131 | __u32 features; |
132 | 132 | ||
133 | unsigned int chunk_size; | 133 | unsigned int chunk_size; |
134 | 134 | ||
@@ -139,7 +139,7 @@ struct lirc_driver { | |||
139 | struct lirc_buffer *rbuf; | 139 | struct lirc_buffer *rbuf; |
140 | int (*set_use_inc) (void *data); | 140 | int (*set_use_inc) (void *data); |
141 | void (*set_use_dec) (void *data); | 141 | void (*set_use_dec) (void *data); |
142 | struct file_operations *fops; | 142 | const struct file_operations *fops; |
143 | struct device *dev; | 143 | struct device *dev; |
144 | struct module *owner; | 144 | struct module *owner; |
145 | }; | 145 | }; |
diff --git a/include/media/omap1_camera.h b/include/media/omap1_camera.h new file mode 100644 index 00000000000..819767cf04d --- /dev/null +++ b/include/media/omap1_camera.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Header for V4L2 SoC Camera driver for OMAP1 Camera Interface | ||
3 | * | ||
4 | * Copyright (C) 2010, Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __MEDIA_OMAP1_CAMERA_H_ | ||
12 | #define __MEDIA_OMAP1_CAMERA_H_ | ||
13 | |||
14 | #include <linux/bitops.h> | ||
15 | |||
16 | #define OMAP1_CAMERA_IOSIZE 0x1c | ||
17 | |||
18 | enum omap1_cam_vb_mode { | ||
19 | OMAP1_CAM_DMA_CONTIG = 0, | ||
20 | OMAP1_CAM_DMA_SG, | ||
21 | }; | ||
22 | |||
23 | #define OMAP1_CAMERA_MIN_BUF_COUNT(x) ((x) == OMAP1_CAM_DMA_CONTIG ? 3 : 2) | ||
24 | |||
25 | struct omap1_cam_platform_data { | ||
26 | unsigned long camexclk_khz; | ||
27 | unsigned long lclk_khz_max; | ||
28 | unsigned long flags; | ||
29 | }; | ||
30 | |||
31 | #define OMAP1_CAMERA_LCLK_RISING BIT(0) | ||
32 | #define OMAP1_CAMERA_RST_LOW BIT(1) | ||
33 | #define OMAP1_CAMERA_RST_HIGH BIT(2) | ||
34 | |||
35 | #endif /* __MEDIA_OMAP1_CAMERA_H_ */ | ||
diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 9b201ec8dc7..e0f17edf38e 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h | |||
@@ -17,12 +17,13 @@ | |||
17 | #define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */ | 17 | #define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */ |
18 | #define IR_TYPE_JVC (1 << 3) /* JVC protocol */ | 18 | #define IR_TYPE_JVC (1 << 3) /* JVC protocol */ |
19 | #define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */ | 19 | #define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */ |
20 | #define IR_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */ | ||
20 | #define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */ | 21 | #define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */ |
21 | #define IR_TYPE_OTHER (1u << 31) | 22 | #define IR_TYPE_OTHER (1u << 31) |
22 | 23 | ||
23 | #define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \ | 24 | #define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \ |
24 | IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \ | 25 | IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \ |
25 | IR_TYPE_OTHER) | 26 | IR_TYPE_RC5_SZ | IR_TYPE_OTHER) |
26 | 27 | ||
27 | struct ir_scancode { | 28 | struct ir_scancode { |
28 | u32 scancode; | 29 | u32 scancode; |
@@ -54,6 +55,8 @@ void rc_map_init(void); | |||
54 | /* Names of the several keytables defined in-kernel */ | 55 | /* Names of the several keytables defined in-kernel */ |
55 | 56 | ||
56 | #define RC_MAP_ADSTECH_DVB_T_PCI "rc-adstech-dvb-t-pci" | 57 | #define RC_MAP_ADSTECH_DVB_T_PCI "rc-adstech-dvb-t-pci" |
58 | #define RC_MAP_ALINK_DTU_M "rc-alink-dtu-m" | ||
59 | #define RC_MAP_ANYSEE "rc-anysee" | ||
57 | #define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp" | 60 | #define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp" |
58 | #define RC_MAP_ASUS_PC39 "rc-asus-pc39" | 61 | #define RC_MAP_ASUS_PC39 "rc-asus-pc39" |
59 | #define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600" | 62 | #define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600" |
@@ -62,8 +65,10 @@ void rc_map_init(void); | |||
62 | #define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" | 65 | #define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" |
63 | #define RC_MAP_AVERMEDIA_M135A "rc-avermedia-m135a" | 66 | #define RC_MAP_AVERMEDIA_M135A "rc-avermedia-m135a" |
64 | #define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6" | 67 | #define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6" |
68 | #define RC_MAP_AVERMEDIA_RM_KS "rc-avermedia-rm-ks" | ||
65 | #define RC_MAP_AVERMEDIA "rc-avermedia" | 69 | #define RC_MAP_AVERMEDIA "rc-avermedia" |
66 | #define RC_MAP_AVERTV_303 "rc-avertv-303" | 70 | #define RC_MAP_AVERTV_303 "rc-avertv-303" |
71 | #define RC_MAP_AZUREWAVE_AD_TU700 "rc-azurewave-ad-tu700" | ||
67 | #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" | 72 | #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" |
68 | #define RC_MAP_BEHOLD "rc-behold" | 73 | #define RC_MAP_BEHOLD "rc-behold" |
69 | #define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old" | 74 | #define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old" |
@@ -71,6 +76,8 @@ void rc_map_init(void); | |||
71 | #define RC_MAP_CINERGY "rc-cinergy" | 76 | #define RC_MAP_CINERGY "rc-cinergy" |
72 | #define RC_MAP_DIB0700_NEC_TABLE "rc-dib0700-nec" | 77 | #define RC_MAP_DIB0700_NEC_TABLE "rc-dib0700-nec" |
73 | #define RC_MAP_DIB0700_RC5_TABLE "rc-dib0700-rc5" | 78 | #define RC_MAP_DIB0700_RC5_TABLE "rc-dib0700-rc5" |
79 | #define RC_MAP_DIGITALNOW_TINYTWIN "rc-digitalnow-tinytwin" | ||
80 | #define RC_MAP_DIGITTRADE "rc-digittrade" | ||
74 | #define RC_MAP_DM1105_NEC "rc-dm1105-nec" | 81 | #define RC_MAP_DM1105_NEC "rc-dm1105-nec" |
75 | #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro" | 82 | #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro" |
76 | #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t" | 83 | #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t" |
@@ -94,8 +101,12 @@ void rc_map_init(void); | |||
94 | #define RC_MAP_KAIOMY "rc-kaiomy" | 101 | #define RC_MAP_KAIOMY "rc-kaiomy" |
95 | #define RC_MAP_KWORLD_315U "rc-kworld-315u" | 102 | #define RC_MAP_KWORLD_315U "rc-kworld-315u" |
96 | #define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog" | 103 | #define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog" |
104 | #define RC_MAP_LEADTEK_Y04G0051 "rc-leadtek-y04g0051" | ||
97 | #define RC_MAP_LIRC "rc-lirc" | 105 | #define RC_MAP_LIRC "rc-lirc" |
106 | #define RC_MAP_LME2510 "rc-lme2510" | ||
98 | #define RC_MAP_MANLI "rc-manli" | 107 | #define RC_MAP_MANLI "rc-manli" |
108 | #define RC_MAP_MSI_DIGIVOX_II "rc-msi-digivox-ii" | ||
109 | #define RC_MAP_MSI_DIGIVOX_III "rc-msi-digivox-iii" | ||
99 | #define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus" | 110 | #define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus" |
100 | #define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere" | 111 | #define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere" |
101 | #define RC_MAP_NEBULA "rc-nebula" | 112 | #define RC_MAP_NEBULA "rc-nebula" |
@@ -114,14 +125,18 @@ void rc_map_init(void); | |||
114 | #define RC_MAP_PURPLETV "rc-purpletv" | 125 | #define RC_MAP_PURPLETV "rc-purpletv" |
115 | #define RC_MAP_PV951 "rc-pv951" | 126 | #define RC_MAP_PV951 "rc-pv951" |
116 | #define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new" | 127 | #define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new" |
117 | #define RC_MAP_RC5_STREAMZAP "rc-rc5-streamzap" | ||
118 | #define RC_MAP_RC5_TV "rc-rc5-tv" | 128 | #define RC_MAP_RC5_TV "rc-rc5-tv" |
119 | #define RC_MAP_RC6_MCE "rc-rc6-mce" | 129 | #define RC_MAP_RC6_MCE "rc-rc6-mce" |
120 | #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" | 130 | #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" |
131 | #define RC_MAP_STREAMZAP "rc-streamzap" | ||
121 | #define RC_MAP_TBS_NEC "rc-tbs-nec" | 132 | #define RC_MAP_TBS_NEC "rc-tbs-nec" |
122 | #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" | 133 | #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" |
134 | #define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" | ||
123 | #define RC_MAP_TEVII_NEC "rc-tevii-nec" | 135 | #define RC_MAP_TEVII_NEC "rc-tevii-nec" |
136 | #define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand" | ||
137 | #define RC_MAP_TREKSTOR "rc-trekstor" | ||
124 | #define RC_MAP_TT_1500 "rc-tt-1500" | 138 | #define RC_MAP_TT_1500 "rc-tt-1500" |
139 | #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" | ||
125 | #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" | 140 | #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" |
126 | #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" | 141 | #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" |
127 | #define RC_MAP_WINFAST "rc-winfast" | 142 | #define RC_MAP_WINFAST "rc-winfast" |
diff --git a/include/media/s3c_fimc.h b/include/media/s3c_fimc.h new file mode 100644 index 00000000000..ca1b6738e4a --- /dev/null +++ b/include/media/s3c_fimc.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Samsung S5P SoC camera interface driver header | ||
3 | * | ||
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd | ||
5 | * Author: Sylwester Nawrocki, <s.nawrocki@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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef S3C_FIMC_H_ | ||
13 | #define S3C_FIMC_H_ | ||
14 | |||
15 | enum cam_bus_type { | ||
16 | FIMC_ITU_601 = 1, | ||
17 | FIMC_ITU_656, | ||
18 | FIMC_MIPI_CSI2, | ||
19 | FIMC_LCD_WB, /* FIFO link from LCD mixer */ | ||
20 | }; | ||
21 | |||
22 | #define FIMC_CLK_INV_PCLK (1 << 0) | ||
23 | #define FIMC_CLK_INV_VSYNC (1 << 1) | ||
24 | #define FIMC_CLK_INV_HREF (1 << 2) | ||
25 | #define FIMC_CLK_INV_HSYNC (1 << 3) | ||
26 | |||
27 | struct i2c_board_info; | ||
28 | |||
29 | /** | ||
30 | * struct s3c_fimc_isp_info - image sensor information required for host | ||
31 | * interace configuration. | ||
32 | * | ||
33 | * @board_info: pointer to I2C subdevice's board info | ||
34 | * @bus_type: determines bus type, MIPI, ITU-R BT.601 etc. | ||
35 | * @i2c_bus_num: i2c control bus id the sensor is attached to | ||
36 | * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) | ||
37 | * @bus_width: camera data bus width in bits | ||
38 | * @flags: flags defining bus signals polarity inversion (High by default) | ||
39 | */ | ||
40 | struct s3c_fimc_isp_info { | ||
41 | struct i2c_board_info *board_info; | ||
42 | enum cam_bus_type bus_type; | ||
43 | u16 i2c_bus_num; | ||
44 | u16 mux_id; | ||
45 | u16 bus_width; | ||
46 | u16 flags; | ||
47 | }; | ||
48 | |||
49 | |||
50 | #define FIMC_MAX_CAMIF_CLIENTS 2 | ||
51 | |||
52 | /** | ||
53 | * struct s3c_platform_fimc - camera host interface platform data | ||
54 | * | ||
55 | * @isp_info: properties of camera sensor required for host interface setup | ||
56 | */ | ||
57 | struct s3c_platform_fimc { | ||
58 | struct s3c_fimc_isp_info *isp_info[FIMC_MAX_CAMIF_CLIENTS]; | ||
59 | }; | ||
60 | #endif /* S3C_FIMC_H_ */ | ||
diff --git a/include/media/sh_vou.h b/include/media/sh_vou.h index a3ef30242b0..ec3ba9a597a 100644 --- a/include/media/sh_vou.h +++ b/include/media/sh_vou.h | |||
@@ -28,7 +28,6 @@ struct sh_vou_pdata { | |||
28 | int i2c_adap; | 28 | int i2c_adap; |
29 | struct i2c_board_info *board_info; | 29 | struct i2c_board_info *board_info; |
30 | unsigned long flags; | 30 | unsigned long flags; |
31 | char *module_name; | ||
32 | }; | 31 | }; |
33 | 32 | ||
34 | #endif | 33 | #endif |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 2ce957301f7..86e3631764e 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | extern struct bus_type soc_camera_bus_type; | 22 | extern struct bus_type soc_camera_bus_type; |
23 | 23 | ||
24 | struct file; | ||
25 | |||
24 | struct soc_camera_device { | 26 | struct soc_camera_device { |
25 | struct list_head list; | 27 | struct list_head list; |
26 | struct device dev; | 28 | struct device dev; |
@@ -41,10 +43,7 @@ struct soc_camera_device { | |||
41 | /* soc_camera.c private count. Only accessed with .video_lock held */ | 43 | /* soc_camera.c private count. Only accessed with .video_lock held */ |
42 | int use_count; | 44 | int use_count; |
43 | struct mutex video_lock; /* Protects device data */ | 45 | struct mutex video_lock; /* Protects device data */ |
44 | }; | 46 | struct file *streamer; /* stream owner */ |
45 | |||
46 | struct soc_camera_file { | ||
47 | struct soc_camera_device *icd; | ||
48 | struct videobuf_queue vb_vidq; | 47 | struct videobuf_queue vb_vidq; |
49 | }; | 48 | }; |
50 | 49 | ||
@@ -79,7 +78,7 @@ struct soc_camera_host_ops { | |||
79 | int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); | 78 | int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); |
80 | void (*init_videobuf)(struct videobuf_queue *, | 79 | void (*init_videobuf)(struct videobuf_queue *, |
81 | struct soc_camera_device *); | 80 | struct soc_camera_device *); |
82 | int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); | 81 | int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); |
83 | int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); | 82 | int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); |
84 | int (*set_bus_param)(struct soc_camera_device *, __u32); | 83 | int (*set_bus_param)(struct soc_camera_device *, __u32); |
85 | int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); | 84 | int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); |
diff --git a/include/media/sr030pc30.h b/include/media/sr030pc30.h new file mode 100644 index 00000000000..6f901a653ba --- /dev/null +++ b/include/media/sr030pc30.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Driver header for SR030PC30 camera sensor | ||
3 | * | ||
4 | * Copyright (c) 2010 Samsung Electronics, Co. Ltd | ||
5 | * Contact: Sylwester Nawrocki <s.nawrocki@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 | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef SR030PC30_H | ||
14 | #define SR030PC30_H | ||
15 | |||
16 | struct sr030pc30_platform_data { | ||
17 | unsigned long clk_rate; /* master clock frequency in Hz */ | ||
18 | int (*set_power)(struct device *dev, int on); | ||
19 | }; | ||
20 | |||
21 | #endif /* SR030PC30_H */ | ||
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 21b4428c12a..51e89f2267b 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h | |||
@@ -38,6 +38,9 @@ enum { | |||
38 | /* module tvaudio: reserved range 50-99 */ | 38 | /* module tvaudio: reserved range 50-99 */ |
39 | V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */ | 39 | V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */ |
40 | 40 | ||
41 | /* Sony IMX074 */ | ||
42 | V4L2_IDENT_IMX074 = 74, | ||
43 | |||
41 | /* module saa7110: just ident 100 */ | 44 | /* module saa7110: just ident 100 */ |
42 | V4L2_IDENT_SAA7110 = 100, | 45 | V4L2_IDENT_SAA7110 = 100, |
43 | 46 | ||
@@ -70,6 +73,7 @@ enum { | |||
70 | V4L2_IDENT_OV9655 = 255, | 73 | V4L2_IDENT_OV9655 = 255, |
71 | V4L2_IDENT_SOI968 = 256, | 74 | V4L2_IDENT_SOI968 = 256, |
72 | V4L2_IDENT_OV9640 = 257, | 75 | V4L2_IDENT_OV9640 = 257, |
76 | V4L2_IDENT_OV6650 = 258, | ||
73 | 77 | ||
74 | /* module saa7146: reserved range 300-309 */ | 78 | /* module saa7146: reserved range 300-309 */ |
75 | V4L2_IDENT_SAA7146 = 300, | 79 | V4L2_IDENT_SAA7146 = 300, |
@@ -111,6 +115,10 @@ enum { | |||
111 | V4L2_IDENT_VPX3216B = 3216, | 115 | V4L2_IDENT_VPX3216B = 3216, |
112 | V4L2_IDENT_VPX3220A = 3220, | 116 | V4L2_IDENT_VPX3220A = 3220, |
113 | 117 | ||
118 | /* VX855 just ident 3409 */ | ||
119 | /* Other via devs could use 3314, 3324, 3327, 3336, 3364, 3353 */ | ||
120 | V4L2_IDENT_VIA_VX855 = 3409, | ||
121 | |||
114 | /* module tvp5150 */ | 122 | /* module tvp5150 */ |
115 | V4L2_IDENT_TVP5150 = 5150, | 123 | V4L2_IDENT_TVP5150 = 5150, |
116 | 124 | ||
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 98b32645e5a..41dd480e45f 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
@@ -232,4 +232,14 @@ void v4l_bound_align_image(unsigned int *w, unsigned int wmin, | |||
232 | unsigned int hmax, unsigned int halign, | 232 | unsigned int hmax, unsigned int halign, |
233 | unsigned int salign); | 233 | unsigned int salign); |
234 | int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info); | 234 | int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info); |
235 | |||
236 | struct v4l2_discrete_probe { | ||
237 | const struct v4l2_frmsize_discrete *sizes; | ||
238 | int num_sizes; | ||
239 | }; | ||
240 | |||
241 | const struct v4l2_frmsize_discrete *v4l2_find_nearest_format( | ||
242 | const struct v4l2_discrete_probe *probe, | ||
243 | s32 width, s32 height); | ||
244 | |||
235 | #endif /* V4L2_COMMON_H_ */ | 245 | #endif /* V4L2_COMMON_H_ */ |
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 1efcacbed01..15802a067a1 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -21,8 +21,7 @@ | |||
21 | #define VFL_TYPE_GRABBER 0 | 21 | #define VFL_TYPE_GRABBER 0 |
22 | #define VFL_TYPE_VBI 1 | 22 | #define VFL_TYPE_VBI 1 |
23 | #define VFL_TYPE_RADIO 2 | 23 | #define VFL_TYPE_RADIO 2 |
24 | #define VFL_TYPE_VTX 3 | 24 | #define VFL_TYPE_MAX 3 |
25 | #define VFL_TYPE_MAX 4 | ||
26 | 25 | ||
27 | struct v4l2_ioctl_callbacks; | 26 | struct v4l2_ioctl_callbacks; |
28 | struct video_device; | 27 | struct video_device; |
@@ -42,8 +41,6 @@ struct v4l2_file_operations { | |||
42 | unsigned int (*poll) (struct file *, struct poll_table_struct *); | 41 | unsigned int (*poll) (struct file *, struct poll_table_struct *); |
43 | long (*ioctl) (struct file *, unsigned int, unsigned long); | 42 | long (*ioctl) (struct file *, unsigned int, unsigned long); |
44 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); | 43 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); |
45 | unsigned long (*get_unmapped_area) (struct file *, unsigned long, | ||
46 | unsigned long, unsigned long, unsigned long); | ||
47 | int (*mmap) (struct file *, struct vm_area_struct *); | 44 | int (*mmap) (struct file *, struct vm_area_struct *); |
48 | int (*open) (struct file *); | 45 | int (*open) (struct file *); |
49 | int (*release) (struct file *); | 46 | int (*release) (struct file *); |
@@ -97,6 +94,9 @@ struct video_device | |||
97 | 94 | ||
98 | /* ioctl callbacks */ | 95 | /* ioctl callbacks */ |
99 | const struct v4l2_ioctl_ops *ioctl_ops; | 96 | const struct v4l2_ioctl_ops *ioctl_ops; |
97 | |||
98 | /* serialization lock */ | ||
99 | struct mutex *lock; | ||
100 | }; | 100 | }; |
101 | 101 | ||
102 | /* dev to video-device */ | 102 | /* dev to video-device */ |
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 8bcbd7a0271..6648036b728 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h | |||
@@ -101,46 +101,67 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); | |||
101 | /* Call the specified callback for all subdevs matching the condition. | 101 | /* Call the specified callback for all subdevs matching the condition. |
102 | Ignore any errors. Note that you cannot add or delete a subdev | 102 | Ignore any errors. Note that you cannot add or delete a subdev |
103 | while walking the subdevs list. */ | 103 | while walking the subdevs list. */ |
104 | #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ | 104 | #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \ |
105 | do { \ | 105 | do { \ |
106 | struct v4l2_subdev *sd; \ | 106 | list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) \ |
107 | if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ | ||
108 | (sd)->ops->o->f((sd) , ##args); \ | ||
109 | } while (0) | ||
110 | |||
111 | #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ | ||
112 | do { \ | ||
113 | struct v4l2_subdev *__sd; \ | ||
107 | \ | 114 | \ |
108 | list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) \ | 115 | __v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o, \ |
109 | if ((cond) && sd->ops->o && sd->ops->o->f) \ | 116 | f , ##args); \ |
110 | sd->ops->o->f(sd , ##args); \ | ||
111 | } while (0) | 117 | } while (0) |
112 | 118 | ||
113 | /* Call the specified callback for all subdevs matching the condition. | 119 | /* Call the specified callback for all subdevs matching the condition. |
114 | If the callback returns an error other than 0 or -ENOIOCTLCMD, then | 120 | If the callback returns an error other than 0 or -ENOIOCTLCMD, then |
115 | return with that error code. Note that you cannot add or delete a | 121 | return with that error code. Note that you cannot add or delete a |
116 | subdev while walking the subdevs list. */ | 122 | subdev while walking the subdevs list. */ |
117 | #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ | 123 | #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \ |
118 | ({ \ | 124 | ({ \ |
119 | struct v4l2_subdev *sd; \ | 125 | long __err = 0; \ |
120 | long err = 0; \ | ||
121 | \ | 126 | \ |
122 | list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) { \ | 127 | list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) { \ |
123 | if ((cond) && sd->ops->o && sd->ops->o->f) \ | 128 | if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ |
124 | err = sd->ops->o->f(sd , ##args); \ | 129 | __err = (sd)->ops->o->f((sd) , ##args); \ |
125 | if (err && err != -ENOIOCTLCMD) \ | 130 | if (__err && __err != -ENOIOCTLCMD) \ |
126 | break; \ | 131 | break; \ |
127 | } \ | 132 | } \ |
128 | (err == -ENOIOCTLCMD) ? 0 : err; \ | 133 | (__err == -ENOIOCTLCMD) ? 0 : __err; \ |
134 | }) | ||
135 | |||
136 | #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ | ||
137 | ({ \ | ||
138 | struct v4l2_subdev *__sd; \ | ||
139 | __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \ | ||
140 | f, args...); \ | ||
129 | }) | 141 | }) |
130 | 142 | ||
131 | /* Call the specified callback for all subdevs matching grp_id (if 0, then | 143 | /* Call the specified callback for all subdevs matching grp_id (if 0, then |
132 | match them all). Ignore any errors. Note that you cannot add or delete | 144 | match them all). Ignore any errors. Note that you cannot add or delete |
133 | a subdev while walking the subdevs list. */ | 145 | a subdev while walking the subdevs list. */ |
134 | #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ | 146 | #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ |
135 | __v4l2_device_call_subdevs(v4l2_dev, \ | 147 | do { \ |
136 | !(grpid) || sd->grp_id == (grpid), o, f , ##args) | 148 | struct v4l2_subdev *__sd; \ |
149 | \ | ||
150 | __v4l2_device_call_subdevs_p(v4l2_dev, __sd, \ | ||
151 | !(grpid) || __sd->grp_id == (grpid), o, f , \ | ||
152 | ##args); \ | ||
153 | } while (0) | ||
137 | 154 | ||
138 | /* Call the specified callback for all subdevs matching grp_id (if 0, then | 155 | /* Call the specified callback for all subdevs matching grp_id (if 0, then |
139 | match them all). If the callback returns an error other than 0 or | 156 | match them all). If the callback returns an error other than 0 or |
140 | -ENOIOCTLCMD, then return with that error code. Note that you cannot | 157 | -ENOIOCTLCMD, then return with that error code. Note that you cannot |
141 | add or delete a subdev while walking the subdevs list. */ | 158 | add or delete a subdev while walking the subdevs list. */ |
142 | #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ | 159 | #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ |
143 | __v4l2_device_call_subdevs_until_err(v4l2_dev, \ | 160 | ({ \ |
144 | !(grpid) || sd->grp_id == (grpid), o, f , ##args) | 161 | struct v4l2_subdev *__sd; \ |
162 | __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ | ||
163 | !(grpid) || __sd->grp_id == (grpid), o, f , \ | ||
164 | ##args); \ | ||
165 | }) | ||
145 | 166 | ||
146 | #endif | 167 | #endif |
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h deleted file mode 100644 index 74bf741d1a9..00000000000 --- a/include/media/v4l2-i2c-drv.h +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* | ||
2 | * v4l2-i2c-drv.h - contains I2C handling code that's identical for | ||
3 | * all V4L2 I2C drivers. Use this header if the | ||
4 | * I2C driver is only used by drivers converted | ||
5 | * to the bus-based I2C API. | ||
6 | * | ||
7 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | /* NOTE: the full version of this header is in the v4l-dvb repository | ||
25 | * and allows v4l i2c drivers to be compiled on pre-2.6.26 kernels. | ||
26 | * The version of this header as it appears in the kernel is a stripped | ||
27 | * version (without all the backwards compatibility stuff) and so it | ||
28 | * looks a bit odd. | ||
29 | * | ||
30 | * If you look at the full version then you will understand the reason | ||
31 | * for introducing this header since you really don't want to have all | ||
32 | * the tricky backwards compatibility code in each and every i2c driver. | ||
33 | * | ||
34 | * If the i2c driver will never be compiled for pre-2.6.26 kernels, then | ||
35 | * DO NOT USE this header! Just write it as a regular i2c driver. | ||
36 | */ | ||
37 | |||
38 | #ifndef __V4L2_I2C_DRV_H__ | ||
39 | #define __V4L2_I2C_DRV_H__ | ||
40 | |||
41 | #include <media/v4l2-common.h> | ||
42 | |||
43 | struct v4l2_i2c_driver_data { | ||
44 | const char * const name; | ||
45 | int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); | ||
46 | int (*probe)(struct i2c_client *client, const struct i2c_device_id *id); | ||
47 | int (*remove)(struct i2c_client *client); | ||
48 | int (*suspend)(struct i2c_client *client, pm_message_t state); | ||
49 | int (*resume)(struct i2c_client *client); | ||
50 | const struct i2c_device_id *id_table; | ||
51 | }; | ||
52 | |||
53 | static struct v4l2_i2c_driver_data v4l2_i2c_data; | ||
54 | static struct i2c_driver v4l2_i2c_driver; | ||
55 | |||
56 | |||
57 | /* Bus-based I2C implementation for kernels >= 2.6.26 */ | ||
58 | |||
59 | static int __init v4l2_i2c_drv_init(void) | ||
60 | { | ||
61 | v4l2_i2c_driver.driver.name = v4l2_i2c_data.name; | ||
62 | v4l2_i2c_driver.command = v4l2_i2c_data.command; | ||
63 | v4l2_i2c_driver.probe = v4l2_i2c_data.probe; | ||
64 | v4l2_i2c_driver.remove = v4l2_i2c_data.remove; | ||
65 | v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend; | ||
66 | v4l2_i2c_driver.resume = v4l2_i2c_data.resume; | ||
67 | v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table; | ||
68 | return i2c_add_driver(&v4l2_i2c_driver); | ||
69 | } | ||
70 | |||
71 | |||
72 | static void __exit v4l2_i2c_drv_cleanup(void) | ||
73 | { | ||
74 | i2c_del_driver(&v4l2_i2c_driver); | ||
75 | } | ||
76 | |||
77 | module_init(v4l2_i2c_drv_init); | ||
78 | module_exit(v4l2_i2c_drv_cleanup); | ||
79 | |||
80 | #endif /* __V4L2_I2C_DRV_H__ */ | ||
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index f0cf2e7def0..8e6559838ae 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h | |||
@@ -28,10 +28,18 @@ enum v4l2_mbus_pixelcode { | |||
28 | V4L2_MBUS_FMT_YVYU8_2X8, | 28 | V4L2_MBUS_FMT_YVYU8_2X8, |
29 | V4L2_MBUS_FMT_UYVY8_2X8, | 29 | V4L2_MBUS_FMT_UYVY8_2X8, |
30 | V4L2_MBUS_FMT_VYUY8_2X8, | 30 | V4L2_MBUS_FMT_VYUY8_2X8, |
31 | V4L2_MBUS_FMT_YVYU10_2X10, | ||
32 | V4L2_MBUS_FMT_YUYV10_2X10, | ||
33 | V4L2_MBUS_FMT_YVYU10_1X20, | ||
34 | V4L2_MBUS_FMT_YUYV10_1X20, | ||
35 | V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, | ||
36 | V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, | ||
31 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, | 37 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, |
32 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, | 38 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, |
33 | V4L2_MBUS_FMT_RGB565_2X8_LE, | 39 | V4L2_MBUS_FMT_RGB565_2X8_LE, |
34 | V4L2_MBUS_FMT_RGB565_2X8_BE, | 40 | V4L2_MBUS_FMT_RGB565_2X8_BE, |
41 | V4L2_MBUS_FMT_BGR565_2X8_LE, | ||
42 | V4L2_MBUS_FMT_BGR565_2X8_BE, | ||
35 | V4L2_MBUS_FMT_SBGGR8_1X8, | 43 | V4L2_MBUS_FMT_SBGGR8_1X8, |
36 | V4L2_MBUS_FMT_SBGGR10_1X10, | 44 | V4L2_MBUS_FMT_SBGGR10_1X10, |
37 | V4L2_MBUS_FMT_GREY8_1X8, | 45 | V4L2_MBUS_FMT_GREY8_1X8, |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 4a97d7341a9..b0316a7cf08 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
@@ -256,10 +256,6 @@ struct v4l2_subdev_video_ops { | |||
256 | int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); | 256 | int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); |
257 | int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); | 257 | int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); |
258 | int (*s_stream)(struct v4l2_subdev *sd, int enable); | 258 | int (*s_stream)(struct v4l2_subdev *sd, int enable); |
259 | int (*enum_fmt)(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmtdesc); | ||
260 | int (*g_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); | ||
261 | int (*try_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); | ||
262 | int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); | ||
263 | int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); | 259 | int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); |
264 | int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); | 260 | int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); |
265 | int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); | 261 | int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); |
@@ -442,17 +438,28 @@ struct v4l2_subdev { | |||
442 | /* can be used to group similar subdevs, value is driver-specific */ | 438 | /* can be used to group similar subdevs, value is driver-specific */ |
443 | u32 grp_id; | 439 | u32 grp_id; |
444 | /* pointer to private data */ | 440 | /* pointer to private data */ |
445 | void *priv; | 441 | void *dev_priv; |
442 | void *host_priv; | ||
446 | }; | 443 | }; |
447 | 444 | ||
448 | static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) | 445 | static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) |
449 | { | 446 | { |
450 | sd->priv = p; | 447 | sd->dev_priv = p; |
451 | } | 448 | } |
452 | 449 | ||
453 | static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) | 450 | static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) |
454 | { | 451 | { |
455 | return sd->priv; | 452 | return sd->dev_priv; |
453 | } | ||
454 | |||
455 | static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p) | ||
456 | { | ||
457 | sd->host_priv = p; | ||
458 | } | ||
459 | |||
460 | static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd) | ||
461 | { | ||
462 | return sd->host_priv; | ||
456 | } | 463 | } |
457 | 464 | ||
458 | static inline void v4l2_subdev_init(struct v4l2_subdev *sd, | 465 | static inline void v4l2_subdev_init(struct v4l2_subdev *sd, |
@@ -466,7 +473,8 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, | |||
466 | sd->flags = 0; | 473 | sd->flags = 0; |
467 | sd->name[0] = '\0'; | 474 | sd->name[0] = '\0'; |
468 | sd->grp_id = 0; | 475 | sd->grp_id = 0; |
469 | sd->priv = NULL; | 476 | sd->dev_priv = NULL; |
477 | sd->host_priv = NULL; | ||
470 | } | 478 | } |
471 | 479 | ||
472 | /* Call an ops of a v4l2_subdev, doing the right checks against | 480 | /* Call an ops of a v4l2_subdev, doing the right checks against |
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index f2c41cebf45..1d3835fc26b 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h | |||
@@ -139,6 +139,7 @@ struct videobuf_qtype_ops { | |||
139 | 139 | ||
140 | struct videobuf_queue { | 140 | struct videobuf_queue { |
141 | struct mutex vb_lock; | 141 | struct mutex vb_lock; |
142 | struct mutex *ext_lock; | ||
142 | spinlock_t *irqlock; | 143 | spinlock_t *irqlock; |
143 | struct device *dev; | 144 | struct device *dev; |
144 | 145 | ||
@@ -167,7 +168,20 @@ struct videobuf_queue { | |||
167 | void *priv_data; | 168 | void *priv_data; |
168 | }; | 169 | }; |
169 | 170 | ||
170 | int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); | 171 | static inline void videobuf_queue_lock(struct videobuf_queue *q) |
172 | { | ||
173 | if (!q->ext_lock) | ||
174 | mutex_lock(&q->vb_lock); | ||
175 | } | ||
176 | |||
177 | static inline void videobuf_queue_unlock(struct videobuf_queue *q) | ||
178 | { | ||
179 | if (!q->ext_lock) | ||
180 | mutex_unlock(&q->vb_lock); | ||
181 | } | ||
182 | |||
183 | int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
184 | int non_blocking, int intr); | ||
171 | int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, | 185 | int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, |
172 | struct v4l2_framebuffer *fbuf); | 186 | struct v4l2_framebuffer *fbuf); |
173 | 187 | ||
@@ -185,7 +199,8 @@ void videobuf_queue_core_init(struct videobuf_queue *q, | |||
185 | enum v4l2_field field, | 199 | enum v4l2_field field, |
186 | unsigned int msize, | 200 | unsigned int msize, |
187 | void *priv, | 201 | void *priv, |
188 | struct videobuf_qtype_ops *int_ops); | 202 | struct videobuf_qtype_ops *int_ops, |
203 | struct mutex *ext_lock); | ||
189 | int videobuf_queue_is_busy(struct videobuf_queue *q); | 204 | int videobuf_queue_is_busy(struct videobuf_queue *q); |
190 | void videobuf_queue_cancel(struct videobuf_queue *q); | 205 | void videobuf_queue_cancel(struct videobuf_queue *q); |
191 | 206 | ||
diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h index ebaa9bc1ee8..f0ed82543d9 100644 --- a/include/media/videobuf-dma-contig.h +++ b/include/media/videobuf-dma-contig.h | |||
@@ -23,7 +23,8 @@ void videobuf_queue_dma_contig_init(struct videobuf_queue *q, | |||
23 | enum v4l2_buf_type type, | 23 | enum v4l2_buf_type type, |
24 | enum v4l2_field field, | 24 | enum v4l2_field field, |
25 | unsigned int msize, | 25 | unsigned int msize, |
26 | void *priv); | 26 | void *priv, |
27 | struct mutex *ext_lock); | ||
27 | 28 | ||
28 | dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); | 29 | dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); |
29 | void videobuf_dma_contig_free(struct videobuf_queue *q, | 30 | void videobuf_dma_contig_free(struct videobuf_queue *q, |
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index aa4ebb42a56..1c647e8148c 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h | |||
@@ -103,7 +103,8 @@ void videobuf_queue_sg_init(struct videobuf_queue *q, | |||
103 | enum v4l2_buf_type type, | 103 | enum v4l2_buf_type type, |
104 | enum v4l2_field field, | 104 | enum v4l2_field field, |
105 | unsigned int msize, | 105 | unsigned int msize, |
106 | void *priv); | 106 | void *priv, |
107 | struct mutex *ext_lock); | ||
107 | 108 | ||
108 | #endif /* _VIDEOBUF_DMA_SG_H */ | 109 | #endif /* _VIDEOBUF_DMA_SG_H */ |
109 | 110 | ||
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index e19403c18da..486a97efdb5 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h | |||
@@ -36,7 +36,8 @@ void videobuf_queue_vmalloc_init(struct videobuf_queue *q, | |||
36 | enum v4l2_buf_type type, | 36 | enum v4l2_buf_type type, |
37 | enum v4l2_field field, | 37 | enum v4l2_field field, |
38 | unsigned int msize, | 38 | unsigned int msize, |
39 | void *priv); | 39 | void *priv, |
40 | struct mutex *ext_lock); | ||
40 | 41 | ||
41 | void *videobuf_to_vmalloc(struct videobuf_buffer *buf); | 42 | void *videobuf_to_vmalloc(struct videobuf_buffer *buf); |
42 | 43 | ||
diff --git a/include/media/wm8775.h b/include/media/wm8775.h index 60739c5a23a..a1c4d417dfa 100644 --- a/include/media/wm8775.h +++ b/include/media/wm8775.h | |||
@@ -32,4 +32,7 @@ | |||
32 | #define WM8775_AIN3 4 | 32 | #define WM8775_AIN3 4 |
33 | #define WM8775_AIN4 8 | 33 | #define WM8775_AIN4 8 |
34 | 34 | ||
35 | /* subdev group ID */ | ||
36 | #define WM8775_GID (1 << 0) | ||
37 | |||
35 | #endif | 38 | #endif |