Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (57 commits) [media] as3645a: Fix compilation by including slab.h [media] s5p-fimc: Remove linux/version.h include from fimc-mdevice.c [media] s5p-mfc: Remove linux/version.h include from s5p_mfc.c [media] ds3000: using logical && instead of bitwise & [media] v4l2-ctrls: make control names consistent [media] DVB: dib0700, add support for Nova-TD LEDs [media] DVB: dib0700, add corrected Nova-TD frontend_attach [media] DVB: dib0700, separate stk7070pd initialization [media] DVB: dib0700, move Nova-TD Stick to a separate set [media] : add MODULE_FIRMWARE to dib0700 [media] DVB-CORE: remove superfluous DTV_CMDs [media] s5p-jpeg: adapt to recent videobuf2 changes [media] s5p-g2d: fixed a bug in controls setting function [media] s5p-mfc: Fix volatile controls setup [media] drivers/media/video/s5p-mfc/s5p_mfc.c: adjust double test [media] drivers/media/video/s5p-fimc/fimc-capture.c: adjust double test [media] s5p-fimc: Fix incorrect control ID assignment [media] dvb_frontend: Don't call get_frontend() if idle [media] DocBook/dvbproperty.xml: Remove DTV_MODULATION from ISDB-T [media] DocBook/dvbproperty.xml: Fix ISDB-T delivery system parameters ...
This commit is contained in:
Коммит
4a7c1ff236
|
@ -163,14 +163,16 @@ get/set up to 64 properties. The actual meaning of each property is described on
|
|||
<section id="DTV-FREQUENCY">
|
||||
<title><constant>DTV_FREQUENCY</constant></title>
|
||||
|
||||
<para>Central frequency of the channel, in HZ.</para>
|
||||
<para>Central frequency of the channel.</para>
|
||||
|
||||
<para>Notes:</para>
|
||||
<para>1)For ISDB-T, the channels are usually transmitted with an offset of 143kHz.
|
||||
<para>1)For satellital delivery systems, it is measured in kHz.
|
||||
For the other ones, it is measured in Hz.</para>
|
||||
<para>2)For ISDB-T, the channels are usually transmitted with an offset of 143kHz.
|
||||
E.g. a valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
|
||||
the channel which is 6MHz.</para>
|
||||
|
||||
<para>2)As in ISDB-Tsb the channel consists of only one or three segments the
|
||||
<para>3)As in ISDB-Tsb the channel consists of only one or three segments the
|
||||
frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
|
||||
central frequency of the channel is expected.</para>
|
||||
</section>
|
||||
|
@ -735,14 +737,10 @@ typedef enum fe_hierarchy {
|
|||
<listitem><para><link linkend="DTV-TUNE"><constant>DTV_TUNE</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-CLEAR"><constant>DTV_CLEAR</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-MODULATION"><constant>DTV_MODULATION</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-INVERSION"><constant>DTV_INVERSION</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-CODE-RATE-HP"><constant>DTV_CODE_RATE_HP</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-CODE-RATE-LP"><constant>DTV_CODE_RATE_LP</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-GUARD-INTERVAL"><constant>DTV_GUARD_INTERVAL</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-TRANSMISSION-MODE"><constant>DTV_TRANSMISSION_MODE</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-HIERARCHY"><constant>DTV_HIERARCHY</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ISDBT-LAYER-ENABLED"><constant>DTV_ISDBT_LAYER_ENABLED</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ISDBT-PARTIAL-RECEPTION"><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ISDBT-SOUND-BROADCASTING"><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></link></para></listitem>
|
||||
|
|
|
@ -183,7 +183,12 @@ applications must set the array to zero.</entry>
|
|||
<entry>__u32</entry>
|
||||
<entry><structfield>ctrl_class</structfield></entry>
|
||||
<entry>The control class to which all controls belong, see
|
||||
<xref linkend="ctrl-class" />.</entry>
|
||||
<xref linkend="ctrl-class" />. Drivers that use a kernel framework for handling
|
||||
controls will also accept a value of 0 here, meaning that the controls can
|
||||
belong to any control class. Whether drivers support this can be tested by setting
|
||||
<structfield>ctrl_class</structfield> to 0 and calling <constant>VIDIOC_TRY_EXT_CTRLS</constant>
|
||||
with a <structfield>count</structfield> of 0. If that succeeds, then the driver
|
||||
supports this feature.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
@ -194,10 +199,13 @@ also be zero.</entry>
|
|||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>error_idx</structfield></entry>
|
||||
<entry>Set by the driver in case of an error. It is the
|
||||
index of the control causing the error or equal to 'count' when the
|
||||
error is not associated with a particular control. Undefined when the
|
||||
ioctl returns 0 (success).</entry>
|
||||
<entry>Set by the driver in case of an error. If it is equal
|
||||
to <structfield>count</structfield>, then no actual changes were made to
|
||||
controls. In other words, the error was not associated with setting a particular
|
||||
control. If it is another value, then only the controls up to <structfield>error_idx-1</structfield>
|
||||
were modified and control <structfield>error_idx</structfield> is the one that
|
||||
caused the error. The <structfield>error_idx</structfield> value is undefined
|
||||
if the ioctl returned 0 (success).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -364,15 +364,20 @@ capability and it is cleared otherwise.</entry>
|
|||
<row>
|
||||
<entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry>
|
||||
<entry>0x0002</entry>
|
||||
<entry>The frame buffer is an overlay surface the same
|
||||
size as the capture. [?]</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="hspan">The purpose of
|
||||
<constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear.
|
||||
Most drivers seem to ignore this flag. For compatibility with the
|
||||
<wordasword>bttv</wordasword> driver applications should set the
|
||||
<constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry>
|
||||
<entry>If this flag is set for a video capture device, then the
|
||||
driver will set the initial overlay size to cover the full framebuffer size,
|
||||
otherwise the existing overlay size (as set by &VIDIOC-S-FMT;) will be used.
|
||||
|
||||
Only one video capture driver (bttv) supports this flag. The use of this flag
|
||||
for capture devices is deprecated. There is no way to detect which drivers
|
||||
support this flag, so the only reliable method of setting the overlay size is
|
||||
through &VIDIOC-S-FMT;.
|
||||
|
||||
If this flag is set for a video output device, then the video output overlay
|
||||
window is relative to the top-left corner of the framebuffer and restricted
|
||||
to the size of the framebuffer. If it is cleared, then the video output
|
||||
overlay window is relative to the video output display.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_FBUF_FLAG_CHROMAKEY</constant></entry>
|
||||
|
|
|
@ -98,8 +98,11 @@ the &v4l2-output; <structfield>modulator</structfield> field and the
|
|||
<entry>&v4l2-tuner-type;</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>The tuner type. This is the same value as in the
|
||||
&v4l2-tuner; <structfield>type</structfield> field. The field is not
|
||||
applicable to modulators, &ie; ignored by drivers.</entry>
|
||||
&v4l2-tuner; <structfield>type</structfield> field. The type must be set
|
||||
to <constant>V4L2_TUNER_RADIO</constant> for <filename>/dev/radioX</filename>
|
||||
device nodes, and to <constant>V4L2_TUNER_ANALOG_TV</constant>
|
||||
for all others. The field is not applicable to modulators, &ie; ignored
|
||||
by drivers.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -61,8 +61,8 @@ desired input in an integer and call the
|
|||
<constant>VIDIOC_S_INPUT</constant> ioctl with a pointer to this
|
||||
integer. Side effects are possible. For example inputs may support
|
||||
different video standards, so the driver may implicitly switch the
|
||||
current standard. It is good practice to select an input before
|
||||
querying or negotiating any other parameters.</para>
|
||||
current standard. Because of these possible side effects applications
|
||||
must select an input before querying or negotiating any other parameters.</para>
|
||||
|
||||
<para>Information about video inputs is available using the
|
||||
&VIDIOC-ENUMINPUT; ioctl.</para>
|
||||
|
|
|
@ -61,8 +61,9 @@ desired output in an integer and call the
|
|||
<constant>VIDIOC_S_OUTPUT</constant> ioctl with a pointer to this integer.
|
||||
Side effects are possible. For example outputs may support different
|
||||
video standards, so the driver may implicitly switch the current
|
||||
standard. It is good practice to select an output before querying or
|
||||
negotiating any other parameters.</para>
|
||||
standard.
|
||||
standard. Because of these possible side effects applications
|
||||
must select an output before querying or negotiating any other parameters.</para>
|
||||
|
||||
<para>Information about video outputs is available using the
|
||||
&VIDIOC-ENUMOUTPUT; ioctl.</para>
|
||||
|
|
|
@ -439,17 +439,6 @@ Who: Jean Delvare <khali@linux-fr.org>
|
|||
|
||||
----------------------------
|
||||
|
||||
What: For VIDIOC_S_FREQUENCY the type field must match the device node's type.
|
||||
If not, return -EINVAL.
|
||||
When: 3.2
|
||||
Why: It makes no sense to switch the tuner to radio mode by calling
|
||||
VIDIOC_S_FREQUENCY on a video node, or to switch the tuner to tv mode by
|
||||
calling VIDIOC_S_FREQUENCY on a radio node. This is the first step of a
|
||||
move to more consistent handling of tv and radio tuners.
|
||||
Who: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: Opening a radio device node will no longer automatically switch the
|
||||
tuner mode from tv to radio.
|
||||
When: 3.3
|
||||
|
|
|
@ -666,27 +666,6 @@ a control of this type whenever the first control belonging to a new control
|
|||
class is added.
|
||||
|
||||
|
||||
Differences from the Spec
|
||||
=========================
|
||||
|
||||
There are a few places where the framework acts slightly differently from the
|
||||
V4L2 Specification. Those differences are described in this section. We will
|
||||
have to see whether we need to adjust the spec or not.
|
||||
|
||||
1) It is no longer required to have all controls contained in a
|
||||
v4l2_ext_control array be from the same control class. The framework will be
|
||||
able to handle any type of control in the array. You need to set ctrl_class
|
||||
to 0 in order to enable this. If ctrl_class is non-zero, then it will still
|
||||
check that all controls belong to that control class.
|
||||
|
||||
If you set ctrl_class to 0 and count to 0, then it will only return an error
|
||||
if there are no controls at all.
|
||||
|
||||
2) Clarified the way error_idx works. For get and set it will be equal to
|
||||
count if nothing was done yet. If it is less than count then only the controls
|
||||
up to error_idx-1 were successfully applied.
|
||||
|
||||
|
||||
Proposals for Extensions
|
||||
========================
|
||||
|
||||
|
|
|
@ -24,6 +24,21 @@
|
|||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
/* Registers (Write-only) */
|
||||
#define XREG_INIT 0x00
|
||||
#define XREG_RF_FREQ 0x02
|
||||
#define XREG_POWER_DOWN 0x08
|
||||
|
||||
/* Registers (Read-only) */
|
||||
#define XREG_FREQ_ERROR 0x01
|
||||
#define XREG_LOCK 0x02
|
||||
#define XREG_VERSION 0x04
|
||||
#define XREG_PRODUCT_ID 0x08
|
||||
#define XREG_HSYNC_FREQ 0x10
|
||||
#define XREG_FRAME_LINES 0x20
|
||||
#define XREG_SNR 0x40
|
||||
|
||||
#define XREG_ADC_ENV 0x0100
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
|
@ -885,7 +900,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
|
|||
mutex_lock(&priv->lock);
|
||||
|
||||
/* Sync Lock Indicator */
|
||||
rc = xc2028_get_reg(priv, 0x0002, &frq_lock);
|
||||
rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
|
@ -894,7 +909,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
|
|||
signal = 1 << 11;
|
||||
|
||||
/* Get SNR of the video signal */
|
||||
rc = xc2028_get_reg(priv, 0x0040, &signal);
|
||||
rc = xc2028_get_reg(priv, XREG_SNR, &signal);
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
|
@ -1019,9 +1034,9 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
|
|||
|
||||
/* CMD= Set frequency */
|
||||
if (priv->firm_version < 0x0202)
|
||||
rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00});
|
||||
rc = send_seq(priv, {0x00, XREG_RF_FREQ, 0x00, 0x00});
|
||||
else
|
||||
rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00});
|
||||
rc = send_seq(priv, {0x80, XREG_RF_FREQ, 0x00, 0x00});
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
|
@ -1201,9 +1216,9 @@ static int xc2028_sleep(struct dvb_frontend *fe)
|
|||
mutex_lock(&priv->lock);
|
||||
|
||||
if (priv->firm_version < 0x0202)
|
||||
rc = send_seq(priv, {0x00, 0x08, 0x00, 0x00});
|
||||
rc = send_seq(priv, {0x00, XREG_POWER_DOWN, 0x00, 0x00});
|
||||
else
|
||||
rc = send_seq(priv, {0x80, 0x08, 0x00, 0x00});
|
||||
rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
|
||||
|
||||
priv->cur_fw.type = 0; /* need firmware reload */
|
||||
|
||||
|
|
|
@ -154,6 +154,8 @@ struct xc4000_priv {
|
|||
#define XREG_SNR 0x06
|
||||
#define XREG_VERSION 0x07
|
||||
#define XREG_PRODUCT_ID 0x08
|
||||
#define XREG_SIGNAL_LEVEL 0x0A
|
||||
#define XREG_NOISE_LEVEL 0x0B
|
||||
|
||||
/*
|
||||
Basic firmware description. This will remain with
|
||||
|
@ -486,6 +488,16 @@ static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
|
|||
return xc4000_readreg(priv, XREG_QUALITY, quality);
|
||||
}
|
||||
|
||||
static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal)
|
||||
{
|
||||
return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal);
|
||||
}
|
||||
|
||||
static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise)
|
||||
{
|
||||
return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise);
|
||||
}
|
||||
|
||||
static u16 xc_wait_for_lock(struct xc4000_priv *priv)
|
||||
{
|
||||
u16 lock_state = 0;
|
||||
|
@ -1089,6 +1101,8 @@ static void xc_debug_dump(struct xc4000_priv *priv)
|
|||
u32 hsync_freq_hz = 0;
|
||||
u16 frame_lines;
|
||||
u16 quality;
|
||||
u16 signal = 0;
|
||||
u16 noise = 0;
|
||||
u8 hw_majorversion = 0, hw_minorversion = 0;
|
||||
u8 fw_majorversion = 0, fw_minorversion = 0;
|
||||
|
||||
|
@ -1119,6 +1133,12 @@ static void xc_debug_dump(struct xc4000_priv *priv)
|
|||
|
||||
xc_get_quality(priv, &quality);
|
||||
dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
|
||||
|
||||
xc_get_signal_level(priv, &signal);
|
||||
dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal);
|
||||
|
||||
xc_get_noise_level(priv, &noise);
|
||||
dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise);
|
||||
}
|
||||
|
||||
static int xc4000_set_params(struct dvb_frontend *fe)
|
||||
|
@ -1432,6 +1452,71 @@ fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct xc4000_priv *priv = fe->tuner_priv;
|
||||
u16 value = 0;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
/* Informations from real testing of DVB-T and radio part,
|
||||
coeficient for one dB is 0xff.
|
||||
*/
|
||||
tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value);
|
||||
|
||||
/* all known digital modes */
|
||||
if ((priv->video_standard == XC4000_DTV6) ||
|
||||
(priv->video_standard == XC4000_DTV7) ||
|
||||
(priv->video_standard == XC4000_DTV7_8) ||
|
||||
(priv->video_standard == XC4000_DTV8))
|
||||
goto digital;
|
||||
|
||||
/* Analog mode has NOISE LEVEL important, signal
|
||||
depends only on gain of antenna and amplifiers,
|
||||
but it doesn't tell anything about real quality
|
||||
of reception.
|
||||
*/
|
||||
mutex_lock(&priv->lock);
|
||||
rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value);
|
||||
|
||||
/* highest noise level: 32dB */
|
||||
if (value >= 0x2000) {
|
||||
value = 0;
|
||||
} else {
|
||||
value = ~value << 3;
|
||||
}
|
||||
|
||||
goto ret;
|
||||
|
||||
/* Digital mode has SIGNAL LEVEL important and real
|
||||
noise level is stored in demodulator registers.
|
||||
*/
|
||||
digital:
|
||||
/* best signal: -50dB */
|
||||
if (value <= 0x3200) {
|
||||
value = 0xffff;
|
||||
/* minimum: -114dB - should be 0x7200 but real zero is 0x713A */
|
||||
} else if (value >= 0x713A) {
|
||||
value = 0;
|
||||
} else {
|
||||
value = ~(value - 0x3200) << 2;
|
||||
}
|
||||
|
||||
ret:
|
||||
*strength = value;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
struct xc4000_priv *priv = fe->tuner_priv;
|
||||
|
@ -1559,6 +1644,7 @@ static const struct dvb_tuner_ops xc4000_tuner_ops = {
|
|||
.set_params = xc4000_set_params,
|
||||
.set_analog_params = xc4000_set_analog_params,
|
||||
.get_frequency = xc4000_get_frequency,
|
||||
.get_rf_strength = xc4000_get_signal,
|
||||
.get_bandwidth = xc4000_get_bandwidth,
|
||||
.get_status = xc4000_get_status
|
||||
};
|
||||
|
|
|
@ -904,8 +904,11 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
|||
{
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int i;
|
||||
u32 delsys;
|
||||
|
||||
delsys = c->delivery_system;
|
||||
memset(c, 0, sizeof(struct dtv_frontend_properties));
|
||||
c->delivery_system = delsys;
|
||||
|
||||
c->state = DTV_CLEAR;
|
||||
|
||||
|
@ -1009,25 +1012,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
|
|||
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
|
||||
|
||||
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
|
||||
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
|
||||
|
||||
_DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
|
||||
_DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0),
|
||||
|
||||
|
@ -1413,6 +1397,15 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
|
|||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
enum dvbv3_emulation_type type;
|
||||
|
||||
/*
|
||||
* It was reported that some old DVBv5 applications were
|
||||
* filling delivery_system with SYS_UNDEFINED. If this happens,
|
||||
* assume that the application wants to use the first supported
|
||||
* delivery system.
|
||||
*/
|
||||
if (c->delivery_system == SYS_UNDEFINED)
|
||||
c->delivery_system = fe->ops.delsys[0];
|
||||
|
||||
if (desired_system == SYS_UNDEFINED) {
|
||||
/*
|
||||
* A DVBv3 call doesn't know what's the desired system.
|
||||
|
@ -1732,6 +1725,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
|||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct dvb_frontend *fe = dvbdev->priv;
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int err = 0;
|
||||
|
||||
|
@ -1798,9 +1792,14 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
|||
|
||||
/*
|
||||
* Fills the cache out struct with the cache contents, plus
|
||||
* the data retrieved from get_frontend.
|
||||
* the data retrieved from get_frontend, if the frontend
|
||||
* is not idle. Otherwise, returns the cached content
|
||||
*/
|
||||
dtv_get_frontend(fe, NULL);
|
||||
if (fepriv->state != FESTATE_IDLE) {
|
||||
err = dtv_get_frontend(fe, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
err = dtv_property_process_get(fe, c, tvp + i, file);
|
||||
if (err < 0)
|
||||
|
|
|
@ -877,24 +877,18 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
case ANYSEE_HW_508T2C: /* 20 */
|
||||
/* E7 T2C */
|
||||
|
||||
if (state->fe_id)
|
||||
break;
|
||||
|
||||
/* enable DVB-T/T2/C demod on IOE[5] */
|
||||
ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (state->fe_id == 0) {
|
||||
/* DVB-T/T2 */
|
||||
adap->fe_adap[state->fe_id].fe =
|
||||
dvb_attach(cxd2820r_attach,
|
||||
&anysee_cxd2820r_config,
|
||||
&adap->dev->i2c_adap, NULL);
|
||||
} else {
|
||||
/* DVB-C */
|
||||
adap->fe_adap[state->fe_id].fe =
|
||||
dvb_attach(cxd2820r_attach,
|
||||
&anysee_cxd2820r_config,
|
||||
&adap->dev->i2c_adap, adap->fe_adap[0].fe);
|
||||
}
|
||||
/* attach demod */
|
||||
adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach,
|
||||
&anysee_cxd2820r_config, &adap->dev->i2c_adap,
|
||||
NULL);
|
||||
|
||||
state->has_ci = true;
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ struct dib0700_state {
|
|||
u8 disable_streaming_master_mode;
|
||||
u32 fw_version;
|
||||
u32 nb_packet_buffer_size;
|
||||
int (*read_status)(struct dvb_frontend *, fe_status_t *);
|
||||
int (*sleep)(struct dvb_frontend* fe);
|
||||
u8 buf[255];
|
||||
};
|
||||
|
||||
|
|
|
@ -834,6 +834,7 @@ static struct usb_driver dib0700_driver = {
|
|||
|
||||
module_usb_driver(dib0700_driver);
|
||||
|
||||
MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
|
||||
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
|
||||
MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
|
||||
MODULE_VERSION("1.0");
|
||||
|
|
|
@ -3066,19 +3066,25 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
|
|||
}
|
||||
};
|
||||
|
||||
static void stk7070pd_init(struct dvb_usb_device *dev)
|
||||
{
|
||||
dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0);
|
||||
|
||||
dib0700_ctrl_clock(dev, 72, 1);
|
||||
|
||||
msleep(10);
|
||||
dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1);
|
||||
}
|
||||
|
||||
static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
||||
stk7070pd_init(adap->dev);
|
||||
|
||||
dib0700_ctrl_clock(adap->dev, 72, 1);
|
||||
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
||||
|
||||
|
@ -3099,6 +3105,77 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
|
|||
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
static int novatd_read_status_override(struct dvb_frontend *fe,
|
||||
fe_status_t *stat)
|
||||
{
|
||||
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
||||
struct dvb_usb_device *dev = adap->dev;
|
||||
struct dib0700_state *state = dev->priv;
|
||||
int ret;
|
||||
|
||||
ret = state->read_status(fe, stat);
|
||||
|
||||
if (!ret)
|
||||
dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT,
|
||||
!!(*stat & FE_HAS_LOCK));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int novatd_sleep_override(struct dvb_frontend* fe)
|
||||
{
|
||||
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
||||
struct dvb_usb_device *dev = adap->dev;
|
||||
struct dib0700_state *state = dev->priv;
|
||||
|
||||
/* turn off LED */
|
||||
dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0);
|
||||
|
||||
return state->sleep(fe);
|
||||
}
|
||||
|
||||
/**
|
||||
* novatd_frontend_attach - Nova-TD specific attach
|
||||
*
|
||||
* Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
|
||||
* information purposes.
|
||||
*/
|
||||
static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct dvb_usb_device *dev = adap->dev;
|
||||
struct dib0700_state *st = dev->priv;
|
||||
|
||||
if (adap->id == 0) {
|
||||
stk7070pd_init(dev);
|
||||
|
||||
/* turn the power LED on, the other two off (just in case) */
|
||||
dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0);
|
||||
dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
|
||||
dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
|
||||
|
||||
if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18,
|
||||
stk7070pd_dib7000p_config) != 0) {
|
||||
err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap,
|
||||
adap->id == 0 ? 0x80 : 0x82,
|
||||
&stk7070pd_dib7000p_config[adap->id]);
|
||||
|
||||
if (adap->fe_adap[0].fe == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
st->read_status = adap->fe_adap[0].fe->ops.read_status;
|
||||
adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override;
|
||||
st->sleep = adap->fe_adap[0].fe->ops.sleep;
|
||||
adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* S5H1411 */
|
||||
static struct s5h1411_config pinnacle_801e_config = {
|
||||
.output_mode = S5H1411_PARALLEL_OUTPUT,
|
||||
|
@ -3861,6 +3938,57 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
},
|
||||
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
||||
|
||||
.num_adapters = 2,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = stk70x0p_pid_filter,
|
||||
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
||||
.frontend_attach = novatd_frontend_attach,
|
||||
.tuner_attach = dib7070p_tuner_attach,
|
||||
|
||||
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
||||
}},
|
||||
.size_of_priv = sizeof(struct dib0700_adapter_state),
|
||||
}, {
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = stk70x0p_pid_filter,
|
||||
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
||||
.frontend_attach = novatd_frontend_attach,
|
||||
.tuner_attach = dib7070p_tuner_attach,
|
||||
|
||||
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
||||
}},
|
||||
.size_of_priv = sizeof(struct dib0700_adapter_state),
|
||||
}
|
||||
},
|
||||
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{ "Hauppauge Nova-TD Stick (52009)",
|
||||
{ &dib0700_usb_id_table[35], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
},
|
||||
|
||||
.rc.core = {
|
||||
.rc_interval = DEFAULT_RC_INTERVAL,
|
||||
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
||||
.module_name = "dib0700",
|
||||
.rc_query = dib0700_rc_query_old_firmware,
|
||||
.allowed_protos = RC_TYPE_RC5 |
|
||||
RC_TYPE_RC6 |
|
||||
RC_TYPE_NEC,
|
||||
.change_protocol = dib0700_change_protocol,
|
||||
},
|
||||
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
||||
|
||||
.num_adapters = 2,
|
||||
.adapter = {
|
||||
{
|
||||
|
@ -3892,7 +4020,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
}
|
||||
},
|
||||
|
||||
.num_device_descs = 6,
|
||||
.num_device_descs = 5,
|
||||
.devices = {
|
||||
{ "DiBcom STK7070PD reference design",
|
||||
{ &dib0700_usb_id_table[17], NULL },
|
||||
|
@ -3902,10 +4030,6 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
{ &dib0700_usb_id_table[18], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Hauppauge Nova-TD Stick (52009)",
|
||||
{ &dib0700_usb_id_table[35], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Hauppauge Nova-TD-500 (84xxx)",
|
||||
{ &dib0700_usb_id_table[36], NULL },
|
||||
{ NULL },
|
||||
|
|
|
@ -309,9 +309,14 @@ static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
|||
|
||||
static int cxd2820r_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct cxd2820r_priv *priv = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
|
||||
|
||||
if (priv->delivery_system == SYS_UNDEFINED)
|
||||
return 0;
|
||||
|
||||
switch (fe->dtv_property_cache.delivery_system) {
|
||||
case SYS_DVBT:
|
||||
ret = cxd2820r_get_frontend_t(fe);
|
||||
|
@ -476,10 +481,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
|
|||
dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
|
||||
|
||||
/* switch between DVB-T and DVB-T2 when tune fails */
|
||||
if (priv->last_tune_failed && (priv->delivery_system != SYS_DVBC_ANNEX_A)) {
|
||||
if (priv->last_tune_failed) {
|
||||
if (priv->delivery_system == SYS_DVBT)
|
||||
c->delivery_system = SYS_DVBT2;
|
||||
else
|
||||
else if (priv->delivery_system == SYS_DVBT2)
|
||||
c->delivery_system = SYS_DVBT;
|
||||
}
|
||||
|
||||
|
@ -492,6 +497,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
|
|||
/* frontend lock wait loop count */
|
||||
switch (priv->delivery_system) {
|
||||
case SYS_DVBT:
|
||||
case SYS_DVBC_ANNEX_A:
|
||||
i = 20;
|
||||
break;
|
||||
case SYS_DVBT2:
|
||||
|
|
|
@ -1195,7 +1195,7 @@ static int ds3000_set_frontend(struct dvb_frontend *fe)
|
|||
|
||||
for (i = 0; i < 30 ; i++) {
|
||||
ds3000_read_status(fe, &status);
|
||||
if (status && FE_HAS_LOCK)
|
||||
if (status & FE_HAS_LOCK)
|
||||
break;
|
||||
|
||||
msleep(10);
|
||||
|
|
|
@ -402,7 +402,7 @@ static int mb86a20s_get_modulation(struct mb86a20s_state *state,
|
|||
[2] = 0x8e, /* Layer C */
|
||||
};
|
||||
|
||||
if (layer > ARRAY_SIZE(reg))
|
||||
if (layer >= ARRAY_SIZE(reg))
|
||||
return -EINVAL;
|
||||
rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
|
||||
if (rc < 0)
|
||||
|
@ -435,7 +435,7 @@ static int mb86a20s_get_fec(struct mb86a20s_state *state,
|
|||
[2] = 0x8f, /* Layer C */
|
||||
};
|
||||
|
||||
if (layer > ARRAY_SIZE(reg))
|
||||
if (layer >= ARRAY_SIZE(reg))
|
||||
return -EINVAL;
|
||||
rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
|
||||
if (rc < 0)
|
||||
|
@ -470,7 +470,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
|
|||
[2] = 0x90, /* Layer C */
|
||||
};
|
||||
|
||||
if (layer > ARRAY_SIZE(reg))
|
||||
if (layer >= ARRAY_SIZE(reg))
|
||||
return -EINVAL;
|
||||
rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
|
||||
if (rc < 0)
|
||||
|
@ -494,7 +494,7 @@ static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
|
|||
[2] = 0x91, /* Layer C */
|
||||
};
|
||||
|
||||
if (layer > ARRAY_SIZE(reg))
|
||||
if (layer >= ARRAY_SIZE(reg))
|
||||
return -EINVAL;
|
||||
rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
|
||||
if (rc < 0)
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/version.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <media/as3645a.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
|
|
@ -751,20 +751,10 @@ int cx18_v4l2_close(struct file *filp)
|
|||
|
||||
CX18_DEBUG_IOCTL("close() of %s\n", s->name);
|
||||
|
||||
v4l2_fh_del(fh);
|
||||
v4l2_fh_exit(fh);
|
||||
|
||||
/* Easy case first: this stream was never claimed by us */
|
||||
if (s->id != id->open_id) {
|
||||
kfree(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 'Unclaim' this stream */
|
||||
|
||||
/* Stop radio */
|
||||
mutex_lock(&cx->serialize_lock);
|
||||
if (id->type == CX18_ENC_STREAM_TYPE_RAD) {
|
||||
/* Stop radio */
|
||||
if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
|
||||
v4l2_fh_is_singular_file(filp)) {
|
||||
/* Closing radio device, return to TV mode */
|
||||
cx18_mute(cx);
|
||||
/* Mark that the radio is no longer in use */
|
||||
|
@ -781,10 +771,14 @@ int cx18_v4l2_close(struct file *filp)
|
|||
}
|
||||
/* Done! Unmute and continue. */
|
||||
cx18_unmute(cx);
|
||||
cx18_release_stream(s);
|
||||
} else {
|
||||
cx18_stop_capture(id, 0);
|
||||
}
|
||||
|
||||
v4l2_fh_del(fh);
|
||||
v4l2_fh_exit(fh);
|
||||
|
||||
/* 'Unclaim' this stream */
|
||||
if (s->id == id->open_id)
|
||||
cx18_stop_capture(id, 0);
|
||||
kfree(id);
|
||||
mutex_unlock(&cx->serialize_lock);
|
||||
return 0;
|
||||
|
@ -810,21 +804,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
|
|||
|
||||
item->open_id = cx->open_id++;
|
||||
filp->private_data = &item->fh;
|
||||
v4l2_fh_add(&item->fh);
|
||||
|
||||
if (item->type == CX18_ENC_STREAM_TYPE_RAD) {
|
||||
/* Try to claim this stream */
|
||||
if (cx18_claim_stream(item, item->type)) {
|
||||
/* No, it's already in use */
|
||||
v4l2_fh_exit(&item->fh);
|
||||
kfree(item);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
|
||||
v4l2_fh_is_singular_file(filp)) {
|
||||
if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
|
||||
if (atomic_read(&cx->ana_capturing) > 0) {
|
||||
/* switching to radio while capture is
|
||||
in progress is not polite */
|
||||
cx18_release_stream(s);
|
||||
v4l2_fh_del(&item->fh);
|
||||
v4l2_fh_exit(&item->fh);
|
||||
kfree(item);
|
||||
return -EBUSY;
|
||||
|
@ -842,7 +830,6 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
|
|||
/* Done! Unmute and continue. */
|
||||
cx18_unmute(cx);
|
||||
}
|
||||
v4l2_fh_add(&item->fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1052,7 +1052,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
|
|||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (dev == NULL) {
|
||||
cx231xx_err(DRIVER_NAME ": out of memory!\n");
|
||||
clear_bit(dev->devno, &cx231xx_devused);
|
||||
clear_bit(nr, &cx231xx_devused);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
@ -213,8 +213,8 @@ struct cx23885_board cx23885_boards[] = {
|
|||
.portc = CX23885_MPEG_DVB,
|
||||
.tuner_type = TUNER_XC4000,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_type = TUNER_XC4000,
|
||||
.radio_addr = 0x61,
|
||||
.radio_type = UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.input = {{
|
||||
.type = CX23885_VMUX_TELEVISION,
|
||||
.vmux = CX25840_VIN2_CH1 |
|
||||
|
|
|
@ -943,6 +943,11 @@ static int dvb_register(struct cx23885_tsport *port)
|
|||
|
||||
fe = dvb_attach(xc4000_attach, fe0->dvb.frontend,
|
||||
&dev->i2c_bus[1].i2c_adap, &cfg);
|
||||
if (!fe) {
|
||||
printk(KERN_ERR "%s/2: xc4000 attach failed\n",
|
||||
dev->name);
|
||||
goto frontend_detach;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CX23885_BOARD_TBS_6920:
|
||||
|
|
|
@ -1550,7 +1550,6 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
|
|||
struct v4l2_control ctrl;
|
||||
struct videobuf_dvb_frontend *vfe;
|
||||
struct dvb_frontend *fe;
|
||||
int err = 0;
|
||||
|
||||
struct analog_parameters params = {
|
||||
.mode = V4L2_TUNER_ANALOG_TV,
|
||||
|
@ -1572,8 +1571,10 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
|
|||
params.frequency, f->tuner, params.std);
|
||||
|
||||
vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
|
||||
if (!vfe)
|
||||
err = -EINVAL;
|
||||
if (!vfe) {
|
||||
mutex_unlock(&dev->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fe = vfe->dvb.frontend;
|
||||
|
||||
|
|
|
@ -1573,8 +1573,8 @@ static const struct cx88_board cx88_boards[] = {
|
|||
.name = "Pinnacle Hybrid PCTV",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_type = TUNER_XC2028,
|
||||
.radio_addr = 0x61,
|
||||
.radio_type = UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.input = { {
|
||||
.type = CX88_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
|
@ -1611,8 +1611,8 @@ static const struct cx88_board cx88_boards[] = {
|
|||
.name = "Leadtek TV2000 XP Global",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_type = TUNER_XC2028,
|
||||
.radio_addr = 0x61,
|
||||
.radio_type = UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.input = { {
|
||||
.type = CX88_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
|
@ -2115,8 +2115,8 @@ static const struct cx88_board cx88_boards[] = {
|
|||
.name = "Terratec Cinergy HT PCI MKII",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_type = TUNER_XC2028,
|
||||
.radio_addr = 0x61,
|
||||
.radio_type = UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.input = { {
|
||||
.type = CX88_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
|
@ -2154,9 +2154,9 @@ static const struct cx88_board cx88_boards[] = {
|
|||
[CX88_BOARD_WINFAST_DTV1800H] = {
|
||||
.name = "Leadtek WinFast DTV1800 Hybrid",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.radio_type = TUNER_XC2028,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_addr = 0x61,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
/*
|
||||
* GPIO setting
|
||||
*
|
||||
|
@ -2195,9 +2195,9 @@ static const struct cx88_board cx88_boards[] = {
|
|||
[CX88_BOARD_WINFAST_DTV1800H_XC4000] = {
|
||||
.name = "Leadtek WinFast DTV1800 H (XC4000)",
|
||||
.tuner_type = TUNER_XC4000,
|
||||
.radio_type = TUNER_XC4000,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_addr = 0x61,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
/*
|
||||
* GPIO setting
|
||||
*
|
||||
|
@ -2236,9 +2236,9 @@ static const struct cx88_board cx88_boards[] = {
|
|||
[CX88_BOARD_WINFAST_DTV2000H_PLUS] = {
|
||||
.name = "Leadtek WinFast DTV2000 H PLUS",
|
||||
.tuner_type = TUNER_XC4000,
|
||||
.radio_type = TUNER_XC4000,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_addr = 0x61,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
/*
|
||||
* GPIO
|
||||
* 2: 1: mute audio
|
||||
|
|
|
@ -731,9 +731,6 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
|
|||
|
||||
init_kthread_work(&itv->irq_work, ivtv_irq_work_handler);
|
||||
|
||||
/* start counting open_id at 1 */
|
||||
itv->open_id = 1;
|
||||
|
||||
/* Initial settings */
|
||||
itv->cxhdl.port = CX2341X_PORT_MEMORY;
|
||||
itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
|
||||
|
|
|
@ -332,7 +332,7 @@ struct ivtv_stream {
|
|||
const char *name; /* name of the stream */
|
||||
int type; /* stream type */
|
||||
|
||||
u32 id;
|
||||
struct v4l2_fh *fh; /* pointer to the streaming filehandle */
|
||||
spinlock_t qlock; /* locks access to the queues */
|
||||
unsigned long s_flags; /* status flags, see above */
|
||||
int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
|
||||
|
@ -379,7 +379,6 @@ struct ivtv_stream {
|
|||
|
||||
struct ivtv_open_id {
|
||||
struct v4l2_fh fh;
|
||||
u32 open_id; /* unique ID for this file descriptor */
|
||||
int type; /* stream type */
|
||||
int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
|
||||
struct ivtv *itv;
|
||||
|
|
|
@ -50,16 +50,16 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
|
|||
|
||||
if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
|
||||
/* someone already claimed this stream */
|
||||
if (s->id == id->open_id) {
|
||||
if (s->fh == &id->fh) {
|
||||
/* yes, this file descriptor did. So that's OK. */
|
||||
return 0;
|
||||
}
|
||||
if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI ||
|
||||
if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
|
||||
type == IVTV_ENC_STREAM_TYPE_VBI)) {
|
||||
/* VBI is handled already internally, now also assign
|
||||
the file descriptor to this stream for external
|
||||
reading of the stream. */
|
||||
s->id = id->open_id;
|
||||
s->fh = &id->fh;
|
||||
IVTV_DEBUG_INFO("Start Read VBI\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
|
|||
IVTV_DEBUG_INFO("Stream %d is busy\n", type);
|
||||
return -EBUSY;
|
||||
}
|
||||
s->id = id->open_id;
|
||||
s->fh = &id->fh;
|
||||
if (type == IVTV_DEC_STREAM_TYPE_VBI) {
|
||||
/* Enable reinsertion interrupt */
|
||||
ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
|
||||
|
@ -104,7 +104,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
|
|||
struct ivtv *itv = s->itv;
|
||||
struct ivtv_stream *s_vbi;
|
||||
|
||||
s->id = -1;
|
||||
s->fh = NULL;
|
||||
if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
|
||||
test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
|
||||
/* this stream is still in use internally */
|
||||
|
@ -136,7 +136,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
|
|||
/* was already cleared */
|
||||
return;
|
||||
}
|
||||
if (s_vbi->id != -1) {
|
||||
if (s_vbi->fh) {
|
||||
/* VBI stream still claimed by a file descriptor */
|
||||
return;
|
||||
}
|
||||
|
@ -268,11 +268,13 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
|
|||
}
|
||||
|
||||
/* wait for more data to arrive */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
/* New buffers might have become available before we were added to the waitqueue */
|
||||
if (!s->q_full.buffers)
|
||||
schedule();
|
||||
finish_wait(&s->waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (signal_pending(current)) {
|
||||
/* return if a signal was received */
|
||||
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
|
|||
size_t tot_written = 0;
|
||||
int single_frame = 0;
|
||||
|
||||
if (atomic_read(&itv->capturing) == 0 && s->id == -1) {
|
||||
if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
|
||||
/* shouldn't happen */
|
||||
IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
|
||||
return -EIO;
|
||||
|
@ -507,9 +509,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_
|
|||
|
||||
IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
rc = ivtv_start_capture(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
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
|
|||
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
|
||||
|
||||
/* Start decoder (returns 0 if already started) */
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
rc = ivtv_start_decoding(id, itv->speed);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
if (rc) {
|
||||
IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
|
||||
|
||||
|
@ -627,11 +625,13 @@ retry:
|
|||
break;
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
/* New buffers might have become free before we were added to the waitqueue */
|
||||
if (!s->q_free.buffers)
|
||||
schedule();
|
||||
finish_wait(&s->waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (signal_pending(current)) {
|
||||
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
|
||||
return -EINTR;
|
||||
|
@ -686,12 +686,14 @@ retry:
|
|||
if (mode == OUT_YUV)
|
||||
ivtv_yuv_setup_stream_frame(itv);
|
||||
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
while (!(got_sig = signal_pending(current)) &&
|
||||
test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
|
||||
schedule();
|
||||
}
|
||||
finish_wait(&itv->dma_waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (got_sig) {
|
||||
IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
|
||||
return -EINTR;
|
||||
|
@ -756,9 +758,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
|
|||
if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
|
||||
int rc;
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
rc = ivtv_start_capture(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
if (rc) {
|
||||
IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
|
||||
s->name, rc);
|
||||
|
@ -808,7 +808,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
|
|||
id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
|
||||
test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
|
||||
/* Also used internally, don't stop capturing */
|
||||
s->id = -1;
|
||||
s->fh = NULL;
|
||||
}
|
||||
else {
|
||||
ivtv_stop_v4l2_encode_stream(s, gop_end);
|
||||
|
@ -861,20 +861,9 @@ int ivtv_v4l2_close(struct file *filp)
|
|||
|
||||
IVTV_DEBUG_FILE("close %s\n", s->name);
|
||||
|
||||
v4l2_fh_del(fh);
|
||||
v4l2_fh_exit(fh);
|
||||
|
||||
/* Easy case first: this stream was never claimed by us */
|
||||
if (s->id != id->open_id) {
|
||||
kfree(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 'Unclaim' this stream */
|
||||
|
||||
/* Stop radio */
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (id->type == IVTV_ENC_STREAM_TYPE_RAD) {
|
||||
if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
|
||||
v4l2_fh_is_singular_file(filp)) {
|
||||
/* Closing radio device, return to TV mode */
|
||||
ivtv_mute(itv);
|
||||
/* Mark that the radio is no longer in use */
|
||||
|
@ -890,13 +879,25 @@ int ivtv_v4l2_close(struct file *filp)
|
|||
if (atomic_read(&itv->capturing) > 0) {
|
||||
/* Undo video mute */
|
||||
ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
|
||||
v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
|
||||
(v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
|
||||
v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
|
||||
(v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
|
||||
}
|
||||
/* Done! Unmute and continue. */
|
||||
ivtv_unmute(itv);
|
||||
ivtv_release_stream(s);
|
||||
} else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
|
||||
}
|
||||
|
||||
v4l2_fh_del(fh);
|
||||
v4l2_fh_exit(fh);
|
||||
|
||||
/* Easy case first: this stream was never claimed by us */
|
||||
if (s->fh != &id->fh) {
|
||||
kfree(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 'Unclaim' this stream */
|
||||
|
||||
if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
|
||||
struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
|
||||
|
||||
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)
|
|||
ivtv_stop_capture(id, 0);
|
||||
}
|
||||
kfree(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
||||
int ivtv_v4l2_open(struct file *filp)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
struct video_device *vdev = video_devdata(filp);
|
||||
#endif
|
||||
struct ivtv_stream *s = video_get_drvdata(vdev);
|
||||
struct ivtv *itv = s->itv;
|
||||
struct ivtv_open_id *item;
|
||||
int res = 0;
|
||||
|
||||
IVTV_DEBUG_FILE("open %s\n", s->name);
|
||||
|
||||
if (ivtv_init_on_first_open(itv)) {
|
||||
IVTV_ERR("Failed to initialize on device %s\n",
|
||||
video_device_node_name(vdev));
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
/* Unless ivtv_fw_debug is set, error out if firmware dead. */
|
||||
if (ivtv_fw_debug) {
|
||||
|
@ -966,31 +971,19 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|||
return -ENOMEM;
|
||||
}
|
||||
v4l2_fh_init(&item->fh, s->vdev);
|
||||
if (res < 0) {
|
||||
v4l2_fh_exit(&item->fh);
|
||||
kfree(item);
|
||||
return res;
|
||||
}
|
||||
item->itv = itv;
|
||||
item->type = s->type;
|
||||
|
||||
item->open_id = itv->open_id++;
|
||||
filp->private_data = &item->fh;
|
||||
v4l2_fh_add(&item->fh);
|
||||
|
||||
if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {
|
||||
/* Try to claim this stream */
|
||||
if (ivtv_claim_stream(item, item->type)) {
|
||||
/* No, it's already in use */
|
||||
v4l2_fh_exit(&item->fh);
|
||||
kfree(item);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
|
||||
v4l2_fh_is_singular_file(filp)) {
|
||||
if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
|
||||
if (atomic_read(&itv->capturing) > 0) {
|
||||
/* switching to radio while capture is
|
||||
in progress is not polite */
|
||||
ivtv_release_stream(s);
|
||||
v4l2_fh_del(&item->fh);
|
||||
v4l2_fh_exit(&item->fh);
|
||||
kfree(item);
|
||||
return -EBUSY;
|
||||
|
@ -1022,32 +1015,9 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|||
1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
|
||||
itv->yuv_info.stream_size = 0;
|
||||
}
|
||||
v4l2_fh_add(&item->fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ivtv_v4l2_open(struct file *filp)
|
||||
{
|
||||
int res;
|
||||
struct ivtv *itv = NULL;
|
||||
struct ivtv_stream *s = NULL;
|
||||
struct video_device *vdev = video_devdata(filp);
|
||||
|
||||
s = video_get_drvdata(vdev);
|
||||
itv = s->itv;
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (ivtv_init_on_first_open(itv)) {
|
||||
IVTV_ERR("Failed to initialize on device %s\n",
|
||||
video_device_node_name(vdev));
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
res = ivtv_serialized_open(s, filp);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ivtv_mute(struct ivtv *itv)
|
||||
{
|
||||
if (atomic_read(&itv->capturing))
|
||||
|
|
|
@ -179,6 +179,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
|
|||
ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
|
||||
|
||||
/* Wait for any DMA to finish */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
|
||||
got_sig = signal_pending(current);
|
||||
|
@ -188,6 +189,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
|
|||
schedule();
|
||||
}
|
||||
finish_wait(&itv->dma_waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (got_sig)
|
||||
return -EINTR;
|
||||
|
||||
|
@ -1107,6 +1109,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
|
|||
* happens within the first 100 lines of the top field.
|
||||
* Make 4 attempts to sync to the decoder before giving up.
|
||||
*/
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
for (f = 0; f < 4; f++) {
|
||||
prepare_to_wait(&itv->vsync_waitq, &wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
|
@ -1115,6 +1118,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
|
|||
schedule_timeout(msecs_to_jiffies(25));
|
||||
}
|
||||
finish_wait(&itv->vsync_waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
|
||||
if (f == 4)
|
||||
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,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(filp);
|
||||
long ret;
|
||||
|
@ -1855,21 +1858,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct ivtv_open_id *id = fh2id(filp->private_data);
|
||||
struct ivtv *itv = id->itv;
|
||||
long res;
|
||||
|
||||
/* DQEVENT can block, so this should not run with the serialize lock */
|
||||
if (cmd == VIDIOC_DQEVENT)
|
||||
return ivtv_serialized_ioctl(itv, filp, cmd, arg);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
|
||||
.vidioc_querycap = ivtv_querycap,
|
||||
.vidioc_s_audio = ivtv_s_audio,
|
||||
|
|
|
@ -288,13 +288,13 @@ static void dma_post(struct ivtv_stream *s)
|
|||
ivtv_process_vbi_data(itv, buf, 0, s->type);
|
||||
s->q_dma.bytesused += buf->bytesused;
|
||||
}
|
||||
if (s->id == -1) {
|
||||
if (s->fh == NULL) {
|
||||
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);
|
||||
if (s->id != -1)
|
||||
if (s->fh)
|
||||
wake_up(&s->waitq);
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,6 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
|
|||
s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size;
|
||||
spin_lock_init(&s->qlock);
|
||||
init_waitqueue_head(&s->waitq);
|
||||
s->id = -1;
|
||||
s->sg_handle = IVTV_DMA_UNMAPPED;
|
||||
ivtv_queue_init(&s->q_free);
|
||||
ivtv_queue_init(&s->q_full);
|
||||
|
@ -214,6 +213,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
|
|||
s->vdev->fops = ivtv_stream_info[type].fops;
|
||||
s->vdev->release = video_device_release;
|
||||
s->vdev->tvnorms = V4L2_STD_ALL;
|
||||
s->vdev->lock = &itv->serialize_lock;
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
|
||||
ivtv_set_funcs(s->vdev);
|
||||
return 0;
|
||||
|
|
|
@ -1149,23 +1149,37 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
|
|||
{
|
||||
struct yuv_playback_info *yi = &itv->yuv_info;
|
||||
struct ivtv_dma_frame dma_args;
|
||||
int res;
|
||||
|
||||
ivtv_yuv_setup_stream_frame(itv);
|
||||
|
||||
/* We only need to supply source addresses for this */
|
||||
dma_args.y_source = src;
|
||||
dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
|
||||
return ivtv_yuv_udma_frame(itv, &dma_args);
|
||||
/* Wait for frame DMA. Note that serialize_lock is locked,
|
||||
so to allow other processes to access the driver while
|
||||
we are waiting unlock first and later lock again. */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
res = ivtv_yuv_udma_frame(itv, &dma_args);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* IVTV_IOC_DMA_FRAME ioctl handler */
|
||||
int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
|
||||
{
|
||||
/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
|
||||
int res;
|
||||
|
||||
/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
|
||||
ivtv_yuv_next_free(itv);
|
||||
ivtv_yuv_setup_frame(itv, args);
|
||||
return ivtv_yuv_udma_frame(itv, args);
|
||||
/* Wait for frame DMA. Note that serialize_lock is locked,
|
||||
so to allow other processes to access the driver while
|
||||
we are waiting unlock first and later lock again. */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
res = ivtv_yuv_udma_frame(itv, args);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ivtv_yuv_close(struct ivtv *itv)
|
||||
|
@ -1174,7 +1188,9 @@ void ivtv_yuv_close(struct ivtv *itv)
|
|||
int h_filter, v_filter_1, v_filter_2;
|
||||
|
||||
IVTV_DEBUG_YUV("ivtv_yuv_close\n");
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
ivtv_waitq(&itv->vsync_waitq);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
|
||||
yi->running = 0;
|
||||
atomic_set(&yi->next_dma_frame, -1);
|
||||
|
|
|
@ -1042,7 +1042,8 @@ static int vidioc_querycap(struct file *file, void *fh,
|
|||
strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
|
||||
strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
|
||||
cap->bus_info[0] = '\0';
|
||||
cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
|
||||
cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
|
||||
V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1825,7 +1826,9 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
|
|||
ovid = &vout->vid_info;
|
||||
ovl = ovid->overlays[0];
|
||||
|
||||
a->flags = 0x0;
|
||||
/* The video overlay must stay within the framebuffer and can't be
|
||||
positioned independently. */
|
||||
a->flags = V4L2_FBUF_FLAG_OVERLAY;
|
||||
a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
|
||||
| V4L2_FBUF_CAP_SRC_CHROMAKEY;
|
||||
|
||||
|
|
|
@ -104,47 +104,16 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
static int _send_control_msg(struct pwc_device *pdev,
|
||||
u8 request, u16 value, int index, void *buf, int buflen)
|
||||
{
|
||||
int rc;
|
||||
void *kbuf = NULL;
|
||||
|
||||
if (buflen) {
|
||||
kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */
|
||||
if (kbuf == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
|
||||
request,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value,
|
||||
index,
|
||||
kbuf, buflen, USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
kfree(kbuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int recv_control_msg(struct pwc_device *pdev,
|
||||
u8 request, u16 value, void *buf, int buflen)
|
||||
u8 request, u16 value, int recv_count)
|
||||
{
|
||||
int rc;
|
||||
void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
|
||||
|
||||
if (kbuf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
|
||||
request,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value,
|
||||
pdev->vcinterface,
|
||||
kbuf, buflen, USB_CTRL_GET_TIMEOUT);
|
||||
memcpy(buf, kbuf, buflen);
|
||||
kfree(kbuf);
|
||||
|
||||
value, pdev->vcinterface,
|
||||
pdev->ctrl_buf, recv_count, USB_CTRL_GET_TIMEOUT);
|
||||
if (rc < 0)
|
||||
PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
|
||||
rc, request, value);
|
||||
|
@ -152,27 +121,39 @@ static int recv_control_msg(struct pwc_device *pdev,
|
|||
}
|
||||
|
||||
static inline int send_video_command(struct pwc_device *pdev,
|
||||
int index, void *buf, int buflen)
|
||||
int index, const unsigned char *buf, int buflen)
|
||||
{
|
||||
return _send_control_msg(pdev,
|
||||
SET_EP_STREAM_CTL,
|
||||
VIDEO_OUTPUT_CONTROL_FORMATTER,
|
||||
index,
|
||||
buf, buflen);
|
||||
int rc;
|
||||
|
||||
memcpy(pdev->ctrl_buf, buf, buflen);
|
||||
|
||||
rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
|
||||
SET_EP_STREAM_CTL,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
VIDEO_OUTPUT_CONTROL_FORMATTER, index,
|
||||
pdev->ctrl_buf, buflen, USB_CTRL_SET_TIMEOUT);
|
||||
if (rc >= 0)
|
||||
memcpy(pdev->cmd_buf, buf, buflen);
|
||||
else
|
||||
PWC_ERROR("send_video_command error %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int send_control_msg(struct pwc_device *pdev,
|
||||
u8 request, u16 value, void *buf, int buflen)
|
||||
{
|
||||
return _send_control_msg(pdev,
|
||||
request, value, pdev->vcinterface, buf, buflen);
|
||||
return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
|
||||
request,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
value, pdev->vcinterface,
|
||||
buf, buflen, USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
|
||||
static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames,
|
||||
int *compression)
|
||||
static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
|
||||
int frames, int *compression, int send_to_cam)
|
||||
{
|
||||
unsigned char buf[3];
|
||||
int ret, fps;
|
||||
int fps, ret = 0;
|
||||
struct Nala_table_entry *pEntry;
|
||||
int frames2frames[31] =
|
||||
{ /* closest match of framerate */
|
||||
|
@ -194,30 +175,29 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames,
|
|||
7 /* 30 */
|
||||
};
|
||||
|
||||
if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
|
||||
if (size < 0 || size > PSZ_CIF)
|
||||
return -EINVAL;
|
||||
if (frames < 4)
|
||||
frames = 4;
|
||||
else if (frames > 25)
|
||||
frames = 25;
|
||||
frames = frames2frames[frames];
|
||||
fps = frames2table[frames];
|
||||
pEntry = &Nala_table[size][fps];
|
||||
if (pEntry->alternate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buf, pEntry->mode, 3);
|
||||
ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
|
||||
if (ret < 0) {
|
||||
PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
|
||||
if (send_to_cam)
|
||||
ret = send_video_command(pdev, pdev->vendpoint,
|
||||
pEntry->mode, 3);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
|
||||
ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdev->cmd_len = 3;
|
||||
memcpy(pdev->cmd_buf, buf, 3);
|
||||
if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420)
|
||||
pwc_dec1_init(pdev, pEntry->mode);
|
||||
|
||||
/* Set various parameters */
|
||||
pdev->pixfmt = pixfmt;
|
||||
pdev->vframes = frames;
|
||||
pdev->valternate = pEntry->alternate;
|
||||
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,
|
|||
}
|
||||
|
||||
|
||||
static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
|
||||
int *compression)
|
||||
static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt,
|
||||
int frames, int *compression, int send_to_cam)
|
||||
{
|
||||
unsigned char buf[13];
|
||||
const struct Timon_table_entry *pChoose;
|
||||
int ret, fps;
|
||||
int fps, ret = 0;
|
||||
|
||||
if (size >= PSZ_MAX || frames < 5 || frames > 30 ||
|
||||
*compression < 0 || *compression > 3)
|
||||
return -EINVAL;
|
||||
if (size == PSZ_VGA && frames > 15)
|
||||
if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
|
||||
return -EINVAL;
|
||||
if (frames < 5)
|
||||
frames = 5;
|
||||
else if (size == PSZ_VGA && frames > 15)
|
||||
frames = 15;
|
||||
else if (frames > 30)
|
||||
frames = 30;
|
||||
fps = (frames / 5) - 1;
|
||||
|
||||
/* 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,
|
|||
if (pChoose == NULL || pChoose->alternate == 0)
|
||||
return -ENOENT; /* Not supported. */
|
||||
|
||||
memcpy(buf, pChoose->mode, 13);
|
||||
ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
|
||||
if (send_to_cam)
|
||||
ret = send_video_command(pdev, pdev->vendpoint,
|
||||
pChoose->mode, 13);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
|
||||
ret = pwc_dec23_init(pdev, pdev->type, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdev->cmd_len = 13;
|
||||
memcpy(pdev->cmd_buf, buf, 13);
|
||||
if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
|
||||
pwc_dec23_init(pdev, pChoose->mode);
|
||||
|
||||
/* Set various parameters */
|
||||
pdev->vframes = frames;
|
||||
pdev->pixfmt = pixfmt;
|
||||
pdev->vframes = (fps + 1) * 5;
|
||||
pdev->valternate = pChoose->alternate;
|
||||
pdev->width = pwc_image_sizes[size][0];
|
||||
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,
|
|||
}
|
||||
|
||||
|
||||
static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
|
||||
int *compression)
|
||||
static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt,
|
||||
int frames, int *compression, int send_to_cam)
|
||||
{
|
||||
const struct Kiara_table_entry *pChoose = NULL;
|
||||
int fps, ret;
|
||||
unsigned char buf[12];
|
||||
int fps, ret = 0;
|
||||
|
||||
if (size >= PSZ_MAX || frames < 5 || frames > 30 ||
|
||||
*compression < 0 || *compression > 3)
|
||||
return -EINVAL;
|
||||
if (size == PSZ_VGA && frames > 15)
|
||||
if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
|
||||
return -EINVAL;
|
||||
if (frames < 5)
|
||||
frames = 5;
|
||||
else if (size == PSZ_VGA && frames > 15)
|
||||
frames = 15;
|
||||
else if (frames > 30)
|
||||
frames = 30;
|
||||
fps = (frames / 5) - 1;
|
||||
|
||||
/* 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,
|
|||
if (pChoose == NULL || pChoose->alternate == 0)
|
||||
return -ENOENT; /* Not supported. */
|
||||
|
||||
PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
|
||||
|
||||
/* usb_control_msg won't take staticly allocated arrays as argument?? */
|
||||
memcpy(buf, pChoose->mode, 12);
|
||||
|
||||
/* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
|
||||
ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
|
||||
if (send_to_cam)
|
||||
ret = send_video_command(pdev, 4, pChoose->mode, 12);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
|
||||
ret = pwc_dec23_init(pdev, pdev->type, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
|
||||
pwc_dec23_init(pdev, pChoose->mode);
|
||||
|
||||
pdev->cmd_len = 12;
|
||||
memcpy(pdev->cmd_buf, buf, 12);
|
||||
/* All set and go */
|
||||
pdev->vframes = frames;
|
||||
pdev->pixfmt = pixfmt;
|
||||
pdev->vframes = (fps + 1) * 5;
|
||||
pdev->valternate = pChoose->alternate;
|
||||
pdev->width = pwc_image_sizes[size][0];
|
||||
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,
|
|||
}
|
||||
|
||||
int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
|
||||
int frames, int *compression)
|
||||
int pixfmt, int frames, int *compression, int send_to_cam)
|
||||
{
|
||||
int ret, size;
|
||||
|
||||
PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt);
|
||||
PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n",
|
||||
width, height, frames, pixfmt);
|
||||
size = pwc_get_size(pdev, width, height);
|
||||
PWC_TRACE("decode_size = %d.\n", size);
|
||||
|
||||
if (DEVICE_USE_CODEC1(pdev->type)) {
|
||||
ret = set_video_mode_Nala(pdev, size, frames, compression);
|
||||
|
||||
ret = set_video_mode_Nala(pdev, size, pixfmt, frames,
|
||||
compression, send_to_cam);
|
||||
} else if (DEVICE_USE_CODEC3(pdev->type)) {
|
||||
ret = set_video_mode_Kiara(pdev, size, frames, compression);
|
||||
|
||||
ret = set_video_mode_Kiara(pdev, size, pixfmt, frames,
|
||||
compression, send_to_cam);
|
||||
} else {
|
||||
ret = set_video_mode_Timon(pdev, size, frames, compression);
|
||||
ret = set_video_mode_Timon(pdev, size, pixfmt, frames,
|
||||
compression, send_to_cam);
|
||||
}
|
||||
if (ret < 0) {
|
||||
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
|
|||
int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
|
||||
{
|
||||
int ret;
|
||||
u8 buf;
|
||||
|
||||
ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
|
||||
ret = recv_control_msg(pdev, request, value, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*data = buf;
|
||||
*data = pdev->ctrl_buf[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -450,7 +423,8 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = send_control_msg(pdev, request, value, &data, sizeof(data));
|
||||
pdev->ctrl_buf[0] = data;
|
||||
ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -460,37 +434,34 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
|
|||
int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
|
||||
{
|
||||
int ret;
|
||||
s8 buf;
|
||||
|
||||
ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
|
||||
ret = recv_control_msg(pdev, request, value, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*data = buf;
|
||||
*data = ((s8 *)pdev->ctrl_buf)[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
|
||||
ret = recv_control_msg(pdev, request, value, buf, sizeof(buf));
|
||||
ret = recv_control_msg(pdev, request, value, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*data = (buf[1] << 8) | buf[0];
|
||||
*data = (pdev->ctrl_buf[1] << 8) | pdev->ctrl_buf[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
|
||||
buf[0] = data & 0xff;
|
||||
buf[1] = data >> 8;
|
||||
ret = send_control_msg(pdev, request, value, buf, sizeof(buf));
|
||||
pdev->ctrl_buf[0] = data & 0xff;
|
||||
pdev->ctrl_buf[1] = data >> 8;
|
||||
ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -511,7 +482,6 @@ int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
|
|||
/* POWER */
|
||||
void pwc_camera_power(struct pwc_device *pdev, int power)
|
||||
{
|
||||
char buf;
|
||||
int r;
|
||||
|
||||
if (!pdev->power_save)
|
||||
|
@ -521,13 +491,11 @@ void pwc_camera_power(struct pwc_device *pdev, int power)
|
|||
return; /* Not supported by Nala or Timon < release 6 */
|
||||
|
||||
if (power)
|
||||
buf = 0x00; /* active */
|
||||
pdev->ctrl_buf[0] = 0x00; /* active */
|
||||
else
|
||||
buf = 0xFF; /* power save */
|
||||
r = send_control_msg(pdev,
|
||||
SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
|
||||
&buf, sizeof(buf));
|
||||
|
||||
pdev->ctrl_buf[0] = 0xFF; /* power save */
|
||||
r = send_control_msg(pdev, SET_STATUS_CTL,
|
||||
SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1);
|
||||
if (r < 0)
|
||||
PWC_ERROR("Failed to power %s camera (%d)\n",
|
||||
power ? "on" : "off", r);
|
||||
|
@ -535,7 +503,6 @@ void pwc_camera_power(struct pwc_device *pdev, int power)
|
|||
|
||||
int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
int r;
|
||||
|
||||
if (pdev->type < 730)
|
||||
|
@ -551,11 +518,11 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
|
|||
if (off_value > 0xff)
|
||||
off_value = 0xff;
|
||||
|
||||
buf[0] = on_value;
|
||||
buf[1] = off_value;
|
||||
pdev->ctrl_buf[0] = on_value;
|
||||
pdev->ctrl_buf[1] = off_value;
|
||||
|
||||
r = send_control_msg(pdev,
|
||||
SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
|
||||
SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2);
|
||||
if (r < 0)
|
||||
PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
|
||||
|
||||
|
@ -565,7 +532,6 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
|
|||
#ifdef CONFIG_USB_PWC_DEBUG
|
||||
int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret = -1, request;
|
||||
|
||||
if (pdev->type < 675)
|
||||
|
@ -575,14 +541,13 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
|
|||
else
|
||||
request = SENSOR_TYPE_FORMATTER2;
|
||||
|
||||
ret = recv_control_msg(pdev,
|
||||
GET_STATUS_CTL, request, &buf, sizeof(buf));
|
||||
ret = recv_control_msg(pdev, GET_STATUS_CTL, request, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (pdev->type < 675)
|
||||
*sensor = buf | 0x100;
|
||||
*sensor = pdev->ctrl_buf[0] | 0x100;
|
||||
else
|
||||
*sensor = buf;
|
||||
*sensor = pdev->ctrl_buf[0];
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,19 +22,11 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "pwc-dec1.h"
|
||||
#include "pwc.h"
|
||||
|
||||
int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer)
|
||||
void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd)
|
||||
{
|
||||
struct pwc_dec1_private *pdec;
|
||||
struct pwc_dec1_private *pdec = &pdev->dec1;
|
||||
|
||||
if (pwc->decompress_data == NULL) {
|
||||
pdec = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
|
||||
if (pdec == NULL)
|
||||
return -ENOMEM;
|
||||
pwc->decompress_data = pdec;
|
||||
}
|
||||
pdec = pwc->decompress_data;
|
||||
|
||||
return 0;
|
||||
pdec->version = pdev->release;
|
||||
}
|
||||
|
|
|
@ -25,13 +25,15 @@
|
|||
#ifndef PWC_DEC1_H
|
||||
#define PWC_DEC1_H
|
||||
|
||||
#include "pwc.h"
|
||||
#include <linux/mutex.h>
|
||||
|
||||
struct pwc_device;
|
||||
|
||||
struct pwc_dec1_private
|
||||
{
|
||||
int version;
|
||||
};
|
||||
|
||||
int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer);
|
||||
void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -294,22 +294,17 @@ static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
|
|||
|
||||
|
||||
/* If the type or the command change, we rebuild the lookup table */
|
||||
int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
|
||||
void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd)
|
||||
{
|
||||
int flags, version, shift, i;
|
||||
struct pwc_dec23_private *pdec;
|
||||
|
||||
if (pwc->decompress_data == NULL) {
|
||||
pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
|
||||
if (pdec == NULL)
|
||||
return -ENOMEM;
|
||||
pwc->decompress_data = pdec;
|
||||
}
|
||||
pdec = pwc->decompress_data;
|
||||
struct pwc_dec23_private *pdec = &pdev->dec23;
|
||||
|
||||
mutex_init(&pdec->lock);
|
||||
|
||||
if (DEVICE_USE_CODEC3(type)) {
|
||||
if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2])
|
||||
return;
|
||||
|
||||
if (DEVICE_USE_CODEC3(pdev->type)) {
|
||||
flags = cmd[2] & 0x18;
|
||||
if (flags == 8)
|
||||
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)
|
|||
pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
pdec->last_cmd = cmd[2];
|
||||
pdec->last_cmd_valid = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -659,12 +655,12 @@ static void DecompressBand23(struct pwc_dec23_private *pdec,
|
|||
* src: raw data
|
||||
* dst: image output
|
||||
*/
|
||||
void pwc_dec23_decompress(const struct pwc_device *pwc,
|
||||
void pwc_dec23_decompress(struct pwc_device *pdev,
|
||||
const void *src,
|
||||
void *dst)
|
||||
{
|
||||
int bandlines_left, bytes_per_block;
|
||||
struct pwc_dec23_private *pdec = pwc->decompress_data;
|
||||
struct pwc_dec23_private *pdec = &pdev->dec23;
|
||||
|
||||
/* YUV420P image format */
|
||||
unsigned char *pout_planar_y;
|
||||
|
@ -674,23 +670,22 @@ void pwc_dec23_decompress(const struct pwc_device *pwc,
|
|||
|
||||
mutex_lock(&pdec->lock);
|
||||
|
||||
bandlines_left = pwc->height / 4;
|
||||
bytes_per_block = pwc->width * 4;
|
||||
plane_size = pwc->height * pwc->width;
|
||||
bandlines_left = pdev->height / 4;
|
||||
bytes_per_block = pdev->width * 4;
|
||||
plane_size = pdev->height * pdev->width;
|
||||
|
||||
pout_planar_y = dst;
|
||||
pout_planar_u = dst + plane_size;
|
||||
pout_planar_v = dst + plane_size + plane_size / 4;
|
||||
|
||||
while (bandlines_left--) {
|
||||
DecompressBand23(pwc->decompress_data,
|
||||
src,
|
||||
DecompressBand23(pdec, src,
|
||||
pout_planar_y, pout_planar_u, pout_planar_v,
|
||||
pwc->width, pwc->width);
|
||||
src += pwc->vbandlength;
|
||||
pdev->width, pdev->width);
|
||||
src += pdev->vbandlength;
|
||||
pout_planar_y += bytes_per_block;
|
||||
pout_planar_u += pwc->width;
|
||||
pout_planar_v += pwc->width;
|
||||
pout_planar_u += pdev->width;
|
||||
pout_planar_v += pdev->width;
|
||||
}
|
||||
mutex_unlock(&pdec->lock);
|
||||
}
|
||||
|
|
|
@ -25,17 +25,20 @@
|
|||
#ifndef PWC_DEC23_H
|
||||
#define PWC_DEC23_H
|
||||
|
||||
#include "pwc.h"
|
||||
struct pwc_device;
|
||||
|
||||
struct pwc_dec23_private
|
||||
{
|
||||
struct mutex lock;
|
||||
|
||||
unsigned char last_cmd, last_cmd_valid;
|
||||
|
||||
unsigned int scalebits;
|
||||
unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */
|
||||
|
||||
unsigned int reservoir;
|
||||
unsigned int nbits_in_reservoir;
|
||||
|
||||
const unsigned char *stream;
|
||||
int temp_colors[16];
|
||||
|
||||
|
@ -51,8 +54,8 @@ struct pwc_dec23_private
|
|||
|
||||
};
|
||||
|
||||
int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd);
|
||||
void pwc_dec23_decompress(const struct pwc_device *pwc,
|
||||
void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd);
|
||||
void pwc_dec23_decompress(struct pwc_device *pdev,
|
||||
const void *src,
|
||||
void *dst);
|
||||
#endif
|
||||
|
|
|
@ -128,18 +128,11 @@ static struct usb_driver pwc_driver = {
|
|||
#define MAX_DEV_HINTS 20
|
||||
#define MAX_ISOC_ERRORS 20
|
||||
|
||||
static int default_fps = 10;
|
||||
#ifdef CONFIG_USB_PWC_DEBUG
|
||||
int pwc_trace = PWC_DEBUG_LEVEL;
|
||||
#endif
|
||||
static int power_save = -1;
|
||||
static int led_on = 100, led_off; /* defaults to LED that is on while in use */
|
||||
static struct {
|
||||
int type;
|
||||
char serial_number[30];
|
||||
int device_node;
|
||||
struct pwc_device *pdev;
|
||||
} device_hint[MAX_DEV_HINTS];
|
||||
static int leds[2] = { 100, 0 };
|
||||
|
||||
/***/
|
||||
|
||||
|
@ -386,8 +379,8 @@ static int pwc_isoc_init(struct pwc_device *pdev)
|
|||
retry:
|
||||
/* We first try with low compression and then retry with a higher
|
||||
compression setting if there is not enough bandwidth. */
|
||||
ret = pwc_set_video_mode(pdev, pdev->width, pdev->height,
|
||||
pdev->vframes, &compression);
|
||||
ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
|
||||
pdev->vframes, &compression, 1);
|
||||
|
||||
/* Get the current alternate interface, adjust packet size */
|
||||
intf = usb_ifnum_to_if(udev, 0);
|
||||
|
@ -597,23 +590,9 @@ leave:
|
|||
static void pwc_video_release(struct v4l2_device *v)
|
||||
{
|
||||
struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
|
||||
int hint;
|
||||
|
||||
/* search device_hint[] table if we occupy a slot, by any chance */
|
||||
for (hint = 0; hint < MAX_DEV_HINTS; hint++)
|
||||
if (device_hint[hint].pdev == pdev)
|
||||
device_hint[hint].pdev = NULL;
|
||||
|
||||
/* Free intermediate decompression buffer & tables */
|
||||
if (pdev->decompress_data != NULL) {
|
||||
PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n",
|
||||
pdev->decompress_data);
|
||||
kfree(pdev->decompress_data);
|
||||
pdev->decompress_data = NULL;
|
||||
}
|
||||
|
||||
v4l2_ctrl_handler_free(&pdev->ctrl_handler);
|
||||
|
||||
kfree(pdev->ctrl_buf);
|
||||
kfree(pdev);
|
||||
}
|
||||
|
||||
|
@ -758,7 +737,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||
|
||||
/* Turn on camera and set LEDS on */
|
||||
pwc_camera_power(pdev, 1);
|
||||
pwc_set_leds(pdev, led_on, led_off);
|
||||
pwc_set_leds(pdev, leds[0], leds[1]);
|
||||
|
||||
r = pwc_isoc_init(pdev);
|
||||
if (r) {
|
||||
|
@ -813,10 +792,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
struct pwc_device *pdev = NULL;
|
||||
int vendor_id, product_id, type_id;
|
||||
int hint, rc;
|
||||
int rc;
|
||||
int features = 0;
|
||||
int compression = 0;
|
||||
int video_nr = -1; /* default: use next available device */
|
||||
int my_power_save = power_save;
|
||||
char serial_number[30], *name;
|
||||
|
||||
|
@ -1076,7 +1054,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
return -ENOMEM;
|
||||
}
|
||||
pdev->type = type_id;
|
||||
pdev->vframes = default_fps;
|
||||
pdev->features = features;
|
||||
pwc_construct(pdev); /* set min/max sizes correct */
|
||||
|
||||
|
@ -1107,24 +1084,14 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
|
||||
PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
|
||||
|
||||
/* Now search device_hint[] table for a match, so we can hint a node number. */
|
||||
for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
|
||||
if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
|
||||
(device_hint[hint].pdev == NULL)) {
|
||||
/* so far, so good... try serial number */
|
||||
if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
|
||||
/* match! */
|
||||
video_nr = device_hint[hint].device_node;
|
||||
PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Allocate USB command buffers */
|
||||
pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
|
||||
if (!pdev->ctrl_buf) {
|
||||
PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
/* occupy slot */
|
||||
if (hint < MAX_DEV_HINTS)
|
||||
device_hint[hint].pdev = pdev;
|
||||
|
||||
#ifdef CONFIG_USB_PWC_DEBUG
|
||||
/* Query sensor type */
|
||||
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
|
|||
pwc_set_leds(pdev, 0, 0);
|
||||
|
||||
/* Setup intial videomode */
|
||||
rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes,
|
||||
&compression);
|
||||
rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
|
||||
V4L2_PIX_FMT_YUV420, 30, &compression, 1);
|
||||
if (rc)
|
||||
goto err_free_mem;
|
||||
|
||||
|
@ -1164,7 +1131,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
|
||||
pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
|
||||
|
||||
rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
|
||||
rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
|
||||
if (rc < 0) {
|
||||
PWC_ERROR("Failed to register as video device (%d).\n", rc);
|
||||
goto err_unregister_v4l2_dev;
|
||||
|
@ -1207,8 +1174,7 @@ err_unregister_v4l2_dev:
|
|||
err_free_controls:
|
||||
v4l2_ctrl_handler_free(&pdev->ctrl_handler);
|
||||
err_free_mem:
|
||||
if (hint < MAX_DEV_HINTS)
|
||||
device_hint[hint].pdev = NULL;
|
||||
kfree(pdev->ctrl_buf);
|
||||
kfree(pdev);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1243,27 +1209,19 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
|
|||
* Initialization code & module stuff
|
||||
*/
|
||||
|
||||
static int fps;
|
||||
static int leds[2] = { -1, -1 };
|
||||
static unsigned int leds_nargs;
|
||||
static char *dev_hint[MAX_DEV_HINTS];
|
||||
static unsigned int dev_hint_nargs;
|
||||
|
||||
module_param(fps, int, 0444);
|
||||
#ifdef CONFIG_USB_PWC_DEBUG
|
||||
module_param_named(trace, pwc_trace, int, 0644);
|
||||
#endif
|
||||
module_param(power_save, int, 0644);
|
||||
module_param_array(leds, int, &leds_nargs, 0444);
|
||||
module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
|
||||
|
||||
MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
|
||||
#ifdef CONFIG_USB_PWC_DEBUG
|
||||
MODULE_PARM_DESC(trace, "For debugging purposes");
|
||||
#endif
|
||||
MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
|
||||
MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
|
||||
MODULE_PARM_DESC(dev_hint, "Device node hints");
|
||||
|
||||
MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
|
||||
MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
|
||||
|
@ -1273,114 +1231,13 @@ MODULE_VERSION( PWC_VERSION );
|
|||
|
||||
static int __init usb_pwc_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_USB_PWC_DEBUG
|
||||
PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n");
|
||||
PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
|
||||
PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
|
||||
PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
|
||||
|
||||
if (pwc_trace >= 0) {
|
||||
PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fps) {
|
||||
if (fps < 4 || fps > 30) {
|
||||
PWC_ERROR("Framerate out of bounds (4-30).\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
default_fps = fps;
|
||||
PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
|
||||
}
|
||||
|
||||
if (leds[0] >= 0)
|
||||
led_on = leds[0];
|
||||
if (leds[1] >= 0)
|
||||
led_off = leds[1];
|
||||
|
||||
/* Big device node whoopla. Basically, it allows you to assign a
|
||||
device node (/dev/videoX) to a camera, based on its type
|
||||
& serial number. The format is [type[.serialnumber]:]node.
|
||||
|
||||
Any camera that isn't matched by these rules gets the next
|
||||
available free device node.
|
||||
*/
|
||||
for (i = 0; i < MAX_DEV_HINTS; i++) {
|
||||
char *s, *colon, *dot;
|
||||
|
||||
/* This loop also initializes the array */
|
||||
device_hint[i].pdev = NULL;
|
||||
s = dev_hint[i];
|
||||
if (s != NULL && *s != '\0') {
|
||||
device_hint[i].type = -1; /* wildcard */
|
||||
strcpy(device_hint[i].serial_number, "*");
|
||||
|
||||
/* parse string: chop at ':' & '/' */
|
||||
colon = dot = s;
|
||||
while (*colon != '\0' && *colon != ':')
|
||||
colon++;
|
||||
while (*dot != '\0' && *dot != '.')
|
||||
dot++;
|
||||
/* Few sanity checks */
|
||||
if (*dot != '\0' && dot > colon) {
|
||||
PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*colon == '\0') {
|
||||
/* No colon */
|
||||
if (*dot != '\0') {
|
||||
PWC_ERROR("Malformed camera hint: no colon + device node given.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
else {
|
||||
/* No type or serial number specified, just a number. */
|
||||
device_hint[i].device_node =
|
||||
simple_strtol(s, NULL, 10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* There's a colon, so we have at least a type and a device node */
|
||||
device_hint[i].type =
|
||||
simple_strtol(s, NULL, 10);
|
||||
device_hint[i].device_node =
|
||||
simple_strtol(colon + 1, NULL, 10);
|
||||
if (*dot != '\0') {
|
||||
/* There's a serial number as well */
|
||||
int k;
|
||||
|
||||
dot++;
|
||||
k = 0;
|
||||
while (*dot != ':' && k < 29) {
|
||||
device_hint[i].serial_number[k++] = *dot;
|
||||
dot++;
|
||||
}
|
||||
device_hint[i].serial_number[k] = '\0';
|
||||
}
|
||||
}
|
||||
PWC_TRACE("device_hint[%d]:\n", i);
|
||||
PWC_TRACE(" type : %d\n", device_hint[i].type);
|
||||
PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number);
|
||||
PWC_TRACE(" node : %d\n", device_hint[i].device_node);
|
||||
}
|
||||
else
|
||||
device_hint[i].type = 0; /* not filled */
|
||||
} /* ..for MAX_DEV_HINTS */
|
||||
|
||||
PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver);
|
||||
return usb_register(&pwc_driver);
|
||||
}
|
||||
|
||||
static void __exit usb_pwc_exit(void)
|
||||
{
|
||||
PWC_DEBUG_MODULE("Deregistering driver.\n");
|
||||
usb_deregister(&pwc_driver);
|
||||
PWC_INFO("Philips webcam module removed.\n");
|
||||
}
|
||||
|
||||
module_init(usb_pwc_init);
|
||||
module_exit(usb_pwc_exit);
|
||||
|
||||
/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
|
||||
|
|
|
@ -90,5 +90,4 @@ void pwc_construct(struct pwc_device *pdev)
|
|||
pdev->frame_header_size = 0;
|
||||
pdev->frame_trailer_size = 0;
|
||||
}
|
||||
pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
|
||||
}
|
||||
|
|
|
@ -493,16 +493,11 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
|
|||
(pixelformat>>24)&255);
|
||||
|
||||
ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height,
|
||||
pdev->vframes, &compression);
|
||||
pixelformat, 30, &compression, 0);
|
||||
|
||||
PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
|
||||
|
||||
if (ret == 0) {
|
||||
pdev->pixfmt = pixelformat;
|
||||
pwc_vidioc_fill_fmt(f, pdev->width, pdev->height,
|
||||
pdev->pixfmt);
|
||||
}
|
||||
|
||||
pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
|
||||
leave:
|
||||
mutex_unlock(&pdev->udevlock);
|
||||
return ret;
|
||||
|
@ -777,33 +772,33 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev)
|
|||
static int pwc_set_motor(struct pwc_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[4];
|
||||
|
||||
buf[0] = 0;
|
||||
pdev->ctrl_buf[0] = 0;
|
||||
if (pdev->motor_pan_reset->is_new)
|
||||
buf[0] |= 0x01;
|
||||
pdev->ctrl_buf[0] |= 0x01;
|
||||
if (pdev->motor_tilt_reset->is_new)
|
||||
buf[0] |= 0x02;
|
||||
pdev->ctrl_buf[0] |= 0x02;
|
||||
if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
|
||||
ret = send_control_msg(pdev, SET_MPT_CTL,
|
||||
PT_RESET_CONTROL_FORMATTER, buf, 1);
|
||||
PT_RESET_CONTROL_FORMATTER,
|
||||
pdev->ctrl_buf, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(pdev->ctrl_buf, 0, 4);
|
||||
if (pdev->motor_pan->is_new) {
|
||||
buf[0] = pdev->motor_pan->val & 0xFF;
|
||||
buf[1] = (pdev->motor_pan->val >> 8);
|
||||
pdev->ctrl_buf[0] = pdev->motor_pan->val & 0xFF;
|
||||
pdev->ctrl_buf[1] = (pdev->motor_pan->val >> 8);
|
||||
}
|
||||
if (pdev->motor_tilt->is_new) {
|
||||
buf[2] = pdev->motor_tilt->val & 0xFF;
|
||||
buf[3] = (pdev->motor_tilt->val >> 8);
|
||||
pdev->ctrl_buf[2] = pdev->motor_tilt->val & 0xFF;
|
||||
pdev->ctrl_buf[3] = (pdev->motor_tilt->val >> 8);
|
||||
}
|
||||
if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
|
||||
ret = send_control_msg(pdev, SET_MPT_CTL,
|
||||
PT_RELATIVE_CONTROL_FORMATTER,
|
||||
buf, sizeof(buf));
|
||||
pdev->ctrl_buf, 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1094,6 +1089,63 @@ static int pwc_enum_frameintervals(struct file *file, void *fh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pwc_g_parm(struct file *file, void *fh,
|
||||
struct v4l2_streamparm *parm)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
|
||||
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
|
||||
memset(parm, 0, sizeof(*parm));
|
||||
|
||||
parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
parm->parm.capture.readbuffers = MIN_FRAMES;
|
||||
parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
|
||||
parm->parm.capture.timeperframe.denominator = pdev->vframes;
|
||||
parm->parm.capture.timeperframe.numerator = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pwc_s_parm(struct file *file, void *fh,
|
||||
struct v4l2_streamparm *parm)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int compression = 0;
|
||||
int ret, fps;
|
||||
|
||||
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
|
||||
parm->parm.capture.timeperframe.numerator == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (pwc_test_n_set_capt_file(pdev, file))
|
||||
return -EBUSY;
|
||||
|
||||
fps = parm->parm.capture.timeperframe.denominator /
|
||||
parm->parm.capture.timeperframe.numerator;
|
||||
|
||||
mutex_lock(&pdev->udevlock);
|
||||
if (!pdev->udev) {
|
||||
ret = -ENODEV;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (pdev->iso_init) {
|
||||
ret = -EBUSY;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
|
||||
fps, &compression, 0);
|
||||
|
||||
pwc_g_parm(file, fh, parm);
|
||||
|
||||
leave:
|
||||
mutex_unlock(&pdev->udevlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_log_status(struct file *file, void *priv)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
|
@ -1120,4 +1172,6 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
|
|||
.vidioc_log_status = pwc_log_status,
|
||||
.vidioc_enum_framesizes = pwc_enum_framesizes,
|
||||
.vidioc_enum_frameintervals = pwc_enum_frameintervals,
|
||||
.vidioc_g_parm = pwc_g_parm,
|
||||
.vidioc_s_parm = pwc_s_parm,
|
||||
};
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
#include "pwc-dec1.h"
|
||||
#include "pwc-dec23.h"
|
||||
|
||||
/* Version block */
|
||||
#define PWC_VERSION "10.0.15"
|
||||
|
@ -132,9 +134,6 @@
|
|||
#define DEVICE_USE_CODEC3(x) ((x)>=700)
|
||||
#define DEVICE_USE_CODEC23(x) ((x)>=675)
|
||||
|
||||
/* from pwc-dec.h */
|
||||
#define PWCX_FLAG_PLANAR 0x0001
|
||||
|
||||
/* Request types: video */
|
||||
#define SET_LUM_CTL 0x01
|
||||
#define GET_LUM_CTL 0x02
|
||||
|
@ -248,8 +247,8 @@ struct pwc_device
|
|||
char vmirror; /* for ToUCaM series */
|
||||
char power_save; /* Do powersaving for this cam */
|
||||
|
||||
int cmd_len;
|
||||
unsigned char cmd_buf[13];
|
||||
unsigned char *ctrl_buf;
|
||||
|
||||
struct urb *urbs[MAX_ISO_BUFS];
|
||||
char iso_init;
|
||||
|
@ -272,7 +271,10 @@ struct pwc_device
|
|||
int frame_total_size; /* including header & trailer */
|
||||
int drop_frames;
|
||||
|
||||
void *decompress_data; /* private data for decompression engine */
|
||||
union { /* private data for decompression engine */
|
||||
struct pwc_dec1_private dec1;
|
||||
struct pwc_dec23_private dec23;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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);
|
|||
/** Functions in pwc-ctrl.c */
|
||||
/* Request a certain video mode. Returns < 0 if not possible */
|
||||
extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
|
||||
int frames, int *compression);
|
||||
int pixfmt, int frames, int *compression, int send_to_cam);
|
||||
extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
|
||||
extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
|
||||
extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
|
||||
|
|
|
@ -693,7 +693,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
|
|||
mf->code = 0;
|
||||
continue;
|
||||
}
|
||||
if (mf->width != tfmt->width || mf->width != tfmt->width) {
|
||||
if (mf->width != tfmt->width || mf->height != tfmt->height) {
|
||||
u32 fcc = ffmt->fourcc;
|
||||
tfmt->width = mf->width;
|
||||
tfmt->height = mf->height;
|
||||
|
@ -702,7 +702,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
|
|||
NULL, &fcc, FIMC_SD_PAD_SOURCE);
|
||||
if (ffmt && ffmt->mbus_code)
|
||||
mf->code = ffmt->mbus_code;
|
||||
if (mf->width != tfmt->width || mf->width != tfmt->width)
|
||||
if (mf->width != tfmt->width ||
|
||||
mf->height != tfmt->height)
|
||||
continue;
|
||||
tfmt->code = mf->code;
|
||||
}
|
||||
|
@ -710,7 +711,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
|
|||
ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt);
|
||||
|
||||
if (mf->code == tfmt->code &&
|
||||
mf->width == tfmt->width && mf->width == tfmt->width)
|
||||
mf->width == tfmt->width && mf->height == tfmt->height)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -848,11 +848,11 @@ int fimc_ctrls_create(struct fimc_ctx *ctx)
|
|||
v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
|
||||
|
||||
ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
|
||||
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
V4L2_CID_ROTATE, 0, 270, 90, 0);
|
||||
ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
|
||||
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
|
||||
V4L2_CID_ROTATE, 0, 270, 90, 0);
|
||||
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
if (variant->has_alpha)
|
||||
ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/media-device.h>
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||
ctx->rop = ROP4_INVERT;
|
||||
else
|
||||
ctx->rop = ROP4_COPY;
|
||||
break;
|
||||
default:
|
||||
v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -989,9 +989,10 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
|
|||
* ============================================================================
|
||||
*/
|
||||
|
||||
static int s5p_jpeg_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
|
||||
unsigned int *nplanes, unsigned int sizes[],
|
||||
void *alloc_ctxs[])
|
||||
static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
|
||||
const struct v4l2_format *fmt,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
{
|
||||
struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
struct s5p_jpeg_q_data *q_data = NULL;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
|
@ -475,7 +474,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
|
|||
ctx->mv_size = 0;
|
||||
}
|
||||
ctx->dpb_count = s5p_mfc_get_dpb_count();
|
||||
if (ctx->img_width == 0 || ctx->img_width == 0)
|
||||
if (ctx->img_width == 0 || ctx->img_height == 0)
|
||||
ctx->state = MFCINST_ERROR;
|
||||
else
|
||||
ctx->state = MFCINST_HEAD_PARSED;
|
||||
|
|
|
@ -165,7 +165,7 @@ static struct mfc_control controls[] = {
|
|||
.maximum = 32,
|
||||
.step = 1,
|
||||
.default_value = 1,
|
||||
.flags = V4L2_CTRL_FLAG_VOLATILE,
|
||||
.is_volatile = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -269,8 +269,6 @@ struct saa7164_board saa7164_boards[] = {
|
|||
.portb = SAA7164_MPEG_DVB,
|
||||
.portc = SAA7164_MPEG_ENCODER,
|
||||
.portd = SAA7164_MPEG_ENCODER,
|
||||
.portc = SAA7164_MPEG_ENCODER,
|
||||
.portd = SAA7164_MPEG_ENCODER,
|
||||
.porte = SAA7164_MPEG_VBI,
|
||||
.portf = SAA7164_MPEG_VBI,
|
||||
.chiprev = SAA7164_CHIP_REV3,
|
||||
|
@ -333,8 +331,6 @@ struct saa7164_board saa7164_boards[] = {
|
|||
.portd = SAA7164_MPEG_ENCODER,
|
||||
.porte = SAA7164_MPEG_VBI,
|
||||
.portf = SAA7164_MPEG_VBI,
|
||||
.porte = SAA7164_MPEG_VBI,
|
||||
.portf = SAA7164_MPEG_VBI,
|
||||
.chiprev = SAA7164_CHIP_REV3,
|
||||
.unit = {{
|
||||
.id = 0x28,
|
||||
|
|
|
@ -374,7 +374,7 @@ static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool check_firmware(struct usb_device *udev, int *down_firmware)
|
||||
static int check_firmware(struct usb_device *udev, int *down_firmware)
|
||||
{
|
||||
void *buf;
|
||||
int ret;
|
||||
|
@ -398,7 +398,7 @@ static bool check_firmware(struct usb_device *udev, int *down_firmware)
|
|||
*down_firmware = 1;
|
||||
return firmware_download(udev);
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int poseidon_probe(struct usb_interface *interface,
|
||||
|
|
|
@ -465,8 +465,8 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|||
case V4L2_CID_CHROMA_GAIN: return "Chroma Gain";
|
||||
case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1";
|
||||
case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2";
|
||||
case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Minimum Number of Capture Buffers";
|
||||
case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Minimum Number of Output Buffers";
|
||||
case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers";
|
||||
case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers";
|
||||
case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
|
||||
|
||||
/* MPEG controls */
|
||||
|
@ -506,25 +506,25 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|||
case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV";
|
||||
case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface";
|
||||
case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable";
|
||||
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "The Number of Intra Refresh MBs";
|
||||
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs";
|
||||
case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable";
|
||||
case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control";
|
||||
case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode";
|
||||
case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "The Max Number of Reference Picture";
|
||||
case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entorpy Mode";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I Period";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset";
|
||||
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)
|
|||
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable";
|
||||
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile";
|
||||
case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable";
|
||||
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "The Maximum Bytes Per Slice";
|
||||
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "The Number of MB in a Slice";
|
||||
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "The Slice Partitioning Method";
|
||||
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice";
|
||||
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice";
|
||||
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method";
|
||||
case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size";
|
||||
|
||||
/* CAMERA controls */
|
||||
|
@ -580,7 +580,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|||
case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
|
||||
case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
|
||||
case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
|
||||
case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Feature Enabled";
|
||||
case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled";
|
||||
case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain";
|
||||
case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold";
|
||||
case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time";
|
||||
|
@ -588,24 +588,24 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|||
case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled";
|
||||
case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation";
|
||||
case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency";
|
||||
case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-emphasis settings";
|
||||
case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis";
|
||||
case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
|
||||
case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
|
||||
|
||||
/* Flash controls */
|
||||
case V4L2_CID_FLASH_CLASS: return "Flash controls";
|
||||
case V4L2_CID_FLASH_LED_MODE: return "LED mode";
|
||||
case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe source";
|
||||
case V4L2_CID_FLASH_CLASS: return "Flash Controls";
|
||||
case V4L2_CID_FLASH_LED_MODE: return "LED Mode";
|
||||
case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source";
|
||||
case V4L2_CID_FLASH_STROBE: return "Strobe";
|
||||
case V4L2_CID_FLASH_STROBE_STOP: return "Stop strobe";
|
||||
case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe status";
|
||||
case V4L2_CID_FLASH_TIMEOUT: return "Strobe timeout";
|
||||
case V4L2_CID_FLASH_INTENSITY: return "Intensity, flash mode";
|
||||
case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, torch mode";
|
||||
case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, indicator";
|
||||
case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe";
|
||||
case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status";
|
||||
case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout";
|
||||
case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode";
|
||||
case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode";
|
||||
case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator";
|
||||
case V4L2_CID_FLASH_FAULT: return "Faults";
|
||||
case V4L2_CID_FLASH_CHARGE: return "Charge";
|
||||
case V4L2_CID_FLASH_READY: return "Ready to strobe";
|
||||
case V4L2_CID_FLASH_READY: return "Ready to Strobe";
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
|
|
|
@ -1871,6 +1871,7 @@ static long __video_do_ioctl(struct file *file,
|
|||
case VIDIOC_S_FREQUENCY:
|
||||
{
|
||||
struct v4l2_frequency *p = arg;
|
||||
enum v4l2_tuner_type type;
|
||||
|
||||
if (!ops->vidioc_s_frequency)
|
||||
break;
|
||||
|
@ -1878,9 +1879,14 @@ static long __video_do_ioctl(struct file *file,
|
|||
ret = ret_prio;
|
||||
break;
|
||||
}
|
||||
type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
|
||||
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
|
||||
dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
|
||||
p->tuner, p->type, p->frequency);
|
||||
ret = ops->vidioc_s_frequency(file, fh, p);
|
||||
if (p->type != type)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
ret = ops->vidioc_s_frequency(file, fh, p);
|
||||
break;
|
||||
}
|
||||
case VIDIOC_G_SLICED_VBI_CAP:
|
||||
|
|
|
@ -1958,7 +1958,6 @@ static int zoran_g_fbuf(struct file *file, void *__fh,
|
|||
mutex_unlock(&zr->resource_lock);
|
||||
fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
|
||||
fb->fmt.field = V4L2_FIELD_INTERLACED;
|
||||
fb->flags = V4L2_FBUF_FLAG_OVERLAY;
|
||||
fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -127,7 +127,6 @@
|
|||
#define TUNER_PHILIPS_FMD1216MEX_MK3 78
|
||||
#define TUNER_PHILIPS_FM1216MK5 79
|
||||
#define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */
|
||||
#define TUNER_XC4000 81 /* Xceive Silicon Tuner */
|
||||
|
||||
#define TUNER_PARTSNIC_PTI_5NF05 81
|
||||
#define TUNER_PHILIPS_CU1216L 82
|
||||
|
@ -136,6 +135,8 @@
|
|||
#define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */
|
||||
#define TUNER_TENA_TNF_5337 86
|
||||
|
||||
#define TUNER_XC4000 87 /* Xceive Silicon Tuner */
|
||||
|
||||
/* tv card specific */
|
||||
#define TDA9887_PRESENT (1<<0)
|
||||
#define TDA9887_PORT1_INACTIVE (1<<1)
|
||||
|
|
Загрузка…
Ссылка в новой задаче