提交 db0a2901 编写于 作者: M Mauro Carvalho Chehab

Merge branch 'fixes_stg' of ../git_old into fixes

...@@ -3,3 +3,4 @@ ...@@ -3,3 +3,4 @@
2 -> Hauppauge HVR850 (au0828) [2040:7240] 2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
5 -> Hauppauge Woodbury (au0828) [2040:8200]
...@@ -88,14 +88,14 @@ zc3xx 0471:0325 Philips SPC 200 NC ...@@ -88,14 +88,14 @@ zc3xx 0471:0325 Philips SPC 200 NC
zc3xx 0471:0326 Philips SPC 300 NC zc3xx 0471:0326 Philips SPC 300 NC
sonixj 0471:0327 Philips SPC 600 NC sonixj 0471:0327 Philips SPC 600 NC
sonixj 0471:0328 Philips SPC 700 NC sonixj 0471:0328 Philips SPC 700 NC
zc3xx 0471:032d Philips spc210nc zc3xx 0471:032d Philips SPC 210 NC
zc3xx 0471:032e Philips spc315nc zc3xx 0471:032e Philips SPC 315 NC
sonixj 0471:0330 Philips SPC 710NC sonixj 0471:0330 Philips SPC 710 NC
spca501 0497:c001 Smile International spca501 0497:c001 Smile International
sunplus 04a5:3003 Benq DC 1300 sunplus 04a5:3003 Benq DC 1300
sunplus 04a5:3008 Benq DC 1500 sunplus 04a5:3008 Benq DC 1500
sunplus 04a5:300a Benq DC3410 sunplus 04a5:300a Benq DC 3410
spca500 04a5:300c Benq DC1016 spca500 04a5:300c Benq DC 1016
sunplus 04f1:1001 JVC GC A50 sunplus 04f1:1001 JVC GC A50
spca561 04fc:0561 Flexcam 100 spca561 04fc:0561 Flexcam 100
sunplus 04fc:500c Sunplus CA500C sunplus 04fc:500c Sunplus CA500C
...@@ -175,19 +175,21 @@ sunplus 08ca:2060 Aiptek PocketDV5300 ...@@ -175,19 +175,21 @@ sunplus 08ca:2060 Aiptek PocketDV5300
tv8532 0923:010f ICM532 cams tv8532 0923:010f ICM532 cams
mars 093a:050f Mars-Semi Pc-Camera mars 093a:050f Mars-Semi Pc-Camera
pac207 093a:2460 PAC207 Qtec Webcam 100 pac207 093a:2460 PAC207 Qtec Webcam 100
pac207 093a:2463 Philips spc200nc pac207 pac207 093a:2463 Philips SPC 220 NC
pac207 093a:2464 Labtec Webcam 1200 pac207 093a:2464 Labtec Webcam 1200
pac207 093a:2468 PAC207 pac207 093a:2468 PAC207
pac207 093a:2470 Genius GF112 pac207 093a:2470 Genius GF112
pac207 093a:2471 PAC207 Genius VideoCam ge111 pac207 093a:2471 Genius VideoCam ge111
pac207 093a:2472 PAC207 Genius VideoCam ge110 pac207 093a:2472 Genius VideoCam ge110
pac7311 093a:2600 PAC7311 Typhoon pac7311 093a:2600 PAC7311 Typhoon
pac7311 093a:2601 PAC7311 Phillips SPC610NC pac7311 093a:2601 Philips SPC 610 NC
pac7311 093a:2603 PAC7312 pac7311 093a:2603 PAC7312
pac7311 093a:2608 PAC7311 Trust WB-3300p pac7311 093a:2608 Trust WB-3300p
pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
pac7311 093a:260f PAC7311 SnakeCam pac7311 093a:260f SnakeCam
pac7311 093a:2621 PAC731x pac7311 093a:2621 PAC731x
pac7311 093a:2624 PAC7302
pac7311 093a:2626 Labtec 2200
zc3xx 0ac8:0302 Z-star Vimicro zc0302 zc3xx 0ac8:0302 Z-star Vimicro zc0302
vc032x 0ac8:0321 Vimicro generic vc0321 vc032x 0ac8:0321 Vimicro generic vc0321
vc032x 0ac8:0323 Vimicro Vc0323 vc032x 0ac8:0323 Vimicro Vc0323
...@@ -220,6 +222,7 @@ sonixj 0c45:60c0 Sangha Sn535 ...@@ -220,6 +222,7 @@ sonixj 0c45:60c0 Sangha Sn535
sonixj 0c45:60ec SN9C105+MO4000 sonixj 0c45:60ec SN9C105+MO4000
sonixj 0c45:60fb Surfer NoName sonixj 0c45:60fb Surfer NoName
sonixj 0c45:60fc LG-LIC300 sonixj 0c45:60fc LG-LIC300
sonixj 0c45:6128 Microdia/Sonix SNP325
sonixj 0c45:612a Avant Camera sonixj 0c45:612a Avant Camera
sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
sonixj 0c45:6130 Sonix Pccam sonixj 0c45:6130 Sonix Pccam
...@@ -234,7 +237,7 @@ zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 ...@@ -234,7 +237,7 @@ zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
spca561 10fd:7e50 FlyCam Usb 100 spca561 10fd:7e50 FlyCam Usb 100
zc3xx 10fd:8050 Typhoon Webshot II USB 300k zc3xx 10fd:8050 Typhoon Webshot II USB 300k
spca501 1776:501c Arowana 300K CMOS Camera spca501 1776:501c Arowana 300K CMOS Camera
t613 17a1:0128 T613/TAS5130A t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
pac207 2001:f115 D-Link DSB-C120 pac207 2001:f115 D-Link DSB-C120
spca500 2899:012c Toptro Industrial spca500 2899:012c Toptro Industrial
......
...@@ -1068,7 +1068,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -1068,7 +1068,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
{ {
v4l2_std_id *id = arg; v4l2_std_id *id = arg;
int found = 0; int found = 0;
int i, err; int i;
DEB_EE(("VIDIOC_S_STD\n")); DEB_EE(("VIDIOC_S_STD\n"));
...@@ -1116,7 +1116,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -1116,7 +1116,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
case VIDIOC_OVERLAY: case VIDIOC_OVERLAY:
{ {
int on = *(int *)arg; int on = *(int *)arg;
int err = 0;
DEB_D(("VIDIOC_OVERLAY on:%d\n",on)); DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
if (on != 0) { if (on != 0) {
...@@ -1192,7 +1191,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -1192,7 +1191,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
case VIDIOCGMBUF: case VIDIOCGMBUF:
{ {
struct video_mbuf *mbuf = arg; struct video_mbuf *mbuf = arg;
struct videobuf_queue *q;
int i; int i;
/* fixme: number of capture buffers and sizes for v4l apps */ /* fixme: number of capture buffers and sizes for v4l apps */
......
/* /*
* Driver for Microtune MT2131 "QAM/8VSB single chip tuner" * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for Microtune MT2131 "QAM/8VSB single chip tuner" * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for Microtune MT2131 "QAM/8VSB single chip tuner" * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
MaxLinear MXL5005S VSB/QAM/DVBT tuner driver MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
Copyright (C) 2008 MaxLinear Copyright (C) 2008 MaxLinear
Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
Functions: Functions:
mxl5005s_reset() mxl5005s_reset()
mxl5005s_writereg() mxl5005s_writereg()
...@@ -3837,7 +3837,7 @@ static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis) ...@@ -3837,7 +3837,7 @@ static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* Begin: Everything after here is new code to adapt the * Begin: Everything after here is new code to adapt the
* proprietary Realtek driver into a Linux API tuner. * proprietary Realtek driver into a Linux API tuner.
* Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
*/ */
static int mxl5005s_reset(struct dvb_frontend *fe) static int mxl5005s_reset(struct dvb_frontend *fe)
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
MaxLinear MXL5005S VSB/QAM/DVBT tuner driver MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
Copyright (C) 2008 MaxLinear Copyright (C) 2008 MaxLinear
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
...@@ -253,7 +253,7 @@ static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe, ...@@ -253,7 +253,7 @@ static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe,
static int simple_config_lookup(struct dvb_frontend *fe, static int simple_config_lookup(struct dvb_frontend *fe,
struct tuner_params *t_params, struct tuner_params *t_params,
int *frequency, u8 *config, u8 *cb) unsigned *frequency, u8 *config, u8 *cb)
{ {
struct tuner_simple_priv *priv = fe->tuner_priv; struct tuner_simple_priv *priv = fe->tuner_priv;
int i; int i;
...@@ -587,45 +587,45 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, ...@@ -587,45 +587,45 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
priv->last_div = div; priv->last_div = div;
if (t_params->has_tda9887) { if (t_params->has_tda9887) {
struct v4l2_priv_tun_config tda9887_cfg; struct v4l2_priv_tun_config tda9887_cfg;
int config = 0; int tda_config = 0;
int is_secam_l = (params->std & (V4L2_STD_SECAM_L | int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
V4L2_STD_SECAM_LC)) && V4L2_STD_SECAM_LC)) &&
!(params->std & ~(V4L2_STD_SECAM_L | !(params->std & ~(V4L2_STD_SECAM_L |
V4L2_STD_SECAM_LC)); V4L2_STD_SECAM_LC));
tda9887_cfg.tuner = TUNER_TDA9887; tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &config; tda9887_cfg.priv = &tda_config;
if (params->std == V4L2_STD_SECAM_LC) { if (params->std == V4L2_STD_SECAM_LC) {
if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc) if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
config |= TDA9887_PORT1_ACTIVE; tda_config |= TDA9887_PORT1_ACTIVE;
if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
config |= TDA9887_PORT2_ACTIVE; tda_config |= TDA9887_PORT2_ACTIVE;
} else { } else {
if (t_params->port1_active) if (t_params->port1_active)
config |= TDA9887_PORT1_ACTIVE; tda_config |= TDA9887_PORT1_ACTIVE;
if (t_params->port2_active) if (t_params->port2_active)
config |= TDA9887_PORT2_ACTIVE; tda_config |= TDA9887_PORT2_ACTIVE;
} }
if (t_params->intercarrier_mode) if (t_params->intercarrier_mode)
config |= TDA9887_INTERCARRIER; tda_config |= TDA9887_INTERCARRIER;
if (is_secam_l) { if (is_secam_l) {
if (i == 0 && t_params->default_top_secam_low) if (i == 0 && t_params->default_top_secam_low)
config |= TDA9887_TOP(t_params->default_top_secam_low); tda_config |= TDA9887_TOP(t_params->default_top_secam_low);
else if (i == 1 && t_params->default_top_secam_mid) else if (i == 1 && t_params->default_top_secam_mid)
config |= TDA9887_TOP(t_params->default_top_secam_mid); tda_config |= TDA9887_TOP(t_params->default_top_secam_mid);
else if (t_params->default_top_secam_high) else if (t_params->default_top_secam_high)
config |= TDA9887_TOP(t_params->default_top_secam_high); tda_config |= TDA9887_TOP(t_params->default_top_secam_high);
} else { } else {
if (i == 0 && t_params->default_top_low) if (i == 0 && t_params->default_top_low)
config |= TDA9887_TOP(t_params->default_top_low); tda_config |= TDA9887_TOP(t_params->default_top_low);
else if (i == 1 && t_params->default_top_mid) else if (i == 1 && t_params->default_top_mid)
config |= TDA9887_TOP(t_params->default_top_mid); tda_config |= TDA9887_TOP(t_params->default_top_mid);
else if (t_params->default_top_high) else if (t_params->default_top_high)
config |= TDA9887_TOP(t_params->default_top_high); tda_config |= TDA9887_TOP(t_params->default_top_high);
} }
if (t_params->default_pll_gating_18) if (t_params->default_pll_gating_18)
config |= TDA9887_GATING_18; tda_config |= TDA9887_GATING_18;
i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
&tda9887_cfg); &tda9887_cfg);
} }
...@@ -813,7 +813,8 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, ...@@ -813,7 +813,8 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf,
static struct tuner_params *t_params; static struct tuner_params *t_params;
u8 config, cb; u8 config, cb;
u32 div; u32 div;
int ret, frequency = params->frequency / 62500; int ret;
unsigned frequency = params->frequency / 62500;
t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Driver for Xceive XC5000 "QAM/8VSB single chip tuner" * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
* *
* Copyright (c) 2007 Xceive Corporation * Copyright (c) 2007 Xceive Corporation
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for Xceive XC5000 "QAM/8VSB single chip tuner" * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
* *
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for Xceive XC5000 "QAM/8VSB single chip tuner" * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
* *
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -221,12 +221,12 @@ int flexcop_i2c_init(struct flexcop_device *fc) ...@@ -221,12 +221,12 @@ int flexcop_i2c_init(struct flexcop_device *fc)
fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM; fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER; fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
strncpy(fc->fc_i2c_adap[0].i2c_adap.name, strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
"B2C2 FlexCop I2C to demod", I2C_NAME_SIZE); sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
strncpy(fc->fc_i2c_adap[1].i2c_adap.name, strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
"B2C2 FlexCop I2C to eeprom", I2C_NAME_SIZE); sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
strncpy(fc->fc_i2c_adap[2].i2c_adap.name, strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
"B2C2 FlexCop I2C to tuner", I2C_NAME_SIZE); sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]); i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
......
...@@ -641,7 +641,6 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) ...@@ -641,7 +641,6 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
struct timespec timeout = { 0 }; struct timespec timeout = { 0 };
struct dmx_pes_filter_params *para = &filter->params.pes; struct dmx_pes_filter_params *para = &filter->params.pes;
dmx_output_t otype; dmx_output_t otype;
int ret;
int ts_type; int ts_type;
enum dmx_ts_pes ts_pes; enum dmx_ts_pes ts_pes;
struct dmx_ts_feed **tsfeed = &filter->feed.ts; struct dmx_ts_feed **tsfeed = &filter->feed.ts;
......
...@@ -1032,7 +1032,7 @@ static int dvb_ca_en50221_thread(void *data) ...@@ -1032,7 +1032,7 @@ static int dvb_ca_en50221_thread(void *data)
/* we need this extra check for annoying interfaces like the budget-av */ /* we need this extra check for annoying interfaces like the budget-av */
if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
(ca->pub->poll_slot_status)) { (ca->pub->poll_slot_status)) {
int status = ca->pub->poll_slot_status(ca->pub, slot, 0); status = ca->pub->poll_slot_status(ca->pub, slot, 0);
if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
dvb_ca_en50221_thread_update_delay(ca); dvb_ca_en50221_thread_update_delay(ca);
...@@ -1089,7 +1089,7 @@ static int dvb_ca_en50221_thread(void *data) ...@@ -1089,7 +1089,7 @@ static int dvb_ca_en50221_thread(void *data)
/* we need this extra check for annoying interfaces like the budget-av */ /* we need this extra check for annoying interfaces like the budget-av */
if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
(ca->pub->poll_slot_status)) { (ca->pub->poll_slot_status)) {
int status = ca->pub->poll_slot_status(ca->pub, slot, 0); status = ca->pub->poll_slot_status(ca->pub, slot, 0);
if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
dvb_ca_en50221_thread_update_delay(ca); dvb_ca_en50221_thread_update_delay(ca);
......
...@@ -889,13 +889,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, ...@@ -889,13 +889,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
* initialization, so parg is 8 bits and does not * initialization, so parg is 8 bits and does not
* include the initialization or start bit * include the initialization or start bit
*/ */
unsigned long cmd = ((unsigned long) parg) << 1; unsigned long swcmd = ((unsigned long) parg) << 1;
struct timeval nexttime; struct timeval nexttime;
struct timeval tv[10]; struct timeval tv[10];
int i; int i;
u8 last = 1; u8 last = 1;
if (dvb_frontend_debug) if (dvb_frontend_debug)
printk("%s switch command: 0x%04lx\n", __func__, cmd); printk("%s switch command: 0x%04lx\n", __func__, swcmd);
do_gettimeofday(&nexttime); do_gettimeofday(&nexttime);
if (dvb_frontend_debug) if (dvb_frontend_debug)
memcpy(&tv[0], &nexttime, sizeof(struct timeval)); memcpy(&tv[0], &nexttime, sizeof(struct timeval));
...@@ -908,12 +908,12 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, ...@@ -908,12 +908,12 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
for (i = 0; i < 9; i++) { for (i = 0; i < 9; i++) {
if (dvb_frontend_debug) if (dvb_frontend_debug)
do_gettimeofday(&tv[i + 1]); do_gettimeofday(&tv[i + 1]);
if ((cmd & 0x01) != last) { if ((swcmd & 0x01) != last) {
/* set voltage to (last ? 13V : 18V) */ /* set voltage to (last ? 13V : 18V) */
fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
last = (last) ? 0 : 1; last = (last) ? 0 : 1;
} }
cmd = cmd >> 1; swcmd = swcmd >> 1;
if (i != 8) if (i != 8)
dvb_frontend_sleep_until(&nexttime, 8000); dvb_frontend_sleep_until(&nexttime, 8000);
} }
......
...@@ -210,7 +210,7 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff) ...@@ -210,7 +210,7 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
if (d->state == DVB_USB_STATE_INIT && if (d->state == DVB_USB_STATE_INIT &&
usb_set_interface(d->udev, 0, 0) < 0) usb_set_interface(d->udev, 0, 0) < 0)
err("set interface failed"); err("set interface failed");
do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
!(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
!(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
if (!ret) { if (!ret) {
......
...@@ -1117,7 +1117,8 @@ struct usb_device_id dib0700_usb_id_table[] = { ...@@ -1117,7 +1117,8 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
{ USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, /* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
{ 0 } /* Terminating entry */ { 0 } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
...@@ -1373,7 +1374,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { ...@@ -1373,7 +1374,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
} }
}, },
.num_device_descs = 3, .num_device_descs = 4,
.devices = { .devices = {
{ "DiBcom STK7070PD reference design", { "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL }, { &dib0700_usb_id_table[17], NULL },
...@@ -1386,6 +1387,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { ...@@ -1386,6 +1387,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Hauppauge Nova-TD Stick (52009)", { "Hauppauge Nova-TD Stick (52009)",
{ &dib0700_usb_id_table[35], NULL }, { &dib0700_usb_id_table[35], NULL },
{ NULL }, { NULL },
},
{ "Hauppauge Nova-TD-500 (84xxx)",
{ &dib0700_usb_id_table[36], NULL },
{ NULL },
} }
} }
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
......
...@@ -129,6 +129,7 @@ ...@@ -129,6 +129,7 @@
#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
#define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941 #define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941
#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950 #define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950
#define USB_PID_HAUPPAUGE_NOVA_T_500_3 0x8400
#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050 #define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050
#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060
#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
......
/* /*
Auvitek AU8522 QAM/8VSB demodulator driver Auvitek AU8522 QAM/8VSB demodulator driver
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -304,6 +304,43 @@ static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, ...@@ -304,6 +304,43 @@ static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
return ret; return ret;
} }
static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
{
struct au8522_state *state = fe->demodulator_priv;
u8 r0b5, r0b6, r0b7;
char *ifmhz;
switch (if_freq) {
case AU8522_IF_3_25MHZ:
ifmhz = "3.25";
r0b5 = 0x00;
r0b6 = 0x3d;
r0b7 = 0xa0;
break;
case AU8522_IF_4MHZ:
ifmhz = "4.00";
r0b5 = 0x00;
r0b6 = 0x4b;
r0b7 = 0xd9;
break;
case AU8522_IF_6MHZ:
ifmhz = "6.00";
r0b5 = 0xfb;
r0b6 = 0x8e;
r0b7 = 0x39;
break;
default:
dprintk("%s() IF Frequency not supported\n", __func__);
return -EINVAL;
}
dprintk("%s() %s MHz\n", __func__, ifmhz);
au8522_writereg(state, 0x80b5, r0b5);
au8522_writereg(state, 0x80b6, r0b6);
au8522_writereg(state, 0x80b7, r0b7);
return 0;
}
/* VSB Modulation table */ /* VSB Modulation table */
static struct { static struct {
u16 reg; u16 reg;
...@@ -334,9 +371,6 @@ static struct { ...@@ -334,9 +371,6 @@ static struct {
{ 0x80af, 0x66 }, { 0x80af, 0x66 },
{ 0x821b, 0xcc }, { 0x821b, 0xcc },
{ 0x821d, 0x80 }, { 0x821d, 0x80 },
{ 0x80b5, 0xfb },
{ 0x80b6, 0x8e },
{ 0x80b7, 0x39 },
{ 0x80a4, 0xe8 }, { 0x80a4, 0xe8 },
{ 0x8231, 0x13 }, { 0x8231, 0x13 },
}; };
...@@ -350,9 +384,6 @@ static struct { ...@@ -350,9 +384,6 @@ static struct {
{ 0x80a4, 0x00 }, { 0x80a4, 0x00 },
{ 0x8081, 0xc4 }, { 0x8081, 0xc4 },
{ 0x80a5, 0x40 }, { 0x80a5, 0x40 },
{ 0x80b5, 0xfb },
{ 0x80b6, 0x8e },
{ 0x80b7, 0x39 },
{ 0x80aa, 0x77 }, { 0x80aa, 0x77 },
{ 0x80ad, 0x77 }, { 0x80ad, 0x77 },
{ 0x80a6, 0x67 }, { 0x80a6, 0x67 },
...@@ -438,6 +469,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, ...@@ -438,6 +469,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_writereg(state, au8522_writereg(state,
VSB_mod_tab[i].reg, VSB_mod_tab[i].reg,
VSB_mod_tab[i].data); VSB_mod_tab[i].data);
au8522_set_if(fe, state->config->vsb_if);
break; break;
case QAM_64: case QAM_64:
case QAM_256: case QAM_256:
...@@ -446,6 +478,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, ...@@ -446,6 +478,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_writereg(state, au8522_writereg(state,
QAM_mod_tab[i].reg, QAM_mod_tab[i].reg,
QAM_mod_tab[i].data); QAM_mod_tab[i].data);
au8522_set_if(fe, state->config->qam_if);
break; break;
default: default:
dprintk("%s() Invalid modulation\n", __func__); dprintk("%s() Invalid modulation\n", __func__);
......
/* /*
Auvitek AU8522 QAM/8VSB demodulator driver Auvitek AU8522 QAM/8VSB demodulator driver
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
enum au8522_if_freq {
AU8522_IF_6MHZ = 0,
AU8522_IF_4MHZ,
AU8522_IF_3_25MHZ,
};
struct au8522_config { struct au8522_config {
/* the demodulator's i2c address */ /* the demodulator's i2c address */
u8 demod_address; u8 demod_address;
...@@ -32,6 +38,9 @@ struct au8522_config { ...@@ -32,6 +38,9 @@ struct au8522_config {
#define AU8522_TUNERLOCKING 0 #define AU8522_TUNERLOCKING 0
#define AU8522_DEMODLOCKING 1 #define AU8522_DEMODLOCKING 1
u8 status_mode; u8 status_mode;
enum au8522_if_freq vsb_if;
enum au8522_if_freq qam_if;
}; };
#if defined(CONFIG_DVB_AU8522) || \ #if defined(CONFIG_DVB_AU8522) || \
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Copyright (C) 2001-2002 Convergence Integrated Media GmbH Copyright (C) 2001-2002 Convergence Integrated Media GmbH
Holger Waechtler <holger@convergence.de> Holger Waechtler <holger@convergence.de>
Copyright (C) 2004 Steven Toth <stoth@hauppauge.com> Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Copyright (C) 2001-2002 Convergence Integrated Media GmbH Copyright (C) 2001-2002 Convergence Integrated Media GmbH
Holger Waechtler <holger@convergence.de> Holger Waechtler <holger@convergence.de>
Copyright (C) 2004 Steven Toth <stoth@hauppauge.com> Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
/* /*
* Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
* *
* Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> * Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
* *
* Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> * Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
* *
...@@ -1072,8 +1072,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, ...@@ -1072,8 +1072,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
if (config->dont_use_pll) if (config->dont_use_pll)
cx24123_repeater_mode(state, 1, 0); cx24123_repeater_mode(state, 1, 0);
strncpy(state->tuner_i2c_adapter.name, strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
"CX24123 tuner I2C bus", I2C_NAME_SIZE); sizeof(state->tuner_i2c_adapter.name));
state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo;
state->tuner_i2c_adapter.algo_data = NULL; state->tuner_i2c_adapter.algo_data = NULL;
......
/* /*
Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
/* /*
Samsung S5H1409 VSB/QAM demodulator driver Samsung S5H1409 VSB/QAM demodulator driver
Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -404,6 +404,7 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe, ...@@ -404,6 +404,7 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
break; break;
case QAM_64: case QAM_64:
case QAM_256: case QAM_256:
case QAM_AUTO:
dprintk("%s() QAM_AUTO (64/256)\n", __func__); dprintk("%s() QAM_AUTO (64/256)\n", __func__);
if (state->if_freq != S5H1409_QAM_IF_FREQ) if (state->if_freq != S5H1409_QAM_IF_FREQ)
s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ); s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
......
/* /*
Samsung S5H1409 VSB/QAM demodulator driver Samsung S5H1409 VSB/QAM demodulator driver
Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
/* /*
Samsung S5H1411 VSB/QAM demodulator driver Samsung S5H1411 VSB/QAM demodulator driver
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -488,6 +488,7 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe, ...@@ -488,6 +488,7 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe,
break; break;
case QAM_64: case QAM_64:
case QAM_256: case QAM_256:
case QAM_AUTO:
dprintk("%s() QAM_AUTO (64/256)\n", __func__); dprintk("%s() QAM_AUTO (64/256)\n", __func__);
s5h1411_set_if_freq(fe, state->config->qam_if); s5h1411_set_if_freq(fe, state->config->qam_if);
s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171); s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
......
/* /*
Samsung S5H1411 VSB/QAM demodulator driver Samsung S5H1411 VSB/QAM demodulator driver
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
...@@ -915,7 +915,8 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, ...@@ -915,7 +915,8 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
state->frontend.demodulator_priv = state; state->frontend.demodulator_priv = state;
/* create tuner i2c adapter */ /* create tuner i2c adapter */
strncpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", I2C_NAME_SIZE); strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
sizeof(state->tuner_i2c_adapter.name));
state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo;
state->tuner_i2c_adapter.algo_data = NULL; state->tuner_i2c_adapter.algo_data = NULL;
......
/* /*
NXP TDA10048HN DVB OFDM demodulator driver NXP TDA10048HN DVB OFDM demodulator driver
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -303,7 +303,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe) ...@@ -303,7 +303,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe)
if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) { if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
printk(KERN_ERR "%s: firmware incorrect size\n", __func__); printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
return -EIO; ret = -EIO;
} else { } else {
printk(KERN_INFO "%s: firmware uploading\n", __func__); printk(KERN_INFO "%s: firmware uploading\n", __func__);
......
/* /*
NXP TDA10048HN DVB OFDM demodulator driver NXP TDA10048HN DVB OFDM demodulator driver
Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation; * published by the Free Software Foundation;
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation; * published by the Free Software Foundation;
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation; * published by the Free Software Foundation;
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation; * published by the Free Software Foundation;
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation; * published by the Free Software Foundation;
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation; * published by the Free Software Foundation;
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
# Makefile for the kernel character device drivers. # Makefile for the kernel character device drivers.
# #
miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o
obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
...@@ -14,8 +12,6 @@ obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o ...@@ -14,8 +12,6 @@ obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o
obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o
obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
obj-$(CONFIG_RADIO_MIROPCM20) += miropcm20.o
obj-$(CONFIG_RADIO_MIROPCM20_RDS) += miropcm20-rds.o
obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
......
...@@ -493,7 +493,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, ...@@ -493,7 +493,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
radio->usbdev = interface_to_usbdev(intf); radio->usbdev = interface_to_usbdev(intf);
radio->curfreq = FREQ_MIN*FREQ_MUL; radio->curfreq = FREQ_MIN*FREQ_MUL;
video_set_drvdata(radio->videodev, radio); video_set_drvdata(radio->videodev, radio);
if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) { if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
warn("Could not register video device"); warn("Could not register video device");
video_device_release(radio->videodev); video_device_release(radio->videodev);
kfree(radio->transfer_buffer); kfree(radio->transfer_buffer);
......
/* Miro PCM20 radio driver for Linux radio support
* (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
* Thanks to Norberto Pellici for the ACI device interface specification
* The API part is based on the radiotrack driver by M. Kirkwood
* This driver relies on the aci mixer (drivers/sound/aci.c)
* Look there for further info...
*/
/* Revision history:
*
* 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
* 2000-09-05 Robert Siemer <Robert.Siemer@gmx.de>
* removed unfinished volume control (maybe adding it later again)
* use OSS-mixer; added stereo control
*/
/* What ever you think about the ACI, version 0x07 is not very well!
* I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
* conditions... Robert
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include "oss/aci.h"
#include "miropcm20-rds-core.h"
static int radio_nr = -1;
module_param(radio_nr, int, 0);
struct pcm20_device {
unsigned long freq;
int muted;
int stereo;
};
static int pcm20_mute(struct pcm20_device *dev, unsigned char mute)
{
dev->muted = mute;
return aci_write_cmd(ACI_SET_TUNERMUTE, mute);
}
static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo)
{
dev->stereo = stereo;
return aci_write_cmd(ACI_SET_TUNERMONO, !stereo);
}
static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
{
unsigned char freql;
unsigned char freqh;
dev->freq=freq;
freq /= 160;
if (!(aci_version==0x07 || aci_version>=0xb0))
freq /= 10; /* I don't know exactly which version
* needs this hack */
freql = freq & 0xff;
freqh = freq >> 8;
aci_rds_cmd(RDS_RESET, NULL, 0);
pcm20_stereo(dev, 1);
return aci_rw_cmd(ACI_WRITE_TUNE, freql, freqh);
}
static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal)
{
/* okay, check for signal, stereo and rds here... */
int i;
unsigned char buf;
if ((i=aci_rw_cmd(ACI_READ_TUNERSTATION, -1, -1))<0)
return i;
pr_debug("check_sig: 0x%x\n", i);
if (i & 0x80) {
/* no signal from tuner */
*flags=0;
*signal=0;
return 0;
} else
*signal=0xffff;
if ((i=aci_rw_cmd(ACI_READ_TUNERSTEREO, -1, -1))<0)
return i;
if (i & 0x40) {
*flags=0;
} else {
/* stereo */
*flags=VIDEO_TUNER_STEREO_ON;
/* I can't see stereo, when forced to mono */
dev->stereo=1;
}
if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0)
return i;
if (buf & 1)
/* RDS available */
*flags|=VIDEO_TUNER_RDS_ON;
else
return 0;
if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0)
return i;
pr_debug("rds-signal: %d\n", buf);
if (buf > 15) {
printk("miropcm20-radio: RX strengths unexpected high...\n");
buf=15;
}
/* refine signal */
if ((*signal=SCALE(15, 0xffff, buf))==0)
*signal = 1;
return 0;
}
static int pcm20_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
struct video_device *dev = video_devdata(file);
struct pcm20_device *pcm20 = dev->priv;
int i;
switch(cmd)
{
case VIDIOCGCAP:
{
struct video_capability *v = arg;
memset(v,0,sizeof(*v));
v->type=VID_TYPE_TUNER;
strcpy(v->name, "Miro PCM20");
v->channels=1;
v->audios=1;
return 0;
}
case VIDIOCGTUNER:
{
struct video_tuner *v = arg;
if(v->tuner) /* Only 1 tuner */
return -EINVAL;
v->rangelow=87*16000;
v->rangehigh=108*16000;
pcm20_getflags(pcm20, &v->flags, &v->signal);
v->flags|=VIDEO_TUNER_LOW;
v->mode=VIDEO_MODE_AUTO;
strcpy(v->name, "FM");
return 0;
}
case VIDIOCSTUNER:
{
struct video_tuner *v = arg;
if(v->tuner!=0)
return -EINVAL;
/* Only 1 tuner so no setting needed ! */
return 0;
}
case VIDIOCGFREQ:
{
unsigned long *freq = arg;
*freq = pcm20->freq;
return 0;
}
case VIDIOCSFREQ:
{
unsigned long *freq = arg;
pcm20->freq = *freq;
i=pcm20_setfreq(pcm20, pcm20->freq);
pr_debug("First view (setfreq): 0x%x\n", i);
return i;
}
case VIDIOCGAUDIO:
{
struct video_audio *v = arg;
memset(v,0, sizeof(*v));
v->flags=VIDEO_AUDIO_MUTABLE;
if (pcm20->muted)
v->flags|=VIDEO_AUDIO_MUTE;
v->mode=VIDEO_SOUND_STEREO;
if (pcm20->stereo)
v->mode|=VIDEO_SOUND_MONO;
/* v->step=2048; */
strcpy(v->name, "Radio");
return 0;
}
case VIDIOCSAUDIO:
{
struct video_audio *v = arg;
if(v->audio)
return -EINVAL;
pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE));
if(v->flags&VIDEO_SOUND_MONO)
pcm20_stereo(pcm20, 0);
if(v->flags&VIDEO_SOUND_STEREO)
pcm20_stereo(pcm20, 1);
return 0;
}
default:
return -ENOIOCTLCMD;
}
}
static int pcm20_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
return video_usercopy(inode, file, cmd, arg, pcm20_do_ioctl);
}
static struct pcm20_device pcm20_unit = {
.freq = 87*16000,
.muted = 1,
};
static const struct file_operations pcm20_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
.ioctl = pcm20_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = v4l_compat_ioctl32,
#endif
.llseek = no_llseek,
};
static struct video_device pcm20_radio = {
.name = "Miro PCM 20 radio",
.fops = &pcm20_fops,
.priv = &pcm20_unit
};
static int __init pcm20_init(void)
{
if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
goto video_register_device;
if(attach_aci_rds()<0)
goto attach_aci_rds;
printk(KERN_INFO "Miro PCM20 radio card driver.\n");
return 0;
attach_aci_rds:
video_unregister_device(&pcm20_radio);
video_register_device:
return -EINVAL;
}
MODULE_AUTHOR("Ruurd Reitsma");
MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
MODULE_LICENSE("GPL");
static void __exit pcm20_cleanup(void)
{
unload_aci_rds();
video_unregister_device(&pcm20_radio);
}
module_init(pcm20_init);
module_exit(pcm20_cleanup);
/*
* Many thanks to Fred Seidel <seidel@metabox.de>, the
* designer of the RDS decoder hardware. With his help
* I was able to code this driver.
* Thanks also to Norberto Pellicci, Dominic Mounteney
* <DMounteney@pinnaclesys.com> and www.teleauskunft.de
* for good hints on finding Fred. It was somewhat hard
* to locate him here in Germany... [:
*
* Revision history:
*
* 2000-08-09 Robert Siemer <Robert.Siemer@gmx.de>
* RDS support for MiroSound PCM20 radio
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include "oss/aci.h"
#include "miropcm20-rds-core.h"
#define DEBUG 0
static struct mutex aci_rds_mutex;
#define RDS_DATASHIFT 2 /* Bit 2 */
#define RDS_DATAMASK (1 << RDS_DATASHIFT)
#define RDS_BUSYMASK 0x10 /* Bit 4 */
#define RDS_CLOCKMASK 0x08 /* Bit 3 */
#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1)
#if DEBUG
static void print_matrix(char array[], unsigned int length)
{
int i, j;
for (i=0; i<length; i++) {
printk(KERN_DEBUG "aci-rds: ");
for (j=7; j>=0; j--) {
printk("%d", (array[i] >> j) & 0x1);
}
if (i%8 == 0)
printk(" byte-border\n");
else
printk("\n");
}
}
#endif /* DEBUG */
static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
{
int i;
if (size != 8)
return -1;
for (i = 7; i >= 0; i--)
sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
sendbuffer[0] |= RDS_CLOCKMASK;
return 0;
}
static int rds_waitread(void)
{
unsigned char byte;
int i=2000;
do {
byte=inb(RDS_REGISTER);
i--;
}
while ((byte & RDS_BUSYMASK) && i);
if (i) {
#if DEBUG
printk(KERN_DEBUG "rds_waitread()");
print_matrix(&byte, 1);
#endif
return (byte);
} else {
printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n");
return -1;
}
}
/* don't use any ..._nowait() function if you are not sure what you do... */
static inline void rds_rawwrite_nowait(unsigned char byte)
{
#if DEBUG
printk(KERN_DEBUG "rds_rawwrite()");
print_matrix(&byte, 1);
#endif
outb(byte, RDS_REGISTER);
}
static int rds_rawwrite(unsigned char byte)
{
if (rds_waitread() >= 0) {
rds_rawwrite_nowait(byte);
return 0;
} else
return -1;
}
static int rds_write(unsigned char cmd)
{
unsigned char sendbuffer[8];
int i;
if (byte2trans(cmd, sendbuffer, 8) != 0){
return -1;
} else {
for (i=0; i<8; i++) {
rds_rawwrite(sendbuffer[i]);
}
}
return 0;
}
static int rds_readcycle_nowait(void)
{
rds_rawwrite_nowait(0);
return rds_waitread();
}
static int rds_readcycle(void)
{
if (rds_rawwrite(0) < 0)
return -1;
return rds_waitread();
}
static int rds_read(unsigned char databuffer[], int datasize)
{
#define READSIZE (8*datasize)
int i,j;
if (datasize < 1) /* nothing to read */
return 0;
/* to be able to use rds_readcycle_nowait()
I have to waitread() here */
if (rds_waitread() < 0)
return -1;
memset(databuffer, 0, datasize);
for (i=0; i< READSIZE; i++)
if((j=rds_readcycle_nowait()) < 0) {
return -1;
} else {
databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8)));
}
return 0;
}
static int rds_ack(void)
{
int i=rds_readcycle();
if (i < 0)
return -1;
if (i & RDS_DATAMASK) {
return 0; /* ACK */
} else {
printk(KERN_DEBUG "aci-rds: NACK\n");
return 1; /* NACK */
}
}
int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
{
int ret;
if (mutex_lock_interruptible(&aci_rds_mutex))
return -EINTR;
rds_write(cmd);
/* RDS_RESET doesn't need further processing */
if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
ret = -1;
else
ret = 0;
mutex_unlock(&aci_rds_mutex);
return ret;
}
EXPORT_SYMBOL(aci_rds_cmd);
int __init attach_aci_rds(void)
{
mutex_init(&aci_rds_mutex);
return 0;
}
void __exit unload_aci_rds(void)
{
}
MODULE_LICENSE("GPL");
#ifndef _MIROPCM20_RDS_CORE_H_
#define _MIROPCM20_RDS_CORE_H_
extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize);
#define RDS_STATUS 0x01
#define RDS_STATIONNAME 0x02
#define RDS_TEXT 0x03
#define RDS_ALTFREQ 0x04
#define RDS_TIMEDATE 0x05
#define RDS_PI_CODE 0x06
#define RDS_PTYTATP 0x07
#define RDS_RESET 0x08
#define RDS_RXVALUE 0x09
extern void __exit unload_aci_rds(void);
extern int __init attach_aci_rds(void);
#endif /* _MIROPCM20_RDS_CORE_H_ */
/* MiroSOUND PCM20 radio rds interface driver
* (c) 2001 Robert Siemer <Robert.Siemer@gmx.de>
* Thanks to Fred Seidel. See miropcm20-rds-core.c for further information.
*/
/* Revision history:
*
* 2001-04-18 Robert Siemer <Robert.Siemer@gmx.de>
* separate file for user interface driver
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include "miropcm20-rds-core.h"
static char * text_buffer;
static int rds_users;
static int rds_f_open(struct inode *in, struct file *fi)
{
if (rds_users)
return -EBUSY;
lock_kernel();
rds_users++;
if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) {
rds_users--;
printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n");
unlock_kernel();
return -ENOMEM;
}
unlock_kernel();
return 0;
}
static int rds_f_release(struct inode *in, struct file *fi)
{
kfree(text_buffer);
rds_users--;
return 0;
}
static void print_matrix(char *ch, char out[])
{
int j;
for (j=7; j>=0; j--) {
out[7-j] = ((*ch >> j) & 0x1) + '0';
}
}
static ssize_t rds_f_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
// i = sprintf(text_buffer, "length: %d, offset: %d\n", length, *offset);
char c;
char bits[8];
msleep(2000);
aci_rds_cmd(RDS_STATUS, &c, 1);
print_matrix(&c, bits);
if (copy_to_user(buffer, bits, 8))
return -EFAULT;
/* if ((c >> 3) & 1) {
aci_rds_cmd(RDS_STATIONNAME, text_buffer+1, 8);
text_buffer[0] = ' ' ;
text_buffer[9] = '\n';
return copy_to_user(buffer+8, text_buffer, 10) ? -EFAULT: 18;
}
*/
/* if ((c >> 6) & 1) {
aci_rds_cmd(RDS_PTYTATP, &c, 1);
if ( c & 1)
sprintf(text_buffer, " M");
else
sprintf(text_buffer, " S");
if ((c >> 1) & 1)
sprintf(text_buffer+2, " TA");
else
sprintf(text_buffer+2, " --");
if ((c >> 7) & 1)
sprintf(text_buffer+5, " TP");
else
sprintf(text_buffer+5, " --");
sprintf(text_buffer+8, " %2d\n", (c >> 2) & 0x1f);
return copy_to_user(buffer+8, text_buffer, 12) ? -EFAULT: 20;
}
*/
if ((c >> 4) & 1) {
aci_rds_cmd(RDS_TEXT, text_buffer, 65);
text_buffer[0] = ' ' ;
text_buffer[65] = '\n';
return copy_to_user(buffer+8, text_buffer,66) ? -EFAULT : 66+8;
} else {
put_user('\n', buffer+8);
return 9;
}
}
static const struct file_operations rds_fops = {
.owner = THIS_MODULE,
.read = rds_f_read,
.open = rds_f_open,
.release = rds_f_release
};
static struct miscdevice rds_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "radiotext",
.fops = &rds_fops,
};
static int __init miropcm20_rds_init(void)
{
return misc_register(&rds_miscdev);
}
static void __exit miropcm20_rds_cleanup(void)
{
misc_deregister(&rds_miscdev);
}
module_init(miropcm20_rds_init);
module_exit(miropcm20_rds_cleanup);
MODULE_LICENSE("GPL");
...@@ -426,8 +426,7 @@ static int __init rtrack_init(void) ...@@ -426,8 +426,7 @@ static int __init rtrack_init(void)
rtrack_radio.priv=&rtrack_unit; rtrack_radio.priv=&rtrack_unit;
if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
{
release_region(io, 2); release_region(io, 2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -394,8 +394,7 @@ static int __init aztech_init(void) ...@@ -394,8 +394,7 @@ static int __init aztech_init(void)
mutex_init(&lock); mutex_init(&lock);
aztech_radio.priv=&aztech_unit; aztech_radio.priv=&aztech_unit;
if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
{
release_region(io,2); release_region(io,2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -682,7 +682,7 @@ static int __init cadet_init(void) ...@@ -682,7 +682,7 @@ static int __init cadet_init(void)
} }
if (!request_region(io,2,"cadet")) if (!request_region(io,2,"cadet"))
goto fail; goto fail;
if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) { if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
release_region(io,2); release_region(io,2);
goto fail; goto fail;
} }
......
...@@ -425,7 +425,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci ...@@ -425,7 +425,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
} }
*devradio = vdev_template; *devradio = vdev_template;
if ( video_register_device( devradio, VFL_TYPE_RADIO , nr_radio) == -1 ) { if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) {
kfree( devradio ); kfree( devradio );
goto err_video; goto err_video;
} }
......
...@@ -612,8 +612,7 @@ static int __init gemtek_init(void) ...@@ -612,8 +612,7 @@ static int __init gemtek_init(void)
gemtek_radio.priv = &gemtek_unit; gemtek_radio.priv = &gemtek_unit;
if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
radio_nr) == -1) {
release_region(io, 1); release_region(io, 1);
return -EBUSY; return -EBUSY;
} }
......
...@@ -409,8 +409,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev, ...@@ -409,8 +409,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
video_set_drvdata(maestro_radio_inst, radio_unit); video_set_drvdata(maestro_radio_inst, radio_unit);
pci_set_drvdata(pdev, maestro_radio_inst); pci_set_drvdata(pdev, maestro_radio_inst);
retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr);
radio_nr);
if (retval) { if (retval) {
printk(KERN_ERR "can't register video device!\n"); printk(KERN_ERR "can't register video device!\n");
goto errfr1; goto errfr1;
......
...@@ -156,28 +156,28 @@ static void set_freq(__u16 io, __u32 freq) ...@@ -156,28 +156,28 @@ static void set_freq(__u16 io, __u32 freq)
{ {
unsigned long int si; unsigned long int si;
int bl; int bl;
int data = FREQ2BITS(freq); int val = FREQ2BITS(freq);
/* TEA5757 shift register bits (see pdf) */ /* TEA5757 shift register bits (see pdf) */
outbit(0,io); // 24 search outbit(0, io); /* 24 search */
outbit(1,io); // 23 search up/down outbit(1, io); /* 23 search up/down */
outbit(0,io); // 22 stereo/mono outbit(0, io); /* 22 stereo/mono */
outbit(0,io); // 21 band outbit(0, io); /* 21 band */
outbit(0,io); // 20 band (only 00=FM works I think) outbit(0, io); /* 20 band (only 00=FM works I think) */
outbit(0,io); // 19 port ? outbit(0, io); /* 19 port ? */
outbit(0,io); // 18 port ? outbit(0, io); /* 18 port ? */
outbit(0,io); // 17 search level outbit(0, io); /* 17 search level */
outbit(0,io); // 16 search level outbit(0, io); /* 16 search level */
si = 0x8000; si = 0x8000;
for (bl = 1; bl <= 16 ; bl++) { for (bl = 1; bl <= 16; bl++) {
outbit(data & si,io); outbit(val & si, io);
si >>=1; si >>= 1;
} }
dprintk(1, "Radio freq set to %d.%02d MHz\n", dprintk(1, "Radio freq set to %d.%02d MHz\n",
...@@ -410,7 +410,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d ...@@ -410,7 +410,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d
mutex_init(&radio_unit.lock); mutex_init(&radio_unit.lock);
maxiradio_radio.priv = &radio_unit; maxiradio_radio.priv = &radio_unit;
if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
printk("radio-maxiradio: can't register device!"); printk("radio-maxiradio: can't register device!");
goto err_out_free_region; goto err_out_free_region;
} }
......
...@@ -332,8 +332,7 @@ static int __init rtrack2_init(void) ...@@ -332,8 +332,7 @@ static int __init rtrack2_init(void)
rtrack2_radio.priv=&rtrack2_unit; rtrack2_radio.priv=&rtrack2_unit;
spin_lock_init(&lock); spin_lock_init(&lock);
if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1) if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
{
release_region(io, 4); release_region(io, 4);
return -EINVAL; return -EINVAL;
} }
......
...@@ -377,7 +377,7 @@ static int __init fmi_init(void) ...@@ -377,7 +377,7 @@ static int __init fmi_init(void)
mutex_init(&lock); mutex_init(&lock);
if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
release_region(io, 2); release_region(io, 2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -1694,8 +1694,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, ...@@ -1694,8 +1694,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
INIT_DELAYED_WORK(&radio->work, si470x_work); INIT_DELAYED_WORK(&radio->work, si470x_work);
/* register video device */ /* register video device */
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
retval = -EIO; if (retval) {
printk(KERN_WARNING DRIVER_NAME printk(KERN_WARNING DRIVER_NAME
": Could not register video device\n"); ": Could not register video device\n");
goto err_all; goto err_all;
......
...@@ -405,8 +405,7 @@ static int __init terratec_init(void) ...@@ -405,8 +405,7 @@ static int __init terratec_init(void)
spin_lock_init(&lock); spin_lock_init(&lock);
if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1) if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
{
release_region(io,2); release_region(io,2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -378,8 +378,7 @@ static int __init trust_init(void) ...@@ -378,8 +378,7 @@ static int __init trust_init(void)
printk(KERN_ERR "trust: port 0x%x already in use\n", io); printk(KERN_ERR "trust: port 0x%x already in use\n", io);
return -EBUSY; return -EBUSY;
} }
if(video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr)==-1) if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
{
release_region(io, 2); release_region(io, 2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -446,8 +446,7 @@ static int __init zoltrix_init(void) ...@@ -446,8 +446,7 @@ static int __init zoltrix_init(void)
return -EBUSY; return -EBUSY;
} }
if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) == -1) if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
{
release_region(io, 2); release_region(io, 2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -20,6 +20,8 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) ...@@ -20,6 +20,8 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
endif endif
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
obj-$(CONFIG_VIDEO_BT848) += bt8xx/ obj-$(CONFIG_VIDEO_BT848) += bt8xx/
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
...@@ -85,8 +87,6 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o ...@@ -85,8 +87,6 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
obj-$(CONFIG_VIDEO_DPC) += dpc7146.o obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
......
...@@ -7,6 +7,7 @@ config VIDEO_AU0828 ...@@ -7,6 +7,7 @@ config VIDEO_AU0828
select DVB_AU8522 if !DVB_FE_CUSTOMIZE select DVB_AU8522 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
---help--- ---help---
This is a video4linux driver for Auvitek's USB device. This is a video4linux driver for Auvitek's USB device.
......
/* /*
* Driver for the Auvitek USB bridge * Driver for the Auvitek USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -38,6 +38,9 @@ struct au0828_board au0828_boards[] = { ...@@ -38,6 +38,9 @@ struct au0828_board au0828_boards[] = {
[AU0828_BOARD_DVICO_FUSIONHDTV7] = { [AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB", .name = "DViCO FusionHDTV USB",
}, },
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
},
}; };
/* Tuner callback function for au0828 boards. Currently only needed /* Tuner callback function for au0828 boards. Currently only needed
...@@ -115,6 +118,7 @@ void au0828_card_setup(struct au0828_dev *dev) ...@@ -115,6 +118,7 @@ void au0828_card_setup(struct au0828_dev *dev)
case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
if (dev->i2c_rc == 0) if (dev->i2c_rc == 0)
hauppauge_eeprom(dev, eeprom+0xa0); hauppauge_eeprom(dev, eeprom+0xa0);
break; break;
...@@ -134,6 +138,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) ...@@ -134,6 +138,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
/* GPIO's /* GPIO's
* 4 - CS5340 * 4 - CS5340
* 5 - AU8522 Demodulator * 5 - AU8522 Demodulator
...@@ -205,6 +210,8 @@ struct usb_device_id au0828_usb_id_table [] = { ...@@ -205,6 +210,8 @@ struct usb_device_id au0828_usb_id_table [] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
{ USB_DEVICE(0x2040, 0x7281), { USB_DEVICE(0x2040, 0x7281),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
{ USB_DEVICE(0x2040, 0x8200),
.driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
{ }, { },
}; };
......
/* /*
* Driver for the Auvitek USB bridge * Driver for the Auvitek USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -24,3 +24,4 @@ ...@@ -24,3 +24,4 @@
#define AU0828_BOARD_HAUPPAUGE_HVR850 2 #define AU0828_BOARD_HAUPPAUGE_HVR850 2
#define AU0828_BOARD_DVICO_FUSIONHDTV7 3 #define AU0828_BOARD_DVICO_FUSIONHDTV7 3
#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4 #define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4
#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5
/* /*
* Driver for the Auvitek USB bridge * Driver for the Auvitek USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -252,5 +252,5 @@ module_init(au0828_init); ...@@ -252,5 +252,5 @@ module_init(au0828_init);
module_exit(au0828_exit); module_exit(au0828_exit);
MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products"); MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products");
MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* /*
* Driver for the Auvitek USB bridge * Driver for the Auvitek USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "au8522.h" #include "au8522.h"
#include "xc5000.h" #include "xc5000.h"
#include "mxl5007t.h" #include "mxl5007t.h"
#include "tda18271.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
...@@ -38,6 +39,15 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ...@@ -38,6 +39,15 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static struct au8522_config hauppauge_hvr950q_config = { static struct au8522_config hauppauge_hvr950q_config = {
.demod_address = 0x8e >> 1, .demod_address = 0x8e >> 1,
.status_mode = AU8522_DEMODLOCKING, .status_mode = AU8522_DEMODLOCKING,
.qam_if = AU8522_IF_6MHZ,
.vsb_if = AU8522_IF_6MHZ,
};
static struct au8522_config hauppauge_woodbury_config = {
.demod_address = 0x8e >> 1,
.status_mode = AU8522_DEMODLOCKING,
.qam_if = AU8522_IF_4MHZ,
.vsb_if = AU8522_IF_3_25MHZ,
}; };
static struct xc5000_config hauppauge_hvr950q_tunerconfig = { static struct xc5000_config hauppauge_hvr950q_tunerconfig = {
...@@ -51,6 +61,10 @@ static struct mxl5007t_config mxl5007t_hvr950q_config = { ...@@ -51,6 +61,10 @@ static struct mxl5007t_config mxl5007t_hvr950q_config = {
.if_freq_hz = MxL_IF_6_MHZ, .if_freq_hz = MxL_IF_6_MHZ,
}; };
static struct tda18271_config hauppauge_woodbury_tunerconfig = {
.gate = TDA18271_GATE_DIGITAL,
};
/*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb) static void urb_completion(struct urb *purb)
{ {
...@@ -357,6 +371,15 @@ int au0828_dvb_register(struct au0828_dev *dev) ...@@ -357,6 +371,15 @@ int au0828_dvb_register(struct au0828_dev *dev)
&dev->i2c_adap, 0x60, &dev->i2c_adap, 0x60,
&mxl5007t_hvr950q_config); &mxl5007t_hvr950q_config);
break; break;
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
dvb->frontend = dvb_attach(au8522_attach,
&hauppauge_woodbury_config,
&dev->i2c_adap);
if (dvb->frontend != NULL)
dvb_attach(tda18271_attach, dvb->frontend,
0x60, &dev->i2c_adap,
&hauppauge_woodbury_tunerconfig);
break;
default: default:
printk(KERN_WARNING "The frontend of your DVB/ATSC card " printk(KERN_WARNING "The frontend of your DVB/ATSC card "
"isn't supported yet\n"); "isn't supported yet\n");
......
/* /*
* Driver for the Auvitek AU0828 USB bridge * Driver for the Auvitek AU0828 USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Auvitek USB bridge * Driver for the Auvitek USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Auvitek AU0828 USB bridge * Driver for the Auvitek AU0828 USB bridge
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -3144,8 +3144,9 @@ static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]) ...@@ -3144,8 +3144,9 @@ static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
static void flyvideo_gpio(struct bttv *btv) static void flyvideo_gpio(struct bttv *btv)
{ {
int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; int gpio, has_remote, has_radio, is_capture_only;
int tuner=UNSET,ttype; int is_lr90, has_tda9820_tda9821;
int tuner_type = UNSET, ttype;
gpio_inout(0xffffff, 0); gpio_inout(0xffffff, 0);
udelay(8); /* without this we would see the 0x1800 mask */ udelay(8); /* without this we would see the 0x1800 mask */
...@@ -3163,20 +3164,26 @@ static void flyvideo_gpio(struct bttv *btv) ...@@ -3163,20 +3164,26 @@ static void flyvideo_gpio(struct bttv *btv)
* xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
* Note: Some bits are Audio_Mask ! * Note: Some bits are Audio_Mask !
*/ */
ttype=(gpio&0x0f0000)>>16; ttype = (gpio & 0x0f0000) >> 16;
switch(ttype) { switch (ttype) {
case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ case 0x0:
tuner_type = 2; /* NTSC, e.g. TPI8NSR11P */
break; break;
case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ case 0x2:
tuner_type = 39; /* LG NTSC (newer TAPC series) TAPC-H701P */
break; break;
case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ case 0x4:
tuner_type = 5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
break; break;
case 0x6: tuner=37;/* LG PAL (newer TAPC series) TAPC-G702P */ case 0x6:
tuner_type = 37; /* LG PAL (newer TAPC series) TAPC-G702P */
break; break;
case 0xC: tuner=3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */ case 0xC:
tuner_type = 3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
break; break;
default: default:
printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr); printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
break;
} }
has_remote = gpio & 0x800000; has_remote = gpio & 0x800000;
...@@ -3189,23 +3196,26 @@ static void flyvideo_gpio(struct bttv *btv) ...@@ -3189,23 +3196,26 @@ static void flyvideo_gpio(struct bttv *btv)
/* /*
* gpio & 0x001000 output bit for audio routing */ * gpio & 0x001000 output bit for audio routing */
if(is_capture_only) if (is_capture_only)
tuner = TUNER_ABSENT; /* No tuner present */ tuner_type = TUNER_ABSENT; /* No tuner present */
printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); btv->c.nr, has_radio ? "yes" : "no ",
has_remote ? "yes" : "no ", tuner_type, gpio);
printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n", printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", btv->c.nr, is_lr90 ? "yes" : "no ",
is_capture_only?"yes":"no "); has_tda9820_tda9821 ? "yes" : "no ",
is_capture_only ? "yes" : "no ");
if (tuner != UNSET) /* only set if known tuner autodetected, else let insmod option through */ if (tuner_type != UNSET) /* only set if known tuner autodetected, else let insmod option through */
btv->tuner_type = tuner; btv->tuner_type = tuner_type;
btv->has_radio = has_radio; btv->has_radio = has_radio;
/* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80 /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
* LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
* Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */ * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
if(has_tda9820_tda9821) btv->audio_mode_gpio = lt9415_audio; if (has_tda9820_tda9821)
btv->audio_mode_gpio = lt9415_audio;
/* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */ /* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */
} }
...@@ -3962,7 +3972,7 @@ static int tuner_1_table[] = { ...@@ -3962,7 +3972,7 @@ static int tuner_1_table[] = {
static void __devinit avermedia_eeprom(struct bttv *btv) static void __devinit avermedia_eeprom(struct bttv *btv)
{ {
int tuner_make,tuner_tv_fm,tuner_format,tuner=0; int tuner_make, tuner_tv_fm, tuner_format, tuner_type = 0;
tuner_make = (eeprom_data[0x41] & 0x7); tuner_make = (eeprom_data[0x41] & 0x7);
tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
...@@ -3970,24 +3980,24 @@ static void __devinit avermedia_eeprom(struct bttv *btv) ...@@ -3970,24 +3980,24 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
btv->has_remote = (eeprom_data[0x42] & 0x01); btv->has_remote = (eeprom_data[0x42] & 0x01);
if (tuner_make == 0 || tuner_make == 2) if (tuner_make == 0 || tuner_make == 2)
if(tuner_format <=0x0a) if (tuner_format <= 0x0a)
tuner = tuner_0_table[tuner_format]; tuner_type = tuner_0_table[tuner_format];
if (tuner_make == 1) if (tuner_make == 1)
if(tuner_format <=9) if (tuner_format <= 9)
tuner = tuner_1_table[tuner_format]; tuner_type = tuner_1_table[tuner_format];
if (tuner_make == 4) if (tuner_make == 4)
if(tuner_format == 0x09) if (tuner_format == 0x09)
tuner = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */ tuner_type = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=", printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]); btv->c.nr, eeprom_data[0x41], eeprom_data[0x42]);
if(tuner) { if (tuner_type) {
btv->tuner_type=tuner; btv->tuner_type = tuner_type;
printk("%d",tuner); printk(KERN_CONT "%d", tuner_type);
} else } else
printk("Unknown type"); printk(KERN_CONT "Unknown type");
printk(" radio:%s remote control:%s\n", printk(KERN_CONT " radio:%s remote control:%s\n",
tuner_tv_fm ? "yes" : "no", tuner_tv_fm ? "yes" : "no",
btv->has_remote ? "yes" : "no"); btv->has_remote ? "yes" : "no");
} }
......
...@@ -96,7 +96,6 @@ static unsigned int irq_iswitch; ...@@ -96,7 +96,6 @@ static unsigned int irq_iswitch;
static unsigned int uv_ratio = 50; static unsigned int uv_ratio = 50;
static unsigned int full_luma_range; static unsigned int full_luma_range;
static unsigned int coring; static unsigned int coring;
extern int no_overlay;
/* API features (turn on/off stuff for testing) */ /* API features (turn on/off stuff for testing) */
static unsigned int v4l2 = 1; static unsigned int v4l2 = 1;
......
...@@ -244,7 +244,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -244,7 +244,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
const struct bttv_format *fmt, struct bttv_overlay *ov, const struct bttv_format *fmt, struct bttv_overlay *ov,
int skip_even, int skip_odd) int skip_even, int skip_odd)
{ {
int dwords,rc,line,maxy,start,end,skip,nskips; int dwords, rc, line, maxy, start, end;
unsigned skip, nskips;
struct btcx_skiplist *skips; struct btcx_skiplist *skips;
__le32 *rp; __le32 *rp;
u32 ri,ra; u32 ri,ra;
......
...@@ -266,6 +266,11 @@ extern struct bus_type bttv_sub_bus_type; ...@@ -266,6 +266,11 @@ extern struct bus_type bttv_sub_bus_type;
int bttv_sub_add_device(struct bttv_core *core, char *name); int bttv_sub_add_device(struct bttv_core *core, char *name);
int bttv_sub_del_devices(struct bttv_core *core); int bttv_sub_del_devices(struct bttv_core *core);
/* ---------------------------------------------------------- */
/* bttv-cards.c */
extern int no_overlay;
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
/* bttv-driver.c */ /* bttv-driver.c */
......
...@@ -184,12 +184,12 @@ btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips) ...@@ -184,12 +184,12 @@ btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
} }
void void
btcx_calc_skips(int line, int width, unsigned int *maxy, btcx_calc_skips(int line, int width, int *maxy,
struct btcx_skiplist *skips, unsigned int *nskips, struct btcx_skiplist *skips, unsigned int *nskips,
const struct v4l2_clip *clips, unsigned int nclips) const struct v4l2_clip *clips, unsigned int nclips)
{ {
unsigned int clip,skip; unsigned int clip,skip;
int end,maxline; int end, maxline;
skip=0; skip=0;
maxline = 9999; maxline = 9999;
......
...@@ -23,7 +23,7 @@ int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, ...@@ -23,7 +23,7 @@ int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
unsigned int n, int mask); unsigned int n, int mask);
void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
void btcx_calc_skips(int line, int width, unsigned int *maxy, void btcx_calc_skips(int line, int width, int *maxy,
struct btcx_skiplist *skips, unsigned int *nskips, struct btcx_skiplist *skips, unsigned int *nskips,
const struct v4l2_clip *clips, unsigned int nclips); const struct v4l2_clip *clips, unsigned int nclips);
......
...@@ -946,8 +946,7 @@ static int init_bwqcam(struct parport *port) ...@@ -946,8 +946,7 @@ static int init_bwqcam(struct parport *port)
printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
{
parport_unregister_device(qcam->pdev); parport_unregister_device(qcam->pdev);
kfree(qcam); kfree(qcam);
return -ENODEV; return -ENODEV;
......
...@@ -787,8 +787,7 @@ static int init_cqcam(struct parport *port) ...@@ -787,8 +787,7 @@ static int init_cqcam(struct parport *port)
parport_release(qcam->pdev); parport_release(qcam->pdev);
if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
{
printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
qcam->pport->name); qcam->pport->name);
parport_unregister_device(qcam->pdev); parport_unregister_device(qcam->pdev);
......
...@@ -3955,7 +3955,7 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve ...@@ -3955,7 +3955,7 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve
camera->lowlevel_data = lowlevel; camera->lowlevel_data = lowlevel;
/* register v4l device */ /* register v4l device */
if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
kfree(camera); kfree(camera);
printk(KERN_DEBUG "video_register_device failed\n"); printk(KERN_DEBUG "video_register_device failed\n");
return NULL; return NULL;
......
...@@ -1024,7 +1024,6 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam) ...@@ -1024,7 +1024,6 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam)
if(cam->params.pnp_id.device_type == DEVICE_STV_672 && if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
// Maximum 15fps // Maximum 15fps
int i;
for(i=0; i<c->maximum; ++i) { for(i=0; i<c->maximum; ++i) {
if(framerate_controls[i].value == if(framerate_controls[i].value ==
CPIA2_VP_FRAMERATE_15) { CPIA2_VP_FRAMERATE_15) {
...@@ -1959,8 +1958,7 @@ int cpia2_register_camera(struct camera_data *cam) ...@@ -1959,8 +1958,7 @@ int cpia2_register_camera(struct camera_data *cam)
reset_camera_struct_v4l(cam); reset_camera_struct_v4l(cam);
/* register v4l device */ /* register v4l device */
if (video_register_device if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
(cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
ERR("video_register_device failed\n"); ERR("video_register_device failed\n");
video_device_release(cam->vdev); video_device_release(cam->vdev);
return -ENODEV; return -ENODEV;
......
...@@ -32,7 +32,7 @@ int cx18_av_loadfw(struct cx18 *cx) ...@@ -32,7 +32,7 @@ int cx18_av_loadfw(struct cx18 *cx)
u32 v; u32 v;
const u8 *ptr; const u8 *ptr;
int i; int i;
int retries = 0; int retries1 = 0;
if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
CX18_ERR("unable to open firmware %s\n", FWFILE); CX18_ERR("unable to open firmware %s\n", FWFILE);
...@@ -41,7 +41,7 @@ int cx18_av_loadfw(struct cx18 *cx) ...@@ -41,7 +41,7 @@ int cx18_av_loadfw(struct cx18 *cx)
/* The firmware load often has byte errors, so allow for several /* The firmware load often has byte errors, so allow for several
retries, both at byte level and at the firmware load level. */ retries, both at byte level and at the firmware load level. */
while (retries < 5) { while (retries1 < 5) {
cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
...@@ -57,9 +57,9 @@ int cx18_av_loadfw(struct cx18 *cx) ...@@ -57,9 +57,9 @@ int cx18_av_loadfw(struct cx18 *cx)
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
u32 value = 0; u32 value = 0;
int retries; int retries2;
for (retries = 0; retries < 5; retries++) { for (retries2 = 0; retries2 < 5; retries2++) {
cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
udelay(10); udelay(10);
value = cx18_av_read4(cx, CXADEC_DL_CTL); value = cx18_av_read4(cx, CXADEC_DL_CTL);
...@@ -69,18 +69,18 @@ int cx18_av_loadfw(struct cx18 *cx) ...@@ -69,18 +69,18 @@ int cx18_av_loadfw(struct cx18 *cx)
the address. We can only write the lower the address. We can only write the lower
address byte of the address. */ address byte of the address. */
if ((value & 0x3F00) != (dl_control & 0x3F00)) { if ((value & 0x3F00) != (dl_control & 0x3F00)) {
retries = 5; retries2 = 5;
break; break;
} }
} }
if (retries >= 5) if (retries2 >= 5)
break; break;
} }
if (i == size) if (i == size)
break; break;
retries++; retries1++;
} }
if (retries >= 5) { if (retries1 >= 5) {
CX18_ERR("unable to load firmware %s\n", FWFILE); CX18_ERR("unable to load firmware %s\n", FWFILE);
release_firmware(fw); release_firmware(fw);
return -EIO; return -EIO;
......
...@@ -74,9 +74,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, ...@@ -74,9 +74,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 }; -1, -1, -1, -1, -1, -1, -1, -1 };
static int cardtype_c = 1; static unsigned cardtype_c = 1;
static int tuner_c = 1; static unsigned tuner_c = 1;
static int radio_c = 1; static unsigned radio_c = 1;
static char pal[] = "--"; static char pal[] = "--";
static char secam[] = "--"; static char secam[] = "--";
static char ntsc[] = "-"; static char ntsc[] = "-";
......
/* /*
* cx18 functions for DVB support * cx18 functions for DVB support
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* cx18 functions for DVB support * cx18 functions for DVB support
* *
* Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) ...@@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
CX18_WARN("Ack struct = %d for %s\n", CX18_WARN("Ack struct = %d for %s\n",
mb->args[2], s->name); mb->args[2], s->name);
id = read_enc(off); id = read_enc(off);
buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4));
CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
if (buf) { if (buf) {
cx18_buf_sync_for_cpu(s, buf); cx18_buf_sync_for_cpu(s, buf);
......
...@@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) ...@@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
return buf; return buf;
} }
struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
u32 bytesused) u32 bytesused)
{ {
struct cx18 *cx = s->cx; struct cx18 *cx = s->cx;
struct list_head *p; struct list_head *p;
spin_lock(&s->qlock);
list_for_each(p, &s->q_free.list) { list_for_each(p, &s->q_free.list) {
struct cx18_buffer *buf = struct cx18_buffer *buf =
list_entry(p, struct cx18_buffer, list); list_entry(p, struct cx18_buffer, list);
...@@ -92,114 +93,48 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, ...@@ -92,114 +93,48 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
continue; continue;
buf->bytesused = bytesused; buf->bytesused = bytesused;
/* the transport buffers are handled differently, /* the transport buffers are handled differently,
so there is no need to move them to the full queue */ they are not moved to the full queue */
if (s->type == CX18_ENC_STREAM_TYPE_TS) if (s->type != CX18_ENC_STREAM_TYPE_TS) {
return buf; s->q_free.buffers--;
s->q_free.buffers--; s->q_free.length -= s->buf_size;
s->q_free.length -= s->buf_size; s->q_full.buffers++;
s->q_full.buffers++; s->q_full.length += s->buf_size;
s->q_full.length += s->buf_size; s->q_full.bytesused += buf->bytesused;
s->q_full.bytesused += buf->bytesused; list_move_tail(&buf->list, &s->q_full.list);
list_move_tail(&buf->list, &s->q_full.list); }
spin_unlock(&s->qlock);
return buf; return buf;
} }
spin_unlock(&s->qlock);
CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
return NULL; return NULL;
} }
static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from, /* Move all buffers of a queue to q_free, while flushing the buffers */
struct cx18_queue *to, int clear, int full) static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
{
struct cx18_buffer *buf =
list_entry(from->list.next, struct cx18_buffer, list);
list_move_tail(from->list.next, &to->list);
from->buffers--;
from->length -= s->buf_size;
from->bytesused -= buf->bytesused - buf->readpos;
/* special handling for q_free */
if (clear)
buf->bytesused = buf->readpos = buf->b_flags = 0;
else if (full) {
/* special handling for stolen buffers, assume
all bytes are used. */
buf->bytesused = s->buf_size;
buf->readpos = buf->b_flags = 0;
}
to->buffers++;
to->length += s->buf_size;
to->bytesused += buf->bytesused - buf->readpos;
}
/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
If 'steal' != NULL, then buffers may also taken from that queue if
needed.
The buffer is automatically cleared if it goes to the free queue. It is
also cleared if buffers need to be taken from the 'steal' queue and
the 'from' queue is the free queue.
When 'from' is q_free, then needed_bytes is compared to the total
available buffer length, otherwise needed_bytes is compared to the
bytesused value. For the 'steal' queue the total available buffer
length is always used.
-ENOMEM is returned if the buffers could not be obtained, 0 if all
buffers where obtained from the 'from' list and if non-zero then
the number of stolen buffers is returned. */
static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
struct cx18_queue *steal, struct cx18_queue *to,
int needed_bytes)
{ {
unsigned long flags; unsigned long flags;
int rc = 0; struct cx18_buffer *buf;
int from_free = from == &s->q_free;
int to_free = to == &s->q_free;
int bytes_available;
spin_lock_irqsave(&s->qlock, flags);
if (needed_bytes == 0) {
from_free = 1;
needed_bytes = from->length;
}
bytes_available = from_free ? from->length : from->bytesused;
bytes_available += steal ? steal->length : 0;
if (bytes_available < needed_bytes) { if (q == &s->q_free)
spin_unlock_irqrestore(&s->qlock, flags); return;
return -ENOMEM;
}
if (from_free) {
u32 old_length = to->length;
while (to->length - old_length < needed_bytes) { spin_lock_irqsave(&s->qlock, flags);
if (list_empty(&from->list)) while (!list_empty(&q->list)) {
from = steal; buf = list_entry(q->list.next, struct cx18_buffer, list);
if (from == steal) list_move_tail(q->list.next, &s->q_free.list);
rc++; /* keep track of 'stolen' buffers */ buf->bytesused = buf->readpos = buf->b_flags = 0;
cx18_queue_move_buf(s, from, to, 1, 0); s->q_free.buffers++;
} s->q_free.length += s->buf_size;
} else {
u32 old_bytesused = to->bytesused;
while (to->bytesused - old_bytesused < needed_bytes) {
if (list_empty(&from->list))
from = steal;
if (from == steal)
rc++; /* keep track of 'stolen' buffers */
cx18_queue_move_buf(s, from, to, to_free, rc);
}
} }
cx18_queue_init(q);
spin_unlock_irqrestore(&s->qlock, flags); spin_unlock_irqrestore(&s->qlock, flags);
return rc;
} }
void cx18_flush_queues(struct cx18_stream *s) void cx18_flush_queues(struct cx18_stream *s)
{ {
cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0); cx18_queue_flush(s, &s->q_io);
cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0); cx18_queue_flush(s, &s->q_full);
} }
int cx18_stream_alloc(struct cx18_stream *s) int cx18_stream_alloc(struct cx18_stream *s)
...@@ -214,10 +149,10 @@ int cx18_stream_alloc(struct cx18_stream *s) ...@@ -214,10 +149,10 @@ int cx18_stream_alloc(struct cx18_stream *s)
s->name, s->buffers, s->buf_size, s->name, s->buffers, s->buf_size,
s->buffers * s->buf_size / 1024); s->buffers * s->buf_size / 1024);
if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
(char *)cx->scb) > SCB_RESERVED_SIZE) { (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE - unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
((char *)cx->scb->cpu_mdl)); ((char __iomem *)cx->scb->cpu_mdl));
CX18_ERR("Too many buffers, cannot fit in SCB area\n"); CX18_ERR("Too many buffers, cannot fit in SCB area\n");
CX18_ERR("Max buffers = %zd\n", CX18_ERR("Max buffers = %zd\n",
......
...@@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q); ...@@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q);
void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
struct cx18_queue *q); struct cx18_queue *q);
struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
u32 bytesused); u32 bytesused);
void cx18_flush_queues(struct cx18_stream *s); void cx18_flush_queues(struct cx18_stream *s);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* (c) 2004 Jelle Foks <jelle@foks.8m.com> * (c) 2004 Jelle Foks <jelle@foks.8m.com>
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
* (c) 2008 Steven Toth <stoth@hauppauge.com> * (c) 2008 Steven Toth <stoth@linuxtv.org>
* - CX23885/7/8 support * - CX23885/7/8 support
* *
* Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "cx23885.h" #include "cx23885.h"
MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static unsigned int debug; static unsigned int debug;
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#endif #endif
MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
......
/* /*
* Driver for the Conexant CX23885 PCIe bridge * Driver for the Conexant CX23885 PCIe bridge
* *
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca> * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
* with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>. * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
* *
* CX23885 support by Steven Toth <stoth@hauppauge.com>. * CX23885 support by Steven Toth <stoth@linuxtv.org>.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -124,7 +124,7 @@ static void reg_r(struct gspca_dev *gspca_dev, ...@@ -124,7 +124,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
#ifdef GSPCA_DEBUG #ifdef GSPCA_DEBUG
if (len > sizeof gspca_dev->usb_buf) { if (len > USB_BUF_SZ) {
err("reg_r: buffer overflow"); err("reg_r: buffer overflow");
return; return;
} }
...@@ -164,7 +164,7 @@ static void reg_w(struct gspca_dev *gspca_dev, ...@@ -164,7 +164,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
#ifdef GSPCA_DEBUG #ifdef GSPCA_DEBUG
if (len > sizeof gspca_dev->usb_buf) { if (len > USB_BUF_SZ) {
err("reg_w: buffer overflow"); err("reg_w: buffer overflow");
return; return;
} }
...@@ -826,8 +826,8 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -826,8 +826,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0; return 0;
} }
/* this function is called at open time */ /* this function is called at probe and resume time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_init(struct gspca_dev *gspca_dev)
{ {
cx11646_init1(gspca_dev); cx11646_init1(gspca_dev);
cx11646_initsize(gspca_dev); cx11646_initsize(gspca_dev);
...@@ -845,10 +845,6 @@ static void sd_start(struct gspca_dev *gspca_dev) ...@@ -845,10 +845,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
cx11646_jpeg(gspca_dev); cx11646_jpeg(gspca_dev);
} }
static void sd_stopN(struct gspca_dev *gspca_dev)
{
}
static void sd_stop0(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev)
{ {
int retry = 50; int retry = 50;
...@@ -871,10 +867,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) ...@@ -871,10 +867,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev, 0x00fc, 0xe0); reg_w_val(gspca_dev, 0x00fc, 0xe0);
} }
static void sd_close(struct gspca_dev *gspca_dev)
{
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */ struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */ __u8 *data, /* isoc packet */
...@@ -998,11 +990,9 @@ static struct sd_desc sd_desc = { ...@@ -998,11 +990,9 @@ static struct sd_desc sd_desc = {
.ctrls = sd_ctrls, .ctrls = sd_ctrls,
.nctrls = ARRAY_SIZE(sd_ctrls), .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config, .config = sd_config,
.open = sd_open, .init = sd_init,
.start = sd_start, .start = sd_start,
.stopN = sd_stopN,
.stop0 = sd_stop0, .stop0 = sd_stop0,
.close = sd_close,
.pkt_scan = sd_pkt_scan, .pkt_scan = sd_pkt_scan,
}; };
...@@ -1026,6 +1016,10 @@ static struct usb_driver sd_driver = { ...@@ -1026,6 +1016,10 @@ static struct usb_driver sd_driver = {
.id_table = device_table, .id_table = device_table,
.probe = sd_probe, .probe = sd_probe,
.disconnect = gspca_disconnect, .disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
.resume = gspca_resume,
#endif
}; };
/* -- module insert / remove -- */ /* -- module insert / remove -- */
......
...@@ -81,6 +81,7 @@ static struct ctrl sd_ctrls[] = { ...@@ -81,6 +81,7 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setcontrast, .set = sd_setcontrast,
.get = sd_getcontrast, .get = sd_getcontrast,
}, },
#define COLOR_IDX 2
{ {
{ {
.id = V4L2_CID_SATURATION, .id = V4L2_CID_SATURATION,
...@@ -234,7 +235,7 @@ static void reg_r(struct gspca_dev *gspca_dev, ...@@ -234,7 +235,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
#ifdef GSPCA_DEBUG #ifdef GSPCA_DEBUG
if (len > sizeof gspca_dev->usb_buf) { if (len > USB_BUF_SZ) {
err("reg_r: buffer overflow"); err("reg_r: buffer overflow");
return; return;
} }
...@@ -272,7 +273,7 @@ static void reg_w(struct gspca_dev *gspca_dev, ...@@ -272,7 +273,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
#ifdef GSPCA_DEBUG #ifdef GSPCA_DEBUG
if (len > sizeof gspca_dev->usb_buf) { if (len > USB_BUF_SZ) {
err("reg_w: buffer overflow"); err("reg_w: buffer overflow");
return; return;
} }
...@@ -665,6 +666,7 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -665,6 +666,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
} else { } else {
cam->cam_mode = vga_mode; cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
gspca_dev->ctrl_dis = (1 << COLOR_IDX);
} }
sd->brightness = BRIGHTNESS_DEF; sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF; sd->contrast = CONTRAST_DEF;
...@@ -674,8 +676,8 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -674,8 +676,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0; return 0;
} }
/* this function is called at open time */ /* this function is called at probe and resume time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_init(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
...@@ -709,14 +711,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ...@@ -709,14 +711,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
et_video(gspca_dev, 0); /* video off */ et_video(gspca_dev, 0); /* video off */
} }
static void sd_stop0(struct gspca_dev *gspca_dev)
{
}
static void sd_close(struct gspca_dev *gspca_dev)
{
}
static __u8 Et_getgainG(struct gspca_dev *gspca_dev) static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
...@@ -893,21 +887,19 @@ static struct sd_desc sd_desc = { ...@@ -893,21 +887,19 @@ static struct sd_desc sd_desc = {
.ctrls = sd_ctrls, .ctrls = sd_ctrls,
.nctrls = ARRAY_SIZE(sd_ctrls), .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config, .config = sd_config,
.open = sd_open, .init = sd_init,
.start = sd_start, .start = sd_start,
.stopN = sd_stopN, .stopN = sd_stopN,
.stop0 = sd_stop0,
.close = sd_close,
.pkt_scan = sd_pkt_scan, .pkt_scan = sd_pkt_scan,
.dq_callback = do_autogain, .dq_callback = do_autogain,
}; };
/* -- module initialisation -- */ /* -- module initialisation -- */
static __devinitdata struct usb_device_id device_table[] = { static __devinitdata struct usb_device_id device_table[] = {
#ifndef CONFIG_USB_ET61X251
{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
#endif #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
#endif
{} {}
}; };
...@@ -926,6 +918,10 @@ static struct usb_driver sd_driver = { ...@@ -926,6 +918,10 @@ static struct usb_driver sd_driver = {
.id_table = device_table, .id_table = device_table,
.probe = sd_probe, .probe = sd_probe,
.disconnect = gspca_disconnect, .disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
.resume = gspca_resume,
#endif
}; };
/* -- module insert / remove -- */ /* -- module insert / remove -- */
......
...@@ -114,7 +114,10 @@ static void fill_frame(struct gspca_dev *gspca_dev, ...@@ -114,7 +114,10 @@ static void fill_frame(struct gspca_dev *gspca_dev,
cam_pkt_op pkt_scan; cam_pkt_op pkt_scan;
if (urb->status != 0) { if (urb->status != 0) {
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); #ifdef CONFIG_PM
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
return; /* disconnection ? */ return; /* disconnection ? */
} }
pkt_scan = gspca_dev->sd_desc->pkt_scan; pkt_scan = gspca_dev->sd_desc->pkt_scan;
...@@ -555,10 +558,12 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) ...@@ -555,10 +558,12 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
gspca_dev->streaming = 0; gspca_dev->streaming = 0;
atomic_set(&gspca_dev->nevent, 0); atomic_set(&gspca_dev->nevent, 0);
if (gspca_dev->present) { if (gspca_dev->present) {
gspca_dev->sd_desc->stopN(gspca_dev); if (gspca_dev->sd_desc->stopN)
gspca_dev->sd_desc->stopN(gspca_dev);
destroy_urbs(gspca_dev); destroy_urbs(gspca_dev);
gspca_set_alt0(gspca_dev); gspca_set_alt0(gspca_dev);
gspca_dev->sd_desc->stop0(gspca_dev); if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK"); PDEBUG(D_STREAM, "stream off OK");
} }
} }
...@@ -767,19 +772,7 @@ static int dev_open(struct inode *inode, struct file *file) ...@@ -767,19 +772,7 @@ static int dev_open(struct inode *inode, struct file *file)
goto out; goto out;
} }
/* if not done yet, initialize the sensor */ if (gspca_dev->users > 4) { /* (arbitrary value) */
if (gspca_dev->users == 0) {
if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
ret = -ERESTARTSYS;
goto out;
}
ret = gspca_dev->sd_desc->open(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
if (ret != 0) {
PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
goto out;
}
} else if (gspca_dev->users > 4) { /* (arbitrary value) */
ret = -EBUSY; ret = -EBUSY;
goto out; goto out;
} }
...@@ -792,6 +785,7 @@ static int dev_open(struct inode *inode, struct file *file) ...@@ -792,6 +785,7 @@ static int dev_open(struct inode *inode, struct file *file)
else else
gspca_dev->vdev.debug &= ~3; gspca_dev->vdev.debug &= ~3;
#endif #endif
ret = 0;
out: out:
mutex_unlock(&gspca_dev->queue_lock); mutex_unlock(&gspca_dev->queue_lock);
if (ret != 0) if (ret != 0)
...@@ -812,11 +806,11 @@ static int dev_close(struct inode *inode, struct file *file) ...@@ -812,11 +806,11 @@ static int dev_close(struct inode *inode, struct file *file)
/* if the file did the capture, free the streaming resources */ /* if the file did the capture, free the streaming resources */
if (gspca_dev->capt_file == file) { if (gspca_dev->capt_file == file) {
mutex_lock(&gspca_dev->usb_lock); if (gspca_dev->streaming) {
if (gspca_dev->streaming) mutex_lock(&gspca_dev->usb_lock);
gspca_stream_off(gspca_dev); gspca_stream_off(gspca_dev);
gspca_dev->sd_desc->close(gspca_dev); mutex_unlock(&gspca_dev->usb_lock);
mutex_unlock(&gspca_dev->usb_lock); }
frame_free(gspca_dev); frame_free(gspca_dev);
gspca_dev->capt_file = NULL; gspca_dev->capt_file = NULL;
gspca_dev->memory = GSPCA_MEMORY_NO; gspca_dev->memory = GSPCA_MEMORY_NO;
...@@ -853,42 +847,44 @@ static int vidioc_querycap(struct file *file, void *priv, ...@@ -853,42 +847,44 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0; return 0;
} }
/* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */
static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *q_ctrl) struct v4l2_queryctrl *q_ctrl)
{ {
struct gspca_dev *gspca_dev = priv; struct gspca_dev *gspca_dev = priv;
int i; int i, ix;
u32 id; u32 id;
ix = -1;
id = q_ctrl->id; id = q_ctrl->id;
if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
id &= V4L2_CTRL_ID_MASK; id &= V4L2_CTRL_ID_MASK;
id++; id++;
for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
memcpy(q_ctrl, continue;
&gspca_dev->sd_desc->ctrls[i].qctrl, if (ix < 0) {
sizeof *q_ctrl); ix = i;
return 0; continue;
} }
if (gspca_dev->sd_desc->ctrls[i].qctrl.id
> gspca_dev->sd_desc->ctrls[ix].qctrl.id)
continue;
ix = i;
} }
return -EINVAL;
} }
for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
memcpy(q_ctrl, ix = i;
&gspca_dev->sd_desc->ctrls[i].qctrl, break;
sizeof *q_ctrl);
return 0;
} }
} }
if (id >= V4L2_CID_BASE if (ix < 0)
&& id <= V4L2_CID_LASTP1) { return -EINVAL;
memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl,
sizeof *q_ctrl);
if (gspca_dev->ctrl_dis & (1 << ix))
q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0; return 0;
}
return -EINVAL;
} }
static int vidioc_s_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv,
...@@ -903,6 +899,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv, ...@@ -903,6 +899,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
i++, ctrls++) { i++, ctrls++) {
if (ctrl->id != ctrls->qctrl.id) if (ctrl->id != ctrls->qctrl.id)
continue; continue;
if (gspca_dev->ctrl_dis & (1 << i))
return -EINVAL;
if (ctrl->value < ctrls->qctrl.minimum if (ctrl->value < ctrls->qctrl.minimum
|| ctrl->value > ctrls->qctrl.maximum) || ctrl->value > ctrls->qctrl.maximum)
return -ERANGE; return -ERANGE;
...@@ -929,6 +927,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, ...@@ -929,6 +927,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
i++, ctrls++) { i++, ctrls++) {
if (ctrl->id != ctrls->qctrl.id) if (ctrl->id != ctrls->qctrl.id)
continue; continue;
if (gspca_dev->ctrl_dis & (1 << i))
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock)) if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS; return -ERESTARTSYS;
ret = ctrls->get(gspca_dev, &ctrl->value); ret = ctrls->get(gspca_dev, &ctrl->value);
...@@ -1403,7 +1403,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, ...@@ -1403,7 +1403,7 @@ static int vidioc_dqbuf(struct file *file, void *priv,
i = ret; /* frame index */ i = ret; /* frame index */
frame = &gspca_dev->frame[i]; frame = &gspca_dev->frame[i];
if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr, if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
frame->data, frame->data,
frame->v4l2_buf.bytesused)) { frame->v4l2_buf.bytesused)) {
PDEBUG(D_ERR|D_STREAM, PDEBUG(D_ERR|D_STREAM,
...@@ -1731,6 +1731,12 @@ int gspca_dev_probe(struct usb_interface *intf, ...@@ -1731,6 +1731,12 @@ int gspca_dev_probe(struct usb_interface *intf,
err("couldn't kzalloc gspca struct"); err("couldn't kzalloc gspca struct");
return -EIO; return -EIO;
} }
gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
if (!gspca_dev->usb_buf) {
err("out of memory");
ret = -EIO;
goto out;
}
gspca_dev->dev = dev; gspca_dev->dev = dev;
gspca_dev->iface = interface->bInterfaceNumber; gspca_dev->iface = interface->bInterfaceNumber;
gspca_dev->nbalt = intf->num_altsetting; gspca_dev->nbalt = intf->num_altsetting;
...@@ -1738,8 +1744,11 @@ int gspca_dev_probe(struct usb_interface *intf, ...@@ -1738,8 +1744,11 @@ int gspca_dev_probe(struct usb_interface *intf,
/* gspca_dev->users = 0; (done by kzalloc) */ /* gspca_dev->users = 0; (done by kzalloc) */
gspca_dev->nbufread = 2; gspca_dev->nbufread = 2;
/* configure the subdriver */ /* configure the subdriver and initialize the USB device */
ret = gspca_dev->sd_desc->config(gspca_dev, id); ret = gspca_dev->sd_desc->config(gspca_dev, id);
if (ret < 0)
goto out;
ret = gspca_dev->sd_desc->init(gspca_dev);
if (ret < 0) if (ret < 0)
goto out; goto out;
ret = gspca_set_alt0(gspca_dev); ret = gspca_set_alt0(gspca_dev);
...@@ -1771,6 +1780,7 @@ int gspca_dev_probe(struct usb_interface *intf, ...@@ -1771,6 +1780,7 @@ int gspca_dev_probe(struct usb_interface *intf,
PDEBUG(D_PROBE, "probe ok"); PDEBUG(D_PROBE, "probe ok");
return 0; return 0;
out: out:
kfree(gspca_dev->usb_buf);
kfree(gspca_dev); kfree(gspca_dev);
return ret; return ret;
} }
...@@ -1803,11 +1813,42 @@ void gspca_disconnect(struct usb_interface *intf) ...@@ -1803,11 +1813,42 @@ void gspca_disconnect(struct usb_interface *intf)
/* We don't want people trying to open up the device */ /* We don't want people trying to open up the device */
video_unregister_device(&gspca_dev->vdev); video_unregister_device(&gspca_dev->vdev);
/* Free the memory */ /* Free the memory */
kfree(gspca_dev->usb_buf);
kfree(gspca_dev); kfree(gspca_dev);
PDEBUG(D_PROBE, "disconnect complete"); PDEBUG(D_PROBE, "disconnect complete");
} }
EXPORT_SYMBOL(gspca_disconnect); EXPORT_SYMBOL(gspca_disconnect);
#ifdef CONFIG_PM
int gspca_suspend(struct usb_interface *intf, pm_message_t message)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
if (!gspca_dev->streaming)
return 0;
gspca_dev->frozen = 1; /* avoid urb error messages */
if (gspca_dev->sd_desc->stopN)
gspca_dev->sd_desc->stopN(gspca_dev);
destroy_urbs(gspca_dev);
gspca_set_alt0(gspca_dev);
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
return 0;
}
EXPORT_SYMBOL(gspca_suspend);
int gspca_resume(struct usb_interface *intf)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
gspca_dev->frozen = 0;
gspca_dev->sd_desc->init(gspca_dev);
if (gspca_dev->streaming)
return gspca_init_transfer(gspca_dev);
return 0;
}
EXPORT_SYMBOL(gspca_resume);
#endif
/* -- cam driver utility functions -- */ /* -- cam driver utility functions -- */
/* auto gain and exposure algorithm based on the knee algorithm described here: /* auto gain and exposure algorithm based on the knee algorithm described here:
......
...@@ -56,7 +56,6 @@ extern int gspca_debug; ...@@ -56,7 +56,6 @@ extern int gspca_debug;
/* device information - set at probe time */ /* device information - set at probe time */
struct cam { struct cam {
char *dev_name;
struct v4l2_pix_format *cam_mode; /* size nmodes */ struct v4l2_pix_format *cam_mode; /* size nmodes */
char nmodes; char nmodes;
__u8 epaddr; __u8 epaddr;
...@@ -91,15 +90,14 @@ struct sd_desc { ...@@ -91,15 +90,14 @@ struct sd_desc {
/* controls */ /* controls */
const struct ctrl *ctrls; const struct ctrl *ctrls;
int nctrls; int nctrls;
/* operations */ /* mandatory operations */
cam_cf_op config; /* called on probe */ cam_cf_op config; /* called on probe */
cam_op open; /* called on open */ cam_op init; /* called on probe and resume */
cam_v_op start; /* called on stream on */ cam_v_op start; /* called on stream on */
cam_v_op stopN; /* called on stream off - main alt */
cam_v_op stop0; /* called on stream off - alt 0 */
cam_v_op close; /* called on close */
cam_pkt_op pkt_scan; cam_pkt_op pkt_scan;
/* optional operations */ /* optional operations */
cam_v_op stopN; /* called on stream off - main alt */
cam_v_op stop0; /* called on stream off - alt 0 */
cam_v_op dq_callback; /* called when a frame has been dequeued */ cam_v_op dq_callback; /* called when a frame has been dequeued */
cam_jpg_op get_jcomp; cam_jpg_op get_jcomp;
cam_jpg_op set_jcomp; cam_jpg_op set_jcomp;
...@@ -127,8 +125,10 @@ struct gspca_dev { ...@@ -127,8 +125,10 @@ struct gspca_dev {
struct cam cam; /* device information */ struct cam cam; /* device information */
const struct sd_desc *sd_desc; /* subdriver description */ const struct sd_desc *sd_desc; /* subdriver description */
unsigned ctrl_dis; /* disabled controls (bit map) */
__u8 usb_buf[8]; /* buffer for USB exchanges */ #define USB_BUF_SZ 64
__u8 *usb_buf; /* buffer for USB exchanges */
struct urb *urb[MAX_NURBS]; struct urb *urb[MAX_NURBS];
__u8 *frbuf; /* buffer for nframes */ __u8 *frbuf; /* buffer for nframes */
...@@ -155,6 +155,9 @@ struct gspca_dev { ...@@ -155,6 +155,9 @@ struct gspca_dev {
struct mutex queue_lock; /* ISOC queue protection */ struct mutex queue_lock; /* ISOC queue protection */
__u32 sequence; /* frame sequence number */ __u32 sequence; /* frame sequence number */
char streaming; char streaming;
#ifdef CONFIG_PM
char frozen; /* suspend - resume */
#endif
char users; /* number of opens */ char users; /* number of opens */
char present; /* device connected */ char present; /* device connected */
char nbufread; /* number of buffers for read() */ char nbufread; /* number of buffers for read() */
...@@ -174,6 +177,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, ...@@ -174,6 +177,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, struct gspca_frame *frame,
const __u8 *data, const __u8 *data,
int len); int len);
#ifdef CONFIG_PM
int gspca_suspend(struct usb_interface *intf, pm_message_t message);
int gspca_resume(struct usb_interface *intf);
#endif
int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
#endif /* GSPCAV2_H */ #endif /* GSPCAV2_H */
...@@ -100,22 +100,6 @@ static int reg_w(struct gspca_dev *gspca_dev, ...@@ -100,22 +100,6 @@ static int reg_w(struct gspca_dev *gspca_dev,
return rc; return rc;
} }
static int reg_w_buf(struct gspca_dev *gspca_dev,
__u16 index, __u8 *buf, int len)
{
int rc;
rc = usb_control_msg(gspca_dev->dev,
usb_sndbulkpipe(gspca_dev->dev, 4),
0x12,
0xc8, /* ?? */
0, /* value */
index, buf, len, 500);
if (rc < 0)
PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
return rc;
}
static void bulk_w(struct gspca_dev *gspca_dev, static void bulk_w(struct gspca_dev *gspca_dev,
__u16 *pch, __u16 *pch,
__u16 Address) __u16 Address)
...@@ -144,8 +128,8 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -144,8 +128,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0; return 0;
} }
/* this function is called at open time */ /* this function is called at probe and resume time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_init(struct gspca_dev *gspca_dev)
{ {
return 0; return 0;
} }
...@@ -175,7 +159,6 @@ static void sd_start(struct gspca_dev *gspca_dev) ...@@ -175,7 +159,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* /*
Initialize the MR97113 chip register Initialize the MR97113 chip register
*/ */
data = kmalloc(16, GFP_KERNEL);
data[0] = 0x00; /* address */ data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */ data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */ data[2] = 0x01; /* reg 1 */
...@@ -195,12 +178,10 @@ static void sd_start(struct gspca_dev *gspca_dev) ...@@ -195,12 +178,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
data[10] = 0x5d; /* reg 9, I2C device address data[10] = 0x5d; /* reg 9, I2C device address
* [for PAS5101 (0x40)] [for MI (0x5d)] */ * [for PAS5101 (0x40)] [for MI (0x5d)] */
err_code = reg_w_buf(gspca_dev, data[0], data, 11); err_code = reg_w(gspca_dev, data[0], 11);
kfree(data);
if (err_code < 0) if (err_code < 0)
return; return;
data = gspca_dev->usb_buf;
data[0] = 0x23; /* address */ data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */ data[1] = 0x09; /* reg 35, append frame header */
...@@ -358,14 +339,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ...@@ -358,14 +339,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "Camera Stop failed"); PDEBUG(D_ERR, "Camera Stop failed");
} }
static void sd_stop0(struct gspca_dev *gspca_dev)
{
}
static void sd_close(struct gspca_dev *gspca_dev)
{
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */ struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */ __u8 *data, /* isoc packet */
...@@ -411,11 +384,9 @@ static const struct sd_desc sd_desc = { ...@@ -411,11 +384,9 @@ static const struct sd_desc sd_desc = {
.ctrls = sd_ctrls, .ctrls = sd_ctrls,
.nctrls = ARRAY_SIZE(sd_ctrls), .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config, .config = sd_config,
.open = sd_open, .init = sd_init,
.start = sd_start, .start = sd_start,
.stopN = sd_stopN, .stopN = sd_stopN,
.stop0 = sd_stop0,
.close = sd_close,
.pkt_scan = sd_pkt_scan, .pkt_scan = sd_pkt_scan,
}; };
...@@ -439,6 +410,10 @@ static struct usb_driver sd_driver = { ...@@ -439,6 +410,10 @@ static struct usb_driver sd_driver = {
.id_table = device_table, .id_table = device_table,
.probe = sd_probe, .probe = sd_probe,
.disconnect = gspca_disconnect, .disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
.resume = gspca_resume,
#endif
}; };
/* -- module insert / remove -- */ /* -- module insert / remove -- */
......
此差异已折叠。
...@@ -56,12 +56,6 @@ MODULE_LICENSE("GPL"); ...@@ -56,12 +56,6 @@ MODULE_LICENSE("GPL");
#define PAC207_GAIN_KNEE 20 #define PAC207_GAIN_KNEE 20
#define PAC207_AUTOGAIN_DEADZONE 30 #define PAC207_AUTOGAIN_DEADZONE 30
/* We calculating the autogain at the end of the transfer of a frame, at this
moment a frame with the old settings is being transmitted, and a frame is
being captured with the old settings. So if we adjust the autogain we must
ignore atleast the 2 next frames for the new settings to come into effect
before doing any other adjustments */
#define PAC207_AUTOGAIN_IGNORE_FRAMES 3
/* specific webcam descriptor */ /* specific webcam descriptor */
struct sd { struct sd {
...@@ -131,7 +125,8 @@ static struct ctrl sd_ctrls[] = { ...@@ -131,7 +125,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0, .minimum = 0,
.maximum = 1, .maximum = 1,
.step = 1, .step = 1,
.default_value = 1, #define AUTOGAIN_DEF 1
.default_value = AUTOGAIN_DEF,
.flags = 0, .flags = 0,
}, },
.set = sd_setautogain, .set = sd_setautogain,
...@@ -181,9 +176,6 @@ static const __u8 pac207_sensor_init[][8] = { ...@@ -181,9 +176,6 @@ static const __u8 pac207_sensor_init[][8] = {
/* 48 reg_72 Rate Control end BalSize_4a =0x36 */ /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
static const unsigned char pac207_sof_marker[5] =
{ 0xff, 0xff, 0x00, 0xff, 0x96 };
static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
const u8 *buffer, u16 length) const u8 *buffer, u16 length)
{ {
...@@ -259,35 +251,32 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -259,35 +251,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
return -ENODEV; return -ENODEV;
} }
pac207_write_reg(gspca_dev, 0x41, 0x00);
/* Bit_0=Image Format,
* Bit_1=LED,
* Bit_2=Compression test mode enable */
pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
PDEBUG(D_PROBE, PDEBUG(D_PROBE,
"Pixart PAC207BCA Image Processor and Control Chip detected" "Pixart PAC207BCA Image Processor and Control Chip detected"
" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
cam = &gspca_dev->cam; cam = &gspca_dev->cam;
cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x05; cam->epaddr = 0x05;
cam->cam_mode = sif_mode; cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode); cam->nmodes = ARRAY_SIZE(sif_mode);
sd->brightness = PAC207_BRIGHTNESS_DEFAULT; sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
sd->exposure = PAC207_EXPOSURE_DEFAULT; sd->exposure = PAC207_EXPOSURE_DEFAULT;
sd->gain = PAC207_GAIN_DEFAULT; sd->gain = PAC207_GAIN_DEFAULT;
sd->autogain = AUTOGAIN_DEF;
return 0; return 0;
} }
/* this function is called at open time */ /* this function is called at probe and resume time */
static int sd_open(struct gspca_dev *gspca_dev) static int sd_init(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; pac207_write_reg(gspca_dev, 0x41, 0x00);
/* Bit_0=Image Format,
* Bit_1=LED,
* Bit_2=Compression test mode enable */
pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
sd->autogain = 1;
return 0; return 0;
} }
...@@ -343,14 +332,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ...@@ -343,14 +332,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
} }
static void sd_stop0(struct gspca_dev *gspca_dev) /* Include pac common sof detection functions */
{ #include "pac_common.h"
}
/* this function is called at close time */
static void sd_close(struct gspca_dev *gspca_dev)
{
}
static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
{ {
...@@ -365,33 +348,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) ...@@ -365,33 +348,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
}
static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
unsigned char *m, int len)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
/* Search for the SOF marker (fixed part) in the header */
for (i = 0; i < len; i++) {
if (m[i] == pac207_sof_marker[sd->sof_read]) {
sd->sof_read++;
if (sd->sof_read == sizeof(pac207_sof_marker)) {
PDEBUG(D_STREAM,
"SOF found, bytes to analyze: %u."
" Frame starts at byte #%u",
len, i + 1);
sd->sof_read = 0;
return m + i + 1;
}
} else {
sd->sof_read = 0;
}
}
return NULL;
} }
static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void sd_pkt_scan(struct gspca_dev *gspca_dev,
...@@ -402,14 +359,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ...@@ -402,14 +359,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
unsigned char *sof; unsigned char *sof;
sof = pac207_find_sof(gspca_dev, data, len); sof = pac_find_sof(gspca_dev, data, len);
if (sof) { if (sof) {
int n; int n;
/* finish decoding current frame */ /* finish decoding current frame */
n = sof - data; n = sof - data;
if (n > sizeof pac207_sof_marker) if (n > sizeof pac_sof_marker)
n -= sizeof pac207_sof_marker; n -= sizeof pac_sof_marker;
else else
n = 0; n = 0;
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
...@@ -537,7 +494,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) ...@@ -537,7 +494,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
sd->gain = PAC207_GAIN_DEFAULT; sd->gain = PAC207_GAIN_DEFAULT;
if (gspca_dev->streaming) { if (gspca_dev->streaming) {
sd->autogain_ignore_frames = sd->autogain_ignore_frames =
PAC207_AUTOGAIN_IGNORE_FRAMES; PAC_AUTOGAIN_IGNORE_FRAMES;
setexposure(gspca_dev); setexposure(gspca_dev);
setgain(gspca_dev); setgain(gspca_dev);
} }
...@@ -560,11 +517,9 @@ static const struct sd_desc sd_desc = { ...@@ -560,11 +517,9 @@ static const struct sd_desc sd_desc = {
.ctrls = sd_ctrls, .ctrls = sd_ctrls,
.nctrls = ARRAY_SIZE(sd_ctrls), .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config, .config = sd_config,
.open = sd_open, .init = sd_init,
.start = sd_start, .start = sd_start,
.stopN = sd_stopN, .stopN = sd_stopN,
.stop0 = sd_stop0,
.close = sd_close,
.dq_callback = pac207_do_auto_gain, .dq_callback = pac207_do_auto_gain,
.pkt_scan = sd_pkt_scan, .pkt_scan = sd_pkt_scan,
}; };
...@@ -597,6 +552,10 @@ static struct usb_driver sd_driver = { ...@@ -597,6 +552,10 @@ static struct usb_driver sd_driver = {
.id_table = device_table, .id_table = device_table,
.probe = sd_probe, .probe = sd_probe,
.disconnect = gspca_disconnect, .disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
.resume = gspca_resume,
#endif
}; };
/* -- module insert / remove -- */ /* -- module insert / remove -- */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册