Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (34 commits) V4L/DVB (12303): cx23885: check pointers before dereferencing in dprintk macro V4L/DVB (12302): cx23885-417: fix broken IOCTL handling V4L/DVB (12300): bttv: fix regression: tvaudio must be loaded before tuner V4L/DVB (12291): b2c2: fix frontends compiled into kernel V4L/DVB (12286): sn9c20x: reorder includes to be like other drivers V4L/DVB (12284): gspca - jpeg subdrivers: Check the result of kmalloc(jpeg header). V4L/DVB (12283): gspca - sn9c20x: New subdriver for sn9c201 and sn9c202 bridges. V4L/DVB (12282): gspca - main: Support for vidioc_g_chip_ident and vidioc_g/s_register. V4L/DVB (12269): af9013: auto-detect parameters in case of garbage given by app V4L/DVB (12267): gspca - sonixj: Bad sensor init of non ov76xx sensors. V4L/DVB (12265): em28xx: fix tuning problem in HVR-900 (R1) V4L/DVB (12263): em28xx: set demod profile for Pinnacle Hybrid Pro 320e V4L/DVB (12262): em28xx: Make sure the tuner is initialized if generic empia USB id was used V4L/DVB (12261): em28xx: set GPIO properly for Pinnacle Hybrid Pro analog support V4L/DVB (12260): em28xx: make support work for the Pinnacle Hybrid Pro (eb1a:2881) V4L/DVB (12258): em28xx: fix typo in mt352 init sequence for Terratec Cinergy T XS USB V4L/DVB (12257): em28xx: make tuning work for Terratec Cinergy T XS USB (mt352 variant) V4L/DVB (12245): em28xx: add support for mt9m001 webcams V4L/DVB (12244): em28xx: adjust vinmode/vinctl based on the stream input format V4L/DVB (12243): em28xx: allow specifying sensor xtal frequency ...
This commit is contained in:
commit
04fc0a4097
@ -20,7 +20,7 @@
|
||||
19 -> EM2860/SAA711X Reference Design (em2860)
|
||||
20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002]
|
||||
21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801]
|
||||
22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751]
|
||||
22 -> EM2710/EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751]
|
||||
23 -> Huaqi DLCW-130 (em2750)
|
||||
24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112]
|
||||
25 -> Gadmei UTV310 (em2820/em2840)
|
||||
|
@ -44,7 +44,9 @@ zc3xx 0458:7007 Genius VideoCam V2
|
||||
zc3xx 0458:700c Genius VideoCam V3
|
||||
zc3xx 0458:700f Genius VideoCam Web V2
|
||||
sonixj 0458:7025 Genius Eye 311Q
|
||||
sn9c20x 0458:7029 Genius Look 320s
|
||||
sonixj 0458:702e Genius Slim 310 NB
|
||||
sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650)
|
||||
sonixj 045e:00f5 MicroSoft VX3000
|
||||
sonixj 045e:00f7 MicroSoft VX1000
|
||||
ov519 045e:028c Micro$oft xbox cam
|
||||
@ -282,6 +284,28 @@ sonixj 0c45:613a Microdia Sonix PC Camera
|
||||
sonixj 0c45:613b Surfer SN-206
|
||||
sonixj 0c45:613c Sonix Pccam168
|
||||
sonixj 0c45:6143 Sonix Pccam168
|
||||
sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001)
|
||||
sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111)
|
||||
sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655)
|
||||
sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968)
|
||||
sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650)
|
||||
sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650)
|
||||
sn9c20x 0c45:6253 PC Camera (SN9C201 + OV9650)
|
||||
sn9c20x 0c45:6260 PC Camera (SN9C201 + OV7670)
|
||||
sn9c20x 0c45:6270 PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112)
|
||||
sn9c20x 0c45:627b PC Camera (SN9C201 + OV7660)
|
||||
sn9c20x 0c45:627c PC Camera (SN9C201 + HV7131R)
|
||||
sn9c20x 0c45:627f PC Camera (SN9C201 + OV9650)
|
||||
sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001)
|
||||
sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111)
|
||||
sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655)
|
||||
sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968)
|
||||
sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650)
|
||||
sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670)
|
||||
sn9c20x 0c45:62b0 PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112)
|
||||
sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655)
|
||||
sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660)
|
||||
sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R)
|
||||
sunplus 0d64:0303 Sunplus FashionCam DXG
|
||||
etoms 102c:6151 Qcam Sangha CIF
|
||||
etoms 102c:6251 Qcam xxxxxx VGA
|
||||
@ -290,6 +314,7 @@ spca561 10fd:7e50 FlyCam Usb 100
|
||||
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
|
||||
ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201)
|
||||
pac207 145f:013a Trust WB-1300N
|
||||
sn9c20x 145f:013d Trust WB-3600R
|
||||
vc032x 15b8:6001 HP 2.0 Megapixel
|
||||
vc032x 15b8:6002 HP 2.0 Megapixel rz406aa
|
||||
spca501 1776:501c Arowana 300K CMOS Camera
|
||||
@ -300,4 +325,11 @@ spca500 2899:012c Toptro Industrial
|
||||
spca508 8086:0110 Intel Easy PC Camera
|
||||
spca500 8086:0630 Intel Pocket PC Camera
|
||||
spca506 99fa:8988 Grandtec V.cap
|
||||
sn9c20x a168:0610 Dino-Lite Digital Microscope (SN9C201 + HV7131R)
|
||||
sn9c20x a168:0611 Dino-Lite Digital Microscope (SN9C201 + HV7131R)
|
||||
sn9c20x a168:0613 Dino-Lite Digital Microscope (SN9C201 + HV7131R)
|
||||
sn9c20x a168:0618 Dino-Lite Digital Microscope (SN9C201 + HV7131R)
|
||||
sn9c20x a168:0614 Dino-Lite Digital Microscope (SN9C201 + MT9M111)
|
||||
sn9c20x a168:0615 Dino-Lite Digital Microscope (SN9C201 + MT9M111)
|
||||
sn9c20x a168:0617 Dino-Lite Digital Microscope (SN9C201 + MT9M111)
|
||||
spca561 abcd:cdee Petcam
|
||||
|
@ -20,8 +20,14 @@
|
||||
#include "tuner-simple.h"
|
||||
#include "stv0297.h"
|
||||
|
||||
|
||||
/* Can we use the specified front-end? Remember that if we are compiled
|
||||
* into the kernel we can't call code that's in modules. */
|
||||
#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
|
||||
(defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
|
||||
|
||||
/* lnb control */
|
||||
#if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE)
|
||||
#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
|
||||
static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
|
||||
{
|
||||
struct flexcop_device *fc = fe->dvb->priv;
|
||||
@ -49,8 +55,7 @@ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \
|
||||
|| defined(CONFIG_DVB_MT312_MODULE)
|
||||
#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
|
||||
static int flexcop_sleep(struct dvb_frontend* fe)
|
||||
{
|
||||
struct flexcop_device *fc = fe->dvb->priv;
|
||||
@ -61,7 +66,7 @@ static int flexcop_sleep(struct dvb_frontend* fe)
|
||||
#endif
|
||||
|
||||
/* SkyStar2 DVB-S rev 2.3 */
|
||||
#if defined(CONFIG_DVB_MT312_MODULE)
|
||||
#if FE_SUPPORTED(MT312)
|
||||
static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
||||
{
|
||||
/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
|
||||
@ -193,10 +198,12 @@ static int skystar2_rev23_attach(struct flexcop_device *fc,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define skystar2_rev23_attach NULL
|
||||
#endif
|
||||
|
||||
/* SkyStar2 DVB-S rev 2.6 */
|
||||
#if defined(CONFIG_DVB_STV0299_MODULE)
|
||||
#if FE_SUPPORTED(STV0299)
|
||||
static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
|
||||
u32 srate, u32 ratio)
|
||||
{
|
||||
@ -321,10 +328,12 @@ static int skystar2_rev26_attach(struct flexcop_device *fc,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define skystar2_rev26_attach NULL
|
||||
#endif
|
||||
|
||||
/* SkyStar2 DVB-S rev 2.7 */
|
||||
#if defined(CONFIG_DVB_S5H1420_MODULE)
|
||||
#if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
|
||||
static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
|
||||
.demod_address = 0x53,
|
||||
.invert = 1,
|
||||
@ -385,10 +394,12 @@ fail:
|
||||
fc->fc_i2c_adap[0].no_base_addr = 0;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define skystar2_rev27_attach NULL
|
||||
#endif
|
||||
|
||||
/* SkyStar2 rev 2.8 */
|
||||
#if defined(CONFIG_DVB_CX24123_MODULE)
|
||||
#if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
|
||||
static struct cx24123_config skystar2_rev2_8_cx24123_config = {
|
||||
.demod_address = 0x55,
|
||||
.dont_use_pll = 1,
|
||||
@ -433,10 +444,12 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
|
||||
* IR-receiver (PIC16F818) - but the card has no input for that ??? */
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
#define skystar2_rev28_attach NULL
|
||||
#endif
|
||||
|
||||
/* AirStar DVB-T */
|
||||
#if defined(CONFIG_DVB_MT352_MODULE)
|
||||
#if FE_SUPPORTED(MT352)
|
||||
static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
|
||||
{
|
||||
static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
|
||||
@ -495,10 +508,12 @@ static int airstar_dvbt_attach(struct flexcop_device *fc,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define airstar_dvbt_attach NULL
|
||||
#endif
|
||||
|
||||
/* AirStar ATSC 1st generation */
|
||||
#if defined(CONFIG_DVB_BCM3510_MODULE)
|
||||
#if FE_SUPPORTED(BCM3510)
|
||||
static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
|
||||
const struct firmware **fw, char* name)
|
||||
{
|
||||
@ -517,10 +532,12 @@ static int airstar_atsc1_attach(struct flexcop_device *fc,
|
||||
fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
|
||||
return fc->fe != NULL;
|
||||
}
|
||||
#else
|
||||
#define airstar_atsc1_attach NULL
|
||||
#endif
|
||||
|
||||
/* AirStar ATSC 2nd generation */
|
||||
#if defined(CONFIG_DVB_NXT200X_MODULE)
|
||||
#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
|
||||
static struct nxt200x_config samsung_tbmv_config = {
|
||||
.demod_address = 0x0a,
|
||||
};
|
||||
@ -535,10 +552,12 @@ static int airstar_atsc2_attach(struct flexcop_device *fc,
|
||||
return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
|
||||
DVB_PLL_SAMSUNG_TBMV);
|
||||
}
|
||||
#else
|
||||
#define airstar_atsc2_attach NULL
|
||||
#endif
|
||||
|
||||
/* AirStar ATSC 3rd generation */
|
||||
#if defined(CONFIG_DVB_LGDT330X_MODULE)
|
||||
#if FE_SUPPORTED(LGDT330X)
|
||||
static struct lgdt330x_config air2pc_atsc_hd5000_config = {
|
||||
.demod_address = 0x59,
|
||||
.demod_chip = LGDT3303,
|
||||
@ -556,10 +575,12 @@ static int airstar_atsc3_attach(struct flexcop_device *fc,
|
||||
return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
|
||||
TUNER_LG_TDVS_H06XF);
|
||||
}
|
||||
#else
|
||||
#define airstar_atsc3_attach NULL
|
||||
#endif
|
||||
|
||||
/* CableStar2 DVB-C */
|
||||
#if defined(CONFIG_DVB_STV0297_MODULE)
|
||||
#if FE_SUPPORTED(STV0297)
|
||||
static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
|
||||
struct dvb_frontend_parameters *fep)
|
||||
{
|
||||
@ -698,39 +719,23 @@ static int cablestar2_attach(struct flexcop_device *fc,
|
||||
fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
#define cablestar2_attach NULL
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
flexcop_device_type_t type;
|
||||
int (*attach)(struct flexcop_device *, struct i2c_adapter *);
|
||||
} flexcop_frontends[] = {
|
||||
#if defined(CONFIG_DVB_S5H1420_MODULE)
|
||||
{ FC_SKY_REV27, skystar2_rev27_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_CX24123_MODULE)
|
||||
{ FC_SKY_REV28, skystar2_rev28_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_STV0299_MODULE)
|
||||
{ FC_SKY_REV26, skystar2_rev26_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_MT352_MODULE)
|
||||
{ FC_AIR_DVBT, airstar_dvbt_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_NXT200X_MODULE)
|
||||
{ FC_AIR_ATSC2, airstar_atsc2_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_LGDT330X_MODULE)
|
||||
{ FC_AIR_ATSC3, airstar_atsc3_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_BCM3510_MODULE)
|
||||
{ FC_AIR_ATSC1, airstar_atsc1_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_STV0297_MODULE)
|
||||
{ FC_CABLE, cablestar2_attach },
|
||||
#endif
|
||||
#if defined(CONFIG_DVB_MT312_MODULE)
|
||||
{ FC_SKY_REV23, skystar2_rev23_attach },
|
||||
#endif
|
||||
};
|
||||
|
||||
/* try to figure out the frontend */
|
||||
@ -738,6 +743,8 @@ int flexcop_frontend_init(struct flexcop_device *fc)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
|
||||
if (!flexcop_frontends[i].attach)
|
||||
continue;
|
||||
/* type needs to be set before, because of some workarounds
|
||||
* done based on the probed card type */
|
||||
fc->dev_type = flexcop_frontends[i].type;
|
||||
|
@ -527,6 +527,10 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
u8 i, buf[3] = {0, 0, 0};
|
||||
*auto_mode = 0; /* set if parameters are requested to auto set */
|
||||
|
||||
/* Try auto-detect transmission parameters in case of AUTO requested or
|
||||
garbage parameters given by application for compatibility.
|
||||
MPlayer seems to provide garbage parameters currently. */
|
||||
|
||||
switch (params->transmission_mode) {
|
||||
case TRANSMISSION_MODE_AUTO:
|
||||
*auto_mode = 1;
|
||||
@ -536,7 +540,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
buf[0] |= (1 << 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid transmission_mode\n", __func__);
|
||||
*auto_mode = 1;
|
||||
}
|
||||
|
||||
switch (params->guard_interval) {
|
||||
@ -554,7 +559,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
buf[0] |= (3 << 2);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid guard_interval\n", __func__);
|
||||
*auto_mode = 1;
|
||||
}
|
||||
|
||||
switch (params->hierarchy_information) {
|
||||
@ -572,7 +578,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
buf[0] |= (3 << 4);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid hierarchy_information\n", __func__);
|
||||
*auto_mode = 1;
|
||||
};
|
||||
|
||||
switch (params->constellation) {
|
||||
@ -587,7 +594,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
buf[1] |= (2 << 6);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid constellation\n", __func__);
|
||||
*auto_mode = 1;
|
||||
}
|
||||
|
||||
/* Use HP. How and which case we can switch to LP? */
|
||||
@ -611,7 +619,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
buf[2] |= (4 << 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid code_rate_HP\n", __func__);
|
||||
*auto_mode = 1;
|
||||
}
|
||||
|
||||
switch (params->code_rate_LP) {
|
||||
@ -638,7 +647,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
if (params->hierarchy_information == HIERARCHY_AUTO)
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid code_rate_LP\n", __func__);
|
||||
*auto_mode = 1;
|
||||
}
|
||||
|
||||
switch (params->bandwidth) {
|
||||
@ -651,7 +661,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state,
|
||||
buf[1] |= (2 << 2);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
deb_info("%s: invalid bandwidth\n", __func__);
|
||||
buf[1] |= (2 << 2); /* cannot auto-detect BW, try 8 MHz */
|
||||
}
|
||||
|
||||
/* program */
|
||||
|
@ -3324,8 +3324,6 @@ void __devinit bttv_init_card1(struct bttv *btv)
|
||||
/* initialization part two -- after registering i2c bus */
|
||||
void __devinit bttv_init_card2(struct bttv *btv)
|
||||
{
|
||||
int addr=ADDR_UNSET;
|
||||
|
||||
btv->tuner_type = UNSET;
|
||||
|
||||
if (BTTV_BOARD_UNKNOWN == btv->c.type) {
|
||||
@ -3470,9 +3468,6 @@ void __devinit bttv_init_card2(struct bttv *btv)
|
||||
btv->pll.pll_current = -1;
|
||||
|
||||
/* tuner configuration (from card list / autodetect / insmod option) */
|
||||
if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
|
||||
addr = bttv_tvcards[btv->c.type].tuner_addr;
|
||||
|
||||
if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
|
||||
if (UNSET == btv->tuner_type)
|
||||
btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
|
||||
@ -3496,40 +3491,6 @@ void __devinit bttv_init_card2(struct bttv *btv)
|
||||
if (UNSET == btv->tuner_type)
|
||||
btv->tuner_type = TUNER_ABSENT;
|
||||
|
||||
if (btv->tuner_type != TUNER_ABSENT) {
|
||||
struct tuner_setup tun_setup;
|
||||
|
||||
/* Load tuner module before issuing tuner config call! */
|
||||
if (bttv_tvcards[btv->c.type].has_radio)
|
||||
v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
|
||||
&btv->c.i2c_adap, "tuner", "tuner",
|
||||
v4l2_i2c_tuner_addrs(ADDRS_RADIO));
|
||||
v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
|
||||
&btv->c.i2c_adap, "tuner", "tuner",
|
||||
v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
|
||||
v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
|
||||
&btv->c.i2c_adap, "tuner", "tuner",
|
||||
v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
|
||||
|
||||
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
|
||||
tun_setup.type = btv->tuner_type;
|
||||
tun_setup.addr = addr;
|
||||
|
||||
if (bttv_tvcards[btv->c.type].has_radio)
|
||||
tun_setup.mode_mask |= T_RADIO;
|
||||
|
||||
bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
|
||||
}
|
||||
|
||||
if (btv->tda9887_conf) {
|
||||
struct v4l2_priv_tun_config tda9887_cfg;
|
||||
|
||||
tda9887_cfg.tuner = TUNER_TDA9887;
|
||||
tda9887_cfg.priv = &btv->tda9887_conf;
|
||||
|
||||
bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
|
||||
}
|
||||
|
||||
btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
|
||||
bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET;
|
||||
btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ?
|
||||
@ -3540,15 +3501,15 @@ void __devinit bttv_init_card2(struct bttv *btv)
|
||||
btv->has_remote = remote[btv->c.nr];
|
||||
|
||||
if (bttv_tvcards[btv->c.type].has_radio)
|
||||
btv->has_radio=1;
|
||||
btv->has_radio = 1;
|
||||
if (bttv_tvcards[btv->c.type].has_remote)
|
||||
btv->has_remote=1;
|
||||
btv->has_remote = 1;
|
||||
if (!bttv_tvcards[btv->c.type].no_gpioirq)
|
||||
btv->gpioirq=1;
|
||||
btv->gpioirq = 1;
|
||||
if (bttv_tvcards[btv->c.type].volume_gpio)
|
||||
btv->volume_gpio=bttv_tvcards[btv->c.type].volume_gpio;
|
||||
btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio;
|
||||
if (bttv_tvcards[btv->c.type].audio_mode_gpio)
|
||||
btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
|
||||
btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio;
|
||||
|
||||
if (btv->tuner_type == TUNER_ABSENT)
|
||||
return; /* no tuner or related drivers to load */
|
||||
@ -3666,6 +3627,49 @@ no_audio:
|
||||
}
|
||||
|
||||
|
||||
/* initialize the tuner */
|
||||
void __devinit bttv_init_tuner(struct bttv *btv)
|
||||
{
|
||||
int addr = ADDR_UNSET;
|
||||
|
||||
if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
|
||||
addr = bttv_tvcards[btv->c.type].tuner_addr;
|
||||
|
||||
if (btv->tuner_type != TUNER_ABSENT) {
|
||||
struct tuner_setup tun_setup;
|
||||
|
||||
/* Load tuner module before issuing tuner config call! */
|
||||
if (bttv_tvcards[btv->c.type].has_radio)
|
||||
v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
|
||||
&btv->c.i2c_adap, "tuner", "tuner",
|
||||
v4l2_i2c_tuner_addrs(ADDRS_RADIO));
|
||||
v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
|
||||
&btv->c.i2c_adap, "tuner", "tuner",
|
||||
v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
|
||||
v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
|
||||
&btv->c.i2c_adap, "tuner", "tuner",
|
||||
v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
|
||||
|
||||
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
|
||||
tun_setup.type = btv->tuner_type;
|
||||
tun_setup.addr = addr;
|
||||
|
||||
if (bttv_tvcards[btv->c.type].has_radio)
|
||||
tun_setup.mode_mask |= T_RADIO;
|
||||
|
||||
bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
|
||||
}
|
||||
|
||||
if (btv->tda9887_conf) {
|
||||
struct v4l2_priv_tun_config tda9887_cfg;
|
||||
|
||||
tda9887_cfg.tuner = TUNER_TDA9887;
|
||||
tda9887_cfg.priv = &btv->tda9887_conf;
|
||||
|
||||
bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static void modtec_eeprom(struct bttv *btv)
|
||||
|
@ -4419,6 +4419,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
|
||||
|
||||
/* some card-specific stuff (needs working i2c) */
|
||||
bttv_init_card2(btv);
|
||||
bttv_init_tuner(btv);
|
||||
init_irqreg(btv);
|
||||
|
||||
/* register video4linux + input */
|
||||
|
@ -283,6 +283,7 @@ extern struct tvcard bttv_tvcards[];
|
||||
extern void bttv_idcard(struct bttv *btv);
|
||||
extern void bttv_init_card1(struct bttv *btv);
|
||||
extern void bttv_init_card2(struct bttv *btv);
|
||||
extern void bttv_init_tuner(struct bttv *btv);
|
||||
|
||||
/* card-specific funtions */
|
||||
extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
|
||||
|
@ -58,7 +58,8 @@ MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages");
|
||||
|
||||
#define dprintk(level, fmt, arg...)\
|
||||
do { if (v4l_debug >= level) \
|
||||
printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg);\
|
||||
printk(KERN_DEBUG "%s: " fmt, \
|
||||
(dev) ? dev->name : "cx23885[?]", ## arg); \
|
||||
} while (0)
|
||||
|
||||
static struct cx23885_tvnorm cx23885_tvnorms[] = {
|
||||
@ -1677,6 +1678,7 @@ static struct v4l2_file_operations mpeg_fops = {
|
||||
.read = mpeg_read,
|
||||
.poll = mpeg_poll,
|
||||
.mmap = mpeg_mmap,
|
||||
.ioctl = video_ioctl2,
|
||||
};
|
||||
|
||||
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
|
||||
|
@ -58,8 +58,6 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
||||
module_param_array(card, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(card, "card type");
|
||||
|
||||
#define MT9V011_VERSION 0x8243
|
||||
|
||||
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
|
||||
static unsigned long em28xx_devused;
|
||||
|
||||
@ -159,6 +157,20 @@ static struct em28xx_reg_seq evga_indtube_digital[] = {
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
/* Pinnacle Hybrid Pro eb1a:2881 */
|
||||
static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
|
||||
{EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10},
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
|
||||
{EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
|
||||
{EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */
|
||||
{EM2880_R04_GPO, 0x0c, 0xff, 1},
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
|
||||
/* Callback for the most boards */
|
||||
static struct em28xx_reg_seq default_tuner_gpio[] = {
|
||||
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
|
||||
@ -205,13 +217,15 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
|
||||
*/
|
||||
struct em28xx_board em28xx_boards[] = {
|
||||
[EM2750_BOARD_UNKNOWN] = {
|
||||
.name = "Unknown EM2750/EM2751 webcam grabber",
|
||||
.name = "EM2710/EM2750/EM2751 webcam grabber",
|
||||
.xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
|
||||
.tuner_type = TUNER_ABSENT, /* This is a webcam */
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.is_webcam = 1,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = 0,
|
||||
.amux = EM28XX_AMUX_VIDEO,
|
||||
.gpio = silvercrest_reg_seq,
|
||||
} },
|
||||
},
|
||||
[EM2800_BOARD_UNKNOWN] = {
|
||||
@ -233,13 +247,15 @@ struct em28xx_board em28xx_boards[] = {
|
||||
[EM2820_BOARD_UNKNOWN] = {
|
||||
.name = "Unknown EM2750/28xx video grabber",
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.is_webcam = 1, /* To enable sensor probe */
|
||||
},
|
||||
[EM2750_BOARD_DLCW_130] = {
|
||||
/* Beijing Huaqi Information Digital Technology Co., Ltd */
|
||||
.name = "Huaqi DLCW-130",
|
||||
.valid = EM28XX_BOARD_NOT_VALIDATED,
|
||||
.xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
|
||||
.tuner_type = TUNER_ABSENT, /* This is a webcam */
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.is_webcam = 1,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = 0,
|
||||
@ -440,7 +456,8 @@ struct em28xx_board em28xx_boards[] = {
|
||||
[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
|
||||
.name = "Videology 20K14XUSB USB2.0",
|
||||
.valid = EM28XX_BOARD_NOT_VALIDATED,
|
||||
.tuner_type = TUNER_ABSENT, /* This is a webcam */
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.is_webcam = 1,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = 0,
|
||||
@ -450,8 +467,7 @@ struct em28xx_board em28xx_boards[] = {
|
||||
[EM2820_BOARD_SILVERCREST_WEBCAM] = {
|
||||
.name = "Silvercrest Webcam 1.3mpix",
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.is_27xx = 1,
|
||||
.decoder = EM28XX_MT9V011,
|
||||
.is_webcam = 1,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = 0,
|
||||
@ -500,7 +516,8 @@ struct em28xx_board em28xx_boards[] = {
|
||||
/* Beijing Huaqi Information Digital Technology Co., Ltd */
|
||||
.name = "NetGMBH Cam",
|
||||
.valid = EM28XX_BOARD_NOT_VALIDATED,
|
||||
.tuner_type = TUNER_ABSENT, /* This is a webcam */
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.is_webcam = 1,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = 0,
|
||||
@ -1250,25 +1267,26 @@ struct em28xx_board em28xx_boards[] = {
|
||||
},
|
||||
[EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
|
||||
.name = "Pinnacle Hybrid Pro",
|
||||
.valid = EM28XX_BOARD_NOT_VALIDATED,
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.tuner_gpio = default_tuner_gpio,
|
||||
.decoder = EM28XX_TVP5150,
|
||||
.has_dvb = 1,
|
||||
.dvb_gpio = pinnacle_hybrid_pro_digital,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_TELEVISION,
|
||||
.vmux = TVP5150_COMPOSITE0,
|
||||
.amux = EM28XX_AMUX_VIDEO,
|
||||
.gpio = default_analog,
|
||||
.gpio = pinnacle_hybrid_pro_analog,
|
||||
}, {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = TVP5150_COMPOSITE1,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
.gpio = default_analog,
|
||||
.gpio = pinnacle_hybrid_pro_analog,
|
||||
}, {
|
||||
.type = EM28XX_VMUX_SVIDEO,
|
||||
.vmux = TVP5150_SVIDEO,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
.gpio = default_analog,
|
||||
.gpio = pinnacle_hybrid_pro_analog,
|
||||
} },
|
||||
},
|
||||
[EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
|
||||
@ -1638,6 +1656,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
|
||||
{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
|
||||
{0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
|
||||
{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
|
||||
{0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
|
||||
};
|
||||
|
||||
/* I2C devicelist hash table for devices with generic USB IDs */
|
||||
@ -1704,6 +1723,32 @@ static inline void em28xx_set_model(struct em28xx *dev)
|
||||
EM28XX_I2C_FREQ_100_KHZ;
|
||||
}
|
||||
|
||||
/* FIXME: Should be replaced by a proper mt9m001 driver */
|
||||
static int em28xx_initialize_mt9m001(struct em28xx *dev)
|
||||
{
|
||||
int i;
|
||||
unsigned char regs[][3] = {
|
||||
{ 0x0d, 0x00, 0x01, },
|
||||
{ 0x0d, 0x00, 0x00, },
|
||||
{ 0x04, 0x05, 0x00, }, /* hres = 1280 */
|
||||
{ 0x03, 0x04, 0x00, }, /* vres = 1024 */
|
||||
{ 0x20, 0x11, 0x00, },
|
||||
{ 0x06, 0x00, 0x10, },
|
||||
{ 0x2b, 0x00, 0x24, },
|
||||
{ 0x2e, 0x00, 0x24, },
|
||||
{ 0x35, 0x00, 0x24, },
|
||||
{ 0x2d, 0x00, 0x20, },
|
||||
{ 0x2c, 0x00, 0x20, },
|
||||
{ 0x09, 0x0a, 0xd4, },
|
||||
{ 0x35, 0x00, 0x57, },
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs); i++)
|
||||
i2c_master_send(&dev->i2c_client, ®s[i][0], 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HINT method: webcam I2C chips
|
||||
*
|
||||
* This method work for webcams with Micron sensors
|
||||
@ -1716,9 +1761,6 @@ static int em28xx_hint_sensor(struct em28xx *dev)
|
||||
__be16 version_be;
|
||||
u16 version;
|
||||
|
||||
if (dev->model != EM2820_BOARD_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
dev->i2c_client.addr = 0xba >> 1;
|
||||
cmd = 0;
|
||||
i2c_master_send(&dev->i2c_client, &cmd, 1);
|
||||
@ -1729,16 +1771,38 @@ static int em28xx_hint_sensor(struct em28xx *dev)
|
||||
version = be16_to_cpu(version_be);
|
||||
|
||||
switch (version) {
|
||||
case MT9V011_VERSION:
|
||||
case 0x8243: /* mt9v011 640x480 1.3 Mpix sensor */
|
||||
dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
|
||||
sensor_name = "mt9v011";
|
||||
dev->em28xx_sensor = EM28XX_MT9V011;
|
||||
dev->sensor_xres = 640;
|
||||
dev->sensor_yres = 480;
|
||||
dev->sensor_xtal = 6300000;
|
||||
|
||||
/* probably means GRGB 16 bit bayer */
|
||||
dev->vinmode = 0x0d;
|
||||
dev->vinctl = 0x00;
|
||||
|
||||
break;
|
||||
case 0x8431:
|
||||
dev->model = EM2750_BOARD_UNKNOWN;
|
||||
sensor_name = "mt9m001";
|
||||
dev->em28xx_sensor = EM28XX_MT9M001;
|
||||
em28xx_initialize_mt9m001(dev);
|
||||
dev->sensor_xres = 1280;
|
||||
dev->sensor_yres = 1024;
|
||||
|
||||
/* probably means BGGR 16 bit bayer */
|
||||
dev->vinmode = 0x0c;
|
||||
dev->vinctl = 0x00;
|
||||
|
||||
break;
|
||||
default:
|
||||
printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version));
|
||||
printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
em28xx_errdev("Sensor is %s, assuming that webcam is %s\n",
|
||||
em28xx_errdev("Sensor is %s, using model %s entry.\n",
|
||||
sensor_name, em28xx_boards[dev->model].name);
|
||||
|
||||
return 0;
|
||||
@ -1772,10 +1836,7 @@ void em28xx_pre_card_setup(struct em28xx *dev)
|
||||
em28xx_info("chip ID is em2750\n");
|
||||
break;
|
||||
case CHIP_ID_EM2820:
|
||||
if (dev->board.is_27xx)
|
||||
em28xx_info("chip is em2710\n");
|
||||
else
|
||||
em28xx_info("chip ID is em2820\n");
|
||||
em28xx_info("chip ID is em2710 or em2820\n");
|
||||
break;
|
||||
case CHIP_ID_EM2840:
|
||||
em28xx_info("chip ID is em2840\n");
|
||||
@ -1929,6 +1990,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
|
||||
ctl->demod = XC3028_FE_ZARLINK456;
|
||||
break;
|
||||
case EM2880_BOARD_TERRATEC_HYBRID_XS:
|
||||
case EM2881_BOARD_PINNACLE_HYBRID_PRO:
|
||||
ctl->demod = XC3028_FE_ZARLINK456;
|
||||
break;
|
||||
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
|
||||
@ -2225,6 +2287,7 @@ void em28xx_card_setup(struct em28xx *dev)
|
||||
em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
|
||||
so make the call now so the analog GPIOs are set properly
|
||||
before probing the i2c bus. */
|
||||
em28xx_gpio_set(dev, dev->board.tuner_gpio);
|
||||
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
|
||||
break;
|
||||
case EM2820_BOARD_SILVERCREST_WEBCAM:
|
||||
@ -2262,9 +2325,14 @@ void em28xx_card_setup(struct em28xx *dev)
|
||||
v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
|
||||
"tvp5150", "tvp5150", tvp5150_addrs);
|
||||
|
||||
if (dev->board.decoder == EM28XX_MT9V011)
|
||||
v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
|
||||
"mt9v011", "mt9v011", mt9v011_addrs);
|
||||
if (dev->em28xx_sensor == EM28XX_MT9V011) {
|
||||
struct v4l2_subdev *sd;
|
||||
|
||||
sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
|
||||
&dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs);
|
||||
v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
|
||||
}
|
||||
|
||||
|
||||
if (dev->board.adecoder == EM28XX_TVAUDIO)
|
||||
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
|
||||
@ -2410,7 +2478,19 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
||||
return errCode;
|
||||
}
|
||||
|
||||
em28xx_hint_sensor(dev);
|
||||
/*
|
||||
* Default format, used for tvp5150 or saa711x output formats
|
||||
*/
|
||||
dev->vinmode = 0x10;
|
||||
dev->vinctl = 0x11;
|
||||
|
||||
/*
|
||||
* If the device can be a webcam, seek for a sensor.
|
||||
* If sensor is not found, then it isn't a webcam.
|
||||
*/
|
||||
if (dev->board.is_webcam)
|
||||
if (em28xx_hint_sensor(dev) < 0)
|
||||
dev->board.is_webcam = 0;
|
||||
|
||||
/* Do board specific init and eeprom reading */
|
||||
em28xx_card_setup(dev);
|
||||
|
@ -648,28 +648,17 @@ int em28xx_capture_start(struct em28xx *dev, int start)
|
||||
int em28xx_set_outfmt(struct em28xx *dev)
|
||||
{
|
||||
int ret;
|
||||
int vinmode, vinctl, outfmt;
|
||||
|
||||
outfmt = dev->format->reg;
|
||||
|
||||
if (dev->board.is_27xx) {
|
||||
vinmode = 0x0d;
|
||||
vinctl = 0x00;
|
||||
} else {
|
||||
vinmode = 0x10;
|
||||
vinctl = 0x11;
|
||||
}
|
||||
|
||||
ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
|
||||
outfmt | 0x20, 0xff);
|
||||
dev->format->reg | 0x20, 0xff);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, vinmode);
|
||||
ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctl);
|
||||
return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, dev->vinctl);
|
||||
}
|
||||
|
||||
static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
|
||||
@ -707,10 +696,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
|
||||
u8 mode;
|
||||
/* the em2800 scaler only supports scaling down to 50% */
|
||||
|
||||
if (dev->board.is_27xx) {
|
||||
/* FIXME: Don't use the scaler yet */
|
||||
mode = 0;
|
||||
} else if (dev->board.is_em2800) {
|
||||
if (dev->board.is_em2800) {
|
||||
mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
|
||||
} else {
|
||||
u8 buf[2];
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "lgdt330x.h"
|
||||
#include "zl10353.h"
|
||||
#include "s5h1409.h"
|
||||
#include "mt352.h"
|
||||
#include "mt352_priv.h" /* FIXME */
|
||||
|
||||
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
|
||||
@ -243,7 +245,7 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
|
||||
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
|
||||
};
|
||||
|
||||
static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = {
|
||||
static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
|
||||
.demod_address = (0x1e >> 1),
|
||||
.no_tuner = 1,
|
||||
.disable_i2c_gate_ctrl = 1,
|
||||
@ -258,6 +260,41 @@ static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int mt352_terratec_xs_init(struct dvb_frontend *fe)
|
||||
{
|
||||
/* Values extracted from a USB trace of the Terratec Windows driver */
|
||||
static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c };
|
||||
static u8 reset[] = { RESET, 0x80 };
|
||||
static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
|
||||
static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 };
|
||||
static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 };
|
||||
static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d };
|
||||
static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
|
||||
static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 };
|
||||
static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 };
|
||||
static u8 tuner_go[] = { TUNER_GO, 0x01};
|
||||
|
||||
mt352_write(fe, clock_config, sizeof(clock_config));
|
||||
udelay(200);
|
||||
mt352_write(fe, reset, sizeof(reset));
|
||||
mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
|
||||
mt352_write(fe, agc_cfg, sizeof(agc_cfg));
|
||||
mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg));
|
||||
mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg));
|
||||
mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
|
||||
mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg));
|
||||
mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg));
|
||||
mt352_write(fe, tuner_go, sizeof(tuner_go));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mt352_config terratec_xs_mt352_cfg = {
|
||||
.demod_address = (0x1e >> 1),
|
||||
.no_tuner = 1,
|
||||
.if2 = 45600,
|
||||
.demod_init = mt352_terratec_xs_init,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int attach_xc3028(u8 addr, struct em28xx *dev)
|
||||
@ -440,7 +477,6 @@ static int dvb_init(struct em28xx *dev)
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
|
||||
case EM2880_BOARD_KWORLD_DVB_310U:
|
||||
case EM2880_BOARD_EMPIRE_DUAL_TV:
|
||||
dvb->frontend = dvb_attach(zl10353_attach,
|
||||
@ -451,20 +487,28 @@ static int dvb_init(struct em28xx *dev)
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case EM2880_BOARD_TERRATEC_HYBRID_XS:
|
||||
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
|
||||
dvb->frontend = dvb_attach(zl10353_attach,
|
||||
&em28xx_terratec_xs_zl10353_xc3028,
|
||||
&em28xx_zl10353_xc3028_no_i2c_gate,
|
||||
&dev->i2c_adap);
|
||||
if (attach_xc3028(0x61, dev) < 0) {
|
||||
result = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case EM2880_BOARD_TERRATEC_HYBRID_XS:
|
||||
case EM2881_BOARD_PINNACLE_HYBRID_PRO:
|
||||
dvb->frontend = dvb_attach(zl10353_attach,
|
||||
&em28xx_zl10353_xc3028_no_i2c_gate,
|
||||
&dev->i2c_adap);
|
||||
if (dvb->frontend == NULL) {
|
||||
/* This board could have either a zl10353 or a mt352.
|
||||
If the chip id isn't for zl10353, try mt352 */
|
||||
|
||||
/* FIXME: make support for mt352 work */
|
||||
printk(KERN_ERR "version of this board with mt352 not "
|
||||
"currently supported\n");
|
||||
result = -EINVAL;
|
||||
goto out_free;
|
||||
dvb->frontend = dvb_attach(mt352_attach,
|
||||
&terratec_xs_mt352_cfg,
|
||||
&dev->i2c_adap);
|
||||
}
|
||||
|
||||
if (attach_xc3028(0x61, dev) < 0) {
|
||||
result = -EINVAL;
|
||||
goto out_free;
|
||||
|
@ -657,8 +657,8 @@ static void get_scale(struct em28xx *dev,
|
||||
unsigned int width, unsigned int height,
|
||||
unsigned int *hscale, unsigned int *vscale)
|
||||
{
|
||||
unsigned int maxw = norm_maxw(dev);
|
||||
unsigned int maxh = norm_maxh(dev);
|
||||
unsigned int maxw = norm_maxw(dev);
|
||||
unsigned int maxh = norm_maxh(dev);
|
||||
|
||||
*hscale = (((unsigned long)maxw) << 12) / width - 4096L;
|
||||
if (*hscale >= 0x4000)
|
||||
@ -726,11 +726,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev->board.is_27xx) {
|
||||
/* FIXME: This is the only supported fmt */
|
||||
width = 640;
|
||||
height = 480;
|
||||
} else if (dev->board.is_em2800) {
|
||||
if (dev->board.is_em2800) {
|
||||
/* the em2800 can only scale down to 50% */
|
||||
height = height > (3 * maxh / 4) ? maxh : maxh / 2;
|
||||
width = width > (3 * maxw / 4) ? maxw : maxw / 2;
|
||||
@ -767,12 +763,6 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
|
||||
{
|
||||
struct em28xx_fmt *fmt;
|
||||
|
||||
/* FIXME: This is the only supported fmt */
|
||||
if (dev->board.is_27xx) {
|
||||
width = 640;
|
||||
height = 480;
|
||||
}
|
||||
|
||||
fmt = format_by_fourcc(fourcc);
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
@ -358,10 +358,15 @@ struct em28xx_input {
|
||||
#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
|
||||
|
||||
enum em28xx_decoder {
|
||||
EM28XX_NODECODER,
|
||||
EM28XX_NODECODER = 0,
|
||||
EM28XX_TVP5150,
|
||||
EM28XX_SAA711X,
|
||||
};
|
||||
|
||||
enum em28xx_sensor {
|
||||
EM28XX_NOSENSOR = 0,
|
||||
EM28XX_MT9V011,
|
||||
EM28XX_MT9M001,
|
||||
};
|
||||
|
||||
enum em28xx_adecoder {
|
||||
@ -390,7 +395,7 @@ struct em28xx_board {
|
||||
unsigned int max_range_640_480:1;
|
||||
unsigned int has_dvb:1;
|
||||
unsigned int has_snapshot_button:1;
|
||||
unsigned int is_27xx:1;
|
||||
unsigned int is_webcam:1;
|
||||
unsigned int valid:1;
|
||||
|
||||
unsigned char xclk, i2c_speed;
|
||||
@ -474,6 +479,14 @@ struct em28xx {
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct em28xx_board board;
|
||||
|
||||
/* Webcam specific fields */
|
||||
enum em28xx_sensor em28xx_sensor;
|
||||
int sensor_xres, sensor_yres;
|
||||
int sensor_xtal;
|
||||
|
||||
/* Vinmode/Vinctl used at the driver */
|
||||
int vinmode, vinctl;
|
||||
|
||||
unsigned int stream_on:1; /* Locks streams */
|
||||
unsigned int has_audio_class:1;
|
||||
unsigned int has_alsa_audio:1;
|
||||
@ -754,17 +767,23 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val)
|
||||
/*FIXME: maxw should be dependent of alt mode */
|
||||
static inline unsigned int norm_maxw(struct em28xx *dev)
|
||||
{
|
||||
if (dev->board.is_webcam)
|
||||
return dev->sensor_xres;
|
||||
|
||||
if (dev->board.max_range_640_480)
|
||||
return 640;
|
||||
else
|
||||
return 720;
|
||||
|
||||
return 720;
|
||||
}
|
||||
|
||||
static inline unsigned int norm_maxh(struct em28xx *dev)
|
||||
{
|
||||
if (dev->board.is_webcam)
|
||||
return dev->sensor_yres;
|
||||
|
||||
if (dev->board.max_range_640_480)
|
||||
return 480;
|
||||
else
|
||||
return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
|
||||
|
||||
return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
|
||||
}
|
||||
#endif
|
||||
|
@ -102,6 +102,22 @@ config USB_GSPCA_PAC7311
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gspca_pac7311.
|
||||
|
||||
config USB_GSPCA_SN9C20X
|
||||
tristate "SN9C20X USB Camera Driver"
|
||||
depends on VIDEO_V4L2 && USB_GSPCA
|
||||
help
|
||||
Say Y here if you want support for cameras based on the
|
||||
sn9c20x chips (SN9C201 and SN9C202).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gspca_sn9c20x.
|
||||
|
||||
config USB_GSPCA_SN9C20X_EVDEV
|
||||
bool "Enable evdev support"
|
||||
depends on USB_GSPCA_SN9C20X
|
||||
---help---
|
||||
Say Y here in order to enable evdev support for sn9c20x webcam button.
|
||||
|
||||
config USB_GSPCA_SONIXB
|
||||
tristate "SONIX Bayer USB Camera Driver"
|
||||
depends on VIDEO_V4L2 && USB_GSPCA
|
||||
|
@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
|
||||
obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
|
||||
obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
|
||||
obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
|
||||
obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
|
||||
obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
|
||||
obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
|
||||
obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
|
||||
@ -35,6 +36,7 @@ gspca_ov519-objs := ov519.o
|
||||
gspca_ov534-objs := ov534.o
|
||||
gspca_pac207-objs := pac207.o
|
||||
gspca_pac7311-objs := pac7311.o
|
||||
gspca_sn9c20x-objs := sn9c20x.o
|
||||
gspca_sonixb-objs := sonixb.o
|
||||
gspca_sonixj-objs := sonixj.o
|
||||
gspca_spca500-objs := spca500.o
|
||||
|
@ -846,6 +846,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x22); /* JPEG 411 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
@ -727,6 +727,74 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
static int vidioc_g_register(struct file *file, void *priv,
|
||||
struct v4l2_dbg_register *reg)
|
||||
{
|
||||
int ret;
|
||||
struct gspca_dev *gspca_dev = priv;
|
||||
|
||||
if (!gspca_dev->sd_desc->get_chip_ident)
|
||||
return -EINVAL;
|
||||
|
||||
if (!gspca_dev->sd_desc->get_register)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (gspca_dev->present)
|
||||
ret = gspca_dev->sd_desc->get_register(gspca_dev, reg);
|
||||
else
|
||||
ret = -ENODEV;
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vidioc_s_register(struct file *file, void *priv,
|
||||
struct v4l2_dbg_register *reg)
|
||||
{
|
||||
int ret;
|
||||
struct gspca_dev *gspca_dev = priv;
|
||||
|
||||
if (!gspca_dev->sd_desc->get_chip_ident)
|
||||
return -EINVAL;
|
||||
|
||||
if (!gspca_dev->sd_desc->set_register)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (gspca_dev->present)
|
||||
ret = gspca_dev->sd_desc->set_register(gspca_dev, reg);
|
||||
else
|
||||
ret = -ENODEV;
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int vidioc_g_chip_ident(struct file *file, void *priv,
|
||||
struct v4l2_dbg_chip_ident *chip)
|
||||
{
|
||||
int ret;
|
||||
struct gspca_dev *gspca_dev = priv;
|
||||
|
||||
if (!gspca_dev->sd_desc->get_chip_ident)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (gspca_dev->present)
|
||||
ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
|
||||
else
|
||||
ret = -ENODEV;
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_fmtdesc *fmtdesc)
|
||||
{
|
||||
@ -1883,6 +1951,11 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
|
||||
.vidioc_s_parm = vidioc_s_parm,
|
||||
.vidioc_s_std = vidioc_s_std,
|
||||
.vidioc_enum_framesizes = vidioc_enum_framesizes,
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
.vidioc_g_register = vidioc_g_register,
|
||||
.vidioc_s_register = vidioc_s_register,
|
||||
#endif
|
||||
.vidioc_g_chip_ident = vidioc_g_chip_ident,
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
.vidiocgmbuf = vidiocgmbuf,
|
||||
#endif
|
||||
|
@ -69,6 +69,10 @@ typedef void (*cam_v_op) (struct gspca_dev *);
|
||||
typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
|
||||
typedef int (*cam_jpg_op) (struct gspca_dev *,
|
||||
struct v4l2_jpegcompression *);
|
||||
typedef int (*cam_reg_op) (struct gspca_dev *,
|
||||
struct v4l2_dbg_register *);
|
||||
typedef int (*cam_ident_op) (struct gspca_dev *,
|
||||
struct v4l2_dbg_chip_ident *);
|
||||
typedef int (*cam_streamparm_op) (struct gspca_dev *,
|
||||
struct v4l2_streamparm *);
|
||||
typedef int (*cam_qmnu_op) (struct gspca_dev *,
|
||||
@ -105,6 +109,11 @@ struct sd_desc {
|
||||
cam_qmnu_op querymenu;
|
||||
cam_streamparm_op get_streamparm;
|
||||
cam_streamparm_op set_streamparm;
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
cam_reg_op set_register;
|
||||
cam_reg_op get_register;
|
||||
#endif
|
||||
cam_ident_op get_chip_ident;
|
||||
};
|
||||
|
||||
/* packet types when moving from iso buf to frame buf */
|
||||
|
@ -474,9 +474,6 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
|
||||
|
||||
PDEBUG(D_V4L2, "Set vertical flip to %d", val);
|
||||
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -522,9 +519,6 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
|
||||
|
||||
PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
|
||||
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -201,6 +201,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x21); /* JPEG 422 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
2434
drivers/media/video/gspca/sn9c20x.c
Normal file
2434
drivers/media/video/gspca/sn9c20x.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1634,6 +1634,8 @@ static void setfreq(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
|
||||
return;
|
||||
if (sd->sensor == SENSOR_OV7660) {
|
||||
switch (sd->freq) {
|
||||
case 0: /* Banding filter disabled */
|
||||
@ -1735,6 +1737,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x21); /* JPEG 422 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
@ -670,6 +670,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x22); /* JPEG 411 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
@ -333,6 +333,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x22); /* JPEG 411 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
@ -64,7 +64,7 @@ static struct v4l2_pix_format hdcs1x00_mode[] = {
|
||||
{
|
||||
HDCS_1X00_DEF_WIDTH,
|
||||
HDCS_1X00_DEF_HEIGHT,
|
||||
V4L2_PIX_FMT_SBGGR8,
|
||||
V4L2_PIX_FMT_SGRBG8,
|
||||
V4L2_FIELD_NONE,
|
||||
.sizeimage =
|
||||
HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
|
||||
@ -80,7 +80,7 @@ static struct v4l2_pix_format hdcs1020_mode[] = {
|
||||
{
|
||||
HDCS_1020_DEF_WIDTH,
|
||||
HDCS_1020_DEF_HEIGHT,
|
||||
V4L2_PIX_FMT_SBGGR8,
|
||||
V4L2_PIX_FMT_SGRBG8,
|
||||
V4L2_FIELD_NONE,
|
||||
.sizeimage =
|
||||
HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
|
||||
@ -131,9 +131,11 @@ static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
|
||||
(reg + len > 0xff)))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < len; i++, reg++) {
|
||||
regs[2*i] = reg;
|
||||
regs[2*i+1] = vals[i];
|
||||
for (i = 0; i < len; i++) {
|
||||
regs[2 * i] = reg;
|
||||
regs[2 * i + 1] = vals[i];
|
||||
/* All addresses are shifted left one bit as bit 0 toggles r/w */
|
||||
reg += 2;
|
||||
}
|
||||
|
||||
return stv06xx_write_sensor_bytes(sd, regs, len);
|
||||
@ -174,7 +176,9 @@ static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
|
||||
}
|
||||
|
||||
ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
|
||||
if (ret < 0)
|
||||
|
||||
/* Update the state if the write succeeded */
|
||||
if (!ret)
|
||||
hdcs->state = state;
|
||||
|
||||
return ret;
|
||||
|
@ -973,6 +973,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x22); /* JPEG 411 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
@ -7243,6 +7243,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
/* create the JPEG header */
|
||||
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
|
||||
if (!sd->jpeg_hdr)
|
||||
return -ENOMEM;
|
||||
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
|
||||
0x21); /* JPEG 422 */
|
||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/div64.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include "mt9v011.h"
|
||||
#include <media/v4l2-i2c-drv.h>
|
||||
@ -57,6 +58,7 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = {
|
||||
struct mt9v011 {
|
||||
struct v4l2_subdev sd;
|
||||
unsigned width, height;
|
||||
unsigned xtal;
|
||||
|
||||
u16 global_gain, red_bal, blue_bal;
|
||||
};
|
||||
@ -131,7 +133,7 @@ static const struct i2c_reg_value mt9v011_init_default[] = {
|
||||
{ R1E_MT9V011_DIGITAL_ZOOM, 0x0000 },
|
||||
{ R20_MT9V011_READ_MODE, 0x1000 },
|
||||
|
||||
{ R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */
|
||||
{ R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */
|
||||
};
|
||||
|
||||
static void set_balance(struct v4l2_subdev *sd)
|
||||
@ -154,6 +156,31 @@ static void set_balance(struct v4l2_subdev *sd)
|
||||
mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
|
||||
}
|
||||
|
||||
static void calc_fps(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct mt9v011 *core = to_mt9v011(sd);
|
||||
unsigned height, width, hblank, vblank, speed;
|
||||
unsigned row_time, t_time;
|
||||
u64 frames_per_ms;
|
||||
unsigned tmp;
|
||||
|
||||
height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
|
||||
width = mt9v011_read(sd, R04_MT9V011_WIDTH);
|
||||
hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
|
||||
vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
|
||||
speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED);
|
||||
|
||||
row_time = (width + 113 + hblank) * (speed + 2);
|
||||
t_time = row_time * (height + vblank + 1);
|
||||
|
||||
frames_per_ms = core->xtal * 1000l;
|
||||
do_div(frames_per_ms, t_time);
|
||||
tmp = frames_per_ms;
|
||||
|
||||
v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
|
||||
tmp / 1000, tmp % 1000, t_time);
|
||||
}
|
||||
|
||||
static void set_res(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct mt9v011 *core = to_mt9v011(sd);
|
||||
@ -175,10 +202,12 @@ static void set_res(struct v4l2_subdev *sd)
|
||||
mt9v011_write(sd, R04_MT9V011_WIDTH, core->width);
|
||||
mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width);
|
||||
|
||||
vstart = 8 + (640 - core->height) / 2;
|
||||
vstart = 8 + (480 - core->height) / 2;
|
||||
mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart);
|
||||
mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
|
||||
mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
|
||||
|
||||
calc_fps(sd);
|
||||
};
|
||||
|
||||
static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
|
||||
@ -215,6 +244,23 @@ static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
|
||||
{
|
||||
int i;
|
||||
|
||||
v4l2_dbg(1, debug, sd, "queryctrl called\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
|
||||
if (qc->id && qc->id == mt9v011_qctrl[i].id) {
|
||||
memcpy(qc, &(mt9v011_qctrl[i]),
|
||||
sizeof(*qc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
|
||||
{
|
||||
struct mt9v011 *core = to_mt9v011(sd);
|
||||
@ -294,6 +340,22 @@ static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data)
|
||||
{
|
||||
struct mt9v011 *core = to_mt9v011(sd);
|
||||
unsigned *xtal = data;
|
||||
|
||||
v4l2_dbg(1, debug, sd, "s_config called\n");
|
||||
|
||||
if (xtal) {
|
||||
core->xtal = *xtal;
|
||||
v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n",
|
||||
*xtal / 1000000, (*xtal / 1000) % 1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
static int mt9v011_g_register(struct v4l2_subdev *sd,
|
||||
@ -338,9 +400,11 @@ static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
|
||||
.queryctrl = mt9v011_queryctrl,
|
||||
.g_ctrl = mt9v011_g_ctrl,
|
||||
.s_ctrl = mt9v011_s_ctrl,
|
||||
.reset = mt9v011_reset,
|
||||
.s_config = mt9v011_s_config,
|
||||
.g_chip_ident = mt9v011_g_chip_ident,
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
.g_register = mt9v011_g_register,
|
||||
@ -395,6 +459,7 @@ static int mt9v011_probe(struct i2c_client *c,
|
||||
core->global_gain = 0x0024;
|
||||
core->width = 640;
|
||||
core->height = 480;
|
||||
core->xtal = 27000000; /* Hz */
|
||||
|
||||
v4l_info(c, "chip found @ 0x%02x (%s)\n",
|
||||
c->addr << 1, c->adapter->name);
|
||||
|
@ -338,6 +338,7 @@ struct v4l2_pix_format {
|
||||
/* Vendor-specific formats */
|
||||
#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
|
||||
#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
|
||||
#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */
|
||||
#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */
|
||||
#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */
|
||||
#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
|
||||
|
@ -60,6 +60,10 @@ enum {
|
||||
V4L2_IDENT_OV7670 = 250,
|
||||
V4L2_IDENT_OV7720 = 251,
|
||||
V4L2_IDENT_OV7725 = 252,
|
||||
V4L2_IDENT_OV7660 = 253,
|
||||
V4L2_IDENT_OV9650 = 254,
|
||||
V4L2_IDENT_OV9655 = 255,
|
||||
V4L2_IDENT_SOI968 = 256,
|
||||
|
||||
/* module saa7146: reserved range 300-309 */
|
||||
V4L2_IDENT_SAA7146 = 300,
|
||||
@ -161,6 +165,9 @@ enum {
|
||||
/* module tw9910: just ident 9910 */
|
||||
V4L2_IDENT_TW9910 = 9910,
|
||||
|
||||
/* module sn9c20x: just ident 10000 */
|
||||
V4L2_IDENT_SN9C20X = 10000,
|
||||
|
||||
/* module msp3400: reserved range 34000-34999 and 44000-44999 */
|
||||
V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only
|
||||
use internally (tveeprom.c). */
|
||||
@ -237,6 +244,11 @@ enum {
|
||||
V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */
|
||||
V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */
|
||||
V4L2_IDENT_MT9T031 = 45020,
|
||||
V4L2_IDENT_MT9V111 = 45031,
|
||||
V4L2_IDENT_MT9V112 = 45032,
|
||||
|
||||
/* HV7131R CMOS sensor: just ident 46000 */
|
||||
V4L2_IDENT_HV7131R = 46000,
|
||||
|
||||
/* module cs53132a: just ident 53132 */
|
||||
V4L2_IDENT_CS53l32A = 53132,
|
||||
|
Loading…
Reference in New Issue
Block a user