forked from Minki/linux
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: (62 commits) V4L/DVB (12131): BUGFIX: An incorrect Carrier Recovery Loop optimization table was being V4L/DVB (12130): Fix a redundant compiler warning V4L/DVB (12003): v4l2: Move bounding code outside I2C ifdef block V4L/DVB (11913): cx231xx: TRY_FMT should not actually set anything V4L/DVB (11912): em28xx: Use v4l bounding/alignment function V4L/DVB (11911): cx231xx: Use v4l bounding/alignment function V4L/DVB (11910): mt9: Use v4l bounding/alignment function V4L/DVB (11909): cx23885: Use v4l bounding/alignment function V4L/DVB (11908): w8968cf: Use v4l bounding/alignment function V4L/DVB (11907): cx88: Use v4l bounding/alignment function V4L/DVB (11906): saa7134: Use v4l bounding/alignment function V4L/DVB (11905): vivi: Use v4l bounding/alignment function V4L/DVB (11904): zoran: Use v4l bounding/alignment functiob V4L/DVB (11903): sh_mobile_ceu_camera: Use v4l bounding/alignment function V4L/DVB (11902): pxa-camera: Use v4l bounding/alignment function V4L/DVB (11901): v4l2: Create helper function for bounding and aligning images V4L/DVB (12128): v4l2: update framework documentation. V4L/DVB (12125): v4l2: add new s_config subdev ops and v4l2_i2c_new_subdev_cfg/board calls V4L/DVB (12122): pvrusb2: De-obfuscate code which handles routing schemes V4L/DVB (12121): pvrusb2: Improve handling of routing schemes ...
This commit is contained in:
commit
135aae340d
@ -6,8 +6,8 @@
|
||||
5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613]
|
||||
6 -> AverTV Studio 303 (M126) [1461:000b]
|
||||
7 -> MSI TV-@nywhere Master [1462:8606]
|
||||
8 -> Leadtek Winfast DV2000 [107d:6620]
|
||||
9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632]
|
||||
8 -> Leadtek Winfast DV2000 [107d:6620,107d:6621]
|
||||
9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632,107d:6630,107d:6638,107d:6631,107d:6637,107d:663d]
|
||||
10 -> IODATA GV-VCP3/PCI [10fc:d003]
|
||||
11 -> Prolink PlayTV PVR
|
||||
12 -> ASUS PVR-416 [1043:4823,1461:c111]
|
||||
@ -59,7 +59,7 @@
|
||||
58 -> Pinnacle PCTV HD 800i [11bd:0051]
|
||||
59 -> DViCO FusionHDTV 5 PCI nano [18ac:d530]
|
||||
60 -> Pinnacle Hybrid PCTV [12ab:1788]
|
||||
61 -> Winfast TV2000 XP Global [107d:6f18]
|
||||
61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618]
|
||||
62 -> PowerColor RA330 [14f1:ea3d]
|
||||
63 -> Geniatech X8000-MT DVBT [14f1:8852]
|
||||
64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30]
|
||||
|
@ -65,3 +65,4 @@
|
||||
67 -> Terratec Grabby (em2860) [0ccd:0096]
|
||||
68 -> Terratec AV350 (em2860) [0ccd:0084]
|
||||
69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313]
|
||||
70 -> Evga inDtube (em2882)
|
||||
|
@ -390,6 +390,30 @@ later date. It differs between i2c drivers and as such can be confusing.
|
||||
To see which chip variants are supported you can look in the i2c driver code
|
||||
for the i2c_device_id table. This lists all the possibilities.
|
||||
|
||||
There are two more helper functions:
|
||||
|
||||
v4l2_i2c_new_subdev_cfg: this function adds new irq and platform_data
|
||||
arguments and has both 'addr' and 'probed_addrs' arguments: if addr is not
|
||||
0 then that will be used (non-probing variant), otherwise the probed_addrs
|
||||
are probed.
|
||||
|
||||
For example: this will probe for address 0x10:
|
||||
|
||||
struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter,
|
||||
"module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10));
|
||||
|
||||
v4l2_i2c_new_subdev_board uses an i2c_board_info struct which is passed
|
||||
to the i2c driver and replaces the irq, platform_data and addr arguments.
|
||||
|
||||
If the subdev supports the s_config core ops, then that op is called with
|
||||
the irq and platform_data arguments after the subdev was setup. The older
|
||||
v4l2_i2c_new_(probed_)subdev functions will call s_config as well, but with
|
||||
irq set to 0 and platform_data set to NULL.
|
||||
|
||||
Note that in the next kernel release the functions v4l2_i2c_new_subdev,
|
||||
v4l2_i2c_new_probed_subdev and v4l2_i2c_new_probed_subdev_addr will all be
|
||||
replaced by a single v4l2_i2c_new_subdev that is identical to
|
||||
v4l2_i2c_new_subdev_cfg but without the irq and platform_data arguments.
|
||||
|
||||
struct video_device
|
||||
-------------------
|
||||
|
@ -2750,3 +2750,26 @@ IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = {
|
||||
[0x1b] = KEY_B, /*recall*/
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec);
|
||||
|
||||
/* EVGA inDtube
|
||||
Devin Heitmueller <devin.heitmueller@gmail.com>
|
||||
*/
|
||||
IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = {
|
||||
[0x12] = KEY_POWER,
|
||||
[0x02] = KEY_MODE, /* TV */
|
||||
[0x14] = KEY_MUTE,
|
||||
[0x1a] = KEY_CHANNELUP,
|
||||
[0x16] = KEY_TV2, /* PIP */
|
||||
[0x1d] = KEY_VOLUMEUP,
|
||||
[0x05] = KEY_CHANNELDOWN,
|
||||
[0x0f] = KEY_PLAYPAUSE,
|
||||
[0x19] = KEY_VOLUMEDOWN,
|
||||
[0x1c] = KEY_REWIND,
|
||||
[0x0d] = KEY_RECORD,
|
||||
[0x18] = KEY_FORWARD,
|
||||
[0x1e] = KEY_PREVIOUS,
|
||||
[0x1b] = KEY_STOP,
|
||||
[0x1f] = KEY_NEXT,
|
||||
[0x13] = KEY_CAMERA,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_evga_indtube);
|
||||
|
@ -29,6 +29,11 @@
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
struct stv0900_reg {
|
||||
u16 addr;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
struct stv0900_config {
|
||||
u8 demod_address;
|
||||
u32 xtal;
|
||||
@ -38,7 +43,7 @@ struct stv0900_config {
|
||||
|
||||
u8 path1_mode;
|
||||
u8 path2_mode;
|
||||
|
||||
struct stv0900_reg *ts_config_regs;
|
||||
u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
|
||||
u8 tun2_maddress;
|
||||
u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
|
||||
|
@ -149,31 +149,31 @@ void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
|
||||
dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
|
||||
}
|
||||
|
||||
u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr)
|
||||
u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg)
|
||||
{
|
||||
u8 data[2];
|
||||
int ret;
|
||||
struct i2c_msg i2cmsg = {
|
||||
.addr = i_params->i2c_addr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = data,
|
||||
u8 b0[] = { MSB(reg), LSB(reg) };
|
||||
u8 buf = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i_params->i2c_addr,
|
||||
.flags = 0,
|
||||
.buf = b0,
|
||||
.len = 2,
|
||||
}, {
|
||||
.addr = i_params->i2c_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.buf = &buf,
|
||||
.len = 1,
|
||||
},
|
||||
};
|
||||
|
||||
data[0] = MSB(reg_addr);
|
||||
data[1] = LSB(reg_addr);
|
||||
ret = i2c_transfer(i_params->i2c_adap, msg, 2);
|
||||
if (ret != 2)
|
||||
dprintk(KERN_ERR "%s: i2c error %d, reg[0x%02x]\n",
|
||||
__func__, ret, reg);
|
||||
|
||||
ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
|
||||
if (ret != 1)
|
||||
dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
|
||||
|
||||
i2cmsg.flags = I2C_M_RD;
|
||||
i2cmsg.len = 1;
|
||||
ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
|
||||
if (ret != 1)
|
||||
dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
|
||||
|
||||
return data[0];
|
||||
return buf;
|
||||
}
|
||||
|
||||
void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
|
||||
@ -712,6 +712,44 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
|
||||
return c_n;
|
||||
}
|
||||
|
||||
static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
|
||||
{
|
||||
struct stv0900_state *state = fe->demodulator_priv;
|
||||
struct stv0900_internal *i_params = state->internal;
|
||||
enum fe_stv0900_demod_num demod = state->demod;
|
||||
u8 err_val1, err_val0;
|
||||
s32 err_field1, err_field0;
|
||||
u32 header_err_val = 0;
|
||||
|
||||
*ucblocks = 0x0;
|
||||
if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
|
||||
/* DVB-S2 delineator errors count */
|
||||
|
||||
/* retreiving number for errnous headers */
|
||||
dmd_reg(err_field0, R0900_P1_BBFCRCKO0,
|
||||
R0900_P2_BBFCRCKO0);
|
||||
dmd_reg(err_field1, R0900_P1_BBFCRCKO1,
|
||||
R0900_P2_BBFCRCKO1);
|
||||
|
||||
err_val1 = stv0900_read_reg(i_params, err_field1);
|
||||
err_val0 = stv0900_read_reg(i_params, err_field0);
|
||||
header_err_val = (err_val1<<8) | err_val0;
|
||||
|
||||
/* retreiving number for errnous packets */
|
||||
dmd_reg(err_field0, R0900_P1_UPCRCKO0,
|
||||
R0900_P2_UPCRCKO0);
|
||||
dmd_reg(err_field1, R0900_P1_UPCRCKO1,
|
||||
R0900_P2_UPCRCKO1);
|
||||
|
||||
err_val1 = stv0900_read_reg(i_params, err_field1);
|
||||
err_val0 = stv0900_read_reg(i_params, err_field0);
|
||||
*ucblocks = (err_val1<<8) | err_val0;
|
||||
*ucblocks += header_err_val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
*snr = stv0900_carr_get_quality(fe,
|
||||
@ -1355,7 +1393,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
|
||||
struct stv0900_state *state = fe->demodulator_priv;
|
||||
enum fe_stv0900_error error = STV0900_NO_ERROR;
|
||||
enum fe_stv0900_error demodError = STV0900_NO_ERROR;
|
||||
int selosci;
|
||||
int selosci, i;
|
||||
|
||||
struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
|
||||
state->config->demod_address);
|
||||
@ -1402,7 +1440,23 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
|
||||
stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
|
||||
stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
|
||||
|
||||
stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock);
|
||||
state->internal->ts_config = p_init->ts_config;
|
||||
if (state->internal->ts_config == NULL)
|
||||
stv0900_set_ts_parallel_serial(state->internal,
|
||||
p_init->path1_ts_clock,
|
||||
p_init->path2_ts_clock);
|
||||
else {
|
||||
for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++)
|
||||
stv0900_write_reg(state->internal,
|
||||
state->internal->ts_config[i].addr,
|
||||
state->internal->ts_config[i].val);
|
||||
|
||||
stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1);
|
||||
stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0);
|
||||
stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1);
|
||||
stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0);
|
||||
}
|
||||
|
||||
stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
|
||||
switch (p_init->tuner1_adc) {
|
||||
case 1:
|
||||
@ -1882,6 +1936,7 @@ static struct dvb_frontend_ops stv0900_ops = {
|
||||
.read_ber = stv0900_read_ber,
|
||||
.read_signal_strength = stv0900_read_signal_strength,
|
||||
.read_snr = stv0900_read_snr,
|
||||
.read_ucblocks = stv0900_read_ucblocks,
|
||||
};
|
||||
|
||||
struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
|
||||
@ -1915,6 +1970,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
|
||||
init_params.tun1_iq_inversion = STV0900_IQ_NORMAL;
|
||||
init_params.tuner1_adc = config->tun1_adc;
|
||||
init_params.path2_ts_clock = config->path2_mode;
|
||||
init_params.ts_config = config->ts_config_regs;
|
||||
init_params.tun2_maddress = config->tun2_maddress;
|
||||
init_params.tuner2_adc = config->tun2_adc;
|
||||
init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED;
|
||||
|
@ -271,6 +271,7 @@ struct stv0900_init_params{
|
||||
|
||||
/* IQ from the tuner2 to the demod */
|
||||
enum stv0900_iq_inversion tun2_iq_inversion;
|
||||
struct stv0900_reg *ts_config;
|
||||
};
|
||||
|
||||
struct stv0900_search_params {
|
||||
@ -363,6 +364,7 @@ struct stv0900_internal{
|
||||
u8 i2c_addr;
|
||||
u8 clkmode;/* 0 for CLKI, 2 for XTALI */
|
||||
u8 chip_id;
|
||||
struct stv0900_reg *ts_config;
|
||||
enum fe_stv0900_error errs;
|
||||
int dmds_used;
|
||||
};
|
||||
|
@ -2674,7 +2674,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
|
||||
|
||||
static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
|
||||
{
|
||||
struct stv090x_short_frame_crloop *short_crl;
|
||||
struct stv090x_short_frame_crloop *short_crl = NULL;
|
||||
s32 index = 0;
|
||||
u8 aclc = 0x0b;
|
||||
|
||||
@ -2694,10 +2694,13 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
|
||||
break;
|
||||
}
|
||||
|
||||
if (state->dev_ver >= 0x30)
|
||||
short_crl = stv090x_s2_short_crl_cut20;
|
||||
else if (state->dev_ver >= 0x20)
|
||||
if (state->dev_ver >= 0x30) {
|
||||
/* Cut 3.0 and up */
|
||||
short_crl = stv090x_s2_short_crl_cut30;
|
||||
} else {
|
||||
/* Cut 2.0 and up: we don't support cuts older than 2.0 */
|
||||
short_crl = stv090x_s2_short_crl_cut20;
|
||||
}
|
||||
|
||||
if (state->srate <= 3000000)
|
||||
aclc = short_crl[index].crl_2;
|
||||
|
@ -210,6 +210,7 @@ static struct pll_tab {
|
||||
{ TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 },
|
||||
{ TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 },
|
||||
{ TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 },
|
||||
{ TDA10048_CLK_16000, TDA10048_IF_3800, 10, 3, 0 },
|
||||
{ TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 },
|
||||
{ TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 },
|
||||
{ TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 },
|
||||
|
@ -1422,8 +1422,8 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
|
||||
struct smscore_gpio_config *pGpioConfig) {
|
||||
|
||||
u32 totalLen;
|
||||
u32 TranslatedPinNum;
|
||||
u32 GroupNum;
|
||||
u32 TranslatedPinNum = 0;
|
||||
u32 GroupNum = 0;
|
||||
u32 ElectricChar;
|
||||
u32 groupCfg;
|
||||
void *buffer;
|
||||
|
@ -322,7 +322,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
|
||||
v->rangehigh = FREQ_MAX * FREQ_MUL;
|
||||
v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
if (r->tunchk & TEA5764_TUNCHK_STEREO)
|
||||
v->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
v->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
else
|
||||
v->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
v->audmode = tea5764_get_audout_mode(radio);
|
||||
v->signal = TEA5764_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf;
|
||||
v->afc = TEA5764_TUNCHK_IFCNT(r->tunchk);
|
||||
|
@ -866,9 +866,13 @@ config USB_W9968CF
|
||||
module will be called w9968cf.
|
||||
|
||||
config USB_OV511
|
||||
tristate "USB OV511 Camera support"
|
||||
tristate "USB OV511 Camera support (DEPRECATED)"
|
||||
depends on VIDEO_V4L1
|
||||
---help---
|
||||
This driver is DEPRECATED please use the gspca ov519 module
|
||||
instead. Note that for the ov511 / ov518 support of the gspca module
|
||||
you need atleast version 0.6.0 of libv4l.
|
||||
|
||||
Say Y here if you want to connect this type of camera to your
|
||||
computer's USB port. See <file:Documentation/video4linux/ov511.txt>
|
||||
for more information and for a list of supported cameras.
|
||||
|
@ -61,6 +61,8 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
|
||||
|
||||
switch (qctrl->id) {
|
||||
/* Standard V4L2 controls */
|
||||
case V4L2_CID_USER_CLASS:
|
||||
return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
case V4L2_CID_HUE:
|
||||
case V4L2_CID_SATURATION:
|
||||
|
@ -1052,22 +1052,13 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
|
||||
/* Set resolution of the video */
|
||||
int cx231xx_resolution_set(struct cx231xx *dev)
|
||||
{
|
||||
int width, height;
|
||||
u32 hscale, vscale;
|
||||
int status = 0;
|
||||
|
||||
width = dev->width;
|
||||
height = dev->height;
|
||||
|
||||
get_scale(dev, width, height, &hscale, &vscale);
|
||||
|
||||
/* set horzontal scale */
|
||||
status = vid_blk_write_word(dev, HSCALE_CTRL, hscale);
|
||||
int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* set vertical scale */
|
||||
status = vid_blk_write_word(dev, VSCALE_CTRL, vscale);
|
||||
|
||||
return status;
|
||||
return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -2055,7 +2046,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
|
||||
|
||||
int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
|
||||
{
|
||||
int rc;
|
||||
int rc = -1;
|
||||
u32 ep_mask = -1;
|
||||
struct pcb_config *pcb_config;
|
||||
|
||||
|
@ -893,9 +893,9 @@ static int check_dev(struct cx231xx *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void get_scale(struct cx231xx *dev,
|
||||
unsigned int width, unsigned int height,
|
||||
unsigned int *hscale, unsigned int *vscale)
|
||||
static void get_scale(struct cx231xx *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);
|
||||
@ -907,10 +907,6 @@ void get_scale(struct cx231xx *dev,
|
||||
*vscale = (((unsigned long)maxh) << 12) / height - 4096L;
|
||||
if (*vscale >= 0x4000)
|
||||
*vscale = 0x3fff;
|
||||
|
||||
dev->hscale = *hscale;
|
||||
dev->vscale = *vscale;
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
@ -955,8 +951,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
{
|
||||
struct cx231xx_fh *fh = priv;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
int width = f->fmt.pix.width;
|
||||
int height = f->fmt.pix.height;
|
||||
unsigned int width = f->fmt.pix.width;
|
||||
unsigned int height = f->fmt.pix.height;
|
||||
unsigned int maxw = norm_maxw(dev);
|
||||
unsigned int maxh = norm_maxh(dev);
|
||||
unsigned int hscale, vscale;
|
||||
@ -971,17 +967,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
|
||||
/* width must even because of the YUYV format
|
||||
height must be even because of interlacing */
|
||||
height &= 0xfffe;
|
||||
width &= 0xfffe;
|
||||
|
||||
if (unlikely(height < 32))
|
||||
height = 32;
|
||||
if (unlikely(height > maxh))
|
||||
height = maxh;
|
||||
if (unlikely(width < 48))
|
||||
width = 48;
|
||||
if (unlikely(width > maxw))
|
||||
width = maxw;
|
||||
v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
|
||||
|
||||
get_scale(dev, width, height, &hscale, &vscale);
|
||||
|
||||
|
@ -722,9 +722,6 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input);
|
||||
int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input);
|
||||
int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev);
|
||||
int cx231xx_set_audio_input(struct cx231xx *dev, u8 input);
|
||||
void get_scale(struct cx231xx *dev,
|
||||
unsigned int width, unsigned int height,
|
||||
unsigned int *hscale, unsigned int *vscale);
|
||||
|
||||
/* Provided by cx231xx-video.c */
|
||||
int cx231xx_register_extension(struct cx231xx_ops *dev);
|
||||
|
@ -500,6 +500,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
|
||||
int err;
|
||||
|
||||
switch (qctrl->id) {
|
||||
case V4L2_CID_MPEG_CLASS:
|
||||
return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
|
||||
case V4L2_CID_MPEG_STREAM_TYPE:
|
||||
return v4l2_ctrl_query_fill(qctrl,
|
||||
V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "dibx000_common.h"
|
||||
#include "zl10353.h"
|
||||
#include "stv0900.h"
|
||||
#include "stv0900_reg.h"
|
||||
#include "stv6110.h"
|
||||
#include "lnbh24.h"
|
||||
#include "cx24116.h"
|
||||
@ -242,12 +243,22 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = {
|
||||
.if_lvl = 6, .rfagc_top = 0x37 },
|
||||
};
|
||||
|
||||
static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
|
||||
.dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
|
||||
.if_lvl = 1, .rfagc_top = 0x37, },
|
||||
.dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
|
||||
.if_lvl = 1, .rfagc_top = 0x37, },
|
||||
.dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
|
||||
.if_lvl = 1, .rfagc_top = 0x37, },
|
||||
};
|
||||
|
||||
static struct tda18271_config hauppauge_tda18271_config = {
|
||||
.std_map = &hauppauge_tda18271_std_map,
|
||||
.gate = TDA18271_GATE_ANALOG,
|
||||
};
|
||||
|
||||
static struct tda18271_config hauppauge_hvr1200_tuner_config = {
|
||||
.std_map = &hauppauge_hvr1200_tda18271_std_map,
|
||||
.gate = TDA18271_GATE_ANALOG,
|
||||
};
|
||||
|
||||
@ -370,13 +381,25 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
|
||||
.disable_i2c_gate_ctrl = 1,
|
||||
};
|
||||
|
||||
static struct stv0900_reg stv0900_ts_regs[] = {
|
||||
{ R0900_TSGENERAL, 0x00 },
|
||||
{ R0900_P1_TSSPEED, 0x40 },
|
||||
{ R0900_P2_TSSPEED, 0x40 },
|
||||
{ R0900_P1_TSCFGM, 0xc0 },
|
||||
{ R0900_P2_TSCFGM, 0xc0 },
|
||||
{ R0900_P1_TSCFGH, 0xe0 },
|
||||
{ R0900_P2_TSCFGH, 0xe0 },
|
||||
{ R0900_P1_TSCFGL, 0x20 },
|
||||
{ R0900_P2_TSCFGL, 0x20 },
|
||||
{ 0xffff, 0xff }, /* terminate */
|
||||
};
|
||||
|
||||
static struct stv0900_config netup_stv0900_config = {
|
||||
.demod_address = 0x68,
|
||||
.xtal = 27000000,
|
||||
.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
|
||||
.diseqc_mode = 2,/* 2/3 PWM */
|
||||
.path1_mode = 2,/*Serial continues clock */
|
||||
.path2_mode = 2,/*Serial continues clock */
|
||||
.ts_config_regs = stv0900_ts_regs,
|
||||
.tun1_maddress = 0,/* 0x60 */
|
||||
.tun2_maddress = 3,/* 0x63 */
|
||||
.tun1_adc = 1,/* 1 Vpp */
|
||||
@ -736,7 +759,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
if (!dvb_attach(lnbh24_attach,
|
||||
fe0->dvb.frontend,
|
||||
&i2c_bus->i2c_adap,
|
||||
LNBH24_PCL, 0, 0x09))
|
||||
LNBH24_PCL,
|
||||
LNBH24_TTX, 0x09))
|
||||
printk(KERN_ERR
|
||||
"No LNBH24 found!\n");
|
||||
|
||||
@ -756,7 +780,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
if (!dvb_attach(lnbh24_attach,
|
||||
fe0->dvb.frontend,
|
||||
&i2c_bus->i2c_adap,
|
||||
LNBH24_PCL, 0, 0x0a))
|
||||
LNBH24_PCL,
|
||||
LNBH24_TTX, 0x0a))
|
||||
printk(KERN_ERR
|
||||
"No LNBH24 found!\n");
|
||||
|
||||
|
@ -963,15 +963,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
}
|
||||
|
||||
f->fmt.pix.field = field;
|
||||
if (f->fmt.pix.height < 32)
|
||||
f->fmt.pix.height = 32;
|
||||
if (f->fmt.pix.height > maxh)
|
||||
f->fmt.pix.height = maxh;
|
||||
if (f->fmt.pix.width < 48)
|
||||
f->fmt.pix.width = 48;
|
||||
if (f->fmt.pix.width > maxw)
|
||||
f->fmt.pix.width = maxw;
|
||||
f->fmt.pix.width &= ~0x03;
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
|
||||
&f->fmt.pix.height, 32, maxh, 0, 0);
|
||||
f->fmt.pix.bytesperline =
|
||||
(f->fmt.pix.width * fmt->depth) >> 3;
|
||||
f->fmt.pix.sizeimage =
|
||||
|
@ -1524,33 +1524,45 @@ static const struct cx88_board cx88_boards[] = {
|
||||
},
|
||||
.mpeg = CX88_MPEG_DVB,
|
||||
},
|
||||
/* Terry Wu <terrywu2009@gmail.com> */
|
||||
/* TV Audio : set GPIO 2, 18, 19 value to 0, 1, 0 */
|
||||
/* FM Audio : set GPIO 2, 18, 19 value to 0, 0, 0 */
|
||||
/* Line-in Audio : set GPIO 2, 18, 19 value to 0, 1, 1 */
|
||||
/* Mute Audio : set GPIO 2 value to 1 */
|
||||
[CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
|
||||
.name = "Winfast TV2000 XP Global",
|
||||
.name = "Leadtek TV2000 XP Global",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.tuner_addr = 0x61,
|
||||
.radio_type = TUNER_XC2028,
|
||||
.radio_addr = 0x61,
|
||||
.input = { {
|
||||
.type = CX88_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
.gpio0 = 0x0400, /* pin 2:mute = 0 (off?) */
|
||||
.gpio0 = 0x0400, /* pin 2 = 0 */
|
||||
.gpio1 = 0x0000,
|
||||
.gpio2 = 0x0800, /* pin 19:audio = 0 (tv) */
|
||||
|
||||
.gpio2 = 0x0C04, /* pin 18 = 1, pin 19 = 0 */
|
||||
.gpio3 = 0x0000,
|
||||
}, {
|
||||
.type = CX88_VMUX_COMPOSITE1,
|
||||
.vmux = 1,
|
||||
.gpio0 = 0x0400, /* probably? or 0x0404 to turn mute on */
|
||||
.gpio0 = 0x0400, /* pin 2 = 0 */
|
||||
.gpio1 = 0x0000,
|
||||
.gpio2 = 0x0808, /* pin 19:audio = 1 (line) */
|
||||
|
||||
.gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */
|
||||
.gpio3 = 0x0000,
|
||||
}, {
|
||||
.type = CX88_VMUX_SVIDEO,
|
||||
.vmux = 2,
|
||||
.gpio0 = 0x0400, /* pin 2 = 0 */
|
||||
.gpio1 = 0x0000,
|
||||
.gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */
|
||||
.gpio3 = 0x0000,
|
||||
} },
|
||||
.radio = {
|
||||
.type = CX88_RADIO,
|
||||
.gpio0 = 0x004ff,
|
||||
.gpio1 = 0x010ff,
|
||||
.gpio2 = 0x0ff,
|
||||
.gpio0 = 0x0400, /* pin 2 = 0 */
|
||||
.gpio1 = 0x0000,
|
||||
.gpio2 = 0x0C00, /* pin 18 = 0, pin 19 = 0 */
|
||||
.gpio3 = 0x0000,
|
||||
},
|
||||
},
|
||||
[CX88_BOARD_POWERCOLOR_REAL_ANGEL] = {
|
||||
@ -2438,6 +2450,41 @@ static const struct cx88_subid cx88_subids[] = {
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6654,
|
||||
.card = CX88_BOARD_WINFAST_DTV1800H,
|
||||
}, {
|
||||
/* PVR2000 PAL Model [107d:6630] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6630,
|
||||
.card = CX88_BOARD_LEADTEK_PVR2000,
|
||||
}, {
|
||||
/* PVR2000 PAL Model [107d:6638] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6638,
|
||||
.card = CX88_BOARD_LEADTEK_PVR2000,
|
||||
}, {
|
||||
/* PVR2000 NTSC Model [107d:6631] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6631,
|
||||
.card = CX88_BOARD_LEADTEK_PVR2000,
|
||||
}, {
|
||||
/* PVR2000 NTSC Model [107d:6637] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6637,
|
||||
.card = CX88_BOARD_LEADTEK_PVR2000,
|
||||
}, {
|
||||
/* PVR2000 NTSC Model [107d:663d] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x663d,
|
||||
.card = CX88_BOARD_LEADTEK_PVR2000,
|
||||
}, {
|
||||
/* DV2000 NTSC Model [107d:6621] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6621,
|
||||
.card = CX88_BOARD_WINFAST_DV2000,
|
||||
}, {
|
||||
/* TV2000 XP Global [107d:6618] */
|
||||
.subvendor = 0x107d,
|
||||
.subdevice = 0x6618,
|
||||
.card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
|
||||
},
|
||||
};
|
||||
|
||||
@ -2446,12 +2493,6 @@ static const struct cx88_subid cx88_subids[] = {
|
||||
|
||||
static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
|
||||
{
|
||||
/* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
|
||||
* any others.
|
||||
*
|
||||
* Byte 0 is 1 on the NTSC board.
|
||||
*/
|
||||
|
||||
if (eeprom_data[4] != 0x7d ||
|
||||
eeprom_data[5] != 0x10 ||
|
||||
eeprom_data[7] != 0x66) {
|
||||
@ -2459,8 +2500,19 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
|
||||
return;
|
||||
}
|
||||
|
||||
core->board.tuner_type = (eeprom_data[6] == 0x13) ?
|
||||
TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
|
||||
/* Terry Wu <terrywu2009@gmail.com> */
|
||||
switch (eeprom_data[6]) {
|
||||
case 0x13: /* SSID 6613 for TV2000 XP Expert NTSC Model */
|
||||
case 0x21: /* SSID 6621 for DV2000 NTSC Model */
|
||||
case 0x31: /* SSID 6631 for PVR2000 NTSC Model */
|
||||
case 0x37: /* SSID 6637 for PVR2000 NTSC Model */
|
||||
case 0x3d: /* SSID 6637 for PVR2000 NTSC Model */
|
||||
core->board.tuner_type = TUNER_PHILIPS_FM1236_MK3;
|
||||
break;
|
||||
default:
|
||||
core->board.tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
|
||||
break;
|
||||
}
|
||||
|
||||
info_printk(core, "Leadtek Winfast 2000XP Expert config: "
|
||||
"tuner=%d, eeprom[0]=0x%02x\n",
|
||||
@ -2713,7 +2765,6 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
|
||||
{
|
||||
/* Board-specific callbacks */
|
||||
switch (core->boardnr) {
|
||||
case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
|
||||
case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
|
||||
case CX88_BOARD_GENIATECH_X8000_MT:
|
||||
case CX88_BOARD_KWORLD_ATSC_120:
|
||||
@ -2725,6 +2776,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
|
||||
return cx88_dvico_xc2028_callback(core, command, arg);
|
||||
case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
|
||||
case CX88_BOARD_WINFAST_DTV1800H:
|
||||
return cx88_xc3028_winfast1800h_callback(core, command, arg);
|
||||
}
|
||||
@ -2914,6 +2966,7 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
|
||||
udelay(1000);
|
||||
break;
|
||||
|
||||
case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
|
||||
case CX88_BOARD_WINFAST_DTV1800H:
|
||||
/* GPIO 12 (xc3028 tuner reset) */
|
||||
cx_set(MO_GP1_IO, 0x1010);
|
||||
@ -2950,6 +3003,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
|
||||
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
|
||||
ctl->demod = XC3028_FE_OREN538;
|
||||
break;
|
||||
case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
|
||||
case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
|
||||
case CX88_BOARD_PROLINK_PV_8000GT:
|
||||
/*
|
||||
@ -2993,6 +3047,8 @@ static void cx88_card_setup(struct cx88_core *core)
|
||||
if (0 == core->i2c_rc)
|
||||
gdi_eeprom(core, eeprom);
|
||||
break;
|
||||
case CX88_BOARD_LEADTEK_PVR2000:
|
||||
case CX88_BOARD_WINFAST_DV2000:
|
||||
case CX88_BOARD_WINFAST2000XP_EXPERT:
|
||||
if (0 == core->i2c_rc)
|
||||
leadtek_eeprom(core, eeprom);
|
||||
|
@ -1111,15 +1111,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
}
|
||||
|
||||
f->fmt.pix.field = field;
|
||||
if (f->fmt.pix.height < 32)
|
||||
f->fmt.pix.height = 32;
|
||||
if (f->fmt.pix.height > maxh)
|
||||
f->fmt.pix.height = maxh;
|
||||
if (f->fmt.pix.width < 48)
|
||||
f->fmt.pix.width = 48;
|
||||
if (f->fmt.pix.width > maxw)
|
||||
f->fmt.pix.width = maxw;
|
||||
f->fmt.pix.width &= ~0x03;
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
|
||||
&f->fmt.pix.height, 32, maxh, 0, 0);
|
||||
f->fmt.pix.bytesperline =
|
||||
(f->fmt.pix.width * fmt->depth) >> 3;
|
||||
f->fmt.pix.sizeimage =
|
||||
|
@ -139,6 +139,24 @@ static struct em28xx_reg_seq kworld_330u_digital[] = {
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
/* Evga inDtube
|
||||
GPIO0 - Enable digital power (s5h1409) - low to enable
|
||||
GPIO1 - Enable analog power (tvp5150/emp202) - low to enable
|
||||
GPIO4 - xc3028 reset
|
||||
GOP3 - s5h1409 reset
|
||||
*/
|
||||
static struct em28xx_reg_seq evga_indtube_analog[] = {
|
||||
{EM28XX_R08_GPIO, 0x79, 0xff, 60},
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
static struct em28xx_reg_seq evga_indtube_digital[] = {
|
||||
{EM28XX_R08_GPIO, 0x7a, 0xff, 1},
|
||||
{EM2880_R04_GPO, 0x04, 0xff, 10},
|
||||
{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},
|
||||
@ -1449,6 +1467,33 @@ struct em28xx_board em28xx_boards[] = {
|
||||
.gpio = terratec_av350_unmute_gpio,
|
||||
} },
|
||||
},
|
||||
[EM2882_BOARD_EVGA_INDTUBE] = {
|
||||
.name = "Evga inDtube",
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.tuner_gpio = default_tuner_gpio,
|
||||
.decoder = EM28XX_TVP5150,
|
||||
.xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
|
||||
.mts_firmware = 1,
|
||||
.has_dvb = 1,
|
||||
.dvb_gpio = evga_indtube_digital,
|
||||
.ir_codes = ir_codes_evga_indtube,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_TELEVISION,
|
||||
.vmux = TVP5150_COMPOSITE0,
|
||||
.amux = EM28XX_AMUX_VIDEO,
|
||||
.gpio = evga_indtube_analog,
|
||||
}, {
|
||||
.type = EM28XX_VMUX_COMPOSITE1,
|
||||
.vmux = TVP5150_COMPOSITE1,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
.gpio = evga_indtube_analog,
|
||||
}, {
|
||||
.type = EM28XX_VMUX_SVIDEO,
|
||||
.vmux = TVP5150_SVIDEO,
|
||||
.amux = EM28XX_AMUX_LINE_IN,
|
||||
.gpio = evga_indtube_analog,
|
||||
} },
|
||||
},
|
||||
};
|
||||
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
|
||||
|
||||
@ -1571,6 +1616,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
|
||||
{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
|
||||
{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
|
||||
{0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
|
||||
{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
|
||||
};
|
||||
|
||||
/* I2C devicelist hash table for devices with generic USB IDs */
|
||||
@ -1834,6 +1880,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
|
||||
ctl->demod = XC3028_FE_CHINA;
|
||||
ctl->fname = XC2028_DEFAULT_FIRMWARE;
|
||||
break;
|
||||
case EM2882_BOARD_EVGA_INDTUBE:
|
||||
ctl->demod = XC3028_FE_CHINA;
|
||||
ctl->fname = XC3028L_DEFAULT_FIRMWARE;
|
||||
break;
|
||||
default:
|
||||
ctl->demod = XC3028_FE_OREN538;
|
||||
}
|
||||
@ -2101,6 +2151,12 @@ void em28xx_card_setup(struct em28xx *dev)
|
||||
case EM2880_BOARD_MSI_DIGIVOX_AD:
|
||||
if (!em28xx_hint_board(dev))
|
||||
em28xx_set_model(dev);
|
||||
|
||||
/* In cases where we had to use a board hint, the call to
|
||||
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_set_mode(dev, EM28XX_ANALOG_MODE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -445,6 +445,7 @@ static int dvb_init(struct em28xx *dev)
|
||||
}
|
||||
break;
|
||||
case EM2883_BOARD_KWORLD_HYBRID_330U:
|
||||
case EM2882_BOARD_EVGA_INDTUBE:
|
||||
dvb->frontend = dvb_attach(s5h1409_attach,
|
||||
&em28xx_s5h1409_with_xc3028,
|
||||
&dev->i2c_adap);
|
||||
|
@ -687,8 +687,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
{
|
||||
struct em28xx_fh *fh = priv;
|
||||
struct em28xx *dev = fh->dev;
|
||||
int width = f->fmt.pix.width;
|
||||
int height = f->fmt.pix.height;
|
||||
unsigned int width = f->fmt.pix.width;
|
||||
unsigned int height = f->fmt.pix.height;
|
||||
unsigned int maxw = norm_maxw(dev);
|
||||
unsigned int maxh = norm_maxh(dev);
|
||||
unsigned int hscale, vscale;
|
||||
@ -701,34 +701,20 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* width must even because of the YUYV format
|
||||
height must be even because of interlacing */
|
||||
height &= 0xfffe;
|
||||
width &= 0xfffe;
|
||||
|
||||
if (unlikely(height < 32))
|
||||
height = 32;
|
||||
if (unlikely(height > maxh))
|
||||
height = maxh;
|
||||
if (unlikely(width < 48))
|
||||
width = 48;
|
||||
if (unlikely(width > maxw))
|
||||
width = maxw;
|
||||
|
||||
if (dev->board.is_em2800) {
|
||||
/* the em2800 can only scale down to 50% */
|
||||
if (height % (maxh / 2))
|
||||
height = maxh;
|
||||
if (width % (maxw / 2))
|
||||
width = maxw;
|
||||
/* according to empiatech support */
|
||||
/* the MaxPacketSize is to small to support */
|
||||
/* framesizes larger than 640x480 @ 30 fps */
|
||||
/* or 640x576 @ 25 fps. As this would cut */
|
||||
/* of a part of the image we prefer */
|
||||
/* 360x576 or 360x480 for now */
|
||||
height = height > (3 * maxh / 4) ? maxh : maxh / 2;
|
||||
width = width > (3 * maxw / 4) ? maxw : maxw / 2;
|
||||
/* According to empiatech support the MaxPacketSize is too small
|
||||
* to support framesizes larger than 640x480 @ 30 fps or 640x576
|
||||
* @ 25 fps. As this would cut of a part of the image we prefer
|
||||
* 360x576 or 360x480 for now */
|
||||
if (width == maxw && height == maxh)
|
||||
width /= 2;
|
||||
} else {
|
||||
/* width must even because of the YUYV format
|
||||
height must be even because of interlacing */
|
||||
v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
|
||||
}
|
||||
|
||||
get_scale(dev, width, height, &hscale, &vscale);
|
||||
|
@ -106,6 +106,7 @@
|
||||
#define EM2860_BOARD_TERRATEC_GRABBY 67
|
||||
#define EM2860_BOARD_TERRATEC_AV350 68
|
||||
#define EM2882_BOARD_KWORLD_ATSC_315U 69
|
||||
#define EM2882_BOARD_EVGA_INDTUBE 70
|
||||
|
||||
/* Limits minimum and default number of buffers */
|
||||
#define EM28XX_MIN_BUF 4
|
||||
|
@ -1042,13 +1042,11 @@ static int vidioc_queryctrl(struct file *file, void *priv,
|
||||
for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
|
||||
if (gspca_dev->ctrl_dis & (1 << i))
|
||||
continue;
|
||||
if (ctrls->qctrl.id < id)
|
||||
if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
|
||||
continue;
|
||||
if (ctrls != NULL) {
|
||||
if (gspca_dev->sd_desc->ctrls[i].qctrl.id
|
||||
if (ctrls && gspca_dev->sd_desc->ctrls[i].qctrl.id
|
||||
> ctrls->qctrl.id)
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
ctrls = &gspca_dev->sd_desc->ctrls[i];
|
||||
}
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,7 @@ struct sd {
|
||||
u8 gamma;
|
||||
u8 vflip; /* ov7630/ov7648 only */
|
||||
u8 infrared; /* mt9v111 only */
|
||||
u8 freq; /* ov76xx only */
|
||||
u8 quality; /* image quality */
|
||||
#define QUALITY_MIN 60
|
||||
#define QUALITY_MAX 95
|
||||
@ -96,8 +97,11 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
|
||||
static struct ctrl sd_ctrls[] = {
|
||||
#define BRIGHTNESS_IDX 0
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_BRIGHTNESS,
|
||||
@ -113,6 +117,7 @@ static struct ctrl sd_ctrls[] = {
|
||||
.set = sd_setbrightness,
|
||||
.get = sd_getbrightness,
|
||||
},
|
||||
#define CONTRAST_IDX 1
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_CONTRAST,
|
||||
@ -128,20 +133,22 @@ static struct ctrl sd_ctrls[] = {
|
||||
.set = sd_setcontrast,
|
||||
.get = sd_getcontrast,
|
||||
},
|
||||
#define COLOR_IDX 2
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_SATURATION,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Color",
|
||||
.name = "Saturation",
|
||||
.minimum = 0,
|
||||
.maximum = 40,
|
||||
.step = 1,
|
||||
#define COLOR_DEF 32
|
||||
#define COLOR_DEF 25
|
||||
.default_value = COLOR_DEF,
|
||||
},
|
||||
.set = sd_setcolors,
|
||||
.get = sd_getcolors,
|
||||
},
|
||||
#define BLUE_BALANCE_IDX 3
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_BLUE_BALANCE,
|
||||
@ -156,6 +163,7 @@ static struct ctrl sd_ctrls[] = {
|
||||
.set = sd_setblue_balance,
|
||||
.get = sd_getblue_balance,
|
||||
},
|
||||
#define RED_BALANCE_IDX 4
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_RED_BALANCE,
|
||||
@ -170,6 +178,7 @@ static struct ctrl sd_ctrls[] = {
|
||||
.set = sd_setred_balance,
|
||||
.get = sd_getred_balance,
|
||||
},
|
||||
#define GAMMA_IDX 5
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_GAMMA,
|
||||
@ -184,7 +193,7 @@ static struct ctrl sd_ctrls[] = {
|
||||
.set = sd_setgamma,
|
||||
.get = sd_getgamma,
|
||||
},
|
||||
#define AUTOGAIN_IDX 5
|
||||
#define AUTOGAIN_IDX 6
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_AUTOGAIN,
|
||||
@ -200,7 +209,7 @@ static struct ctrl sd_ctrls[] = {
|
||||
.get = sd_getautogain,
|
||||
},
|
||||
/* ov7630/ov7648 only */
|
||||
#define VFLIP_IDX 6
|
||||
#define VFLIP_IDX 7
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_VFLIP,
|
||||
@ -209,14 +218,14 @@ static struct ctrl sd_ctrls[] = {
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.step = 1,
|
||||
#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
|
||||
#define VFLIP_DEF 0
|
||||
.default_value = VFLIP_DEF,
|
||||
},
|
||||
.set = sd_setvflip,
|
||||
.get = sd_getvflip,
|
||||
},
|
||||
/* mt9v111 only */
|
||||
#define INFRARED_IDX 7
|
||||
#define INFRARED_IDX 8
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_INFRARED,
|
||||
@ -231,28 +240,44 @@ static struct ctrl sd_ctrls[] = {
|
||||
.set = sd_setinfrared,
|
||||
.get = sd_getinfrared,
|
||||
},
|
||||
/* ov7630/ov7648/ov7660 only */
|
||||
#define FREQ_IDX 9
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_POWER_LINE_FREQUENCY,
|
||||
.type = V4L2_CTRL_TYPE_MENU,
|
||||
.name = "Light frequency filter",
|
||||
.minimum = 0,
|
||||
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
|
||||
.step = 1,
|
||||
#define FREQ_DEF 2
|
||||
.default_value = FREQ_DEF,
|
||||
},
|
||||
.set = sd_setfreq,
|
||||
.get = sd_getfreq,
|
||||
},
|
||||
};
|
||||
|
||||
/* table of the disabled controls */
|
||||
static __u32 ctrl_dis[] = {
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
|
||||
/* SENSOR_HV7131R 0 */
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
|
||||
/* SENSOR_MI0360 1 */
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
|
||||
/* SENSOR_MO4000 2 */
|
||||
(1 << VFLIP_IDX),
|
||||
(1 << VFLIP_IDX) | (1 << FREQ_IDX),
|
||||
/* SENSOR_MT9V111 3 */
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
|
||||
(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
|
||||
/* SENSOR_OM6802 4 */
|
||||
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
|
||||
(1 << INFRARED_IDX),
|
||||
/* SENSOR_OV7630 5 */
|
||||
(1 << INFRARED_IDX),
|
||||
/* SENSOR_OV7648 6 */
|
||||
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
|
||||
/* SENSOR_OV7660 7 */
|
||||
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
|
||||
/* SENSOR_SP80708 8 */
|
||||
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
|
||||
(1 << FREQ_IDX), /* SENSOR_SP80708 8 */
|
||||
};
|
||||
|
||||
static const struct v4l2_pix_format vga_mode[] = {
|
||||
@ -268,7 +293,8 @@ static const struct v4l2_pix_format vga_mode[] = {
|
||||
.priv = 1},
|
||||
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||
.bytesperline = 640,
|
||||
.sizeimage = 640 * 480 * 3 / 8 + 590,
|
||||
/* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
|
||||
.sizeimage = 640 * 480 * 3 / 4 + 590,
|
||||
.colorspace = V4L2_COLORSPACE_JPEG,
|
||||
.priv = 0},
|
||||
};
|
||||
@ -604,7 +630,9 @@ static const u8 ov7630_sensor_init[][8] = {
|
||||
/* win: i2c_r from 00 to 80 */
|
||||
{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
|
||||
{0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
|
||||
{0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
|
||||
/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
|
||||
0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
|
||||
{0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
|
||||
{0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
|
||||
{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
|
||||
{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
|
||||
@ -638,9 +666,8 @@ static const u8 ov7630_sensor_init[][8] = {
|
||||
{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
|
||||
/* */
|
||||
{0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
|
||||
/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
|
||||
/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
|
||||
/* */
|
||||
{0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
|
||||
/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
|
||||
@ -673,7 +700,7 @@ static const u8 ov7648_sensor_init[][8] = {
|
||||
{0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
|
||||
/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
|
||||
/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
|
||||
{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
|
||||
/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
|
||||
/*...*/
|
||||
/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
|
||||
/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
|
||||
@ -1294,11 +1321,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||
sd->gamma = GAMMA_DEF;
|
||||
sd->autogain = AUTOGAIN_DEF;
|
||||
sd->ag_cnt = -1;
|
||||
if (sd->sensor != SENSOR_OV7630)
|
||||
sd->vflip = 0;
|
||||
else
|
||||
sd->vflip = 1;
|
||||
sd->vflip = VFLIP_DEF;
|
||||
sd->infrared = INFRARED_DEF;
|
||||
sd->freq = FREQ_DEF;
|
||||
sd->quality = QUALITY_DEF;
|
||||
sd->jpegqual = 80;
|
||||
|
||||
@ -1569,7 +1594,7 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
||||
else
|
||||
comb = 0xa0;
|
||||
if (sd->autogain)
|
||||
comb |= 0x02;
|
||||
comb |= 0x03;
|
||||
i2c_w1(&sd->gspca_dev, 0x13, comb);
|
||||
return;
|
||||
}
|
||||
@ -1585,12 +1610,15 @@ static void setvflip(struct sd *sd)
|
||||
{
|
||||
u8 comn;
|
||||
|
||||
if (sd->sensor == SENSOR_OV7630)
|
||||
if (sd->sensor == SENSOR_OV7630) {
|
||||
comn = 0x02;
|
||||
else
|
||||
if (!sd->vflip)
|
||||
comn |= 0x80;
|
||||
} else {
|
||||
comn = 0x06;
|
||||
if (sd->vflip)
|
||||
comn |= 0x80;
|
||||
if (sd->vflip)
|
||||
comn |= 0x80;
|
||||
}
|
||||
i2c_w1(&sd->gspca_dev, 0x75, comn);
|
||||
}
|
||||
|
||||
@ -1602,6 +1630,58 @@ static void setinfrared(struct sd *sd)
|
||||
sd->infrared ? 0x66 : 0x64);
|
||||
}
|
||||
|
||||
static void setfreq(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->sensor == SENSOR_OV7660) {
|
||||
switch (sd->freq) {
|
||||
case 0: /* Banding filter disabled */
|
||||
i2c_w1(gspca_dev, 0x13, 0xdf);
|
||||
break;
|
||||
case 1: /* 50 hz */
|
||||
i2c_w1(gspca_dev, 0x13, 0xff);
|
||||
i2c_w1(gspca_dev, 0x3b, 0x0a);
|
||||
break;
|
||||
case 2: /* 60 hz */
|
||||
i2c_w1(gspca_dev, 0x13, 0xff);
|
||||
i2c_w1(gspca_dev, 0x3b, 0x02);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
u8 reg2a = 0, reg2b = 0, reg2d = 0;
|
||||
|
||||
/* Get reg2a / reg2d base values */
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_OV7630:
|
||||
reg2a = 0x08;
|
||||
reg2d = 0x01;
|
||||
break;
|
||||
case SENSOR_OV7648:
|
||||
reg2a = 0x11;
|
||||
reg2d = 0x81;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (sd->freq) {
|
||||
case 0: /* Banding filter disabled */
|
||||
break;
|
||||
case 1: /* 50 hz (filter on and framerate adj) */
|
||||
reg2a |= 0x80;
|
||||
reg2b = 0xac;
|
||||
reg2d |= 0x04;
|
||||
break;
|
||||
case 2: /* 60 hz (filter on, no framerate adj) */
|
||||
reg2a |= 0x80;
|
||||
reg2d |= 0x04;
|
||||
break;
|
||||
}
|
||||
i2c_w1(gspca_dev, 0x2a, reg2a);
|
||||
i2c_w1(gspca_dev, 0x2b, reg2b);
|
||||
i2c_w1(gspca_dev, 0x2d, reg2d);
|
||||
}
|
||||
}
|
||||
|
||||
static void setjpegqual(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
@ -1828,6 +1908,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
setbrightness(gspca_dev);
|
||||
setcontrast(gspca_dev);
|
||||
setautogain(gspca_dev);
|
||||
setfreq(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2131,6 +2212,24 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->freq = val;
|
||||
if (gspca_dev->streaming)
|
||||
setfreq(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->freq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
|
||||
struct v4l2_jpegcompression *jcomp)
|
||||
{
|
||||
@ -2159,6 +2258,27 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_querymenu(struct gspca_dev *gspca_dev,
|
||||
struct v4l2_querymenu *menu)
|
||||
{
|
||||
switch (menu->id) {
|
||||
case V4L2_CID_POWER_LINE_FREQUENCY:
|
||||
switch (menu->index) {
|
||||
case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
|
||||
strcpy((char *) menu->name, "NoFliker");
|
||||
return 0;
|
||||
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
|
||||
strcpy((char *) menu->name, "50 Hz");
|
||||
return 0;
|
||||
case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
|
||||
strcpy((char *) menu->name, "60 Hz");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* sub-driver description */
|
||||
static const struct sd_desc sd_desc = {
|
||||
.name = MODULE_NAME,
|
||||
@ -2173,6 +2293,7 @@ static const struct sd_desc sd_desc = {
|
||||
.dq_callback = do_autogain,
|
||||
.get_jcomp = sd_get_jcomp,
|
||||
.set_jcomp = sd_set_jcomp,
|
||||
.querymenu = sd_querymenu,
|
||||
};
|
||||
|
||||
/* -- module initialisation -- */
|
||||
@ -2233,7 +2354,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
|
||||
{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
|
||||
#endif
|
||||
{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
|
||||
/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
|
||||
{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
|
||||
{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
|
||||
{}
|
||||
};
|
||||
|
@ -3,7 +3,8 @@ obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o
|
||||
gspca_stv06xx-objs := stv06xx.o \
|
||||
stv06xx_vv6410.o \
|
||||
stv06xx_hdcs.o \
|
||||
stv06xx_pb0100.o
|
||||
stv06xx_pb0100.o \
|
||||
stv06xx_st6422.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/video/gspca
|
||||
|
||||
|
@ -92,11 +92,10 @@ static int stv06xx_write_sensor_finish(struct sd *sd)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (IS_850(sd)) {
|
||||
if (sd->bridge == BRIDGE_STV610) {
|
||||
struct usb_device *udev = sd->gspca_dev.dev;
|
||||
__u8 *buf = sd->gspca_dev.usb_buf;
|
||||
|
||||
/* Quickam Web needs an extra packet */
|
||||
buf[0] = 0;
|
||||
err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x04, 0x40, 0x1704, 0, buf, 1,
|
||||
@ -253,7 +252,7 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
|
||||
|
||||
err = sd->sensor->init(sd);
|
||||
|
||||
if (dump_sensor)
|
||||
if (dump_sensor && sd->sensor->dump)
|
||||
sd->sensor->dump(sd);
|
||||
|
||||
return (err < 0) ? err : 0;
|
||||
@ -318,6 +317,8 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
__u8 *data, /* isoc packet */
|
||||
int len) /* iso packet length */
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
PDEBUG(D_PACK, "Packet of length %d arrived", len);
|
||||
|
||||
/* A packet may contain several frames
|
||||
@ -343,14 +344,29 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
if (len < chunk_len) {
|
||||
PDEBUG(D_ERR, "URB packet length is smaller"
|
||||
" than the specified chunk length");
|
||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||
return;
|
||||
}
|
||||
|
||||
/* First byte seem to be 02=data 2nd byte is unknown??? */
|
||||
if (sd->bridge == BRIDGE_ST6422 && (id & 0xFF00) == 0x0200)
|
||||
goto frame_data;
|
||||
|
||||
switch (id) {
|
||||
case 0x0200:
|
||||
case 0x4200:
|
||||
frame_data:
|
||||
PDEBUG(D_PACK, "Frame data packet detected");
|
||||
|
||||
if (sd->to_skip) {
|
||||
int skip = (sd->to_skip < chunk_len) ?
|
||||
sd->to_skip : chunk_len;
|
||||
data += skip;
|
||||
len -= skip;
|
||||
chunk_len -= skip;
|
||||
sd->to_skip -= skip;
|
||||
}
|
||||
|
||||
gspca_frame_add(gspca_dev, INTER_PACKET, frame,
|
||||
data, chunk_len);
|
||||
break;
|
||||
@ -365,6 +381,9 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
gspca_frame_add(gspca_dev, FIRST_PACKET,
|
||||
frame, data, 0);
|
||||
|
||||
if (sd->bridge == BRIDGE_ST6422)
|
||||
sd->to_skip = gspca_dev->width * 4;
|
||||
|
||||
if (chunk_len)
|
||||
PDEBUG(D_ERR, "Chunk length is "
|
||||
"non-zero on a SOF");
|
||||
@ -395,8 +414,12 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
/* Unknown chunk with 2 bytes of data,
|
||||
occurs 2-3 times per USB interrupt */
|
||||
break;
|
||||
case 0x42ff:
|
||||
PDEBUG(D_PACK, "Chunk 0x42ff detected");
|
||||
/* Special chunk seen sometimes on the ST6422 */
|
||||
break;
|
||||
default:
|
||||
PDEBUG(D_PACK, "Unknown chunk %d detected", id);
|
||||
PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id);
|
||||
/* Unknown chunk */
|
||||
}
|
||||
data += chunk_len;
|
||||
@ -428,11 +451,16 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
|
||||
|
||||
cam = &gspca_dev->cam;
|
||||
sd->desc = sd_desc;
|
||||
sd->bridge = id->driver_info;
|
||||
gspca_dev->sd_desc = &sd->desc;
|
||||
|
||||
if (dump_bridge)
|
||||
stv06xx_dump_bridge(sd);
|
||||
|
||||
sd->sensor = &stv06xx_sensor_st6422;
|
||||
if (!sd->sensor->probe(sd))
|
||||
return 0;
|
||||
|
||||
sd->sensor = &stv06xx_sensor_vv6410;
|
||||
if (!sd->sensor->probe(sd))
|
||||
return 0;
|
||||
@ -457,9 +485,20 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
|
||||
|
||||
/* -- module initialisation -- */
|
||||
static const __devinitdata struct usb_device_id device_table[] = {
|
||||
{USB_DEVICE(0x046d, 0x0840)}, /* QuickCam Express */
|
||||
{USB_DEVICE(0x046d, 0x0850)}, /* LEGO cam / QuickCam Web */
|
||||
{USB_DEVICE(0x046d, 0x0870)}, /* Dexxa WebCam USB */
|
||||
/* QuickCam Express */
|
||||
{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
|
||||
/* LEGO cam / QuickCam Web */
|
||||
{USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 },
|
||||
/* Dexxa WebCam USB */
|
||||
{USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 },
|
||||
/* QuickCam Messenger */
|
||||
{USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 },
|
||||
/* QuickCam Communicate */
|
||||
{USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
|
||||
/* QuickCam Messenger (new) */
|
||||
{USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
|
||||
/* QuickCam Messenger (new) */
|
||||
{USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, device_table);
|
||||
|
@ -93,6 +93,17 @@ struct sd {
|
||||
|
||||
/* Sensor private data */
|
||||
void *sensor_priv;
|
||||
|
||||
/* The first 4 lines produced by the stv6422 are no good, this keeps
|
||||
track of how many bytes we still need to skip during a frame */
|
||||
int to_skip;
|
||||
|
||||
/* Bridge / Camera type */
|
||||
u8 bridge;
|
||||
#define BRIDGE_STV600 0
|
||||
#define BRIDGE_STV602 1
|
||||
#define BRIDGE_STV610 2
|
||||
#define BRIDGE_ST6422 3 /* With integrated sensor */
|
||||
};
|
||||
|
||||
int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data);
|
||||
|
@ -434,7 +434,7 @@ static int hdcs_probe_1x00(struct sd *sd)
|
||||
hdcs->exp.er = 100;
|
||||
|
||||
/*
|
||||
* Frame rate on HDCS-1000 0x46D:0x840 depends on PSMP:
|
||||
* Frame rate on HDCS-1000 with STV600 depends on PSMP:
|
||||
* 4 = doesn't work at all
|
||||
* 5 = 7.8 fps,
|
||||
* 6 = 6.9 fps,
|
||||
@ -443,7 +443,7 @@ static int hdcs_probe_1x00(struct sd *sd)
|
||||
* 15 = 4.4 fps,
|
||||
* 31 = 2.8 fps
|
||||
*
|
||||
* Frame rate on HDCS-1000 0x46D:0x870 depends on PSMP:
|
||||
* Frame rate on HDCS-1000 with STV602 depends on PSMP:
|
||||
* 15 = doesn't work at all
|
||||
* 18 = doesn't work at all
|
||||
* 19 = 7.3 fps
|
||||
@ -453,7 +453,7 @@ static int hdcs_probe_1x00(struct sd *sd)
|
||||
* 24 = 6.3 fps
|
||||
* 30 = 5.4 fps
|
||||
*/
|
||||
hdcs->psmp = IS_870(sd) ? 20 : 5;
|
||||
hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5;
|
||||
|
||||
sd->sensor_priv = hdcs;
|
||||
|
||||
@ -530,7 +530,7 @@ static int hdcs_init(struct sd *sd)
|
||||
int i, err = 0;
|
||||
|
||||
/* Set the STV0602AA in STV0600 emulation mode */
|
||||
if (IS_870(sd))
|
||||
if (sd->bridge == BRIDGE_STV602)
|
||||
stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
|
||||
|
||||
/* Execute the bridge init */
|
||||
@ -558,7 +558,7 @@ static int hdcs_init(struct sd *sd)
|
||||
return err;
|
||||
|
||||
/* Set PGA sample duration
|
||||
(was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */
|
||||
(was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */
|
||||
if (IS_1020(sd))
|
||||
err = stv06xx_write_sensor(sd, HDCS_TCTRL,
|
||||
(HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
|
||||
|
@ -32,14 +32,13 @@
|
||||
|
||||
#include "stv06xx.h"
|
||||
|
||||
#define IS_850(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x850)
|
||||
#define IS_870(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x870)
|
||||
#define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020)
|
||||
|
||||
extern const struct stv06xx_sensor stv06xx_sensor_vv6410;
|
||||
extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
|
||||
extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
|
||||
extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
|
||||
extern const struct stv06xx_sensor stv06xx_sensor_st6422;
|
||||
|
||||
struct stv06xx_sensor {
|
||||
/* Defines the name of a sensor */
|
||||
|
453
drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
Normal file
453
drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
Normal file
@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Support for the sensor part which is integrated (I think) into the
|
||||
* st6422 stv06xx alike bridge, as its integrated there are no i2c writes
|
||||
* but instead direct bridge writes.
|
||||
*
|
||||
* Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
|
||||
*
|
||||
* Strongly based on qc-usb-messenger, which is:
|
||||
* Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
|
||||
* Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
|
||||
* Copyright (c) 2002, 2003 Tuukka Toivonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stv06xx_st6422.h"
|
||||
|
||||
static struct v4l2_pix_format st6422_mode[] = {
|
||||
/* Note we actually get 124 lines of data, of which we skip the 4st
|
||||
4 as they are garbage */
|
||||
{
|
||||
162,
|
||||
120,
|
||||
V4L2_PIX_FMT_SGRBG8,
|
||||
V4L2_FIELD_NONE,
|
||||
.sizeimage = 162 * 120,
|
||||
.bytesperline = 162,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 1
|
||||
},
|
||||
/* Note we actually get 248 lines of data, of which we skip the 4st
|
||||
4 as they are garbage, and we tell the app it only gets the
|
||||
first 240 of the 244 lines it actually gets, so that it ignores
|
||||
the last 4. */
|
||||
{
|
||||
324,
|
||||
240,
|
||||
V4L2_PIX_FMT_SGRBG8,
|
||||
V4L2_FIELD_NONE,
|
||||
.sizeimage = 324 * 244,
|
||||
.bytesperline = 324,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 0
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ctrl st6422_ctrl[] = {
|
||||
#define BRIGHTNESS_IDX 0
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_BRIGHTNESS,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Brightness",
|
||||
.minimum = 0,
|
||||
.maximum = 31,
|
||||
.step = 1,
|
||||
.default_value = 3
|
||||
},
|
||||
.set = st6422_set_brightness,
|
||||
.get = st6422_get_brightness
|
||||
},
|
||||
#define CONTRAST_IDX 1
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_CONTRAST,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Contrast",
|
||||
.minimum = 0,
|
||||
.maximum = 15,
|
||||
.step = 1,
|
||||
.default_value = 11
|
||||
},
|
||||
.set = st6422_set_contrast,
|
||||
.get = st6422_get_contrast
|
||||
},
|
||||
#define GAIN_IDX 2
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_GAIN,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Gain",
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 64
|
||||
},
|
||||
.set = st6422_set_gain,
|
||||
.get = st6422_get_gain
|
||||
},
|
||||
#define EXPOSURE_IDX 3
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_EXPOSURE,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Exposure",
|
||||
.minimum = 0,
|
||||
.maximum = 1023,
|
||||
.step = 1,
|
||||
.default_value = 256
|
||||
},
|
||||
.set = st6422_set_exposure,
|
||||
.get = st6422_get_exposure
|
||||
},
|
||||
};
|
||||
|
||||
static int st6422_probe(struct sd *sd)
|
||||
{
|
||||
int i;
|
||||
s32 *sensor_settings;
|
||||
|
||||
if (sd->bridge != BRIDGE_ST6422)
|
||||
return -ENODEV;
|
||||
|
||||
info("st6422 sensor detected");
|
||||
|
||||
sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32),
|
||||
GFP_KERNEL);
|
||||
if (!sensor_settings)
|
||||
return -ENOMEM;
|
||||
|
||||
sd->gspca_dev.cam.cam_mode = st6422_mode;
|
||||
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
|
||||
sd->desc.ctrls = st6422_ctrl;
|
||||
sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
|
||||
sd->sensor_priv = sensor_settings;
|
||||
|
||||
for (i = 0; i < sd->desc.nctrls; i++)
|
||||
sensor_settings[i] = st6422_ctrl[i].qctrl.default_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_init(struct sd *sd)
|
||||
{
|
||||
int err = 0, i;
|
||||
|
||||
const u16 st6422_bridge_init[][2] = {
|
||||
{ STV_ISO_ENABLE, 0x00 }, /* disable capture */
|
||||
{ 0x1436, 0x00 },
|
||||
{ 0x1432, 0x03 }, /* 0x00-0x1F brightness */
|
||||
{ 0x143a, 0xF9 }, /* 0x00-0x0F contrast */
|
||||
{ 0x0509, 0x38 }, /* R */
|
||||
{ 0x050a, 0x38 }, /* G */
|
||||
{ 0x050b, 0x38 }, /* B */
|
||||
{ 0x050c, 0x2A },
|
||||
{ 0x050d, 0x01 },
|
||||
|
||||
|
||||
{ 0x1431, 0x00 }, /* 0x00-0x07 ??? */
|
||||
{ 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */
|
||||
{ 0x1438, 0x18 }, /* 640x480 */
|
||||
/* 18 bayes */
|
||||
/* 10 compressed? */
|
||||
|
||||
{ 0x1439, 0x00 },
|
||||
/* antiflimmer?? 0xa2 ger perfekt bild mot monitor */
|
||||
|
||||
{ 0x143b, 0x05 },
|
||||
{ 0x143c, 0x00 }, /* 0x00-0x01 - ??? */
|
||||
|
||||
|
||||
/* shutter time 0x0000-0x03FF */
|
||||
/* low value give good picures on moving objects (but requires much light) */
|
||||
/* high value gives good picures in darkness (but tends to be overexposed) */
|
||||
{ 0x143e, 0x01 },
|
||||
{ 0x143d, 0x00 },
|
||||
|
||||
{ 0x1442, 0xe2 },
|
||||
/* write: 1x1x xxxx */
|
||||
/* read: 1x1x xxxx */
|
||||
/* bit 5 == button pressed and hold if 0 */
|
||||
/* write 0xe2,0xea */
|
||||
|
||||
/* 0x144a */
|
||||
/* 0x00 init */
|
||||
/* bit 7 == button has been pressed, but not handled */
|
||||
|
||||
/* interrupt */
|
||||
/* if(urb->iso_frame_desc[i].status == 0x80) { */
|
||||
/* if(urb->iso_frame_desc[i].status == 0x88) { */
|
||||
|
||||
{ 0x1500, 0xd0 },
|
||||
{ 0x1500, 0xd0 },
|
||||
{ 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */
|
||||
|
||||
{ 0x1501, 0xaf },
|
||||
/* high val-> ljus area blir morkare. */
|
||||
/* low val -> ljus area blir ljusare. */
|
||||
{ 0x1502, 0xc2 },
|
||||
/* high val-> ljus area blir morkare. */
|
||||
/* low val -> ljus area blir ljusare. */
|
||||
{ 0x1503, 0x45 },
|
||||
/* high val-> ljus area blir morkare. */
|
||||
/* low val -> ljus area blir ljusare. */
|
||||
|
||||
{ 0x1505, 0x02 },
|
||||
/* 2 : 324x248 80352 bytes */
|
||||
/* 7 : 248x162 40176 bytes */
|
||||
/* c+f: 162*124 20088 bytes */
|
||||
|
||||
{ 0x150e, 0x8e },
|
||||
{ 0x150f, 0x37 },
|
||||
{ 0x15c0, 0x00 },
|
||||
{ 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */
|
||||
{ 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */
|
||||
|
||||
|
||||
{ 0x143f, 0x01 }, /* commit settings */
|
||||
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) {
|
||||
err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0],
|
||||
st6422_bridge_init[i][1]);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void st6422_disconnect(struct sd *sd)
|
||||
{
|
||||
sd->sensor = NULL;
|
||||
kfree(sd->sensor_priv);
|
||||
}
|
||||
|
||||
static int st6422_start(struct sd *sd)
|
||||
{
|
||||
int err, packet_size;
|
||||
struct cam *cam = &sd->gspca_dev.cam;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
struct usb_host_interface *alt;
|
||||
struct usb_interface *intf;
|
||||
|
||||
intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
|
||||
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
|
||||
if (!alt) {
|
||||
PDEBUG(D_ERR, "Couldn't get altsetting");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
|
||||
err = stv06xx_write_bridge(sd, 0x15c1, packet_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
|
||||
err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
|
||||
else
|
||||
err = stv06xx_write_bridge(sd, 0x1505, 0x02);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st6422_set_brightness(&sd->gspca_dev,
|
||||
sensor_settings[BRIGHTNESS_IDX]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st6422_set_contrast(&sd->gspca_dev,
|
||||
sensor_settings[CONTRAST_IDX]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st6422_set_exposure(&sd->gspca_dev,
|
||||
sensor_settings[EXPOSURE_IDX]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st6422_set_gain(&sd->gspca_dev,
|
||||
sensor_settings[GAIN_IDX]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
PDEBUG(D_STREAM, "Starting stream");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_stop(struct sd *sd)
|
||||
{
|
||||
PDEBUG(D_STREAM, "Halting stream");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
*val = sensor_settings[BRIGHTNESS_IDX];
|
||||
|
||||
PDEBUG(D_V4L2, "Read brightness %d", *val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
int err;
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
sensor_settings[BRIGHTNESS_IDX] = val;
|
||||
|
||||
if (!gspca_dev->streaming)
|
||||
return 0;
|
||||
|
||||
/* val goes from 0 -> 31 */
|
||||
PDEBUG(D_V4L2, "Set brightness to %d", val);
|
||||
err = stv06xx_write_bridge(sd, 0x1432, val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* commit settings */
|
||||
err = stv06xx_write_bridge(sd, 0x143f, 0x01);
|
||||
return (err < 0) ? err : 0;
|
||||
}
|
||||
|
||||
static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
*val = sensor_settings[CONTRAST_IDX];
|
||||
|
||||
PDEBUG(D_V4L2, "Read contrast %d", *val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
int err;
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
sensor_settings[CONTRAST_IDX] = val;
|
||||
|
||||
if (!gspca_dev->streaming)
|
||||
return 0;
|
||||
|
||||
/* Val goes from 0 -> 15 */
|
||||
PDEBUG(D_V4L2, "Set contrast to %d\n", val);
|
||||
err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* commit settings */
|
||||
err = stv06xx_write_bridge(sd, 0x143f, 0x01);
|
||||
return (err < 0) ? err : 0;
|
||||
}
|
||||
|
||||
static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
*val = sensor_settings[GAIN_IDX];
|
||||
|
||||
PDEBUG(D_V4L2, "Read gain %d", *val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
int err;
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
sensor_settings[GAIN_IDX] = val;
|
||||
|
||||
if (!gspca_dev->streaming)
|
||||
return 0;
|
||||
|
||||
PDEBUG(D_V4L2, "Set gain to %d", val);
|
||||
|
||||
/* Set red, green, blue, gain */
|
||||
err = stv06xx_write_bridge(sd, 0x0509, val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = stv06xx_write_bridge(sd, 0x050a, val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = stv06xx_write_bridge(sd, 0x050b, val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* 2 mystery writes */
|
||||
err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = stv06xx_write_bridge(sd, 0x050d, 0x01);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* commit settings */
|
||||
err = stv06xx_write_bridge(sd, 0x143f, 0x01);
|
||||
return (err < 0) ? err : 0;
|
||||
}
|
||||
|
||||
static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
*val = sensor_settings[EXPOSURE_IDX];
|
||||
|
||||
PDEBUG(D_V4L2, "Read exposure %d", *val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
int err;
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
s32 *sensor_settings = sd->sensor_priv;
|
||||
|
||||
sensor_settings[EXPOSURE_IDX] = val;
|
||||
|
||||
if (!gspca_dev->streaming)
|
||||
return 0;
|
||||
|
||||
PDEBUG(D_V4L2, "Set exposure to %d\n", val);
|
||||
err = stv06xx_write_bridge(sd, 0x143d, val & 0xff);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = stv06xx_write_bridge(sd, 0x143e, val >> 8);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* commit settings */
|
||||
err = stv06xx_write_bridge(sd, 0x143f, 0x01);
|
||||
return (err < 0) ? err : 0;
|
||||
}
|
59
drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
Normal file
59
drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Support for the sensor part which is integrated (I think) into the
|
||||
* st6422 stv06xx alike bridge, as its integrated there are no i2c writes
|
||||
* but instead direct bridge writes.
|
||||
*
|
||||
* Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
|
||||
*
|
||||
* Strongly based on qc-usb-messenger, which is:
|
||||
* Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
|
||||
* Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
|
||||
* Copyright (c) 2002, 2003 Tuukka Toivonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STV06XX_ST6422_H_
|
||||
#define STV06XX_ST6422_H_
|
||||
|
||||
#include "stv06xx_sensor.h"
|
||||
|
||||
static int st6422_probe(struct sd *sd);
|
||||
static int st6422_start(struct sd *sd);
|
||||
static int st6422_init(struct sd *sd);
|
||||
static int st6422_stop(struct sd *sd);
|
||||
static void st6422_disconnect(struct sd *sd);
|
||||
|
||||
/* V4L2 controls supported by the driver */
|
||||
static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
|
||||
|
||||
const struct stv06xx_sensor stv06xx_sensor_st6422 = {
|
||||
.name = "ST6422",
|
||||
.init = st6422_init,
|
||||
.probe = st6422_probe,
|
||||
.start = st6422_start,
|
||||
.stop = st6422_stop,
|
||||
.disconnect = st6422_disconnect,
|
||||
};
|
||||
|
||||
#endif
|
@ -60,6 +60,8 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
|
||||
|
||||
switch (qctrl->id) {
|
||||
/* Standard V4L2 controls */
|
||||
case V4L2_CID_USER_CLASS:
|
||||
return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
case V4L2_CID_HUE:
|
||||
case V4L2_CID_SATURATION:
|
||||
|
@ -280,15 +280,9 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd,
|
||||
{
|
||||
struct v4l2_pix_format *pix = &f->fmt.pix;
|
||||
|
||||
if (pix->height < 32 + icd->y_skip_top)
|
||||
pix->height = 32 + icd->y_skip_top;
|
||||
if (pix->height > 1024 + icd->y_skip_top)
|
||||
pix->height = 1024 + icd->y_skip_top;
|
||||
if (pix->width < 48)
|
||||
pix->width = 48;
|
||||
if (pix->width > 1280)
|
||||
pix->width = 1280;
|
||||
pix->width &= ~0x01; /* has to be even, unsure why was ~3 */
|
||||
v4l_bound_align_image(&pix->width, 48, 1280, 1,
|
||||
&pix->height, 32 + icd->y_skip_top,
|
||||
1024 + icd->y_skip_top, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -385,17 +385,9 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
|
||||
{
|
||||
struct v4l2_pix_format *pix = &f->fmt.pix;
|
||||
|
||||
if (pix->height < MT9T031_MIN_HEIGHT)
|
||||
pix->height = MT9T031_MIN_HEIGHT;
|
||||
if (pix->height > MT9T031_MAX_HEIGHT)
|
||||
pix->height = MT9T031_MAX_HEIGHT;
|
||||
if (pix->width < MT9T031_MIN_WIDTH)
|
||||
pix->width = MT9T031_MIN_WIDTH;
|
||||
if (pix->width > MT9T031_MAX_WIDTH)
|
||||
pix->width = MT9T031_MAX_WIDTH;
|
||||
|
||||
pix->width &= ~0x01; /* has to be even */
|
||||
pix->height &= ~0x01; /* has to be even */
|
||||
v4l_bound_align_image(
|
||||
&pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
|
||||
&pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -364,15 +364,9 @@ static int mt9v022_try_fmt(struct soc_camera_device *icd,
|
||||
{
|
||||
struct v4l2_pix_format *pix = &f->fmt.pix;
|
||||
|
||||
if (pix->height < 32 + icd->y_skip_top)
|
||||
pix->height = 32 + icd->y_skip_top;
|
||||
if (pix->height > 480 + icd->y_skip_top)
|
||||
pix->height = 480 + icd->y_skip_top;
|
||||
if (pix->width < 48)
|
||||
pix->width = 48;
|
||||
if (pix->width > 752)
|
||||
pix->width = 752;
|
||||
pix->width &= ~0x03; /* ? */
|
||||
v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */,
|
||||
&pix->height, 32 + icd->y_skip_top,
|
||||
480 + icd->y_skip_top, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -211,8 +211,6 @@ static const int i2c_detect_tries = 5;
|
||||
static struct usb_device_id device_table [] = {
|
||||
{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
|
||||
{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
|
||||
{ USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
|
||||
{ USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) },
|
||||
{ USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
@ -48,11 +48,13 @@ static const int routing_scheme0[] = {
|
||||
MSP_DSP_IN_SCART),
|
||||
};
|
||||
|
||||
static const struct routing_scheme routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
|
||||
.def = routing_scheme0,
|
||||
.cnt = ARRAY_SIZE(routing_scheme0),
|
||||
},
|
||||
static const struct routing_scheme routing_def0 = {
|
||||
.def = routing_scheme0,
|
||||
.cnt = ARRAY_SIZE(routing_scheme0),
|
||||
};
|
||||
|
||||
static const struct routing_scheme *routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
|
||||
};
|
||||
|
||||
void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
@ -65,7 +67,7 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
|
||||
|
||||
if ((sid < ARRAY_SIZE(routing_schemes)) &&
|
||||
((sp = routing_schemes + sid) != NULL) &&
|
||||
((sp = routing_schemes[sid]) != NULL) &&
|
||||
(hdw->input_val >= 0) &&
|
||||
(hdw->input_val < sp->cnt)) {
|
||||
input = sp->def[hdw->input_val];
|
||||
|
@ -49,11 +49,13 @@ static const int routing_scheme1[] = {
|
||||
[PVR2_CVAL_INPUT_SVIDEO] = 0,
|
||||
};
|
||||
|
||||
static const struct routing_scheme routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_ONAIR] = {
|
||||
.def = routing_scheme1,
|
||||
.cnt = ARRAY_SIZE(routing_scheme1),
|
||||
},
|
||||
static const struct routing_scheme routing_def1 = {
|
||||
.def = routing_scheme1,
|
||||
.cnt = ARRAY_SIZE(routing_scheme1),
|
||||
};
|
||||
|
||||
static const struct routing_scheme *routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
|
||||
};
|
||||
|
||||
|
||||
@ -65,12 +67,11 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
u32 input;
|
||||
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
|
||||
hdw->input_val);
|
||||
if ((sid < ARRAY_SIZE(routing_schemes)) &&
|
||||
((sp = routing_schemes + sid) != NULL) &&
|
||||
(hdw->input_val >= 0) &&
|
||||
(hdw->input_val < sp->cnt)) {
|
||||
input = sp->def[hdw->input_val];
|
||||
} else {
|
||||
sp = (sid < ARRAY_SIZE(routing_schemes)) ?
|
||||
routing_schemes[sid] : NULL;
|
||||
if ((sp == NULL) ||
|
||||
(hdw->input_val < 0) ||
|
||||
(hdw->input_val >= sp->cnt)) {
|
||||
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
|
||||
"*** WARNING *** subdev v4l2 set_input:"
|
||||
" Invalid routing scheme (%u)"
|
||||
@ -78,6 +79,7 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
sid, hdw->input_val);
|
||||
return;
|
||||
}
|
||||
input = sp->def[hdw->input_val];
|
||||
sd->ops->audio->s_routing(sd, input, 0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,11 @@ static const struct routing_scheme_item routing_scheme0[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct routing_scheme routing_def0 = {
|
||||
.def = routing_scheme0,
|
||||
.cnt = ARRAY_SIZE(routing_scheme0),
|
||||
};
|
||||
|
||||
/* Specific to gotview device */
|
||||
static const struct routing_scheme_item routing_schemegv[] = {
|
||||
[PVR2_CVAL_INPUT_TV] = {
|
||||
@ -90,15 +95,14 @@ static const struct routing_scheme_item routing_schemegv[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct routing_scheme routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
|
||||
.def = routing_scheme0,
|
||||
.cnt = ARRAY_SIZE(routing_scheme0),
|
||||
},
|
||||
[PVR2_ROUTING_SCHEME_GOTVIEW] = {
|
||||
.def = routing_schemegv,
|
||||
.cnt = ARRAY_SIZE(routing_schemegv),
|
||||
},
|
||||
static const struct routing_scheme routing_defgv = {
|
||||
.def = routing_schemegv,
|
||||
.cnt = ARRAY_SIZE(routing_schemegv),
|
||||
};
|
||||
|
||||
static const struct routing_scheme *routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
|
||||
[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
|
||||
};
|
||||
|
||||
void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
@ -110,13 +114,11 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
const struct routing_scheme *sp;
|
||||
unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
|
||||
|
||||
if ((sid < ARRAY_SIZE(routing_schemes)) &&
|
||||
((sp = routing_schemes + sid) != NULL) &&
|
||||
(hdw->input_val >= 0) &&
|
||||
(hdw->input_val < sp->cnt)) {
|
||||
vid_input = sp->def[hdw->input_val].vid;
|
||||
aud_input = sp->def[hdw->input_val].aud;
|
||||
} else {
|
||||
sp = (sid < ARRAY_SIZE(routing_schemes)) ?
|
||||
routing_schemes[sid] : NULL;
|
||||
if ((sp == NULL) ||
|
||||
(hdw->input_val < 0) ||
|
||||
(hdw->input_val >= sp->cnt)) {
|
||||
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
|
||||
"*** WARNING *** subdev cx2584x set_input:"
|
||||
" Invalid routing scheme (%u)"
|
||||
@ -124,7 +126,8 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
sid, hdw->input_val);
|
||||
return;
|
||||
}
|
||||
|
||||
vid_input = sp->def[hdw->input_val].vid;
|
||||
aud_input = sp->def[hdw->input_val].aud;
|
||||
pvr2_trace(PVR2_TRACE_CHIPS,
|
||||
"subdev cx2584x set_input vid=0x%x aud=0x%x",
|
||||
vid_input, aud_input);
|
||||
|
@ -85,8 +85,8 @@ MODULE_PARM_DESC(video_std,"specify initial video standard");
|
||||
module_param_array(tolerance, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
|
||||
|
||||
/* US Broadcast channel 7 (175.25 MHz) */
|
||||
static int default_tv_freq = 175250000L;
|
||||
/* US Broadcast channel 3 (61.25 MHz), to help with testing */
|
||||
static int default_tv_freq = 61250000L;
|
||||
/* 104.3 MHz, a usable FM station for my area */
|
||||
static int default_radio_freq = 104300000L;
|
||||
|
||||
@ -1987,6 +1987,34 @@ static unsigned int pvr2_copy_i2c_addr_list(
|
||||
}
|
||||
|
||||
|
||||
static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
|
||||
{
|
||||
/*
|
||||
Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit of nuttiness
|
||||
for cx25840 causes that module to correctly set up its video
|
||||
scaling. This is really a problem in the cx25840 module itself,
|
||||
but we work around it here. The problem has not been seen in
|
||||
ivtv because there VBI is supported and set up. We don't do VBI
|
||||
here (at least not yet) and thus we never attempted to even set
|
||||
it up.
|
||||
*/
|
||||
struct v4l2_format fmt;
|
||||
if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) {
|
||||
/* We're not using a cx25840 so don't enable the hack */
|
||||
return;
|
||||
}
|
||||
|
||||
pvr2_trace(PVR2_TRACE_INIT,
|
||||
"Module ID %u:"
|
||||
" Executing cx25840 VBI hack",
|
||||
hdw->decoder_client_id);
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
|
||||
v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
|
||||
video, s_fmt, &fmt);
|
||||
}
|
||||
|
||||
|
||||
static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
|
||||
const struct pvr2_device_client_desc *cd)
|
||||
{
|
||||
@ -2078,30 +2106,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
|
||||
/* client-specific setup... */
|
||||
switch (mid) {
|
||||
case PVR2_CLIENT_ID_CX25840:
|
||||
hdw->decoder_client_id = mid;
|
||||
{
|
||||
/*
|
||||
Mike Isely <isely@pobox.com> 19-Nov-2006 - This
|
||||
bit of nuttiness for cx25840 causes that module
|
||||
to correctly set up its video scaling. This is
|
||||
really a problem in the cx25840 module itself,
|
||||
but we work around it here. The problem has not
|
||||
been seen in ivtv because there VBI is supported
|
||||
and set up. We don't do VBI here (at least not
|
||||
yet) and thus we never attempted to even set it
|
||||
up.
|
||||
*/
|
||||
struct v4l2_format fmt;
|
||||
pvr2_trace(PVR2_TRACE_INIT,
|
||||
"Module ID %u:"
|
||||
" Executing cx25840 VBI hack",
|
||||
mid);
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
|
||||
v4l2_device_call_all(&hdw->v4l2_dev, mid,
|
||||
video, s_fmt, &fmt);
|
||||
}
|
||||
break;
|
||||
case PVR2_CLIENT_ID_SAA7115:
|
||||
hdw->decoder_client_id = mid;
|
||||
break;
|
||||
@ -2202,6 +2206,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
|
||||
cptr->info->set_value(cptr,~0,cptr->info->default_value);
|
||||
}
|
||||
|
||||
pvr2_hdw_cx25840_vbi_hack(hdw);
|
||||
|
||||
/* Set up special default values for the television and radio
|
||||
frequencies here. It's not really important what these defaults
|
||||
are, but I set them to something usable in the Chicago area just
|
||||
@ -2954,6 +2960,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
|
||||
vs = hdw->std_mask_cur;
|
||||
v4l2_device_call_all(&hdw->v4l2_dev, 0,
|
||||
core, s_std, vs);
|
||||
pvr2_hdw_cx25840_vbi_hack(hdw);
|
||||
}
|
||||
hdw->tuner_signal_stale = !0;
|
||||
hdw->cropcap_stale = !0;
|
||||
@ -4076,6 +4083,7 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
|
||||
if (hdw->decoder_client_id) {
|
||||
v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
|
||||
core, reset, 0);
|
||||
pvr2_hdw_cx25840_vbi_hack(hdw);
|
||||
return 0;
|
||||
}
|
||||
pvr2_trace(PVR2_TRACE_INIT,
|
||||
|
@ -54,6 +54,11 @@ static const int routing_scheme0[] = {
|
||||
[PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
|
||||
};
|
||||
|
||||
static const struct routing_scheme routing_def0 = {
|
||||
.def = routing_scheme0,
|
||||
.cnt = ARRAY_SIZE(routing_scheme0),
|
||||
};
|
||||
|
||||
static const int routing_scheme1[] = {
|
||||
[PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
|
||||
[PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
|
||||
@ -61,15 +66,14 @@ static const int routing_scheme1[] = {
|
||||
[PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
|
||||
};
|
||||
|
||||
static const struct routing_scheme routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
|
||||
.def = routing_scheme0,
|
||||
.cnt = ARRAY_SIZE(routing_scheme0),
|
||||
},
|
||||
[PVR2_ROUTING_SCHEME_ONAIR] = {
|
||||
.def = routing_scheme1,
|
||||
.cnt = ARRAY_SIZE(routing_scheme1),
|
||||
},
|
||||
static const struct routing_scheme routing_def1 = {
|
||||
.def = routing_scheme1,
|
||||
.cnt = ARRAY_SIZE(routing_scheme1),
|
||||
};
|
||||
|
||||
static const struct routing_scheme *routing_schemes[] = {
|
||||
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
|
||||
[PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
|
||||
};
|
||||
|
||||
void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
@ -81,12 +85,12 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
|
||||
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
|
||||
hdw->input_val);
|
||||
if ((sid < ARRAY_SIZE(routing_schemes)) &&
|
||||
((sp = routing_schemes + sid) != NULL) &&
|
||||
(hdw->input_val >= 0) &&
|
||||
(hdw->input_val < sp->cnt)) {
|
||||
input = sp->def[hdw->input_val];
|
||||
} else {
|
||||
|
||||
sp = (sid < ARRAY_SIZE(routing_schemes)) ?
|
||||
routing_schemes[sid] : NULL;
|
||||
if ((sp == NULL) ||
|
||||
(hdw->input_val < 0) ||
|
||||
(hdw->input_val >= sp->cnt)) {
|
||||
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
|
||||
"*** WARNING *** subdev v4l2 set_input:"
|
||||
" Invalid routing scheme (%u)"
|
||||
@ -94,6 +98,7 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
|
||||
sid, hdw->input_val);
|
||||
return;
|
||||
}
|
||||
input = sp->def[hdw->input_val];
|
||||
sd->ops->video->s_routing(sd, input, 0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -162,13 +162,6 @@
|
||||
CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
|
||||
CICR0_EOFM | CICR0_FOM)
|
||||
|
||||
/*
|
||||
* YUV422P picture size should be a multiple of 16, so the heuristic aligns
|
||||
* height, width on 4 byte boundaries to reach the 16 multiple for the size.
|
||||
*/
|
||||
#define YUV422P_X_Y_ALIGN 4
|
||||
#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN
|
||||
|
||||
/*
|
||||
* Structures
|
||||
*/
|
||||
@ -1398,28 +1391,15 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* limit to pxa hardware capabilities */
|
||||
if (pix->height < 32)
|
||||
pix->height = 32;
|
||||
if (pix->height > 2048)
|
||||
pix->height = 2048;
|
||||
if (pix->width < 48)
|
||||
pix->width = 48;
|
||||
if (pix->width > 2048)
|
||||
pix->width = 2048;
|
||||
pix->width &= ~0x01;
|
||||
|
||||
/*
|
||||
* YUV422P planar format requires images size to be a 16 bytes
|
||||
* multiple. If not, zeros will be inserted between Y and U planes, and
|
||||
* U and V planes, and YUV422P standard would be violated.
|
||||
* Limit to pxa hardware capabilities. YUV422P planar format requires
|
||||
* images size to be a multiple of 16 bytes. If not, zeros will be
|
||||
* inserted between Y and U planes, and U and V planes, which violates
|
||||
* the YUV422P standard.
|
||||
*/
|
||||
if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
|
||||
if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
|
||||
pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN);
|
||||
if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
|
||||
pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN);
|
||||
}
|
||||
v4l_bound_align_image(&pix->width, 48, 2048, 1,
|
||||
&pix->height, 32, 2048, 0,
|
||||
xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
|
||||
|
||||
pix->bytesperline = pix->width *
|
||||
DIV_ROUND_UP(xlate->host_fmt->depth, 8);
|
||||
|
@ -1640,15 +1640,8 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
}
|
||||
|
||||
f->fmt.pix.field = field;
|
||||
if (f->fmt.pix.width < 48)
|
||||
f->fmt.pix.width = 48;
|
||||
if (f->fmt.pix.height < 32)
|
||||
f->fmt.pix.height = 32;
|
||||
if (f->fmt.pix.width > maxw)
|
||||
f->fmt.pix.width = maxw;
|
||||
if (f->fmt.pix.height > maxh)
|
||||
f->fmt.pix.height = maxh;
|
||||
f->fmt.pix.width &= ~0x03;
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
|
||||
&f->fmt.pix.height, 32, maxh, 0, 0);
|
||||
f->fmt.pix.bytesperline =
|
||||
(f->fmt.pix.width * fmt->depth) >> 3;
|
||||
f->fmt.pix.sizeimage =
|
||||
|
@ -689,16 +689,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
|
||||
|
||||
/* FIXME: calculate using depth and bus width */
|
||||
|
||||
if (f->fmt.pix.height < 4)
|
||||
f->fmt.pix.height = 4;
|
||||
if (f->fmt.pix.height > 1920)
|
||||
f->fmt.pix.height = 1920;
|
||||
if (f->fmt.pix.width < 2)
|
||||
f->fmt.pix.width = 2;
|
||||
if (f->fmt.pix.width > 2560)
|
||||
f->fmt.pix.width = 2560;
|
||||
f->fmt.pix.width &= ~0x01;
|
||||
f->fmt.pix.height &= ~0x03;
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1,
|
||||
&f->fmt.pix.height, 4, 1920, 2, 0);
|
||||
|
||||
f->fmt.pix.bytesperline = f->fmt.pix.width *
|
||||
DIV_ROUND_UP(xlate->host_fmt->depth, 8);
|
||||
|
@ -878,7 +878,7 @@ static int tcm825x_probe(struct i2c_client *client,
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int __exit tcm825x_remove(struct i2c_client *client)
|
||||
static int tcm825x_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tcm825x_sensor *sensor = i2c_get_clientdata(client);
|
||||
|
||||
@ -902,7 +902,7 @@ static struct i2c_driver tcm825x_i2c_driver = {
|
||||
.name = TCM825X_NAME,
|
||||
},
|
||||
.probe = tcm825x_probe,
|
||||
.remove = __exit_p(tcm825x_remove),
|
||||
.remove = tcm825x_remove,
|
||||
.id_table = tcm825x_id,
|
||||
};
|
||||
|
||||
|
@ -38,10 +38,13 @@ config USB_KONICAWC
|
||||
module will be called konicawc.
|
||||
|
||||
config USB_QUICKCAM_MESSENGER
|
||||
tristate "USB Logitech Quickcam Messenger"
|
||||
tristate "USB Logitech Quickcam Messenger (DEPRECATED)"
|
||||
depends on VIDEO_V4L1
|
||||
select VIDEO_USBVIDEO
|
||||
---help---
|
||||
This driver is DEPRECATED please use the gspca stv06xx module
|
||||
instead.
|
||||
|
||||
Say Y or M here to enable support for the USB Logitech Quickcam
|
||||
Messenger webcam.
|
||||
|
||||
|
@ -802,6 +802,17 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
|
||||
/* Decrease the module use count to match the first try_module_get. */
|
||||
module_put(client->driver->driver.owner);
|
||||
|
||||
if (sd) {
|
||||
/* We return errors from v4l2_subdev_call only if we have the
|
||||
callback as the .s_config is not mandatory */
|
||||
int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
|
||||
|
||||
if (err && err != -ENOIOCTLCMD) {
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
sd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
/* If we have a client but no subdev, then something went wrong and
|
||||
we must unregister the client. */
|
||||
@ -852,6 +863,17 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
|
||||
/* Decrease the module use count to match the first try_module_get. */
|
||||
module_put(client->driver->driver.owner);
|
||||
|
||||
if (sd) {
|
||||
/* We return errors from v4l2_subdev_call only if we have the
|
||||
callback as the .s_config is not mandatory */
|
||||
int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
|
||||
|
||||
if (err && err != -ENOIOCTLCMD) {
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
sd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
/* If we have a client but no subdev, then something went wrong and
|
||||
we must unregister the client. */
|
||||
@ -872,6 +894,89 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
|
||||
|
||||
/* Load an i2c sub-device. */
|
||||
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
|
||||
struct i2c_adapter *adapter, const char *module_name,
|
||||
struct i2c_board_info *info, const unsigned short *probe_addrs)
|
||||
{
|
||||
struct v4l2_subdev *sd = NULL;
|
||||
struct i2c_client *client;
|
||||
|
||||
BUG_ON(!v4l2_dev);
|
||||
|
||||
if (module_name)
|
||||
request_module(module_name);
|
||||
|
||||
/* Create the i2c client */
|
||||
if (info->addr == 0 && probe_addrs)
|
||||
client = i2c_new_probed_device(adapter, info, probe_addrs);
|
||||
else
|
||||
client = i2c_new_device(adapter, info);
|
||||
|
||||
/* Note: by loading the module first we are certain that c->driver
|
||||
will be set if the driver was found. If the module was not loaded
|
||||
first, then the i2c core tries to delay-load the module for us,
|
||||
and then c->driver is still NULL until the module is finally
|
||||
loaded. This delay-load mechanism doesn't work if other drivers
|
||||
want to use the i2c device, so explicitly loading the module
|
||||
is the best alternative. */
|
||||
if (client == NULL || client->driver == NULL)
|
||||
goto error;
|
||||
|
||||
/* Lock the module so we can safely get the v4l2_subdev pointer */
|
||||
if (!try_module_get(client->driver->driver.owner))
|
||||
goto error;
|
||||
sd = i2c_get_clientdata(client);
|
||||
|
||||
/* Register with the v4l2_device which increases the module's
|
||||
use count as well. */
|
||||
if (v4l2_device_register_subdev(v4l2_dev, sd))
|
||||
sd = NULL;
|
||||
/* Decrease the module use count to match the first try_module_get. */
|
||||
module_put(client->driver->driver.owner);
|
||||
|
||||
if (sd) {
|
||||
/* We return errors from v4l2_subdev_call only if we have the
|
||||
callback as the .s_config is not mandatory */
|
||||
int err = v4l2_subdev_call(sd, core, s_config,
|
||||
info->irq, info->platform_data);
|
||||
|
||||
if (err && err != -ENOIOCTLCMD) {
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
sd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
/* If we have a client but no subdev, then something went wrong and
|
||||
we must unregister the client. */
|
||||
if (client && sd == NULL)
|
||||
i2c_unregister_device(client);
|
||||
return sd;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
|
||||
|
||||
struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
|
||||
struct i2c_adapter *adapter,
|
||||
const char *module_name, const char *client_type,
|
||||
int irq, void *platform_data,
|
||||
u8 addr, const unsigned short *probe_addrs)
|
||||
{
|
||||
struct i2c_board_info info;
|
||||
|
||||
/* Setup the i2c board info with the device type and
|
||||
the device address. */
|
||||
memset(&info, 0, sizeof(info));
|
||||
strlcpy(info.type, client_type, sizeof(info.type));
|
||||
info.addr = addr;
|
||||
info.irq = irq;
|
||||
info.platform_data = platform_data;
|
||||
|
||||
return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name,
|
||||
&info, probe_addrs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg);
|
||||
|
||||
/* Return i2c client address of v4l2_subdev. */
|
||||
unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
|
||||
{
|
||||
@ -916,4 +1021,78 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
|
||||
|
||||
#endif
|
||||
#endif /* defined(CONFIG_I2C) */
|
||||
|
||||
/* Clamp x to be between min and max, aligned to a multiple of 2^align. min
|
||||
* and max don't have to be aligned, but there must be at least one valid
|
||||
* value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples
|
||||
* of 16 between 17 and 31. */
|
||||
static unsigned int clamp_align(unsigned int x, unsigned int min,
|
||||
unsigned int max, unsigned int align)
|
||||
{
|
||||
/* Bits that must be zero to be aligned */
|
||||
unsigned int mask = ~((1 << align) - 1);
|
||||
|
||||
/* Round to nearest aligned value */
|
||||
if (align)
|
||||
x = (x + (1 << (align - 1))) & mask;
|
||||
|
||||
/* Clamp to aligned value of min and max */
|
||||
if (x < min)
|
||||
x = (min + ~mask) & mask;
|
||||
else if (x > max)
|
||||
x = max & mask;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Bound an image to have a width between wmin and wmax, and height between
|
||||
* hmin and hmax, inclusive. Additionally, the width will be a multiple of
|
||||
* 2^walign, the height will be a multiple of 2^halign, and the overall size
|
||||
* (width*height) will be a multiple of 2^salign. The image may be shrunk
|
||||
* or enlarged to fit the alignment constraints.
|
||||
*
|
||||
* The width or height maximum must not be smaller than the corresponding
|
||||
* minimum. The alignments must not be so high there are no possible image
|
||||
* sizes within the allowed bounds. wmin and hmin must be at least 1
|
||||
* (don't use 0). If you don't care about a certain alignment, specify 0,
|
||||
* as 2^0 is 1 and one byte alignment is equivalent to no alignment. If
|
||||
* you only want to adjust downward, specify a maximum that's the same as
|
||||
* the initial value.
|
||||
*/
|
||||
void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
|
||||
unsigned int walign,
|
||||
u32 *h, unsigned int hmin, unsigned int hmax,
|
||||
unsigned int halign, unsigned int salign)
|
||||
{
|
||||
*w = clamp_align(*w, wmin, wmax, walign);
|
||||
*h = clamp_align(*h, hmin, hmax, halign);
|
||||
|
||||
/* Usually we don't need to align the size and are done now. */
|
||||
if (!salign)
|
||||
return;
|
||||
|
||||
/* How much alignment do we have? */
|
||||
walign = __ffs(*w);
|
||||
halign = __ffs(*h);
|
||||
/* Enough to satisfy the image alignment? */
|
||||
if (walign + halign < salign) {
|
||||
/* Max walign where there is still a valid width */
|
||||
unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
|
||||
/* Max halign where there is still a valid height */
|
||||
unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
|
||||
|
||||
/* up the smaller alignment until we have enough */
|
||||
do {
|
||||
if (halign >= hmaxa ||
|
||||
(walign <= halign && walign < wmaxa)) {
|
||||
*w = clamp_align(*w, wmin, wmax, walign + 1);
|
||||
walign = __ffs(*w);
|
||||
} else {
|
||||
*h = clamp_align(*h, hmin, hmax, halign + 1);
|
||||
halign = __ffs(*h);
|
||||
}
|
||||
} while (halign + walign < salign);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l_bound_align_image);
|
||||
|
@ -883,15 +883,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
maxh = norm_maxh();
|
||||
|
||||
f->fmt.pix.field = field;
|
||||
if (f->fmt.pix.height < 32)
|
||||
f->fmt.pix.height = 32;
|
||||
if (f->fmt.pix.height > maxh)
|
||||
f->fmt.pix.height = maxh;
|
||||
if (f->fmt.pix.width < 48)
|
||||
f->fmt.pix.width = 48;
|
||||
if (f->fmt.pix.width > maxw)
|
||||
f->fmt.pix.width = maxw;
|
||||
f->fmt.pix.width &= ~0x03;
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
|
||||
&f->fmt.pix.height, 32, maxh, 0, 0);
|
||||
f->fmt.pix.bytesperline =
|
||||
(f->fmt.pix.width * fmt->depth) >> 3;
|
||||
f->fmt.pix.sizeimage =
|
||||
|
@ -460,7 +460,7 @@ static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
|
||||
static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
|
||||
static int w9968cf_postprocess_frame(struct w9968cf_device*,
|
||||
struct w9968cf_frame_t*);
|
||||
static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
|
||||
static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h);
|
||||
static void w9968cf_init_framelist(struct w9968cf_device*);
|
||||
static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
|
||||
static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
|
||||
@ -1763,8 +1763,7 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
|
||||
#define UNSC(x) ((x) >> 10)
|
||||
|
||||
/* Make sure we are using a supported resolution */
|
||||
if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
|
||||
(u16*)&win.height)))
|
||||
if ((err = w9968cf_adjust_window_size(cam, &win.width, &win.height)))
|
||||
goto error;
|
||||
|
||||
/* Scaling factors */
|
||||
@ -1914,12 +1913,9 @@ error:
|
||||
Return 0 on success, -1 otherwise.
|
||||
--------------------------------------------------------------------------*/
|
||||
static int
|
||||
w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
|
||||
w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height)
|
||||
{
|
||||
u16 maxw, maxh;
|
||||
|
||||
if ((*width < cam->minwidth) || (*height < cam->minheight))
|
||||
return -ERANGE;
|
||||
unsigned int maxw, maxh, align;
|
||||
|
||||
maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
|
||||
w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
|
||||
@ -1927,16 +1923,10 @@ w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
|
||||
maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
|
||||
w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
|
||||
: cam->maxheight;
|
||||
align = (cam->vpp_flag & VPP_DECOMPRESSION) ? 4 : 0;
|
||||
|
||||
if (*width > maxw)
|
||||
*width = maxw;
|
||||
if (*height > maxh)
|
||||
*height = maxh;
|
||||
|
||||
if (cam->vpp_flag & VPP_DECOMPRESSION) {
|
||||
*width &= ~15L; /* multiple of 16 */
|
||||
*height &= ~15L;
|
||||
}
|
||||
v4l_bound_align_image(width, cam->minwidth, maxw, align,
|
||||
height, cam->minheight, maxh, align, 0);
|
||||
|
||||
PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
|
||||
|
||||
@ -3043,8 +3033,8 @@ static long w9968cf_v4l_ioctl(struct file *filp,
|
||||
if (win.clipcount != 0 || win.flags != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
|
||||
(u16*)&win.height))) {
|
||||
if ((err = w9968cf_adjust_window_size(cam, &win.width,
|
||||
&win.height))) {
|
||||
DBG(4, "Resolution not supported (%ux%u). "
|
||||
"VIDIOCSWIN failed", win.width, win.height)
|
||||
return err;
|
||||
@ -3116,6 +3106,7 @@ static long w9968cf_v4l_ioctl(struct file *filp,
|
||||
{
|
||||
struct video_mmap mmap;
|
||||
struct w9968cf_frame_t* fr;
|
||||
u32 w, h;
|
||||
int err = 0;
|
||||
|
||||
if (copy_from_user(&mmap, arg, sizeof(mmap)))
|
||||
@ -3164,8 +3155,10 @@ static long w9968cf_v4l_ioctl(struct file *filp,
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
|
||||
(u16*)&mmap.height))) {
|
||||
w = mmap.width; h = mmap.height;
|
||||
err = w9968cf_adjust_window_size(cam, &w, &h);
|
||||
mmap.width = w; mmap.height = h;
|
||||
if (err) {
|
||||
DBG(4, "Resolution not supported (%dx%d). "
|
||||
"VIDIOCMCAPTURE failed",
|
||||
mmap.width, mmap.height)
|
||||
|
@ -2088,16 +2088,10 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bpp = (zoran_formats[i].depth + 7) / 8;
|
||||
fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
|
||||
if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
|
||||
fmt->fmt.pix.width = BUZ_MAX_WIDTH;
|
||||
if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
|
||||
fmt->fmt.pix.width = BUZ_MIN_WIDTH;
|
||||
if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
|
||||
fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
|
||||
if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
|
||||
fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
|
||||
bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
|
||||
v4l_bound_align_image(
|
||||
&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2,
|
||||
&fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0);
|
||||
mutex_unlock(&zr->resource_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -348,6 +348,7 @@ struct v4l2_pix_format {
|
||||
#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
|
||||
#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
|
||||
#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
|
||||
#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
|
||||
#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
|
||||
|
||||
/*
|
||||
@ -894,9 +895,10 @@ enum v4l2_colorfx {
|
||||
V4L2_COLORFX_BW = 1,
|
||||
V4L2_COLORFX_SEPIA = 2,
|
||||
};
|
||||
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
|
||||
|
||||
/* last CID + 1 */
|
||||
#define V4L2_CID_LASTP1 (V4L2_CID_BASE+32)
|
||||
#define V4L2_CID_LASTP1 (V4L2_CID_BASE+33)
|
||||
|
||||
/* MPEG-class control IDs defined by V4L2 */
|
||||
#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
|
||||
|
@ -162,6 +162,8 @@ extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE];
|
||||
extern IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE];
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -153,6 +153,22 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
|
||||
struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
|
||||
struct i2c_adapter *adapter,
|
||||
const char *module_name, const char *client_type, u8 addr);
|
||||
|
||||
/* Load an i2c module and return an initialized v4l2_subdev struct.
|
||||
Only call request_module if module_name != NULL.
|
||||
The client_type argument is the name of the chip that's on the adapter. */
|
||||
struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
|
||||
struct i2c_adapter *adapter,
|
||||
const char *module_name, const char *client_type,
|
||||
int irq, void *platform_data,
|
||||
u8 addr, const unsigned short *probe_addrs);
|
||||
|
||||
struct i2c_board_info;
|
||||
|
||||
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
|
||||
struct i2c_adapter *adapter, const char *module_name,
|
||||
struct i2c_board_info *info, const unsigned short *probe_addrs);
|
||||
|
||||
/* Initialize an v4l2_subdev with data from an i2c_client struct */
|
||||
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
|
||||
const struct v4l2_subdev_ops *ops);
|
||||
@ -193,4 +209,14 @@ struct v4l2_routing {
|
||||
u32 output;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Miscellaneous helper functions */
|
||||
|
||||
void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
|
||||
unsigned int wmax, unsigned int walign,
|
||||
unsigned int *h, unsigned int hmin,
|
||||
unsigned int hmax, unsigned int halign,
|
||||
unsigned int salign);
|
||||
|
||||
#endif /* V4L2_COMMON_H_ */
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* NOTE: the full version of this header is in the v4l-dvb repository
|
||||
* and allows v4l i2c drivers to be compiled on older kernels as well.
|
||||
* and allows v4l i2c drivers to be compiled on pre-2.6.26 kernels.
|
||||
* The version of this header as it appears in the kernel is a stripped
|
||||
* version (without all the backwards compatibility stuff) and so it
|
||||
* looks a bit odd.
|
||||
@ -30,6 +30,9 @@
|
||||
* If you look at the full version then you will understand the reason
|
||||
* for introducing this header since you really don't want to have all
|
||||
* the tricky backwards compatibility code in each and every i2c driver.
|
||||
*
|
||||
* If the i2c driver will never be compiled for pre-2.6.26 kernels, then
|
||||
* DO NOT USE this header! Just write it as a regular i2c driver.
|
||||
*/
|
||||
|
||||
#ifndef __V4L2_I2C_DRV_H__
|
||||
|
@ -79,7 +79,11 @@ struct v4l2_decode_vbi_line {
|
||||
not yet implemented) since ops provide proper type-checking.
|
||||
*/
|
||||
|
||||
/* init: initialize the sensor registors to some sort of reasonable default
|
||||
/* s_config: if set, then it is always called by the v4l2_i2c_new_subdev*
|
||||
functions after the v4l2_subdev was registered. It is used to pass
|
||||
platform data to the subdev which can be used during initialization.
|
||||
|
||||
init: initialize the sensor registors to some sort of reasonable default
|
||||
values. Do not use for new drivers and should be removed in existing
|
||||
drivers.
|
||||
|
||||
@ -96,6 +100,7 @@ struct v4l2_decode_vbi_line {
|
||||
struct v4l2_subdev_core_ops {
|
||||
int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
|
||||
int (*log_status)(struct v4l2_subdev *sd);
|
||||
int (*s_config)(struct v4l2_subdev *sd, int irq, void *platform_data);
|
||||
int (*init)(struct v4l2_subdev *sd, u32 val);
|
||||
int (*load_fw)(struct v4l2_subdev *sd);
|
||||
int (*reset)(struct v4l2_subdev *sd, u32 val);
|
||||
|
Loading…
Reference in New Issue
Block a user