Commit 0dd51986 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits)
  V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added.
  V4L/DVB (12004): poll method lose race condition
  V4L/DVB (11894): flexcop-pci: dmesg visible names broken
  V4L/DVB (11892): Siano: smsendian - declare function as extern
  V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol
  V4L/DVB (11890): Siano: smscore - remove redundant code
  V4L/DVB (11889): Siano: smsdvb - add DVB v3 events
  V4L/DVB (11888): Siano: smsusb - remove redundant ifdef
  V4L/DVB (11887): Siano: smscards - add board (target) events
  V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names
  V4L/DVB (11885): Siano: Add new GPIO management interface
  V4L/DVB (11884): Siano: smssdio - revert to stand alone module
  V4L/DVB (11883): Siano: cards - add two additional (USB) devices
  V4L/DVB (11824): Siano: smsusb - change exit func debug msg
  V4L/DVB (11823): Siano: smsusb - fix typo in module description
  V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode
  V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name
  V4L/DVB (11820): Siano: smscore - fix byte ordering bug
  V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug
  V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets
  ...
parents c868d550 11c635a2
......@@ -112,7 +112,7 @@ sub tda10045 {
sub tda10046 {
my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip";
my $url = "http://technotrend-online.com/download/software/219/$sourcefile";
my $url = "http://www.tt-download.com/download/updates/219/$sourcefile";
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
......@@ -129,8 +129,8 @@ sub tda10046 {
}
sub tda10046lifeview {
my $sourcefile = "Drv_2.11.02.zip";
my $url = "http://www.lifeview.com.tw/drivers/pci_card/FlyDVB-T/$sourcefile";
my $sourcefile = "7%5Cdrv_2.11.02.zip";
my $url = "http://www.lifeview.hk/dbimages/document/$sourcefile";
my $hash = "1ea24dee4eea8fe971686981f34fd2e0";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
......@@ -317,7 +317,7 @@ sub nxt2002 {
sub nxt2004 {
my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
my $url = "http://www.aver.com/support/Drivers/$sourcefile";
my $url = "http://www.avermedia-usa.com/support/Drivers/$sourcefile";
my $hash = "111cb885b1e009188346d72acfed024c";
my $outfile = "dvb-fe-nxt2004.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
......
......@@ -16,3 +16,8 @@
15 -> TeVii S470 [d470:9022]
16 -> DVBWorld DVB-S2 2005 [0001:2005]
17 -> NetUP Dual DVB-S2 CI [1b55:2a2c]
18 -> Hauppauge WinTV-HVR1270 [0070:2211]
19 -> Hauppauge WinTV-HVR1275 [0070:2215]
20 -> Hauppauge WinTV-HVR1255 [0070:2251]
21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295]
22 -> Mygica X8506 DMB-TH [14f1:8651]
......@@ -78,3 +78,5 @@
77 -> TBS 8910 DVB-S [8910:8888]
78 -> Prof 6200 DVB-S [b022:3022]
79 -> Terratec Cinergy HT PCI MKII [153b:1177]
80 -> Hauppauge WinTV-IR Only [0070:9290]
81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654]
......@@ -17,7 +17,7 @@
16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b]
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
19 -> PointNix Intra-Oral Camera (em2860)
19 -> EM2860/SAA711X Reference Design (em2860)
20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002]
21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801]
22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751]
......@@ -61,3 +61,7 @@
63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303]
64 -> Easy Cap Capture DC-60 (em2860)
65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515]
66 -> Empire dual TV (em2880)
67 -> Terratec Grabby (em2860) [0ccd:0096]
68 -> Terratec AV350 (em2860) [0ccd:0084]
69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313]
......@@ -124,10 +124,10 @@
123 -> Beholder BeholdTV 407 [0000:4070]
124 -> Beholder BeholdTV 407 FM [0000:4071]
125 -> Beholder BeholdTV 409 [0000:4090]
126 -> Beholder BeholdTV 505 FM/RDS [0000:5051,0000:505B,5ace:5050]
127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
126 -> Beholder BeholdTV 505 FM [5ace:5050]
127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090]
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
129 -> Beholder BeholdTV 607 FM [5ace:6070]
130 -> Beholder BeholdTV M6 [5ace:6190]
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
132 -> Genius TVGO AM11MCE
......@@ -143,7 +143,7 @@
142 -> Beholder BeholdTV H6 [5ace:6290]
143 -> Beholder BeholdTV M63 [5ace:6191]
144 -> Beholder BeholdTV M6 Extra [5ace:6193]
145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636]
145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636,1461:f736]
146 -> ASUSTeK P7131 Analog
147 -> Asus Tiger 3in1 [1043:4878]
148 -> Encore ENLTV-FM v5.3 [1a7f:2008]
......@@ -154,4 +154,16 @@
153 -> Kworld Plus TV Analog Lite PCI [17de:7128]
154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d]
155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid [0070:6706,0070:6708]
156 -> Hauppauge WinTV-HVR1110r3 [0070:6707,0070:6709,0070:670a]
156 -> Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid [0070:6707,0070:6709,0070:670a]
157 -> Avermedia AVerTV Studio 507UA [1461:a11b]
158 -> AVerMedia Cardbus TV/Radio (E501R) [1461:b7e9]
159 -> Beholder BeholdTV 505 RDS [0000:505B]
160 -> Beholder BeholdTV 507 RDS [0000:5071]
161 -> Beholder BeholdTV 507 RDS [0000:507B]
162 -> Beholder BeholdTV 607 FM [5ace:6071]
163 -> Beholder BeholdTV 609 FM [5ace:6090]
164 -> Beholder BeholdTV 609 FM [5ace:6091]
165 -> Beholder BeholdTV 607 RDS [5ace:6072]
166 -> Beholder BeholdTV 607 RDS [5ace:6073]
167 -> Beholder BeholdTV 609 RDS [5ace:6092]
168 -> Beholder BeholdTV 609 RDS [5ace:6093]
......@@ -76,3 +76,5 @@ tuner=75 - Philips TEA5761 FM Radio
tuner=76 - Xceive 5000 tuner
tuner=77 - TCL tuner MF02GIP-5N-E
tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
tuner=79 - Philips PAL/SECAM multi (FM1216 MK5)
tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
......@@ -163,10 +163,11 @@ sunplus 055f:c650 Mustek MDC5500Z
zc3xx 055f:d003 Mustek WCam300A
zc3xx 055f:d004 Mustek WCam300 AN
conex 0572:0041 Creative Notebook cx11646
ov519 05a9:0519 OmniVision
ov519 05a9:0519 OV519 Microphone
ov519 05a9:0530 OmniVision
ov519 05a9:4519 OmniVision
ov519 05a9:4519 Webcam Classic
ov519 05a9:8519 OmniVision
ov519 05a9:a518 D-Link DSB-C310 Webcam
sunplus 05da:1018 Digital Dream Enigma 1.3
stk014 05e1:0893 Syntek DV4000
spca561 060b:a001 Maxell Compact Pc PM3
......@@ -178,6 +179,7 @@ spca506 06e1:a190 ADS Instant VCD
ov534 06f8:3002 Hercules Blog Webcam
ov534 06f8:3003 Hercules Dualpix HD Weblog
sonixj 06f8:3004 Hercules Classic Silver
sonixj 06f8:3008 Hercules Deluxe Optical Glass
spca508 0733:0110 ViewQuest VQ110
spca508 0130:0130 Clone Digital Webcam 11043
spca501 0733:0401 Intel Create and Share
......@@ -209,6 +211,7 @@ sunplus 08ca:2050 Medion MD 41437
sunplus 08ca:2060 Aiptek PocketDV5300
tv8532 0923:010f ICM532 cams
mars 093a:050f Mars-Semi Pc-Camera
mr97310a 093a:010f Sakar Digital no. 77379
pac207 093a:2460 Qtec Webcam 100
pac207 093a:2461 HP Webcam
pac207 093a:2463 Philips SPC 220 NC
......@@ -265,6 +268,11 @@ sonixj 0c45:60ec SN9C105+MO4000
sonixj 0c45:60fb Surfer NoName
sonixj 0c45:60fc LG-LIC300
sonixj 0c45:60fe Microdia Audio
sonixj 0c45:6100 PC Camera (SN9C128)
sonixj 0c45:610a PC Camera (SN9C128)
sonixj 0c45:610b PC Camera (SN9C128)
sonixj 0c45:610c PC Camera (SN9C128)
sonixj 0c45:610e PC Camera (SN9C128)
sonixj 0c45:6128 Microdia/Sonix SNP325
sonixj 0c45:612a Avant Camera
sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
......
......@@ -26,6 +26,55 @@ Global video workflow
Once the last buffer is filled in, the QCI interface stops.
c) Capture global finite state machine schema
+----+ +---+ +----+
| DQ | | Q | | DQ |
| v | v | v
+-----------+ +------------------------+
| STOP | | Wait for capture start |
+-----------+ Q +------------------------+
+-> | QCI: stop | ------------------> | QCI: run | <------------+
| | DMA: stop | | DMA: stop | |
| +-----------+ +-----> +------------------------+ |
| / | |
| / +---+ +----+ | |
|capture list empty / | Q | | DQ | | QCI Irq EOF |
| / | v | v v |
| +--------------------+ +----------------------+ |
| | DMA hotlink missed | | Capture running | |
| +--------------------+ +----------------------+ |
| | QCI: run | +-----> | QCI: run | <-+ |
| | DMA: stop | / | DMA: run | | |
| +--------------------+ / +----------------------+ | Other |
| ^ /DMA still | | channels |
| | capture list / running | DMA Irq End | not |
| | not empty / | | finished |
| | / v | yet |
| +----------------------+ +----------------------+ | |
| | Videobuf released | | Channel completed | | |
| +----------------------+ +----------------------+ | |
+-- | QCI: run | | QCI: run | --+ |
| DMA: run | | DMA: run | |
+----------------------+ +----------------------+ |
^ / | |
| no overrun / | overrun |
| / v |
+--------------------+ / +----------------------+ |
| Frame completed | / | Frame overran | |
+--------------------+ <-----+ +----------------------+ restart frame |
| QCI: run | | QCI: stop | --------------+
| DMA: run | | DMA: stop |
+--------------------+ +----------------------+
Legend: - each box is a FSM state
- each arrow is the condition to transition to another state
- an arrow with a comment is a mandatory transition (no condition)
- arrow "Q" means : a buffer was enqueued
- arrow "DQ" means : a buffer was dequeued
- "QCI: stop" means the QCI interface is not enabled
- "DMA: stop" means all 3 DMA channels are stopped
- "DMA: run" means at least 1 DMA channel is still running
DMA usage
---------
......
......@@ -89,6 +89,11 @@ from dev (driver name followed by the bus_id, to be precise). If you set it
up before calling v4l2_device_register then it will be untouched. If dev is
NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
You can use v4l2_device_set_name() to set the name based on a driver name and
a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
etc. If the name ends with a digit, then it will insert a dash: cx18-0,
cx18-1, etc. This function returns the instance number.
The first 'dev' argument is normally the struct device pointer of a pci_dev,
usb_interface or platform_device. It is rare for dev to be NULL, but it happens
with ISA devices or when one device creates multiple PCI devices, thus making
......
......@@ -380,12 +380,12 @@ static struct pca953x_platform_data pca9536_data = {
.gpio_base = NR_BUILTIN_GPIO,
};
static int gpio_bus_switch;
static int gpio_bus_switch = -EINVAL;
static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
unsigned long flags)
unsigned long flags)
{
if (gpio_bus_switch <= 0) {
if (gpio_bus_switch < 0) {
if (flags == SOCAM_DATAWIDTH_10)
return 0;
else
......@@ -404,25 +404,34 @@ static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
{
int ret;
if (!gpio_bus_switch) {
if (gpio_bus_switch < 0) {
ret = gpio_request(NR_BUILTIN_GPIO, "camera");
if (!ret) {
gpio_bus_switch = NR_BUILTIN_GPIO;
gpio_direction_output(gpio_bus_switch, 0);
} else
gpio_bus_switch = -EINVAL;
}
}
if (gpio_bus_switch > 0)
if (gpio_bus_switch >= 0)
return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
else
return SOCAM_DATAWIDTH_10;
}
static void pcm990_camera_free_bus(struct soc_camera_link *link)
{
if (gpio_bus_switch < 0)
return;
gpio_free(gpio_bus_switch);
gpio_bus_switch = -EINVAL;
}
static struct soc_camera_link iclink = {
.bus_id = 0, /* Must match with the camera ID above */
.query_bus_param = pcm990_camera_query_bus_param,
.set_bus_param = pcm990_camera_set_bus_param,
.free_bus = pcm990_camera_free_bus,
};
/* Board I2C devices. */
......
......@@ -2,8 +2,14 @@
# Multimedia device configuration
#
menu "Multimedia devices"
menuconfig MEDIA_SUPPORT
tristate "Multimedia support"
depends on HAS_IOMEM
help
If you want to use Video for Linux, DVB for Linux, or DAB adapters,
enable this option and other options below.
if MEDIA_SUPPORT
comment "Multimedia core support"
......@@ -136,4 +142,4 @@ config USB_DABUSB
module will be called dabusb.
endif # DAB
endmenu
endif # MEDIA_SUPPORT
......@@ -416,6 +416,24 @@ static int simple_std_setup(struct dvb_frontend *fe,
return 0;
}
static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux)
{
struct tuner_simple_priv *priv = fe->tuner_priv;
int rc;
u8 buffer[2];
buffer[0] = (config & ~0x38) | 0x18;
buffer[1] = aux;
tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]);
rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc);
return rc == 2 ? 0 : rc;
}
static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
u16 div, u8 config, u8 cb)
{
......@@ -424,17 +442,10 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
switch (priv->type) {
case TUNER_LG_TDVS_H06XF:
/* Set the Auxiliary Byte. */
buffer[0] = buffer[2];
buffer[0] &= ~0x20;
buffer[0] |= 0x18;
buffer[1] = 0x20;
tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]);
rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
simple_set_aux_byte(fe, config, 0x20);
break;
case TUNER_PHILIPS_FQ1216LME_MK3:
simple_set_aux_byte(fe, config, 0x60); /* External AGC */
break;
case TUNER_MICROTUNE_4042FI5:
{
......@@ -506,6 +517,11 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
case TUNER_THOMSON_DTT761X:
buffer[3] = 0x39;
break;
case TUNER_PHILIPS_FQ1216LME_MK3:
tuner_err("This tuner doesn't have FM\n");
/* Set the low band for sanity, since it covers 88-108 MHz */
buffer[3] = 0x01;
break;
case TUNER_MICROTUNE_4049FM5:
default:
buffer[3] = 0xa4;
......@@ -678,12 +694,12 @@ static int simple_set_radio_freq(struct dvb_frontend *fe,
return 0;
}
/* Bandswitch byte */
simple_radio_bandswitch(fe, &buffer[0]);
buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
TUNER_RATIO_SELECT_50; /* 50 kHz step */
/* Bandswitch byte */
simple_radio_bandswitch(fe, &buffer[0]);
/* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
freq * (1/800) */
......
......@@ -578,6 +578,31 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = {
},
};
/* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */
static struct tuner_range tuner_fm1216mk5_pal_ranges[] = {
{ 16 * 158.00 /*MHz*/, 0xce, 0x01, },
{ 16 * 441.00 /*MHz*/, 0xce, 0x02, },
{ 16 * 864.00 , 0xce, 0x04, },
};
static struct tuner_params tuner_fm1216mk5_params[] = {
{
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_fm1216mk5_pal_ranges,
.count = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges),
.cb_first_if_lower_freq = 1,
.has_tda9887 = 1,
.port1_active = 1,
.port2_active = 1,
.port2_invert_for_secam_lc = 1,
.port1_fm_high_sensitivity = 1,
.default_top_mid = -2,
.default_top_secam_mid = -2,
.default_top_secam_high = -2,
},
};
/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */
static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
......@@ -1254,6 +1279,28 @@ static struct tuner_params tuner_tcl_mf02gip_5n_params[] = {
},
};
/* 80-89 */
/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */
static struct tuner_params tuner_fq1216lme_mk3_params[] = {
{
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_fm1216me_mk3_pal_ranges,
.count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
.cb_first_if_lower_freq = 1, /* not specified, but safe to do */
.has_tda9887 = 1, /* TDA9886 */
.port1_active = 1,
.port2_active = 1,
.port2_invert_for_secam_lc = 1,
.default_top_low = 4,
.default_top_mid = 4,
.default_top_high = 4,
.default_top_secam_low = 4,
.default_top_secam_mid = 4,
.default_top_secam_high = 4,
},
};
/* --------------------------------------------------------------------- */
struct tunertype tuners[] = {
......@@ -1694,6 +1741,18 @@ struct tunertype tuners[] = {
.initdata = tua603x_agc112,
.sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
},
[TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */
.name = "Philips PAL/SECAM multi (FM1216 MK5)",
.params = tuner_fm1216mk5_params,
.count = ARRAY_SIZE(tuner_fm1216mk5_params),
},
/* 80-89 */
[TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */
.name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough",
.params = tuner_fq1216lme_mk3_params,
.count = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
},
};
EXPORT_SYMBOL(tuners);
......
......@@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug, "enable verbose debug messages");
static int no_poweroff;
module_param(no_poweroff, int, 0644);
MODULE_PARM_DESC(debug, "0 (default) powers device off when not used.\n"
MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
"1 keep device energized and with tuner ready all the times.\n"
" Faster, but consumes more power and keeps the device hotter\n");
......@@ -272,7 +272,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
fname = firmware_name;
tuner_dbg("Reading firmware %s\n", fname);
rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev);
rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
if (rc < 0) {
if (rc == -ENOENT)
tuner_err("Error: firmware %s not found.\n",
......@@ -917,22 +917,29 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
* that xc2028 will be in a safe state.
* Maybe this might also be needed for DTV.
*/
if (new_mode == T_ANALOG_TV) {
if (new_mode == T_ANALOG_TV)
rc = send_seq(priv, {0x00, 0x00});
} else if (priv->cur_fw.type & ATSC) {
offset = 1750000;
} else {
offset = 2750000;
/*
* Digital modes require an offset to adjust to the
* proper frequency.
* Analog modes require offset = 0
*/
if (new_mode == T_DIGITAL_TV) {
/* Sets the offset according with firmware */
if (priv->cur_fw.type & DTV6)
offset = 1750000;
else if (priv->cur_fw.type & DTV7)
offset = 2250000;
else /* DTV8 or DTV78 */
offset = 2750000;
/*
* We must adjust the offset by 500kHz in two cases in order
* to correctly center the IF output:
* 1) When the ZARLINK456 or DIBCOM52 tables were explicitly
* selected and a 7MHz channel is tuned;
* 2) When tuning a VHF channel with DTV78 firmware.
* We must adjust the offset by 500kHz when
* tuning a 7MHz VHF channel with DTV78 firmware
* (used in Australia, Italy and Germany)
*/
if (((priv->cur_fw.type & DTV7) &&
(priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) ||
((priv->cur_fw.type & DTV78) && freq < 470000000))
if ((priv->cur_fw.type & DTV78) && freq < 470000000)
offset -= 500000;
}
......@@ -991,7 +998,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
if (priv->ctrl.input1)
type |= INPUT1;
return generic_set_freq(fe, (625l * p->frequency) / 10,
T_ANALOG_TV, type, 0, 0);
T_RADIO, type, 0, 0);
}
/* if std is not defined, choose one */
......@@ -1022,21 +1029,20 @@ static int xc2028_set_params(struct dvb_frontend *fe,
switch(fe->ops.info.type) {
case FE_OFDM:
bw = p->u.ofdm.bandwidth;
break;
case FE_QAM:
tuner_info("WARN: There are some reports that "
"QAM 6 MHz doesn't work.\n"
"If this works for you, please report by "
"e-mail to: v4l-dvb-maintainer@linuxtv.org\n");
bw = BANDWIDTH_6_MHZ;
type |= QAM;
/*
* The only countries with 6MHz seem to be Taiwan/Uruguay.
* Both seem to require QAM firmware for OFDM decoding
* Tested in Taiwan by Terry Wu <terrywu2009@gmail.com>
*/
if (bw == BANDWIDTH_6_MHZ)
type |= QAM;
break;
case FE_ATSC:
bw = BANDWIDTH_6_MHZ;
/* The only ATSC firmware (at least on v2.7) is D2633 */
type |= ATSC | D2633;
break;
/* DVB-S is not supported */
/* DVB-S and pure QAM (FE_QAM) are not supported */
default:
return -EINVAL;
}
......
......@@ -3,6 +3,7 @@
*
* Copyright (c) 2007 Xceive Corporation
* Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
* Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
*
* 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
......@@ -36,14 +37,20 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
static int no_poweroff;
module_param(no_poweroff, int, 0644);
MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
"\t\t1 keep device energized and with tuner ready all the times.\n"
"\t\tFaster, but consumes more power and keeps the device hotter");
static DEFINE_MUTEX(xc5000_list_mutex);
static LIST_HEAD(hybrid_tuner_instance_list);
#define dprintk(level, fmt, arg...) if (debug >= level) \
printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
#define XC5000_DEFAULT_FIRMWARE_SIZE 12332
#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
struct xc5000_priv {
struct tuner_i2c_props i2c_props;
......@@ -83,11 +90,11 @@ struct xc5000_priv {
#define XREG_D_CODE 0x04
#define XREG_IF_OUT 0x05
#define XREG_SEEK_MODE 0x07
#define XREG_POWER_DOWN 0x0A
#define XREG_POWER_DOWN 0x0A /* Obsolete */
#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
#define XREG_SMOOTHEDCVBS 0x0E
#define XREG_XTALFREQ 0x0F
#define XREG_FINERFFREQ 0x10
#define XREG_FINERFREQ 0x10
#define XREG_DDIMODE 0x11
#define XREG_ADC_ENV 0x00
......@@ -100,6 +107,7 @@ struct xc5000_priv {
#define XREG_VERSION 0x07
#define XREG_PRODUCT_ID 0x08
#define XREG_BUSY 0x09
#define XREG_BUILD 0x0D
/*
Basic firmware description. This will remain with
......@@ -191,27 +199,36 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"FM Radio-INPUT1", 0x0208, 0x9002}
};
static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len);
static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len);
static void xc5000_TunerReset(struct dvb_frontend *fe);
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
static int xc5000_TunerReset(struct dvb_frontend *fe);
static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
{
return xc5000_writeregs(priv, buf, len)
? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS;
struct i2c_msg msg = { .addr = priv->i2c_props.addr,
.flags = 0, .buf = buf, .len = len };
if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
return XC_RESULT_I2C_WRITE_FAILURE;
}
return XC_RESULT_SUCCESS;
}
/* This routine is never used because the only time we read data from the
i2c bus is when we read registers, and we want that to be an atomic i2c
transaction in case we are on a multi-master bus */
static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
{
return xc5000_readregs(priv, buf, len)
? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS;
}
struct i2c_msg msg = { .addr = priv->i2c_props.addr,
.flags = I2C_M_RD, .buf = buf, .len = len };
static int xc_reset(struct dvb_frontend *fe)
{
xc5000_TunerReset(fe);
return XC_RESULT_SUCCESS;
if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
return -EREMOTEIO;
}
return 0;
}
static void xc_wait(int wait_ms)
......@@ -219,7 +236,7 @@ static void xc_wait(int wait_ms)
msleep(wait_ms);
}
static void xc5000_TunerReset(struct dvb_frontend *fe)
static int xc5000_TunerReset(struct dvb_frontend *fe)
{
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
......@@ -232,16 +249,21 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
priv->i2c_props.adap->algo_data,
DVB_FRONTEND_COMPONENT_TUNER,
XC5000_TUNER_RESET, 0);
if (ret)
if (ret) {
printk(KERN_ERR "xc5000: reset failed\n");
} else
return XC_RESULT_RESET_FAILURE;
}
} else {
printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
return XC_RESULT_RESET_FAILURE;
}
return XC_RESULT_SUCCESS;
}
static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
{
u8 buf[4];
int WatchDogTimer = 5;
int WatchDogTimer = 100;
int result;
buf[0] = (regAddr >> 8) & 0xFF;
......@@ -263,7 +285,7 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
/* busy flag cleared */
break;
} else {
xc_wait(100); /* wait 5 ms */
xc_wait(5); /* wait 5 ms */
WatchDogTimer--;
}
}
......@@ -276,25 +298,6 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
return result;
}
static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData)
{
u8 buf[2];
int result;
buf[0] = (regAddr >> 8) & 0xFF;
buf[1] = regAddr & 0xFF;
result = xc_send_i2c_data(priv, buf, 2);
if (result != XC_RESULT_SUCCESS)
return result;
result = xc_read_i2c_data(priv, buf, 2);
if (result != XC_RESULT_SUCCESS)
return result;
*i2cData = buf[0] * 256 + buf[1];
return result;
}
static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
{
struct xc5000_priv *priv = fe->tuner_priv;
......@@ -309,7 +312,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
if (len == 0x0000) {
/* RESET command */
result = xc_reset(fe);
result = xc5000_TunerReset(fe);
index += 2;
if (result != XC_RESULT_SUCCESS)
return result;
......@@ -371,15 +374,6 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
return ret;
}
static int xc_shutdown(struct xc5000_priv *priv)
{
return XC_RESULT_SUCCESS;
/* Fixme: cannot bring tuner back alive once shutdown
* without reloading the driver modules.
* return xc_write_reg(priv, XREG_POWER_DOWN, 0);
*/
}
static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
{
dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
......@@ -408,7 +402,10 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
freq_code = (u16)(freq_hz / 15625);
return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
/* Starting in firmware version 1.1.44, Xceive recommends using the
FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
only be used for fast scanning for channel lock) */
return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
}
......@@ -424,7 +421,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
{
return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope);
return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
}
static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
......@@ -433,8 +430,8 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
u16 regData;
u32 tmp;
result = xc_read_reg(priv, XREG_FREQ_ERROR, &regData);
if (result)
result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
if (result != XC_RESULT_SUCCESS)
return result;
tmp = (u32)regData;
......@@ -444,7 +441,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
{
return xc_read_reg(priv, XREG_LOCK, lock_status);
return xc5000_readreg(priv, XREG_LOCK, lock_status);
}
static int xc_get_version(struct xc5000_priv *priv,
......@@ -454,8 +451,8 @@ static int xc_get_version(struct xc5000_priv *priv,
u16 data;
int result;
result = xc_read_reg(priv, XREG_VERSION, &data);
if (result)
result = xc5000_readreg(priv, XREG_VERSION, &data);
if (result != XC_RESULT_SUCCESS)
return result;
(*hw_majorversion) = (data >> 12) & 0x0F;
......@@ -466,13 +463,18 @@ static int xc_get_version(struct xc5000_priv *priv,
return 0;
}
static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
{
return xc5000_readreg(priv, XREG_BUILD, buildrev);
}
static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
{
u16 regData;
int result;
result = xc_read_reg(priv, XREG_HSYNC_FREQ, &regData);
if (result)
result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
if (result != XC_RESULT_SUCCESS)
return result;
(*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
......@@ -481,12 +483,12 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
{
return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines);
return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
}
static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
{
return xc_read_reg(priv, XREG_QUALITY, quality);
return xc5000_readreg(priv, XREG_QUALITY, quality);
}
static u16 WaitForLock(struct xc5000_priv *priv)
......@@ -504,7 +506,9 @@ static u16 WaitForLock(struct xc5000_priv *priv)
return lockState;
}
static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz)
#define XC_TUNE_ANALOG 0
#define XC_TUNE_DIGITAL 1
static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
{
int found = 0;
......@@ -513,8 +517,10 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz)
if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
return 0;
if (WaitForLock(priv) == 1)
found = 1;
if (mode == XC_TUNE_ANALOG) {
if (WaitForLock(priv) == 1)
found = 1;
}
return found;
}
......@@ -536,32 +542,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
}
*val = (bval[0] << 8) | bval[1];
return 0;
}
static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
{
struct i2c_msg msg = { .addr = priv->i2c_props.addr,
.flags = 0, .buf = buf, .len = len };
if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n",
(int)len);
return -EREMOTEIO;
}
return 0;
}
static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
{
struct i2c_msg msg = { .addr = priv->i2c_props.addr,
.flags = I2C_M_RD, .buf = buf, .len = len };
if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len);
return -EREMOTEIO;
}
return 0;
return XC_RESULT_SUCCESS;
}
static int xc5000_fwupload(struct dvb_frontend *fe)
......@@ -575,13 +556,13 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
XC5000_DEFAULT_FIRMWARE);
ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
&priv->i2c_props.adap->dev);
priv->i2c_props.adap->dev.parent);
if (ret) {
printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
ret = XC_RESULT_RESET_FAILURE;
goto out;
} else {
printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n",
printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
fw->size);
ret = XC_RESULT_SUCCESS;
}
......@@ -590,8 +571,9 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
printk(KERN_ERR "xc5000: firmware incorrect size\n");
ret = XC_RESULT_RESET_FAILURE;
} else {
printk(KERN_INFO "xc5000: firmware upload\n");
printk(KERN_INFO "xc5000: firmware uploading...\n");
ret = xc_load_i2c_sequence(fe, fw->data);
printk(KERN_INFO "xc5000: firmware upload complete...\n");
}
out:
......@@ -609,6 +591,7 @@ static void xc_debug_dump(struct xc5000_priv *priv)
u16 quality;
u8 hw_majorversion = 0, hw_minorversion = 0;
u8 fw_majorversion = 0, fw_minorversion = 0;
u16 fw_buildversion = 0;
/* Wait for stats to stabilize.
* Frame Lines needs two frame times after initial lock
......@@ -628,9 +611,10 @@ static void xc_debug_dump(struct xc5000_priv *priv)
xc_get_version(priv, &hw_majorversion, &hw_minorversion,
&fw_majorversion, &fw_minorversion);
dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
xc_get_buildversion(priv, &fw_buildversion);
dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
hw_majorversion, hw_minorversion,
fw_majorversion, fw_minorversion);
fw_majorversion, fw_minorversion, fw_buildversion);
xc_get_hsync_freq(priv, &hsync_freq_hz);
dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
......@@ -648,27 +632,57 @@ static int xc5000_set_params(struct dvb_frontend *fe,
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
xc_load_fw_and_init_tuner(fe);
dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
switch (params->u.vsb.modulation) {
case VSB_8:
case VSB_16:
dprintk(1, "%s() VSB modulation\n", __func__);
if (fe->ops.info.type == FE_ATSC) {
dprintk(1, "%s() ATSC\n", __func__);
switch (params->u.vsb.modulation) {
case VSB_8:
case VSB_16:
dprintk(1, "%s() VSB modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_AIR;
priv->freq_hz = params->frequency - 1750000;
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->video_standard = DTV6;
break;
case QAM_64:
case QAM_256:
case QAM_AUTO:
dprintk(1, "%s() QAM modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_CABLE;
priv->freq_hz = params->frequency - 1750000;
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->video_standard = DTV6;
break;
default:
return -EINVAL;
}
} else if (fe->ops.info.type == FE_OFDM) {
dprintk(1, "%s() OFDM\n", __func__);
switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->video_standard = DTV6;
priv->freq_hz = params->frequency - 1750000;
break;
case BANDWIDTH_7_MHZ:
printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n");
return -EINVAL;
case BANDWIDTH_8_MHZ:
priv->bandwidth = BANDWIDTH_8_MHZ;
priv->video_standard = DTV8;
priv->freq_hz = params->frequency - 2750000;
break;
default:
printk(KERN_ERR "xc5000 bandwidth not set!\n");
return -EINVAL;
}
priv->rf_mode = XC_RF_MODE_AIR;
priv->freq_hz = params->frequency - 1750000;
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->video_standard = DTV6;
break;
case QAM_64:
case QAM_256:
case QAM_AUTO:
dprintk(1, "%s() QAM modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_CABLE;
priv->freq_hz = params->frequency - 1750000;
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->video_standard = DTV6;
break;
default:
} else {
printk(KERN_ERR "xc5000 modulation type not supported!\n");
return -EINVAL;
}
......@@ -698,7 +712,7 @@ static int xc5000_set_params(struct dvb_frontend *fe,
return -EIO;
}
xc_tune_channel(priv, priv->freq_hz);
xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
if (debug)
xc_debug_dump(priv);
......@@ -725,8 +739,6 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
return ret;
}
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
static int xc5000_set_analog_params(struct dvb_frontend *fe,
struct analog_parameters *params)
{
......@@ -807,7 +819,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
return -EREMOTEIO;
}
xc_tune_channel(priv, priv->freq_hz);
xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
if (debug)
xc_debug_dump(priv);
......@@ -875,18 +887,18 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
static int xc5000_sleep(struct dvb_frontend *fe)
{
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
dprintk(1, "%s()\n", __func__);
/* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized
* once shutdown without reloading the driver. Maybe I am not
* doing something right.
*
*/
/* Avoid firmware reload on slow devices */
if (no_poweroff)
return 0;
ret = xc_shutdown(priv);
/* According to Xceive technical support, the "powerdown" register
was removed in newer versions of the firmware. The "supported"
way to sleep the tuner is to pull the reset pin low for 10ms */
ret = xc5000_TunerReset(fe);
if (ret != XC_RESULT_SUCCESS) {
printk(KERN_ERR
"xc5000: %s() unable to shutdown tuner\n",
......@@ -991,7 +1003,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
/* Check if firmware has been loaded. It is possible that another
instance of the driver has loaded the firmware.
*/
if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
goto fail;
switch (id) {
......
/*
* This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
*
* flexcop-common.h - common header file for device-specific source files also.
*
* see flexcop.c for copyright information.
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-common.h - common header file for device-specific source files
* see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_COMMON_H__
#define __FLEXCOP_COMMON_H__
......
This diff is collapsed.
......@@ -200,7 +200,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
msgs[i].buf[0], &msgs[i].buf[1],
msgs[i].len - 1);
if (ret < 0) {
err("i2c master_xfer failed");
deb_i2c("i2c master_xfer failed");
break;
}
}
......
......@@ -46,16 +46,16 @@ static const char *flexcop_revision_names[] = {
};
static const char *flexcop_device_names[] = {
"Unknown device",
"Air2PC/AirStar 2 DVB-T",
"Air2PC/AirStar 2 ATSC 1st generation",
"Air2PC/AirStar 2 ATSC 2nd generation",
"Sky2PC/SkyStar 2 DVB-S",
"Sky2PC/SkyStar 2 DVB-S (old version)",
"Cable2PC/CableStar 2 DVB-C",
"Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
"Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
"Sky2PC/SkyStar 2 DVB-S rev 2.8",
[FC_UNK] = "Unknown device",
[FC_CABLE] = "Cable2PC/CableStar 2 DVB-C",
[FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T",
[FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation",
[FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation",
[FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
[FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
[FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
[FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
[FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
};
static const char *flexcop_bus_names[] = {
......
......@@ -508,12 +508,6 @@ static int __devinit bt878_probe(struct pci_dev *dev,
pci_set_master(dev);
pci_set_drvdata(dev, bt);
/* if(init_bt878(btv) < 0) {
bt878_remove(dev);
return -EIO;
}
*/
if ((result = bt878_mem_alloc(bt))) {
printk(KERN_ERR "bt878: failed to allocate memory!\n");
goto fail2;
......@@ -579,7 +573,7 @@ static struct pci_driver bt878_pci_driver = {
.name = "bt878",
.id_table = bt878_pci_tbl,
.probe = bt878_probe,
.remove = bt878_remove,
.remove = __devexit_p(bt878_remove),
};
static int bt878_pci_driver_registered;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment