mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 12:10:53 +07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (59 commits) V4L/DVB (7219): zoran: Fix namespace conflicts with Zoran 'GPIO_MAX' enum V4L/DVB (7205): tuner-xc2028 depends on FW_LOADER V4L/DVB (7201): cx88-mpeg: Fix race condition in variable access V4L/DVB (7200): Fix FM firmware loading V4L/DVB (7198): V4L, include ioctl.h in videodev headers V4L/DVB (7197): bttv: Fix overlay divide error V4L/DVB (7195): xc5000: fix build error when built as module V4L/DVB (7194): cx88-mpeg: Allow concurrent access to cx88-mpeg devices V4L/DVB (7193): tveeprom: Add proper tuner mapping for hauppauge eeprom id 133 V4L/DVB (7192): Adds support for Genius TVGo A11MCE V4L/DVB (7189): autosuspend support V4L/DVB (7188): radio-si470x version 1.0.6 V4L/DVB (7186): tda10086: make the 22kHz tone for DISEQC a config option V4L/DVB (7183): radio-si470x: fix build warning V4L/DVB (7180): em28xx: add URB_NO_TRANSFER_DMA_MAP, since urb->transfer_dma is set V4L/DVB (7179): Allow more than one em28xx board V4L/DVB (7164): em28xx-alsa: Add a missing mutex V4L/DVB (7163): em28xx: makes audio settings more stable V4L/DVB (7162): em28xx: Fix endian and returns the correct values V4L/DVB (7161): em28xx: Fix printing debug values higher than 127 ...
This commit is contained in:
commit
20ef0f1ad0
@ -8,7 +8,7 @@
|
||||
7 -> Leadtek Winfast USB II (em2800)
|
||||
8 -> Kworld USB2800 (em2800)
|
||||
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502]
|
||||
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
||||
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||
|
@ -92,9 +92,9 @@
|
||||
91 -> AVerMedia A169 B [1461:7360]
|
||||
92 -> AVerMedia A169 B1 [1461:6360]
|
||||
93 -> Medion 7134 Bridge #2 [16be:0005]
|
||||
94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502]
|
||||
94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502]
|
||||
95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138]
|
||||
96 -> Medion Md8800 Quadro [16be:0007,16be:0008]
|
||||
96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d]
|
||||
97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300]
|
||||
98 -> Proteus Pro 2309 [0919:2003]
|
||||
99 -> AVerMedia TV Hybrid A16AR [1461:2c00]
|
||||
@ -129,3 +129,5 @@
|
||||
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
|
||||
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
|
||||
130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
|
||||
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
|
||||
132 -> Genius TVGO AM11MCE
|
||||
|
@ -25,7 +25,7 @@ modprobe zr364xx debug=X mode=Y
|
||||
- debug : set to 1 to enable verbose debug messages
|
||||
- mode : 0 = 320x240, 1 = 160x120, 2 = 640x480
|
||||
You can then use the camera with V4L2 compatible applications, for example Ekiga.
|
||||
To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
|
||||
To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M count=1
|
||||
|
||||
links :
|
||||
http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
|
||||
@ -63,3 +63,5 @@ Vendor Product Distributor Model
|
||||
0x06d6 0x0034 Trust Powerc@m 750
|
||||
0x0a17 0x0062 Pentax Optio 50L
|
||||
0x06d6 0x003b Trust Powerc@m 970Z
|
||||
0x0a17 0x004e Pentax Optio 50
|
||||
0x041e 0x405d Creative DiVi CAM 516
|
||||
|
@ -25,11 +25,16 @@ config VIDEO_DEV
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called videodev.
|
||||
|
||||
config VIDEO_V4L2_COMMON
|
||||
tristate
|
||||
depends on (I2C || I2C=n) && VIDEO_DEV
|
||||
default (I2C || I2C=n) && VIDEO_DEV
|
||||
|
||||
config VIDEO_V4L1
|
||||
bool "Enable Video For Linux API 1 (DEPRECATED)"
|
||||
depends on VIDEO_DEV
|
||||
depends on VIDEO_DEV && VIDEO_V4L2_COMMON
|
||||
default VIDEO_DEV && VIDEO_V4L2_COMMON
|
||||
select VIDEO_V4L1_COMPAT
|
||||
default y
|
||||
---help---
|
||||
Enables a compatibility API used by most V4L2 devices to allow
|
||||
its usage with legacy applications that supports only V4L1 api.
|
||||
@ -39,7 +44,7 @@ config VIDEO_V4L1
|
||||
config VIDEO_V4L1_COMPAT
|
||||
bool "Enable Video For Linux API 1 compatible Layer"
|
||||
depends on VIDEO_DEV
|
||||
default y
|
||||
default VIDEO_DEV
|
||||
---help---
|
||||
This api were developed to be used at Kernel 2.2 and 2.4, but
|
||||
lacks support for several video standards. There are several
|
||||
@ -55,8 +60,8 @@ config VIDEO_V4L1_COMPAT
|
||||
|
||||
config VIDEO_V4L2
|
||||
bool
|
||||
depends on VIDEO_DEV
|
||||
default y
|
||||
depends on VIDEO_DEV && VIDEO_V4L2_COMMON
|
||||
default VIDEO_DEV && VIDEO_V4L2_COMMON
|
||||
|
||||
source "drivers/media/video/Kconfig"
|
||||
|
||||
@ -93,7 +98,7 @@ if VIDEO_TUNER_CUSTOMIZE
|
||||
|
||||
config TUNER_XC2028
|
||||
tristate "XCeive xc2028/xc3028 tuners"
|
||||
depends on I2C
|
||||
depends on I2C && FW_LOADER
|
||||
default m if VIDEO_TUNER_CUSTOMIZE
|
||||
help
|
||||
Say Y here to include support for the xc2028/xc3028 tuners.
|
||||
@ -180,7 +185,6 @@ config VIDEO_TVEEPROM
|
||||
|
||||
config DAB
|
||||
boolean "DAB adapters"
|
||||
default y
|
||||
---help---
|
||||
Allow selecting support for for Digital Audio Broadcasting (DAB)
|
||||
Receiver adapters.
|
||||
|
@ -4,6 +4,6 @@ config VIDEO_SAA7146
|
||||
|
||||
config VIDEO_SAA7146_VV
|
||||
tristate
|
||||
depends on VIDEO_DEV
|
||||
depends on VIDEO_V4L2
|
||||
select VIDEOBUF_DMA_SG
|
||||
select VIDEO_SAA7146
|
||||
|
@ -1987,3 +1987,49 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL_GPL(ir_codes_behold);
|
||||
|
||||
/*
|
||||
* Remote control for the Genius TVGO A11MCE
|
||||
* Adrian Pardini <pardo.bsso@gmail.com>
|
||||
*/
|
||||
IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = {
|
||||
/* Keys 0 to 9 */
|
||||
[0x48] = KEY_0,
|
||||
[0x09] = KEY_1,
|
||||
[0x1d] = KEY_2,
|
||||
[0x1f] = KEY_3,
|
||||
[0x19] = KEY_4,
|
||||
[0x1b] = KEY_5,
|
||||
[0x11] = KEY_6,
|
||||
[0x17] = KEY_7,
|
||||
[0x12] = KEY_8,
|
||||
[0x16] = KEY_9,
|
||||
|
||||
[0x54] = KEY_RECORD, /* recording */
|
||||
[0x06] = KEY_MUTE, /* mute */
|
||||
[0x10] = KEY_POWER,
|
||||
[0x40] = KEY_LAST, /* recall */
|
||||
[0x4c] = KEY_CHANNELUP, /* channel / program + */
|
||||
[0x00] = KEY_CHANNELDOWN, /* channel / program - */
|
||||
[0x0d] = KEY_VOLUMEUP,
|
||||
[0x15] = KEY_VOLUMEDOWN,
|
||||
[0x4d] = KEY_OK, /* also labeled as Pause */
|
||||
[0x1c] = KEY_ZOOM, /* full screen and Stop*/
|
||||
[0x02] = KEY_MODE, /* AV Source or Rewind*/
|
||||
[0x04] = KEY_LIST, /* -/-- */
|
||||
/* small arrows above numbers */
|
||||
[0x1a] = KEY_NEXT, /* also Fast Forward */
|
||||
[0x0e] = KEY_PREVIOUS, /* also Rewind */
|
||||
/* these are in a rather non standard layout and have
|
||||
an alternate name written */
|
||||
[0x1e] = KEY_UP, /* Video Setting */
|
||||
[0x0a] = KEY_DOWN, /* Video Default */
|
||||
[0x05] = KEY_LEFT, /* Snapshot */
|
||||
[0x0c] = KEY_RIGHT, /* Hide Panel */
|
||||
/* Four buttons without label */
|
||||
[0x49] = KEY_RED,
|
||||
[0x0b] = KEY_GREEN,
|
||||
[0x13] = KEY_YELLOW,
|
||||
[0x50] = KEY_BLUE,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce);
|
||||
|
@ -413,7 +413,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
|
||||
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
|
||||
sizeof(struct saa7146_buf),
|
||||
file);
|
||||
mutex_init(&fh->vbi_q.lock);
|
||||
|
||||
init_timer(&fh->vbi_read_timeout);
|
||||
fh->vbi_read_timeout.function = vbi_read_timeout;
|
||||
|
@ -1417,8 +1417,6 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
|
||||
sizeof(struct saa7146_buf),
|
||||
file);
|
||||
|
||||
mutex_init(&fh->video_q.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,11 @@ EXPORT_SYMBOL(bt878);
|
||||
#if defined(dprintk)
|
||||
#undef dprintk
|
||||
#endif
|
||||
#define dprintk if(bt878_debug) printk
|
||||
#define dprintk(fmt, arg...) \
|
||||
do { \
|
||||
if (bt878_debug) \
|
||||
printk(KERN_DEBUG fmt, ##arg); \
|
||||
} while (0)
|
||||
|
||||
static void bt878_mem_free(struct bt878 *bt)
|
||||
{
|
||||
@ -154,7 +158,7 @@ static int bt878_make_risc(struct bt878 *bt)
|
||||
}
|
||||
|
||||
if (bt->line_count > 255) {
|
||||
printk("bt878: buffer size error!\n");
|
||||
printk(KERN_ERR "bt878: buffer size error!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
@ -285,7 +289,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
|
||||
|
||||
if (astat & (BT878_ASCERR | BT878_AOCERR)) {
|
||||
if (bt878_verbose) {
|
||||
printk("bt878(%d): irq%s%s risc_pc=%08x\n",
|
||||
printk(KERN_INFO
|
||||
"bt878(%d): irq%s%s risc_pc=%08x\n",
|
||||
bt->nr,
|
||||
(astat & BT878_ASCERR) ? " SCERR" :
|
||||
"",
|
||||
@ -295,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
|
||||
}
|
||||
if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
|
||||
if (bt878_verbose) {
|
||||
printk
|
||||
("bt878(%d): irq%s%s%s risc_pc=%08x\n",
|
||||
printk(KERN_INFO
|
||||
"bt878(%d): irq%s%s%s risc_pc=%08x\n",
|
||||
bt->nr,
|
||||
(astat & BT878_APABORT) ? " PABORT" :
|
||||
"",
|
||||
@ -308,8 +313,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
|
||||
}
|
||||
if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
|
||||
if (bt878_verbose) {
|
||||
printk
|
||||
("bt878(%d): irq%s%s%s risc_pc=%08x\n",
|
||||
printk(KERN_INFO
|
||||
"bt878(%d): irq%s%s%s risc_pc=%08x\n",
|
||||
bt->nr,
|
||||
(astat & BT878_AFDSR) ? " FDSR" : "",
|
||||
(astat & BT878_AFTRGT) ? " FTRGT" :
|
||||
@ -510,7 +515,7 @@ static int __devinit bt878_probe(struct pci_dev *dev,
|
||||
*/
|
||||
|
||||
if ((result = bt878_mem_alloc(bt))) {
|
||||
printk("bt878: failed to allocate memory!\n");
|
||||
printk(KERN_ERR "bt878: failed to allocate memory!\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
@ -536,7 +541,7 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev)
|
||||
struct bt878 *bt = pci_get_drvdata(pci_dev);
|
||||
|
||||
if (bt878_verbose)
|
||||
printk("bt878(%d): unloading\n", bt->nr);
|
||||
printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
|
||||
|
||||
/* turn off all capturing, DMA and IRQs */
|
||||
btand(~0x13, BT878_AGPIO_DMA_CTL);
|
||||
|
@ -144,6 +144,7 @@ static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
static struct tda10086_config tda10086_config = {
|
||||
.demod_address = 0x0e,
|
||||
.invert = 0,
|
||||
.diseqc_tone = 1,
|
||||
};
|
||||
|
||||
static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
|
@ -106,9 +106,12 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask,
|
||||
static int tda10086_init(struct dvb_frontend* fe)
|
||||
{
|
||||
struct tda10086_state* state = fe->demodulator_priv;
|
||||
u8 t22k_off = 0x80;
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
if (state->config->diseqc_tone)
|
||||
t22k_off = 0;
|
||||
// reset
|
||||
tda10086_write_byte(state, 0x00, 0x00);
|
||||
msleep(10);
|
||||
@ -158,7 +161,7 @@ static int tda10086_init(struct dvb_frontend* fe)
|
||||
tda10086_write_byte(state, 0x3d, 0x80);
|
||||
|
||||
// setup SEC
|
||||
tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone
|
||||
tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone
|
||||
tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency
|
||||
tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
|
||||
|
||||
@ -180,16 +183,20 @@ static void tda10086_diseqc_wait(struct tda10086_state *state)
|
||||
static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
|
||||
{
|
||||
struct tda10086_state* state = fe->demodulator_priv;
|
||||
u8 t22k_off = 0x80;
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
if (state->config->diseqc_tone)
|
||||
t22k_off = 0;
|
||||
|
||||
switch (tone) {
|
||||
case SEC_TONE_OFF:
|
||||
tda10086_write_byte(state, 0x36, 0x80);
|
||||
tda10086_write_byte(state, 0x36, t22k_off);
|
||||
break;
|
||||
|
||||
case SEC_TONE_ON:
|
||||
tda10086_write_byte(state, 0x36, 0x81);
|
||||
tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -202,9 +209,13 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
|
||||
struct tda10086_state* state = fe->demodulator_priv;
|
||||
int i;
|
||||
u8 oldval;
|
||||
u8 t22k_off = 0x80;
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
if (state->config->diseqc_tone)
|
||||
t22k_off = 0;
|
||||
|
||||
if (cmd->msg_len > 6)
|
||||
return -EINVAL;
|
||||
oldval = tda10086_read_byte(state, 0x36);
|
||||
@ -212,7 +223,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
|
||||
for(i=0; i< cmd->msg_len; i++) {
|
||||
tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
|
||||
}
|
||||
tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4));
|
||||
tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
|
||||
| ((cmd->msg_len - 1) << 4));
|
||||
|
||||
tda10086_diseqc_wait(state);
|
||||
|
||||
@ -225,16 +237,20 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic
|
||||
{
|
||||
struct tda10086_state* state = fe->demodulator_priv;
|
||||
u8 oldval = tda10086_read_byte(state, 0x36);
|
||||
u8 t22k_off = 0x80;
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
if (state->config->diseqc_tone)
|
||||
t22k_off = 0;
|
||||
|
||||
switch(minicmd) {
|
||||
case SEC_MINI_A:
|
||||
tda10086_write_byte(state, 0x36, 0x84);
|
||||
tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
|
||||
break;
|
||||
|
||||
case SEC_MINI_B:
|
||||
tda10086_write_byte(state, 0x36, 0x86);
|
||||
tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,9 @@ struct tda10086_config
|
||||
|
||||
/* does the "inversion" need inverted? */
|
||||
u8 invert;
|
||||
|
||||
/* do we need the diseqc signal with carrier? */
|
||||
u8 diseqc_tone;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
|
||||
|
@ -171,7 +171,7 @@ int tda18271_read_extended(struct dvb_frontend *fe)
|
||||
if (ret != 2)
|
||||
tda_err("ERROR: i2c_transfer returned: %d\n", ret);
|
||||
|
||||
for (i = 0; i <= TDA18271_NUM_REGS; i++) {
|
||||
for (i = 0; i < TDA18271_NUM_REGS; i++) {
|
||||
/* don't update write-only registers */
|
||||
if ((i != R_EB9) &&
|
||||
(i != R_EB16) &&
|
||||
|
@ -45,7 +45,8 @@ struct xc5000_config {
|
||||
/* xc5000 callback command */
|
||||
#define XC5000_TUNER_RESET 0
|
||||
|
||||
#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE)
|
||||
#if defined(CONFIG_DVB_TUNER_XC5000) || \
|
||||
(defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg);
|
||||
|
@ -966,6 +966,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x
|
||||
static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
|
||||
{
|
||||
int i, n;
|
||||
int progressive = 0;
|
||||
|
||||
dprintk(2, "av7110:%p, \n", av7110);
|
||||
|
||||
@ -974,6 +975,14 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
for (i = 0; i < len - 5; i++) {
|
||||
/* get progressive flag from picture extension */
|
||||
if (buf[i] == 0x00 && buf[i+1] == 0x00 &&
|
||||
buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 &&
|
||||
(buf[i+4] & 0xf0) == 0x10)
|
||||
progressive = buf[i+5] & 0x08;
|
||||
}
|
||||
|
||||
/* setting n always > 1, fixes problems when playing stillframes
|
||||
consisting of I- and P-Frames */
|
||||
n = MIN_IFRAME / len + 1;
|
||||
@ -985,7 +994,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
|
||||
dvb_play(av7110, buf, len, 0, 1);
|
||||
|
||||
av7110_ipack_flush(&av7110->ipack[1]);
|
||||
return 0;
|
||||
|
||||
if (progressive)
|
||||
return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -896,6 +896,7 @@ static u8 read_pwm(struct budget_av *budget_av)
|
||||
#define SUBID_DVBS_CINERGY1200 0x1154
|
||||
#define SUBID_DVBS_CYNERGY1200N 0x1155
|
||||
#define SUBID_DVBS_TV_STAR 0x0014
|
||||
#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
|
||||
#define SUBID_DVBS_TV_STAR_CI 0x0016
|
||||
#define SUBID_DVBS_EASYWATCH_1 0x001a
|
||||
#define SUBID_DVBS_EASYWATCH_2 0x001b
|
||||
@ -910,6 +911,7 @@ static u8 read_pwm(struct budget_av *budget_av)
|
||||
#define SUBID_DVBC_CINERGY1200 0x1156
|
||||
#define SUBID_DVBC_CINERGY1200_MK3 0x1176
|
||||
|
||||
#define SUBID_DVBT_EASYWATCH 0x003a
|
||||
#define SUBID_DVBT_KNC1_PLUS 0x0031
|
||||
#define SUBID_DVBT_KNC1 0x0030
|
||||
#define SUBID_DVBT_CINERGY1200 0x1157
|
||||
@ -957,6 +959,7 @@ static void frontend_init(struct budget_av *budget_av)
|
||||
break;
|
||||
|
||||
case SUBID_DVBS_TV_STAR:
|
||||
case SUBID_DVBS_TV_STAR_PLUS_X4:
|
||||
case SUBID_DVBS_TV_STAR_CI:
|
||||
case SUBID_DVBS_CYNERGY1200N:
|
||||
case SUBID_DVBS_EASYWATCH:
|
||||
@ -1018,6 +1021,7 @@ static void frontend_init(struct budget_av *budget_av)
|
||||
}
|
||||
break;
|
||||
|
||||
case SUBID_DVBT_EASYWATCH:
|
||||
case SUBID_DVBT_KNC1:
|
||||
case SUBID_DVBT_KNC1_PLUS:
|
||||
case SUBID_DVBT_CINERGY1200:
|
||||
@ -1248,7 +1252,9 @@ MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
|
||||
MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
|
||||
MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
|
||||
MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
|
||||
MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
|
||||
MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
|
||||
MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
|
||||
MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
|
||||
MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
|
||||
MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
|
||||
@ -1266,12 +1272,14 @@ static struct pci_device_id pci_tbl[] = {
|
||||
MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
|
||||
MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
|
||||
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
|
||||
MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
|
||||
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
|
||||
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
|
||||
MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
|
||||
MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
|
||||
MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
|
||||
MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
|
||||
MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
|
||||
MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
|
||||
MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
|
||||
MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
|
||||
|
@ -351,6 +351,7 @@ static struct s5h1420_config s5h1420_config = {
|
||||
static struct tda10086_config tda10086_config = {
|
||||
.demod_address = 0x0e,
|
||||
.invert = 0,
|
||||
.diseqc_tone = 1,
|
||||
};
|
||||
|
||||
static u8 read_pwm(struct budget* budget)
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
menuconfig RADIO_ADAPTERS
|
||||
bool "Radio Adapters"
|
||||
depends on VIDEO_DEV
|
||||
depends on VIDEO_V4L2
|
||||
default y
|
||||
---help---
|
||||
Say Y here to enable selecting AM/FM radio adapters.
|
||||
|
||||
if RADIO_ADAPTERS && VIDEO_DEV
|
||||
if RADIO_ADAPTERS && VIDEO_V4L2
|
||||
|
||||
config RADIO_CADET
|
||||
tristate "ADS Cadet AM/FM Tuner"
|
||||
|
@ -361,6 +361,7 @@ static int __init fmi_init(void)
|
||||
}
|
||||
if (!request_region(io, 2, "radio-sf16fmi")) {
|
||||
printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
|
||||
pnp_device_detach(dev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -470,9 +470,8 @@ static int __init fmr2_init(void)
|
||||
|
||||
mutex_init(&lock);
|
||||
|
||||
if (request_region(io, 2, "sf16fmr2"))
|
||||
{
|
||||
printk(KERN_ERR "fmr2: port 0x%x already in use\n", io);
|
||||
if (!request_region(io, 2, "sf16fmr2")) {
|
||||
printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,29 @@
|
||||
* - code cleaned of unnecessary rds_commands
|
||||
* - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
|
||||
* (thanks to Guillaume RAMOUSSE)
|
||||
* 2008-01-27 Tobias Lorenz <tobias.lorenz@gmx.net>
|
||||
* Version 1.0.5
|
||||
* - number of seek_retries changed to tune_timeout
|
||||
* - fixed problem with incomplete tune operations by own buffers
|
||||
* - optimization of variables and printf types
|
||||
* - improved error logging
|
||||
* 2008-01-31 Tobias Lorenz <tobias.lorenz@gmx.net>
|
||||
* Oliver Neukum <oliver@neukum.org>
|
||||
* Version 1.0.6
|
||||
* - fixed coverity checker warnings in *_usb_driver_disconnect
|
||||
* - probe()/open() race by correct ordering in probe()
|
||||
* - DMA coherency rules by separate allocation of all buffers
|
||||
* - use of endianness macros
|
||||
* - abuse of spinlock, replaced by mutex
|
||||
* - racy handling of timer in disconnect,
|
||||
* replaced by delayed_work
|
||||
* - racy interruptible_sleep_on(),
|
||||
* replaced with wait_event_interruptible()
|
||||
* - handle signals in read()
|
||||
* 2008-02-08 Tobias Lorenz <tobias.lorenz@gmx.net>
|
||||
* Oliver Neukum <oliver@neukum.org>
|
||||
* Version 1.0.7
|
||||
* - usb autosuspend support
|
||||
*
|
||||
* ToDo:
|
||||
* - add seeking support
|
||||
@ -74,9 +97,10 @@
|
||||
/* driver definitions */
|
||||
#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
|
||||
#define DRIVER_NAME "radio-si470x"
|
||||
#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4)
|
||||
#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6)
|
||||
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
|
||||
#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
|
||||
#define DRIVER_VERSION "1.0.6"
|
||||
|
||||
|
||||
/* kernel includes */
|
||||
@ -89,8 +113,10 @@
|
||||
#include <linux/hid.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/rds.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
||||
/* USB Device ID List */
|
||||
@ -119,56 +145,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
|
||||
/* 0: 200 kHz (USA, Australia) */
|
||||
/* 1: 100 kHz (Europe, Japan) */
|
||||
/* 2: 50 kHz */
|
||||
static int space = 2;
|
||||
module_param(space, int, 0);
|
||||
static unsigned short space = 2;
|
||||
module_param(space, ushort, 0);
|
||||
MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
|
||||
|
||||
/* Bottom of Band (MHz) */
|
||||
/* 0: 87.5 - 108 MHz (USA, Europe)*/
|
||||
/* 1: 76 - 108 MHz (Japan wide band) */
|
||||
/* 2: 76 - 90 MHz (Japan) */
|
||||
static int band = 1;
|
||||
module_param(band, int, 0);
|
||||
static unsigned short band = 1;
|
||||
module_param(band, ushort, 0);
|
||||
MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
|
||||
|
||||
/* De-emphasis */
|
||||
/* 0: 75 us (USA) */
|
||||
/* 1: 50 us (Europe, Australia, Japan) */
|
||||
static int de = 1;
|
||||
module_param(de, int, 0);
|
||||
static unsigned short de = 1;
|
||||
module_param(de, ushort, 0);
|
||||
MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
|
||||
|
||||
/* USB timeout */
|
||||
static int usb_timeout = 500;
|
||||
module_param(usb_timeout, int, 0);
|
||||
static unsigned int usb_timeout = 500;
|
||||
module_param(usb_timeout, uint, 0);
|
||||
MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
|
||||
|
||||
/* Seek retries */
|
||||
static int seek_retries = 100;
|
||||
module_param(seek_retries, int, 0);
|
||||
MODULE_PARM_DESC(seek_retries, "Seek retries: *100*");
|
||||
/* Tune timeout */
|
||||
static unsigned int tune_timeout = 3000;
|
||||
module_param(tune_timeout, uint, 0);
|
||||
MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
|
||||
|
||||
/* RDS buffer blocks */
|
||||
static int rds_buf = 100;
|
||||
module_param(rds_buf, int, 0);
|
||||
static unsigned int rds_buf = 100;
|
||||
module_param(rds_buf, uint, 0);
|
||||
MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
|
||||
|
||||
/* RDS maximum block errors */
|
||||
static int max_rds_errors = 1;
|
||||
static unsigned short max_rds_errors = 1;
|
||||
/* 0 means 0 errors requiring correction */
|
||||
/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
|
||||
/* 2 means 3-5 errors requiring correction */
|
||||
/* 3 means 6+ errors or errors in checkword, correction not possible */
|
||||
module_param(max_rds_errors, int, 0);
|
||||
module_param(max_rds_errors, ushort, 0);
|
||||
MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
|
||||
|
||||
/* RDS poll frequency */
|
||||
static int rds_poll_time = 40;
|
||||
static unsigned int rds_poll_time = 40;
|
||||
/* 40 is used by the original USBRadio.exe */
|
||||
/* 50 is used by radio-cadet */
|
||||
/* 75 should be okay */
|
||||
/* 80 is the usual RDS receive interval */
|
||||
module_param(rds_poll_time, int, 0);
|
||||
module_param(rds_poll_time, uint, 0);
|
||||
MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
|
||||
|
||||
|
||||
@ -393,22 +419,19 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
|
||||
struct si470x_device {
|
||||
/* reference to USB and video device */
|
||||
struct usb_device *usbdev;
|
||||
struct usb_interface *intf;
|
||||
struct video_device *videodev;
|
||||
|
||||
/* are these really necessary ? */
|
||||
int users;
|
||||
|
||||
/* report buffer (maximum 64 bytes) */
|
||||
unsigned char buf[64];
|
||||
/* driver management */
|
||||
unsigned int users;
|
||||
|
||||
/* Silabs internal registers (0..15) */
|
||||
unsigned short registers[RADIO_REGISTER_NUM];
|
||||
|
||||
/* RDS receive buffer */
|
||||
struct work_struct work;
|
||||
struct delayed_work work;
|
||||
wait_queue_head_t read_queue;
|
||||
struct timer_list timer;
|
||||
spinlock_t lock; /* buffer locking */
|
||||
struct mutex lock; /* buffer locking */
|
||||
unsigned char *buffer; /* size is always multiple of three */
|
||||
unsigned int buf_size;
|
||||
unsigned int rd_index;
|
||||
@ -434,28 +457,46 @@ struct si470x_device {
|
||||
/*
|
||||
* si470x_get_report - receive a HID report
|
||||
*/
|
||||
static int si470x_get_report(struct si470x_device *radio, int size)
|
||||
static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
|
||||
{
|
||||
return usb_control_msg(radio->usbdev,
|
||||
unsigned char *report = (unsigned char *) buf;
|
||||
int retval;
|
||||
|
||||
retval = usb_control_msg(radio->usbdev,
|
||||
usb_rcvctrlpipe(radio->usbdev, 0),
|
||||
HID_REQ_GET_REPORT,
|
||||
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
|
||||
radio->buf[0], 2,
|
||||
radio->buf, size, usb_timeout);
|
||||
report[0], 2,
|
||||
buf, size, usb_timeout);
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": si470x_get_report: usb_control_msg returned %d\n",
|
||||
retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_set_report - send a HID report
|
||||
*/
|
||||
static int si470x_set_report(struct si470x_device *radio, int size)
|
||||
static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
|
||||
{
|
||||
return usb_control_msg(radio->usbdev,
|
||||
unsigned char *report = (unsigned char *) buf;
|
||||
int retval;
|
||||
|
||||
retval = usb_control_msg(radio->usbdev,
|
||||
usb_sndctrlpipe(radio->usbdev, 0),
|
||||
HID_REQ_SET_REPORT,
|
||||
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
|
||||
radio->buf[0], 2,
|
||||
radio->buf, size, usb_timeout);
|
||||
report[0], 2,
|
||||
buf, size, usb_timeout);
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": si470x_set_report: usb_control_msg returned %d\n",
|
||||
retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -464,13 +505,16 @@ static int si470x_set_report(struct si470x_device *radio, int size)
|
||||
*/
|
||||
static int si470x_get_register(struct si470x_device *radio, int regnr)
|
||||
{
|
||||
unsigned char buf[REGISTER_REPORT_SIZE];
|
||||
int retval;
|
||||
|
||||
radio->buf[0] = REGISTER_REPORT(regnr);
|
||||
buf[0] = REGISTER_REPORT(regnr);
|
||||
|
||||
retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
|
||||
|
||||
retval = si470x_get_report(radio, REGISTER_REPORT_SIZE);
|
||||
if (retval >= 0)
|
||||
radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2];
|
||||
radio->registers[regnr] = be16_to_cpu(get_unaligned(
|
||||
(unsigned short *) &buf[1]));
|
||||
|
||||
return (retval < 0) ? -EINVAL : 0;
|
||||
}
|
||||
@ -481,13 +525,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
|
||||
*/
|
||||
static int si470x_set_register(struct si470x_device *radio, int regnr)
|
||||
{
|
||||
unsigned char buf[REGISTER_REPORT_SIZE];
|
||||
int retval;
|
||||
|
||||
radio->buf[0] = REGISTER_REPORT(regnr);
|
||||
radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8;
|
||||
radio->buf[2] = (radio->registers[regnr] & 0x00ff);
|
||||
buf[0] = REGISTER_REPORT(regnr);
|
||||
put_unaligned(cpu_to_be16(radio->registers[regnr]),
|
||||
(unsigned short *) &buf[1]);
|
||||
|
||||
retval = si470x_set_report(radio, REGISTER_REPORT_SIZE);
|
||||
retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
|
||||
|
||||
return (retval < 0) ? -EINVAL : 0;
|
||||
}
|
||||
@ -498,18 +543,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
|
||||
*/
|
||||
static int si470x_get_all_registers(struct si470x_device *radio)
|
||||
{
|
||||
unsigned char buf[ENTIRE_REPORT_SIZE];
|
||||
int retval;
|
||||
int regnr;
|
||||
unsigned char regnr;
|
||||
|
||||
radio->buf[0] = ENTIRE_REPORT;
|
||||
buf[0] = ENTIRE_REPORT;
|
||||
|
||||
retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE);
|
||||
retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
|
||||
|
||||
if (retval >= 0)
|
||||
for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
|
||||
radio->registers[regnr] =
|
||||
(radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
|
||||
radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
|
||||
radio->registers[regnr] = be16_to_cpu(get_unaligned(
|
||||
(unsigned short *)
|
||||
&buf[regnr * RADIO_REGISTER_SIZE + 1]));
|
||||
|
||||
return (retval < 0) ? -EINVAL : 0;
|
||||
}
|
||||
@ -520,21 +566,28 @@ static int si470x_get_all_registers(struct si470x_device *radio)
|
||||
*/
|
||||
static int si470x_get_rds_registers(struct si470x_device *radio)
|
||||
{
|
||||
unsigned char buf[RDS_REPORT_SIZE];
|
||||
int retval;
|
||||
int regnr;
|
||||
int size;
|
||||
unsigned char regnr;
|
||||
|
||||
radio->buf[0] = RDS_REPORT;
|
||||
buf[0] = RDS_REPORT;
|
||||
|
||||
retval = usb_interrupt_msg(radio->usbdev,
|
||||
usb_rcvctrlpipe(radio->usbdev, 1),
|
||||
radio->buf, RDS_REPORT_SIZE, &size, usb_timeout);
|
||||
usb_rcvintpipe(radio->usbdev, 1),
|
||||
(void *) &buf, sizeof(buf), &size, usb_timeout);
|
||||
if (size != sizeof(buf))
|
||||
printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: "
|
||||
"return size differs: %d != %zu\n", size, sizeof(buf));
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
|
||||
"usb_interrupt_msg returned %d\n", retval);
|
||||
|
||||
if (retval >= 0)
|
||||
for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
|
||||
radio->registers[STATUSRSSI + regnr] =
|
||||
(radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
|
||||
radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
|
||||
be16_to_cpu(get_unaligned((unsigned short *)
|
||||
&buf[regnr * RADIO_REGISTER_SIZE + 1]));
|
||||
|
||||
return (retval < 0) ? -EINVAL : 0;
|
||||
}
|
||||
@ -543,9 +596,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
|
||||
/*
|
||||
* si470x_set_chan - set the channel
|
||||
*/
|
||||
static int si470x_set_chan(struct si470x_device *radio, int chan)
|
||||
static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
|
||||
{
|
||||
int retval, i;
|
||||
int retval;
|
||||
unsigned long timeout;
|
||||
bool timed_out = 0;
|
||||
|
||||
/* start tuning */
|
||||
radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
|
||||
@ -555,16 +610,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
|
||||
return retval;
|
||||
|
||||
/* wait till seek operation has completed */
|
||||
i = 0;
|
||||
timeout = jiffies + msecs_to_jiffies(tune_timeout);
|
||||
do {
|
||||
retval = si470x_get_register(radio, STATUSRSSI);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
} while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) &&
|
||||
(++i < seek_retries));
|
||||
if (i >= seek_retries)
|
||||
timed_out = time_after(jiffies, timeout);
|
||||
} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
|
||||
(!timed_out));
|
||||
if (timed_out)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": seek does not finish after %d tries\n", i);
|
||||
": seek does not finish after %u ms\n", tune_timeout);
|
||||
|
||||
/* stop tuning */
|
||||
radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
|
||||
@ -575,9 +631,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
|
||||
/*
|
||||
* si470x_get_freq - get the frequency
|
||||
*/
|
||||
static int si470x_get_freq(struct si470x_device *radio)
|
||||
static unsigned int si470x_get_freq(struct si470x_device *radio)
|
||||
{
|
||||
int spacing, band_bottom, chan, freq;
|
||||
unsigned int spacing, band_bottom, freq;
|
||||
unsigned short chan;
|
||||
int retval;
|
||||
|
||||
/* Spacing (kHz) */
|
||||
@ -616,9 +673,10 @@ static int si470x_get_freq(struct si470x_device *radio)
|
||||
/*
|
||||
* si470x_set_freq - set the frequency
|
||||
*/
|
||||
static int si470x_set_freq(struct si470x_device *radio, int freq)
|
||||
static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
|
||||
{
|
||||
int spacing, band_bottom, chan;
|
||||
unsigned int spacing, band_bottom;
|
||||
unsigned short chan;
|
||||
|
||||
/* Spacing (kHz) */
|
||||
switch (space) {
|
||||
@ -709,9 +767,17 @@ static int si470x_stop(struct si470x_device *radio)
|
||||
*/
|
||||
static int si470x_rds_on(struct si470x_device *radio)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/* sysconfig 1 */
|
||||
mutex_lock(&radio->lock);
|
||||
radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
|
||||
return si470x_set_register(radio, SYSCONFIG1);
|
||||
retval = si470x_set_register(radio, SYSCONFIG1);
|
||||
if (retval < 0)
|
||||
radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -725,11 +791,10 @@ static int si470x_rds_on(struct si470x_device *radio)
|
||||
*/
|
||||
static void si470x_rds(struct si470x_device *radio)
|
||||
{
|
||||
unsigned char tmpbuf[3];
|
||||
unsigned char blocknum;
|
||||
unsigned char bler; /* rds block errors */
|
||||
unsigned short bler; /* rds block errors */
|
||||
unsigned short rds;
|
||||
unsigned int i;
|
||||
unsigned char tmpbuf[3];
|
||||
|
||||
/* get rds blocks */
|
||||
if (si470x_get_rds_registers(radio) < 0)
|
||||
@ -743,63 +808,58 @@ static void si470x_rds(struct si470x_device *radio)
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy four RDS blocks to internal buffer */
|
||||
if (spin_trylock(&radio->lock)) {
|
||||
/* process each rds block */
|
||||
for (blocknum = 0; blocknum < 4; blocknum++) {
|
||||
switch (blocknum) {
|
||||
default:
|
||||
bler = (radio->registers[STATUSRSSI] &
|
||||
STATUSRSSI_BLERA) >> 9;
|
||||
rds = radio->registers[RDSA];
|
||||
break;
|
||||
case 1:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERB) >> 14;
|
||||
rds = radio->registers[RDSB];
|
||||
break;
|
||||
case 2:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERC) >> 12;
|
||||
rds = radio->registers[RDSC];
|
||||
break;
|
||||
case 3:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERD) >> 10;
|
||||
rds = radio->registers[RDSD];
|
||||
break;
|
||||
};
|
||||
/* copy all four RDS blocks to internal buffer */
|
||||
mutex_lock(&radio->lock);
|
||||
for (blocknum = 0; blocknum < 4; blocknum++) {
|
||||
switch (blocknum) {
|
||||
default:
|
||||
bler = (radio->registers[STATUSRSSI] &
|
||||
STATUSRSSI_BLERA) >> 9;
|
||||
rds = radio->registers[RDSA];
|
||||
break;
|
||||
case 1:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERB) >> 14;
|
||||
rds = radio->registers[RDSB];
|
||||
break;
|
||||
case 2:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERC) >> 12;
|
||||
rds = radio->registers[RDSC];
|
||||
break;
|
||||
case 3:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERD) >> 10;
|
||||
rds = radio->registers[RDSD];
|
||||
break;
|
||||
};
|
||||
|
||||
/* Fill the V4L2 RDS buffer */
|
||||
tmpbuf[0] = rds & 0x00ff; /* LSB */
|
||||
tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */
|
||||
tmpbuf[2] = blocknum; /* offset name */
|
||||
tmpbuf[2] |= blocknum << 3; /* received offset */
|
||||
if (bler > max_rds_errors)
|
||||
tmpbuf[2] |= 0x80; /* uncorrectable errors */
|
||||
else if (bler > 0)
|
||||
tmpbuf[2] |= 0x40; /* corrected error(s) */
|
||||
/* Fill the V4L2 RDS buffer */
|
||||
put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf);
|
||||
tmpbuf[2] = blocknum; /* offset name */
|
||||
tmpbuf[2] |= blocknum << 3; /* received offset */
|
||||
if (bler > max_rds_errors)
|
||||
tmpbuf[2] |= 0x80; /* uncorrectable errors */
|
||||
else if (bler > 0)
|
||||
tmpbuf[2] |= 0x40; /* corrected error(s) */
|
||||
|
||||
/* copy RDS block to internal buffer */
|
||||
for (i = 0; i < 3; i++) {
|
||||
radio->buffer[radio->wr_index] = tmpbuf[i];
|
||||
radio->wr_index++;
|
||||
}
|
||||
/* copy RDS block to internal buffer */
|
||||
memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
|
||||
radio->wr_index += 3;
|
||||
|
||||
/* wrap write pointer */
|
||||
if (radio->wr_index >= radio->buf_size)
|
||||
radio->wr_index = 0;
|
||||
/* wrap write pointer */
|
||||
if (radio->wr_index >= radio->buf_size)
|
||||
radio->wr_index = 0;
|
||||
|
||||
/* check for overflow */
|
||||
if (radio->wr_index == radio->rd_index) {
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
}
|
||||
/* check for overflow */
|
||||
if (radio->wr_index == radio->rd_index) {
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
}
|
||||
spin_unlock(&radio->lock);
|
||||
}
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
/* wake up read queue */
|
||||
if (radio->wr_index != radio->rd_index)
|
||||
@ -807,30 +867,19 @@ static void si470x_rds(struct si470x_device *radio)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_timer - rds timer function
|
||||
*/
|
||||
static void si470x_timer(unsigned long data)
|
||||
{
|
||||
struct si470x_device *radio = (struct si470x_device *) data;
|
||||
|
||||
schedule_work(&radio->work);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_work - rds work function
|
||||
*/
|
||||
static void si470x_work(struct work_struct *work)
|
||||
{
|
||||
struct si470x_device *radio = container_of(work, struct si470x_device,
|
||||
work);
|
||||
work.work);
|
||||
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
|
||||
return;
|
||||
|
||||
si470x_rds(radio);
|
||||
mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time));
|
||||
schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
|
||||
}
|
||||
|
||||
|
||||
@ -852,44 +901,44 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
|
||||
/* switch on rds reception */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
|
||||
si470x_rds_on(radio);
|
||||
schedule_work(&radio->work);
|
||||
schedule_delayed_work(&radio->work,
|
||||
msecs_to_jiffies(rds_poll_time));
|
||||
}
|
||||
|
||||
/* block if no new data available */
|
||||
while (radio->wr_index == radio->rd_index) {
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EWOULDBLOCK;
|
||||
interruptible_sleep_on(&radio->read_queue);
|
||||
if (wait_event_interruptible(radio->read_queue,
|
||||
radio->wr_index != radio->rd_index) < 0)
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
/* calculate block count from byte count */
|
||||
count /= 3;
|
||||
|
||||
/* copy RDS block out of internal buffer and to user buffer */
|
||||
if (spin_trylock(&radio->lock)) {
|
||||
while (block_count < count) {
|
||||
if (radio->rd_index == radio->wr_index)
|
||||
break;
|
||||
mutex_lock(&radio->lock);
|
||||
while (block_count < count) {
|
||||
if (radio->rd_index == radio->wr_index)
|
||||
break;
|
||||
|
||||
/* always transfer rds complete blocks */
|
||||
if (copy_to_user(buf,
|
||||
&radio->buffer[radio->rd_index], 3))
|
||||
/* retval = -EFAULT; */
|
||||
break;
|
||||
/* always transfer rds complete blocks */
|
||||
if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
|
||||
/* retval = -EFAULT; */
|
||||
break;
|
||||
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
|
||||
/* increment counters */
|
||||
block_count++;
|
||||
buf += 3;
|
||||
retval += 3;
|
||||
}
|
||||
|
||||
spin_unlock(&radio->lock);
|
||||
/* increment counters */
|
||||
block_count++;
|
||||
buf += 3;
|
||||
retval += 3;
|
||||
}
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -906,7 +955,8 @@ static unsigned int si470x_fops_poll(struct file *file,
|
||||
/* switch on rds reception */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
|
||||
si470x_rds_on(radio);
|
||||
schedule_work(&radio->work);
|
||||
schedule_delayed_work(&radio->work,
|
||||
msecs_to_jiffies(rds_poll_time));
|
||||
}
|
||||
|
||||
poll_wait(file, &radio->read_queue, pts);
|
||||
@ -924,10 +974,22 @@ static unsigned int si470x_fops_poll(struct file *file,
|
||||
static int si470x_fops_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
|
||||
int retval;
|
||||
|
||||
radio->users++;
|
||||
if (radio->users == 1)
|
||||
return si470x_start(radio);
|
||||
|
||||
retval = usb_autopm_get_interface(radio->intf);
|
||||
if (retval < 0) {
|
||||
radio->users--;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (radio->users == 1) {
|
||||
retval = si470x_start(radio);
|
||||
if (retval < 0)
|
||||
usb_autopm_put_interface(radio->intf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -939,6 +1001,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
|
||||
static int si470x_fops_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
|
||||
int retval;
|
||||
|
||||
if (!radio)
|
||||
return -ENODEV;
|
||||
@ -946,13 +1009,14 @@ static int si470x_fops_release(struct inode *inode, struct file *file)
|
||||
radio->users--;
|
||||
if (radio->users == 0) {
|
||||
/* stop rds reception */
|
||||
del_timer_sync(&radio->timer);
|
||||
flush_scheduled_work();
|
||||
cancel_delayed_work_sync(&radio->work);
|
||||
|
||||
/* cancel read processes */
|
||||
wake_up_interruptible(&radio->read_queue);
|
||||
|
||||
return si470x_stop(radio);
|
||||
retval = si470x_stop(radio);
|
||||
usb_autopm_put_interface(radio->intf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1030,7 +1094,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
|
||||
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
|
||||
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
|
||||
sprintf(capability->bus_info, "USB");
|
||||
capability->version = DRIVER_VERSION;
|
||||
capability->version = DRIVER_KERNEL_VERSION;
|
||||
capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
|
||||
|
||||
return 0;
|
||||
@ -1067,16 +1131,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
|
||||
static int si470x_vidioc_queryctrl(struct file *file, void *priv,
|
||||
struct v4l2_queryctrl *qc)
|
||||
{
|
||||
int i;
|
||||
unsigned char i;
|
||||
int retval = -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
|
||||
if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
|
||||
memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
|
||||
return 0;
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": query control failed with %d\n", retval);
|
||||
|
||||
return -EINVAL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -1110,21 +1179,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
|
||||
struct v4l2_control *ctrl)
|
||||
{
|
||||
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
|
||||
int retval;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
|
||||
radio->registers[SYSCONFIG2] |= ctrl->value;
|
||||
return si470x_set_register(radio, SYSCONFIG2);
|
||||
retval = si470x_set_register(radio, SYSCONFIG2);
|
||||
break;
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
if (ctrl->value == 1)
|
||||
radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
|
||||
else
|
||||
radio->registers[POWERCFG] |= POWERCFG_DMUTE;
|
||||
return si470x_set_register(radio, POWERCFG);
|
||||
retval = si470x_set_register(radio, POWERCFG);
|
||||
break;
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
}
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": set control failed with %d\n", retval);
|
||||
|
||||
return -EINVAL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -1163,8 +1240,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv,
|
||||
static int si470x_vidioc_g_tuner(struct file *file, void *priv,
|
||||
struct v4l2_tuner *tuner)
|
||||
{
|
||||
int retval;
|
||||
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
|
||||
int retval;
|
||||
|
||||
if (tuner->index > 0)
|
||||
return -EINVAL;
|
||||
@ -1220,6 +1297,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
|
||||
struct v4l2_tuner *tuner)
|
||||
{
|
||||
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
|
||||
int retval;
|
||||
|
||||
if (tuner->index > 0)
|
||||
return -EINVAL;
|
||||
@ -1229,7 +1307,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
|
||||
else
|
||||
radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
|
||||
|
||||
return si470x_set_register(radio, POWERCFG);
|
||||
retval = si470x_set_register(radio, POWERCFG);
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": set tuner failed with %d\n", retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -1255,11 +1338,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
|
||||
struct v4l2_frequency *freq)
|
||||
{
|
||||
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
|
||||
int retval;
|
||||
|
||||
if (freq->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
|
||||
return si470x_set_freq(radio, freq->frequency);
|
||||
retval = si470x_set_freq(radio, freq->frequency);
|
||||
if (retval < 0)
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": set frequency failed with %d\n", retval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1299,71 +1388,116 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct si470x_device *radio;
|
||||
int retval = -ENOMEM;
|
||||
|
||||
/* memory and interface allocations */
|
||||
radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL);
|
||||
/* private data allocation */
|
||||
radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
|
||||
if (!radio)
|
||||
return -ENOMEM;
|
||||
goto err_initial;
|
||||
|
||||
/* video device allocation */
|
||||
radio->videodev = video_device_alloc();
|
||||
if (!radio->videodev) {
|
||||
kfree(radio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!radio->videodev)
|
||||
goto err_radio;
|
||||
|
||||
/* initial configuration */
|
||||
memcpy(radio->videodev, &si470x_viddev_template,
|
||||
sizeof(si470x_viddev_template));
|
||||
radio->users = 0;
|
||||
radio->usbdev = interface_to_usbdev(intf);
|
||||
radio->intf = intf;
|
||||
mutex_init(&radio->lock);
|
||||
video_set_drvdata(radio->videodev, radio);
|
||||
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": Could not register video device\n");
|
||||
video_device_release(radio->videodev);
|
||||
kfree(radio);
|
||||
return -EIO;
|
||||
}
|
||||
usb_set_intfdata(intf, radio);
|
||||
|
||||
/* show some infos about the specific device */
|
||||
if (si470x_get_all_registers(radio) < 0) {
|
||||
video_device_release(radio->videodev);
|
||||
kfree(radio);
|
||||
return -EIO;
|
||||
}
|
||||
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n",
|
||||
retval = -EIO;
|
||||
if (si470x_get_all_registers(radio) < 0)
|
||||
goto err_all;
|
||||
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
|
||||
radio->registers[DEVICEID], radio->registers[CHIPID]);
|
||||
|
||||
/* check if firmware is current */
|
||||
if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
|
||||
< RADIO_SW_VERSION_CURRENT)
|
||||
< RADIO_SW_VERSION_CURRENT) {
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": This driver is known to work with chip version %d, "
|
||||
"but the device has firmware %d.\n"
|
||||
DRIVER_NAME
|
||||
"If you have some trouble using this driver, please "
|
||||
"report to V4L ML at video4linux-list@redhat.com\n",
|
||||
radio->registers[CHIPID] & CHIPID_FIRMWARE,
|
||||
RADIO_SW_VERSION_CURRENT);
|
||||
": This driver is known to work with "
|
||||
"firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": but the device has firmware version %hu.\n",
|
||||
radio->registers[CHIPID] & CHIPID_FIRMWARE);
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": If you have some trouble using this driver,\n");
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": please report to V4L ML at "
|
||||
"video4linux-list@redhat.com\n");
|
||||
}
|
||||
|
||||
/* set initial frequency */
|
||||
si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
|
||||
|
||||
/* rds initialization */
|
||||
/* rds buffer allocation */
|
||||
radio->buf_size = rds_buf * 3;
|
||||
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
|
||||
if (!radio->buffer) {
|
||||
video_device_release(radio->videodev);
|
||||
kfree(radio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!radio->buffer)
|
||||
goto err_all;
|
||||
|
||||
/* rds buffer configuration */
|
||||
radio->wr_index = 0;
|
||||
radio->rd_index = 0;
|
||||
init_waitqueue_head(&radio->read_queue);
|
||||
|
||||
/* prepare polling via eventd */
|
||||
INIT_WORK(&radio->work, si470x_work);
|
||||
init_timer(&radio->timer);
|
||||
radio->timer.function = si470x_timer;
|
||||
radio->timer.data = (unsigned long) radio;
|
||||
/* prepare rds work function */
|
||||
INIT_DELAYED_WORK(&radio->work, si470x_work);
|
||||
|
||||
/* register video device */
|
||||
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
|
||||
printk(KERN_WARNING DRIVER_NAME
|
||||
": Could not register video device\n");
|
||||
goto err_all;
|
||||
}
|
||||
usb_set_intfdata(intf, radio);
|
||||
|
||||
return 0;
|
||||
err_all:
|
||||
video_device_release(radio->videodev);
|
||||
kfree(radio->buffer);
|
||||
err_radio:
|
||||
kfree(radio);
|
||||
err_initial:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_usb_driver_suspend - suspend the device
|
||||
*/
|
||||
static int si470x_usb_driver_suspend(struct usb_interface *intf,
|
||||
pm_message_t message)
|
||||
{
|
||||
struct si470x_device *radio = usb_get_intfdata(intf);
|
||||
|
||||
printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
|
||||
|
||||
cancel_delayed_work_sync(&radio->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_usb_driver_resume - resume the device
|
||||
*/
|
||||
static int si470x_usb_driver_resume(struct usb_interface *intf)
|
||||
{
|
||||
struct si470x_device *radio = usb_get_intfdata(intf);
|
||||
|
||||
printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
|
||||
|
||||
mutex_lock(&radio->lock);
|
||||
if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
|
||||
schedule_delayed_work(&radio->work,
|
||||
msecs_to_jiffies(rds_poll_time));
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1376,15 +1510,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct si470x_device *radio = usb_get_intfdata(intf);
|
||||
|
||||
del_timer_sync(&radio->timer);
|
||||
flush_scheduled_work();
|
||||
|
||||
cancel_delayed_work_sync(&radio->work);
|
||||
usb_set_intfdata(intf, NULL);
|
||||
if (radio) {
|
||||
video_unregister_device(radio->videodev);
|
||||
kfree(radio->buffer);
|
||||
kfree(radio);
|
||||
}
|
||||
video_unregister_device(radio->videodev);
|
||||
kfree(radio->buffer);
|
||||
kfree(radio);
|
||||
}
|
||||
|
||||
|
||||
@ -1392,10 +1522,13 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
|
||||
* si470x_usb_driver - usb driver interface
|
||||
*/
|
||||
static struct usb_driver si470x_usb_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.probe = si470x_usb_driver_probe,
|
||||
.disconnect = si470x_usb_driver_disconnect,
|
||||
.id_table = si470x_usb_driver_id_table,
|
||||
.name = DRIVER_NAME,
|
||||
.probe = si470x_usb_driver_probe,
|
||||
.disconnect = si470x_usb_driver_disconnect,
|
||||
.suspend = si470x_usb_driver_suspend,
|
||||
.resume = si470x_usb_driver_resume,
|
||||
.id_table = si470x_usb_driver_id_table,
|
||||
.supports_autosuspend = 1,
|
||||
};
|
||||
|
||||
|
||||
@ -1409,7 +1542,7 @@ static struct usb_driver si470x_usb_driver = {
|
||||
*/
|
||||
static int __init si470x_module_init(void)
|
||||
{
|
||||
printk(KERN_INFO DRIVER_DESC "\n");
|
||||
printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
|
||||
return usb_register(&si470x_usb_driver);
|
||||
}
|
||||
|
||||
@ -1429,4 +1562,4 @@ module_exit(si470x_module_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_VERSION("1.0.4");
|
||||
MODULE_VERSION(DRIVER_VERSION);
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
menuconfig VIDEO_CAPTURE_DRIVERS
|
||||
bool "Video capture adapters"
|
||||
depends on VIDEO_DEV
|
||||
depends on VIDEO_V4L2
|
||||
default y
|
||||
---help---
|
||||
Say Y here to enable selecting the video adapters for
|
||||
webcams, analog TV, and hybrid analog/digital TV.
|
||||
Some of those devices also supports FM radio.
|
||||
|
||||
if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV
|
||||
if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
|
||||
|
||||
config VIDEO_ADV_DEBUG
|
||||
bool "Enable advanced debug functionality"
|
||||
|
@ -10,8 +10,9 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o
|
||||
|
||||
stkwebcam-objs := stk-webcam.o stk-sensor.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \
|
||||
v4l2-int-device.o
|
||||
obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
|
||||
|
||||
ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
|
||||
obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
|
||||
|
@ -2354,8 +2354,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
|
||||
BUG();
|
||||
}
|
||||
|
||||
mutex_lock(&fh->cap.lock);
|
||||
kfree(fh->ov.clips);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
kfree(fh->ov.clips);
|
||||
fh->ov.clips = clips;
|
||||
fh->ov.nclips = n;
|
||||
|
||||
@ -2376,7 +2376,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
|
||||
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
|
||||
retval = bttv_switch_overlay(btv,fh,new);
|
||||
}
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -2576,7 +2576,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
|
||||
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
||||
|
||||
/* update our state informations */
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
fh->fmt = fmt;
|
||||
fh->cap.field = f->fmt.pix.field;
|
||||
fh->cap.last = V4L2_FIELD_NONE;
|
||||
@ -2585,7 +2585,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
|
||||
btv->init.fmt = fmt;
|
||||
btv->init.width = f->fmt.pix.width;
|
||||
btv->init.height = f->fmt.pix.height;
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2611,11 +2611,11 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
|
||||
unsigned int i;
|
||||
struct bttv_fh *fh = priv;
|
||||
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
|
||||
V4L2_MEMORY_MMAP);
|
||||
if (retval < 0) {
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -2627,7 +2627,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
|
||||
for (i = 0; i < gbuffers; i++)
|
||||
mbuf->offsets[i] = i * gbufsize;
|
||||
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -2756,10 +2756,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
|
||||
if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY))
|
||||
return -EBUSY;
|
||||
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
if (on) {
|
||||
fh->ov.tvnorm = btv->tvnorm;
|
||||
new = videobuf_pci_alloc(sizeof(*new));
|
||||
new->crop = btv->crop[!!fh->do_crop].rect;
|
||||
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
|
||||
} else {
|
||||
new = NULL;
|
||||
@ -2767,7 +2768,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
|
||||
|
||||
/* switch over */
|
||||
retval = bttv_switch_overlay(btv, fh, new);
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -2806,7 +2807,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
|
||||
}
|
||||
|
||||
/* ok, accept it */
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
btv->fbuf.base = fb->base;
|
||||
btv->fbuf.fmt.width = fb->fmt.width;
|
||||
btv->fbuf.fmt.height = fb->fmt.height;
|
||||
@ -2838,7 +2839,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
|
||||
retval = bttv_switch_overlay(btv, fh, new);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -3090,7 +3091,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
||||
|
||||
fh->do_crop = 1;
|
||||
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
|
||||
if (fh->width < c.min_scaled_width) {
|
||||
fh->width = c.min_scaled_width;
|
||||
@ -3108,7 +3109,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
||||
btv->init.height = c.max_scaled_height;
|
||||
}
|
||||
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3177,30 +3178,25 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
|
||||
buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
|
||||
} else {
|
||||
/* read() capture */
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
if (NULL == fh->cap.read_buf) {
|
||||
/* need to capture a new frame */
|
||||
if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) {
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
return POLLERR;
|
||||
}
|
||||
if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM))
|
||||
goto err;
|
||||
fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
|
||||
if (NULL == fh->cap.read_buf) {
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
return POLLERR;
|
||||
}
|
||||
if (NULL == fh->cap.read_buf)
|
||||
goto err;
|
||||
fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
|
||||
field = videobuf_next_field(&fh->cap);
|
||||
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
|
||||
kfree (fh->cap.read_buf);
|
||||
fh->cap.read_buf = NULL;
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
return POLLERR;
|
||||
goto err;
|
||||
}
|
||||
fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
|
||||
fh->cap.read_off = 0;
|
||||
}
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
buf = (struct bttv_buffer*)fh->cap.read_buf;
|
||||
}
|
||||
|
||||
@ -3209,6 +3205,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
|
||||
buf->vb.state == VIDEOBUF_ERROR)
|
||||
return POLLIN|POLLRDNORM;
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return POLLERR;
|
||||
}
|
||||
|
||||
static int bttv_open(struct inode *inode, struct file *file)
|
||||
|
@ -352,13 +352,13 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
|
||||
because vbi_fmt.end counts field lines times two. */
|
||||
end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
|
||||
|
||||
mutex_lock(&fh->vbi.lock);
|
||||
mutex_lock(&fh->vbi.vb_lock);
|
||||
|
||||
fh->vbi_fmt.fmt = frt->fmt.vbi;
|
||||
fh->vbi_fmt.tvnorm = tvnorm;
|
||||
fh->vbi_fmt.end = end;
|
||||
|
||||
mutex_unlock(&fh->vbi.lock);
|
||||
mutex_unlock(&fh->vbi.vb_lock);
|
||||
|
||||
rc = 0;
|
||||
|
||||
|
@ -609,13 +609,19 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
|
||||
struct cx88_core *core = drv->core;
|
||||
|
||||
/* Fail a request for hardware if the device is busy. */
|
||||
if (core->active_type_id != CX88_BOARD_NONE)
|
||||
if (core->active_type_id != CX88_BOARD_NONE &&
|
||||
core->active_type_id != drv->type_id)
|
||||
return -EBUSY;
|
||||
|
||||
if (drv->advise_acquire)
|
||||
{
|
||||
core->active_type_id = drv->type_id;
|
||||
drv->advise_acquire(drv);
|
||||
mutex_lock(&drv->core->lock);
|
||||
core->active_ref++;
|
||||
if (core->active_type_id == CX88_BOARD_NONE) {
|
||||
core->active_type_id = drv->type_id;
|
||||
drv->advise_acquire(drv);
|
||||
}
|
||||
mutex_unlock(&drv->core->lock);
|
||||
|
||||
mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
|
||||
}
|
||||
@ -628,12 +634,14 @@ static int cx8802_request_release(struct cx8802_driver *drv)
|
||||
{
|
||||
struct cx88_core *core = drv->core;
|
||||
|
||||
if (drv->advise_release)
|
||||
mutex_lock(&drv->core->lock);
|
||||
if (drv->advise_release && --core->active_ref == 0)
|
||||
{
|
||||
drv->advise_release(drv);
|
||||
core->active_type_id = CX88_BOARD_NONE;
|
||||
mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
|
||||
}
|
||||
mutex_unlock(&drv->core->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -336,6 +336,7 @@ struct cx88_core {
|
||||
/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
|
||||
struct cx8802_dev *dvbdev;
|
||||
enum cx88_board_type active_type_id;
|
||||
int active_ref;
|
||||
};
|
||||
|
||||
struct cx8800_dev;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <sound/driver.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
@ -270,8 +269,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
|
||||
dprintk("opening device and trying to acquire exclusive lock\n");
|
||||
|
||||
/* Sets volume, mute, etc */
|
||||
|
||||
dev->mute = 0;
|
||||
mutex_lock(&dev->lock);
|
||||
ret = em28xx_audio_analog_set(dev);
|
||||
mutex_unlock(&dev->lock);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
@ -303,7 +305,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
|
||||
dprintk("closing device\n");
|
||||
|
||||
dev->mute = 1;
|
||||
mutex_lock(&dev->lock);
|
||||
em28xx_audio_analog_set(dev);
|
||||
mutex_unlock(&dev->lock);
|
||||
|
||||
if (dev->adev->users == 0 && dev->adev->shutdown == 1) {
|
||||
dprintk("audio users: %d\n", dev->adev->users);
|
||||
|
@ -393,15 +393,15 @@ struct em28xx_board em28xx_boards[] = {
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_TELEVISION,
|
||||
.vmux = SAA7115_COMPOSITE2,
|
||||
.amux = 1,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
}, {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = SAA7115_COMPOSITE0,
|
||||
.amux = 1,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
}, {
|
||||
.type = EM28XX_VMUX_SVIDEO,
|
||||
.vmux = SAA7115_SVIDEO3,
|
||||
.amux = 1,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
} },
|
||||
},
|
||||
};
|
||||
@ -441,6 +441,8 @@ struct usb_device_id em28xx_id_table [] = {
|
||||
.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
|
||||
{ USB_DEVICE(0x2040, 0x6500),
|
||||
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
|
||||
{ USB_DEVICE(0x2040, 0x6502),
|
||||
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
|
||||
{ USB_DEVICE(0x2040, 0x6513),
|
||||
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
|
||||
{ USB_DEVICE(0x0ccd, 0x0042),
|
||||
|
@ -72,7 +72,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
|
||||
const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
|
||||
void *buff = NULL;
|
||||
u32 i;
|
||||
em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
|
||||
em28xx_coredbg("requested %i buffers with size %zi\n",
|
||||
count, imagesize);
|
||||
if (count > EM28XX_NUM_FRAMES)
|
||||
count = EM28XX_NUM_FRAMES;
|
||||
|
||||
@ -150,7 +151,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
|
||||
if (reg_debug){
|
||||
printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
|
||||
for (byte = 0; byte < len; byte++) {
|
||||
printk(" %02x", buf[byte]);
|
||||
printk(" %02x", (unsigned char)buf[byte]);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
@ -177,7 +178,8 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
|
||||
0x0000, reg, &val, 1, HZ);
|
||||
|
||||
if (reg_debug)
|
||||
printk(ret < 0 ? " failed!\n" : "%02x\n", val);
|
||||
printk(ret < 0 ? " failed!\n" :
|
||||
"%02x\n", (unsigned char) val);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -237,7 +239,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
|
||||
* sets only some bits (specified by bitmask) of a register, by first reading
|
||||
* the actual value
|
||||
*/
|
||||
int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
|
||||
static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
|
||||
u8 bitmask)
|
||||
{
|
||||
int oldval;
|
||||
@ -254,26 +256,31 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
|
||||
*/
|
||||
static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
|
||||
{
|
||||
int ret;
|
||||
int ret, i;
|
||||
u8 addr = reg & 0x7f;
|
||||
if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
|
||||
return ret;
|
||||
if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
|
||||
return ret;
|
||||
if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
|
||||
return ret;
|
||||
else if (((u8) ret) & 0x01) {
|
||||
em28xx_warn ("AC97 command still being executed: not handled properly!\n");
|
||||
|
||||
/* Wait up to 50 ms for AC97 command to complete */
|
||||
for (i = 0; i < 10; i++) {
|
||||
if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
|
||||
return ret;
|
||||
if (!((u8) ret) & 0x01)
|
||||
return 0;
|
||||
msleep(5);
|
||||
}
|
||||
em28xx_warn ("AC97 command still being executed: not handled properly!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int em28xx_set_audio_source(struct em28xx *dev)
|
||||
static int em28xx_set_audio_source(struct em28xx *dev)
|
||||
{
|
||||
static char *enable = "\x08\x08";
|
||||
static char *disable = "\x08\x88";
|
||||
char *video = enable, *line = disable;
|
||||
int ret, no_ac97;
|
||||
int ret;
|
||||
u8 input;
|
||||
|
||||
if (dev->is_em2800) {
|
||||
@ -293,11 +300,9 @@ int em28xx_set_audio_source(struct em28xx *dev)
|
||||
switch (dev->ctl_ainput) {
|
||||
case EM28XX_AMUX_VIDEO:
|
||||
input = EM28XX_AUDIO_SRC_TUNER;
|
||||
no_ac97 = 1;
|
||||
break;
|
||||
case EM28XX_AMUX_LINE_IN:
|
||||
input = EM28XX_AUDIO_SRC_LINE;
|
||||
no_ac97 = 1;
|
||||
break;
|
||||
case EM28XX_AMUX_AC97_VIDEO:
|
||||
input = EM28XX_AUDIO_SRC_LINE;
|
||||
@ -313,12 +318,11 @@ int em28xx_set_audio_source(struct em28xx *dev)
|
||||
ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
msleep(5);
|
||||
|
||||
if (no_ac97)
|
||||
return 0;
|
||||
|
||||
/* Sets AC97 mixer registers */
|
||||
|
||||
/* Sets AC97 mixer registers
|
||||
This is seems to be needed, even for non-ac97 configs
|
||||
*/
|
||||
ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -337,9 +341,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
|
||||
s[0] |= 0x1f - dev->volume;
|
||||
s[1] |= 0x1f - dev->volume;
|
||||
|
||||
if (dev->mute)
|
||||
s[1] |= 0x80;
|
||||
/* Mute */
|
||||
s[1] |= 0x80;
|
||||
ret = em28xx_write_ac97(dev, MASTER_AC97, s);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -357,6 +362,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
|
||||
/* Selects the proper audio input */
|
||||
ret = em28xx_set_audio_source(dev);
|
||||
|
||||
/* Unmute device */
|
||||
if (!dev->mute)
|
||||
s[1] &= ~0x80;
|
||||
ret = em28xx_write_ac97(dev, MASTER_AC97, s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
|
||||
@ -667,7 +677,7 @@ static void em28xx_isocIrq(struct urb *urb)
|
||||
continue;
|
||||
}
|
||||
if (urb->iso_frame_desc[i].actual_length >
|
||||
dev->max_pkt_size) {
|
||||
urb->iso_frame_desc[i].length) {
|
||||
em28xx_isocdbg("packet bigger than packet size");
|
||||
continue;
|
||||
}
|
||||
@ -713,8 +723,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
|
||||
for (i = 0; i < EM28XX_NUM_BUFS; i++) {
|
||||
if (dev->urb[i]) {
|
||||
usb_kill_urb(dev->urb[i]);
|
||||
if (dev->transfer_buffer[i]){
|
||||
usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
|
||||
if (dev->transfer_buffer[i]) {
|
||||
usb_buffer_free(dev->udev,
|
||||
dev->urb[i]->transfer_buffer_length,
|
||||
dev->transfer_buffer[i],
|
||||
dev->urb[i]->transfer_dma);
|
||||
}
|
||||
usb_free_urb(dev->urb[i]);
|
||||
}
|
||||
@ -732,7 +745,10 @@ int em28xx_init_isoc(struct em28xx *dev)
|
||||
{
|
||||
/* change interface to 3 which allows the biggest packet sizes */
|
||||
int i, errCode;
|
||||
const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
|
||||
int sb_size;
|
||||
|
||||
em28xx_set_alternate(dev);
|
||||
sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
|
||||
|
||||
/* reset streaming vars */
|
||||
dev->frame_current = NULL;
|
||||
@ -741,7 +757,7 @@ int em28xx_init_isoc(struct em28xx *dev)
|
||||
/* allocate urbs */
|
||||
for (i = 0; i < EM28XX_NUM_BUFS; i++) {
|
||||
struct urb *urb;
|
||||
int j, k;
|
||||
int j;
|
||||
/* allocate transfer buffer */
|
||||
urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
|
||||
if (!urb){
|
||||
@ -749,7 +765,9 @@ int em28xx_init_isoc(struct em28xx *dev)
|
||||
em28xx_uninit_isoc(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
|
||||
dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size,
|
||||
GFP_KERNEL,
|
||||
&urb->transfer_dma);
|
||||
if (!dev->transfer_buffer[i]) {
|
||||
em28xx_errdev
|
||||
("unable to allocate %i bytes for transfer buffer %i\n",
|
||||
@ -762,22 +780,22 @@ int em28xx_init_isoc(struct em28xx *dev)
|
||||
urb->dev = dev->udev;
|
||||
urb->context = dev;
|
||||
urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
|
||||
urb->transfer_flags = URB_ISO_ASAP;
|
||||
urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
|
||||
urb->interval = 1;
|
||||
urb->transfer_buffer = dev->transfer_buffer[i];
|
||||
urb->complete = em28xx_isocIrq;
|
||||
urb->number_of_packets = EM28XX_NUM_PACKETS;
|
||||
urb->transfer_buffer_length = sb_size;
|
||||
for (j = k = 0; j < EM28XX_NUM_PACKETS;
|
||||
j++, k += dev->max_pkt_size) {
|
||||
urb->iso_frame_desc[j].offset = k;
|
||||
urb->iso_frame_desc[j].length =
|
||||
dev->max_pkt_size;
|
||||
for (j = 0; j < EM28XX_NUM_PACKETS; j++) {
|
||||
urb->iso_frame_desc[j].offset = j * dev->max_pkt_size;
|
||||
urb->iso_frame_desc[j].length = dev->max_pkt_size;
|
||||
}
|
||||
dev->urb[i] = urb;
|
||||
}
|
||||
|
||||
/* submit urbs */
|
||||
em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n",
|
||||
EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size);
|
||||
for (i = 0; i < EM28XX_NUM_BUFS; i++) {
|
||||
errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
|
||||
if (errCode) {
|
||||
@ -794,22 +812,31 @@ int em28xx_init_isoc(struct em28xx *dev)
|
||||
int em28xx_set_alternate(struct em28xx *dev)
|
||||
{
|
||||
int errCode, prev_alt = dev->alt;
|
||||
dev->alt = alt;
|
||||
if (dev->alt == 0) {
|
||||
int i;
|
||||
for(i=0;i< dev->num_alt; i++)
|
||||
if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
|
||||
dev->alt=i;
|
||||
}
|
||||
int i;
|
||||
unsigned int min_pkt_size = dev->bytesperline+4;
|
||||
|
||||
/* When image size is bigger than a ceirtain value,
|
||||
the frame size should be increased, otherwise, only
|
||||
green screen will be received.
|
||||
*/
|
||||
if (dev->frame_size > 720*240*2)
|
||||
min_pkt_size *= 2;
|
||||
|
||||
for (i = 0; i < dev->num_alt; i++)
|
||||
if (dev->alt_max_pkt_size[i] >= min_pkt_size)
|
||||
break;
|
||||
dev->alt = i;
|
||||
|
||||
if (dev->alt != prev_alt) {
|
||||
em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
|
||||
min_pkt_size, dev->alt);
|
||||
dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
|
||||
em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
|
||||
dev->max_pkt_size);
|
||||
em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
|
||||
dev->alt, dev->max_pkt_size);
|
||||
errCode = usb_set_interface(dev->udev, 0, dev->alt);
|
||||
if (errCode < 0) {
|
||||
em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
|
||||
dev->alt, errCode);
|
||||
dev->alt, errCode);
|
||||
return errCode;
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index)
|
||||
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||
}
|
||||
|
||||
em28xx_set_audio_source(dev);
|
||||
em28xx_audio_analog_set(dev);
|
||||
}
|
||||
|
||||
/* Usage lock check functions */
|
||||
@ -830,6 +830,63 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
static int em28xx_reg_len(int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case AC97LSB_REG:
|
||||
case HSCALELOW_REG:
|
||||
case VSCALELOW_REG:
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int vidioc_g_register(struct file *file, void *priv,
|
||||
struct v4l2_register *reg)
|
||||
{
|
||||
struct em28xx_fh *fh = priv;
|
||||
struct em28xx *dev = fh->dev;
|
||||
int ret;
|
||||
|
||||
if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
|
||||
return -EINVAL;
|
||||
|
||||
if (em28xx_reg_len(reg->reg) == 1) {
|
||||
ret = em28xx_read_reg(dev, reg->reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
reg->val = ret;
|
||||
} else {
|
||||
u64 val = 0;
|
||||
ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
|
||||
reg->reg, (char *)&val, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
reg->val = cpu_to_le64((__u64)val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_register(struct file *file, void *priv,
|
||||
struct v4l2_register *reg)
|
||||
{
|
||||
struct em28xx_fh *fh = priv;
|
||||
struct em28xx *dev = fh->dev;
|
||||
u64 buf;
|
||||
|
||||
buf = le64_to_cpu((__u64)reg->val);
|
||||
|
||||
return em28xx_write_regs(dev, reg->reg, (char *)&buf,
|
||||
em28xx_reg_len(reg->reg));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int vidioc_cropcap(struct file *file, void *priv,
|
||||
struct v4l2_cropcap *cc)
|
||||
{
|
||||
@ -1295,8 +1352,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
||||
filp->private_data = fh;
|
||||
|
||||
if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
|
||||
em28xx_set_alternate(dev);
|
||||
|
||||
dev->width = norm_maxw(dev);
|
||||
dev->height = norm_maxh(dev);
|
||||
dev->frame_size = dev->width * dev->height * 2;
|
||||
@ -1305,6 +1360,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
||||
dev->hscale = 0;
|
||||
dev->vscale = 0;
|
||||
|
||||
em28xx_set_alternate(dev);
|
||||
em28xx_capture_start(dev, 1);
|
||||
em28xx_resolution_set(dev);
|
||||
|
||||
@ -1730,6 +1786,10 @@ static const struct video_device em28xx_video_template = {
|
||||
.vidioc_s_tuner = vidioc_s_tuner,
|
||||
.vidioc_g_frequency = vidioc_g_frequency,
|
||||
.vidioc_s_frequency = vidioc_s_frequency,
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
.vidioc_g_register = vidioc_g_register,
|
||||
.vidioc_s_register = vidioc_s_register,
|
||||
#endif
|
||||
|
||||
.tvnorms = V4L2_STD_ALL,
|
||||
.current_norm = V4L2_STD_PAL,
|
||||
@ -1752,6 +1812,10 @@ static struct video_device em28xx_radio_template = {
|
||||
.vidioc_s_ctrl = vidioc_s_ctrl,
|
||||
.vidioc_g_frequency = vidioc_g_frequency,
|
||||
.vidioc_s_frequency = vidioc_s_frequency,
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
.vidioc_g_register = vidioc_g_register,
|
||||
.vidioc_s_register = vidioc_s_register,
|
||||
#endif
|
||||
};
|
||||
|
||||
/******************************** usb interface *****************************************/
|
||||
@ -1796,10 +1860,10 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
|
||||
}
|
||||
EXPORT_SYMBOL(em28xx_unregister_extension);
|
||||
|
||||
struct video_device *em28xx_vdev_init(struct em28xx *dev,
|
||||
const struct video_device *template,
|
||||
const int type,
|
||||
const char *type_name)
|
||||
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
|
||||
const struct video_device *template,
|
||||
const int type,
|
||||
const char *type_name)
|
||||
{
|
||||
struct video_device *vfd;
|
||||
|
||||
@ -2064,6 +2128,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
|
||||
snprintf(dev->name, 29, "em28xx #%d", nr);
|
||||
dev->devno = nr;
|
||||
dev->model = id->driver_info;
|
||||
dev->alt = -1;
|
||||
|
||||
/* Checks if audio is provided by some interface */
|
||||
for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
|
||||
|
@ -33,7 +33,7 @@
|
||||
#define UNSET -1
|
||||
|
||||
/* maximum number of em28xx boards */
|
||||
#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
|
||||
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
|
||||
|
||||
/* maximum number of frames that can be queued */
|
||||
#define EM28XX_NUM_FRAMES 5
|
||||
@ -345,9 +345,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg);
|
||||
int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
|
||||
int len);
|
||||
int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
|
||||
int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
|
||||
u8 bitmask);
|
||||
int em28xx_set_audio_source(struct em28xx *dev);
|
||||
int em28xx_audio_analog_set(struct em28xx *dev);
|
||||
|
||||
int em28xx_colorlevels_set_default(struct em28xx *dev);
|
||||
|
@ -928,27 +928,38 @@ struct saa7134_board saa7134_boards[] = {
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.tda9887_conf = TDA9887_PRESENT,
|
||||
.gpiomask = 0x03,
|
||||
.inputs = {{
|
||||
.name = name_tv,
|
||||
.vmux = 1,
|
||||
.amux = TV,
|
||||
.tv = 1,
|
||||
},{
|
||||
.gpio = 0x00,
|
||||
}, {
|
||||
.name = name_comp1,
|
||||
.vmux = 0,
|
||||
.amux = LINE2,
|
||||
},{
|
||||
.name = name_comp2,
|
||||
.vmux = 3,
|
||||
.amux = LINE2,
|
||||
},{
|
||||
.amux = LINE1,
|
||||
.gpio = 0x02,
|
||||
}, {
|
||||
.name = name_comp2,
|
||||
.vmux = 0,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x02,
|
||||
}, {
|
||||
.name = name_svideo,
|
||||
.vmux = 8,
|
||||
.amux = LINE2,
|
||||
}},
|
||||
.amux = LINE1,
|
||||
.gpio = 0x02,
|
||||
} },
|
||||
.radio = {
|
||||
.name = name_radio,
|
||||
.amux = LINE2,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x01,
|
||||
},
|
||||
.mute = {
|
||||
.name = name_mute,
|
||||
.amux = TV,
|
||||
.gpio = 0x00,
|
||||
},
|
||||
},
|
||||
[SAA7134_BOARD_BMK_MPEX_TUNER] = {
|
||||
@ -3912,6 +3923,74 @@ struct saa7134_board saa7134_boards[] = {
|
||||
},
|
||||
.mpeg = SAA7134_MPEG_EMPRESS,
|
||||
},
|
||||
[SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = {
|
||||
.name = "Twinhan Hybrid DTV-DVB 3056 PCI",
|
||||
.audio_clock = 0x00187de7,
|
||||
.tuner_type = TUNER_PHILIPS_TDA8290,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.tuner_config = 2,
|
||||
.mpeg = SAA7134_MPEG_DVB,
|
||||
.gpiomask = 0x0200000,
|
||||
.inputs = {{
|
||||
.name = name_tv,
|
||||
.vmux = 1,
|
||||
.amux = TV,
|
||||
.tv = 1,
|
||||
}, {
|
||||
.name = name_comp1,
|
||||
.vmux = 3,
|
||||
.amux = LINE1,
|
||||
}, {
|
||||
.name = name_svideo,
|
||||
.vmux = 8, /* untested */
|
||||
.amux = LINE1,
|
||||
} },
|
||||
.radio = {
|
||||
.name = name_radio,
|
||||
.amux = TV,
|
||||
.gpio = 0x0200000,
|
||||
},
|
||||
},
|
||||
[SAA7134_BOARD_GENIUS_TVGO_A11MCE] = {
|
||||
/* Adrian Pardini <pardo.bsso@gmail.com> */
|
||||
.name = "Genius TVGO AM11MCE",
|
||||
.audio_clock = 0x00200000,
|
||||
.tuner_type = TUNER_TNF_5335MF,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.gpiomask = 0xf000,
|
||||
.inputs = {{
|
||||
.name = name_tv_mono,
|
||||
.vmux = 1,
|
||||
.amux = LINE2,
|
||||
.gpio = 0x0000,
|
||||
.tv = 1,
|
||||
}, {
|
||||
.name = name_comp1,
|
||||
.vmux = 3,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x2000,
|
||||
.tv = 1
|
||||
}, {
|
||||
.name = name_svideo,
|
||||
.vmux = 8,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x2000,
|
||||
} },
|
||||
.radio = {
|
||||
.name = name_radio,
|
||||
.amux = LINE2,
|
||||
.gpio = 0x1000,
|
||||
},
|
||||
.mute = {
|
||||
.name = name_mute,
|
||||
.amux = LINE2,
|
||||
.gpio = 0x6000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
|
||||
@ -4509,6 +4588,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
|
||||
.subdevice = 0x3502, /* whats the difference to 0x3306 ?*/
|
||||
.driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
|
||||
},{
|
||||
.vendor = PCI_VENDOR_ID_PHILIPS,
|
||||
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
|
||||
.subvendor = 0x5168,
|
||||
.subdevice = 0x3307, /* FlyDVB-T Hybrid Mini PCI */
|
||||
.driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
|
||||
}, {
|
||||
.vendor = PCI_VENDOR_ID_PHILIPS,
|
||||
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
|
||||
.subvendor = 0x16be,
|
||||
@ -4521,6 +4606,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
|
||||
.subdevice = 0x0008,
|
||||
.driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
|
||||
},{
|
||||
.vendor = PCI_VENDOR_ID_PHILIPS,
|
||||
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
|
||||
.subvendor = 0x16be,
|
||||
.subdevice = 0x000d, /* triple CTX948_V1.1.1 */
|
||||
.driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
|
||||
}, {
|
||||
.vendor = PCI_VENDOR_ID_PHILIPS,
|
||||
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
|
||||
.subvendor = 0x1461,
|
||||
@ -4843,7 +4934,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
|
||||
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
|
||||
.subvendor = 0x4e42,
|
||||
.subdevice = 0x3502,
|
||||
.driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS
|
||||
.driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
|
||||
}, {
|
||||
.vendor = PCI_VENDOR_ID_PHILIPS,
|
||||
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
|
||||
.subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/
|
||||
.subdevice = 0x0022,
|
||||
.driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
|
||||
},{
|
||||
/* --- boards without eeprom + subsystem ID --- */
|
||||
.vendor = PCI_VENDOR_ID_PHILIPS,
|
||||
@ -4995,6 +5092,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
|
||||
case SAA7134_BOARD_BEHOLD_409:
|
||||
case SAA7134_BOARD_BEHOLD_505FM:
|
||||
case SAA7134_BOARD_BEHOLD_507_9FM:
|
||||
case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
|
||||
dev->has_remote = SAA7134_REMOTE_GPIO;
|
||||
break;
|
||||
case SAA7134_BOARD_FLYDVBS_LR300:
|
||||
@ -5232,7 +5330,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
||||
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
|
||||
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
|
||||
case SAA7134_BOARD_MEDION_MD8800_QUADRO:
|
||||
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
|
||||
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
|
||||
case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
|
||||
/* this is a hybrid board, initialize to analog mode
|
||||
* and configure firmware eeprom address
|
||||
*/
|
||||
|
@ -779,6 +779,21 @@ static struct tda1004x_config avermedia_super_007_config = {
|
||||
.request_firmware = philips_tda1004x_request_firmware
|
||||
};
|
||||
|
||||
static struct tda1004x_config twinhan_dtv_dvb_3056_config = {
|
||||
.demod_address = 0x08,
|
||||
.invert = 1,
|
||||
.invert_oclk = 0,
|
||||
.xtal_freq = TDA10046_XTAL_16M,
|
||||
.agc_config = TDA10046_AGC_TDA827X,
|
||||
.gpio_config = TDA10046_GP01_I,
|
||||
.if_freq = TDA10046_FREQ_045,
|
||||
.i2c_gate = 0x42,
|
||||
.tuner_address = 0x61,
|
||||
.tuner_config = 2,
|
||||
.antenna_switch = 1,
|
||||
.request_firmware = philips_tda1004x_request_firmware
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* special case: this card uses saa713x GPIO22 for the mode switch
|
||||
*/
|
||||
@ -826,6 +841,7 @@ static struct tda1004x_config ads_tech_duo_config = {
|
||||
static struct tda10086_config flydvbs = {
|
||||
.demod_address = 0x0e,
|
||||
.invert = 0,
|
||||
.diseqc_tone = 0,
|
||||
};
|
||||
|
||||
/* ==================================================================
|
||||
@ -940,9 +956,9 @@ static int dvb_init(struct saa7134_dev *dev)
|
||||
configure_tda827x_fe(dev, &tda827x_lifeview_config);
|
||||
break;
|
||||
case SAA7134_BOARD_FLYDVB_TRIO:
|
||||
if(! use_frontend) { //terrestrial
|
||||
if(! use_frontend) { /* terrestrial */
|
||||
configure_tda827x_fe(dev, &lifeview_trio_config);
|
||||
} else { //satellite
|
||||
} else { /* satellite */
|
||||
dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
|
||||
if (dev->dvb.frontend) {
|
||||
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
|
||||
@ -1007,8 +1023,9 @@ static int dvb_init(struct saa7134_dev *dev)
|
||||
}
|
||||
break;
|
||||
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
|
||||
dev->dvb.frontend = tda10046_attach(&medion_cardbus,
|
||||
&dev->i2c_adap);
|
||||
dev->dvb.frontend = dvb_attach(tda10046_attach,
|
||||
&medion_cardbus,
|
||||
&dev->i2c_adap);
|
||||
if (dev->dvb.frontend) {
|
||||
dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
|
||||
dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
|
||||
@ -1044,6 +1061,9 @@ static int dvb_init(struct saa7134_dev *dev)
|
||||
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
|
||||
configure_tda827x_fe(dev, &avermedia_super_007_config);
|
||||
break;
|
||||
case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
|
||||
configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config);
|
||||
break;
|
||||
default:
|
||||
wprintk("Huh? unknown DVB card?\n");
|
||||
break;
|
||||
|
@ -87,7 +87,7 @@ static int ts_open(struct inode *inode, struct file *file)
|
||||
|
||||
dprintk("open minor=%d\n",minor);
|
||||
err = -EBUSY;
|
||||
if (!mutex_trylock(&dev->empress_tsq.lock))
|
||||
if (!mutex_trylock(&dev->empress_tsq.vb_lock))
|
||||
goto done;
|
||||
if (dev->empress_users)
|
||||
goto done_up;
|
||||
@ -101,7 +101,7 @@ static int ts_open(struct inode *inode, struct file *file)
|
||||
err = 0;
|
||||
|
||||
done_up:
|
||||
mutex_unlock(&dev->empress_tsq.lock);
|
||||
mutex_unlock(&dev->empress_tsq.vb_lock);
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
@ -110,7 +110,6 @@ static int ts_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct saa7134_dev *dev = file->private_data;
|
||||
|
||||
mutex_lock(&dev->empress_tsq.lock);
|
||||
videobuf_stop(&dev->empress_tsq);
|
||||
videobuf_mmap_free(&dev->empress_tsq);
|
||||
dev->empress_users--;
|
||||
@ -122,7 +121,6 @@ static int ts_release(struct inode *inode, struct file *file)
|
||||
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
|
||||
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
|
||||
|
||||
mutex_unlock(&dev->empress_tsq.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -406,6 +406,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
|
||||
mask_keyup = 0x8000000;
|
||||
polling = 50; //ms
|
||||
break;
|
||||
case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
|
||||
ir_codes = ir_codes_genius_tvgo_a11mce;
|
||||
mask_keycode = 0xff;
|
||||
mask_keydown = 0xf00000;
|
||||
polling = 50; /* ms */
|
||||
break;
|
||||
}
|
||||
if (NULL == ir_codes) {
|
||||
printk("%s: Oops: IR config error [card=%d]\n",
|
||||
|
@ -1414,21 +1414,17 @@ video_poll(struct file *file, struct poll_table_struct *wait)
|
||||
if (!list_empty(&fh->cap.stream))
|
||||
buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
|
||||
} else {
|
||||
mutex_lock(&fh->cap.lock);
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
if (UNSET == fh->cap.read_off) {
|
||||
/* need to capture a new frame */
|
||||
if (res_locked(fh->dev,RESOURCE_VIDEO)) {
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
return POLLERR;
|
||||
}
|
||||
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
return POLLERR;
|
||||
}
|
||||
if (res_locked(fh->dev,RESOURCE_VIDEO))
|
||||
goto err;
|
||||
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field))
|
||||
goto err;
|
||||
fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
|
||||
fh->cap.read_off = 0;
|
||||
}
|
||||
mutex_unlock(&fh->cap.lock);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
buf = fh->cap.read_buf;
|
||||
}
|
||||
|
||||
@ -1440,6 +1436,10 @@ video_poll(struct file *file, struct poll_table_struct *wait)
|
||||
buf->state == VIDEOBUF_ERROR)
|
||||
return POLLIN|POLLRDNORM;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return POLLERR;
|
||||
}
|
||||
|
||||
static int video_release(struct inode *inode, struct file *file)
|
||||
|
@ -252,6 +252,8 @@ struct saa7134_format {
|
||||
#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
|
||||
#define SAA7134_BOARD_BEHOLD_607_9FM 129
|
||||
#define SAA7134_BOARD_BEHOLD_M6 130
|
||||
#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
|
||||
#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
|
||||
|
||||
#define SAA7134_MAXBOARDS 8
|
||||
#define SAA7134_INPUT_MAX 8
|
||||
|
@ -225,7 +225,7 @@
|
||||
|
||||
|
||||
/* Returns 0 if OK */
|
||||
int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
|
||||
static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
|
||||
{
|
||||
int i = 0;
|
||||
int tmpval = 0;
|
||||
@ -250,7 +250,7 @@ int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
|
||||
static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
|
||||
{
|
||||
int i = 0;
|
||||
int tmpval = 0;
|
||||
@ -380,7 +380,7 @@ int stk_sensor_init(struct stk_camera *dev)
|
||||
STK_ERROR("Strange error reading sensor ID\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (idh != 0x7F || idl != 0xA2) {
|
||||
if (idh != 0x7f || idl != 0xa2) {
|
||||
STK_ERROR("Huh? you don't have a sensor from ovt\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
@ -409,6 +409,19 @@ static struct regval ov_fmt_uyvy[] = {
|
||||
{REG_COM15, COM15_R00FF },
|
||||
{0xff, 0xff}, /* END MARKER */
|
||||
};
|
||||
/* V4L2_PIX_FMT_YUYV */
|
||||
static struct regval ov_fmt_yuyv[] = {
|
||||
{REG_TSLB, 0 },
|
||||
{ 0x4f, 0x80 }, /* "matrix coefficient 1" */
|
||||
{ 0x50, 0x80 }, /* "matrix coefficient 2" */
|
||||
{ 0x51, 0 }, /* vb */
|
||||
{ 0x52, 0x22 }, /* "matrix coefficient 4" */
|
||||
{ 0x53, 0x5e }, /* "matrix coefficient 5" */
|
||||
{ 0x54, 0x80 }, /* "matrix coefficient 6" */
|
||||
{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
|
||||
{REG_COM15, COM15_R00FF },
|
||||
{0xff, 0xff}, /* END MARKER */
|
||||
};
|
||||
|
||||
/* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */
|
||||
static struct regval ov_fmt_rgbr[] = {
|
||||
@ -519,6 +532,10 @@ int stk_sensor_configure(struct stk_camera *dev)
|
||||
com7 |= COM7_YUV;
|
||||
rv = ov_fmt_uyvy;
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
com7 |= COM7_YUV;
|
||||
rv = ov_fmt_yuyv;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB565:
|
||||
com7 |= COM7_RGB;
|
||||
rv = ov_fmt_rgbp;
|
||||
|
@ -63,7 +63,7 @@ static struct usb_device_id stkwebcam_table[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, stkwebcam_table);
|
||||
|
||||
void stk_camera_cleanup(struct kref *kref)
|
||||
static void stk_camera_cleanup(struct kref *kref)
|
||||
{
|
||||
struct stk_camera *dev = to_stk_camera(kref);
|
||||
|
||||
@ -682,6 +682,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
|
||||
return -ENXIO;
|
||||
fp->private_data = vdev;
|
||||
kref_get(&dev->kref);
|
||||
usb_autopm_get_interface(dev->interface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -703,6 +704,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
|
||||
}
|
||||
|
||||
if (dev->owner != fp) {
|
||||
usb_autopm_put_interface(dev->interface);
|
||||
kref_put(&dev->kref, stk_camera_cleanup);
|
||||
return 0;
|
||||
}
|
||||
@ -713,6 +715,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
|
||||
|
||||
dev->owner = NULL;
|
||||
|
||||
usb_autopm_put_interface(dev->interface);
|
||||
kref_put(&dev->kref, stk_camera_cleanup);
|
||||
|
||||
return 0;
|
||||
@ -993,6 +996,10 @@ static int stk_vidioc_enum_fmt_cap(struct file *filp,
|
||||
fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
|
||||
strcpy(fmtd->description, "Raw bayer");
|
||||
break;
|
||||
case 4:
|
||||
fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
strcpy(fmtd->description, "yuv4:2:2");
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1048,6 +1055,7 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
|
||||
case V4L2_PIX_FMT_RGB565:
|
||||
case V4L2_PIX_FMT_RGB565X:
|
||||
case V4L2_PIX_FMT_UYVY:
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
case V4L2_PIX_FMT_SBGGR8:
|
||||
break;
|
||||
default:
|
||||
@ -1080,6 +1088,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stk_setup_format(struct stk_camera *dev)
|
||||
{
|
||||
int i = 0;
|
||||
int depth;
|
||||
if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
|
||||
depth = 1;
|
||||
else
|
||||
depth = 2;
|
||||
while (stk_sizes[i].m != dev->vsettings.mode
|
||||
&& i < ARRAY_SIZE(stk_sizes))
|
||||
i++;
|
||||
if (i == ARRAY_SIZE(stk_sizes)) {
|
||||
STK_ERROR("Something is broken in %s\n", __FUNCTION__);
|
||||
return -EFAULT;
|
||||
}
|
||||
/* This registers controls some timings, not sure of what. */
|
||||
stk_camera_write_reg(dev, 0x001b, 0x0e);
|
||||
if (dev->vsettings.mode == MODE_SXGA)
|
||||
stk_camera_write_reg(dev, 0x001c, 0x0e);
|
||||
else
|
||||
stk_camera_write_reg(dev, 0x001c, 0x46);
|
||||
/*
|
||||
* Registers 0x0115 0x0114 are the size of each line (bytes),
|
||||
* regs 0x0117 0x0116 are the heigth of the image.
|
||||
*/
|
||||
stk_camera_write_reg(dev, 0x0115,
|
||||
((stk_sizes[i].w * depth) >> 8) & 0xff);
|
||||
stk_camera_write_reg(dev, 0x0114,
|
||||
(stk_sizes[i].w * depth) & 0xff);
|
||||
stk_camera_write_reg(dev, 0x0117,
|
||||
(stk_sizes[i].h >> 8) & 0xff);
|
||||
stk_camera_write_reg(dev, 0x0116,
|
||||
stk_sizes[i].h & 0xff);
|
||||
return stk_sensor_configure(dev);
|
||||
}
|
||||
|
||||
static int stk_vidioc_s_fmt_cap(struct file *filp,
|
||||
void *priv, struct v4l2_format *fmtd)
|
||||
{
|
||||
@ -1094,10 +1138,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
|
||||
return -EBUSY;
|
||||
if (dev->owner && dev->owner != filp)
|
||||
return -EBUSY;
|
||||
dev->owner = filp;
|
||||
ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
dev->owner = filp;
|
||||
|
||||
dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
|
||||
stk_free_buffers(dev);
|
||||
@ -1105,25 +1149,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
|
||||
dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
|
||||
|
||||
stk_initialise(dev);
|
||||
/* This registers controls some timings, not sure of what. */
|
||||
stk_camera_write_reg(dev, 0x001b, 0x0e);
|
||||
if (dev->vsettings.mode == MODE_SXGA)
|
||||
stk_camera_write_reg(dev, 0x001c, 0x0e);
|
||||
else
|
||||
stk_camera_write_reg(dev, 0x001c, 0x46);
|
||||
/*
|
||||
* Registers 0x0115 0x0114 are the size of each line (bytes),
|
||||
* regs 0x0117 0x0116 are the heigth of the image.
|
||||
*/
|
||||
stk_camera_write_reg(dev, 0x0115,
|
||||
(fmtd->fmt.pix.bytesperline >> 8) & 0xff);
|
||||
stk_camera_write_reg(dev, 0x0114,
|
||||
fmtd->fmt.pix.bytesperline & 0xff);
|
||||
stk_camera_write_reg(dev, 0x0117,
|
||||
(fmtd->fmt.pix.height >> 8) & 0xff);
|
||||
stk_camera_write_reg(dev, 0x0116,
|
||||
fmtd->fmt.pix.height & 0xff);
|
||||
return stk_sensor_configure(dev);
|
||||
return stk_setup_format(dev);
|
||||
}
|
||||
|
||||
static int stk_vidioc_reqbufs(struct file *filp,
|
||||
@ -1288,6 +1314,9 @@ static struct file_operations v4l_stk_fops = {
|
||||
.poll = v4l_stk_poll,
|
||||
.mmap = v4l_stk_mmap,
|
||||
.ioctl = video_ioctl2,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = v4l_compat_ioctl32,
|
||||
#endif
|
||||
.llseek = no_llseek
|
||||
};
|
||||
|
||||
@ -1403,7 +1432,7 @@ static int stk_camera_probe(struct usb_interface *interface,
|
||||
dev->vsettings.brightness = 0x7fff;
|
||||
dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
|
||||
dev->vsettings.mode = MODE_VGA;
|
||||
dev->frame_size = 640*480*2;
|
||||
dev->frame_size = 640 * 480 * 2;
|
||||
|
||||
INIT_LIST_HEAD(&dev->sio_avail);
|
||||
INIT_LIST_HEAD(&dev->sio_full);
|
||||
@ -1417,6 +1446,7 @@ static int stk_camera_probe(struct usb_interface *interface,
|
||||
}
|
||||
|
||||
stk_create_sysfs_files(&dev->vdev);
|
||||
usb_autopm_enable(dev->interface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1434,11 +1464,41 @@ static void stk_camera_disconnect(struct usb_interface *interface)
|
||||
kref_put(&dev->kref, stk_camera_cleanup);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
{
|
||||
struct stk_camera *dev = usb_get_intfdata(intf);
|
||||
if (is_streaming(dev)) {
|
||||
stk_stop_stream(dev);
|
||||
/* yes, this is ugly */
|
||||
set_streaming(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stk_camera_resume(struct usb_interface *intf)
|
||||
{
|
||||
struct stk_camera *dev = usb_get_intfdata(intf);
|
||||
if (!is_initialised(dev))
|
||||
return 0;
|
||||
unset_initialised(dev);
|
||||
stk_initialise(dev);
|
||||
stk_setup_format(dev);
|
||||
if (is_streaming(dev))
|
||||
stk_start_stream(dev);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct usb_driver stk_camera_driver = {
|
||||
.name = "stkwebcam",
|
||||
.probe = stk_camera_probe,
|
||||
.disconnect = stk_camera_disconnect,
|
||||
.id_table = stkwebcam_table,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = stk_camera_suspend,
|
||||
.resume = stk_camera_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -79,6 +79,7 @@ enum stk_status {
|
||||
#define unset_present(dev) ((dev)->status &= \
|
||||
~(S_PRESENT|S_INITIALISED|S_STREAMING))
|
||||
#define set_initialised(dev) ((dev)->status |= S_INITIALISED)
|
||||
#define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED)
|
||||
#define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD)
|
||||
#define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD)
|
||||
#define set_streaming(dev) ((dev)->status |= S_STREAMING)
|
||||
@ -127,8 +128,6 @@ void stk_camera_delete(struct kref *);
|
||||
int stk_camera_write_reg(struct stk_camera *, u16, u8);
|
||||
int stk_camera_read_reg(struct stk_camera *, u16, int *);
|
||||
|
||||
int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val);
|
||||
int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val);
|
||||
int stk_sensor_init(struct stk_camera *);
|
||||
int stk_sensor_configure(struct stk_camera *);
|
||||
int stk_sensor_sleep(struct stk_camera *dev);
|
||||
|
@ -851,7 +851,7 @@ static int tcm825x_probe(struct i2c_client *client)
|
||||
sensor->platform_data = client->dev.platform_data;
|
||||
|
||||
if (sensor->platform_data == NULL
|
||||
&& !sensor->platform_data->is_okay())
|
||||
|| !sensor->platform_data->is_okay())
|
||||
return -ENODEV;
|
||||
|
||||
sensor->v4l2_int_device = &tcm825x_int_device;
|
||||
|
@ -1038,7 +1038,7 @@ static int tuner_resume(struct i2c_client *c)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
LIST_HEAD(tuner_list);
|
||||
static LIST_HEAD(tuner_list);
|
||||
|
||||
/* Search for existing radio and/or TV tuners on the given I2C adapter.
|
||||
Note that when this function is called from tuner_probe you can be
|
||||
|
@ -754,6 +754,9 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
|
||||
goto check_device;
|
||||
}
|
||||
|
||||
if (new_fw.type & FM)
|
||||
goto check_device;
|
||||
|
||||
/* Load SCODE firmware, if exists */
|
||||
tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
|
||||
|
||||
|
@ -1571,14 +1571,14 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
|
||||
ctrl->value=chip->muted;
|
||||
return 0;
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
if (!desc->flags & CHIP_HAS_VOLUME)
|
||||
if (!(desc->flags & CHIP_HAS_VOLUME))
|
||||
break;
|
||||
ctrl->value = max(chip->left,chip->right);
|
||||
return 0;
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
{
|
||||
int volume;
|
||||
if (!desc->flags & CHIP_HAS_VOLUME)
|
||||
if (!(desc->flags & CHIP_HAS_VOLUME))
|
||||
break;
|
||||
volume = max(chip->left,chip->right);
|
||||
if (volume)
|
||||
@ -1621,7 +1621,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
|
||||
{
|
||||
int volume,balance;
|
||||
|
||||
if (!desc->flags & CHIP_HAS_VOLUME)
|
||||
if (!(desc->flags & CHIP_HAS_VOLUME))
|
||||
break;
|
||||
|
||||
volume = max(chip->left,chip->right);
|
||||
@ -1642,7 +1642,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
{
|
||||
int volume, balance;
|
||||
if (!desc->flags & CHIP_HAS_VOLUME)
|
||||
if (!(desc->flags & CHIP_HAS_VOLUME))
|
||||
break;
|
||||
|
||||
volume = max(chip->left,chip->right);
|
||||
@ -1702,7 +1702,7 @@ static int chip_command(struct i2c_client *client,
|
||||
break;
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
if (!desc->flags & CHIP_HAS_VOLUME)
|
||||
if (!(desc->flags & CHIP_HAS_VOLUME))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case V4L2_CID_AUDIO_BASS:
|
||||
|
@ -242,7 +242,7 @@ hauppauge_tuner[] =
|
||||
{ TUNER_ABSENT, "TCL M2523_3DBH_E"},
|
||||
{ TUNER_ABSENT, "TCL M2523_3DIH_E"},
|
||||
{ TUNER_ABSENT, "TCL MFPE05_2_U"},
|
||||
{ TUNER_ABSENT, "Philips FMD1216MEX"},
|
||||
{ TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"},
|
||||
{ TUNER_ABSENT, "Philips FRH2036B"},
|
||||
{ TUNER_ABSENT, "Panasonic ENGF75_01GF"},
|
||||
{ TUNER_ABSENT, "MaxLinear MXL5005"},
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/div64.h>
|
||||
#include <linux/video_decoder.h>
|
||||
#define __OLD_VIDIOC_ /* To allow fixing old calls*/
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-chip-ident.h>
|
||||
@ -82,108 +81,6 @@ MODULE_LICENSE("GPL");
|
||||
*/
|
||||
|
||||
|
||||
char *v4l2_norm_to_name(v4l2_std_id id)
|
||||
{
|
||||
char *name;
|
||||
u32 myid = id;
|
||||
|
||||
/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
|
||||
64 bit comparations. So, on that architecture, with some gcc variants,
|
||||
compilation fails. Currently, the max value is 30bit wide.
|
||||
*/
|
||||
BUG_ON(myid != id);
|
||||
|
||||
switch (myid) {
|
||||
case V4L2_STD_PAL:
|
||||
name="PAL"; break;
|
||||
case V4L2_STD_PAL_BG:
|
||||
name="PAL-BG"; break;
|
||||
case V4L2_STD_PAL_DK:
|
||||
name="PAL-DK"; break;
|
||||
case V4L2_STD_PAL_B:
|
||||
name="PAL-B"; break;
|
||||
case V4L2_STD_PAL_B1:
|
||||
name="PAL-B1"; break;
|
||||
case V4L2_STD_PAL_G:
|
||||
name="PAL-G"; break;
|
||||
case V4L2_STD_PAL_H:
|
||||
name="PAL-H"; break;
|
||||
case V4L2_STD_PAL_I:
|
||||
name="PAL-I"; break;
|
||||
case V4L2_STD_PAL_D:
|
||||
name="PAL-D"; break;
|
||||
case V4L2_STD_PAL_D1:
|
||||
name="PAL-D1"; break;
|
||||
case V4L2_STD_PAL_K:
|
||||
name="PAL-K"; break;
|
||||
case V4L2_STD_PAL_M:
|
||||
name="PAL-M"; break;
|
||||
case V4L2_STD_PAL_N:
|
||||
name="PAL-N"; break;
|
||||
case V4L2_STD_PAL_Nc:
|
||||
name="PAL-Nc"; break;
|
||||
case V4L2_STD_PAL_60:
|
||||
name="PAL-60"; break;
|
||||
case V4L2_STD_NTSC:
|
||||
name="NTSC"; break;
|
||||
case V4L2_STD_NTSC_M:
|
||||
name="NTSC-M"; break;
|
||||
case V4L2_STD_NTSC_M_JP:
|
||||
name="NTSC-M-JP"; break;
|
||||
case V4L2_STD_NTSC_443:
|
||||
name="NTSC-443"; break;
|
||||
case V4L2_STD_NTSC_M_KR:
|
||||
name="NTSC-M-KR"; break;
|
||||
case V4L2_STD_SECAM:
|
||||
name="SECAM"; break;
|
||||
case V4L2_STD_SECAM_DK:
|
||||
name="SECAM-DK"; break;
|
||||
case V4L2_STD_SECAM_B:
|
||||
name="SECAM-B"; break;
|
||||
case V4L2_STD_SECAM_D:
|
||||
name="SECAM-D"; break;
|
||||
case V4L2_STD_SECAM_G:
|
||||
name="SECAM-G"; break;
|
||||
case V4L2_STD_SECAM_H:
|
||||
name="SECAM-H"; break;
|
||||
case V4L2_STD_SECAM_K:
|
||||
name="SECAM-K"; break;
|
||||
case V4L2_STD_SECAM_K1:
|
||||
name="SECAM-K1"; break;
|
||||
case V4L2_STD_SECAM_L:
|
||||
name="SECAM-L"; break;
|
||||
case V4L2_STD_SECAM_LC:
|
||||
name="SECAM-LC"; break;
|
||||
default:
|
||||
name="Unknown"; break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Fill in the fields of a v4l2_standard structure according to the
|
||||
'id' and 'transmission' parameters. Returns negative on error. */
|
||||
int v4l2_video_std_construct(struct v4l2_standard *vs,
|
||||
int id, char *name)
|
||||
{
|
||||
u32 index = vs->index;
|
||||
|
||||
memset(vs, 0, sizeof(struct v4l2_standard));
|
||||
vs->index = index;
|
||||
vs->id = id;
|
||||
if (id & V4L2_STD_525_60) {
|
||||
vs->frameperiod.numerator = 1001;
|
||||
vs->frameperiod.denominator = 30000;
|
||||
vs->framelines = 525;
|
||||
} else {
|
||||
vs->frameperiod.numerator = 1;
|
||||
vs->frameperiod.denominator = 25;
|
||||
vs->framelines = 625;
|
||||
}
|
||||
strlcpy(vs->name,name,sizeof(vs->name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* priority handling */
|
||||
|
||||
@ -196,6 +93,7 @@ int v4l2_prio_init(struct v4l2_prio_state *global)
|
||||
memset(global,0,sizeof(*global));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_prio_init);
|
||||
|
||||
int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
|
||||
enum v4l2_priority new)
|
||||
@ -211,11 +109,13 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
|
||||
*local = new;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_prio_change);
|
||||
|
||||
int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
|
||||
{
|
||||
return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_prio_open);
|
||||
|
||||
int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
|
||||
{
|
||||
@ -223,6 +123,7 @@ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
|
||||
atomic_dec(&global->prios[*local]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_prio_close);
|
||||
|
||||
enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
|
||||
{
|
||||
@ -234,6 +135,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
|
||||
return V4L2_PRIORITY_BACKGROUND;
|
||||
return V4L2_PRIORITY_UNSET;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_prio_max);
|
||||
|
||||
int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
|
||||
{
|
||||
@ -241,225 +143,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* some arrays for pretty-printing debug messages of enum types */
|
||||
|
||||
char *v4l2_field_names[] = {
|
||||
[V4L2_FIELD_ANY] = "any",
|
||||
[V4L2_FIELD_NONE] = "none",
|
||||
[V4L2_FIELD_TOP] = "top",
|
||||
[V4L2_FIELD_BOTTOM] = "bottom",
|
||||
[V4L2_FIELD_INTERLACED] = "interlaced",
|
||||
[V4L2_FIELD_SEQ_TB] = "seq-tb",
|
||||
[V4L2_FIELD_SEQ_BT] = "seq-bt",
|
||||
[V4L2_FIELD_ALTERNATE] = "alternate",
|
||||
[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
|
||||
[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
|
||||
};
|
||||
|
||||
char *v4l2_type_names[] = {
|
||||
[V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
|
||||
[V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
|
||||
[V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
|
||||
[V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
|
||||
[V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
|
||||
[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
|
||||
[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
|
||||
[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
|
||||
};
|
||||
|
||||
|
||||
#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* debug help functions */
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
static const char *v4l1_ioctls[] = {
|
||||
[_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
|
||||
[_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
|
||||
[_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
|
||||
[_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
|
||||
[_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
|
||||
[_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
|
||||
[_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
|
||||
[_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
|
||||
[_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
|
||||
[_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
|
||||
[_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
|
||||
[_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
|
||||
[_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
|
||||
[_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
|
||||
[_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
|
||||
[_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
|
||||
[_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
|
||||
[_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
|
||||
[_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
|
||||
[_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
|
||||
[_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
|
||||
[_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
|
||||
[_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
|
||||
[_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
|
||||
[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
|
||||
[_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
|
||||
[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
|
||||
[_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
|
||||
[_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
|
||||
};
|
||||
#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
|
||||
#endif
|
||||
|
||||
static const char *v4l2_ioctls[] = {
|
||||
[_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
|
||||
[_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
|
||||
[_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
|
||||
[_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
|
||||
[_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
|
||||
[_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
|
||||
[_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
|
||||
[_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
|
||||
[_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
|
||||
[_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
|
||||
[_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
|
||||
[_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
|
||||
[_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
|
||||
[_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
|
||||
[_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
|
||||
[_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
|
||||
[_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
|
||||
[_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
|
||||
[_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
|
||||
[_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
|
||||
[_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
|
||||
[_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
|
||||
[_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
|
||||
[_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
|
||||
[_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
|
||||
[_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
|
||||
[_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
|
||||
[_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
|
||||
[_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
|
||||
[_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
|
||||
[_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
|
||||
[_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
|
||||
[_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
|
||||
[_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
|
||||
[_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
|
||||
[_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
|
||||
[_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
|
||||
[_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
|
||||
[_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
|
||||
[_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
|
||||
[_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
|
||||
[_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
|
||||
[_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
|
||||
[_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
|
||||
[_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
|
||||
[_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
|
||||
[_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
|
||||
[_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
|
||||
[_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
|
||||
[_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
|
||||
[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
|
||||
[_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
|
||||
[_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
|
||||
[_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
|
||||
[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
|
||||
#if 1
|
||||
[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
|
||||
[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
|
||||
[_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
|
||||
[_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
|
||||
[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
|
||||
|
||||
[_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
|
||||
[_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
|
||||
|
||||
[_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
|
||||
#endif
|
||||
};
|
||||
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
|
||||
|
||||
static const char *v4l2_int_ioctls[] = {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
[_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
|
||||
[_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
|
||||
[_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
|
||||
[_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
|
||||
[_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
|
||||
[_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
|
||||
[_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
|
||||
[_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
|
||||
[_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
|
||||
[_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
|
||||
[_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
|
||||
#endif
|
||||
[_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
|
||||
|
||||
[_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
|
||||
[_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
|
||||
[_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
|
||||
|
||||
[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
|
||||
[_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
|
||||
[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
|
||||
[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
|
||||
[_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
|
||||
[_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
|
||||
[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
|
||||
[_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
|
||||
[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
|
||||
[_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
|
||||
[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
|
||||
[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
|
||||
};
|
||||
#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
|
||||
|
||||
|
||||
/* Common ioctl debug function. This function can be used by
|
||||
external ioctl messages as well as internal V4L ioctl */
|
||||
void v4l_printk_ioctl(unsigned int cmd)
|
||||
{
|
||||
char *dir;
|
||||
|
||||
switch (_IOC_DIR(cmd)) {
|
||||
case _IOC_NONE: dir = "--"; break;
|
||||
case _IOC_READ: dir = "r-"; break;
|
||||
case _IOC_WRITE: dir = "-w"; break;
|
||||
case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
|
||||
default: dir = "*ERR*"; break;
|
||||
}
|
||||
switch (_IOC_TYPE(cmd)) {
|
||||
case 'd':
|
||||
printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
|
||||
v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case 'v':
|
||||
printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L1_IOCTLS) ?
|
||||
v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
#endif
|
||||
case 'V':
|
||||
printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L2_IOCTLS) ?
|
||||
v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
|
||||
_IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(v4l2_prio_check);
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
@ -488,6 +172,7 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_check);
|
||||
|
||||
/* Returns NULL or a character pointer array containing the menu for
|
||||
the given control ID. The pointer array ends with a NULL pointer.
|
||||
@ -648,6 +333,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_get_menu);
|
||||
|
||||
/* Fill in a struct v4l2_queryctrl */
|
||||
int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
|
||||
@ -770,6 +456,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
|
||||
snprintf(qctrl->name, sizeof(qctrl->name), name);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_query_fill);
|
||||
|
||||
/* Fill in a struct v4l2_queryctrl with standard values based on
|
||||
the control ID. */
|
||||
@ -904,6 +591,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
|
||||
|
||||
/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
|
||||
the menu. The qctrl pointer may be NULL, in which case it is ignored. */
|
||||
@ -922,6 +610,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
|
||||
qmenu->reserved = 0;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_query_menu);
|
||||
|
||||
/* ctrl_classes points to an array of u32 pointers, the last element is
|
||||
a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
|
||||
@ -972,7 +661,20 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
|
||||
return 0;
|
||||
return **ctrl_classes;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_next);
|
||||
|
||||
int v4l2_chip_match_host(u32 match_type, u32 match_chip)
|
||||
{
|
||||
switch (match_type) {
|
||||
case V4L2_CHIP_MATCH_HOST:
|
||||
return match_chip == 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_chip_match_host);
|
||||
|
||||
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
|
||||
int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
|
||||
{
|
||||
switch (match_type) {
|
||||
@ -984,6 +686,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
|
||||
|
||||
int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
|
||||
u32 ident, u32 revision)
|
||||
@ -1000,16 +703,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v4l2_chip_match_host(u32 match_type, u32 match_chip)
|
||||
{
|
||||
switch (match_type) {
|
||||
case V4L2_CHIP_MATCH_HOST:
|
||||
return match_chip == 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
@ -1038,38 +732,5 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
|
||||
}
|
||||
return err != -ENOMEM ? 0 : err;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
EXPORT_SYMBOL(v4l2_norm_to_name);
|
||||
EXPORT_SYMBOL(v4l2_video_std_construct);
|
||||
|
||||
EXPORT_SYMBOL(v4l2_prio_init);
|
||||
EXPORT_SYMBOL(v4l2_prio_change);
|
||||
EXPORT_SYMBOL(v4l2_prio_open);
|
||||
EXPORT_SYMBOL(v4l2_prio_close);
|
||||
EXPORT_SYMBOL(v4l2_prio_max);
|
||||
EXPORT_SYMBOL(v4l2_prio_check);
|
||||
|
||||
EXPORT_SYMBOL(v4l2_field_names);
|
||||
EXPORT_SYMBOL(v4l2_type_names);
|
||||
EXPORT_SYMBOL(v4l_printk_ioctl);
|
||||
|
||||
EXPORT_SYMBOL(v4l2_ctrl_next);
|
||||
EXPORT_SYMBOL(v4l2_ctrl_check);
|
||||
EXPORT_SYMBOL(v4l2_ctrl_get_menu);
|
||||
EXPORT_SYMBOL(v4l2_ctrl_query_menu);
|
||||
EXPORT_SYMBOL(v4l2_ctrl_query_fill);
|
||||
EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
|
||||
|
||||
EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
|
||||
EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
|
||||
EXPORT_SYMBOL(v4l2_chip_match_host);
|
||||
|
||||
EXPORT_SYMBOL(v4l2_i2c_attach);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
#endif
|
||||
|
@ -147,7 +147,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
|
||||
/* Having implementations for abstract methods are mandatory */
|
||||
BUG_ON(!q->int_ops);
|
||||
|
||||
mutex_init(&q->lock);
|
||||
mutex_init(&q->vb_lock);
|
||||
INIT_LIST_HEAD(&q->stream);
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
void videobuf_queue_cancel(struct videobuf_queue *q)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
@ -220,7 +220,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
|
||||
{
|
||||
enum v4l2_field field = q->field;
|
||||
@ -239,7 +239,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
|
||||
return field;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
|
||||
struct videobuf_buffer *vb, enum v4l2_buf_type type)
|
||||
{
|
||||
@ -295,7 +295,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
|
||||
b->sequence = vb->field_count >> 1;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
static int __videobuf_mmap_free(struct videobuf_queue *q)
|
||||
{
|
||||
int i;
|
||||
@ -328,13 +328,13 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
|
||||
int videobuf_mmap_free(struct videobuf_queue *q)
|
||||
{
|
||||
int ret;
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
ret = __videobuf_mmap_free(q);
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
static int __videobuf_mmap_setup(struct videobuf_queue *q,
|
||||
unsigned int bcount, unsigned int bsize,
|
||||
enum v4l2_memory memory)
|
||||
@ -384,9 +384,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
|
||||
enum v4l2_memory memory)
|
||||
{
|
||||
int ret;
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
if (req->type != q->type) {
|
||||
dprintk(1, "reqbufs: queue type invalid\n");
|
||||
retval = -EINVAL;
|
||||
@ -444,7 +444,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
|
||||
req->count = retval;
|
||||
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -452,7 +452,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
if (unlikely(b->type != q->type)) {
|
||||
dprintk(1, "querybuf: Wrong type.\n");
|
||||
goto done;
|
||||
@ -470,7 +470,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -487,7 +487,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
|
||||
if (b->memory == V4L2_MEMORY_MMAP)
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
retval = -EBUSY;
|
||||
if (q->reading) {
|
||||
dprintk(1, "qbuf: Reading running...\n");
|
||||
@ -573,7 +573,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
|
||||
retval = 0;
|
||||
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
|
||||
if (b->memory == V4L2_MEMORY_MMAP)
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
@ -589,7 +589,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
|
||||
|
||||
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
retval = -EBUSY;
|
||||
if (q->reading) {
|
||||
dprintk(1, "dqbuf: Reading running...\n");
|
||||
@ -632,7 +632,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
|
||||
videobuf_status(q, b, buf, q->type);
|
||||
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -642,7 +642,7 @@ int videobuf_streamon(struct videobuf_queue *q)
|
||||
unsigned long flags = 0;
|
||||
int retval;
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
retval = -EBUSY;
|
||||
if (q->reading)
|
||||
goto done;
|
||||
@ -659,11 +659,11 @@ int videobuf_streamon(struct videobuf_queue *q)
|
||||
spin_unlock_irqrestore(q->irqlock, flags);
|
||||
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
static int __videobuf_streamoff(struct videobuf_queue *q)
|
||||
{
|
||||
if (!q->streaming)
|
||||
@ -679,14 +679,14 @@ int videobuf_streamoff(struct videobuf_queue *q)
|
||||
{
|
||||
int retval;
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
retval = __videobuf_streamoff(q);
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
|
||||
char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -745,7 +745,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
|
||||
|
||||
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
|
||||
nbufs = 1; size = 0;
|
||||
q->ops->buf_setup(q, &nbufs, &size);
|
||||
@ -817,11 +817,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Locking: Caller holds q->lock */
|
||||
/* Locking: Caller holds q->vb_lock */
|
||||
static int __videobuf_read_start(struct videobuf_queue *q)
|
||||
{
|
||||
enum v4l2_field field;
|
||||
@ -882,23 +882,23 @@ int videobuf_read_start(struct videobuf_queue *q)
|
||||
{
|
||||
int rc;
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
rc = __videobuf_read_start(q);
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void videobuf_read_stop(struct videobuf_queue *q)
|
||||
{
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
__videobuf_read_stop(q);
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
}
|
||||
|
||||
void videobuf_stop(struct videobuf_queue *q)
|
||||
{
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
|
||||
if (q->streaming)
|
||||
__videobuf_streamoff(q);
|
||||
@ -906,7 +906,7 @@ void videobuf_stop(struct videobuf_queue *q)
|
||||
if (q->reading)
|
||||
__videobuf_read_stop(q);
|
||||
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
}
|
||||
|
||||
|
||||
@ -920,7 +920,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
|
||||
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
||||
|
||||
dprintk(2, "%s\n", __FUNCTION__);
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
retval = -EBUSY;
|
||||
if (q->streaming)
|
||||
goto done;
|
||||
@ -980,7 +980,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -991,7 +991,7 @@ unsigned int videobuf_poll_stream(struct file *file,
|
||||
struct videobuf_buffer *buf = NULL;
|
||||
unsigned int rc = 0;
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
if (q->streaming) {
|
||||
if (!list_empty(&q->stream))
|
||||
buf = list_entry(q->stream.next,
|
||||
@ -1019,7 +1019,7 @@ unsigned int videobuf_poll_stream(struct file *file,
|
||||
buf->state == VIDEOBUF_ERROR)
|
||||
rc = POLLIN|POLLRDNORM;
|
||||
}
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1030,10 +1030,10 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
|
||||
|
||||
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
retval = CALL(q, mmap_mapper, q, vma);
|
||||
q->is_mmapped = 1;
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
|
||||
map->count--;
|
||||
if (0 == map->count) {
|
||||
dprintk(1,"munmap %p q=%p\n",map,q);
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
|
||||
if (NULL == q->bufs[i])
|
||||
continue;
|
||||
@ -373,7 +373,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
|
||||
q->bufs[i]->baddr = 0;
|
||||
q->ops->buf_release(q,q->bufs[i]);
|
||||
}
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
kfree(map);
|
||||
}
|
||||
return;
|
||||
|
@ -70,7 +70,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
|
||||
map->count--;
|
||||
if (0 == map->count) {
|
||||
dprintk(1,"munmap %p q=%p\n",map,q);
|
||||
mutex_lock(&q->lock);
|
||||
mutex_lock(&q->vb_lock);
|
||||
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
|
||||
if (NULL == q->bufs[i])
|
||||
continue;
|
||||
@ -83,7 +83,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
|
||||
q->bufs[i]->map = NULL;
|
||||
q->bufs[i]->baddr = 0;
|
||||
}
|
||||
mutex_unlock(&q->lock);
|
||||
mutex_unlock(&q->vb_lock);
|
||||
kfree(map);
|
||||
}
|
||||
return;
|
||||
@ -107,7 +107,7 @@ static struct vm_operations_struct videobuf_vm_ops =
|
||||
|
||||
static void *__videobuf_alloc(size_t size)
|
||||
{
|
||||
struct videbuf_vmalloc_memory *mem;
|
||||
struct videobuf_vmalloc_memory *mem;
|
||||
struct videobuf_buffer *vb;
|
||||
|
||||
vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
|
||||
@ -127,9 +127,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
|
||||
struct v4l2_framebuffer *fbuf)
|
||||
{
|
||||
int pages;
|
||||
|
||||
struct videbuf_vmalloc_memory *mem=vb->priv;
|
||||
|
||||
struct videobuf_vmalloc_memory *mem=vb->priv;
|
||||
|
||||
BUG_ON(!mem);
|
||||
|
||||
@ -195,7 +193,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
|
||||
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct videbuf_vmalloc_memory *mem;
|
||||
struct videobuf_vmalloc_memory *mem;
|
||||
struct videobuf_mapping *map;
|
||||
unsigned int first;
|
||||
int retval;
|
||||
@ -267,7 +265,7 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q,
|
||||
char __user *data, size_t count,
|
||||
int nonblocking )
|
||||
{
|
||||
struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
|
||||
struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
|
||||
BUG_ON (!mem);
|
||||
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
|
||||
|
||||
@ -288,7 +286,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q,
|
||||
int vbihack, int nonblocking )
|
||||
{
|
||||
unsigned int *fc;
|
||||
struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
|
||||
struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
|
||||
BUG_ON (!mem);
|
||||
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
|
||||
|
||||
@ -341,7 +339,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
|
||||
|
||||
void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
|
||||
{
|
||||
struct videbuf_vmalloc_memory *mem=buf->priv;
|
||||
struct videobuf_vmalloc_memory *mem=buf->priv;
|
||||
BUG_ON (!mem);
|
||||
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
|
||||
|
||||
@ -351,7 +349,7 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
|
||||
|
||||
void videobuf_vmalloc_free (struct videobuf_buffer *buf)
|
||||
{
|
||||
struct videbuf_vmalloc_memory *mem=buf->priv;
|
||||
struct videobuf_vmalloc_memory *mem=buf->priv;
|
||||
BUG_ON (!mem);
|
||||
|
||||
MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
|
||||
|
@ -46,10 +46,373 @@
|
||||
#include <linux/videodev.h>
|
||||
#endif
|
||||
#include <media/v4l2-common.h>
|
||||
#include <linux/video_decoder.h>
|
||||
|
||||
#define VIDEO_NUM_DEVICES 256
|
||||
#define VIDEO_NAME "video4linux"
|
||||
|
||||
/* video4linux standard ID conversion to standard name
|
||||
*/
|
||||
char *v4l2_norm_to_name(v4l2_std_id id)
|
||||
{
|
||||
char *name;
|
||||
u32 myid = id;
|
||||
|
||||
/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
|
||||
64 bit comparations. So, on that architecture, with some gcc
|
||||
variants, compilation fails. Currently, the max value is 30bit wide.
|
||||
*/
|
||||
BUG_ON(myid != id);
|
||||
|
||||
switch (myid) {
|
||||
case V4L2_STD_PAL:
|
||||
name = "PAL";
|
||||
break;
|
||||
case V4L2_STD_PAL_BG:
|
||||
name = "PAL-BG";
|
||||
break;
|
||||
case V4L2_STD_PAL_DK:
|
||||
name = "PAL-DK";
|
||||
break;
|
||||
case V4L2_STD_PAL_B:
|
||||
name = "PAL-B";
|
||||
break;
|
||||
case V4L2_STD_PAL_B1:
|
||||
name = "PAL-B1";
|
||||
break;
|
||||
case V4L2_STD_PAL_G:
|
||||
name = "PAL-G";
|
||||
break;
|
||||
case V4L2_STD_PAL_H:
|
||||
name = "PAL-H";
|
||||
break;
|
||||
case V4L2_STD_PAL_I:
|
||||
name = "PAL-I";
|
||||
break;
|
||||
case V4L2_STD_PAL_D:
|
||||
name = "PAL-D";
|
||||
break;
|
||||
case V4L2_STD_PAL_D1:
|
||||
name = "PAL-D1";
|
||||
break;
|
||||
case V4L2_STD_PAL_K:
|
||||
name = "PAL-K";
|
||||
break;
|
||||
case V4L2_STD_PAL_M:
|
||||
name = "PAL-M";
|
||||
break;
|
||||
case V4L2_STD_PAL_N:
|
||||
name = "PAL-N";
|
||||
break;
|
||||
case V4L2_STD_PAL_Nc:
|
||||
name = "PAL-Nc";
|
||||
break;
|
||||
case V4L2_STD_PAL_60:
|
||||
name = "PAL-60";
|
||||
break;
|
||||
case V4L2_STD_NTSC:
|
||||
name = "NTSC";
|
||||
break;
|
||||
case V4L2_STD_NTSC_M:
|
||||
name = "NTSC-M";
|
||||
break;
|
||||
case V4L2_STD_NTSC_M_JP:
|
||||
name = "NTSC-M-JP";
|
||||
break;
|
||||
case V4L2_STD_NTSC_443:
|
||||
name = "NTSC-443";
|
||||
break;
|
||||
case V4L2_STD_NTSC_M_KR:
|
||||
name = "NTSC-M-KR";
|
||||
break;
|
||||
case V4L2_STD_SECAM:
|
||||
name = "SECAM";
|
||||
break;
|
||||
case V4L2_STD_SECAM_DK:
|
||||
name = "SECAM-DK";
|
||||
break;
|
||||
case V4L2_STD_SECAM_B:
|
||||
name = "SECAM-B";
|
||||
break;
|
||||
case V4L2_STD_SECAM_D:
|
||||
name = "SECAM-D";
|
||||
break;
|
||||
case V4L2_STD_SECAM_G:
|
||||
name = "SECAM-G";
|
||||
break;
|
||||
case V4L2_STD_SECAM_H:
|
||||
name = "SECAM-H";
|
||||
break;
|
||||
case V4L2_STD_SECAM_K:
|
||||
name = "SECAM-K";
|
||||
break;
|
||||
case V4L2_STD_SECAM_K1:
|
||||
name = "SECAM-K1";
|
||||
break;
|
||||
case V4L2_STD_SECAM_L:
|
||||
name = "SECAM-L";
|
||||
break;
|
||||
case V4L2_STD_SECAM_LC:
|
||||
name = "SECAM-LC";
|
||||
break;
|
||||
default:
|
||||
name = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_norm_to_name);
|
||||
|
||||
/* Fill in the fields of a v4l2_standard structure according to the
|
||||
'id' and 'transmission' parameters. Returns negative on error. */
|
||||
int v4l2_video_std_construct(struct v4l2_standard *vs,
|
||||
int id, char *name)
|
||||
{
|
||||
u32 index = vs->index;
|
||||
|
||||
memset(vs, 0, sizeof(struct v4l2_standard));
|
||||
vs->index = index;
|
||||
vs->id = id;
|
||||
if (id & V4L2_STD_525_60) {
|
||||
vs->frameperiod.numerator = 1001;
|
||||
vs->frameperiod.denominator = 30000;
|
||||
vs->framelines = 525;
|
||||
} else {
|
||||
vs->frameperiod.numerator = 1;
|
||||
vs->frameperiod.denominator = 25;
|
||||
vs->framelines = 625;
|
||||
}
|
||||
strlcpy(vs->name, name, sizeof(vs->name));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_video_std_construct);
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* some arrays for pretty-printing debug messages of enum types */
|
||||
|
||||
char *v4l2_field_names[] = {
|
||||
[V4L2_FIELD_ANY] = "any",
|
||||
[V4L2_FIELD_NONE] = "none",
|
||||
[V4L2_FIELD_TOP] = "top",
|
||||
[V4L2_FIELD_BOTTOM] = "bottom",
|
||||
[V4L2_FIELD_INTERLACED] = "interlaced",
|
||||
[V4L2_FIELD_SEQ_TB] = "seq-tb",
|
||||
[V4L2_FIELD_SEQ_BT] = "seq-bt",
|
||||
[V4L2_FIELD_ALTERNATE] = "alternate",
|
||||
[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
|
||||
[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
|
||||
};
|
||||
EXPORT_SYMBOL(v4l2_field_names);
|
||||
|
||||
char *v4l2_type_names[] = {
|
||||
[V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
|
||||
[V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
|
||||
[V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
|
||||
[V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
|
||||
[V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
|
||||
[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
|
||||
[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
|
||||
[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
|
||||
};
|
||||
EXPORT_SYMBOL(v4l2_type_names);
|
||||
|
||||
static char *v4l2_memory_names[] = {
|
||||
[V4L2_MEMORY_MMAP] = "mmap",
|
||||
[V4L2_MEMORY_USERPTR] = "userptr",
|
||||
[V4L2_MEMORY_OVERLAY] = "overlay",
|
||||
};
|
||||
|
||||
#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
|
||||
arr[a] : "unknown")
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* debug help functions */
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
static const char *v4l1_ioctls[] = {
|
||||
[_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
|
||||
[_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
|
||||
[_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
|
||||
[_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
|
||||
[_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
|
||||
[_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
|
||||
[_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
|
||||
[_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
|
||||
[_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
|
||||
[_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
|
||||
[_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
|
||||
[_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
|
||||
[_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
|
||||
[_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
|
||||
[_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
|
||||
[_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
|
||||
[_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
|
||||
[_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
|
||||
[_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
|
||||
[_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
|
||||
[_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
|
||||
[_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
|
||||
[_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
|
||||
[_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
|
||||
[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
|
||||
[_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
|
||||
[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
|
||||
[_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
|
||||
[_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
|
||||
};
|
||||
#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
|
||||
#endif
|
||||
|
||||
static const char *v4l2_ioctls[] = {
|
||||
[_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
|
||||
[_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
|
||||
[_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
|
||||
[_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
|
||||
[_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
|
||||
[_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
|
||||
[_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
|
||||
[_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
|
||||
[_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
|
||||
[_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
|
||||
[_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
|
||||
[_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
|
||||
[_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
|
||||
[_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
|
||||
[_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
|
||||
[_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
|
||||
[_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
|
||||
[_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
|
||||
[_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
|
||||
[_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
|
||||
[_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
|
||||
[_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
|
||||
[_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
|
||||
[_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
|
||||
[_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
|
||||
[_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
|
||||
[_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
|
||||
[_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
|
||||
[_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
|
||||
[_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
|
||||
[_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
|
||||
[_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
|
||||
[_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
|
||||
[_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
|
||||
[_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
|
||||
[_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
|
||||
[_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
|
||||
[_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
|
||||
[_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
|
||||
[_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
|
||||
[_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
|
||||
[_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
|
||||
[_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
|
||||
[_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
|
||||
[_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
|
||||
[_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
|
||||
[_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
|
||||
[_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
|
||||
[_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
|
||||
[_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
|
||||
[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
|
||||
[_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
|
||||
[_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
|
||||
[_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
|
||||
[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
|
||||
#if 1
|
||||
[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
|
||||
[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
|
||||
[_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
|
||||
[_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
|
||||
[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
|
||||
|
||||
[_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
|
||||
[_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
|
||||
|
||||
[_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
|
||||
#endif
|
||||
};
|
||||
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
|
||||
|
||||
static const char *v4l2_int_ioctls[] = {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
[_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
|
||||
[_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
|
||||
[_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
|
||||
[_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
|
||||
[_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
|
||||
[_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
|
||||
[_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
|
||||
[_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
|
||||
[_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
|
||||
[_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
|
||||
[_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
|
||||
#endif
|
||||
[_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
|
||||
|
||||
[_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
|
||||
[_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
|
||||
[_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
|
||||
|
||||
[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
|
||||
[_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
|
||||
[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
|
||||
[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
|
||||
[_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
|
||||
[_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
|
||||
[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
|
||||
[_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
|
||||
[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
|
||||
[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
|
||||
[_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
|
||||
[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
|
||||
[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
|
||||
};
|
||||
#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
|
||||
|
||||
/* Common ioctl debug function. This function can be used by
|
||||
external ioctl messages as well as internal V4L ioctl */
|
||||
void v4l_printk_ioctl(unsigned int cmd)
|
||||
{
|
||||
char *dir;
|
||||
|
||||
switch (_IOC_DIR(cmd)) {
|
||||
case _IOC_NONE: dir = "--"; break;
|
||||
case _IOC_READ: dir = "r-"; break;
|
||||
case _IOC_WRITE: dir = "-w"; break;
|
||||
case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
|
||||
default: dir = "*ERR*"; break;
|
||||
}
|
||||
switch (_IOC_TYPE(cmd)) {
|
||||
case 'd':
|
||||
printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
|
||||
v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case 'v':
|
||||
printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L1_IOCTLS) ?
|
||||
v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
#endif
|
||||
case 'V':
|
||||
printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L2_IOCTLS) ?
|
||||
v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
|
||||
_IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(v4l_printk_ioctl);
|
||||
|
||||
/*
|
||||
* sysfs stuff
|
||||
*/
|
||||
@ -69,11 +432,13 @@ struct video_device *video_device_alloc(void)
|
||||
vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
|
||||
return vfd;
|
||||
}
|
||||
EXPORT_SYMBOL(video_device_alloc);
|
||||
|
||||
void video_device_release(struct video_device *vfd)
|
||||
{
|
||||
kfree(vfd);
|
||||
}
|
||||
EXPORT_SYMBOL(video_device_release);
|
||||
|
||||
static void video_release(struct device *cd)
|
||||
{
|
||||
@ -110,6 +475,7 @@ struct video_device* video_devdata(struct file *file)
|
||||
{
|
||||
return video_device[iminor(file->f_path.dentry->d_inode)];
|
||||
}
|
||||
EXPORT_SYMBOL(video_devdata);
|
||||
|
||||
/*
|
||||
* Open a video device - FIXME: Obsoleted
|
||||
@ -278,6 +644,7 @@ video_usercopy(struct inode *inode, struct file *file,
|
||||
kfree(mbuf);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(video_usercopy);
|
||||
|
||||
/*
|
||||
* open/release helper functions -- handle exclusive opens
|
||||
@ -297,6 +664,7 @@ int video_exclusive_open(struct inode *inode, struct file *file)
|
||||
mutex_unlock(&vfl->lock);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(video_exclusive_open);
|
||||
|
||||
int video_exclusive_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
@ -305,41 +673,7 @@ int video_exclusive_release(struct inode *inode, struct file *file)
|
||||
vfl->users--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *v4l2_memory_names[] = {
|
||||
[V4L2_MEMORY_MMAP] = "mmap",
|
||||
[V4L2_MEMORY_USERPTR] = "userptr",
|
||||
[V4L2_MEMORY_OVERLAY] = "overlay",
|
||||
};
|
||||
|
||||
|
||||
/* FIXME: Those stuff are replicated also on v4l2-common.c */
|
||||
static char *v4l2_type_names_FIXME[] = {
|
||||
[V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
|
||||
[V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
|
||||
[V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
|
||||
[V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
|
||||
[V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
|
||||
[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
|
||||
[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
|
||||
[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
|
||||
[V4L2_BUF_TYPE_PRIVATE] = "private",
|
||||
};
|
||||
|
||||
static char *v4l2_field_names_FIXME[] = {
|
||||
[V4L2_FIELD_ANY] = "any",
|
||||
[V4L2_FIELD_NONE] = "none",
|
||||
[V4L2_FIELD_TOP] = "top",
|
||||
[V4L2_FIELD_BOTTOM] = "bottom",
|
||||
[V4L2_FIELD_INTERLACED] = "interlaced",
|
||||
[V4L2_FIELD_SEQ_TB] = "seq-tb",
|
||||
[V4L2_FIELD_SEQ_BT] = "seq-bt",
|
||||
[V4L2_FIELD_ALTERNATE] = "alternate",
|
||||
[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
|
||||
[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
|
||||
};
|
||||
|
||||
#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
|
||||
EXPORT_SYMBOL(video_exclusive_release);
|
||||
|
||||
static void dbgbuf(unsigned int cmd, struct video_device *vfd,
|
||||
struct v4l2_buffer *p)
|
||||
@ -354,10 +688,10 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
|
||||
(int)(p->timestamp.tv_sec%60),
|
||||
p->timestamp.tv_usec,
|
||||
p->index,
|
||||
prt_names(p->type,v4l2_type_names_FIXME),
|
||||
p->bytesused,p->flags,
|
||||
p->field,p->sequence,
|
||||
prt_names(p->memory,v4l2_memory_names),
|
||||
prt_names(p->type, v4l2_type_names),
|
||||
p->bytesused, p->flags,
|
||||
p->field, p->sequence,
|
||||
prt_names(p->memory, v4l2_memory_names),
|
||||
p->m.userptr, p->length);
|
||||
dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
|
||||
"flags=0x%08d, frames=%d, userbits=0x%08x\n",
|
||||
@ -382,8 +716,8 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd,
|
||||
(fmt->pixelformat >> 8) & 0xff,
|
||||
(fmt->pixelformat >> 16) & 0xff,
|
||||
(fmt->pixelformat >> 24) & 0xff,
|
||||
prt_names(fmt->field,v4l2_field_names_FIXME),
|
||||
fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
|
||||
prt_names(fmt->field, v4l2_field_names),
|
||||
fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
|
||||
};
|
||||
|
||||
|
||||
@ -597,7 +931,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
||||
|
||||
/* FIXME: Should be one dump per type */
|
||||
dbgarg (cmd, "type=%s\n", prt_names(type,
|
||||
v4l2_type_names_FIXME));
|
||||
v4l2_type_names));
|
||||
|
||||
switch (type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
@ -650,7 +984,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
||||
|
||||
/* FIXME: Should be one dump per type */
|
||||
dbgarg (cmd, "type=%s\n", prt_names(f->type,
|
||||
v4l2_type_names_FIXME));
|
||||
v4l2_type_names));
|
||||
|
||||
switch (f->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
@ -702,7 +1036,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
||||
|
||||
/* FIXME: Should be one dump per type */
|
||||
dbgarg (cmd, "type=%s\n", prt_names(f->type,
|
||||
v4l2_type_names_FIXME));
|
||||
v4l2_type_names));
|
||||
switch (f->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
if (vfd->vidioc_try_fmt_cap)
|
||||
@ -768,8 +1102,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
||||
ret=vfd->vidioc_reqbufs(file, fh, p);
|
||||
dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
|
||||
p->count,
|
||||
prt_names(p->type,v4l2_type_names_FIXME),
|
||||
prt_names(p->memory,v4l2_memory_names));
|
||||
prt_names(p->type, v4l2_type_names),
|
||||
prt_names(p->memory, v4l2_memory_names));
|
||||
break;
|
||||
}
|
||||
case VIDIOC_QUERYBUF:
|
||||
@ -858,7 +1192,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
||||
enum v4l2_buf_type i = *(int *)arg;
|
||||
if (!vfd->vidioc_streamon)
|
||||
break;
|
||||
dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
|
||||
dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
|
||||
ret=vfd->vidioc_streamon(file, fh,i);
|
||||
break;
|
||||
}
|
||||
@ -868,7 +1202,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
||||
|
||||
if (!vfd->vidioc_streamoff)
|
||||
break;
|
||||
dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
|
||||
dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
|
||||
ret=vfd->vidioc_streamoff(file, fh, i);
|
||||
break;
|
||||
}
|
||||
@ -1624,7 +1958,7 @@ int video_ioctl2 (struct inode *inode, struct file *file,
|
||||
kfree(mbuf);
|
||||
return err;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(video_ioctl2);
|
||||
|
||||
static const struct file_operations video_fops;
|
||||
|
||||
@ -1743,6 +2077,7 @@ int video_register_device(struct video_device *vfd, int type, int nr)
|
||||
mutex_unlock(&videodev_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(video_register_device);
|
||||
|
||||
/**
|
||||
* video_unregister_device - unregister a video4linux device
|
||||
@ -1762,6 +2097,7 @@ void video_unregister_device(struct video_device *vfd)
|
||||
device_unregister(&vfd->class_dev);
|
||||
mutex_unlock(&videodev_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(video_unregister_device);
|
||||
|
||||
/*
|
||||
* Video fs operations
|
||||
@ -1806,16 +2142,6 @@ static void __exit videodev_exit(void)
|
||||
module_init(videodev_init)
|
||||
module_exit(videodev_exit)
|
||||
|
||||
EXPORT_SYMBOL(video_register_device);
|
||||
EXPORT_SYMBOL(video_unregister_device);
|
||||
EXPORT_SYMBOL(video_devdata);
|
||||
EXPORT_SYMBOL(video_usercopy);
|
||||
EXPORT_SYMBOL(video_exclusive_open);
|
||||
EXPORT_SYMBOL(video_exclusive_release);
|
||||
EXPORT_SYMBOL(video_ioctl2);
|
||||
EXPORT_SYMBOL(video_device_alloc);
|
||||
EXPORT_SYMBOL(video_device_release);
|
||||
|
||||
MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
|
||||
MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -221,15 +221,15 @@ enum zoran_map_mode {
|
||||
};
|
||||
|
||||
enum gpio_type {
|
||||
GPIO_JPEG_SLEEP = 0,
|
||||
GPIO_JPEG_RESET,
|
||||
GPIO_JPEG_FRAME,
|
||||
GPIO_VID_DIR,
|
||||
GPIO_VID_EN,
|
||||
GPIO_VID_RESET,
|
||||
GPIO_CLK_SEL1,
|
||||
GPIO_CLK_SEL2,
|
||||
GPIO_MAX,
|
||||
ZR_GPIO_JPEG_SLEEP = 0,
|
||||
ZR_GPIO_JPEG_RESET,
|
||||
ZR_GPIO_JPEG_FRAME,
|
||||
ZR_GPIO_VID_DIR,
|
||||
ZR_GPIO_VID_EN,
|
||||
ZR_GPIO_VID_RESET,
|
||||
ZR_GPIO_CLK_SEL1,
|
||||
ZR_GPIO_CLK_SEL2,
|
||||
ZR_GPIO_MAX,
|
||||
};
|
||||
|
||||
enum gpcs_type {
|
||||
@ -378,11 +378,11 @@ struct card_info {
|
||||
|
||||
u32 jpeg_int; /* JPEG interrupt */
|
||||
u32 vsync_int; /* VSYNC interrupt */
|
||||
s8 gpio[GPIO_MAX];
|
||||
s8 gpio[ZR_GPIO_MAX];
|
||||
u8 gpcs[GPCS_MAX];
|
||||
|
||||
struct vfe_polarity vfe_pol;
|
||||
u8 gpio_pol[GPIO_MAX];
|
||||
u8 gpio_pol[ZR_GPIO_MAX];
|
||||
|
||||
/* is the /GWS line conected? */
|
||||
u8 gws_not_connected;
|
||||
|
@ -250,7 +250,7 @@ void
|
||||
jpeg_codec_sleep (struct zoran *zr,
|
||||
int sleep)
|
||||
{
|
||||
GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep);
|
||||
GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
|
||||
if (!sleep) {
|
||||
dprintk(3,
|
||||
KERN_DEBUG
|
||||
@ -277,9 +277,9 @@ jpeg_codec_reset (struct zoran *zr)
|
||||
0);
|
||||
udelay(2);
|
||||
} else {
|
||||
GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0);
|
||||
GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
|
||||
udelay(2);
|
||||
GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1);
|
||||
GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
@ -688,7 +688,7 @@ static inline void
|
||||
set_frame (struct zoran *zr,
|
||||
int val)
|
||||
{
|
||||
GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val);
|
||||
GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -704,8 +704,8 @@ set_videobus_dir (struct zoran *zr,
|
||||
GPIO(zr, 5, 1);
|
||||
break;
|
||||
default:
|
||||
GPIO(zr, zr->card.gpio[GPIO_VID_DIR],
|
||||
zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val);
|
||||
GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
|
||||
zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,8 @@ static struct usb_device_id device_table[] = {
|
||||
{USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
|
||||
{USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
|
||||
{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
|
||||
{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
|
||||
{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#ifndef __LINUX_VIDEODEV_H
|
||||
#define __LINUX_VIDEODEV_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
|
||||
|
@ -62,6 +62,7 @@
|
||||
#define __user
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
|
@ -142,6 +142,7 @@ extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -61,8 +61,6 @@
|
||||
v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
|
||||
} while (0)
|
||||
|
||||
/* Prints the ioctl in a human-readable format */
|
||||
extern void v4l_printk_ioctl(unsigned int cmd);
|
||||
|
||||
/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
|
||||
#define v4l_print_ioctl(name, cmd) \
|
||||
|
@ -44,6 +44,8 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
|
||||
extern char *v4l2_norm_to_name(v4l2_std_id id);
|
||||
extern int v4l2_video_std_construct(struct v4l2_standard *vs,
|
||||
int id, char *name);
|
||||
/* Prints the ioctl in a human-readable format */
|
||||
extern void v4l_printk_ioctl(unsigned int cmd);
|
||||
|
||||
/* prority handling */
|
||||
struct v4l2_prio_state {
|
||||
|
@ -149,7 +149,7 @@ struct videobuf_qtype_ops {
|
||||
};
|
||||
|
||||
struct videobuf_queue {
|
||||
struct mutex lock;
|
||||
struct mutex vb_lock;
|
||||
spinlock_t *irqlock;
|
||||
void *dev; /* on pci, points to struct pci_dev */
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
struct videbuf_vmalloc_memory
|
||||
struct videobuf_vmalloc_memory
|
||||
{
|
||||
u32 magic;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user