diff options
56 files changed, 727 insertions, 679 deletions
diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml index ffee1fbbc001..c7a4ca517859 100644 --- a/Documentation/DocBook/media/dvb/dvbproperty.xml +++ b/Documentation/DocBook/media/dvb/dvbproperty.xml | |||
| @@ -163,14 +163,16 @@ get/set up to 64 properties. The actual meaning of each property is described on | |||
| 163 | <section id="DTV-FREQUENCY"> | 163 | <section id="DTV-FREQUENCY"> |
| 164 | <title><constant>DTV_FREQUENCY</constant></title> | 164 | <title><constant>DTV_FREQUENCY</constant></title> |
| 165 | 165 | ||
| 166 | <para>Central frequency of the channel, in HZ.</para> | 166 | <para>Central frequency of the channel.</para> |
| 167 | 167 | ||
| 168 | <para>Notes:</para> | 168 | <para>Notes:</para> |
| 169 | <para>1)For ISDB-T, the channels are usually transmitted with an offset of 143kHz. | 169 | <para>1)For satellital delivery systems, it is measured in kHz. |
| 170 | For the other ones, it is measured in Hz.</para> | ||
| 171 | <para>2)For ISDB-T, the channels are usually transmitted with an offset of 143kHz. | ||
| 170 | E.g. a valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of | 172 | E.g. a valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of |
| 171 | the channel which is 6MHz.</para> | 173 | the channel which is 6MHz.</para> |
| 172 | 174 | ||
| 173 | <para>2)As in ISDB-Tsb the channel consists of only one or three segments the | 175 | <para>3)As in ISDB-Tsb the channel consists of only one or three segments the |
| 174 | frequency step is 429kHz, 3*429 respectively. As for ISDB-T the | 176 | frequency step is 429kHz, 3*429 respectively. As for ISDB-T the |
| 175 | central frequency of the channel is expected.</para> | 177 | central frequency of the channel is expected.</para> |
| 176 | </section> | 178 | </section> |
| @@ -735,14 +737,10 @@ typedef enum fe_hierarchy { | |||
| 735 | <listitem><para><link linkend="DTV-TUNE"><constant>DTV_TUNE</constant></link></para></listitem> | 737 | <listitem><para><link linkend="DTV-TUNE"><constant>DTV_TUNE</constant></link></para></listitem> |
| 736 | <listitem><para><link linkend="DTV-CLEAR"><constant>DTV_CLEAR</constant></link></para></listitem> | 738 | <listitem><para><link linkend="DTV-CLEAR"><constant>DTV_CLEAR</constant></link></para></listitem> |
| 737 | <listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem> | 739 | <listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem> |
| 738 | <listitem><para><link linkend="DTV-MODULATION"><constant>DTV_MODULATION</constant></link></para></listitem> | ||
| 739 | <listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem> | 740 | <listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem> |
| 740 | <listitem><para><link linkend="DTV-INVERSION"><constant>DTV_INVERSION</constant></link></para></listitem> | 741 | <listitem><para><link linkend="DTV-INVERSION"><constant>DTV_INVERSION</constant></link></para></listitem> |
| 741 | <listitem><para><link linkend="DTV-CODE-RATE-HP"><constant>DTV_CODE_RATE_HP</constant></link></para></listitem> | ||
| 742 | <listitem><para><link linkend="DTV-CODE-RATE-LP"><constant>DTV_CODE_RATE_LP</constant></link></para></listitem> | ||
| 743 | <listitem><para><link linkend="DTV-GUARD-INTERVAL"><constant>DTV_GUARD_INTERVAL</constant></link></para></listitem> | 742 | <listitem><para><link linkend="DTV-GUARD-INTERVAL"><constant>DTV_GUARD_INTERVAL</constant></link></para></listitem> |
| 744 | <listitem><para><link linkend="DTV-TRANSMISSION-MODE"><constant>DTV_TRANSMISSION_MODE</constant></link></para></listitem> | 743 | <listitem><para><link linkend="DTV-TRANSMISSION-MODE"><constant>DTV_TRANSMISSION_MODE</constant></link></para></listitem> |
| 745 | <listitem><para><link linkend="DTV-HIERARCHY"><constant>DTV_HIERARCHY</constant></link></para></listitem> | ||
| 746 | <listitem><para><link linkend="DTV-ISDBT-LAYER-ENABLED"><constant>DTV_ISDBT_LAYER_ENABLED</constant></link></para></listitem> | 744 | <listitem><para><link linkend="DTV-ISDBT-LAYER-ENABLED"><constant>DTV_ISDBT_LAYER_ENABLED</constant></link></para></listitem> |
| 747 | <listitem><para><link linkend="DTV-ISDBT-PARTIAL-RECEPTION"><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></link></para></listitem> | 745 | <listitem><para><link linkend="DTV-ISDBT-PARTIAL-RECEPTION"><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></link></para></listitem> |
| 748 | <listitem><para><link linkend="DTV-ISDBT-SOUND-BROADCASTING"><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></link></para></listitem> | 746 | <listitem><para><link linkend="DTV-ISDBT-SOUND-BROADCASTING"><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></link></para></listitem> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 6f1f9a629dc3..b17a7aac6997 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml | |||
| @@ -183,7 +183,12 @@ applications must set the array to zero.</entry> | |||
| 183 | <entry>__u32</entry> | 183 | <entry>__u32</entry> |
| 184 | <entry><structfield>ctrl_class</structfield></entry> | 184 | <entry><structfield>ctrl_class</structfield></entry> |
| 185 | <entry>The control class to which all controls belong, see | 185 | <entry>The control class to which all controls belong, see |
| 186 | <xref linkend="ctrl-class" />.</entry> | 186 | <xref linkend="ctrl-class" />. Drivers that use a kernel framework for handling |
| 187 | controls will also accept a value of 0 here, meaning that the controls can | ||
| 188 | belong to any control class. Whether drivers support this can be tested by setting | ||
| 189 | <structfield>ctrl_class</structfield> to 0 and calling <constant>VIDIOC_TRY_EXT_CTRLS</constant> | ||
| 190 | with a <structfield>count</structfield> of 0. If that succeeds, then the driver | ||
| 191 | supports this feature.</entry> | ||
| 187 | </row> | 192 | </row> |
| 188 | <row> | 193 | <row> |
| 189 | <entry>__u32</entry> | 194 | <entry>__u32</entry> |
| @@ -194,10 +199,13 @@ also be zero.</entry> | |||
| 194 | <row> | 199 | <row> |
| 195 | <entry>__u32</entry> | 200 | <entry>__u32</entry> |
| 196 | <entry><structfield>error_idx</structfield></entry> | 201 | <entry><structfield>error_idx</structfield></entry> |
| 197 | <entry>Set by the driver in case of an error. It is the | 202 | <entry>Set by the driver in case of an error. If it is equal |
| 198 | index of the control causing the error or equal to 'count' when the | 203 | to <structfield>count</structfield>, then no actual changes were made to |
| 199 | error is not associated with a particular control. Undefined when the | 204 | controls. In other words, the error was not associated with setting a particular |
| 200 | ioctl returns 0 (success).</entry> | 205 | control. If it is another value, then only the controls up to <structfield>error_idx-1</structfield> |
| 206 | were modified and control <structfield>error_idx</structfield> is the one that | ||
| 207 | caused the error. The <structfield>error_idx</structfield> value is undefined | ||
| 208 | if the ioctl returned 0 (success).</entry> | ||
| 201 | </row> | 209 | </row> |
| 202 | <row> | 210 | <row> |
| 203 | <entry>__u32</entry> | 211 | <entry>__u32</entry> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml index 93817f337033..7c63815e7afd 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml | |||
| @@ -364,15 +364,20 @@ capability and it is cleared otherwise.</entry> | |||
| 364 | <row> | 364 | <row> |
| 365 | <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry> | 365 | <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry> |
| 366 | <entry>0x0002</entry> | 366 | <entry>0x0002</entry> |
| 367 | <entry>The frame buffer is an overlay surface the same | 367 | <entry>If this flag is set for a video capture device, then the |
| 368 | size as the capture. [?]</entry> | 368 | driver will set the initial overlay size to cover the full framebuffer size, |
| 369 | </row> | 369 | otherwise the existing overlay size (as set by &VIDIOC-S-FMT;) will be used. |
| 370 | <row> | 370 | |
| 371 | <entry spanname="hspan">The purpose of | 371 | Only one video capture driver (bttv) supports this flag. The use of this flag |
| 372 | <constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear. | 372 | for capture devices is deprecated. There is no way to detect which drivers |
| 373 | Most drivers seem to ignore this flag. For compatibility with the | 373 | support this flag, so the only reliable method of setting the overlay size is |
| 374 | <wordasword>bttv</wordasword> driver applications should set the | 374 | through &VIDIOC-S-FMT;. |
| 375 | <constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry> | 375 | |
| 376 | If this flag is set for a video output device, then the video output overlay | ||
| 377 | window is relative to the top-left corner of the framebuffer and restricted | ||
| 378 | to the size of the framebuffer. If it is cleared, then the video output | ||
| 379 | overlay window is relative to the video output display. | ||
| 380 | </entry> | ||
| 376 | </row> | 381 | </row> |
| 377 | <row> | 382 | <row> |
| 378 | <entry><constant>V4L2_FBUF_FLAG_CHROMAKEY</constant></entry> | 383 | <entry><constant>V4L2_FBUF_FLAG_CHROMAKEY</constant></entry> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml index 16431813bebd..66e9a5257861 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml | |||
| @@ -98,8 +98,11 @@ the &v4l2-output; <structfield>modulator</structfield> field and the | |||
| 98 | <entry>&v4l2-tuner-type;</entry> | 98 | <entry>&v4l2-tuner-type;</entry> |
| 99 | <entry><structfield>type</structfield></entry> | 99 | <entry><structfield>type</structfield></entry> |
| 100 | <entry>The tuner type. This is the same value as in the | 100 | <entry>The tuner type. This is the same value as in the |
| 101 | &v4l2-tuner; <structfield>type</structfield> field. The field is not | 101 | &v4l2-tuner; <structfield>type</structfield> field. The type must be set |
| 102 | applicable to modulators, &ie; ignored by drivers.</entry> | 102 | to <constant>V4L2_TUNER_RADIO</constant> for <filename>/dev/radioX</filename> |
| 103 | device nodes, and to <constant>V4L2_TUNER_ANALOG_TV</constant> | ||
| 104 | for all others. The field is not applicable to modulators, &ie; ignored | ||
| 105 | by drivers.</entry> | ||
| 103 | </row> | 106 | </row> |
| 104 | <row> | 107 | <row> |
| 105 | <entry>__u32</entry> | 108 | <entry>__u32</entry> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-input.xml b/Documentation/DocBook/media/v4l/vidioc-g-input.xml index 08ae82f131f2..1d43065090dd 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-input.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-input.xml | |||
| @@ -61,8 +61,8 @@ desired input in an integer and call the | |||
| 61 | <constant>VIDIOC_S_INPUT</constant> ioctl with a pointer to this | 61 | <constant>VIDIOC_S_INPUT</constant> ioctl with a pointer to this |
| 62 | integer. Side effects are possible. For example inputs may support | 62 | integer. Side effects are possible. For example inputs may support |
| 63 | different video standards, so the driver may implicitly switch the | 63 | different video standards, so the driver may implicitly switch the |
| 64 | current standard. It is good practice to select an input before | 64 | current standard. Because of these possible side effects applications |
| 65 | querying or negotiating any other parameters.</para> | 65 | must select an input before querying or negotiating any other parameters.</para> |
| 66 | 66 | ||
| 67 | <para>Information about video inputs is available using the | 67 | <para>Information about video inputs is available using the |
| 68 | &VIDIOC-ENUMINPUT; ioctl.</para> | 68 | &VIDIOC-ENUMINPUT; ioctl.</para> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-output.xml b/Documentation/DocBook/media/v4l/vidioc-g-output.xml index fd45f1c13ccf..4533068ecb8a 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-output.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-output.xml | |||
| @@ -61,8 +61,9 @@ desired output in an integer and call the | |||
| 61 | <constant>VIDIOC_S_OUTPUT</constant> ioctl with a pointer to this integer. | 61 | <constant>VIDIOC_S_OUTPUT</constant> ioctl with a pointer to this integer. |
| 62 | Side effects are possible. For example outputs may support different | 62 | Side effects are possible. For example outputs may support different |
| 63 | video standards, so the driver may implicitly switch the current | 63 | video standards, so the driver may implicitly switch the current |
| 64 | standard. It is good practice to select an output before querying or | 64 | standard. |
| 65 | negotiating any other parameters.</para> | 65 | standard. Because of these possible side effects applications |
| 66 | must select an output before querying or negotiating any other parameters.</para> | ||
| 66 | 67 | ||
| 67 | <para>Information about video outputs is available using the | 68 | <para>Information about video outputs is available using the |
| 68 | &VIDIOC-ENUMOUTPUT; ioctl.</para> | 69 | &VIDIOC-ENUMOUTPUT; ioctl.</para> |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index d725c0dfe032..1bea46a54b1c 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -439,17 +439,6 @@ Who: Jean Delvare <khali@linux-fr.org> | |||
| 439 | 439 | ||
| 440 | ---------------------------- | 440 | ---------------------------- |
| 441 | 441 | ||
| 442 | What: For VIDIOC_S_FREQUENCY the type field must match the device node's type. | ||
| 443 | If not, return -EINVAL. | ||
| 444 | When: 3.2 | ||
| 445 | Why: It makes no sense to switch the tuner to radio mode by calling | ||
| 446 | VIDIOC_S_FREQUENCY on a video node, or to switch the tuner to tv mode by | ||
| 447 | calling VIDIOC_S_FREQUENCY on a radio node. This is the first step of a | ||
| 448 | move to more consistent handling of tv and radio tuners. | ||
| 449 | Who: Hans Verkuil <hans.verkuil@cisco.com> | ||
| 450 | |||
| 451 | ---------------------------- | ||
| 452 | |||
| 453 | What: Opening a radio device node will no longer automatically switch the | 442 | What: Opening a radio device node will no longer automatically switch the |
| 454 | tuner mode from tv to radio. | 443 | tuner mode from tv to radio. |
| 455 | When: 3.3 | 444 | When: 3.3 |
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt index 26aa0573933e..e2492a9d1027 100644 --- a/Documentation/video4linux/v4l2-controls.txt +++ b/Documentation/video4linux/v4l2-controls.txt | |||
| @@ -666,27 +666,6 @@ a control of this type whenever the first control belonging to a new control | |||
| 666 | class is added. | 666 | class is added. |
| 667 | 667 | ||
| 668 | 668 | ||
| 669 | Differences from the Spec | ||
| 670 | ========================= | ||
| 671 | |||
| 672 | There are a few places where the framework acts slightly differently from the | ||
| 673 | V4L2 Specification. Those differences are described in this section. We will | ||
| 674 | have to see whether we need to adjust the spec or not. | ||
| 675 | |||
| 676 | 1) It is no longer required to have all controls contained in a | ||
| 677 | v4l2_ext_control array be from the same control class. The framework will be | ||
| 678 | able to handle any type of control in the array. You need to set ctrl_class | ||
| 679 | to 0 in order to enable this. If ctrl_class is non-zero, then it will still | ||
| 680 | check that all controls belong to that control class. | ||
| 681 | |||
| 682 | If you set ctrl_class to 0 and count to 0, then it will only return an error | ||
| 683 | if there are no controls at all. | ||
| 684 | |||
| 685 | 2) Clarified the way error_idx works. For get and set it will be equal to | ||
| 686 | count if nothing was done yet. If it is less than count then only the controls | ||
| 687 | up to error_idx-1 were successfully applied. | ||
| 688 | |||
| 689 | |||
| 690 | Proposals for Extensions | 669 | Proposals for Extensions |
| 691 | ======================== | 670 | ======================== |
| 692 | 671 | ||
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 27555995f7e4..b5ee3ebfcfca 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
| @@ -24,6 +24,21 @@ | |||
| 24 | #include <linux/dvb/frontend.h> | 24 | #include <linux/dvb/frontend.h> |
| 25 | #include "dvb_frontend.h" | 25 | #include "dvb_frontend.h" |
| 26 | 26 | ||
| 27 | /* Registers (Write-only) */ | ||
| 28 | #define XREG_INIT 0x00 | ||
| 29 | #define XREG_RF_FREQ 0x02 | ||
| 30 | #define XREG_POWER_DOWN 0x08 | ||
| 31 | |||
| 32 | /* Registers (Read-only) */ | ||
| 33 | #define XREG_FREQ_ERROR 0x01 | ||
| 34 | #define XREG_LOCK 0x02 | ||
| 35 | #define XREG_VERSION 0x04 | ||
| 36 | #define XREG_PRODUCT_ID 0x08 | ||
| 37 | #define XREG_HSYNC_FREQ 0x10 | ||
| 38 | #define XREG_FRAME_LINES 0x20 | ||
| 39 | #define XREG_SNR 0x40 | ||
| 40 | |||
| 41 | #define XREG_ADC_ENV 0x0100 | ||
| 27 | 42 | ||
| 28 | static int debug; | 43 | static int debug; |
| 29 | module_param(debug, int, 0644); | 44 | module_param(debug, int, 0644); |
| @@ -885,7 +900,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
| 885 | mutex_lock(&priv->lock); | 900 | mutex_lock(&priv->lock); |
| 886 | 901 | ||
| 887 | /* Sync Lock Indicator */ | 902 | /* Sync Lock Indicator */ |
| 888 | rc = xc2028_get_reg(priv, 0x0002, &frq_lock); | 903 | rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock); |
| 889 | if (rc < 0) | 904 | if (rc < 0) |
| 890 | goto ret; | 905 | goto ret; |
| 891 | 906 | ||
| @@ -894,7 +909,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
| 894 | signal = 1 << 11; | 909 | signal = 1 << 11; |
| 895 | 910 | ||
| 896 | /* Get SNR of the video signal */ | 911 | /* Get SNR of the video signal */ |
| 897 | rc = xc2028_get_reg(priv, 0x0040, &signal); | 912 | rc = xc2028_get_reg(priv, XREG_SNR, &signal); |
| 898 | if (rc < 0) | 913 | if (rc < 0) |
| 899 | goto ret; | 914 | goto ret; |
| 900 | 915 | ||
| @@ -1019,9 +1034,9 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
| 1019 | 1034 | ||
| 1020 | /* CMD= Set frequency */ | 1035 | /* CMD= Set frequency */ |
| 1021 | if (priv->firm_version < 0x0202) | 1036 | if (priv->firm_version < 0x0202) |
| 1022 | rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00}); | 1037 | rc = send_seq(priv, {0x00, XREG_RF_FREQ, 0x00, 0x00}); |
| 1023 | else | 1038 | else |
| 1024 | rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00}); | 1039 | rc = send_seq(priv, {0x80, XREG_RF_FREQ, 0x00, 0x00}); |
| 1025 | if (rc < 0) | 1040 | if (rc < 0) |
| 1026 | goto ret; | 1041 | goto ret; |
| 1027 | 1042 | ||
| @@ -1201,9 +1216,9 @@ static int xc2028_sleep(struct dvb_frontend *fe) | |||
| 1201 | mutex_lock(&priv->lock); | 1216 | mutex_lock(&priv->lock); |
| 1202 | 1217 | ||
| 1203 | if (priv->firm_version < 0x0202) | 1218 | if (priv->firm_version < 0x0202) |
| 1204 | rc = send_seq(priv, {0x00, 0x08, 0x00, 0x00}); | 1219 | rc = send_seq(priv, {0x00, XREG_POWER_DOWN, 0x00, 0x00}); |
| 1205 | else | 1220 | else |
| 1206 | rc = send_seq(priv, {0x80, 0x08, 0x00, 0x00}); | 1221 | rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); |
| 1207 | 1222 | ||
| 1208 | priv->cur_fw.type = 0; /* need firmware reload */ | 1223 | priv->cur_fw.type = 0; /* need firmware reload */ |
| 1209 | 1224 | ||
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c index d218c1d68c33..68397110b7d9 100644 --- a/drivers/media/common/tuners/xc4000.c +++ b/drivers/media/common/tuners/xc4000.c | |||
| @@ -154,6 +154,8 @@ struct xc4000_priv { | |||
| 154 | #define XREG_SNR 0x06 | 154 | #define XREG_SNR 0x06 |
| 155 | #define XREG_VERSION 0x07 | 155 | #define XREG_VERSION 0x07 |
| 156 | #define XREG_PRODUCT_ID 0x08 | 156 | #define XREG_PRODUCT_ID 0x08 |
| 157 | #define XREG_SIGNAL_LEVEL 0x0A | ||
| 158 | #define XREG_NOISE_LEVEL 0x0B | ||
| 157 | 159 | ||
| 158 | /* | 160 | /* |
| 159 | Basic firmware description. This will remain with | 161 | Basic firmware description. This will remain with |
| @@ -486,6 +488,16 @@ static int xc_get_quality(struct xc4000_priv *priv, u16 *quality) | |||
| 486 | return xc4000_readreg(priv, XREG_QUALITY, quality); | 488 | return xc4000_readreg(priv, XREG_QUALITY, quality); |
| 487 | } | 489 | } |
| 488 | 490 | ||
| 491 | static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal) | ||
| 492 | { | ||
| 493 | return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal); | ||
| 494 | } | ||
| 495 | |||
| 496 | static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise) | ||
| 497 | { | ||
| 498 | return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise); | ||
| 499 | } | ||
| 500 | |||
| 489 | static u16 xc_wait_for_lock(struct xc4000_priv *priv) | 501 | static u16 xc_wait_for_lock(struct xc4000_priv *priv) |
| 490 | { | 502 | { |
| 491 | u16 lock_state = 0; | 503 | u16 lock_state = 0; |
| @@ -1089,6 +1101,8 @@ static void xc_debug_dump(struct xc4000_priv *priv) | |||
| 1089 | u32 hsync_freq_hz = 0; | 1101 | u32 hsync_freq_hz = 0; |
| 1090 | u16 frame_lines; | 1102 | u16 frame_lines; |
| 1091 | u16 quality; | 1103 | u16 quality; |
| 1104 | u16 signal = 0; | ||
| 1105 | u16 noise = 0; | ||
| 1092 | u8 hw_majorversion = 0, hw_minorversion = 0; | 1106 | u8 hw_majorversion = 0, hw_minorversion = 0; |
| 1093 | u8 fw_majorversion = 0, fw_minorversion = 0; | 1107 | u8 fw_majorversion = 0, fw_minorversion = 0; |
| 1094 | 1108 | ||
| @@ -1119,6 +1133,12 @@ static void xc_debug_dump(struct xc4000_priv *priv) | |||
| 1119 | 1133 | ||
| 1120 | xc_get_quality(priv, &quality); | 1134 | xc_get_quality(priv, &quality); |
| 1121 | dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); | 1135 | dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); |
| 1136 | |||
| 1137 | xc_get_signal_level(priv, &signal); | ||
| 1138 | dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal); | ||
| 1139 | |||
| 1140 | xc_get_noise_level(priv, &noise); | ||
| 1141 | dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise); | ||
| 1122 | } | 1142 | } |
| 1123 | 1143 | ||
| 1124 | static int xc4000_set_params(struct dvb_frontend *fe) | 1144 | static int xc4000_set_params(struct dvb_frontend *fe) |
| @@ -1432,6 +1452,71 @@ fail: | |||
| 1432 | return ret; | 1452 | return ret; |
| 1433 | } | 1453 | } |
| 1434 | 1454 | ||
| 1455 | static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength) | ||
| 1456 | { | ||
| 1457 | struct xc4000_priv *priv = fe->tuner_priv; | ||
| 1458 | u16 value = 0; | ||
| 1459 | int rc; | ||
| 1460 | |||
| 1461 | mutex_lock(&priv->lock); | ||
| 1462 | rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value); | ||
| 1463 | mutex_unlock(&priv->lock); | ||
| 1464 | |||
| 1465 | if (rc < 0) | ||
| 1466 | goto ret; | ||
| 1467 | |||
| 1468 | /* Informations from real testing of DVB-T and radio part, | ||
| 1469 | coeficient for one dB is 0xff. | ||
| 1470 | */ | ||
| 1471 | tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value); | ||
| 1472 | |||
| 1473 | /* all known digital modes */ | ||
| 1474 | if ((priv->video_standard == XC4000_DTV6) || | ||
| 1475 | (priv->video_standard == XC4000_DTV7) || | ||
| 1476 | (priv->video_standard == XC4000_DTV7_8) || | ||
| 1477 | (priv->video_standard == XC4000_DTV8)) | ||
| 1478 | goto digital; | ||
| 1479 | |||
| 1480 | /* Analog mode has NOISE LEVEL important, signal | ||
| 1481 | depends only on gain of antenna and amplifiers, | ||
| 1482 | but it doesn't tell anything about real quality | ||
| 1483 | of reception. | ||
| 1484 | */ | ||
| 1485 | mutex_lock(&priv->lock); | ||
| 1486 | rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value); | ||
| 1487 | mutex_unlock(&priv->lock); | ||
| 1488 | |||
| 1489 | tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value); | ||
| 1490 | |||
| 1491 | /* highest noise level: 32dB */ | ||
| 1492 | if (value >= 0x2000) { | ||
| 1493 | value = 0; | ||
| 1494 | } else { | ||
| 1495 | value = ~value << 3; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | goto ret; | ||
| 1499 | |||
| 1500 | /* Digital mode has SIGNAL LEVEL important and real | ||
| 1501 | noise level is stored in demodulator registers. | ||
| 1502 | */ | ||
| 1503 | digital: | ||
| 1504 | /* best signal: -50dB */ | ||
| 1505 | if (value <= 0x3200) { | ||
| 1506 | value = 0xffff; | ||
| 1507 | /* minimum: -114dB - should be 0x7200 but real zero is 0x713A */ | ||
| 1508 | } else if (value >= 0x713A) { | ||
| 1509 | value = 0; | ||
| 1510 | } else { | ||
| 1511 | value = ~(value - 0x3200) << 2; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | ret: | ||
| 1515 | *strength = value; | ||
| 1516 | |||
| 1517 | return rc; | ||
| 1518 | } | ||
| 1519 | |||
| 1435 | static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) | 1520 | static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) |
| 1436 | { | 1521 | { |
| 1437 | struct xc4000_priv *priv = fe->tuner_priv; | 1522 | struct xc4000_priv *priv = fe->tuner_priv; |
| @@ -1559,6 +1644,7 @@ static const struct dvb_tuner_ops xc4000_tuner_ops = { | |||
| 1559 | .set_params = xc4000_set_params, | 1644 | .set_params = xc4000_set_params, |
| 1560 | .set_analog_params = xc4000_set_analog_params, | 1645 | .set_analog_params = xc4000_set_analog_params, |
| 1561 | .get_frequency = xc4000_get_frequency, | 1646 | .get_frequency = xc4000_get_frequency, |
| 1647 | .get_rf_strength = xc4000_get_signal, | ||
| 1562 | .get_bandwidth = xc4000_get_bandwidth, | 1648 | .get_bandwidth = xc4000_get_bandwidth, |
| 1563 | .get_status = xc4000_get_status | 1649 | .get_status = xc4000_get_status |
| 1564 | }; | 1650 | }; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index b15db4fe347b..fbbe545a74cb 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
| @@ -904,8 +904,11 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) | |||
| 904 | { | 904 | { |
| 905 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 905 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
| 906 | int i; | 906 | int i; |
| 907 | u32 delsys; | ||
| 907 | 908 | ||
| 909 | delsys = c->delivery_system; | ||
| 908 | memset(c, 0, sizeof(struct dtv_frontend_properties)); | 910 | memset(c, 0, sizeof(struct dtv_frontend_properties)); |
| 911 | c->delivery_system = delsys; | ||
| 909 | 912 | ||
| 910 | c->state = DTV_CLEAR; | 913 | c->state = DTV_CLEAR; |
| 911 | 914 | ||
| @@ -1009,25 +1012,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { | |||
| 1009 | _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), | 1012 | _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), |
| 1010 | _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), | 1013 | _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), |
| 1011 | 1014 | ||
| 1012 | _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0), | ||
| 1013 | _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0), | ||
| 1014 | _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0), | ||
| 1015 | _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0), | ||
| 1016 | _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0), | ||
| 1017 | _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0), | ||
| 1018 | _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0), | ||
| 1019 | _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0), | ||
| 1020 | _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0), | ||
| 1021 | _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0), | ||
| 1022 | _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0), | ||
| 1023 | _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0), | ||
| 1024 | _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0), | ||
| 1025 | _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0), | ||
| 1026 | _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0), | ||
| 1027 | _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0), | ||
| 1028 | _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0), | ||
| 1029 | _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0), | ||
| 1030 | |||
| 1031 | _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), | 1015 | _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), |
| 1032 | _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0), | 1016 | _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0), |
| 1033 | 1017 | ||
| @@ -1413,6 +1397,15 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) | |||
| 1413 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1397 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
| 1414 | enum dvbv3_emulation_type type; | 1398 | enum dvbv3_emulation_type type; |
| 1415 | 1399 | ||
| 1400 | /* | ||
| 1401 | * It was reported that some old DVBv5 applications were | ||
| 1402 | * filling delivery_system with SYS_UNDEFINED. If this happens, | ||
| 1403 | * assume that the application wants to use the first supported | ||
| 1404 | * delivery system. | ||
| 1405 | */ | ||
| 1406 | if (c->delivery_system == SYS_UNDEFINED) | ||
| 1407 | c->delivery_system = fe->ops.delsys[0]; | ||
| 1408 | |||
| 1416 | if (desired_system == SYS_UNDEFINED) { | 1409 | if (desired_system == SYS_UNDEFINED) { |
| 1417 | /* | 1410 | /* |
| 1418 | * A DVBv3 call doesn't know what's the desired system. | 1411 | * A DVBv3 call doesn't know what's the desired system. |
| @@ -1732,6 +1725,7 @@ static int dvb_frontend_ioctl_properties(struct file *file, | |||
| 1732 | { | 1725 | { |
| 1733 | struct dvb_device *dvbdev = file->private_data; | 1726 | struct dvb_device *dvbdev = file->private_data; |
| 1734 | struct dvb_frontend *fe = dvbdev->priv; | 1727 | struct dvb_frontend *fe = dvbdev->priv; |
| 1728 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | ||
| 1735 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1729 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
| 1736 | int err = 0; | 1730 | int err = 0; |
| 1737 | 1731 | ||
| @@ -1798,9 +1792,14 @@ static int dvb_frontend_ioctl_properties(struct file *file, | |||
| 1798 | 1792 | ||
| 1799 | /* | 1793 | /* |
| 1800 | * Fills the cache out struct with the cache contents, plus | 1794 | * Fills the cache out struct with the cache contents, plus |
| 1801 | * the data retrieved from get_frontend. | 1795 | * the data retrieved from get_frontend, if the frontend |
| 1796 | * is not idle. Otherwise, returns the cached content | ||
| 1802 | */ | 1797 | */ |
| 1803 | dtv_get_frontend(fe, NULL); | 1798 | if (fepriv->state != FESTATE_IDLE) { |
| 1799 | err = dtv_get_frontend(fe, NULL); | ||
| 1800 | if (err < 0) | ||
| 1801 | goto out; | ||
| 1802 | } | ||
| 1804 | for (i = 0; i < tvps->num; i++) { | 1803 | for (i = 0; i < tvps->num; i++) { |
| 1805 | err = dtv_property_process_get(fe, c, tvp + i, file); | 1804 | err = dtv_property_process_get(fe, c, tvp + i, file); |
| 1806 | if (err < 0) | 1805 | if (err < 0) |
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index d66192974d68..1455e2644ab5 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
| @@ -877,24 +877,18 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
| 877 | case ANYSEE_HW_508T2C: /* 20 */ | 877 | case ANYSEE_HW_508T2C: /* 20 */ |
| 878 | /* E7 T2C */ | 878 | /* E7 T2C */ |
| 879 | 879 | ||
| 880 | if (state->fe_id) | ||
| 881 | break; | ||
| 882 | |||
| 880 | /* enable DVB-T/T2/C demod on IOE[5] */ | 883 | /* enable DVB-T/T2/C demod on IOE[5] */ |
| 881 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); | 884 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); |
| 882 | if (ret) | 885 | if (ret) |
| 883 | goto error; | 886 | goto error; |
| 884 | 887 | ||
| 885 | if (state->fe_id == 0) { | 888 | /* attach demod */ |
| 886 | /* DVB-T/T2 */ | 889 | adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, |
| 887 | adap->fe_adap[state->fe_id].fe = | 890 | &anysee_cxd2820r_config, &adap->dev->i2c_adap, |
| 888 | dvb_attach(cxd2820r_attach, | 891 | NULL); |
| 889 | &anysee_cxd2820r_config, | ||
| 890 | &adap->dev->i2c_adap, NULL); | ||
| 891 | } else { | ||
| 892 | /* DVB-C */ | ||
| 893 | adap->fe_adap[state->fe_id].fe = | ||
| 894 | dvb_attach(cxd2820r_attach, | ||
| 895 | &anysee_cxd2820r_config, | ||
| 896 | &adap->dev->i2c_adap, adap->fe_adap[0].fe); | ||
| 897 | } | ||
| 898 | 892 | ||
| 899 | state->has_ci = true; | 893 | state->has_ci = true; |
| 900 | 894 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 9bd6d51b3b93..7de125c0b36f 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
| @@ -48,6 +48,8 @@ struct dib0700_state { | |||
| 48 | u8 disable_streaming_master_mode; | 48 | u8 disable_streaming_master_mode; |
| 49 | u32 fw_version; | 49 | u32 fw_version; |
| 50 | u32 nb_packet_buffer_size; | 50 | u32 nb_packet_buffer_size; |
| 51 | int (*read_status)(struct dvb_frontend *, fe_status_t *); | ||
| 52 | int (*sleep)(struct dvb_frontend* fe); | ||
| 51 | u8 buf[255]; | 53 | u8 buf[255]; |
| 52 | }; | 54 | }; |
| 53 | 55 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 206999476f02..070e82aa53f5 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
| @@ -834,6 +834,7 @@ static struct usb_driver dib0700_driver = { | |||
| 834 | 834 | ||
| 835 | module_usb_driver(dib0700_driver); | 835 | module_usb_driver(dib0700_driver); |
| 836 | 836 | ||
| 837 | MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw"); | ||
| 837 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); | 838 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); |
| 838 | MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); | 839 | MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); |
| 839 | MODULE_VERSION("1.0"); | 840 | MODULE_VERSION("1.0"); |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 81ef4b46f790..f9e966aa26e7 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
| @@ -3066,19 +3066,25 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { | |||
| 3066 | } | 3066 | } |
| 3067 | }; | 3067 | }; |
| 3068 | 3068 | ||
| 3069 | static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) | 3069 | static void stk7070pd_init(struct dvb_usb_device *dev) |
| 3070 | { | 3070 | { |
| 3071 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | 3071 | dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1); |
| 3072 | msleep(10); | 3072 | msleep(10); |
| 3073 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | 3073 | dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1); |
| 3074 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | 3074 | dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1); |
| 3075 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | 3075 | dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1); |
| 3076 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | 3076 | dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0); |
| 3077 | 3077 | ||
| 3078 | dib0700_ctrl_clock(adap->dev, 72, 1); | 3078 | dib0700_ctrl_clock(dev, 72, 1); |
| 3079 | 3079 | ||
| 3080 | msleep(10); | 3080 | msleep(10); |
| 3081 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | 3081 | dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1); |
| 3082 | } | ||
| 3083 | |||
| 3084 | static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) | ||
| 3085 | { | ||
| 3086 | stk7070pd_init(adap->dev); | ||
| 3087 | |||
| 3082 | msleep(10); | 3088 | msleep(10); |
| 3083 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 3089 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
| 3084 | 3090 | ||
| @@ -3099,6 +3105,77 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) | |||
| 3099 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; | 3105 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; |
| 3100 | } | 3106 | } |
| 3101 | 3107 | ||
| 3108 | static int novatd_read_status_override(struct dvb_frontend *fe, | ||
| 3109 | fe_status_t *stat) | ||
| 3110 | { | ||
| 3111 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
| 3112 | struct dvb_usb_device *dev = adap->dev; | ||
| 3113 | struct dib0700_state *state = dev->priv; | ||
| 3114 | int ret; | ||
| 3115 | |||
| 3116 | ret = state->read_status(fe, stat); | ||
| 3117 | |||
| 3118 | if (!ret) | ||
| 3119 | dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, | ||
| 3120 | !!(*stat & FE_HAS_LOCK)); | ||
| 3121 | |||
| 3122 | return ret; | ||
| 3123 | } | ||
| 3124 | |||
| 3125 | static int novatd_sleep_override(struct dvb_frontend* fe) | ||
| 3126 | { | ||
| 3127 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
| 3128 | struct dvb_usb_device *dev = adap->dev; | ||
| 3129 | struct dib0700_state *state = dev->priv; | ||
| 3130 | |||
| 3131 | /* turn off LED */ | ||
| 3132 | dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0); | ||
| 3133 | |||
| 3134 | return state->sleep(fe); | ||
| 3135 | } | ||
| 3136 | |||
| 3137 | /** | ||
| 3138 | * novatd_frontend_attach - Nova-TD specific attach | ||
| 3139 | * | ||
| 3140 | * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for | ||
| 3141 | * information purposes. | ||
| 3142 | */ | ||
| 3143 | static int novatd_frontend_attach(struct dvb_usb_adapter *adap) | ||
| 3144 | { | ||
| 3145 | struct dvb_usb_device *dev = adap->dev; | ||
| 3146 | struct dib0700_state *st = dev->priv; | ||
| 3147 | |||
| 3148 | if (adap->id == 0) { | ||
| 3149 | stk7070pd_init(dev); | ||
| 3150 | |||
| 3151 | /* turn the power LED on, the other two off (just in case) */ | ||
| 3152 | dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0); | ||
| 3153 | dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0); | ||
| 3154 | dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1); | ||
| 3155 | |||
| 3156 | if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18, | ||
| 3157 | stk7070pd_dib7000p_config) != 0) { | ||
| 3158 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", | ||
| 3159 | __func__); | ||
| 3160 | return -ENODEV; | ||
| 3161 | } | ||
| 3162 | } | ||
| 3163 | |||
| 3164 | adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap, | ||
| 3165 | adap->id == 0 ? 0x80 : 0x82, | ||
| 3166 | &stk7070pd_dib7000p_config[adap->id]); | ||
| 3167 | |||
| 3168 | if (adap->fe_adap[0].fe == NULL) | ||
| 3169 | return -ENODEV; | ||
| 3170 | |||
| 3171 | st->read_status = adap->fe_adap[0].fe->ops.read_status; | ||
| 3172 | adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override; | ||
| 3173 | st->sleep = adap->fe_adap[0].fe->ops.sleep; | ||
| 3174 | adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override; | ||
| 3175 | |||
| 3176 | return 0; | ||
| 3177 | } | ||
| 3178 | |||
| 3102 | /* S5H1411 */ | 3179 | /* S5H1411 */ |
| 3103 | static struct s5h1411_config pinnacle_801e_config = { | 3180 | static struct s5h1411_config pinnacle_801e_config = { |
| 3104 | .output_mode = S5H1411_PARALLEL_OUTPUT, | 3181 | .output_mode = S5H1411_PARALLEL_OUTPUT, |
| @@ -3870,6 +3947,57 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
| 3870 | .pid_filter_count = 32, | 3947 | .pid_filter_count = 32, |
| 3871 | .pid_filter = stk70x0p_pid_filter, | 3948 | .pid_filter = stk70x0p_pid_filter, |
| 3872 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | 3949 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, |
| 3950 | .frontend_attach = novatd_frontend_attach, | ||
| 3951 | .tuner_attach = dib7070p_tuner_attach, | ||
| 3952 | |||
| 3953 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
| 3954 | }}, | ||
| 3955 | .size_of_priv = sizeof(struct dib0700_adapter_state), | ||
| 3956 | }, { | ||
| 3957 | .num_frontends = 1, | ||
| 3958 | .fe = {{ | ||
| 3959 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
| 3960 | .pid_filter_count = 32, | ||
| 3961 | .pid_filter = stk70x0p_pid_filter, | ||
| 3962 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
| 3963 | .frontend_attach = novatd_frontend_attach, | ||
| 3964 | .tuner_attach = dib7070p_tuner_attach, | ||
| 3965 | |||
| 3966 | DIB0700_DEFAULT_STREAMING_CONFIG(0x03), | ||
| 3967 | }}, | ||
| 3968 | .size_of_priv = sizeof(struct dib0700_adapter_state), | ||
| 3969 | } | ||
| 3970 | }, | ||
| 3971 | |||
| 3972 | .num_device_descs = 1, | ||
| 3973 | .devices = { | ||
| 3974 | { "Hauppauge Nova-TD Stick (52009)", | ||
| 3975 | { &dib0700_usb_id_table[35], NULL }, | ||
| 3976 | { NULL }, | ||
| 3977 | }, | ||
| 3978 | }, | ||
| 3979 | |||
| 3980 | .rc.core = { | ||
| 3981 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
| 3982 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
| 3983 | .module_name = "dib0700", | ||
| 3984 | .rc_query = dib0700_rc_query_old_firmware, | ||
| 3985 | .allowed_protos = RC_TYPE_RC5 | | ||
| 3986 | RC_TYPE_RC6 | | ||
| 3987 | RC_TYPE_NEC, | ||
| 3988 | .change_protocol = dib0700_change_protocol, | ||
| 3989 | }, | ||
| 3990 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
| 3991 | |||
| 3992 | .num_adapters = 2, | ||
| 3993 | .adapter = { | ||
| 3994 | { | ||
| 3995 | .num_frontends = 1, | ||
| 3996 | .fe = {{ | ||
| 3997 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
| 3998 | .pid_filter_count = 32, | ||
| 3999 | .pid_filter = stk70x0p_pid_filter, | ||
| 4000 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
| 3873 | .frontend_attach = stk7070pd_frontend_attach0, | 4001 | .frontend_attach = stk7070pd_frontend_attach0, |
| 3874 | .tuner_attach = dib7070p_tuner_attach, | 4002 | .tuner_attach = dib7070p_tuner_attach, |
| 3875 | 4003 | ||
| @@ -3892,7 +4020,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
| 3892 | } | 4020 | } |
| 3893 | }, | 4021 | }, |
| 3894 | 4022 | ||
| 3895 | .num_device_descs = 6, | 4023 | .num_device_descs = 5, |
| 3896 | .devices = { | 4024 | .devices = { |
| 3897 | { "DiBcom STK7070PD reference design", | 4025 | { "DiBcom STK7070PD reference design", |
| 3898 | { &dib0700_usb_id_table[17], NULL }, | 4026 | { &dib0700_usb_id_table[17], NULL }, |
| @@ -3902,10 +4030,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
| 3902 | { &dib0700_usb_id_table[18], NULL }, | 4030 | { &dib0700_usb_id_table[18], NULL }, |
| 3903 | { NULL }, | 4031 | { NULL }, |
| 3904 | }, | 4032 | }, |
| 3905 | { "Hauppauge Nova-TD Stick (52009)", | ||
| 3906 | { &dib0700_usb_id_table[35], NULL }, | ||
| 3907 | { NULL }, | ||
| 3908 | }, | ||
| 3909 | { "Hauppauge Nova-TD-500 (84xxx)", | 4033 | { "Hauppauge Nova-TD-500 (84xxx)", |
| 3910 | { &dib0700_usb_id_table[36], NULL }, | 4034 | { &dib0700_usb_id_table[36], NULL }, |
| 3911 | { NULL }, | 4035 | { NULL }, |
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c index 93e1b12e7907..caae7f79c837 100644 --- a/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/drivers/media/dvb/frontends/cxd2820r_core.c | |||
| @@ -309,9 +309,14 @@ static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
| 309 | 309 | ||
| 310 | static int cxd2820r_get_frontend(struct dvb_frontend *fe) | 310 | static int cxd2820r_get_frontend(struct dvb_frontend *fe) |
| 311 | { | 311 | { |
| 312 | struct cxd2820r_priv *priv = fe->demodulator_priv; | ||
| 312 | int ret; | 313 | int ret; |
| 313 | 314 | ||
| 314 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); | 315 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); |
| 316 | |||
| 317 | if (priv->delivery_system == SYS_UNDEFINED) | ||
| 318 | return 0; | ||
| 319 | |||
| 315 | switch (fe->dtv_property_cache.delivery_system) { | 320 | switch (fe->dtv_property_cache.delivery_system) { |
| 316 | case SYS_DVBT: | 321 | case SYS_DVBT: |
| 317 | ret = cxd2820r_get_frontend_t(fe); | 322 | ret = cxd2820r_get_frontend_t(fe); |
| @@ -476,10 +481,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
| 476 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); | 481 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); |
| 477 | 482 | ||
| 478 | /* switch between DVB-T and DVB-T2 when tune fails */ | 483 | /* switch between DVB-T and DVB-T2 when tune fails */ |
| 479 | if (priv->last_tune_failed && (priv->delivery_system != SYS_DVBC_ANNEX_A)) { | 484 | if (priv->last_tune_failed) { |
| 480 | if (priv->delivery_system == SYS_DVBT) | 485 | if (priv->delivery_system == SYS_DVBT) |
| 481 | c->delivery_system = SYS_DVBT2; | 486 | c->delivery_system = SYS_DVBT2; |
| 482 | else | 487 | else if (priv->delivery_system == SYS_DVBT2) |
| 483 | c->delivery_system = SYS_DVBT; | 488 | c->delivery_system = SYS_DVBT; |
| 484 | } | 489 | } |
| 485 | 490 | ||
| @@ -492,6 +497,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
| 492 | /* frontend lock wait loop count */ | 497 | /* frontend lock wait loop count */ |
| 493 | switch (priv->delivery_system) { | 498 | switch (priv->delivery_system) { |
| 494 | case SYS_DVBT: | 499 | case SYS_DVBT: |
| 500 | case SYS_DVBC_ANNEX_A: | ||
| 495 | i = 20; | 501 | i = 20; |
| 496 | break; | 502 | break; |
| 497 | case SYS_DVBT2: | 503 | case SYS_DVBT2: |
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 938777065de6..af65d013db11 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c | |||
| @@ -1195,7 +1195,7 @@ static int ds3000_set_frontend(struct dvb_frontend *fe) | |||
| 1195 | 1195 | ||
| 1196 | for (i = 0; i < 30 ; i++) { | 1196 | for (i = 0; i < 30 ; i++) { |
| 1197 | ds3000_read_status(fe, &status); | 1197 | ds3000_read_status(fe, &status); |
| 1198 | if (status && FE_HAS_LOCK) | 1198 | if (status & FE_HAS_LOCK) |
| 1199 | break; | 1199 | break; |
| 1200 | 1200 | ||
| 1201 | msleep(10); | 1201 | msleep(10); |
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c index 7fa3e472cdca..fade566927c3 100644 --- a/drivers/media/dvb/frontends/mb86a20s.c +++ b/drivers/media/dvb/frontends/mb86a20s.c | |||
| @@ -402,7 +402,7 @@ static int mb86a20s_get_modulation(struct mb86a20s_state *state, | |||
| 402 | [2] = 0x8e, /* Layer C */ | 402 | [2] = 0x8e, /* Layer C */ |
| 403 | }; | 403 | }; |
| 404 | 404 | ||
| 405 | if (layer > ARRAY_SIZE(reg)) | 405 | if (layer >= ARRAY_SIZE(reg)) |
| 406 | return -EINVAL; | 406 | return -EINVAL; |
| 407 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 407 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
| 408 | if (rc < 0) | 408 | if (rc < 0) |
| @@ -435,7 +435,7 @@ static int mb86a20s_get_fec(struct mb86a20s_state *state, | |||
| 435 | [2] = 0x8f, /* Layer C */ | 435 | [2] = 0x8f, /* Layer C */ |
| 436 | }; | 436 | }; |
| 437 | 437 | ||
| 438 | if (layer > ARRAY_SIZE(reg)) | 438 | if (layer >= ARRAY_SIZE(reg)) |
| 439 | return -EINVAL; | 439 | return -EINVAL; |
| 440 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 440 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
| 441 | if (rc < 0) | 441 | if (rc < 0) |
| @@ -470,7 +470,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state, | |||
| 470 | [2] = 0x90, /* Layer C */ | 470 | [2] = 0x90, /* Layer C */ |
| 471 | }; | 471 | }; |
| 472 | 472 | ||
| 473 | if (layer > ARRAY_SIZE(reg)) | 473 | if (layer >= ARRAY_SIZE(reg)) |
| 474 | return -EINVAL; | 474 | return -EINVAL; |
| 475 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 475 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
| 476 | if (rc < 0) | 476 | if (rc < 0) |
| @@ -494,7 +494,7 @@ static int mb86a20s_get_segment_count(struct mb86a20s_state *state, | |||
| 494 | [2] = 0x91, /* Layer C */ | 494 | [2] = 0x91, /* Layer C */ |
| 495 | }; | 495 | }; |
| 496 | 496 | ||
| 497 | if (layer > ARRAY_SIZE(reg)) | 497 | if (layer >= ARRAY_SIZE(reg)) |
| 498 | return -EINVAL; | 498 | return -EINVAL; |
| 499 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 499 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
| 500 | if (rc < 0) | 500 | if (rc < 0) |
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c index 86da3d816498..ad7c72e8f517 100644 --- a/drivers/media/dvb/frontends/tda18271c2dd.c +++ b/drivers/media/dvb/frontends/tda18271c2dd.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 30 | #include <linux/firmware.h> | 30 | #include <linux/firmware.h> |
| 31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
| 32 | #include <linux/version.h> | ||
| 33 | #include <asm/div64.h> | 32 | #include <asm/div64.h> |
| 34 | 33 | ||
| 35 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c index ec859a580651..f241702a0f36 100644 --- a/drivers/media/video/as3645a.c +++ b/drivers/media/video/as3645a.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
| 32 | #include <linux/slab.h> | ||
| 32 | 33 | ||
| 33 | #include <media/as3645a.h> | 34 | #include <media/as3645a.h> |
| 34 | #include <media/v4l2-ctrls.h> | 35 | #include <media/v4l2-ctrls.h> |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 14cb961c22bd..4bfd865a4106 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
| @@ -751,20 +751,10 @@ int cx18_v4l2_close(struct file *filp) | |||
| 751 | 751 | ||
| 752 | CX18_DEBUG_IOCTL("close() of %s\n", s->name); | 752 | CX18_DEBUG_IOCTL("close() of %s\n", s->name); |
| 753 | 753 | ||
| 754 | v4l2_fh_del(fh); | ||
| 755 | v4l2_fh_exit(fh); | ||
| 756 | |||
| 757 | /* Easy case first: this stream was never claimed by us */ | ||
| 758 | if (s->id != id->open_id) { | ||
| 759 | kfree(id); | ||
| 760 | return 0; | ||
| 761 | } | ||
| 762 | |||
| 763 | /* 'Unclaim' this stream */ | ||
| 764 | |||
| 765 | /* Stop radio */ | ||
| 766 | mutex_lock(&cx->serialize_lock); | 754 | mutex_lock(&cx->serialize_lock); |
| 767 | if (id->type == CX18_ENC_STREAM_TYPE_RAD) { | 755 | /* Stop radio */ |
| 756 | if (id->type == CX18_ENC_STREAM_TYPE_RAD && | ||
| 757 | v4l2_fh_is_singular_file(filp)) { | ||
| 768 | /* Closing radio device, return to TV mode */ | 758 | /* Closing radio device, return to TV mode */ |
| 769 | cx18_mute(cx); | 759 | cx18_mute(cx); |
| 770 | /* Mark that the radio is no longer in use */ | 760 | /* Mark that the radio is no longer in use */ |
| @@ -781,10 +771,14 @@ int cx18_v4l2_close(struct file *filp) | |||
| 781 | } | 771 | } |
| 782 | /* Done! Unmute and continue. */ | 772 | /* Done! Unmute and continue. */ |
| 783 | cx18_unmute(cx); | 773 | cx18_unmute(cx); |
| 784 | cx18_release_stream(s); | ||
| 785 | } else { | ||
| 786 | cx18_stop_capture(id, 0); | ||
| 787 | } | 774 | } |
| 775 | |||
| 776 | v4l2_fh_del(fh); | ||
| 777 | v4l2_fh_exit(fh); | ||
| 778 | |||
| 779 | /* 'Unclaim' this stream */ | ||
| 780 | if (s->id == id->open_id) | ||
| 781 | cx18_stop_capture(id, 0); | ||
| 788 | kfree(id); | 782 | kfree(id); |
| 789 | mutex_unlock(&cx->serialize_lock); | 783 | mutex_unlock(&cx->serialize_lock); |
| 790 | return 0; | 784 | return 0; |
| @@ -810,21 +804,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
| 810 | 804 | ||
| 811 | item->open_id = cx->open_id++; | 805 | item->open_id = cx->open_id++; |
| 812 | filp->private_data = &item->fh; | 806 | filp->private_data = &item->fh; |
| 807 | v4l2_fh_add(&item->fh); | ||
| 813 | 808 | ||
| 814 | if (item->type == CX18_ENC_STREAM_TYPE_RAD) { | 809 | if (item->type == CX18_ENC_STREAM_TYPE_RAD && |
| 815 | /* Try to claim this stream */ | 810 | v4l2_fh_is_singular_file(filp)) { |
| 816 | if (cx18_claim_stream(item, item->type)) { | ||
| 817 | /* No, it's already in use */ | ||
| 818 | v4l2_fh_exit(&item->fh); | ||
| 819 | kfree(item); | ||
| 820 | return -EBUSY; | ||
| 821 | } | ||
| 822 | |||
| 823 | if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { | 811 | if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { |
| 824 | if (atomic_read(&cx->ana_capturing) > 0) { | 812 | if (atomic_read(&cx->ana_capturing) > 0) { |
| 825 | /* switching to radio while capture is | 813 | /* switching to radio while capture is |
| 826 | in progress is not polite */ | 814 | in progress is not polite */ |
| 827 | cx18_release_stream(s); | 815 | v4l2_fh_del(&item->fh); |
| 828 | v4l2_fh_exit(&item->fh); | 816 | v4l2_fh_exit(&item->fh); |
| 829 | kfree(item); | 817 | kfree(item); |
| 830 | return -EBUSY; | 818 | return -EBUSY; |
| @@ -842,7 +830,6 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
| 842 | /* Done! Unmute and continue. */ | 830 | /* Done! Unmute and continue. */ |
| 843 | cx18_unmute(cx); | 831 | cx18_unmute(cx); |
| 844 | } | 832 | } |
| 845 | v4l2_fh_add(&item->fh); | ||
| 846 | return 0; | 833 | return 0; |
| 847 | } | 834 | } |
| 848 | 835 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 919ed77b32f2..875a7ce94736 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
| @@ -1052,7 +1052,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
| 1052 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1052 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 1053 | if (dev == NULL) { | 1053 | if (dev == NULL) { |
| 1054 | cx231xx_err(DRIVER_NAME ": out of memory!\n"); | 1054 | cx231xx_err(DRIVER_NAME ": out of memory!\n"); |
| 1055 | clear_bit(dev->devno, &cx231xx_devused); | 1055 | clear_bit(nr, &cx231xx_devused); |
| 1056 | return -ENOMEM; | 1056 | return -ENOMEM; |
| 1057 | } | 1057 | } |
| 1058 | 1058 | ||
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 3c01be999e35..19b5499d2624 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
| @@ -213,8 +213,8 @@ struct cx23885_board cx23885_boards[] = { | |||
| 213 | .portc = CX23885_MPEG_DVB, | 213 | .portc = CX23885_MPEG_DVB, |
| 214 | .tuner_type = TUNER_XC4000, | 214 | .tuner_type = TUNER_XC4000, |
| 215 | .tuner_addr = 0x61, | 215 | .tuner_addr = 0x61, |
| 216 | .radio_type = TUNER_XC4000, | 216 | .radio_type = UNSET, |
| 217 | .radio_addr = 0x61, | 217 | .radio_addr = ADDR_UNSET, |
| 218 | .input = {{ | 218 | .input = {{ |
| 219 | .type = CX23885_VMUX_TELEVISION, | 219 | .type = CX23885_VMUX_TELEVISION, |
| 220 | .vmux = CX25840_VIN2_CH1 | | 220 | .vmux = CX25840_VIN2_CH1 | |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index af8a225763d3..6835eb1fc093 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
| @@ -943,6 +943,11 @@ static int dvb_register(struct cx23885_tsport *port) | |||
| 943 | 943 | ||
| 944 | fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, | 944 | fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, |
| 945 | &dev->i2c_bus[1].i2c_adap, &cfg); | 945 | &dev->i2c_bus[1].i2c_adap, &cfg); |
| 946 | if (!fe) { | ||
| 947 | printk(KERN_ERR "%s/2: xc4000 attach failed\n", | ||
| 948 | dev->name); | ||
| 949 | goto frontend_detach; | ||
| 950 | } | ||
| 946 | } | 951 | } |
| 947 | break; | 952 | break; |
| 948 | case CX23885_BOARD_TBS_6920: | 953 | case CX23885_BOARD_TBS_6920: |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 4bbf9bb97bde..c654bdc7ccb2 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
| @@ -1550,7 +1550,6 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
| 1550 | struct v4l2_control ctrl; | 1550 | struct v4l2_control ctrl; |
| 1551 | struct videobuf_dvb_frontend *vfe; | 1551 | struct videobuf_dvb_frontend *vfe; |
| 1552 | struct dvb_frontend *fe; | 1552 | struct dvb_frontend *fe; |
| 1553 | int err = 0; | ||
| 1554 | 1553 | ||
| 1555 | struct analog_parameters params = { | 1554 | struct analog_parameters params = { |
| 1556 | .mode = V4L2_TUNER_ANALOG_TV, | 1555 | .mode = V4L2_TUNER_ANALOG_TV, |
| @@ -1572,8 +1571,10 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
| 1572 | params.frequency, f->tuner, params.std); | 1571 | params.frequency, f->tuner, params.std); |
| 1573 | 1572 | ||
| 1574 | vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1); | 1573 | vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1); |
| 1575 | if (!vfe) | 1574 | if (!vfe) { |
| 1576 | err = -EINVAL; | 1575 | mutex_unlock(&dev->lock); |
| 1576 | return -EINVAL; | ||
| 1577 | } | ||
| 1577 | 1578 | ||
| 1578 | fe = vfe->dvb.frontend; | 1579 | fe = vfe->dvb.frontend; |
| 1579 | 1580 | ||
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 62c7ad050f9b..cbd5d119a2c6 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
| @@ -1573,8 +1573,8 @@ static const struct cx88_board cx88_boards[] = { | |||
| 1573 | .name = "Pinnacle Hybrid PCTV", | 1573 | .name = "Pinnacle Hybrid PCTV", |
| 1574 | .tuner_type = TUNER_XC2028, | 1574 | .tuner_type = TUNER_XC2028, |
| 1575 | .tuner_addr = 0x61, | 1575 | .tuner_addr = 0x61, |
| 1576 | .radio_type = TUNER_XC2028, | 1576 | .radio_type = UNSET, |
| 1577 | .radio_addr = 0x61, | 1577 | .radio_addr = ADDR_UNSET, |
| 1578 | .input = { { | 1578 | .input = { { |
| 1579 | .type = CX88_VMUX_TELEVISION, | 1579 | .type = CX88_VMUX_TELEVISION, |
| 1580 | .vmux = 0, | 1580 | .vmux = 0, |
| @@ -1611,8 +1611,8 @@ static const struct cx88_board cx88_boards[] = { | |||
| 1611 | .name = "Leadtek TV2000 XP Global", | 1611 | .name = "Leadtek TV2000 XP Global", |
| 1612 | .tuner_type = TUNER_XC2028, | 1612 | .tuner_type = TUNER_XC2028, |
| 1613 | .tuner_addr = 0x61, | 1613 | .tuner_addr = 0x61, |
| 1614 | .radio_type = TUNER_XC2028, | 1614 | .radio_type = UNSET, |
| 1615 | .radio_addr = 0x61, | 1615 | .radio_addr = ADDR_UNSET, |
| 1616 | .input = { { | 1616 | .input = { { |
| 1617 | .type = CX88_VMUX_TELEVISION, | 1617 | .type = CX88_VMUX_TELEVISION, |
| 1618 | .vmux = 0, | 1618 | .vmux = 0, |
| @@ -2115,8 +2115,8 @@ static const struct cx88_board cx88_boards[] = { | |||
| 2115 | .name = "Terratec Cinergy HT PCI MKII", | 2115 | .name = "Terratec Cinergy HT PCI MKII", |
| 2116 | .tuner_type = TUNER_XC2028, | 2116 | .tuner_type = TUNER_XC2028, |
| 2117 | .tuner_addr = 0x61, | 2117 | .tuner_addr = 0x61, |
| 2118 | .radio_type = TUNER_XC2028, | 2118 | .radio_type = UNSET, |
| 2119 | .radio_addr = 0x61, | 2119 | .radio_addr = ADDR_UNSET, |
| 2120 | .input = { { | 2120 | .input = { { |
| 2121 | .type = CX88_VMUX_TELEVISION, | 2121 | .type = CX88_VMUX_TELEVISION, |
| 2122 | .vmux = 0, | 2122 | .vmux = 0, |
| @@ -2154,9 +2154,9 @@ static const struct cx88_board cx88_boards[] = { | |||
| 2154 | [CX88_BOARD_WINFAST_DTV1800H] = { | 2154 | [CX88_BOARD_WINFAST_DTV1800H] = { |
| 2155 | .name = "Leadtek WinFast DTV1800 Hybrid", | 2155 | .name = "Leadtek WinFast DTV1800 Hybrid", |
| 2156 | .tuner_type = TUNER_XC2028, | 2156 | .tuner_type = TUNER_XC2028, |
| 2157 | .radio_type = TUNER_XC2028, | 2157 | .radio_type = UNSET, |
| 2158 | .tuner_addr = 0x61, | 2158 | .tuner_addr = 0x61, |
| 2159 | .radio_addr = 0x61, | 2159 | .radio_addr = ADDR_UNSET, |
| 2160 | /* | 2160 | /* |
| 2161 | * GPIO setting | 2161 | * GPIO setting |
| 2162 | * | 2162 | * |
| @@ -2195,9 +2195,9 @@ static const struct cx88_board cx88_boards[] = { | |||
| 2195 | [CX88_BOARD_WINFAST_DTV1800H_XC4000] = { | 2195 | [CX88_BOARD_WINFAST_DTV1800H_XC4000] = { |
| 2196 | .name = "Leadtek WinFast DTV1800 H (XC4000)", | 2196 | .name = "Leadtek WinFast DTV1800 H (XC4000)", |
| 2197 | .tuner_type = TUNER_XC4000, | 2197 | .tuner_type = TUNER_XC4000, |
| 2198 | .radio_type = TUNER_XC4000, | 2198 | .radio_type = UNSET, |
| 2199 | .tuner_addr = 0x61, | 2199 | .tuner_addr = 0x61, |
| 2200 | .radio_addr = 0x61, | 2200 | .radio_addr = ADDR_UNSET, |
| 2201 | /* | 2201 | /* |
| 2202 | * GPIO setting | 2202 | * GPIO setting |
| 2203 | * | 2203 | * |
| @@ -2236,9 +2236,9 @@ static const struct cx88_board cx88_boards[] = { | |||
| 2236 | [CX88_BOARD_WINFAST_DTV2000H_PLUS] = { | 2236 | [CX88_BOARD_WINFAST_DTV2000H_PLUS] = { |
| 2237 | .name = "Leadtek WinFast DTV2000 H PLUS", | 2237 | .name = "Leadtek WinFast DTV2000 H PLUS", |
| 2238 | .tuner_type = TUNER_XC4000, | 2238 | .tuner_type = TUNER_XC4000, |
| 2239 | .radio_type = TUNER_XC4000, | 2239 | .radio_type = UNSET, |
| 2240 | .tuner_addr = 0x61, | 2240 | .tuner_addr = 0x61, |
| 2241 | .radio_addr = 0x61, | 2241 | .radio_addr = ADDR_UNSET, |
| 2242 | /* | 2242 | /* |
| 2243 | * GPIO | 2243 | * GPIO |
| 2244 | * 2: 1: mute audio | 2244 | * 2: 1: mute audio |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 544af91cbdc1..3949b7dc2368 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
| @@ -731,9 +731,6 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) | |||
| 731 | 731 | ||
| 732 | init_kthread_work(&itv->irq_work, ivtv_irq_work_handler); | 732 | init_kthread_work(&itv->irq_work, ivtv_irq_work_handler); |
| 733 | 733 | ||
| 734 | /* start counting open_id at 1 */ | ||
| 735 | itv->open_id = 1; | ||
| 736 | |||
| 737 | /* Initial settings */ | 734 | /* Initial settings */ |
| 738 | itv->cxhdl.port = CX2341X_PORT_MEMORY; | 735 | itv->cxhdl.port = CX2341X_PORT_MEMORY; |
| 739 | itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI; | 736 | itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI; |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 8f9cc17b518e..06f3d78389bf 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
| @@ -332,7 +332,7 @@ struct ivtv_stream { | |||
| 332 | const char *name; /* name of the stream */ | 332 | const char *name; /* name of the stream */ |
| 333 | int type; /* stream type */ | 333 | int type; /* stream type */ |
| 334 | 334 | ||
| 335 | u32 id; | 335 | struct v4l2_fh *fh; /* pointer to the streaming filehandle */ |
| 336 | spinlock_t qlock; /* locks access to the queues */ | 336 | spinlock_t qlock; /* locks access to the queues */ |
| 337 | unsigned long s_flags; /* status flags, see above */ | 337 | unsigned long s_flags; /* status flags, see above */ |
| 338 | int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ | 338 | int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ |
| @@ -379,7 +379,6 @@ struct ivtv_stream { | |||
| 379 | 379 | ||
| 380 | struct ivtv_open_id { | 380 | struct ivtv_open_id { |
| 381 | struct v4l2_fh fh; | 381 | struct v4l2_fh fh; |
| 382 | u32 open_id; /* unique ID for this file descriptor */ | ||
| 383 | int type; /* stream type */ | 382 | int type; /* stream type */ |
| 384 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ | 383 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ |
| 385 | struct ivtv *itv; | 384 | struct ivtv *itv; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 38f052257f46..2cd6c89b7d91 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
| @@ -50,16 +50,16 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) | |||
| 50 | 50 | ||
| 51 | if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { | 51 | if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { |
| 52 | /* someone already claimed this stream */ | 52 | /* someone already claimed this stream */ |
| 53 | if (s->id == id->open_id) { | 53 | if (s->fh == &id->fh) { |
| 54 | /* yes, this file descriptor did. So that's OK. */ | 54 | /* yes, this file descriptor did. So that's OK. */ |
| 55 | return 0; | 55 | return 0; |
| 56 | } | 56 | } |
| 57 | if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI || | 57 | if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI || |
| 58 | type == IVTV_ENC_STREAM_TYPE_VBI)) { | 58 | type == IVTV_ENC_STREAM_TYPE_VBI)) { |
| 59 | /* VBI is handled already internally, now also assign | 59 | /* VBI is handled already internally, now also assign |
| 60 | the file descriptor to this stream for external | 60 | the file descriptor to this stream for external |
| 61 | reading of the stream. */ | 61 | reading of the stream. */ |
| 62 | s->id = id->open_id; | 62 | s->fh = &id->fh; |
| 63 | IVTV_DEBUG_INFO("Start Read VBI\n"); | 63 | IVTV_DEBUG_INFO("Start Read VBI\n"); |
| 64 | return 0; | 64 | return 0; |
| 65 | } | 65 | } |
| @@ -67,7 +67,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) | |||
| 67 | IVTV_DEBUG_INFO("Stream %d is busy\n", type); | 67 | IVTV_DEBUG_INFO("Stream %d is busy\n", type); |
| 68 | return -EBUSY; | 68 | return -EBUSY; |
| 69 | } | 69 | } |
| 70 | s->id = id->open_id; | 70 | s->fh = &id->fh; |
| 71 | if (type == IVTV_DEC_STREAM_TYPE_VBI) { | 71 | if (type == IVTV_DEC_STREAM_TYPE_VBI) { |
| 72 | /* Enable reinsertion interrupt */ | 72 | /* Enable reinsertion interrupt */ |
| 73 | ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); | 73 | ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); |
| @@ -104,7 +104,7 @@ void ivtv_release_stream(struct ivtv_stream *s) | |||
| 104 | struct ivtv *itv = s->itv; | 104 | struct ivtv *itv = s->itv; |
| 105 | struct ivtv_stream *s_vbi; | 105 | struct ivtv_stream *s_vbi; |
| 106 | 106 | ||
| 107 | s->id = -1; | 107 | s->fh = NULL; |
| 108 | if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && | 108 | if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && |
| 109 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { | 109 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { |
| 110 | /* this stream is still in use internally */ | 110 | /* this stream is still in use internally */ |
| @@ -136,7 +136,7 @@ void ivtv_release_stream(struct ivtv_stream *s) | |||
| 136 | /* was already cleared */ | 136 | /* was already cleared */ |
| 137 | return; | 137 | return; |
| 138 | } | 138 | } |
| 139 | if (s_vbi->id != -1) { | 139 | if (s_vbi->fh) { |
| 140 | /* VBI stream still claimed by a file descriptor */ | 140 | /* VBI stream still claimed by a file descriptor */ |
| 141 | return; | 141 | return; |
| 142 | } | 142 | } |
| @@ -268,11 +268,13 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, | |||
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | /* wait for more data to arrive */ | 270 | /* wait for more data to arrive */ |
| 271 | mutex_unlock(&itv->serialize_lock); | ||
| 271 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | 272 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); |
| 272 | /* New buffers might have become available before we were added to the waitqueue */ | 273 | /* New buffers might have become available before we were added to the waitqueue */ |
| 273 | if (!s->q_full.buffers) | 274 | if (!s->q_full.buffers) |
| 274 | schedule(); | 275 | schedule(); |
| 275 | finish_wait(&s->waitq, &wait); | 276 | finish_wait(&s->waitq, &wait); |
| 277 | mutex_lock(&itv->serialize_lock); | ||
| 276 | if (signal_pending(current)) { | 278 | if (signal_pending(current)) { |
| 277 | /* return if a signal was received */ | 279 | /* return if a signal was received */ |
| 278 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); | 280 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); |
| @@ -357,7 +359,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co | |||
| 357 | size_t tot_written = 0; | 359 | size_t tot_written = 0; |
| 358 | int single_frame = 0; | 360 | int single_frame = 0; |
| 359 | 361 | ||
| 360 | if (atomic_read(&itv->capturing) == 0 && s->id == -1) { | 362 | if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) { |
| 361 | /* shouldn't happen */ | 363 | /* shouldn't happen */ |
| 362 | IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); | 364 | IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); |
| 363 | return -EIO; | 365 | return -EIO; |
| @@ -507,9 +509,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ | |||
| 507 | 509 | ||
| 508 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); | 510 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); |
| 509 | 511 | ||
| 510 | mutex_lock(&itv->serialize_lock); | ||
| 511 | rc = ivtv_start_capture(id); | 512 | rc = ivtv_start_capture(id); |
| 512 | mutex_unlock(&itv->serialize_lock); | ||
| 513 | if (rc) | 513 | if (rc) |
| 514 | return rc; | 514 | return rc; |
| 515 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); | 515 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); |
| @@ -584,9 +584,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c | |||
| 584 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | 584 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); |
| 585 | 585 | ||
| 586 | /* Start decoder (returns 0 if already started) */ | 586 | /* Start decoder (returns 0 if already started) */ |
| 587 | mutex_lock(&itv->serialize_lock); | ||
| 588 | rc = ivtv_start_decoding(id, itv->speed); | 587 | rc = ivtv_start_decoding(id, itv->speed); |
| 589 | mutex_unlock(&itv->serialize_lock); | ||
| 590 | if (rc) { | 588 | if (rc) { |
| 591 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); | 589 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); |
| 592 | 590 | ||
| @@ -627,11 +625,13 @@ retry: | |||
| 627 | break; | 625 | break; |
| 628 | if (filp->f_flags & O_NONBLOCK) | 626 | if (filp->f_flags & O_NONBLOCK) |
| 629 | return -EAGAIN; | 627 | return -EAGAIN; |
| 628 | mutex_unlock(&itv->serialize_lock); | ||
| 630 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | 629 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); |
| 631 | /* New buffers might have become free before we were added to the waitqueue */ | 630 | /* New buffers might have become free before we were added to the waitqueue */ |
| 632 | if (!s->q_free.buffers) | 631 | if (!s->q_free.buffers) |
| 633 | schedule(); | 632 | schedule(); |
| 634 | finish_wait(&s->waitq, &wait); | 633 | finish_wait(&s->waitq, &wait); |
| 634 | mutex_lock(&itv->serialize_lock); | ||
| 635 | if (signal_pending(current)) { | 635 | if (signal_pending(current)) { |
| 636 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); | 636 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); |
| 637 | return -EINTR; | 637 | return -EINTR; |
| @@ -686,12 +686,14 @@ retry: | |||
| 686 | if (mode == OUT_YUV) | 686 | if (mode == OUT_YUV) |
| 687 | ivtv_yuv_setup_stream_frame(itv); | 687 | ivtv_yuv_setup_stream_frame(itv); |
| 688 | 688 | ||
| 689 | mutex_unlock(&itv->serialize_lock); | ||
| 689 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | 690 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); |
| 690 | while (!(got_sig = signal_pending(current)) && | 691 | while (!(got_sig = signal_pending(current)) && |
| 691 | test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { | 692 | test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { |
| 692 | schedule(); | 693 | schedule(); |
| 693 | } | 694 | } |
| 694 | finish_wait(&itv->dma_waitq, &wait); | 695 | finish_wait(&itv->dma_waitq, &wait); |
| 696 | mutex_lock(&itv->serialize_lock); | ||
| 695 | if (got_sig) { | 697 | if (got_sig) { |
| 696 | IVTV_DEBUG_INFO("User interrupted %s\n", s->name); | 698 | IVTV_DEBUG_INFO("User interrupted %s\n", s->name); |
| 697 | return -EINTR; | 699 | return -EINTR; |
| @@ -756,9 +758,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) | |||
| 756 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | 758 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
| 757 | int rc; | 759 | int rc; |
| 758 | 760 | ||
| 759 | mutex_lock(&itv->serialize_lock); | ||
| 760 | rc = ivtv_start_capture(id); | 761 | rc = ivtv_start_capture(id); |
| 761 | mutex_unlock(&itv->serialize_lock); | ||
| 762 | if (rc) { | 762 | if (rc) { |
| 763 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", | 763 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", |
| 764 | s->name, rc); | 764 | s->name, rc); |
| @@ -808,7 +808,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end) | |||
| 808 | id->type == IVTV_ENC_STREAM_TYPE_VBI) && | 808 | id->type == IVTV_ENC_STREAM_TYPE_VBI) && |
| 809 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { | 809 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { |
| 810 | /* Also used internally, don't stop capturing */ | 810 | /* Also used internally, don't stop capturing */ |
| 811 | s->id = -1; | 811 | s->fh = NULL; |
| 812 | } | 812 | } |
| 813 | else { | 813 | else { |
| 814 | ivtv_stop_v4l2_encode_stream(s, gop_end); | 814 | ivtv_stop_v4l2_encode_stream(s, gop_end); |
| @@ -861,20 +861,9 @@ int ivtv_v4l2_close(struct file *filp) | |||
| 861 | 861 | ||
| 862 | IVTV_DEBUG_FILE("close %s\n", s->name); | 862 | IVTV_DEBUG_FILE("close %s\n", s->name); |
| 863 | 863 | ||
| 864 | v4l2_fh_del(fh); | ||
| 865 | v4l2_fh_exit(fh); | ||
| 866 | |||
| 867 | /* Easy case first: this stream was never claimed by us */ | ||
| 868 | if (s->id != id->open_id) { | ||
| 869 | kfree(id); | ||
| 870 | return 0; | ||
| 871 | } | ||
| 872 | |||
| 873 | /* 'Unclaim' this stream */ | ||
| 874 | |||
| 875 | /* Stop radio */ | 864 | /* Stop radio */ |
| 876 | mutex_lock(&itv->serialize_lock); | 865 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD && |
| 877 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { | 866 | v4l2_fh_is_singular_file(filp)) { |
| 878 | /* Closing radio device, return to TV mode */ | 867 | /* Closing radio device, return to TV mode */ |
| 879 | ivtv_mute(itv); | 868 | ivtv_mute(itv); |
| 880 | /* Mark that the radio is no longer in use */ | 869 | /* Mark that the radio is no longer in use */ |
| @@ -890,13 +879,25 @@ int ivtv_v4l2_close(struct file *filp) | |||
| 890 | if (atomic_read(&itv->capturing) > 0) { | 879 | if (atomic_read(&itv->capturing) > 0) { |
| 891 | /* Undo video mute */ | 880 | /* Undo video mute */ |
| 892 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, | 881 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, |
| 893 | v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | | 882 | v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | |
| 894 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); | 883 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); |
| 895 | } | 884 | } |
| 896 | /* Done! Unmute and continue. */ | 885 | /* Done! Unmute and continue. */ |
| 897 | ivtv_unmute(itv); | 886 | ivtv_unmute(itv); |
| 898 | ivtv_release_stream(s); | 887 | } |
| 899 | } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | 888 | |
| 889 | v4l2_fh_del(fh); | ||
| 890 | v4l2_fh_exit(fh); | ||
| 891 | |||
| 892 | /* Easy case first: this stream was never claimed by us */ | ||
| 893 | if (s->fh != &id->fh) { | ||
| 894 | kfree(id); | ||
| 895 | return 0; | ||
| 896 | } | ||
| 897 | |||
| 898 | /* 'Unclaim' this stream */ | ||
| 899 | |||
| 900 | if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | ||
| 900 | struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; | 901 | struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; |
| 901 | 902 | ||
| 902 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | 903 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); |
| @@ -911,21 +912,25 @@ int ivtv_v4l2_close(struct file *filp) | |||
| 911 | ivtv_stop_capture(id, 0); | 912 | ivtv_stop_capture(id, 0); |
| 912 | } | 913 | } |
| 913 | kfree(id); | 914 | kfree(id); |
| 914 | mutex_unlock(&itv->serialize_lock); | ||
| 915 | return 0; | 915 | return 0; |
| 916 | } | 916 | } |
| 917 | 917 | ||
| 918 | static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | 918 | int ivtv_v4l2_open(struct file *filp) |
| 919 | { | 919 | { |
| 920 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
| 921 | struct video_device *vdev = video_devdata(filp); | 920 | struct video_device *vdev = video_devdata(filp); |
| 922 | #endif | 921 | struct ivtv_stream *s = video_get_drvdata(vdev); |
| 923 | struct ivtv *itv = s->itv; | 922 | struct ivtv *itv = s->itv; |
| 924 | struct ivtv_open_id *item; | 923 | struct ivtv_open_id *item; |
| 925 | int res = 0; | 924 | int res = 0; |
| 926 | 925 | ||
| 927 | IVTV_DEBUG_FILE("open %s\n", s->name); | 926 | IVTV_DEBUG_FILE("open %s\n", s->name); |
| 928 | 927 | ||
| 928 | if (ivtv_init_on_first_open(itv)) { | ||
| 929 | IVTV_ERR("Failed to initialize on device %s\n", | ||
| 930 | video_device_node_name(vdev)); | ||
| 931 | return -ENXIO; | ||
| 932 | } | ||
| 933 | |||
| 929 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 934 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 930 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ | 935 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ |
| 931 | if (ivtv_fw_debug) { | 936 | if (ivtv_fw_debug) { |
| @@ -966,31 +971,19 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
| 966 | return -ENOMEM; | 971 | return -ENOMEM; |
| 967 | } | 972 | } |
| 968 | v4l2_fh_init(&item->fh, s->vdev); | 973 | v4l2_fh_init(&item->fh, s->vdev); |
| 969 | if (res < 0) { | ||
| 970 | v4l2_fh_exit(&item->fh); | ||
| 971 | kfree(item); | ||
| 972 | return res; | ||
| 973 | } | ||
| 974 | item->itv = itv; | 974 | item->itv = itv; |
| 975 | item->type = s->type; | 975 | item->type = s->type; |
| 976 | 976 | ||
| 977 | item->open_id = itv->open_id++; | ||
| 978 | filp->private_data = &item->fh; | 977 | filp->private_data = &item->fh; |
| 978 | v4l2_fh_add(&item->fh); | ||
| 979 | 979 | ||
| 980 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { | 980 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD && |
| 981 | /* Try to claim this stream */ | 981 | v4l2_fh_is_singular_file(filp)) { |
| 982 | if (ivtv_claim_stream(item, item->type)) { | ||
| 983 | /* No, it's already in use */ | ||
| 984 | v4l2_fh_exit(&item->fh); | ||
| 985 | kfree(item); | ||
| 986 | return -EBUSY; | ||
| 987 | } | ||
| 988 | |||
| 989 | if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { | 982 | if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { |
| 990 | if (atomic_read(&itv->capturing) > 0) { | 983 | if (atomic_read(&itv->capturing) > 0) { |
| 991 | /* switching to radio while capture is | 984 | /* switching to radio while capture is |
| 992 | in progress is not polite */ | 985 | in progress is not polite */ |
| 993 | ivtv_release_stream(s); | 986 | v4l2_fh_del(&item->fh); |
| 994 | v4l2_fh_exit(&item->fh); | 987 | v4l2_fh_exit(&item->fh); |
| 995 | kfree(item); | 988 | kfree(item); |
| 996 | return -EBUSY; | 989 | return -EBUSY; |
| @@ -1022,32 +1015,9 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
| 1022 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); | 1015 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); |
| 1023 | itv->yuv_info.stream_size = 0; | 1016 | itv->yuv_info.stream_size = 0; |
| 1024 | } | 1017 | } |
| 1025 | v4l2_fh_add(&item->fh); | ||
| 1026 | return 0; | 1018 | return 0; |
| 1027 | } | 1019 | } |
| 1028 | 1020 | ||
| 1029 | int ivtv_v4l2_open(struct file *filp) | ||
| 1030 | { | ||
| 1031 | int res; | ||
| 1032 | struct ivtv *itv = NULL; | ||
| 1033 | struct ivtv_stream *s = NULL; | ||
| 1034 | struct video_device *vdev = video_devdata(filp); | ||
| 1035 | |||
| 1036 | s = video_get_drvdata(vdev); | ||
| 1037 | itv = s->itv; | ||
| 1038 | |||
| 1039 | mutex_lock(&itv->serialize_lock); | ||
| 1040 | if (ivtv_init_on_first_open(itv)) { | ||
| 1041 | IVTV_ERR("Failed to initialize on device %s\n", | ||
| 1042 | video_device_node_name(vdev)); | ||
| 1043 | mutex_unlock(&itv->serialize_lock); | ||
| 1044 | return -ENXIO; | ||
| 1045 | } | ||
| 1046 | res = ivtv_serialized_open(s, filp); | ||
| 1047 | mutex_unlock(&itv->serialize_lock); | ||
| 1048 | return res; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | void ivtv_mute(struct ivtv *itv) | 1021 | void ivtv_mute(struct ivtv *itv) |
| 1052 | { | 1022 | { |
| 1053 | if (atomic_read(&itv->capturing)) | 1023 | if (atomic_read(&itv->capturing)) |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index ecafa697326e..c4bc48143098 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
| @@ -179,6 +179,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed) | |||
| 179 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0); | 179 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0); |
| 180 | 180 | ||
| 181 | /* Wait for any DMA to finish */ | 181 | /* Wait for any DMA to finish */ |
| 182 | mutex_unlock(&itv->serialize_lock); | ||
| 182 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | 183 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); |
| 183 | while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { | 184 | while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { |
| 184 | got_sig = signal_pending(current); | 185 | got_sig = signal_pending(current); |
| @@ -188,6 +189,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed) | |||
| 188 | schedule(); | 189 | schedule(); |
| 189 | } | 190 | } |
| 190 | finish_wait(&itv->dma_waitq, &wait); | 191 | finish_wait(&itv->dma_waitq, &wait); |
| 192 | mutex_lock(&itv->serialize_lock); | ||
| 191 | if (got_sig) | 193 | if (got_sig) |
| 192 | return -EINTR; | 194 | return -EINTR; |
| 193 | 195 | ||
| @@ -1107,6 +1109,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std) | |||
| 1107 | * happens within the first 100 lines of the top field. | 1109 | * happens within the first 100 lines of the top field. |
| 1108 | * Make 4 attempts to sync to the decoder before giving up. | 1110 | * Make 4 attempts to sync to the decoder before giving up. |
| 1109 | */ | 1111 | */ |
| 1112 | mutex_unlock(&itv->serialize_lock); | ||
| 1110 | for (f = 0; f < 4; f++) { | 1113 | for (f = 0; f < 4; f++) { |
| 1111 | prepare_to_wait(&itv->vsync_waitq, &wait, | 1114 | prepare_to_wait(&itv->vsync_waitq, &wait, |
| 1112 | TASK_UNINTERRUPTIBLE); | 1115 | TASK_UNINTERRUPTIBLE); |
| @@ -1115,6 +1118,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std) | |||
| 1115 | schedule_timeout(msecs_to_jiffies(25)); | 1118 | schedule_timeout(msecs_to_jiffies(25)); |
| 1116 | } | 1119 | } |
| 1117 | finish_wait(&itv->vsync_waitq, &wait); | 1120 | finish_wait(&itv->vsync_waitq, &wait); |
| 1121 | mutex_lock(&itv->serialize_lock); | ||
| 1118 | 1122 | ||
| 1119 | if (f == 4) | 1123 | if (f == 4) |
| 1120 | IVTV_WARN("Mode change failed to sync to decoder\n"); | 1124 | IVTV_WARN("Mode change failed to sync to decoder\n"); |
| @@ -1842,8 +1846,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio, | |||
| 1842 | return 0; | 1846 | return 0; |
| 1843 | } | 1847 | } |
| 1844 | 1848 | ||
| 1845 | static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | 1849 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
| 1846 | unsigned int cmd, unsigned long arg) | ||
| 1847 | { | 1850 | { |
| 1848 | struct video_device *vfd = video_devdata(filp); | 1851 | struct video_device *vfd = video_devdata(filp); |
| 1849 | long ret; | 1852 | long ret; |
| @@ -1855,21 +1858,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
| 1855 | return ret; | 1858 | return ret; |
| 1856 | } | 1859 | } |
| 1857 | 1860 | ||
| 1858 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
| 1859 | { | ||
| 1860 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
| 1861 | struct ivtv *itv = id->itv; | ||
| 1862 | long res; | ||
| 1863 | |||
| 1864 | /* DQEVENT can block, so this should not run with the serialize lock */ | ||
| 1865 | if (cmd == VIDIOC_DQEVENT) | ||
| 1866 | return ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
| 1867 | mutex_lock(&itv->serialize_lock); | ||
| 1868 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
| 1869 | mutex_unlock(&itv->serialize_lock); | ||
| 1870 | return res; | ||
| 1871 | } | ||
| 1872 | |||
| 1873 | static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | 1861 | static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { |
| 1874 | .vidioc_querycap = ivtv_querycap, | 1862 | .vidioc_querycap = ivtv_querycap, |
| 1875 | .vidioc_s_audio = ivtv_s_audio, | 1863 | .vidioc_s_audio = ivtv_s_audio, |
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 9c29e964d400..1b3b9578bf47 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
| @@ -288,13 +288,13 @@ static void dma_post(struct ivtv_stream *s) | |||
| 288 | ivtv_process_vbi_data(itv, buf, 0, s->type); | 288 | ivtv_process_vbi_data(itv, buf, 0, s->type); |
| 289 | s->q_dma.bytesused += buf->bytesused; | 289 | s->q_dma.bytesused += buf->bytesused; |
| 290 | } | 290 | } |
| 291 | if (s->id == -1) { | 291 | if (s->fh == NULL) { |
| 292 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); | 292 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); |
| 293 | return; | 293 | return; |
| 294 | } | 294 | } |
| 295 | } | 295 | } |
| 296 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); | 296 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); |
| 297 | if (s->id != -1) | 297 | if (s->fh) |
| 298 | wake_up(&s->waitq); | 298 | wake_up(&s->waitq); |
| 299 | } | 299 | } |
| 300 | 300 | ||
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index e7794dc1330e..c6e28b4ebbed 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
| @@ -159,7 +159,6 @@ static void ivtv_stream_init(struct ivtv *itv, int type) | |||
| 159 | s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size; | 159 | s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size; |
| 160 | spin_lock_init(&s->qlock); | 160 | spin_lock_init(&s->qlock); |
| 161 | init_waitqueue_head(&s->waitq); | 161 | init_waitqueue_head(&s->waitq); |
| 162 | s->id = -1; | ||
| 163 | s->sg_handle = IVTV_DMA_UNMAPPED; | 162 | s->sg_handle = IVTV_DMA_UNMAPPED; |
| 164 | ivtv_queue_init(&s->q_free); | 163 | ivtv_queue_init(&s->q_free); |
| 165 | ivtv_queue_init(&s->q_full); | 164 | ivtv_queue_init(&s->q_full); |
| @@ -214,6 +213,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
| 214 | s->vdev->fops = ivtv_stream_info[type].fops; | 213 | s->vdev->fops = ivtv_stream_info[type].fops; |
| 215 | s->vdev->release = video_device_release; | 214 | s->vdev->release = video_device_release; |
| 216 | s->vdev->tvnorms = V4L2_STD_ALL; | 215 | s->vdev->tvnorms = V4L2_STD_ALL; |
| 216 | s->vdev->lock = &itv->serialize_lock; | ||
| 217 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); | 217 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); |
| 218 | ivtv_set_funcs(s->vdev); | 218 | ivtv_set_funcs(s->vdev); |
| 219 | return 0; | 219 | return 0; |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index dcbab6ad4c26..2ad65eb29832 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
| @@ -1149,23 +1149,37 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src) | |||
| 1149 | { | 1149 | { |
| 1150 | struct yuv_playback_info *yi = &itv->yuv_info; | 1150 | struct yuv_playback_info *yi = &itv->yuv_info; |
| 1151 | struct ivtv_dma_frame dma_args; | 1151 | struct ivtv_dma_frame dma_args; |
| 1152 | int res; | ||
| 1152 | 1153 | ||
| 1153 | ivtv_yuv_setup_stream_frame(itv); | 1154 | ivtv_yuv_setup_stream_frame(itv); |
| 1154 | 1155 | ||
| 1155 | /* We only need to supply source addresses for this */ | 1156 | /* We only need to supply source addresses for this */ |
| 1156 | dma_args.y_source = src; | 1157 | dma_args.y_source = src; |
| 1157 | dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31); | 1158 | dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31); |
| 1158 | return ivtv_yuv_udma_frame(itv, &dma_args); | 1159 | /* Wait for frame DMA. Note that serialize_lock is locked, |
| 1160 | so to allow other processes to access the driver while | ||
| 1161 | we are waiting unlock first and later lock again. */ | ||
| 1162 | mutex_unlock(&itv->serialize_lock); | ||
| 1163 | res = ivtv_yuv_udma_frame(itv, &dma_args); | ||
| 1164 | mutex_lock(&itv->serialize_lock); | ||
| 1165 | return res; | ||
| 1159 | } | 1166 | } |
| 1160 | 1167 | ||
| 1161 | /* IVTV_IOC_DMA_FRAME ioctl handler */ | 1168 | /* IVTV_IOC_DMA_FRAME ioctl handler */ |
| 1162 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | 1169 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) |
| 1163 | { | 1170 | { |
| 1164 | /* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */ | 1171 | int res; |
| 1165 | 1172 | ||
| 1173 | /* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */ | ||
| 1166 | ivtv_yuv_next_free(itv); | 1174 | ivtv_yuv_next_free(itv); |
| 1167 | ivtv_yuv_setup_frame(itv, args); | 1175 | ivtv_yuv_setup_frame(itv, args); |
| 1168 | return ivtv_yuv_udma_frame(itv, args); | 1176 | /* Wait for frame DMA. Note that serialize_lock is locked, |
| 1177 | so to allow other processes to access the driver while | ||
| 1178 | we are waiting unlock first and later lock again. */ | ||
| 1179 | mutex_unlock(&itv->serialize_lock); | ||
| 1180 | res = ivtv_yuv_udma_frame(itv, args); | ||
| 1181 | mutex_lock(&itv->serialize_lock); | ||
| 1182 | return res; | ||
| 1169 | } | 1183 | } |
| 1170 | 1184 | ||
| 1171 | void ivtv_yuv_close(struct ivtv *itv) | 1185 | void ivtv_yuv_close(struct ivtv *itv) |
| @@ -1174,7 +1188,9 @@ void ivtv_yuv_close(struct ivtv *itv) | |||
| 1174 | int h_filter, v_filter_1, v_filter_2; | 1188 | int h_filter, v_filter_1, v_filter_2; |
| 1175 | 1189 | ||
| 1176 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); | 1190 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); |
| 1191 | mutex_unlock(&itv->serialize_lock); | ||
| 1177 | ivtv_waitq(&itv->vsync_waitq); | 1192 | ivtv_waitq(&itv->vsync_waitq); |
| 1193 | mutex_lock(&itv->serialize_lock); | ||
| 1178 | 1194 | ||
| 1179 | yi->running = 0; | 1195 | yi->running = 0; |
| 1180 | atomic_set(&yi->next_dma_frame, -1); | 1196 | atomic_set(&yi->next_dma_frame, -1); |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index a277f95091ef..1fb7d5bd5ec2 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
| @@ -1042,7 +1042,8 @@ static int vidioc_querycap(struct file *file, void *fh, | |||
| 1042 | strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); | 1042 | strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); |
| 1043 | strlcpy(cap->card, vout->vfd->name, sizeof(cap->card)); | 1043 | strlcpy(cap->card, vout->vfd->name, sizeof(cap->card)); |
| 1044 | cap->bus_info[0] = '\0'; | 1044 | cap->bus_info[0] = '\0'; |
| 1045 | cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT; | 1045 | cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | |
| 1046 | V4L2_CAP_VIDEO_OUTPUT_OVERLAY; | ||
| 1046 | 1047 | ||
| 1047 | return 0; | 1048 | return 0; |
| 1048 | } | 1049 | } |
| @@ -1825,7 +1826,9 @@ static int vidioc_g_fbuf(struct file *file, void *fh, | |||
| 1825 | ovid = &vout->vid_info; | 1826 | ovid = &vout->vid_info; |
| 1826 | ovl = ovid->overlays[0]; | 1827 | ovl = ovid->overlays[0]; |
| 1827 | 1828 | ||
| 1828 | a->flags = 0x0; | 1829 | /* The video overlay must stay within the framebuffer and can't be |
| 1830 | positioned independently. */ | ||
| 1831 | a->flags = V4L2_FBUF_FLAG_OVERLAY; | ||
| 1829 | a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY | 1832 | a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY |
| 1830 | | V4L2_FBUF_CAP_SRC_CHROMAKEY; | 1833 | | V4L2_FBUF_CAP_SRC_CHROMAKEY; |
| 1831 | 1834 | ||
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 905d41d90c6a..1f506fde97d0 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
| @@ -104,47 +104,16 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] = | |||
| 104 | 104 | ||
| 105 | /****************************************************************************/ | 105 | /****************************************************************************/ |
| 106 | 106 | ||
| 107 | static int _send_control_msg(struct pwc_device *pdev, | ||
| 108 | u8 request, u16 value, int index, void *buf, int buflen) | ||
| 109 | { | ||
| 110 | int rc; | ||
| 111 | void *kbuf = NULL; | ||
| 112 | |||
| 113 | if (buflen) { | ||
| 114 | kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */ | ||
| 115 | if (kbuf == NULL) | ||
| 116 | return -ENOMEM; | ||
| 117 | } | ||
| 118 | |||
| 119 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | ||
| 120 | request, | ||
| 121 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 122 | value, | ||
| 123 | index, | ||
| 124 | kbuf, buflen, USB_CTRL_SET_TIMEOUT); | ||
| 125 | |||
| 126 | kfree(kbuf); | ||
| 127 | return rc; | ||
| 128 | } | ||
| 129 | |||
| 130 | static int recv_control_msg(struct pwc_device *pdev, | 107 | static int recv_control_msg(struct pwc_device *pdev, |
| 131 | u8 request, u16 value, void *buf, int buflen) | 108 | u8 request, u16 value, int recv_count) |
| 132 | { | 109 | { |
| 133 | int rc; | 110 | int rc; |
| 134 | void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */ | ||
| 135 | |||
| 136 | if (kbuf == NULL) | ||
| 137 | return -ENOMEM; | ||
| 138 | 111 | ||
| 139 | rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | 112 | rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), |
| 140 | request, | 113 | request, |
| 141 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 114 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 142 | value, | 115 | value, pdev->vcinterface, |
| 143 | pdev->vcinterface, | 116 | pdev->ctrl_buf, recv_count, USB_CTRL_GET_TIMEOUT); |
| 144 | kbuf, buflen, USB_CTRL_GET_TIMEOUT); | ||
| 145 | memcpy(buf, kbuf, buflen); | ||
| 146 | kfree(kbuf); | ||
| 147 | |||
| 148 | if (rc < 0) | 117 | if (rc < 0) |
| 149 | PWC_ERROR("recv_control_msg error %d req %02x val %04x\n", | 118 | PWC_ERROR("recv_control_msg error %d req %02x val %04x\n", |
| 150 | rc, request, value); | 119 | rc, request, value); |
| @@ -152,27 +121,39 @@ static int recv_control_msg(struct pwc_device *pdev, | |||
| 152 | } | 121 | } |
| 153 | 122 | ||
| 154 | static inline int send_video_command(struct pwc_device *pdev, | 123 | static inline int send_video_command(struct pwc_device *pdev, |
| 155 | int index, void *buf, int buflen) | 124 | int index, const unsigned char *buf, int buflen) |
| 156 | { | 125 | { |
| 157 | return _send_control_msg(pdev, | 126 | int rc; |
| 158 | SET_EP_STREAM_CTL, | 127 | |
| 159 | VIDEO_OUTPUT_CONTROL_FORMATTER, | 128 | memcpy(pdev->ctrl_buf, buf, buflen); |
| 160 | index, | 129 | |
| 161 | buf, buflen); | 130 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), |
| 131 | SET_EP_STREAM_CTL, | ||
| 132 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 133 | VIDEO_OUTPUT_CONTROL_FORMATTER, index, | ||
| 134 | pdev->ctrl_buf, buflen, USB_CTRL_SET_TIMEOUT); | ||
| 135 | if (rc >= 0) | ||
| 136 | memcpy(pdev->cmd_buf, buf, buflen); | ||
| 137 | else | ||
| 138 | PWC_ERROR("send_video_command error %d\n", rc); | ||
| 139 | |||
| 140 | return rc; | ||
| 162 | } | 141 | } |
| 163 | 142 | ||
| 164 | int send_control_msg(struct pwc_device *pdev, | 143 | int send_control_msg(struct pwc_device *pdev, |
| 165 | u8 request, u16 value, void *buf, int buflen) | 144 | u8 request, u16 value, void *buf, int buflen) |
| 166 | { | 145 | { |
| 167 | return _send_control_msg(pdev, | 146 | return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), |
| 168 | request, value, pdev->vcinterface, buf, buflen); | 147 | request, |
| 148 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 149 | value, pdev->vcinterface, | ||
| 150 | buf, buflen, USB_CTRL_SET_TIMEOUT); | ||
| 169 | } | 151 | } |
| 170 | 152 | ||
| 171 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, | 153 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt, |
| 172 | int *compression) | 154 | int frames, int *compression, int send_to_cam) |
| 173 | { | 155 | { |
| 174 | unsigned char buf[3]; | 156 | int fps, ret = 0; |
| 175 | int ret, fps; | ||
| 176 | struct Nala_table_entry *pEntry; | 157 | struct Nala_table_entry *pEntry; |
| 177 | int frames2frames[31] = | 158 | int frames2frames[31] = |
| 178 | { /* closest match of framerate */ | 159 | { /* closest match of framerate */ |
| @@ -194,30 +175,29 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, | |||
| 194 | 7 /* 30 */ | 175 | 7 /* 30 */ |
| 195 | }; | 176 | }; |
| 196 | 177 | ||
| 197 | if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25) | 178 | if (size < 0 || size > PSZ_CIF) |
| 198 | return -EINVAL; | 179 | return -EINVAL; |
| 180 | if (frames < 4) | ||
| 181 | frames = 4; | ||
| 182 | else if (frames > 25) | ||
| 183 | frames = 25; | ||
| 199 | frames = frames2frames[frames]; | 184 | frames = frames2frames[frames]; |
| 200 | fps = frames2table[frames]; | 185 | fps = frames2table[frames]; |
| 201 | pEntry = &Nala_table[size][fps]; | 186 | pEntry = &Nala_table[size][fps]; |
| 202 | if (pEntry->alternate == 0) | 187 | if (pEntry->alternate == 0) |
| 203 | return -EINVAL; | 188 | return -EINVAL; |
| 204 | 189 | ||
| 205 | memcpy(buf, pEntry->mode, 3); | 190 | if (send_to_cam) |
| 206 | ret = send_video_command(pdev, pdev->vendpoint, buf, 3); | 191 | ret = send_video_command(pdev, pdev->vendpoint, |
| 207 | if (ret < 0) { | 192 | pEntry->mode, 3); |
| 208 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); | 193 | if (ret < 0) |
| 209 | return ret; | 194 | return ret; |
| 210 | } | ||
| 211 | if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | ||
| 212 | ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf); | ||
| 213 | if (ret < 0) | ||
| 214 | return ret; | ||
| 215 | } | ||
| 216 | 195 | ||
| 217 | pdev->cmd_len = 3; | 196 | if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420) |
| 218 | memcpy(pdev->cmd_buf, buf, 3); | 197 | pwc_dec1_init(pdev, pEntry->mode); |
| 219 | 198 | ||
| 220 | /* Set various parameters */ | 199 | /* Set various parameters */ |
| 200 | pdev->pixfmt = pixfmt; | ||
| 221 | pdev->vframes = frames; | 201 | pdev->vframes = frames; |
| 222 | pdev->valternate = pEntry->alternate; | 202 | pdev->valternate = pEntry->alternate; |
| 223 | pdev->width = pwc_image_sizes[size][0]; | 203 | pdev->width = pwc_image_sizes[size][0]; |
| @@ -243,18 +223,20 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, | |||
| 243 | } | 223 | } |
| 244 | 224 | ||
| 245 | 225 | ||
| 246 | static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, | 226 | static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt, |
| 247 | int *compression) | 227 | int frames, int *compression, int send_to_cam) |
| 248 | { | 228 | { |
| 249 | unsigned char buf[13]; | ||
| 250 | const struct Timon_table_entry *pChoose; | 229 | const struct Timon_table_entry *pChoose; |
| 251 | int ret, fps; | 230 | int fps, ret = 0; |
| 252 | 231 | ||
| 253 | if (size >= PSZ_MAX || frames < 5 || frames > 30 || | 232 | if (size >= PSZ_MAX || *compression < 0 || *compression > 3) |
| 254 | *compression < 0 || *compression > 3) | ||
| 255 | return -EINVAL; | ||
| 256 | if (size == PSZ_VGA && frames > 15) | ||
| 257 | return -EINVAL; | 233 | return -EINVAL; |
| 234 | if (frames < 5) | ||
| 235 | frames = 5; | ||
| 236 | else if (size == PSZ_VGA && frames > 15) | ||
| 237 | frames = 15; | ||
| 238 | else if (frames > 30) | ||
| 239 | frames = 30; | ||
| 258 | fps = (frames / 5) - 1; | 240 | fps = (frames / 5) - 1; |
| 259 | 241 | ||
| 260 | /* Find a supported framerate with progressively higher compression */ | 242 | /* Find a supported framerate with progressively higher compression */ |
| @@ -268,22 +250,18 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, | |||
| 268 | if (pChoose == NULL || pChoose->alternate == 0) | 250 | if (pChoose == NULL || pChoose->alternate == 0) |
| 269 | return -ENOENT; /* Not supported. */ | 251 | return -ENOENT; /* Not supported. */ |
| 270 | 252 | ||
| 271 | memcpy(buf, pChoose->mode, 13); | 253 | if (send_to_cam) |
| 272 | ret = send_video_command(pdev, pdev->vendpoint, buf, 13); | 254 | ret = send_video_command(pdev, pdev->vendpoint, |
| 255 | pChoose->mode, 13); | ||
| 273 | if (ret < 0) | 256 | if (ret < 0) |
| 274 | return ret; | 257 | return ret; |
| 275 | 258 | ||
| 276 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | 259 | if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420) |
| 277 | ret = pwc_dec23_init(pdev, pdev->type, buf); | 260 | pwc_dec23_init(pdev, pChoose->mode); |
| 278 | if (ret < 0) | ||
| 279 | return ret; | ||
| 280 | } | ||
| 281 | |||
| 282 | pdev->cmd_len = 13; | ||
| 283 | memcpy(pdev->cmd_buf, buf, 13); | ||
| 284 | 261 | ||
| 285 | /* Set various parameters */ | 262 | /* Set various parameters */ |
| 286 | pdev->vframes = frames; | 263 | pdev->pixfmt = pixfmt; |
| 264 | pdev->vframes = (fps + 1) * 5; | ||
| 287 | pdev->valternate = pChoose->alternate; | 265 | pdev->valternate = pChoose->alternate; |
| 288 | pdev->width = pwc_image_sizes[size][0]; | 266 | pdev->width = pwc_image_sizes[size][0]; |
| 289 | pdev->height = pwc_image_sizes[size][1]; | 267 | pdev->height = pwc_image_sizes[size][1]; |
| @@ -296,18 +274,20 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, | |||
| 296 | } | 274 | } |
| 297 | 275 | ||
| 298 | 276 | ||
| 299 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, | 277 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt, |
| 300 | int *compression) | 278 | int frames, int *compression, int send_to_cam) |
| 301 | { | 279 | { |
| 302 | const struct Kiara_table_entry *pChoose = NULL; | 280 | const struct Kiara_table_entry *pChoose = NULL; |
| 303 | int fps, ret; | 281 | int fps, ret = 0; |
| 304 | unsigned char buf[12]; | ||
| 305 | 282 | ||
| 306 | if (size >= PSZ_MAX || frames < 5 || frames > 30 || | 283 | if (size >= PSZ_MAX || *compression < 0 || *compression > 3) |
| 307 | *compression < 0 || *compression > 3) | ||
| 308 | return -EINVAL; | ||
| 309 | if (size == PSZ_VGA && frames > 15) | ||
| 310 | return -EINVAL; | 284 | return -EINVAL; |
| 285 | if (frames < 5) | ||
| 286 | frames = 5; | ||
| 287 | else if (size == PSZ_VGA && frames > 15) | ||
| 288 | frames = 15; | ||
| 289 | else if (frames > 30) | ||
| 290 | frames = 30; | ||
| 311 | fps = (frames / 5) - 1; | 291 | fps = (frames / 5) - 1; |
| 312 | 292 | ||
| 313 | /* Find a supported framerate with progressively higher compression */ | 293 | /* Find a supported framerate with progressively higher compression */ |
| @@ -320,26 +300,18 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, | |||
| 320 | if (pChoose == NULL || pChoose->alternate == 0) | 300 | if (pChoose == NULL || pChoose->alternate == 0) |
| 321 | return -ENOENT; /* Not supported. */ | 301 | return -ENOENT; /* Not supported. */ |
| 322 | 302 | ||
| 323 | PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate); | ||
| 324 | |||
| 325 | /* usb_control_msg won't take staticly allocated arrays as argument?? */ | ||
| 326 | memcpy(buf, pChoose->mode, 12); | ||
| 327 | |||
| 328 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ | 303 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ |
| 329 | ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12); | 304 | if (send_to_cam) |
| 305 | ret = send_video_command(pdev, 4, pChoose->mode, 12); | ||
| 330 | if (ret < 0) | 306 | if (ret < 0) |
| 331 | return ret; | 307 | return ret; |
| 332 | 308 | ||
| 333 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | 309 | if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420) |
| 334 | ret = pwc_dec23_init(pdev, pdev->type, buf); | 310 | pwc_dec23_init(pdev, pChoose->mode); |
| 335 | if (ret < 0) | ||
| 336 | return ret; | ||
| 337 | } | ||
| 338 | 311 | ||
| 339 | pdev->cmd_len = 12; | ||
| 340 | memcpy(pdev->cmd_buf, buf, 12); | ||
| 341 | /* All set and go */ | 312 | /* All set and go */ |
| 342 | pdev->vframes = frames; | 313 | pdev->pixfmt = pixfmt; |
| 314 | pdev->vframes = (fps + 1) * 5; | ||
| 343 | pdev->valternate = pChoose->alternate; | 315 | pdev->valternate = pChoose->alternate; |
| 344 | pdev->width = pwc_image_sizes[size][0]; | 316 | pdev->width = pwc_image_sizes[size][0]; |
| 345 | pdev->height = pwc_image_sizes[size][1]; | 317 | pdev->height = pwc_image_sizes[size][1]; |
| @@ -354,22 +326,24 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, | |||
| 354 | } | 326 | } |
| 355 | 327 | ||
| 356 | int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, | 328 | int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, |
| 357 | int frames, int *compression) | 329 | int pixfmt, int frames, int *compression, int send_to_cam) |
| 358 | { | 330 | { |
| 359 | int ret, size; | 331 | int ret, size; |
| 360 | 332 | ||
| 361 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt); | 333 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", |
| 334 | width, height, frames, pixfmt); | ||
| 362 | size = pwc_get_size(pdev, width, height); | 335 | size = pwc_get_size(pdev, width, height); |
| 363 | PWC_TRACE("decode_size = %d.\n", size); | 336 | PWC_TRACE("decode_size = %d.\n", size); |
| 364 | 337 | ||
| 365 | if (DEVICE_USE_CODEC1(pdev->type)) { | 338 | if (DEVICE_USE_CODEC1(pdev->type)) { |
| 366 | ret = set_video_mode_Nala(pdev, size, frames, compression); | 339 | ret = set_video_mode_Nala(pdev, size, pixfmt, frames, |
| 367 | 340 | compression, send_to_cam); | |
| 368 | } else if (DEVICE_USE_CODEC3(pdev->type)) { | 341 | } else if (DEVICE_USE_CODEC3(pdev->type)) { |
| 369 | ret = set_video_mode_Kiara(pdev, size, frames, compression); | 342 | ret = set_video_mode_Kiara(pdev, size, pixfmt, frames, |
| 370 | 343 | compression, send_to_cam); | |
| 371 | } else { | 344 | } else { |
| 372 | ret = set_video_mode_Timon(pdev, size, frames, compression); | 345 | ret = set_video_mode_Timon(pdev, size, pixfmt, frames, |
| 346 | compression, send_to_cam); | ||
| 373 | } | 347 | } |
| 374 | if (ret < 0) { | 348 | if (ret < 0) { |
| 375 | PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); | 349 | PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); |
| @@ -436,13 +410,12 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i | |||
| 436 | int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 410 | int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) |
| 437 | { | 411 | { |
| 438 | int ret; | 412 | int ret; |
| 439 | u8 buf; | ||
| 440 | 413 | ||
| 441 | ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf)); | 414 | ret = recv_control_msg(pdev, request, value, 1); |
| 442 | if (ret < 0) | 415 | if (ret < 0) |
| 443 | return ret; | 416 | return ret; |
| 444 | 417 | ||
| 445 | *data = buf; | 418 | *data = pdev->ctrl_buf[0]; |
| 446 | return 0; | 419 | return 0; |
| 447 | } | 420 | } |
| 448 | 421 | ||
| @@ -450,7 +423,8 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data) | |||
| 450 | { | 423 | { |
| 451 | int ret; | 424 | int ret; |
| 452 | 425 | ||
| 453 | ret = send_control_msg(pdev, request, value, &data, sizeof(data)); | 426 | pdev->ctrl_buf[0] = data; |
| 427 | ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1); | ||
| 454 | if (ret < 0) | 428 | if (ret < 0) |
| 455 | return ret; | 429 | return ret; |
| 456 | 430 | ||
| @@ -460,37 +434,34 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data) | |||
| 460 | int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 434 | int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) |
| 461 | { | 435 | { |
| 462 | int ret; | 436 | int ret; |
| 463 | s8 buf; | ||
| 464 | 437 | ||
| 465 | ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf)); | 438 | ret = recv_control_msg(pdev, request, value, 1); |
| 466 | if (ret < 0) | 439 | if (ret < 0) |
| 467 | return ret; | 440 | return ret; |
| 468 | 441 | ||
| 469 | *data = buf; | 442 | *data = ((s8 *)pdev->ctrl_buf)[0]; |
| 470 | return 0; | 443 | return 0; |
| 471 | } | 444 | } |
| 472 | 445 | ||
| 473 | int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 446 | int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) |
| 474 | { | 447 | { |
| 475 | int ret; | 448 | int ret; |
| 476 | u8 buf[2]; | ||
| 477 | 449 | ||
| 478 | ret = recv_control_msg(pdev, request, value, buf, sizeof(buf)); | 450 | ret = recv_control_msg(pdev, request, value, 2); |
| 479 | if (ret < 0) | 451 | if (ret < 0) |
| 480 | return ret; | 452 | return ret; |
| 481 | 453 | ||
| 482 | *data = (buf[1] << 8) | buf[0]; | 454 | *data = (pdev->ctrl_buf[1] << 8) | pdev->ctrl_buf[0]; |
| 483 | return 0; | 455 | return 0; |
| 484 | } | 456 | } |
| 485 | 457 | ||
| 486 | int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data) | 458 | int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data) |
| 487 | { | 459 | { |
| 488 | int ret; | 460 | int ret; |
| 489 | u8 buf[2]; | ||
| 490 | 461 | ||
| 491 | buf[0] = data & 0xff; | 462 | pdev->ctrl_buf[0] = data & 0xff; |
| 492 | buf[1] = data >> 8; | 463 | pdev->ctrl_buf[1] = data >> 8; |
| 493 | ret = send_control_msg(pdev, request, value, buf, sizeof(buf)); | 464 | ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2); |
| 494 | if (ret < 0) | 465 | if (ret < 0) |
| 495 | return ret; | 466 | return ret; |
| 496 | 467 | ||
| @@ -511,7 +482,6 @@ int pwc_button_ctrl(struct pwc_device *pdev, u16 value) | |||
| 511 | /* POWER */ | 482 | /* POWER */ |
| 512 | void pwc_camera_power(struct pwc_device *pdev, int power) | 483 | void pwc_camera_power(struct pwc_device *pdev, int power) |
| 513 | { | 484 | { |
| 514 | char buf; | ||
| 515 | int r; | 485 | int r; |
| 516 | 486 | ||
| 517 | if (!pdev->power_save) | 487 | if (!pdev->power_save) |
| @@ -521,13 +491,11 @@ void pwc_camera_power(struct pwc_device *pdev, int power) | |||
| 521 | return; /* Not supported by Nala or Timon < release 6 */ | 491 | return; /* Not supported by Nala or Timon < release 6 */ |
| 522 | 492 | ||
| 523 | if (power) | 493 | if (power) |
| 524 | buf = 0x00; /* active */ | 494 | pdev->ctrl_buf[0] = 0x00; /* active */ |
| 525 | else | 495 | else |
| 526 | buf = 0xFF; /* power save */ | 496 | pdev->ctrl_buf[0] = 0xFF; /* power save */ |
| 527 | r = send_control_msg(pdev, | 497 | r = send_control_msg(pdev, SET_STATUS_CTL, |
| 528 | SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, | 498 | SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1); |
| 529 | &buf, sizeof(buf)); | ||
| 530 | |||
| 531 | if (r < 0) | 499 | if (r < 0) |
| 532 | PWC_ERROR("Failed to power %s camera (%d)\n", | 500 | PWC_ERROR("Failed to power %s camera (%d)\n", |
| 533 | power ? "on" : "off", r); | 501 | power ? "on" : "off", r); |
| @@ -535,7 +503,6 @@ void pwc_camera_power(struct pwc_device *pdev, int power) | |||
| 535 | 503 | ||
| 536 | int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | 504 | int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) |
| 537 | { | 505 | { |
| 538 | unsigned char buf[2]; | ||
| 539 | int r; | 506 | int r; |
| 540 | 507 | ||
| 541 | if (pdev->type < 730) | 508 | if (pdev->type < 730) |
| @@ -551,11 +518,11 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | |||
| 551 | if (off_value > 0xff) | 518 | if (off_value > 0xff) |
| 552 | off_value = 0xff; | 519 | off_value = 0xff; |
| 553 | 520 | ||
| 554 | buf[0] = on_value; | 521 | pdev->ctrl_buf[0] = on_value; |
| 555 | buf[1] = off_value; | 522 | pdev->ctrl_buf[1] = off_value; |
| 556 | 523 | ||
| 557 | r = send_control_msg(pdev, | 524 | r = send_control_msg(pdev, |
| 558 | SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); | 525 | SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2); |
| 559 | if (r < 0) | 526 | if (r < 0) |
| 560 | PWC_ERROR("Failed to set LED on/off time (%d)\n", r); | 527 | PWC_ERROR("Failed to set LED on/off time (%d)\n", r); |
| 561 | 528 | ||
| @@ -565,7 +532,6 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | |||
| 565 | #ifdef CONFIG_USB_PWC_DEBUG | 532 | #ifdef CONFIG_USB_PWC_DEBUG |
| 566 | int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | 533 | int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) |
| 567 | { | 534 | { |
| 568 | unsigned char buf; | ||
| 569 | int ret = -1, request; | 535 | int ret = -1, request; |
| 570 | 536 | ||
| 571 | if (pdev->type < 675) | 537 | if (pdev->type < 675) |
| @@ -575,14 +541,13 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | |||
| 575 | else | 541 | else |
| 576 | request = SENSOR_TYPE_FORMATTER2; | 542 | request = SENSOR_TYPE_FORMATTER2; |
| 577 | 543 | ||
| 578 | ret = recv_control_msg(pdev, | 544 | ret = recv_control_msg(pdev, GET_STATUS_CTL, request, 1); |
| 579 | GET_STATUS_CTL, request, &buf, sizeof(buf)); | ||
| 580 | if (ret < 0) | 545 | if (ret < 0) |
| 581 | return ret; | 546 | return ret; |
| 582 | if (pdev->type < 675) | 547 | if (pdev->type < 675) |
| 583 | *sensor = buf | 0x100; | 548 | *sensor = pdev->ctrl_buf[0] | 0x100; |
| 584 | else | 549 | else |
| 585 | *sensor = buf; | 550 | *sensor = pdev->ctrl_buf[0]; |
| 586 | return 0; | 551 | return 0; |
| 587 | } | 552 | } |
| 588 | #endif | 553 | #endif |
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c index be0e02cb487f..e899036aadf4 100644 --- a/drivers/media/video/pwc/pwc-dec1.c +++ b/drivers/media/video/pwc/pwc-dec1.c | |||
| @@ -22,19 +22,11 @@ | |||
| 22 | along with this program; if not, write to the Free Software | 22 | along with this program; if not, write to the Free Software |
| 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 24 | */ | 24 | */ |
| 25 | #include "pwc-dec1.h" | 25 | #include "pwc.h" |
| 26 | 26 | ||
| 27 | int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer) | 27 | void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd) |
| 28 | { | 28 | { |
| 29 | struct pwc_dec1_private *pdec; | 29 | struct pwc_dec1_private *pdec = &pdev->dec1; |
| 30 | 30 | ||
| 31 | if (pwc->decompress_data == NULL) { | 31 | pdec->version = pdev->release; |
| 32 | pdec = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL); | ||
| 33 | if (pdec == NULL) | ||
| 34 | return -ENOMEM; | ||
| 35 | pwc->decompress_data = pdec; | ||
| 36 | } | ||
| 37 | pdec = pwc->decompress_data; | ||
| 38 | |||
| 39 | return 0; | ||
| 40 | } | 32 | } |
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h index a57d8601080b..c565ef8f52fb 100644 --- a/drivers/media/video/pwc/pwc-dec1.h +++ b/drivers/media/video/pwc/pwc-dec1.h | |||
| @@ -25,13 +25,15 @@ | |||
| 25 | #ifndef PWC_DEC1_H | 25 | #ifndef PWC_DEC1_H |
| 26 | #define PWC_DEC1_H | 26 | #define PWC_DEC1_H |
| 27 | 27 | ||
| 28 | #include "pwc.h" | 28 | #include <linux/mutex.h> |
| 29 | |||
| 30 | struct pwc_device; | ||
| 29 | 31 | ||
| 30 | struct pwc_dec1_private | 32 | struct pwc_dec1_private |
| 31 | { | 33 | { |
| 32 | int version; | 34 | int version; |
| 33 | }; | 35 | }; |
| 34 | 36 | ||
| 35 | int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer); | 37 | void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd); |
| 36 | 38 | ||
| 37 | #endif | 39 | #endif |
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c index 2c6709112b2f..3792fedff951 100644 --- a/drivers/media/video/pwc/pwc-dec23.c +++ b/drivers/media/video/pwc/pwc-dec23.c | |||
| @@ -294,22 +294,17 @@ static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE]; | |||
| 294 | 294 | ||
| 295 | 295 | ||
| 296 | /* If the type or the command change, we rebuild the lookup table */ | 296 | /* If the type or the command change, we rebuild the lookup table */ |
| 297 | int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd) | 297 | void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd) |
| 298 | { | 298 | { |
| 299 | int flags, version, shift, i; | 299 | int flags, version, shift, i; |
| 300 | struct pwc_dec23_private *pdec; | 300 | struct pwc_dec23_private *pdec = &pdev->dec23; |
| 301 | |||
| 302 | if (pwc->decompress_data == NULL) { | ||
| 303 | pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); | ||
| 304 | if (pdec == NULL) | ||
| 305 | return -ENOMEM; | ||
| 306 | pwc->decompress_data = pdec; | ||
| 307 | } | ||
| 308 | pdec = pwc->decompress_data; | ||
| 309 | 301 | ||
| 310 | mutex_init(&pdec->lock); | 302 | mutex_init(&pdec->lock); |
| 311 | 303 | ||
| 312 | if (DEVICE_USE_CODEC3(type)) { | 304 | if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2]) |
| 305 | return; | ||
| 306 | |||
| 307 | if (DEVICE_USE_CODEC3(pdev->type)) { | ||
| 313 | flags = cmd[2] & 0x18; | 308 | flags = cmd[2] & 0x18; |
| 314 | if (flags == 8) | 309 | if (flags == 8) |
| 315 | pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ | 310 | pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ |
| @@ -356,7 +351,8 @@ int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd) | |||
| 356 | pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255; | 351 | pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255; |
| 357 | #endif | 352 | #endif |
| 358 | 353 | ||
| 359 | return 0; | 354 | pdec->last_cmd = cmd[2]; |
| 355 | pdec->last_cmd_valid = 1; | ||
| 360 | } | 356 | } |
| 361 | 357 | ||
| 362 | /* | 358 | /* |
| @@ -659,12 +655,12 @@ static void DecompressBand23(struct pwc_dec23_private *pdec, | |||
| 659 | * src: raw data | 655 | * src: raw data |
| 660 | * dst: image output | 656 | * dst: image output |
| 661 | */ | 657 | */ |
| 662 | void pwc_dec23_decompress(const struct pwc_device *pwc, | 658 | void pwc_dec23_decompress(struct pwc_device *pdev, |
| 663 | const void *src, | 659 | const void *src, |
| 664 | void *dst) | 660 | void *dst) |
| 665 | { | 661 | { |
| 666 | int bandlines_left, bytes_per_block; | 662 | int bandlines_left, bytes_per_block; |
| 667 | struct pwc_dec23_private *pdec = pwc->decompress_data; | 663 | struct pwc_dec23_private *pdec = &pdev->dec23; |
| 668 | 664 | ||
| 669 | /* YUV420P image format */ | 665 | /* YUV420P image format */ |
| 670 | unsigned char *pout_planar_y; | 666 | unsigned char *pout_planar_y; |
| @@ -674,23 +670,22 @@ void pwc_dec23_decompress(const struct pwc_device *pwc, | |||
| 674 | 670 | ||
| 675 | mutex_lock(&pdec->lock); | 671 | mutex_lock(&pdec->lock); |
| 676 | 672 | ||
| 677 | bandlines_left = pwc->height / 4; | 673 | bandlines_left = pdev->height / 4; |
| 678 | bytes_per_block = pwc->width * 4; | 674 | bytes_per_block = pdev->width * 4; |
| 679 | plane_size = pwc->height * pwc->width; | 675 | plane_size = pdev->height * pdev->width; |
| 680 | 676 | ||
| 681 | pout_planar_y = dst; | 677 | pout_planar_y = dst; |
| 682 | pout_planar_u = dst + plane_size; | 678 | pout_planar_u = dst + plane_size; |
| 683 | pout_planar_v = dst + plane_size + plane_size / 4; | 679 | pout_planar_v = dst + plane_size + plane_size / 4; |
| 684 | 680 | ||
| 685 | while (bandlines_left--) { | 681 | while (bandlines_left--) { |
| 686 | DecompressBand23(pwc->decompress_data, | 682 | DecompressBand23(pdec, src, |
| 687 | src, | ||
| 688 | pout_planar_y, pout_planar_u, pout_planar_v, | 683 | pout_planar_y, pout_planar_u, pout_planar_v, |
| 689 | pwc->width, pwc->width); | 684 | pdev->width, pdev->width); |
| 690 | src += pwc->vbandlength; | 685 | src += pdev->vbandlength; |
| 691 | pout_planar_y += bytes_per_block; | 686 | pout_planar_y += bytes_per_block; |
| 692 | pout_planar_u += pwc->width; | 687 | pout_planar_u += pdev->width; |
| 693 | pout_planar_v += pwc->width; | 688 | pout_planar_v += pdev->width; |
| 694 | } | 689 | } |
| 695 | mutex_unlock(&pdec->lock); | 690 | mutex_unlock(&pdec->lock); |
| 696 | } | 691 | } |
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h index d64a3c281af6..c655b1c1e6a9 100644 --- a/drivers/media/video/pwc/pwc-dec23.h +++ b/drivers/media/video/pwc/pwc-dec23.h | |||
| @@ -25,17 +25,20 @@ | |||
| 25 | #ifndef PWC_DEC23_H | 25 | #ifndef PWC_DEC23_H |
| 26 | #define PWC_DEC23_H | 26 | #define PWC_DEC23_H |
| 27 | 27 | ||
| 28 | #include "pwc.h" | 28 | struct pwc_device; |
| 29 | 29 | ||
| 30 | struct pwc_dec23_private | 30 | struct pwc_dec23_private |
| 31 | { | 31 | { |
| 32 | struct mutex lock; | 32 | struct mutex lock; |
| 33 | 33 | ||
| 34 | unsigned char last_cmd, last_cmd_valid; | ||
| 35 | |||
| 34 | unsigned int scalebits; | 36 | unsigned int scalebits; |
| 35 | unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */ | 37 | unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */ |
| 36 | 38 | ||
| 37 | unsigned int reservoir; | 39 | unsigned int reservoir; |
| 38 | unsigned int nbits_in_reservoir; | 40 | unsigned int nbits_in_reservoir; |
| 41 | |||
| 39 | const unsigned char *stream; | 42 | const unsigned char *stream; |
| 40 | int temp_colors[16]; | 43 | int temp_colors[16]; |
| 41 | 44 | ||
| @@ -51,8 +54,8 @@ struct pwc_dec23_private | |||
| 51 | 54 | ||
| 52 | }; | 55 | }; |
| 53 | 56 | ||
| 54 | int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd); | 57 | void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd); |
| 55 | void pwc_dec23_decompress(const struct pwc_device *pwc, | 58 | void pwc_dec23_decompress(struct pwc_device *pdev, |
| 56 | const void *src, | 59 | const void *src, |
| 57 | void *dst); | 60 | void *dst); |
| 58 | #endif | 61 | #endif |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 943d37ad0d33..122fbd0081eb 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
| @@ -128,18 +128,11 @@ static struct usb_driver pwc_driver = { | |||
| 128 | #define MAX_DEV_HINTS 20 | 128 | #define MAX_DEV_HINTS 20 |
| 129 | #define MAX_ISOC_ERRORS 20 | 129 | #define MAX_ISOC_ERRORS 20 |
| 130 | 130 | ||
| 131 | static int default_fps = 10; | ||
| 132 | #ifdef CONFIG_USB_PWC_DEBUG | 131 | #ifdef CONFIG_USB_PWC_DEBUG |
| 133 | int pwc_trace = PWC_DEBUG_LEVEL; | 132 | int pwc_trace = PWC_DEBUG_LEVEL; |
| 134 | #endif | 133 | #endif |
| 135 | static int power_save = -1; | 134 | static int power_save = -1; |
| 136 | static int led_on = 100, led_off; /* defaults to LED that is on while in use */ | 135 | static int leds[2] = { 100, 0 }; |
| 137 | static struct { | ||
| 138 | int type; | ||
| 139 | char serial_number[30]; | ||
| 140 | int device_node; | ||
| 141 | struct pwc_device *pdev; | ||
| 142 | } device_hint[MAX_DEV_HINTS]; | ||
| 143 | 136 | ||
| 144 | /***/ | 137 | /***/ |
| 145 | 138 | ||
| @@ -386,8 +379,8 @@ static int pwc_isoc_init(struct pwc_device *pdev) | |||
| 386 | retry: | 379 | retry: |
| 387 | /* We first try with low compression and then retry with a higher | 380 | /* We first try with low compression and then retry with a higher |
| 388 | compression setting if there is not enough bandwidth. */ | 381 | compression setting if there is not enough bandwidth. */ |
| 389 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, | 382 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, |
| 390 | pdev->vframes, &compression); | 383 | pdev->vframes, &compression, 1); |
| 391 | 384 | ||
| 392 | /* Get the current alternate interface, adjust packet size */ | 385 | /* Get the current alternate interface, adjust packet size */ |
| 393 | intf = usb_ifnum_to_if(udev, 0); | 386 | intf = usb_ifnum_to_if(udev, 0); |
| @@ -597,23 +590,9 @@ leave: | |||
| 597 | static void pwc_video_release(struct v4l2_device *v) | 590 | static void pwc_video_release(struct v4l2_device *v) |
| 598 | { | 591 | { |
| 599 | struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); | 592 | struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); |
| 600 | int hint; | ||
| 601 | |||
| 602 | /* search device_hint[] table if we occupy a slot, by any chance */ | ||
| 603 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
| 604 | if (device_hint[hint].pdev == pdev) | ||
| 605 | device_hint[hint].pdev = NULL; | ||
| 606 | |||
| 607 | /* Free intermediate decompression buffer & tables */ | ||
| 608 | if (pdev->decompress_data != NULL) { | ||
| 609 | PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", | ||
| 610 | pdev->decompress_data); | ||
| 611 | kfree(pdev->decompress_data); | ||
| 612 | pdev->decompress_data = NULL; | ||
| 613 | } | ||
| 614 | 593 | ||
| 615 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | 594 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); |
| 616 | 595 | kfree(pdev->ctrl_buf); | |
| 617 | kfree(pdev); | 596 | kfree(pdev); |
| 618 | } | 597 | } |
| 619 | 598 | ||
| @@ -758,7 +737,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 758 | 737 | ||
| 759 | /* Turn on camera and set LEDS on */ | 738 | /* Turn on camera and set LEDS on */ |
| 760 | pwc_camera_power(pdev, 1); | 739 | pwc_camera_power(pdev, 1); |
| 761 | pwc_set_leds(pdev, led_on, led_off); | 740 | pwc_set_leds(pdev, leds[0], leds[1]); |
| 762 | 741 | ||
| 763 | r = pwc_isoc_init(pdev); | 742 | r = pwc_isoc_init(pdev); |
| 764 | if (r) { | 743 | if (r) { |
| @@ -813,10 +792,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 813 | struct usb_device *udev = interface_to_usbdev(intf); | 792 | struct usb_device *udev = interface_to_usbdev(intf); |
| 814 | struct pwc_device *pdev = NULL; | 793 | struct pwc_device *pdev = NULL; |
| 815 | int vendor_id, product_id, type_id; | 794 | int vendor_id, product_id, type_id; |
| 816 | int hint, rc; | 795 | int rc; |
| 817 | int features = 0; | 796 | int features = 0; |
| 818 | int compression = 0; | 797 | int compression = 0; |
| 819 | int video_nr = -1; /* default: use next available device */ | ||
| 820 | int my_power_save = power_save; | 798 | int my_power_save = power_save; |
| 821 | char serial_number[30], *name; | 799 | char serial_number[30], *name; |
| 822 | 800 | ||
| @@ -1076,7 +1054,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 1076 | return -ENOMEM; | 1054 | return -ENOMEM; |
| 1077 | } | 1055 | } |
| 1078 | pdev->type = type_id; | 1056 | pdev->type = type_id; |
| 1079 | pdev->vframes = default_fps; | ||
| 1080 | pdev->features = features; | 1057 | pdev->features = features; |
| 1081 | pwc_construct(pdev); /* set min/max sizes correct */ | 1058 | pwc_construct(pdev); /* set min/max sizes correct */ |
| 1082 | 1059 | ||
| @@ -1107,24 +1084,14 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 1107 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); | 1084 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); |
| 1108 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); | 1085 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); |
| 1109 | 1086 | ||
| 1110 | /* Now search device_hint[] table for a match, so we can hint a node number. */ | 1087 | /* Allocate USB command buffers */ |
| 1111 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) { | 1088 | pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL); |
| 1112 | if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) && | 1089 | if (!pdev->ctrl_buf) { |
| 1113 | (device_hint[hint].pdev == NULL)) { | 1090 | PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); |
| 1114 | /* so far, so good... try serial number */ | 1091 | rc = -ENOMEM; |
| 1115 | if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { | 1092 | goto err_free_mem; |
| 1116 | /* match! */ | ||
| 1117 | video_nr = device_hint[hint].device_node; | ||
| 1118 | PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr); | ||
| 1119 | break; | ||
| 1120 | } | ||
| 1121 | } | ||
| 1122 | } | 1093 | } |
| 1123 | 1094 | ||
| 1124 | /* occupy slot */ | ||
| 1125 | if (hint < MAX_DEV_HINTS) | ||
| 1126 | device_hint[hint].pdev = pdev; | ||
| 1127 | |||
| 1128 | #ifdef CONFIG_USB_PWC_DEBUG | 1095 | #ifdef CONFIG_USB_PWC_DEBUG |
| 1129 | /* Query sensor type */ | 1096 | /* Query sensor type */ |
| 1130 | if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { | 1097 | if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { |
| @@ -1138,8 +1105,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 1138 | pwc_set_leds(pdev, 0, 0); | 1105 | pwc_set_leds(pdev, 0, 0); |
| 1139 | 1106 | ||
| 1140 | /* Setup intial videomode */ | 1107 | /* Setup intial videomode */ |
| 1141 | rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes, | 1108 | rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, |
| 1142 | &compression); | 1109 | V4L2_PIX_FMT_YUV420, 30, &compression, 1); |
| 1143 | if (rc) | 1110 | if (rc) |
| 1144 | goto err_free_mem; | 1111 | goto err_free_mem; |
| 1145 | 1112 | ||
| @@ -1164,7 +1131,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 1164 | pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; | 1131 | pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; |
| 1165 | pdev->vdev.v4l2_dev = &pdev->v4l2_dev; | 1132 | pdev->vdev.v4l2_dev = &pdev->v4l2_dev; |
| 1166 | 1133 | ||
| 1167 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); | 1134 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); |
| 1168 | if (rc < 0) { | 1135 | if (rc < 0) { |
| 1169 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | 1136 | PWC_ERROR("Failed to register as video device (%d).\n", rc); |
| 1170 | goto err_unregister_v4l2_dev; | 1137 | goto err_unregister_v4l2_dev; |
| @@ -1207,8 +1174,7 @@ err_unregister_v4l2_dev: | |||
| 1207 | err_free_controls: | 1174 | err_free_controls: |
| 1208 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | 1175 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); |
| 1209 | err_free_mem: | 1176 | err_free_mem: |
| 1210 | if (hint < MAX_DEV_HINTS) | 1177 | kfree(pdev->ctrl_buf); |
| 1211 | device_hint[hint].pdev = NULL; | ||
| 1212 | kfree(pdev); | 1178 | kfree(pdev); |
| 1213 | return rc; | 1179 | return rc; |
| 1214 | } | 1180 | } |
| @@ -1243,27 +1209,19 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
| 1243 | * Initialization code & module stuff | 1209 | * Initialization code & module stuff |
| 1244 | */ | 1210 | */ |
| 1245 | 1211 | ||
| 1246 | static int fps; | ||
| 1247 | static int leds[2] = { -1, -1 }; | ||
| 1248 | static unsigned int leds_nargs; | 1212 | static unsigned int leds_nargs; |
| 1249 | static char *dev_hint[MAX_DEV_HINTS]; | ||
| 1250 | static unsigned int dev_hint_nargs; | ||
| 1251 | 1213 | ||
| 1252 | module_param(fps, int, 0444); | ||
| 1253 | #ifdef CONFIG_USB_PWC_DEBUG | 1214 | #ifdef CONFIG_USB_PWC_DEBUG |
| 1254 | module_param_named(trace, pwc_trace, int, 0644); | 1215 | module_param_named(trace, pwc_trace, int, 0644); |
| 1255 | #endif | 1216 | #endif |
| 1256 | module_param(power_save, int, 0644); | 1217 | module_param(power_save, int, 0644); |
| 1257 | module_param_array(leds, int, &leds_nargs, 0444); | 1218 | module_param_array(leds, int, &leds_nargs, 0444); |
| 1258 | module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); | ||
| 1259 | 1219 | ||
| 1260 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); | ||
| 1261 | #ifdef CONFIG_USB_PWC_DEBUG | 1220 | #ifdef CONFIG_USB_PWC_DEBUG |
| 1262 | MODULE_PARM_DESC(trace, "For debugging purposes"); | 1221 | MODULE_PARM_DESC(trace, "For debugging purposes"); |
| 1263 | #endif | 1222 | #endif |
| 1264 | MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); | 1223 | MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); |
| 1265 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); | 1224 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); |
| 1266 | MODULE_PARM_DESC(dev_hint, "Device node hints"); | ||
| 1267 | 1225 | ||
| 1268 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); | 1226 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); |
| 1269 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); | 1227 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); |
| @@ -1273,114 +1231,13 @@ MODULE_VERSION( PWC_VERSION ); | |||
| 1273 | 1231 | ||
| 1274 | static int __init usb_pwc_init(void) | 1232 | static int __init usb_pwc_init(void) |
| 1275 | { | 1233 | { |
| 1276 | int i; | ||
| 1277 | |||
| 1278 | #ifdef CONFIG_USB_PWC_DEBUG | ||
| 1279 | PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n"); | ||
| 1280 | PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); | ||
| 1281 | PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); | ||
| 1282 | PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); | ||
| 1283 | |||
| 1284 | if (pwc_trace >= 0) { | ||
| 1285 | PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); | ||
| 1286 | } | ||
| 1287 | #endif | ||
| 1288 | |||
| 1289 | if (fps) { | ||
| 1290 | if (fps < 4 || fps > 30) { | ||
| 1291 | PWC_ERROR("Framerate out of bounds (4-30).\n"); | ||
| 1292 | return -EINVAL; | ||
| 1293 | } | ||
| 1294 | default_fps = fps; | ||
| 1295 | PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | if (leds[0] >= 0) | ||
| 1299 | led_on = leds[0]; | ||
| 1300 | if (leds[1] >= 0) | ||
| 1301 | led_off = leds[1]; | ||
| 1302 | |||
| 1303 | /* Big device node whoopla. Basically, it allows you to assign a | ||
| 1304 | device node (/dev/videoX) to a camera, based on its type | ||
| 1305 | & serial number. The format is [type[.serialnumber]:]node. | ||
| 1306 | |||
| 1307 | Any camera that isn't matched by these rules gets the next | ||
| 1308 | available free device node. | ||
| 1309 | */ | ||
| 1310 | for (i = 0; i < MAX_DEV_HINTS; i++) { | ||
| 1311 | char *s, *colon, *dot; | ||
| 1312 | |||
| 1313 | /* This loop also initializes the array */ | ||
| 1314 | device_hint[i].pdev = NULL; | ||
| 1315 | s = dev_hint[i]; | ||
| 1316 | if (s != NULL && *s != '\0') { | ||
| 1317 | device_hint[i].type = -1; /* wildcard */ | ||
| 1318 | strcpy(device_hint[i].serial_number, "*"); | ||
| 1319 | |||
| 1320 | /* parse string: chop at ':' & '/' */ | ||
| 1321 | colon = dot = s; | ||
| 1322 | while (*colon != '\0' && *colon != ':') | ||
| 1323 | colon++; | ||
| 1324 | while (*dot != '\0' && *dot != '.') | ||
| 1325 | dot++; | ||
| 1326 | /* Few sanity checks */ | ||
| 1327 | if (*dot != '\0' && dot > colon) { | ||
| 1328 | PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n"); | ||
| 1329 | return -EINVAL; | ||
| 1330 | } | ||
| 1331 | |||
| 1332 | if (*colon == '\0') { | ||
| 1333 | /* No colon */ | ||
| 1334 | if (*dot != '\0') { | ||
| 1335 | PWC_ERROR("Malformed camera hint: no colon + device node given.\n"); | ||
| 1336 | return -EINVAL; | ||
| 1337 | } | ||
| 1338 | else { | ||
| 1339 | /* No type or serial number specified, just a number. */ | ||
| 1340 | device_hint[i].device_node = | ||
| 1341 | simple_strtol(s, NULL, 10); | ||
| 1342 | } | ||
| 1343 | } | ||
| 1344 | else { | ||
| 1345 | /* There's a colon, so we have at least a type and a device node */ | ||
| 1346 | device_hint[i].type = | ||
| 1347 | simple_strtol(s, NULL, 10); | ||
| 1348 | device_hint[i].device_node = | ||
| 1349 | simple_strtol(colon + 1, NULL, 10); | ||
| 1350 | if (*dot != '\0') { | ||
| 1351 | /* There's a serial number as well */ | ||
| 1352 | int k; | ||
| 1353 | |||
| 1354 | dot++; | ||
| 1355 | k = 0; | ||
| 1356 | while (*dot != ':' && k < 29) { | ||
| 1357 | device_hint[i].serial_number[k++] = *dot; | ||
| 1358 | dot++; | ||
| 1359 | } | ||
| 1360 | device_hint[i].serial_number[k] = '\0'; | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | PWC_TRACE("device_hint[%d]:\n", i); | ||
| 1364 | PWC_TRACE(" type : %d\n", device_hint[i].type); | ||
| 1365 | PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number); | ||
| 1366 | PWC_TRACE(" node : %d\n", device_hint[i].device_node); | ||
| 1367 | } | ||
| 1368 | else | ||
| 1369 | device_hint[i].type = 0; /* not filled */ | ||
| 1370 | } /* ..for MAX_DEV_HINTS */ | ||
| 1371 | |||
| 1372 | PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver); | ||
| 1373 | return usb_register(&pwc_driver); | 1234 | return usb_register(&pwc_driver); |
| 1374 | } | 1235 | } |
| 1375 | 1236 | ||
| 1376 | static void __exit usb_pwc_exit(void) | 1237 | static void __exit usb_pwc_exit(void) |
| 1377 | { | 1238 | { |
| 1378 | PWC_DEBUG_MODULE("Deregistering driver.\n"); | ||
| 1379 | usb_deregister(&pwc_driver); | 1239 | usb_deregister(&pwc_driver); |
| 1380 | PWC_INFO("Philips webcam module removed.\n"); | ||
| 1381 | } | 1240 | } |
| 1382 | 1241 | ||
| 1383 | module_init(usb_pwc_init); | 1242 | module_init(usb_pwc_init); |
| 1384 | module_exit(usb_pwc_exit); | 1243 | module_exit(usb_pwc_exit); |
| 1385 | |||
| 1386 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 23a55b5814fc..9be5adffa874 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c | |||
| @@ -90,5 +90,4 @@ void pwc_construct(struct pwc_device *pdev) | |||
| 90 | pdev->frame_header_size = 0; | 90 | pdev->frame_header_size = 0; |
| 91 | pdev->frame_trailer_size = 0; | 91 | pdev->frame_trailer_size = 0; |
| 92 | } | 92 | } |
| 93 | pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ | ||
| 94 | } | 93 | } |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 80e25842e84a..f495eeb5403a 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
| @@ -493,16 +493,11 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
| 493 | (pixelformat>>24)&255); | 493 | (pixelformat>>24)&255); |
| 494 | 494 | ||
| 495 | ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, | 495 | ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, |
| 496 | pdev->vframes, &compression); | 496 | pixelformat, 30, &compression, 0); |
| 497 | 497 | ||
| 498 | PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); | 498 | PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); |
| 499 | 499 | ||
| 500 | if (ret == 0) { | 500 | pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); |
| 501 | pdev->pixfmt = pixelformat; | ||
| 502 | pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, | ||
| 503 | pdev->pixfmt); | ||
| 504 | } | ||
| 505 | |||
| 506 | leave: | 501 | leave: |
| 507 | mutex_unlock(&pdev->udevlock); | 502 | mutex_unlock(&pdev->udevlock); |
| 508 | return ret; | 503 | return ret; |
| @@ -777,33 +772,33 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev) | |||
| 777 | static int pwc_set_motor(struct pwc_device *pdev) | 772 | static int pwc_set_motor(struct pwc_device *pdev) |
| 778 | { | 773 | { |
| 779 | int ret; | 774 | int ret; |
| 780 | u8 buf[4]; | ||
| 781 | 775 | ||
| 782 | buf[0] = 0; | 776 | pdev->ctrl_buf[0] = 0; |
| 783 | if (pdev->motor_pan_reset->is_new) | 777 | if (pdev->motor_pan_reset->is_new) |
| 784 | buf[0] |= 0x01; | 778 | pdev->ctrl_buf[0] |= 0x01; |
| 785 | if (pdev->motor_tilt_reset->is_new) | 779 | if (pdev->motor_tilt_reset->is_new) |
| 786 | buf[0] |= 0x02; | 780 | pdev->ctrl_buf[0] |= 0x02; |
| 787 | if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) { | 781 | if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) { |
| 788 | ret = send_control_msg(pdev, SET_MPT_CTL, | 782 | ret = send_control_msg(pdev, SET_MPT_CTL, |
| 789 | PT_RESET_CONTROL_FORMATTER, buf, 1); | 783 | PT_RESET_CONTROL_FORMATTER, |
| 784 | pdev->ctrl_buf, 1); | ||
| 790 | if (ret < 0) | 785 | if (ret < 0) |
| 791 | return ret; | 786 | return ret; |
| 792 | } | 787 | } |
| 793 | 788 | ||
| 794 | memset(buf, 0, sizeof(buf)); | 789 | memset(pdev->ctrl_buf, 0, 4); |
| 795 | if (pdev->motor_pan->is_new) { | 790 | if (pdev->motor_pan->is_new) { |
| 796 | buf[0] = pdev->motor_pan->val & 0xFF; | 791 | pdev->ctrl_buf[0] = pdev->motor_pan->val & 0xFF; |
| 797 | buf[1] = (pdev->motor_pan->val >> 8); | 792 | pdev->ctrl_buf[1] = (pdev->motor_pan->val >> 8); |
| 798 | } | 793 | } |
| 799 | if (pdev->motor_tilt->is_new) { | 794 | if (pdev->motor_tilt->is_new) { |
| 800 | buf[2] = pdev->motor_tilt->val & 0xFF; | 795 | pdev->ctrl_buf[2] = pdev->motor_tilt->val & 0xFF; |
| 801 | buf[3] = (pdev->motor_tilt->val >> 8); | 796 | pdev->ctrl_buf[3] = (pdev->motor_tilt->val >> 8); |
| 802 | } | 797 | } |
| 803 | if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) { | 798 | if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) { |
| 804 | ret = send_control_msg(pdev, SET_MPT_CTL, | 799 | ret = send_control_msg(pdev, SET_MPT_CTL, |
| 805 | PT_RELATIVE_CONTROL_FORMATTER, | 800 | PT_RELATIVE_CONTROL_FORMATTER, |
| 806 | buf, sizeof(buf)); | 801 | pdev->ctrl_buf, 4); |
| 807 | if (ret < 0) | 802 | if (ret < 0) |
| 808 | return ret; | 803 | return ret; |
| 809 | } | 804 | } |
| @@ -1094,6 +1089,63 @@ static int pwc_enum_frameintervals(struct file *file, void *fh, | |||
| 1094 | return 0; | 1089 | return 0; |
| 1095 | } | 1090 | } |
| 1096 | 1091 | ||
| 1092 | static int pwc_g_parm(struct file *file, void *fh, | ||
| 1093 | struct v4l2_streamparm *parm) | ||
| 1094 | { | ||
| 1095 | struct pwc_device *pdev = video_drvdata(file); | ||
| 1096 | |||
| 1097 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1098 | return -EINVAL; | ||
| 1099 | |||
| 1100 | memset(parm, 0, sizeof(*parm)); | ||
| 1101 | |||
| 1102 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 1103 | parm->parm.capture.readbuffers = MIN_FRAMES; | ||
| 1104 | parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME; | ||
| 1105 | parm->parm.capture.timeperframe.denominator = pdev->vframes; | ||
| 1106 | parm->parm.capture.timeperframe.numerator = 1; | ||
| 1107 | |||
| 1108 | return 0; | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | static int pwc_s_parm(struct file *file, void *fh, | ||
| 1112 | struct v4l2_streamparm *parm) | ||
| 1113 | { | ||
| 1114 | struct pwc_device *pdev = video_drvdata(file); | ||
| 1115 | int compression = 0; | ||
| 1116 | int ret, fps; | ||
| 1117 | |||
| 1118 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
| 1119 | parm->parm.capture.timeperframe.numerator == 0) | ||
| 1120 | return -EINVAL; | ||
| 1121 | |||
| 1122 | if (pwc_test_n_set_capt_file(pdev, file)) | ||
| 1123 | return -EBUSY; | ||
| 1124 | |||
| 1125 | fps = parm->parm.capture.timeperframe.denominator / | ||
| 1126 | parm->parm.capture.timeperframe.numerator; | ||
| 1127 | |||
| 1128 | mutex_lock(&pdev->udevlock); | ||
| 1129 | if (!pdev->udev) { | ||
| 1130 | ret = -ENODEV; | ||
| 1131 | goto leave; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | if (pdev->iso_init) { | ||
| 1135 | ret = -EBUSY; | ||
| 1136 | goto leave; | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, | ||
| 1140 | fps, &compression, 0); | ||
| 1141 | |||
| 1142 | pwc_g_parm(file, fh, parm); | ||
| 1143 | |||
| 1144 | leave: | ||
| 1145 | mutex_unlock(&pdev->udevlock); | ||
| 1146 | return ret; | ||
| 1147 | } | ||
| 1148 | |||
| 1097 | static int pwc_log_status(struct file *file, void *priv) | 1149 | static int pwc_log_status(struct file *file, void *priv) |
| 1098 | { | 1150 | { |
| 1099 | struct pwc_device *pdev = video_drvdata(file); | 1151 | struct pwc_device *pdev = video_drvdata(file); |
| @@ -1120,4 +1172,6 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = { | |||
| 1120 | .vidioc_log_status = pwc_log_status, | 1172 | .vidioc_log_status = pwc_log_status, |
| 1121 | .vidioc_enum_framesizes = pwc_enum_framesizes, | 1173 | .vidioc_enum_framesizes = pwc_enum_framesizes, |
| 1122 | .vidioc_enum_frameintervals = pwc_enum_frameintervals, | 1174 | .vidioc_enum_frameintervals = pwc_enum_frameintervals, |
| 1175 | .vidioc_g_parm = pwc_g_parm, | ||
| 1176 | .vidioc_s_parm = pwc_s_parm, | ||
| 1123 | }; | 1177 | }; |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 47c518fef179..e4d4d711dd1f 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
| @@ -44,6 +44,8 @@ | |||
| 44 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 44 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
| 45 | #include <linux/input.h> | 45 | #include <linux/input.h> |
| 46 | #endif | 46 | #endif |
| 47 | #include "pwc-dec1.h" | ||
| 48 | #include "pwc-dec23.h" | ||
| 47 | 49 | ||
| 48 | /* Version block */ | 50 | /* Version block */ |
| 49 | #define PWC_VERSION "10.0.15" | 51 | #define PWC_VERSION "10.0.15" |
| @@ -132,9 +134,6 @@ | |||
| 132 | #define DEVICE_USE_CODEC3(x) ((x)>=700) | 134 | #define DEVICE_USE_CODEC3(x) ((x)>=700) |
| 133 | #define DEVICE_USE_CODEC23(x) ((x)>=675) | 135 | #define DEVICE_USE_CODEC23(x) ((x)>=675) |
| 134 | 136 | ||
| 135 | /* from pwc-dec.h */ | ||
| 136 | #define PWCX_FLAG_PLANAR 0x0001 | ||
| 137 | |||
| 138 | /* Request types: video */ | 137 | /* Request types: video */ |
| 139 | #define SET_LUM_CTL 0x01 | 138 | #define SET_LUM_CTL 0x01 |
| 140 | #define GET_LUM_CTL 0x02 | 139 | #define GET_LUM_CTL 0x02 |
| @@ -248,8 +247,8 @@ struct pwc_device | |||
| 248 | char vmirror; /* for ToUCaM series */ | 247 | char vmirror; /* for ToUCaM series */ |
| 249 | char power_save; /* Do powersaving for this cam */ | 248 | char power_save; /* Do powersaving for this cam */ |
| 250 | 249 | ||
| 251 | int cmd_len; | ||
| 252 | unsigned char cmd_buf[13]; | 250 | unsigned char cmd_buf[13]; |
| 251 | unsigned char *ctrl_buf; | ||
| 253 | 252 | ||
| 254 | struct urb *urbs[MAX_ISO_BUFS]; | 253 | struct urb *urbs[MAX_ISO_BUFS]; |
| 255 | char iso_init; | 254 | char iso_init; |
| @@ -272,7 +271,10 @@ struct pwc_device | |||
| 272 | int frame_total_size; /* including header & trailer */ | 271 | int frame_total_size; /* including header & trailer */ |
| 273 | int drop_frames; | 272 | int drop_frames; |
| 274 | 273 | ||
| 275 | void *decompress_data; /* private data for decompression engine */ | 274 | union { /* private data for decompression engine */ |
| 275 | struct pwc_dec1_private dec1; | ||
| 276 | struct pwc_dec23_private dec23; | ||
| 277 | }; | ||
| 276 | 278 | ||
| 277 | /* | 279 | /* |
| 278 | * We have an 'image' and a 'view', where 'image' is the fixed-size img | 280 | * We have an 'image' and a 'view', where 'image' is the fixed-size img |
| @@ -364,7 +366,7 @@ void pwc_construct(struct pwc_device *pdev); | |||
| 364 | /** Functions in pwc-ctrl.c */ | 366 | /** Functions in pwc-ctrl.c */ |
| 365 | /* Request a certain video mode. Returns < 0 if not possible */ | 367 | /* Request a certain video mode. Returns < 0 if not possible */ |
| 366 | extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, | 368 | extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, |
| 367 | int frames, int *compression); | 369 | int pixfmt, int frames, int *compression, int send_to_cam); |
| 368 | extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); | 370 | extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); |
| 369 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); | 371 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); |
| 370 | extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); | 372 | extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 510cfab477ff..a9e9653beeb4 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
| @@ -693,7 +693,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
| 693 | mf->code = 0; | 693 | mf->code = 0; |
| 694 | continue; | 694 | continue; |
| 695 | } | 695 | } |
| 696 | if (mf->width != tfmt->width || mf->width != tfmt->width) { | 696 | if (mf->width != tfmt->width || mf->height != tfmt->height) { |
| 697 | u32 fcc = ffmt->fourcc; | 697 | u32 fcc = ffmt->fourcc; |
| 698 | tfmt->width = mf->width; | 698 | tfmt->width = mf->width; |
| 699 | tfmt->height = mf->height; | 699 | tfmt->height = mf->height; |
| @@ -702,7 +702,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
| 702 | NULL, &fcc, FIMC_SD_PAD_SOURCE); | 702 | NULL, &fcc, FIMC_SD_PAD_SOURCE); |
| 703 | if (ffmt && ffmt->mbus_code) | 703 | if (ffmt && ffmt->mbus_code) |
| 704 | mf->code = ffmt->mbus_code; | 704 | mf->code = ffmt->mbus_code; |
| 705 | if (mf->width != tfmt->width || mf->width != tfmt->width) | 705 | if (mf->width != tfmt->width || |
| 706 | mf->height != tfmt->height) | ||
| 706 | continue; | 707 | continue; |
| 707 | tfmt->code = mf->code; | 708 | tfmt->code = mf->code; |
| 708 | } | 709 | } |
| @@ -710,7 +711,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
| 710 | ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt); | 711 | ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt); |
| 711 | 712 | ||
| 712 | if (mf->code == tfmt->code && | 713 | if (mf->code == tfmt->code && |
| 713 | mf->width == tfmt->width && mf->width == tfmt->width) | 714 | mf->width == tfmt->width && mf->height == tfmt->height) |
| 714 | break; | 715 | break; |
| 715 | } | 716 | } |
| 716 | 717 | ||
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index f5cbb8a4c540..81bcbb9492ea 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
| @@ -848,11 +848,11 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) | |||
| 848 | v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); | 848 | v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); |
| 849 | 849 | ||
| 850 | ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, | 850 | ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, |
| 851 | V4L2_CID_HFLIP, 0, 1, 1, 0); | 851 | V4L2_CID_ROTATE, 0, 270, 90, 0); |
| 852 | ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, | 852 | ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, |
| 853 | V4L2_CID_VFLIP, 0, 1, 1, 0); | 853 | V4L2_CID_HFLIP, 0, 1, 1, 0); |
| 854 | ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, | 854 | ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, |
| 855 | V4L2_CID_ROTATE, 0, 270, 90, 0); | 855 | V4L2_CID_VFLIP, 0, 1, 1, 0); |
| 856 | if (variant->has_alpha) | 856 | if (variant->has_alpha) |
| 857 | ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, | 857 | ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, |
| 858 | &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, | 858 | &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, |
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 615c862f0360..8ea4ee116e46 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
| 22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/version.h> | ||
| 25 | #include <media/v4l2-ctrls.h> | 24 | #include <media/v4l2-ctrls.h> |
| 26 | #include <media/media-device.h> | 25 | #include <media/media-device.h> |
| 27 | 26 | ||
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index c40b0dde1883..febaa673d363 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c | |||
| @@ -184,6 +184,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 184 | ctx->rop = ROP4_INVERT; | 184 | ctx->rop = ROP4_INVERT; |
| 185 | else | 185 | else |
| 186 | ctx->rop = ROP4_COPY; | 186 | ctx->rop = ROP4_COPY; |
| 187 | break; | ||
| 187 | default: | 188 | default: |
| 188 | v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); | 189 | v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); |
| 189 | return -EINVAL; | 190 | return -EINVAL; |
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c index f841a3e9845c..1105a8749c8b 100644 --- a/drivers/media/video/s5p-jpeg/jpeg-core.c +++ b/drivers/media/video/s5p-jpeg/jpeg-core.c | |||
| @@ -989,9 +989,10 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = { | |||
| 989 | * ============================================================================ | 989 | * ============================================================================ |
| 990 | */ | 990 | */ |
| 991 | 991 | ||
| 992 | static int s5p_jpeg_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, | 992 | static int s5p_jpeg_queue_setup(struct vb2_queue *vq, |
| 993 | unsigned int *nplanes, unsigned int sizes[], | 993 | const struct v4l2_format *fmt, |
| 994 | void *alloc_ctxs[]) | 994 | unsigned int *nbuffers, unsigned int *nplanes, |
| 995 | unsigned int sizes[], void *alloc_ctxs[]) | ||
| 995 | { | 996 | { |
| 996 | struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq); | 997 | struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq); |
| 997 | struct s5p_jpeg_q_data *q_data = NULL; | 998 | struct s5p_jpeg_q_data *q_data = NULL; |
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/video/s5p-mfc/s5p_mfc.c index e43e128baf5f..83fe461af263 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/version.h> | ||
| 22 | #include <linux/videodev2.h> | 21 | #include <linux/videodev2.h> |
| 23 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
| 24 | #include <media/videobuf2-core.h> | 23 | #include <media/videobuf2-core.h> |
| @@ -475,7 +474,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
| 475 | ctx->mv_size = 0; | 474 | ctx->mv_size = 0; |
| 476 | } | 475 | } |
| 477 | ctx->dpb_count = s5p_mfc_get_dpb_count(); | 476 | ctx->dpb_count = s5p_mfc_get_dpb_count(); |
| 478 | if (ctx->img_width == 0 || ctx->img_width == 0) | 477 | if (ctx->img_width == 0 || ctx->img_height == 0) |
| 479 | ctx->state = MFCINST_ERROR; | 478 | ctx->state = MFCINST_ERROR; |
| 480 | else | 479 | else |
| 481 | ctx->state = MFCINST_HEAD_PARSED; | 480 | ctx->state = MFCINST_HEAD_PARSED; |
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index 844a4d7797bc..c25ec022d267 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c | |||
| @@ -165,7 +165,7 @@ static struct mfc_control controls[] = { | |||
| 165 | .maximum = 32, | 165 | .maximum = 32, |
| 166 | .step = 1, | 166 | .step = 1, |
| 167 | .default_value = 1, | 167 | .default_value = 1, |
| 168 | .flags = V4L2_CTRL_FLAG_VOLATILE, | 168 | .is_volatile = 1, |
| 169 | }, | 169 | }, |
| 170 | }; | 170 | }; |
| 171 | 171 | ||
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c index 971591d6450f..5b72da5ce418 100644 --- a/drivers/media/video/saa7164/saa7164-cards.c +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
| @@ -269,8 +269,6 @@ struct saa7164_board saa7164_boards[] = { | |||
| 269 | .portb = SAA7164_MPEG_DVB, | 269 | .portb = SAA7164_MPEG_DVB, |
| 270 | .portc = SAA7164_MPEG_ENCODER, | 270 | .portc = SAA7164_MPEG_ENCODER, |
| 271 | .portd = SAA7164_MPEG_ENCODER, | 271 | .portd = SAA7164_MPEG_ENCODER, |
| 272 | .portc = SAA7164_MPEG_ENCODER, | ||
| 273 | .portd = SAA7164_MPEG_ENCODER, | ||
| 274 | .porte = SAA7164_MPEG_VBI, | 272 | .porte = SAA7164_MPEG_VBI, |
| 275 | .portf = SAA7164_MPEG_VBI, | 273 | .portf = SAA7164_MPEG_VBI, |
| 276 | .chiprev = SAA7164_CHIP_REV3, | 274 | .chiprev = SAA7164_CHIP_REV3, |
| @@ -333,8 +331,6 @@ struct saa7164_board saa7164_boards[] = { | |||
| 333 | .portd = SAA7164_MPEG_ENCODER, | 331 | .portd = SAA7164_MPEG_ENCODER, |
| 334 | .porte = SAA7164_MPEG_VBI, | 332 | .porte = SAA7164_MPEG_VBI, |
| 335 | .portf = SAA7164_MPEG_VBI, | 333 | .portf = SAA7164_MPEG_VBI, |
| 336 | .porte = SAA7164_MPEG_VBI, | ||
| 337 | .portf = SAA7164_MPEG_VBI, | ||
| 338 | .chiprev = SAA7164_CHIP_REV3, | 334 | .chiprev = SAA7164_CHIP_REV3, |
| 339 | .unit = {{ | 335 | .unit = {{ |
| 340 | .id = 0x28, | 336 | .id = 0x28, |
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c index 129f135d5a5f..c096b3f74200 100644 --- a/drivers/media/video/tlg2300/pd-main.c +++ b/drivers/media/video/tlg2300/pd-main.c | |||
| @@ -374,7 +374,7 @@ static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev) | |||
| 374 | } | 374 | } |
| 375 | #endif | 375 | #endif |
| 376 | 376 | ||
| 377 | static bool check_firmware(struct usb_device *udev, int *down_firmware) | 377 | static int check_firmware(struct usb_device *udev, int *down_firmware) |
| 378 | { | 378 | { |
| 379 | void *buf; | 379 | void *buf; |
| 380 | int ret; | 380 | int ret; |
| @@ -398,7 +398,7 @@ static bool check_firmware(struct usb_device *udev, int *down_firmware) | |||
| 398 | *down_firmware = 1; | 398 | *down_firmware = 1; |
| 399 | return firmware_download(udev); | 399 | return firmware_download(udev); |
| 400 | } | 400 | } |
| 401 | return ret; | 401 | return 0; |
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | static int poseidon_probe(struct usb_interface *interface, | 404 | static int poseidon_probe(struct usb_interface *interface, |
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index da1f4c2d2d4b..cccd42be718a 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c | |||
| @@ -465,8 +465,8 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 465 | case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; | 465 | case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; |
| 466 | case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; | 466 | case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; |
| 467 | case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; | 467 | case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; |
| 468 | case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Minimum Number of Capture Buffers"; | 468 | case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; |
| 469 | case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Minimum Number of Output Buffers"; | 469 | case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; |
| 470 | case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; | 470 | case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; |
| 471 | 471 | ||
| 472 | /* MPEG controls */ | 472 | /* MPEG controls */ |
| @@ -506,25 +506,25 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 506 | case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; | 506 | case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; |
| 507 | case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; | 507 | case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; |
| 508 | case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; | 508 | case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; |
| 509 | case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "The Number of Intra Refresh MBs"; | 509 | case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs"; |
| 510 | case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; | 510 | case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; |
| 511 | case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; | 511 | case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; |
| 512 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; | 512 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; |
| 513 | case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "The Max Number of Reference Picture"; | 513 | case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; |
| 514 | case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; | 514 | case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; |
| 515 | case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P frame QP Value"; | 515 | case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; |
| 516 | case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B frame QP Value"; | 516 | case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; |
| 517 | case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; | 517 | case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; |
| 518 | case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; | 518 | case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; |
| 519 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; | 519 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; |
| 520 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P frame QP Value"; | 520 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value"; |
| 521 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B frame QP Value"; | 521 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value"; |
| 522 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; | 522 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; |
| 523 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; | 523 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; |
| 524 | case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; | 524 | case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; |
| 525 | case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; | 525 | case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; |
| 526 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entorpy Mode"; | 526 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode"; |
| 527 | case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I Period"; | 527 | case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period"; |
| 528 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; | 528 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; |
| 529 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; | 529 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; |
| 530 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; | 530 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; |
| @@ -535,16 +535,16 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 535 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; | 535 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; |
| 536 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; | 536 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; |
| 537 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; | 537 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; |
| 538 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P frame QP Value"; | 538 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; |
| 539 | case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B frame QP Value"; | 539 | case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; |
| 540 | case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; | 540 | case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; |
| 541 | case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; | 541 | case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; |
| 542 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; | 542 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; |
| 543 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; | 543 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; |
| 544 | case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; | 544 | case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; |
| 545 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "The Maximum Bytes Per Slice"; | 545 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice"; |
| 546 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "The Number of MB in a Slice"; | 546 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; |
| 547 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "The Slice Partitioning Method"; | 547 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; |
| 548 | case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; | 548 | case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; |
| 549 | 549 | ||
| 550 | /* CAMERA controls */ | 550 | /* CAMERA controls */ |
| @@ -580,7 +580,7 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 580 | case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; | 580 | case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; |
| 581 | case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; | 581 | case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; |
| 582 | case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; | 582 | case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; |
| 583 | case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Feature Enabled"; | 583 | case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled"; |
| 584 | case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; | 584 | case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; |
| 585 | case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; | 585 | case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; |
| 586 | case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; | 586 | case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; |
| @@ -588,24 +588,24 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 588 | case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; | 588 | case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; |
| 589 | case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; | 589 | case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; |
| 590 | case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; | 590 | case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; |
| 591 | case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-emphasis settings"; | 591 | case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis"; |
| 592 | case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; | 592 | case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; |
| 593 | case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; | 593 | case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; |
| 594 | 594 | ||
| 595 | /* Flash controls */ | 595 | /* Flash controls */ |
| 596 | case V4L2_CID_FLASH_CLASS: return "Flash controls"; | 596 | case V4L2_CID_FLASH_CLASS: return "Flash Controls"; |
| 597 | case V4L2_CID_FLASH_LED_MODE: return "LED mode"; | 597 | case V4L2_CID_FLASH_LED_MODE: return "LED Mode"; |
| 598 | case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe source"; | 598 | case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source"; |
| 599 | case V4L2_CID_FLASH_STROBE: return "Strobe"; | 599 | case V4L2_CID_FLASH_STROBE: return "Strobe"; |
| 600 | case V4L2_CID_FLASH_STROBE_STOP: return "Stop strobe"; | 600 | case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe"; |
| 601 | case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe status"; | 601 | case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status"; |
| 602 | case V4L2_CID_FLASH_TIMEOUT: return "Strobe timeout"; | 602 | case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout"; |
| 603 | case V4L2_CID_FLASH_INTENSITY: return "Intensity, flash mode"; | 603 | case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode"; |
| 604 | case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, torch mode"; | 604 | case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode"; |
| 605 | case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, indicator"; | 605 | case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator"; |
| 606 | case V4L2_CID_FLASH_FAULT: return "Faults"; | 606 | case V4L2_CID_FLASH_FAULT: return "Faults"; |
| 607 | case V4L2_CID_FLASH_CHARGE: return "Charge"; | 607 | case V4L2_CID_FLASH_CHARGE: return "Charge"; |
| 608 | case V4L2_CID_FLASH_READY: return "Ready to strobe"; | 608 | case V4L2_CID_FLASH_READY: return "Ready to Strobe"; |
| 609 | 609 | ||
| 610 | default: | 610 | default: |
| 611 | return NULL; | 611 | return NULL; |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 77feeb67e2db..3f623859a337 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
| @@ -1871,6 +1871,7 @@ static long __video_do_ioctl(struct file *file, | |||
| 1871 | case VIDIOC_S_FREQUENCY: | 1871 | case VIDIOC_S_FREQUENCY: |
| 1872 | { | 1872 | { |
| 1873 | struct v4l2_frequency *p = arg; | 1873 | struct v4l2_frequency *p = arg; |
| 1874 | enum v4l2_tuner_type type; | ||
| 1874 | 1875 | ||
| 1875 | if (!ops->vidioc_s_frequency) | 1876 | if (!ops->vidioc_s_frequency) |
| 1876 | break; | 1877 | break; |
| @@ -1878,9 +1879,14 @@ static long __video_do_ioctl(struct file *file, | |||
| 1878 | ret = ret_prio; | 1879 | ret = ret_prio; |
| 1879 | break; | 1880 | break; |
| 1880 | } | 1881 | } |
| 1882 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
| 1883 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
| 1881 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", | 1884 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
| 1882 | p->tuner, p->type, p->frequency); | 1885 | p->tuner, p->type, p->frequency); |
| 1883 | ret = ops->vidioc_s_frequency(file, fh, p); | 1886 | if (p->type != type) |
| 1887 | ret = -EINVAL; | ||
| 1888 | else | ||
| 1889 | ret = ops->vidioc_s_frequency(file, fh, p); | ||
| 1884 | break; | 1890 | break; |
| 1885 | } | 1891 | } |
| 1886 | case VIDIOC_G_SLICED_VBI_CAP: | 1892 | case VIDIOC_G_SLICED_VBI_CAP: |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index f6d26419445e..4c09ab781ec3 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
| @@ -1958,7 +1958,6 @@ static int zoran_g_fbuf(struct file *file, void *__fh, | |||
| 1958 | mutex_unlock(&zr->resource_lock); | 1958 | mutex_unlock(&zr->resource_lock); |
| 1959 | fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; | 1959 | fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; |
| 1960 | fb->fmt.field = V4L2_FIELD_INTERLACED; | 1960 | fb->fmt.field = V4L2_FIELD_INTERLACED; |
| 1961 | fb->flags = V4L2_FBUF_FLAG_OVERLAY; | ||
| 1962 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | 1961 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; |
| 1963 | 1962 | ||
| 1964 | return 0; | 1963 | return 0; |
diff --git a/include/media/tuner.h b/include/media/tuner.h index 89c290b69a5c..29e1920e7339 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
| @@ -127,7 +127,6 @@ | |||
| 127 | #define TUNER_PHILIPS_FMD1216MEX_MK3 78 | 127 | #define TUNER_PHILIPS_FMD1216MEX_MK3 78 |
| 128 | #define TUNER_PHILIPS_FM1216MK5 79 | 128 | #define TUNER_PHILIPS_FM1216MK5 79 |
| 129 | #define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */ | 129 | #define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */ |
| 130 | #define TUNER_XC4000 81 /* Xceive Silicon Tuner */ | ||
| 131 | 130 | ||
| 132 | #define TUNER_PARTSNIC_PTI_5NF05 81 | 131 | #define TUNER_PARTSNIC_PTI_5NF05 81 |
| 133 | #define TUNER_PHILIPS_CU1216L 82 | 132 | #define TUNER_PHILIPS_CU1216L 82 |
| @@ -136,6 +135,8 @@ | |||
| 136 | #define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */ | 135 | #define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */ |
| 137 | #define TUNER_TENA_TNF_5337 86 | 136 | #define TUNER_TENA_TNF_5337 86 |
| 138 | 137 | ||
| 138 | #define TUNER_XC4000 87 /* Xceive Silicon Tuner */ | ||
| 139 | |||
| 139 | /* tv card specific */ | 140 | /* tv card specific */ |
| 140 | #define TDA9887_PRESENT (1<<0) | 141 | #define TDA9887_PRESENT (1<<0) |
| 141 | #define TDA9887_PORT1_INACTIVE (1<<1) | 142 | #define TDA9887_PORT1_INACTIVE (1<<1) |
