Commit 043fe50f authored by Linus Torvalds's avatar Linus Torvalds

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: (213 commits)
  V4L/DVB (12720): em28xx-cards: Add vendor/product id for Kworld DVD Maker 2
  V4L/DVB (12713): em28xx: Cleanups at ir_i2c handler
  V4L/DVB (12712): em28xx: properly load ir-kbd-i2c when needed
  V4L/DVB (12701): saa7134: ir-kbd-i2c init data needs a persistent object
  V4L/DVB (12699): cx18: ir-kbd-i2c initialization data should point to a persistent object
  V4L/DVB (12698): em28xx: ir-kbd-i2c init data needs a persistent object
  V4L/DVB (12707): gspca - sn9c20x: Add SXGA support to MT9M111
  V4L/DVB (12706): gspca - sn9c20x: disable exposure/gain controls for MT9M111 sensors.
  V4L/DVB (12705): gspca - sn9c20x: Add SXGA support to SOI968
  V4L/DVB (12703): gspca - sn9c20x: Reduces size of object
  V4L/DVB (12704): gspca - sn9c20x: Fix exposure on SOI968 sensors
  V4L/DVB (12696): gspca - sonixj / sn9c102: Two drivers for 0c45:60fc and 0c45:613e.
  V4L/DVB (12695): gspca - vc032x: Do the LED work with the sensor hv7131r.
  V4L/DVB (12694): gspca - vc032x: Change the start exchanges of the sensor hv7131r.
  V4L/DVB (12693): gspca - sunplus: The brightness is signed.
  V4L/DVB (12692): gspca - sunplus: Optimize code.
  V4L/DVB (12691): gspca - sonixj: Don't use mdelay().
  V4L/DVB (12690): gspca - pac7311: Webcam 06f8:3009 added.
  V4L/DVB (12686): dvb-core: check supported QAM modulations
  V4L/DVB (12685): dvb-core: check fe->ops.set_frontend return value
  ...
parents 22742390 ea47689e
......@@ -21,3 +21,5 @@
20 -> Hauppauge WinTV-HVR1255 [0070:2251]
21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295]
22 -> Mygica X8506 DMB-TH [14f1:8651]
23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657]
24 -> Hauppauge WinTV-HVR1850 [0070:8541]
......@@ -80,3 +80,4 @@
79 -> Terratec Cinergy HT PCI MKII [153b:1177]
80 -> Hauppauge WinTV-IR Only [0070:9290]
81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654]
82 -> WinFast DTV2000 H rev. J [107d:6f2b]
......@@ -7,7 +7,7 @@
6 -> Terratec Cinergy 200 USB (em2800)
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,2304:0207,2304:021a]
9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
......@@ -33,7 +33,7 @@
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
35 -> Typhoon DVD Maker (em2860)
36 -> NetGMBH Cam (em2860)
37 -> Gadmei UTV330 (em2860)
37 -> Gadmei UTV330 (em2860) [eb1a:50a6]
38 -> Yakumo MovieMixer (em2861)
39 -> KWorld PVRTV 300U (em2861) [eb1a:e300]
40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005]
......@@ -67,3 +67,4 @@
69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313]
70 -> Evga inDtube (em2882)
71 -> Silvercrest Webcam 1.3mpix (em2820/em2840)
72 -> Gadmei UTV330+ (em2861)
......@@ -167,3 +167,7 @@
166 -> Beholder BeholdTV 607 RDS [5ace:6073]
167 -> Beholder BeholdTV 609 RDS [5ace:6092]
168 -> Beholder BeholdTV 609 RDS [5ace:6093]
169 -> Compro VideoMate S350/S300 [185b:c900]
170 -> AverMedia AverTV Studio 505 [1461:a115]
171 -> Beholder BeholdTV X7 [5ace:7595]
172 -> RoverMedia TV Link Pro FM [19d1:0138]
......@@ -78,3 +78,4 @@ 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
tuner=81 - Partsnic (Daewoo) PTI-5NF05
......@@ -18,8 +18,8 @@ Table of Contents
1.0 Introduction
The file ../drivers/char/c-qcam.c is a device driver for the
Logitech (nee Connectix) parallel port interface color CCD camera.
The file ../../drivers/media/video/c-qcam.c is a device driver for
the Logitech (nee Connectix) parallel port interface color CCD camera.
This is a fairly inexpensive device for capturing images. Logitech
does not currently provide information for developers, but many people
have engineered several solutions for non-Microsoft use of the Color
......
......@@ -140,6 +140,7 @@ spca500 04fc:7333 PalmPixDC85
sunplus 04fc:ffff Pure DigitalDakota
spca501 0506:00df 3Com HomeConnect Lite
sunplus 052b:1513 Megapix V4
sunplus 052b:1803 MegaImage VI
tv8532 0545:808b Veo Stingray
tv8532 0545:8333 Veo Stingray
sunplus 0546:3155 Polaroid PDC3070
......@@ -182,6 +183,7 @@ 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
pac7311 06f8:3009 Hercules Classic Link
spca508 0733:0110 ViewQuest VQ110
spca508 0130:0130 Clone Digital Webcam 11043
spca501 0733:0401 Intel Create and Share
......@@ -235,8 +237,10 @@ pac7311 093a:2621 PAC731x
pac7311 093a:2622 Genius Eye 312
pac7311 093a:2624 PAC7302
pac7311 093a:2626 Labtec 2200
pac7311 093a:2629 Genious iSlim 300
pac7311 093a:262a Webcam 300k
pac7311 093a:262c Philips SPC 230 NC
jeilinj 0979:0280 Sakar 57379
zc3xx 0ac8:0302 Z-star Vimicro zc0302
vc032x 0ac8:0321 Vimicro generic vc0321
vc032x 0ac8:0323 Vimicro Vc0323
......@@ -247,6 +251,7 @@ zc3xx 0ac8:305b Z-star Vimicro zc0305b
zc3xx 0ac8:307b Ldlc VC302+Ov7620
vc032x 0ac8:c001 Sony embedded vimicro
vc032x 0ac8:c002 Sony embedded vimicro
vc032x 0ac8:c301 Samsung Q1 Ultra Premium
spca508 0af9:0010 Hama USB Sightcam 100
spca508 0af9:0011 Hama USB Sightcam 100
sonixb 0c45:6001 Genius VideoCAM NB
......@@ -284,6 +289,7 @@ sonixj 0c45:613a Microdia Sonix PC Camera
sonixj 0c45:613b Surfer SN-206
sonixj 0c45:613c Sonix Pccam168
sonixj 0c45:6143 Sonix Pccam168
sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001)
sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111)
sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655)
......
Driver for I2C radios for the Silicon Labs Si4713 FM Radio Transmitters
Copyright (c) 2009 Nokia Corporation
Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
Information about the Device
============================
This chip is a Silicon Labs product. It is a I2C device, currently on 0x63 address.
Basically, it has transmission and signal noise level measurement features.
The Si4713 integrates transmit functions for FM broadcast stereo transmission.
The chip also allows integrated receive power scanning to identify low signal
power FM channels.
The chip is programmed using commands and responses. There are also several
properties which can change the behavior of this chip.
Users must comply with local regulations on radio frequency (RF) transmission.
Device driver description
=========================
There are two modules to handle this device. One is a I2C device driver
and the other is a platform driver.
The I2C device driver exports a v4l2-subdev interface to the kernel.
All properties can also be accessed by v4l2 extended controls interface, by
using the v4l2-subdev calls (g_ext_ctrls, s_ext_ctrls).
The platform device driver exports a v4l2 radio device interface to user land.
So, it uses the I2C device driver as a sub device in order to send the user
commands to the actual device. Basically it is a wrapper to the I2C device driver.
Applications can use v4l2 radio API to specify frequency of operation, mute state,
etc. But mostly of its properties will be present in the extended controls.
When the v4l2 mute property is set to 1 (true), the driver will turn the chip off.
Properties description
======================
The properties can be accessed using v4l2 extended controls.
Here is an output from v4l2-ctl util:
/ # v4l2-ctl -d /dev/radio0 --all -L
Driver Info:
Driver name : radio-si4713
Card type : Silicon Labs Si4713 Modulator
Bus info :
Driver version: 0
Capabilities : 0x00080800
RDS Output
Modulator
Audio output: 0 (FM Modulator Audio Out)
Frequency: 1408000 (88.000000 MHz)
Video Standard = 0x00000000
Modulator:
Name : FM Modulator
Capabilities : 62.5 Hz stereo rds
Frequency range : 76.0 MHz - 108.0 MHz
Subchannel modulation: stereo+rds
User Controls
mute (bool) : default=1 value=0
FM Radio Modulator Controls
rds_signal_deviation (int) : min=0 max=90000 step=10 default=200 value=200 flags=slider
rds_program_id (int) : min=0 max=65535 step=1 default=0 value=0
rds_program_type (int) : min=0 max=31 step=1 default=0 value=0
rds_ps_name (str) : min=0 max=96 step=8 value='si4713 '
rds_radio_text (str) : min=0 max=384 step=32 value=''
audio_limiter_feature_enabled (bool) : default=1 value=1
audio_limiter_release_time (int) : min=250 max=102390 step=50 default=5010 value=5010 flags=slider
audio_limiter_deviation (int) : min=0 max=90000 step=10 default=66250 value=66250 flags=slider
audio_compression_feature_enabl (bool) : default=1 value=1
audio_compression_gain (int) : min=0 max=20 step=1 default=15 value=15 flags=slider
audio_compression_threshold (int) : min=-40 max=0 step=1 default=-40 value=-40 flags=slider
audio_compression_attack_time (int) : min=0 max=5000 step=500 default=0 value=0 flags=slider
audio_compression_release_time (int) : min=100000 max=1000000 step=100000 default=1000000 value=1000000 flags=slider
pilot_tone_feature_enabled (bool) : default=1 value=1
pilot_tone_deviation (int) : min=0 max=90000 step=10 default=6750 value=6750 flags=slider
pilot_tone_frequency (int) : min=0 max=19000 step=1 default=19000 value=19000 flags=slider
pre_emphasis_settings (menu) : min=0 max=2 default=1 value=1
tune_power_level (int) : min=0 max=120 step=1 default=88 value=88 flags=slider
tune_antenna_capacitor (int) : min=0 max=191 step=1 default=0 value=110 flags=slider
/ #
Here is a summary of them:
* Pilot is an audible tone sent by the device.
pilot_frequency - Configures the frequency of the stereo pilot tone.
pilot_deviation - Configures pilot tone frequency deviation level.
pilot_enabled - Enables or disables the pilot tone feature.
* The si4713 device is capable of applying audio compression to the transmitted signal.
acomp_enabled - Enables or disables the audio dynamic range control feature.
acomp_gain - Sets the gain for audio dynamic range control.
acomp_threshold - Sets the threshold level for audio dynamic range control.
acomp_attack_time - Sets the attack time for audio dynamic range control.
acomp_release_time - Sets the release time for audio dynamic range control.
* Limiter setups audio deviation limiter feature. Once a over deviation occurs,
it is possible to adjust the front-end gain of the audio input and always
prevent over deviation.
limiter_enabled - Enables or disables the limiter feature.
limiter_deviation - Configures audio frequency deviation level.
limiter_release_time - Sets the limiter release time.
* Tuning power
power_level - Sets the output power level for signal transmission.
antenna_capacitor - This selects the value of antenna tuning capacitor manually
or automatically if set to zero.
* RDS related
rds_ps_name - Sets the RDS ps name field for transmission.
rds_radio_text - Sets the RDS radio text for transmission.
rds_pi - Sets the RDS PI field for transmission.
rds_pty - Sets the RDS PTY field for transmission.
* Region related
preemphasis - sets the preemphasis to be applied for transmission.
RNL
===
This device also has an interface to measure received noise level. To do that, you should
ioctl the device node. Here is an code of example:
int main (int argc, char *argv[])
{
struct si4713_rnl rnl;
int fd = open("/dev/radio0", O_RDWR);
int rval;
if (argc < 2)
return -EINVAL;
if (fd < 0)
return fd;
sscanf(argv[1], "%d", &rnl.frequency);
rval = ioctl(fd, SI4713_IOC_MEASURE_RNL, &rnl);
if (rval < 0)
return rval;
printf("received noise level: %d\n", rnl.rnl);
close(fd);
}
The struct si4713_rnl and SI4713_IOC_MEASURE_RNL are defined under
include/media/si4713.h.
Stereo/Mono and RDS subchannels
===============================
The device can also be configured using the available sub channels for
transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
Refer to v4l2-spec for proper use of this ioctl.
Testing
=======
Testing is usually done with v4l2-ctl utility for managing FM tuner cards.
The tool can be found in v4l-dvb repository under v4l2-apps/util directory.
Example for setting rds ps name:
# v4l2-ctl -d /dev/radio0 --set-ctrl=rds_ps_name="Dummy"
......@@ -58,13 +58,24 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
/* -------------------------------------------------------------------------- */
void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
int ir_type, IR_KEYTAB_TYPE *ir_codes)
int ir_type, struct ir_scancode_table *ir_codes)
{
int i;
ir->ir_type = ir_type;
memset(ir->ir_codes, sizeof(ir->ir_codes), 0);
/*
* FIXME: This is a temporary workaround to use the new IR tables
* with the old approach. Later patches will replace this to a
* proper method
*/
if (ir_codes)
memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
for (i = 0; i < ir_codes->size; i++)
if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
dev->keycode = ir->ir_codes;
dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
......
This diff is collapsed.
......@@ -27,7 +27,7 @@ module_param_named(debug, tda18271_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debug level "
"(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
static int tda18271_cal_on_startup;
static int tda18271_cal_on_startup = -1;
module_param_named(cal, tda18271_cal_on_startup, int, 0644);
MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
......@@ -1192,10 +1192,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
case 0:
goto fail;
case 1:
{
/* new tuner instance */
int rf_cal_on_startup;
priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
priv->config = (cfg) ? cfg->config : 0;
/* tda18271_cal_on_startup == -1 when cal
* module option is unset */
if (tda18271_cal_on_startup == -1) {
/* honor attach-time configuration */
rf_cal_on_startup =
((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
} else {
/* module option overrides attach configuration */
rf_cal_on_startup = tda18271_cal_on_startup;
}
priv->cal_initialized = false;
mutex_init(&priv->lock);
......@@ -1213,11 +1228,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
mutex_lock(&priv->lock);
tda18271_init_regs(fe);
if ((tda18271_cal_on_startup) && (priv->id == TDA18271HDC2))
if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2))
tda18271c2_rf_cal_init(fe);
mutex_unlock(&priv->lock);
break;
}
default:
/* existing tuner instance */
fe->tuner_priv = priv;
......
......@@ -137,17 +137,17 @@ extern int tda18271_debug;
#define tda_printk(kern, fmt, arg...) \
printk(kern "%s: " fmt, __func__, ##arg)
#define dprintk(kern, lvl, fmt, arg...) do {\
#define tda_dprintk(lvl, fmt, arg...) do {\
if (tda18271_debug & lvl) \
tda_printk(kern, fmt, ##arg); } while (0)
#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg)
#define tda_dbg(fmt, arg...) dprintk(KERN_DEBUG, DBG_INFO, fmt, ##arg)
#define tda_map(fmt, arg...) dprintk(KERN_DEBUG, DBG_MAP, fmt, ##arg)
#define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg)
#define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg)
tda_printk(KERN_DEBUG, fmt, ##arg); } while (0)
#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg)
#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg)
#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg)
#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg)
#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg)
#define tda_fail(ret) \
({ \
......
......@@ -77,6 +77,9 @@ struct tda18271_config {
/* use i2c gate provided by analog or digital demod */
enum tda18271_i2c_gate gate;
/* force rf tracking filter calibration on startup */
unsigned int rf_cal_on_startup:1;
/* some i2c providers cant write all 39 registers at once */
unsigned int small_i2c:1;
......
......@@ -144,6 +144,8 @@ static inline int tuner_stereo(const int type, const int status)
case TUNER_LG_NTSC_TAPE:
case TUNER_TCL_MF02GIP_5N:
return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
case TUNER_PHILIPS_FM1216MK5:
return status | TUNER_STEREO;
default:
return status & TUNER_STEREO;
}
......@@ -508,6 +510,10 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
case TUNER_TCL_MF02GIP_5N:
buffer[3] = 0x19;
break;
case TUNER_PHILIPS_FM1216MK5:
buffer[2] = 0x88;
buffer[3] = 0x09;
break;
case TUNER_TNF_5335MF:
buffer[3] = 0x11;
break;
......
......@@ -1301,6 +1301,25 @@ static struct tuner_params tuner_fq1216lme_mk3_params[] = {
},
};
/* ----- TUNER_PARTSNIC_PTI_5NF05 - Partsnic (Daewoo) PTI-5NF05 NTSC ----- */
static struct tuner_range tuner_partsnic_pti_5nf05_ranges[] = {
/* The datasheet specified channel ranges and the bandswitch byte */
/* The control byte value of 0x8e is just a guess */
{ 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, /* Channels 2 - B */
{ 16 * 367.25 /*MHz*/, 0x8e, 0x02, }, /* Channels C - W+11 */
{ 16 * 999.99 , 0x8e, 0x08, }, /* Channels W+12 - 69 */
};
static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
{
.type = TUNER_PARAM_TYPE_NTSC,
.ranges = tuner_partsnic_pti_5nf05_ranges,
.count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_ranges),
.cb_first_if_lower_freq = 1, /* not specified but safe to do */
},
};
/* --------------------------------------------------------------------- */
struct tunertype tuners[] = {
......@@ -1753,6 +1772,12 @@ struct tunertype tuners[] = {
.params = tuner_fq1216lme_mk3_params,
.count = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
},
[TUNER_PARTSNIC_PTI_5NF05] = {
.name = "Partsnic (Daewoo) PTI-5NF05",
.params = tuner_partsnic_pti_5nf05_params,
.count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
},
};
EXPORT_SYMBOL(tuners);
......
......@@ -2,6 +2,19 @@
# DVB device configuration
#
config DVB_MAX_ADAPTERS
int "maximum number of DVB/ATSC adapters"
depends on DVB_CORE
default 8
range 1 255
help
Maximum number of DVB/ATSC adapters. Increasing this number
increases the memory consumption of the DVB subsystem even
if a much lower number of DVB/ATSC adapters is present.
Only values in the range 4-32 are tested.
If you are unsure about this, use the default value 8
config DVB_DYNAMIC_MINORS
bool "Dynamic DVB minor allocation"
depends on DVB_CORE
......
......@@ -66,7 +66,7 @@ static int flexcop_sleep(struct dvb_frontend* fe)
#endif
/* SkyStar2 DVB-S rev 2.3 */
#if FE_SUPPORTED(MT312)
#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
......@@ -155,55 +155,34 @@ static struct mt312_config skystar23_samsung_tbdu18132_config = {
.demod_address = 0x0e,
};
static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf,
.len = sizeof(buf) };
struct flexcop_device *fc = fe->dvb->priv;
div = (params->frequency + (125/2)) / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = (div >> 0) & 0xff;
buf[2] = 0x84 | ((div >> 10) & 0x60);
buf[3] = 0x80;
if (params->frequency < 1550000)
buf[3] |= 0x02;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
return -EIO;
return 0;
}
static int skystar2_rev23_attach(struct flexcop_device *fc,
struct i2c_adapter *i2c)
{
struct dvb_frontend_ops *ops;
fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
if (fc->fe != NULL) {
struct dvb_frontend_ops *ops = &fc->fe->ops;
ops->tuner_ops.set_params =
skystar23_samsung_tbdu18132_tuner_set_params;
ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
ops->diseqc_send_burst = flexcop_diseqc_send_burst;
ops->set_tone = flexcop_set_tone;
ops->set_voltage = flexcop_set_voltage;
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
return 1;
}
return 0;
if (!fc->fe)
return 0;
if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
DVB_PLL_SAMSUNG_TBDU18132))
return 0;
ops = &fc->fe->ops;
ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
ops->diseqc_send_burst = flexcop_diseqc_send_burst;
ops->set_tone = flexcop_set_tone;
ops->set_voltage = flexcop_set_voltage;
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
return 1;
}
#else
#define skystar2_rev23_attach NULL
#endif
/* SkyStar2 DVB-S rev 2.6 */
#if FE_SUPPORTED(STV0299)
#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
u32 srate, u32 ratio)
{
......@@ -232,31 +211,6 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
return 0;
}
static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = {
.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
struct flexcop_device *fc = fe->dvb->priv;
div = params->frequency / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
buf[2] = 0x84; /* 0xC4 */
buf[3] = 0x08;
if (params->frequency < 1500000)
buf[3] |= 0x10;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
return -EIO;
return 0;
}
static u8 samsung_tbmu24112_inittab[] = {
0x01, 0x15,
0x02, 0x30,
......@@ -318,15 +272,18 @@ static int skystar2_rev26_attach(struct flexcop_device *fc,
struct i2c_adapter *i2c)
{
fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
if (fc->fe != NULL) {
struct dvb_frontend_ops *ops = &fc->fe->ops;
ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
ops->set_voltage = flexcop_set_voltage;
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
return 1;
}
return 0;
if (!fc->fe)
return 0;
if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
DVB_PLL_SAMSUNG_TBMU24112))
return 0;
fc->fe->ops.set_voltage = flexcop_set_voltage;
fc->fe_sleep = fc->fe->ops.sleep;
fc->fe->ops.sleep = flexcop_sleep;
return 1;
}
#else
#define skystar2_rev26_attach NULL
......@@ -421,7 +378,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
if (!fc->fe)
return 0;
i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);;
i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
if (!i2c_tuner)
return 0;
......@@ -449,7 +406,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
#endif
/* AirStar DVB-T */
#if FE_SUPPORTED(MT352)
#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
{
static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
......@@ -467,32 +424,6 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
return 0;
}
static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
{
u32 div;
unsigned char bs = 0;
if (buf_len < 5)
return -EINVAL;
#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
if (params->frequency >= 48000000 && params->frequency <= 154000000) \
bs = 0x09;
if (params->frequency >= 161000000 && params->frequency <= 439000000) \
bs = 0x0a;
if (params->frequency >= 447000000 && params->frequency <= 863000000) \
bs = 0x08;
pllbuf[0] = 0x61;
pllbuf[1] = div >> 8;
pllbuf[2] = div & 0xff;
pllbuf[3] = 0xcc;
pllbuf[4] = bs;
return 5;
}
static struct mt352_config samsung_tdtc9251dh0_config = {
.demod_address = 0x0f,
.demod_init = samsung_tdtc9251dh0_demod_init,
......@@ -502,11 +433,11 @@ static int airstar_dvbt_attach(struct flexcop_device *fc,
struct i2c_adapter *i2c)
{
fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
if (fc->fe != NULL) {
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
return 1;
}
return 0;
if (!fc->fe)
return 0;
return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
DVB_PLL_SAMSUNG_TDTC9251DH0);
}
#else
#define airstar_dvbt_attach NULL
......@@ -580,54 +511,7 @@ static int airstar_atsc3_attach(struct flexcop_device *fc,
#endif
/* CableStar2 DVB-C */
#if FE_SUPPORTED(STV0297)
static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep)
{
struct flexcop_device *fc = fe->dvb->priv;
u8 buf[4];
u16 div;
int ret;
/* 62.5 kHz * 10 */
#define REF_FREQ 625
#define FREQ_OFFSET 36125
div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ;
/* 4 MHz = 4000 KHz */
buf[0] = (u8)( div >> 8) & 0x7f;
buf[1] = (u8) div & 0xff;
/* F(osc) = N * Reference Freq. (62.5 kHz)
* byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
* byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
* byte 4 : 1 * * AGD R3 R2 R1 R0
* byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
* AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
buf[2] = 0x95;
/* Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
* 47 - 153 0 * 0 0 0 0 0 1 0x01
* 153 - 430 0 * 0 0 0 0 1 0 0x02
* 430 - 822 0 * 0 0 1 0 0 0 0x08
* 822 - 862 1 * 0 0 1 0 0 0 0x88 */
if (fep->frequency <= 153000000) buf[3] = 0x01;
else if (fep->frequency <= 430000000) buf[3] = 0x02;
else if (fep->frequency <= 822000000) buf[3] = 0x08;
else buf[3] = 0x88;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency,
buf[0], buf[1], buf[2], buf[3]);
ret = fc->i2c_request(&fc->fc_i2c_adap[2],
FC_WRITE, 0x61, buf[0], &buf[1], 3);
deb_tuner("tuner write returned: %d\n",ret);
return ret;
}
#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
static u8 alps_tdee4_stv0297_inittab[] = {
0x80, 0x01,
0x80, 0x00,
......@@ -711,13 +595,25 @@ static int cablestar2_attach(struct flexcop_device *fc,
{
fc->fc_i2c_adap[0].no_base_addr = 1;
fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
if (!fc->fe) {
/* Reset for next frontend to try */
fc->fc_i2c_adap[0].no_base_addr = 0;
return 0;
}
fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
if (!fc->fe)
goto fail;
/* This tuner doesn't use the stv0297's I2C gate, but instead the
* tuner is connected to a different flexcop I2C adapter. */
if (fc->fe->ops.i2c_gate_ctrl)
fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
fc->fe->ops.i2c_gate_ctrl = NULL;
if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
&fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
goto fail;
return 1;
fail:
/* Reset for next frontend to try */
fc->fc_i2c_adap[0].no_base_addr = 0;
return 0;
}
#else
#define cablestar2_attach NULL
......
......@@ -1059,7 +1059,7 @@ static int dst_get_tuner_info(struct dst_state *state)
dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
}
if (state->board_info[0] == 0xbc) {
if (state->type_flags != DST_TYPE_IS_ATSC)
if (state->dst_type != DST_TYPE_IS_ATSC)
state->type_flags |= DST_TYPE_HAS_TS188;
else
state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
......
......@@ -44,6 +44,14 @@
#include "cx24116.h"
#include "z0194a.h"
#define UNSET (-1U)
#define DM1105_BOARD_NOAUTO UNSET
#define DM1105_BOARD_UNKNOWN 0
#define DM1105_BOARD_DVBWORLD_2002 1
#define DM1105_BOARD_DVBWORLD_2004 2
#define DM1105_BOARD_AXESS_DM05 3
/* ----------------------------------------------- */
/*
* PCI ID's
......@@ -153,20 +161,105 @@
/* GPIO's for LNB power control */
#define DM1105_LNB_MASK 0x00000000
#define DM1105_LNB_OFF 0x00020000
#define DM1105_LNB_13V 0x00010100
#define DM1105_LNB_18V 0x00000100
/* GPIO's for LNB power control for Axess DM05 */
#define DM05_LNB_MASK 0x00000000
#define DM05_LNB_OFF 0x00020000/* actually 13v */
#define DM05_LNB_13V 0x00020000
#define DM05_LNB_18V 0x00030000
static unsigned int card[] = {[0 ... 3] = UNSET };
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(card, "card type");
static int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
static unsigned int dm1105_devcount;
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct dm1105_board {
char *name;
};
struct dm1105_subid {
u16 subvendor;
u16 subdevice;
u32 card;
};
static const struct dm1105_board dm1105_boards[] = {
[DM1105_BOARD_UNKNOWN] = {
.name = "UNKNOWN/GENERIC",
},
[DM1105_BOARD_DVBWORLD_2002] = {
.name = "DVBWorld PCI 2002",
},
[DM1105_BOARD_DVBWORLD_2004] = {
.name = "DVBWorld PCI 2004",
},
[DM1105_BOARD_AXESS_DM05] = {
.name = "Axess/EasyTv DM05",
},
};
static const struct dm1105_subid dm1105_subids[] = {
{
.subvendor = 0x0000,
.subdevice = 0x2002,
.card = DM1105_BOARD_DVBWORLD_2002,
}, {
.subvendor = 0x0001,
.subdevice = 0x2002,
.card = DM1105_BOARD_DVBWORLD_2002,
}, {
.subvendor = 0x0000,
.subdevice = 0x2004,
.card = DM1105_BOARD_DVBWORLD_2004,
}, {
.subvendor = 0x0001,
.subdevice = 0x2004,
.card = DM1105_BOARD_DVBWORLD_2004,
}, {
.subvendor = 0x195d,
.subdevice = 0x1105,
.card = DM1105_BOARD_AXESS_DM05,
},
};
static void dm1105_card_list(struct pci_dev *pci)
{
int i;
if (0 == pci->subsystem_vendor &&
0 == pci->subsystem_device) {
printk(KERN_ERR
"dm1105: Your board has no valid PCI Subsystem ID\n"
"dm1105: and thus can't be autodetected\n"
"dm1105: Please pass card=<n> insmod option to\n"
"dm1105: workaround that. Redirect complaints to\n"
"dm1105: the vendor of the TV card. Best regards,\n"
"dm1105: -- tux\n");
} else {
printk(KERN_ERR
"dm1105: Your board isn't known (yet) to the driver.\n"
"dm1105: You can try to pick one of the existing\n"
"dm1105: card configs via card=<n> insmod option.\n"
"dm1105: Updating to the latest version might help\n"
"dm1105: as well.\n");
}
printk(KERN_ERR "Here is a list of valid choices for the card=<n> "
"insmod option:\n");
for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++)
printk(KERN_ERR "dm1105: card=%d -> %s\n",
i, dm1105_boards[i].name);
}
/* infrared remote control */
struct infrared {
struct input_dev *input_dev;
......@@ -193,6 +286,8 @@ struct dm1105dvb {
struct dvb_frontend *fe;
struct dvb_net dvbnet;
unsigned int full_ts_users;
unsigned int boardnr;
int nr;
/* i2c */
struct i2c_adapter i2c_adap;
......@@ -211,7 +306,6 @@ struct dm1105dvb {
unsigned int PacketErrorCount;
unsigned int dmarst;
spinlock_t lock;
};
#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg]))
......@@ -326,16 +420,20 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe)
static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe);
u32 lnb_mask, lnb_13v, lnb_18v;
u32 lnb_mask, lnb_13v, lnb_18v, lnb_off;
switch (dm1105dvb->pdev->subsystem_device) {
case PCI_DEVICE_ID_DM05:
switch (dm1105dvb->boardnr) {
case DM1105_BOARD_AXESS_DM05:
lnb_mask = DM05_LNB_MASK;
lnb_off = DM05_LNB_OFF;
lnb_13v = DM05_LNB_13V;
lnb_18v = DM05_LNB_18V;
break;
case DM1105_BOARD_DVBWORLD_2002:
case DM1105_BOARD_DVBWORLD_2004:
default:
lnb_mask = DM1105_LNB_MASK;
lnb_off = DM1105_LNB_OFF;
lnb_13v = DM1105_LNB_13V;
lnb_18v = DM1105_LNB_18V;
}
......@@ -343,8 +441,10 @@ static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volta
outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR));
if (voltage == SEC_VOLTAGE_18)
outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL));
else
else if (voltage == SEC_VOLTAGE_13)
outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL));
else
outl(lnb_off, dm_io_mem(DM1105_GPIOVAL));
return 0;
}
......@@ -477,7 +577,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
{
struct input_dev *input_dev;
IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec;
struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table;
int ir_type = IR_TYPE_OTHER;
int err = -ENOMEM;
......@@ -589,8 +689,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
{
int ret;
switch (dm1105dvb->pdev->subsystem_device) {
case PCI_DEVICE_ID_DW2004:
switch (dm1105dvb->boardnr) {
case DM1105_BOARD_DVBWORLD_2004:
dm1105dvb->fe = dvb_attach(
cx24116_attach, &serit_sp2633_config,
&dm1105dvb->i2c_adap);
......@@ -598,6 +698,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;
break;
case DM1105_BOARD_DVBWORLD_2002:
case DM1105_BOARD_AXESS_DM05:
default:
dm1105dvb->fe = dvb_attach(
stv0299_attach, &sharp_z0194a_config,
......@@ -676,11 +778,31 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
struct dvb_demux *dvbdemux;
struct dmx_demux *dmx;
int ret = -ENOMEM;
int i;
dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
if (!dm1105dvb)
return -ENOMEM;
/* board config */
dm1105dvb->nr = dm1105_devcount;
dm1105dvb->boardnr = UNSET;
if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards))
dm1105dvb->boardnr = card[dm1105dvb->nr];
for (i = 0; UNSET == dm1105dvb->boardnr &&
i < ARRAY_SIZE(dm1105_subids); i++)
if (pdev->subsystem_vendor ==
dm1105_subids[i].subvendor &&
pdev->subsystem_device ==
dm1105_subids[i].subdevice)
dm1105dvb->boardnr = dm1105_subids[i].card;
if (UNSET == dm1105dvb->boardnr) {
dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN;
dm1105_card_list(pdev);
}
dm1105_devcount++;
dm1105dvb->pdev = pdev;
dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
dm1105dvb->PacketErrorCount = 0;
......@@ -853,6 +975,7 @@ static void __devexit dm1105_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
dm1105_devcount--;
kfree(dm1105dvb);
}
......@@ -861,17 +984,12 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = {
.vendor = PCI_VENDOR_ID_TRIGEM,
.device = PCI_DEVICE_ID_DM1105,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_DEVICE_ID_DW2002,
}, {
.vendor = PCI_VENDOR_ID_TRIGEM,
.device = PCI_DEVICE_ID_DM1105,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_DEVICE_ID_DW2004,
.subdevice = PCI_ANY_ID,
}, {
.vendor = PCI_VENDOR_ID_AXESS,
.device = PCI_DEVICE_ID_DM05,
.subvendor = PCI_VENDOR_ID_AXESS,
.subdevice = PCI_DEVICE_ID_DM05,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, {
/* empty */
},
......
......@@ -430,6 +430,8 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
/* stop feed but only mark the specified filter as stopped (state set) */
static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
{
struct dmxdev_feed *feed;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
switch (dmxdevfilter->type) {
......@@ -438,7 +440,8 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
break;
case DMXDEV_TYPE_PES:
dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts);
list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
feed->ts->stop_filtering(feed->ts);
break;
default:
return -EINVAL;
......@@ -449,13 +452,23 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
/* start feed associated with the specified filter */
static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
{
struct dmxdev_feed *feed;
int ret;
dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
switch (filter->type) {
case DMXDEV_TYPE_SEC:
return filter->feed.sec->start_filtering(filter->feed.sec);
case DMXDEV_TYPE_PES:
return filter->feed.ts->start_filtering(filter->feed.ts);
list_for_each_entry(feed, &filter->feed.ts, next) {
ret = feed->ts->start_filtering(feed->ts);
if (ret < 0) {
dvb_dmxdev_feed_stop(filter);
return ret;
}
}
break;
default:
return -EINVAL;
}
......@@ -487,6 +500,9 @@ static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
{
struct dmxdev_feed *feed;
struct dmx_demux *demux;
if (dmxdevfilter->state < DMXDEV_STATE_GO)
return 0;
......@@ -503,13 +519,12 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
dmxdevfilter->feed.sec = NULL;
break;
case DMXDEV_TYPE_PES:
if (!dmxdevfilter->feed.ts)
break;
dvb_dmxdev_feed_stop(dmxdevfilter);
dmxdevfilter->dev->demux->
release_ts_feed(dmxdevfilter->dev->demux,
dmxdevfilter->feed.ts);
dmxdevfilter->feed.ts = NULL;
demux = dmxdevfilter->dev->demux;
list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
demux->release_ts_feed(demux, feed->ts);
feed->ts = NULL;
}
break;
default:
if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
......@@ -521,19 +536,88 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
return 0;
}
static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)
{
struct dmxdev_feed *feed, *tmp;
/* delete all PIDs */
list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {
list_del(&feed->next);
kfree(feed);
}
BUG_ON(!list_empty(&dmxdevfilter->feed.ts));
}
static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
{
if (dmxdevfilter->state < DMXDEV_STATE_SET)
return 0;
if (dmxdevfilter->type == DMXDEV_TYPE_PES)
dvb_dmxdev_delete_pids(dmxdevfilter);
dmxdevfilter->type = DMXDEV_TYPE_NONE;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
return 0;
}
static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
struct dmxdev_filter *filter,
struct dmxdev_feed *feed)
{
struct timespec timeout = { 0 };
struct dmx_pes_filter_params *para = &filter->params.pes;
dmx_output_t otype;
int ret;
int ts_type;
enum dmx_ts_pes ts_pes;
struct dmx_ts_feed *tsfeed;
feed->ts = NULL;
otype = para->output;
ts_pes = (enum dmx_ts_pes)para->pes_type;
if (ts_pes < DMX_PES_OTHER)
ts_type = TS_DECODER;
else
ts_type = 0;
if (otype == DMX_OUT_TS_TAP)
ts_type |= TS_PACKET;
else if (otype == DMX_OUT_TSDEMUX_TAP)
ts_type |= TS_PACKET | TS_DEMUX;
else if (otype == DMX_OUT_TAP)
ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,
dvb_dmxdev_ts_callback);
if (ret < 0)
return ret;
tsfeed = feed->ts;
tsfeed->priv = filter;
ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
if (ret < 0) {
dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
return ret;
}
ret = tsfeed->start_filtering(tsfeed);
if (ret < 0) {
dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
return ret;
}
return 0;
}
static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
{
struct dmxdev *dmxdev = filter->dev;
struct dmxdev_feed *feed;
void *mem;
int ret, i;
......@@ -631,56 +715,14 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
break;
}
case DMXDEV_TYPE_PES:
{
struct timespec timeout = { 0 };
struct dmx_pes_filter_params *para = &filter->params.pes;
dmx_output_t otype;
int ts_type;
enum dmx_ts_pes ts_pes;
struct dmx_ts_feed **tsfeed = &filter->feed.ts;
filter->feed.ts = NULL;
otype = para->output;
ts_pes = (enum dmx_ts_pes)para->pes_type;
if (ts_pes < DMX_PES_OTHER)
ts_type = TS_DECODER;
else
ts_type = 0;
if (otype == DMX_OUT_TS_TAP)
ts_type |= TS_PACKET;
else if (otype == DMX_OUT_TSDEMUX_TAP)
ts_type |= TS_PACKET | TS_DEMUX;
else if (otype == DMX_OUT_TAP)
ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
tsfeed,
dvb_dmxdev_ts_callback);
if (ret < 0)
return ret;
(*tsfeed)->priv = filter;
ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
32768, timeout);
if (ret < 0) {
dmxdev->demux->release_ts_feed(dmxdev->demux,
*tsfeed);
return ret;
}
ret = filter->feed.ts->start_filtering(filter->feed.ts);
if (ret < 0) {
dmxdev->demux->release_ts_feed(dmxdev->demux,
*tsfeed);
return ret;
list_for_each_entry(feed, &filter->feed.ts, next) {
ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
if (ret < 0) {
dvb_dmxdev_filter_stop(filter);
return ret;
}
}
break;
}
default:
return -EINVAL;
}
......@@ -718,7 +760,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
dmxdevfilter->type = DMXDEV_TYPE_NONE;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
dmxdevfilter->feed.ts = NULL;
INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
init_timer(&dmxdevfilter->timer);
dvbdev->users++;
......@@ -760,6 +802,55 @@ static inline void invert_mode(dmx_filter_t *filter)
filter->mode[i] ^= 0xff;
}
static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
struct dmxdev_filter *filter, u16 pid)
{
struct dmxdev_feed *feed;
if ((filter->type != DMXDEV_TYPE_PES) ||
(filter->state < DMXDEV_STATE_SET))
return -EINVAL;
/* only TS packet filters may have multiple PIDs */
if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&
(!list_empty(&filter->feed.ts)))
return -EINVAL;
feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
if (feed == NULL)
return -ENOMEM;
feed->pid = pid;
list_add(&feed->next, &filter->feed.ts);
if (filter->state >= DMXDEV_STATE_GO)
return dvb_dmxdev_start_feed(dmxdev, filter, feed);
return 0;
}
static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,
struct dmxdev_filter *filter, u16 pid)
{
struct dmxdev_feed *feed, *tmp;
if ((filter->type != DMXDEV_TYPE_PES) ||
(filter->state < DMXDEV_STATE_SET))
return -EINVAL;
list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
if ((feed->pid == pid) && (feed->ts != NULL)) {
feed->ts->stop_filtering(feed->ts);
filter->dev->demux->release_ts_feed(filter->dev->demux,
feed->ts);
list_del(&feed->next);
kfree(feed);
}
}
return 0;
}
static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
struct dmxdev_filter *dmxdevfilter,
struct dmx_sct_filter_params *params)
......@@ -784,7 +875,10 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
struct dmxdev_filter *dmxdevfilter,
struct dmx_pes_filter_params *params)
{
int ret;
dvb_dmxdev_filter_stop(dmxdevfilter);
dvb_dmxdev_filter_reset(dmxdevfilter);
if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
return -EINVAL;
......@@ -795,6 +889,11 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,
dmxdevfilter->params.pes.pid);
if (ret < 0)
return ret;
if (params->flags & DMX_IMMEDIATE_START)
return dvb_dmxdev_filter_start(dmxdevfilter);
......@@ -958,6 +1057,24 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
&((struct dmx_stc *)parg)->base);
break;
case DMX_ADD_PID:
if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
ret = -ERESTARTSYS;
break;
}
ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
mutex_unlock(&dmxdevfilter->mutex);
break;
case DMX_REMOVE_PID:
if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
ret = -ERESTARTSYS;
break;
}
ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
mutex_unlock(&dmxdevfilter->mutex);
break;
default:
ret = -EINVAL;
break;
......
......@@ -53,13 +53,20 @@ enum dmxdev_state {
DMXDEV_STATE_TIMEDOUT
};
struct dmxdev_feed {
u16 pid;
struct dmx_ts_feed *ts;
struct list_head next;
};
struct dmxdev_filter {
union {
struct dmx_section_filter *sec;
} filter;
union {
struct dmx_ts_feed *ts;
/* list of TS and PES feeds (struct dmxdev_feed) */
struct list_head ts;
struct dmx_section_feed *sec;
} feed;
......
......@@ -425,13 +425,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
if ((DVR_FEED(feed)) && (dvr_done++))
continue;
if (feed->pid == pid) {
if (feed->pid == pid)
dvb_dmx_swfilter_packet_type(feed, buf);
if (DVR_FEED(feed))
continue;
}
if (feed->pid == 0x2000)
else if (feed->pid == 0x2000)
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
}
}
......
......@@ -72,6 +72,7 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
#define FESTATE_ZIGZAG_FAST 32
#define FESTATE_ZIGZAG_SLOW 64
#define FESTATE_DISEQC 128
#define FESTATE_ERROR 256
#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
......@@ -269,6 +270,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
{
int autoinversion;
int ready = 0;
int fe_set_err = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
int original_inversion = fepriv->parameters.inversion;
u32 original_frequency = fepriv->parameters.frequency;
......@@ -345,7 +347,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
if (autoinversion)
fepriv->parameters.inversion = fepriv->inversion;
if (fe->ops.set_frontend)
fe->ops.set_frontend(fe, &fepriv->parameters);
fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
if (fe_set_err < 0) {
fepriv->state = FESTATE_ERROR;
return fe_set_err;
}
fepriv->parameters.frequency = original_frequency;
fepriv->parameters.inversion = original_inversion;
......@@ -357,6 +363,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
{
fe_status_t s = 0;
int retval = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
/* if we've got no parameters, just keep idling */
......@@ -370,8 +377,12 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
if (fepriv->state & FESTATE_RETUNE) {
if (fe->ops.set_frontend)
fe->ops.set_frontend(fe, &fepriv->parameters);
fepriv->state = FESTATE_TUNED;
retval = fe->ops.set_frontend(fe,
&fepriv->parameters);
if (retval < 0)
fepriv->state = FESTATE_ERROR;
else
fepriv->state = FESTATE_TUNED;
}
fepriv->delay = 3*HZ;
fepriv->quality = 0;
......@@ -449,7 +460,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
fepriv->delay = fepriv->min_delay;
/* peform a tune */
if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
retval = dvb_frontend_swzigzag_autotune(fe,
fepriv->check_wrapped);
if (retval < 0) {
return;
} else if (retval) {
/* OK, if we've run out of trials at the fast speed.
* Drop back to slow for the _next_ attempt */
fepriv->state = FESTATE_SEARCHING_SLOW;
......@@ -823,6 +838,15 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
}
}
/* check for supported modulation */
if (fe->ops.info.type == FE_QAM &&
(parms->u.qam.modulation > QAM_AUTO ||
!((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) {
printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n",
fe->dvb->num, fe->id, parms->u.qam.modulation);
return -EINVAL;
}
return 0;
}
......@@ -1499,7 +1523,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
/* if retune was requested but hasn't occured yet, prevent
* that user get signal state from previous tuning */
if(fepriv->state == FESTATE_RETUNE) {
if (fepriv->state == FESTATE_RETUNE ||
fepriv->state == FESTATE_ERROR) {
err=0;
*status = 0;
break;
......
......@@ -30,7 +30,12 @@
#define DVB_MAJOR 212
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
#else
#warning invalid CONFIG_DVB_MAX_ADAPTERS value
#define DVB_MAX_ADAPTERS 8
#endif
#define DVB_UNSET (-1)
......
......@@ -253,7 +253,7 @@ config DVB_USB_AF9005_REMOTE
Afatech AF9005 based receiver.
config DVB_USB_DW2102
tristate "DvbWorld DVB-S/S2 USB2.0 support"
tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
......@@ -262,9 +262,11 @@ config DVB_USB_DW2102
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_MT312 if !DVB_FE_CUSTOMISE
select DVB_ZL10039 if !DVB_FE_CUSTOMISE
help
Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
and the TeVii S650.
and the TeVii S650, S630.
config DVB_USB_CINERGY_T2
tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
......
......@@ -38,41 +38,41 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
}
static struct dvb_usb_rc_key a800_rc_keys[] = {
{ 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
{ 0x02, 0x00, KEY_POWER }, /* POWER */
{ 0x02, 0x05, KEY_1 }, /* 1 */
{ 0x02, 0x06, KEY_2 }, /* 2 */
{ 0x02, 0x07, KEY_3 }, /* 3 */
{ 0x02, 0x09, KEY_4 }, /* 4 */
{ 0x02, 0x0a, KEY_5 }, /* 5 */
{ 0x02, 0x0b, KEY_6 }, /* 6 */
{ 0x02, 0x0d, KEY_7 }, /* 7 */
{ 0x02, 0x0e, KEY_8 }, /* 8 */
{ 0x02, 0x0f, KEY_9 }, /* 9 */
{ 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */
{ 0x02, 0x11, KEY_0 }, /* 0 */
{ 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
{ 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
{ 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
{ 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
{ 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
{ 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
{ 0x02, 0x14, KEY_MUTE }, /* MUTE */
{ 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
{ 0x02, 0x19, KEY_RECORD }, /* RECORD */
{ 0x02, 0x18, KEY_PLAY }, /* PLAY */
{ 0x02, 0x1b, KEY_STOP }, /* STOP */
{ 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
{ 0x02, 0x1d, KEY_BACK }, /* << / RED */
{ 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
{ 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
{ 0x02, 0x04, KEY_EPG }, /* EPG */
{ 0x02, 0x15, KEY_MENU }, /* MENU */
{ 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */
{ 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
{ 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */
{ 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */
{ 0x0201, KEY_PROG1 }, /* SOURCE */
{ 0x0200, KEY_POWER }, /* POWER */
{ 0x0205, KEY_1 }, /* 1 */
{ 0x0206, KEY_2 }, /* 2 */
{ 0x0207, KEY_3 }, /* 3 */
{ 0x0209, KEY_4 }, /* 4 */
{ 0x020a, KEY_5 }, /* 5 */
{ 0x020b, KEY_6 }, /* 6 */
{ 0x020d, KEY_7 }, /* 7 */
{ 0x020e, KEY_8 }, /* 8 */
{ 0x020f, KEY_9 }, /* 9 */
{ 0x0212, KEY_LEFT }, /* L / DISPLAY */
{ 0x0211, KEY_0 }, /* 0 */
{ 0x0213, KEY_RIGHT }, /* R / CH RTN */
{ 0x0217, KEY_PROG2 }, /* SNAP SHOT */
{ 0x0210, KEY_PROG3 }, /* 16-CH PREV */
{ 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
{ 0x020c, KEY_ZOOM }, /* FULL SCREEN */
{ 0x021f, KEY_VOLUMEUP }, /* VOL UP */
{ 0x0214, KEY_MUTE }, /* MUTE */
{ 0x0208, KEY_AUDIO }, /* AUDIO */
{ 0x0219, KEY_RECORD }, /* RECORD */
{ 0x0218, KEY_PLAY }, /* PLAY */
{ 0x021b, KEY_STOP }, /* STOP */
{ 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
{ 0x021d, KEY_BACK }, /* << / RED */
{ 0x021c, KEY_FORWARD }, /* >> / YELLOW */
{ 0x0203, KEY_TEXT }, /* TELETEXT */
{ 0x0204, KEY_EPG }, /* EPG */
{ 0x0215, KEY_MENU }, /* MENU */
{ 0x0303, KEY_CHANNELUP }, /* CH UP */
{ 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
{ 0x0301, KEY_FIRST }, /* |<< / GREEN */
{ 0x0300, KEY_LAST }, /* >>| / BLUE */
};
......
......@@ -35,43 +35,43 @@ MODULE_PARM_DESC(debug,
struct dvb_usb_rc_key af9005_rc_keys[] = {
{0x01, 0xb7, KEY_POWER},
{0x01, 0xa7, KEY_VOLUMEUP},
{0x01, 0x87, KEY_CHANNELUP},
{0x01, 0x7f, KEY_MUTE},
{0x01, 0xbf, KEY_VOLUMEDOWN},
{0x01, 0x3f, KEY_CHANNELDOWN},
{0x01, 0xdf, KEY_1},
{0x01, 0x5f, KEY_2},
{0x01, 0x9f, KEY_3},
{0x01, 0x1f, KEY_4},
{0x01, 0xef, KEY_5},
{0x01, 0x6f, KEY_6},
{0x01, 0xaf, KEY_7},
{0x01, 0x27, KEY_8},
{0x01, 0x07, KEY_9},
{0x01, 0xcf, KEY_ZOOM},
{0x01, 0x4f, KEY_0},
{0x01, 0x8f, KEY_GOTO}, /* marked jump on the remote */
{0x01b7, KEY_POWER},
{0x01a7, KEY_VOLUMEUP},
{0x0187, KEY_CHANNELUP},
{0x017f, KEY_MUTE},
{0x01bf, KEY_VOLUMEDOWN},
{0x013f, KEY_CHANNELDOWN},
{0x01df, KEY_1},
{0x015f, KEY_2},
{0x019f, KEY_3},
{0x011f, KEY_4},
{0x01ef, KEY_5},
{0x016f, KEY_6},
{0x01af, KEY_7},
{0x0127, KEY_8},
{0x0107, KEY_9},
{0x01cf, KEY_ZOOM},
{0x014f, KEY_0},
{0x018f, KEY_GOTO}, /* marked jump on the remote */
{0x00, 0xbd, KEY_POWER},
{0x00, 0x7d, KEY_VOLUMEUP},
{0x00, 0xfd, KEY_CHANNELUP},
{0x00, 0x9d, KEY_MUTE},
{0x00, 0x5d, KEY_VOLUMEDOWN},
{0x00, 0xdd, KEY_CHANNELDOWN},
{0x00, 0xad, KEY_1},
{0x00, 0x6d, KEY_2},
{0x00, 0xed, KEY_3},
{0x00, 0x8d, KEY_4},
{0x00, 0x4d, KEY_5},
{0x00, 0xcd, KEY_6},
{0x00, 0xb5, KEY_7},
{0x00, 0x75, KEY_8},
{0x00, 0xf5, KEY_9},
{0x00, 0x95, KEY_ZOOM},
{0x00, 0x55, KEY_0},
{0x00, 0xd5, KEY_GOTO}, /* marked jump on the remote */
{0x00bd, KEY_POWER},
{0x007d, KEY_VOLUMEUP},
{0x00fd, KEY_CHANNELUP},
{0x009d, KEY_MUTE},
{0x005d, KEY_VOLUMEDOWN},
{0x00dd, KEY_CHANNELDOWN},
{0x00ad, KEY_1},
{0x006d, KEY_2},
{0x00ed, KEY_3},
{0x008d, KEY_4},
{0x004d, KEY_5},
{0x00cd, KEY_6},
{0x00b5, KEY_7},
{0x0075, KEY_8},
{0x00f5, KEY_9},
{0x0095, KEY_ZOOM},
{0x0055, KEY_0},
{0x00d5, KEY_GOTO}, /* marked jump on the remote */
};
int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys);
......@@ -131,8 +131,8 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
return 0;
}
for (i = 0; i < af9005_rc_keys_size; i++) {
if (af9005_rc_keys[i].custom == cust
&& af9005_rc_keys[i].data == dat) {
if (rc5_custom(&af9005_rc_keys[i]) == cust
&& rc5_data(&af9005_rc_keys[i]) == dat) {
*event = af9005_rc_keys[i].event;
*state = REMOTE_KEY_PRESSED;
deb_decode
......
......@@ -538,24 +538,22 @@ static int af9015_copy_firmware(struct dvb_usb_device *d)
/* dump eeprom */
static int af9015_eeprom_dump(struct dvb_usb_device *d)
{
char buf[4+3*16+1], buf2[4];
u8 reg, val;
for (reg = 0; ; reg++) {
if (reg % 16 == 0) {
if (reg)
deb_info("%s\n", buf);
sprintf(buf, "%02x: ", reg);
deb_info(KERN_CONT "\n");
deb_info(KERN_DEBUG "%02x:", reg);
}
if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0)
sprintf(buf2, "%02x ", val);
deb_info(KERN_CONT " %02x", val);
else
strcpy(buf2, "-- ");
strcat(buf, buf2);
deb_info(KERN_CONT " --");
if (reg == 0xff)
break;
}
deb_info("%s\n", buf);
deb_info(KERN_CONT "\n");
return 0;
}
......@@ -1045,8 +1043,8 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*state = REMOTE_NO_KEY_PRESSED;
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (!buf[1] && keymap[i].custom == buf[0] &&
keymap[i].data == buf[2]) {
if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] &&
rc5_data(&keymap[i]) == buf[2]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
break;
......@@ -1266,6 +1264,7 @@ static struct usb_device_id af9015_usb_table[] = {
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
{USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
......@@ -1346,7 +1345,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
{
.name = "KWorld PlusTV Dual DVB-T Stick " \
"(DVB-T 399U)",
.cold_ids = {&af9015_usb_table[4], NULL},
.cold_ids = {&af9015_usb_table[4],
&af9015_usb_table[25], NULL},
.warm_ids = {NULL},
},
{
......
This diff is collapsed.
......@@ -389,8 +389,8 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*state = REMOTE_NO_KEY_PRESSED;
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (keymap[i].custom == ircode[0] &&
keymap[i].data == ircode[1]) {
if (rc5_custom(&keymap[i]) == ircode[0] &&
rc5_data(&keymap[i]) == ircode[1]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
return 0;
......@@ -400,50 +400,50 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
}
static struct dvb_usb_rc_key anysee_rc_keys[] = {
{ 0x01, 0x00, KEY_0 },
{ 0x01, 0x01, KEY_1 },
{ 0x01, 0x02, KEY_2 },
{ 0x01, 0x03, KEY_3 },
{ 0x01, 0x04, KEY_4 },
{ 0x01, 0x05, KEY_5 },
{ 0x01, 0x06, KEY_6 },
{ 0x01, 0x07, KEY_7 },
{ 0x01, 0x08, KEY_8 },
{ 0x01, 0x09, KEY_9 },
{ 0x01, 0x0a, KEY_POWER },
{ 0x01, 0x0b, KEY_DOCUMENTS }, /* * */
{ 0x01, 0x19, KEY_FAVORITES },
{ 0x01, 0x20, KEY_SLEEP },
{ 0x01, 0x21, KEY_MODE }, /* 4:3 / 16:9 select */
{ 0x01, 0x22, KEY_ZOOM },
{ 0x01, 0x47, KEY_TEXT },
{ 0x01, 0x16, KEY_TV }, /* TV / radio select */
{ 0x01, 0x1e, KEY_LANGUAGE }, /* Second Audio Program */
{ 0x01, 0x1a, KEY_SUBTITLE },
{ 0x01, 0x1b, KEY_CAMERA }, /* screenshot */
{ 0x01, 0x42, KEY_MUTE },
{ 0x01, 0x0e, KEY_MENU },
{ 0x01, 0x0f, KEY_EPG },
{ 0x01, 0x17, KEY_INFO },
{ 0x01, 0x10, KEY_EXIT },
{ 0x01, 0x13, KEY_VOLUMEUP },
{ 0x01, 0x12, KEY_VOLUMEDOWN },
{ 0x01, 0x11, KEY_CHANNELUP },
{ 0x01, 0x14, KEY_CHANNELDOWN },
{ 0x01, 0x15, KEY_OK },
{ 0x01, 0x1d, KEY_RED },
{ 0x01, 0x1f, KEY_GREEN },
{ 0x01, 0x1c, KEY_YELLOW },
{ 0x01, 0x44, KEY_BLUE },
{ 0x01, 0x0c, KEY_SHUFFLE }, /* snapshot */
{ 0x01, 0x48, KEY_STOP },
{ 0x01, 0x50, KEY_PLAY },
{ 0x01, 0x51, KEY_PAUSE },
{ 0x01, 0x49, KEY_RECORD },
{ 0x01, 0x18, KEY_PREVIOUS }, /* |<< */
{ 0x01, 0x0d, KEY_NEXT }, /* >>| */
{ 0x01, 0x24, KEY_PROG1 }, /* F1 */
{ 0x01, 0x25, KEY_PROG2 }, /* F2 */
{ 0x0100, KEY_0 },
{ 0x0101, KEY_1 },
{ 0x0102, KEY_2 },
{ 0x0103, KEY_3 },
{ 0x0104, KEY_4 },
{ 0x0105, KEY_5 },
{ 0x0106, KEY_6 },
{ 0x0107, KEY_7 },
{ 0x0108, KEY_8 },
{ 0x0109, KEY_9 },
{ 0x010a, KEY_POWER },
{ 0x010b, KEY_DOCUMENTS }, /* * */
{ 0x0119, KEY_FAVORITES },
{ 0x0120, KEY_SLEEP },
{ 0x0121, KEY_MODE }, /* 4:3 / 16:9 select */
{ 0x0122, KEY_ZOOM },
{ 0x0147, KEY_TEXT },
{ 0x0116, KEY_TV }, /* TV / radio select */
{ 0x011e, KEY_LANGUAGE }, /* Second Audio Program */
{ 0x011a, KEY_SUBTITLE },
{ 0x011b, KEY_CAMERA }, /* screenshot */
{ 0x0142, KEY_MUTE },
{ 0x010e, KEY_MENU },
{ 0x010f, KEY_EPG },
{ 0x0117, KEY_INFO },
{ 0x0110, KEY_EXIT },
{ 0x0113, KEY_VOLUMEUP },
{ 0x0112, KEY_VOLUMEDOWN },
{ 0x0111, KEY_CHANNELUP },
{ 0x0114, KEY_CHANNELDOWN },
{ 0x0115, KEY_OK },
{ 0x011d, KEY_RED },
{ 0x011f, KEY_GREEN },
{ 0x011c, KEY_YELLOW },
{ 0x0144, KEY_BLUE },
{ 0x010c, KEY_SHUFFLE }, /* snapshot */
{ 0x0148, KEY_STOP },
{ 0x0150, KEY_PLAY },
{ 0x0151, KEY_PAUSE },
{ 0x0149, KEY_RECORD },
{ 0x0118, KEY_PREVIOUS }, /* |<< */
{ 0x010d, KEY_NEXT }, /* >>| */
{ 0x0124, KEY_PROG1 }, /* F1 */
{ 0x0125, KEY_PROG2 }, /* F2 */
};
/* DVB USB Driver stuff */
......
......@@ -85,43 +85,43 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
}
static struct dvb_usb_rc_key cinergyt2_rc_keys[] = {
{ 0x04, 0x01, KEY_POWER },
{ 0x04, 0x02, KEY_1 },
{ 0x04, 0x03, KEY_2 },
{ 0x04, 0x04, KEY_3 },
{ 0x04, 0x05, KEY_4 },
{ 0x04, 0x06, KEY_5 },
{ 0x04, 0x07, KEY_6 },
{ 0x04, 0x08, KEY_7 },
{ 0x04, 0x09, KEY_8 },
{ 0x04, 0x0a, KEY_9 },
{ 0x04, 0x0c, KEY_0 },
{ 0x04, 0x0b, KEY_VIDEO },
{ 0x04, 0x0d, KEY_REFRESH },
{ 0x04, 0x0e, KEY_SELECT },
{ 0x04, 0x0f, KEY_EPG },
{ 0x04, 0x10, KEY_UP },
{ 0x04, 0x14, KEY_DOWN },
{ 0x04, 0x11, KEY_LEFT },
{ 0x04, 0x13, KEY_RIGHT },
{ 0x04, 0x12, KEY_OK },
{ 0x04, 0x15, KEY_TEXT },
{ 0x04, 0x16, KEY_INFO },
{ 0x04, 0x17, KEY_RED },
{ 0x04, 0x18, KEY_GREEN },
{ 0x04, 0x19, KEY_YELLOW },
{ 0x04, 0x1a, KEY_BLUE },
{ 0x04, 0x1c, KEY_VOLUMEUP },
{ 0x04, 0x1e, KEY_VOLUMEDOWN },
{ 0x04, 0x1d, KEY_MUTE },
{ 0x04, 0x1b, KEY_CHANNELUP },
{ 0x04, 0x1f, KEY_CHANNELDOWN },
{ 0x04, 0x40, KEY_PAUSE },
{ 0x04, 0x4c, KEY_PLAY },
{ 0x04, 0x58, KEY_RECORD },
{ 0x04, 0x54, KEY_PREVIOUS },
{ 0x04, 0x48, KEY_STOP },
{ 0x04, 0x5c, KEY_NEXT }
{ 0x0401, KEY_POWER },
{ 0x0402, KEY_1 },
{ 0x0403, KEY_2 },
{ 0x0404, KEY_3 },
{ 0x0405, KEY_4 },
{ 0x0406, KEY_5 },
{ 0x0407, KEY_6 },
{ 0x0408, KEY_7 },
{ 0x0409, KEY_8 },
{ 0x040a, KEY_9 },
{ 0x040c, KEY_0 },
{ 0x040b, KEY_VIDEO },
{ 0x040d, KEY_REFRESH },
{ 0x040e, KEY_SELECT },
{ 0x040f, KEY_EPG },
{ 0x0410, KEY_UP },
{ 0x0414, KEY_DOWN },
{ 0x0411, KEY_LEFT },
{ 0x0413, KEY_RIGHT },
{ 0x0412, KEY_OK },
{ 0x0415, KEY_TEXT },
{ 0x0416, KEY_INFO },
{ 0x0417, KEY_RED },
{ 0x0418, KEY_GREEN },
{ 0x0419, KEY_YELLOW },
{ 0x041a, KEY_BLUE },
{ 0x041c, KEY_VOLUMEUP },
{ 0x041e, KEY_VOLUMEDOWN },
{ 0x041d, KEY_MUTE },
{ 0x041b, KEY_CHANNELUP },
{ 0x041f, KEY_CHANNELDOWN },
{ 0x0440, KEY_PAUSE },
{ 0x044c, KEY_PLAY },
{ 0x0458, KEY_RECORD },
{ 0x0454, KEY_PREVIOUS },
{ 0x0448, KEY_STOP },
{ 0x045c, KEY_NEXT }
};
/* Number of keypresses to ignore before detect repeating */
......
......@@ -275,6 +275,7 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
param.tps = cpu_to_le16(compute_tps(fep));
param.freq = cpu_to_le32(fep->frequency / 1000);
param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
param.flags = 0;
err = dvb_usb_generic_rw(state->d,
(char *)&param, sizeof(param),
......
......@@ -38,7 +38,7 @@
#include "mxl5005s.h"
#include "dib7000p.h"
#include "dib0070.h"
#include "lgs8gl5.h"
#include "lgs8gxx.h"
/* debug */
static int dvb_usb_cxusb_debug;
......@@ -392,8 +392,8 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*state = REMOTE_NO_KEY_PRESSED;
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (keymap[i].custom == ircode[2] &&
keymap[i].data == ircode[3]) {
if (rc5_custom(&keymap[i]) == ircode[2] &&
rc5_data(&keymap[i]) == ircode[3]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
......@@ -420,8 +420,8 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
return 0;
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (keymap[i].custom == ircode[1] &&
keymap[i].data == ircode[2]) {
if (rc5_custom(&keymap[i]) == ircode[1] &&
rc5_data(&keymap[i]) == ircode[2]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
......@@ -446,8 +446,8 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
return 0;
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (keymap[i].custom == ircode[0] &&
keymap[i].data == ircode[1]) {
if (rc5_custom(&keymap[i]) == ircode[0] &&
rc5_data(&keymap[i]) == ircode[1]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
......@@ -459,128 +459,128 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
}
static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
{ 0xfe, 0x02, KEY_TV },
{ 0xfe, 0x0e, KEY_MP3 },
{ 0xfe, 0x1a, KEY_DVD },
{ 0xfe, 0x1e, KEY_FAVORITES },
{ 0xfe, 0x16, KEY_SETUP },
{ 0xfe, 0x46, KEY_POWER2 },
{ 0xfe, 0x0a, KEY_EPG },
{ 0xfe, 0x49, KEY_BACK },
{ 0xfe, 0x4d, KEY_MENU },
{ 0xfe, 0x51, KEY_UP },
{ 0xfe, 0x5b, KEY_LEFT },
{ 0xfe, 0x5f, KEY_RIGHT },
{ 0xfe, 0x53, KEY_DOWN },
{ 0xfe, 0x5e, KEY_OK },
{ 0xfe, 0x59, KEY_INFO },
{ 0xfe, 0x55, KEY_TAB },
{ 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
{ 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */
{ 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */
{ 0xfe, 0x15, KEY_VOLUMEUP },
{ 0xfe, 0x05, KEY_VOLUMEDOWN },
{ 0xfe, 0x11, KEY_CHANNELUP },
{ 0xfe, 0x09, KEY_CHANNELDOWN },
{ 0xfe, 0x52, KEY_CAMERA },
{ 0xfe, 0x5a, KEY_TUNER }, /* Live */
{ 0xfe, 0x19, KEY_OPEN },
{ 0xfe, 0x0b, KEY_1 },
{ 0xfe, 0x17, KEY_2 },
{ 0xfe, 0x1b, KEY_3 },
{ 0xfe, 0x07, KEY_4 },
{ 0xfe, 0x50, KEY_5 },
{ 0xfe, 0x54, KEY_6 },
{ 0xfe, 0x48, KEY_7 },
{ 0xfe, 0x4c, KEY_8 },
{ 0xfe, 0x58, KEY_9 },
{ 0xfe, 0x13, KEY_ANGLE }, /* Aspect */
{ 0xfe, 0x03, KEY_0 },
{ 0xfe, 0x1f, KEY_ZOOM },
{ 0xfe, 0x43, KEY_REWIND },
{ 0xfe, 0x47, KEY_PLAYPAUSE },
{ 0xfe, 0x4f, KEY_FASTFORWARD },
{ 0xfe, 0x57, KEY_MUTE },
{ 0xfe, 0x0d, KEY_STOP },
{ 0xfe, 0x01, KEY_RECORD },
{ 0xfe, 0x4e, KEY_POWER },
{ 0xfe02, KEY_TV },
{ 0xfe0e, KEY_MP3 },
{ 0xfe1a, KEY_DVD },
{ 0xfe1e, KEY_FAVORITES },
{ 0xfe16, KEY_SETUP },
{ 0xfe46, KEY_POWER2 },
{ 0xfe0a, KEY_EPG },
{ 0xfe49, KEY_BACK },
{ 0xfe4d, KEY_MENU },
{ 0xfe51, KEY_UP },
{ 0xfe5b, KEY_LEFT },
{ 0xfe5f, KEY_RIGHT },
{ 0xfe53, KEY_DOWN },
{ 0xfe5e, KEY_OK },
{ 0xfe59, KEY_INFO },
{ 0xfe55, KEY_TAB },
{ 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
{ 0xfe12, KEY_NEXTSONG }, /* Skip */
{ 0xfe42, KEY_ENTER }, /* Windows/Start */
{ 0xfe15, KEY_VOLUMEUP },
{ 0xfe05, KEY_VOLUMEDOWN },
{ 0xfe11, KEY_CHANNELUP },
{ 0xfe09, KEY_CHANNELDOWN },
{ 0xfe52, KEY_CAMERA },
{ 0xfe5a, KEY_TUNER }, /* Live */
{ 0xfe19, KEY_OPEN },
{ 0xfe0b, KEY_1 },
{ 0xfe17, KEY_2 },
{ 0xfe1b, KEY_3 },
{ 0xfe07, KEY_4 },
{ 0xfe50, KEY_5 },
{ 0xfe54, KEY_6 },
{ 0xfe48, KEY_7 },
{ 0xfe4c, KEY_8 },
{ 0xfe58, KEY_9 },
{ 0xfe13, KEY_ANGLE }, /* Aspect */
{ 0xfe03, KEY_0 },
{ 0xfe1f, KEY_ZOOM },
{ 0xfe43, KEY_REWIND },
{ 0xfe47, KEY_PLAYPAUSE },
{ 0xfe4f, KEY_FASTFORWARD },
{ 0xfe57, KEY_MUTE },
{ 0xfe0d, KEY_STOP },
{ 0xfe01, KEY_RECORD },
{ 0xfe4e, KEY_POWER },
};
static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
{ 0xfc, 0x02, KEY_SETUP }, /* Profile */
{ 0xfc, 0x43, KEY_POWER2 },
{ 0xfc, 0x06, KEY_EPG },
{ 0xfc, 0x5a, KEY_BACK },
{ 0xfc, 0x05, KEY_MENU },
{ 0xfc, 0x47, KEY_INFO },
{ 0xfc, 0x01, KEY_TAB },
{ 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */
{ 0xfc, 0x49, KEY_VOLUMEUP },
{ 0xfc, 0x09, KEY_VOLUMEDOWN },
{ 0xfc, 0x54, KEY_CHANNELUP },
{ 0xfc, 0x0b, KEY_CHANNELDOWN },
{ 0xfc, 0x16, KEY_CAMERA },
{ 0xfc, 0x40, KEY_TUNER }, /* ATV/DTV */
{ 0xfc, 0x45, KEY_OPEN },
{ 0xfc, 0x19, KEY_1 },
{ 0xfc, 0x18, KEY_2 },
{ 0xfc, 0x1b, KEY_3 },
{ 0xfc, 0x1a, KEY_4 },
{ 0xfc, 0x58, KEY_5 },
{ 0xfc, 0x59, KEY_6 },
{ 0xfc, 0x15, KEY_7 },
{ 0xfc, 0x14, KEY_8 },
{ 0xfc, 0x17, KEY_9 },
{ 0xfc, 0x44, KEY_ANGLE }, /* Aspect */
{ 0xfc, 0x55, KEY_0 },
{ 0xfc, 0x07, KEY_ZOOM },
{ 0xfc, 0x0a, KEY_REWIND },
{ 0xfc, 0x08, KEY_PLAYPAUSE },
{ 0xfc, 0x4b, KEY_FASTFORWARD },
{ 0xfc, 0x5b, KEY_MUTE },
{ 0xfc, 0x04, KEY_STOP },
{ 0xfc, 0x56, KEY_RECORD },
{ 0xfc, 0x57, KEY_POWER },
{ 0xfc, 0x41, KEY_UNKNOWN }, /* INPUT */
{ 0xfc, 0x00, KEY_UNKNOWN }, /* HD */
{ 0xfc02, KEY_SETUP }, /* Profile */
{ 0xfc43, KEY_POWER2 },
{ 0xfc06, KEY_EPG },
{ 0xfc5a, KEY_BACK },
{ 0xfc05, KEY_MENU },
{ 0xfc47, KEY_INFO },
{ 0xfc01, KEY_TAB },
{ 0xfc42, KEY_PREVIOUSSONG },/* Replay */
{ 0xfc49, KEY_VOLUMEUP },
{ 0xfc09, KEY_VOLUMEDOWN },
{ 0xfc54, KEY_CHANNELUP },
{ 0xfc0b, KEY_CHANNELDOWN },
{ 0xfc16, KEY_CAMERA },
{ 0xfc40, KEY_TUNER }, /* ATV/DTV */
{ 0xfc45, KEY_OPEN },
{ 0xfc19, KEY_1 },
{ 0xfc18, KEY_2 },
{ 0xfc1b, KEY_3 },
{ 0xfc1a, KEY_4 },
{ 0xfc58, KEY_5 },
{ 0xfc59, KEY_6 },
{ 0xfc15, KEY_7 },
{ 0xfc14, KEY_8 },
{ 0xfc17, KEY_9 },
{ 0xfc44, KEY_ANGLE }, /* Aspect */
{ 0xfc55, KEY_0 },
{ 0xfc07, KEY_ZOOM },
{ 0xfc0a, KEY_REWIND },
{ 0xfc08, KEY_PLAYPAUSE },
{ 0xfc4b, KEY_FASTFORWARD },
{ 0xfc5b, KEY_MUTE },
{ 0xfc04, KEY_STOP },
{ 0xfc56, KEY_RECORD },
{ 0xfc57, KEY_POWER },
{ 0xfc41, KEY_UNKNOWN }, /* INPUT */
{ 0xfc00, KEY_UNKNOWN }, /* HD */
};
static struct dvb_usb_rc_key d680_dmb_rc_keys[] = {
{ 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */
{ 0x08, 0x0c, KEY_ZOOM },
{ 0x08, 0x00, KEY_0 },
{ 0x00, 0x01, KEY_1 },
{ 0x08, 0x02, KEY_2 },
{ 0x00, 0x03, KEY_3 },
{ 0x08, 0x04, KEY_4 },
{ 0x00, 0x05, KEY_5 },
{ 0x08, 0x06, KEY_6 },
{ 0x00, 0x07, KEY_7 },
{ 0x08, 0x08, KEY_8 },
{ 0x00, 0x09, KEY_9 },
{ 0x00, 0x0a, KEY_MUTE },
{ 0x08, 0x29, KEY_BACK },
{ 0x00, 0x12, KEY_CHANNELUP },
{ 0x08, 0x13, KEY_CHANNELDOWN },
{ 0x00, 0x2b, KEY_VOLUMEUP },
{ 0x08, 0x2c, KEY_VOLUMEDOWN },
{ 0x00, 0x20, KEY_UP },
{ 0x08, 0x21, KEY_DOWN },
{ 0x00, 0x11, KEY_LEFT },
{ 0x08, 0x10, KEY_RIGHT },
{ 0x00, 0x0d, KEY_OK },
{ 0x08, 0x1f, KEY_RECORD },
{ 0x00, 0x17, KEY_PLAYPAUSE },
{ 0x08, 0x16, KEY_PLAYPAUSE },
{ 0x00, 0x0b, KEY_STOP },
{ 0x08, 0x27, KEY_FASTFORWARD },
{ 0x00, 0x26, KEY_REWIND },
{ 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */
{ 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */
{ 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */
{ 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */
{ 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */
{ 0x00, 0x25, KEY_POWER },
{ 0x0038, KEY_UNKNOWN }, /* TV/AV */
{ 0x080c, KEY_ZOOM },
{ 0x0800, KEY_0 },
{ 0x0001, KEY_1 },
{ 0x0802, KEY_2 },
{ 0x0003, KEY_3 },
{ 0x0804, KEY_4 },
{ 0x0005, KEY_5 },
{ 0x0806, KEY_6 },
{ 0x0007, KEY_7 },
{ 0x0808, KEY_8 },
{ 0x0009, KEY_9 },
{ 0x000a, KEY_MUTE },
{ 0x0829, KEY_BACK },
{ 0x0012, KEY_CHANNELUP },
{ 0x0813, KEY_CHANNELDOWN },
{ 0x002b, KEY_VOLUMEUP },
{ 0x082c, KEY_VOLUMEDOWN },
{ 0x0020, KEY_UP },
{ 0x0821, KEY_DOWN },
{ 0x0011, KEY_LEFT },
{ 0x0810, KEY_RIGHT },
{ 0x000d, KEY_OK },
{ 0x081f, KEY_RECORD },
{ 0x0017, KEY_PLAYPAUSE },
{ 0x0816, KEY_PLAYPAUSE },
{ 0x000b, KEY_STOP },
{ 0x0827, KEY_FASTFORWARD },
{ 0x0026, KEY_REWIND },
{ 0x081e, KEY_UNKNOWN }, /* Time Shift */
{ 0x000e, KEY_UNKNOWN }, /* Snapshot */
{ 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
{ 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
{ 0x0814, KEY_UNKNOWN }, /* Shuffle */
{ 0x0025, KEY_POWER },
};
static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
......@@ -1094,8 +1094,18 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
return -EIO;
}
static struct lgs8gl5_config lgs8gl5_cfg = {
static struct lgs8gxx_config d680_lgs8gl5_cfg = {
.prod = LGS8GXX_PROD_LGS8GL5,
.demod_address = 0x19,
.serial_ts = 0,
.ts_clk_pol = 0,
.ts_clk_gated = 1,
.if_clk_freq = 30400, /* 30.4 MHz */
.if_freq = 5725, /* 5.725 MHz */
.if_neg_center = 0,
.ext_adc = 0,
.adc_signed = 0,
.if_neg_edge = 0,
};
static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
......@@ -1135,7 +1145,7 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
msleep(100);
/* Attach frontend */
adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap);
adap->fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
if (adap->fe == NULL)
return -EIO;
......
This diff is collapsed.
......@@ -318,132 +318,132 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
*/
struct dvb_usb_rc_key dibusb_rc_keys[] = {
/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
{ 0x00, 0x16, KEY_POWER },
{ 0x00, 0x10, KEY_MUTE },
{ 0x00, 0x03, KEY_1 },
{ 0x00, 0x01, KEY_2 },
{ 0x00, 0x06, KEY_3 },
{ 0x00, 0x09, KEY_4 },
{ 0x00, 0x1d, KEY_5 },
{ 0x00, 0x1f, KEY_6 },
{ 0x00, 0x0d, KEY_7 },
{ 0x00, 0x19, KEY_8 },
{ 0x00, 0x1b, KEY_9 },
{ 0x00, 0x15, KEY_0 },
{ 0x00, 0x05, KEY_CHANNELUP },
{ 0x00, 0x02, KEY_CHANNELDOWN },
{ 0x00, 0x1e, KEY_VOLUMEUP },
{ 0x00, 0x0a, KEY_VOLUMEDOWN },
{ 0x00, 0x11, KEY_RECORD },
{ 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
{ 0x00, 0x14, KEY_PLAY },
{ 0x00, 0x1a, KEY_STOP },
{ 0x00, 0x40, KEY_REWIND },
{ 0x00, 0x12, KEY_FASTFORWARD },
{ 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
{ 0x00, 0x4c, KEY_PAUSE },
{ 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
{ 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
{ 0x0003, KEY_1 },
{ 0x0001, KEY_2 },
{ 0x0006, KEY_3 },
{ 0x0009, KEY_4 },
{ 0x001d, KEY_5 },
{ 0x001f, KEY_6 },
{ 0x000d, KEY_7 },
{ 0x0019, KEY_8 },
{ 0x001b, KEY_9 },
{ 0x0015, KEY_0 },
{ 0x0005, KEY_CHANNELUP },
{ 0x0002, KEY_CHANNELDOWN },
{ 0x001e, KEY_VOLUMEUP },
{ 0x000a, KEY_VOLUMEDOWN },
{ 0x0011, KEY_RECORD },
{ 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
{ 0x0014, KEY_PLAY },
{ 0x001a, KEY_STOP },
{ 0x0040, KEY_REWIND },
{ 0x0012, KEY_FASTFORWARD },
{ 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
{ 0x004c, KEY_PAUSE },
{ 0x004d, KEY_SCREEN }, /* Full screen mode. */
{ 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
/* additional keys TwinHan VisionPlus, the Artec seemingly not have */
{ 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
{ 0x00, 0x1c, KEY_EPG }, /* EPG */
{ 0x00, 0x00, KEY_TAB }, /* Tab */
{ 0x00, 0x48, KEY_INFO }, /* Preview */
{ 0x00, 0x04, KEY_LIST }, /* RecordList */
{ 0x00, 0x0f, KEY_TEXT }, /* Teletext */
{ 0x000c, KEY_CANCEL }, /* Cancel */
{ 0x001c, KEY_EPG }, /* EPG */
{ 0x0000, KEY_TAB }, /* Tab */
{ 0x0048, KEY_INFO }, /* Preview */
{ 0x0004, KEY_LIST }, /* RecordList */
{ 0x000f, KEY_TEXT }, /* Teletext */
/* Key codes for the KWorld/ADSTech/JetWay remote. */
{ 0x86, 0x12, KEY_POWER },
{ 0x86, 0x0f, KEY_SELECT }, /* source */
{ 0x86, 0x0c, KEY_UNKNOWN }, /* scan */
{ 0x86, 0x0b, KEY_EPG },
{ 0x86, 0x10, KEY_MUTE },
{ 0x86, 0x01, KEY_1 },
{ 0x86, 0x02, KEY_2 },
{ 0x86, 0x03, KEY_3 },
{ 0x86, 0x04, KEY_4 },
{ 0x86, 0x05, KEY_5 },
{ 0x86, 0x06, KEY_6 },
{ 0x86, 0x07, KEY_7 },
{ 0x86, 0x08, KEY_8 },
{ 0x86, 0x09, KEY_9 },
{ 0x86, 0x0a, KEY_0 },
{ 0x86, 0x18, KEY_ZOOM },
{ 0x86, 0x1c, KEY_UNKNOWN }, /* preview */
{ 0x86, 0x13, KEY_UNKNOWN }, /* snap */
{ 0x86, 0x00, KEY_UNDO },
{ 0x86, 0x1d, KEY_RECORD },
{ 0x86, 0x0d, KEY_STOP },
{ 0x86, 0x0e, KEY_PAUSE },
{ 0x86, 0x16, KEY_PLAY },
{ 0x86, 0x11, KEY_BACK },
{ 0x86, 0x19, KEY_FORWARD },
{ 0x86, 0x14, KEY_UNKNOWN }, /* pip */
{ 0x86, 0x15, KEY_ESC },
{ 0x86, 0x1a, KEY_UP },
{ 0x86, 0x1e, KEY_DOWN },
{ 0x86, 0x1f, KEY_LEFT },
{ 0x86, 0x1b, KEY_RIGHT },
{ 0x8612, KEY_POWER },
{ 0x860f, KEY_SELECT }, /* source */
{ 0x860c, KEY_UNKNOWN }, /* scan */
{ 0x860b, KEY_EPG },
{ 0x8610, KEY_MUTE },
{ 0x8601, KEY_1 },
{ 0x8602, KEY_2 },
{ 0x8603, KEY_3 },
{ 0x8604, KEY_4 },
{ 0x8605, KEY_5 },
{ 0x8606, KEY_6 },
{ 0x8607, KEY_7 },
{ 0x8608, KEY_8 },
{ 0x8609, KEY_9 },
{ 0x860a, KEY_0 },
{ 0x8618, KEY_ZOOM },
{ 0x861c, KEY_UNKNOWN }, /* preview */
{ 0x8613, KEY_UNKNOWN }, /* snap */
{ 0x8600, KEY_UNDO },
{ 0x861d, KEY_RECORD },
{ 0x860d, KEY_STOP },
{ 0x860e, KEY_PAUSE },
{ 0x8616, KEY_PLAY },
{ 0x8611, KEY_BACK },
{ 0x8619, KEY_FORWARD },
{ 0x8614, KEY_UNKNOWN }, /* pip */
{ 0x8615, KEY_ESC },
{ 0x861a, KEY_UP },
{ 0x861e, KEY_DOWN },
{ 0x861f, KEY_LEFT },
{ 0x861b, KEY_RIGHT },
/* Key codes for the DiBcom MOD3000 remote. */
{ 0x80, 0x00, KEY_MUTE },
{ 0x80, 0x01, KEY_TEXT },
{ 0x80, 0x02, KEY_HOME },
{ 0x80, 0x03, KEY_POWER },
{ 0x80, 0x04, KEY_RED },
{ 0x80, 0x05, KEY_GREEN },
{ 0x80, 0x06, KEY_YELLOW },
{ 0x80, 0x07, KEY_BLUE },
{ 0x80, 0x08, KEY_DVD },
{ 0x80, 0x09, KEY_AUDIO },
{ 0x80, 0x0a, KEY_MEDIA }, /* Pictures */
{ 0x80, 0x0b, KEY_VIDEO },
{ 0x80, 0x0c, KEY_BACK },
{ 0x80, 0x0d, KEY_UP },
{ 0x80, 0x0e, KEY_RADIO },
{ 0x80, 0x0f, KEY_EPG },
{ 0x80, 0x10, KEY_LEFT },
{ 0x80, 0x11, KEY_OK },
{ 0x80, 0x12, KEY_RIGHT },
{ 0x80, 0x13, KEY_UNKNOWN }, /* SAP */
{ 0x80, 0x14, KEY_TV },
{ 0x80, 0x15, KEY_DOWN },
{ 0x80, 0x16, KEY_MENU }, /* DVD Menu */
{ 0x80, 0x17, KEY_LAST },
{ 0x80, 0x18, KEY_RECORD },
{ 0x80, 0x19, KEY_STOP },
{ 0x80, 0x1a, KEY_PAUSE },
{ 0x80, 0x1b, KEY_PLAY },
{ 0x80, 0x1c, KEY_PREVIOUS },
{ 0x80, 0x1d, KEY_REWIND },
{ 0x80, 0x1e, KEY_FASTFORWARD },
{ 0x80, 0x1f, KEY_NEXT},
{ 0x80, 0x40, KEY_1 },
{ 0x80, 0x41, KEY_2 },
{ 0x80, 0x42, KEY_3 },
{ 0x80, 0x43, KEY_CHANNELUP },
{ 0x80, 0x44, KEY_4 },
{ 0x80, 0x45, KEY_5 },
{ 0x80, 0x46, KEY_6 },
{ 0x80, 0x47, KEY_CHANNELDOWN },
{ 0x80, 0x48, KEY_7 },
{ 0x80, 0x49, KEY_8 },
{ 0x80, 0x4a, KEY_9 },
{ 0x80, 0x4b, KEY_VOLUMEUP },
{ 0x80, 0x4c, KEY_CLEAR },
{ 0x80, 0x4d, KEY_0 },
{ 0x80, 0x4e, KEY_ENTER },
{ 0x80, 0x4f, KEY_VOLUMEDOWN },
{ 0x8000, KEY_MUTE },
{ 0x8001, KEY_TEXT },
{ 0x8002, KEY_HOME },
{ 0x8003, KEY_POWER },
{ 0x8004, KEY_RED },
{ 0x8005, KEY_GREEN },
{ 0x8006, KEY_YELLOW },
{ 0x8007, KEY_BLUE },
{ 0x8008, KEY_DVD },
{ 0x8009, KEY_AUDIO },
{ 0x800a, KEY_MEDIA }, /* Pictures */
{ 0x800b, KEY_VIDEO },
{ 0x800c, KEY_BACK },
{ 0x800d, KEY_UP },
{ 0x800e, KEY_RADIO },
{ 0x800f, KEY_EPG },
{ 0x8010, KEY_LEFT },
{ 0x8011, KEY_OK },
{ 0x8012, KEY_RIGHT },
{ 0x8013, KEY_UNKNOWN }, /* SAP */
{ 0x8014, KEY_TV },
{ 0x8015, KEY_DOWN },
{ 0x8016, KEY_MENU }, /* DVD Menu */
{ 0x8017, KEY_LAST },
{ 0x8018, KEY_RECORD },
{ 0x8019, KEY_STOP },
{ 0x801a, KEY_PAUSE },
{ 0x801b, KEY_PLAY },
{ 0x801c, KEY_PREVIOUS },
{ 0x801d, KEY_REWIND },
{ 0x801e, KEY_FASTFORWARD },
{ 0x801f, KEY_NEXT},
{ 0x8040, KEY_1 },
{ 0x8041, KEY_2 },
{ 0x8042, KEY_3 },
{ 0x8043, KEY_CHANNELUP },
{ 0x8044, KEY_4 },
{ 0x8045, KEY_5 },
{ 0x8046, KEY_6 },
{ 0x8047, KEY_CHANNELDOWN },
{ 0x8048, KEY_7 },
{ 0x8049, KEY_8 },
{ 0x804a, KEY_9 },
{ 0x804b, KEY_VOLUMEUP },
{ 0x804c, KEY_CLEAR },
{ 0x804d, KEY_0 },
{ 0x804e, KEY_ENTER },
{ 0x804f, KEY_VOLUMEDOWN },
};
EXPORT_SYMBOL(dibusb_rc_keys);
......
......@@ -42,6 +42,8 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) },
/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) },
/* 14 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
/* 15 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
......@@ -66,7 +68,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
.count = 7,
.count = 8,
.endpoint = 0x06,
.u = {
.bulk = {
......@@ -88,7 +90,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
.generic_bulk_ctrl_endpoint = 0x01,
.num_device_descs = 7,
.num_device_descs = 8,
.devices = {
{ "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
{ &dibusb_dib3000mc_table[0], NULL },
......@@ -119,6 +121,10 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
{ &dibusb_dib3000mc_table[12], NULL },
{ &dibusb_dib3000mc_table[13], NULL },
},
{ "Humax/Coex DVB-T USB Stick 2.0 High Speed",
{ &dibusb_dib3000mc_table[14], NULL },
{ &dibusb_dib3000mc_table[15], NULL },
},
{ NULL },
}
};
......
......@@ -162,61 +162,61 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
}
static struct dvb_usb_rc_key digitv_rc_keys[] = {
{ 0x5f, 0x55, KEY_0 },
{ 0x6f, 0x55, KEY_1 },
{ 0x9f, 0x55, KEY_2 },
{ 0xaf, 0x55, KEY_3 },
{ 0x5f, 0x56, KEY_4 },
{ 0x6f, 0x56, KEY_5 },
{ 0x9f, 0x56, KEY_6 },
{ 0xaf, 0x56, KEY_7 },
{ 0x5f, 0x59, KEY_8 },
{ 0x6f, 0x59, KEY_9 },
{ 0x9f, 0x59, KEY_TV },
{ 0xaf, 0x59, KEY_AUX },
{ 0x5f, 0x5a, KEY_DVD },
{ 0x6f, 0x5a, KEY_POWER },
{ 0x9f, 0x5a, KEY_MHP }, /* labelled 'Picture' */
{ 0xaf, 0x5a, KEY_AUDIO },
{ 0x5f, 0x65, KEY_INFO },
{ 0x6f, 0x65, KEY_F13 }, /* 16:9 */
{ 0x9f, 0x65, KEY_F14 }, /* 14:9 */
{ 0xaf, 0x65, KEY_EPG },
{ 0x5f, 0x66, KEY_EXIT },
{ 0x6f, 0x66, KEY_MENU },
{ 0x9f, 0x66, KEY_UP },
{ 0xaf, 0x66, KEY_DOWN },
{ 0x5f, 0x69, KEY_LEFT },
{ 0x6f, 0x69, KEY_RIGHT },
{ 0x9f, 0x69, KEY_ENTER },
{ 0xaf, 0x69, KEY_CHANNELUP },
{ 0x5f, 0x6a, KEY_CHANNELDOWN },
{ 0x6f, 0x6a, KEY_VOLUMEUP },
{ 0x9f, 0x6a, KEY_VOLUMEDOWN },
{ 0xaf, 0x6a, KEY_RED },
{ 0x5f, 0x95, KEY_GREEN },
{ 0x6f, 0x95, KEY_YELLOW },
{ 0x9f, 0x95, KEY_BLUE },
{ 0xaf, 0x95, KEY_SUBTITLE },
{ 0x5f, 0x96, KEY_F15 }, /* AD */
{ 0x6f, 0x96, KEY_TEXT },
{ 0x9f, 0x96, KEY_MUTE },
{ 0xaf, 0x96, KEY_REWIND },
{ 0x5f, 0x99, KEY_STOP },
{ 0x6f, 0x99, KEY_PLAY },
{ 0x9f, 0x99, KEY_FASTFORWARD },
{ 0xaf, 0x99, KEY_F16 }, /* chapter */
{ 0x5f, 0x9a, KEY_PAUSE },
{ 0x6f, 0x9a, KEY_PLAY },
{ 0x9f, 0x9a, KEY_RECORD },
{ 0xaf, 0x9a, KEY_F17 }, /* picture in picture */
{ 0x5f, 0xa5, KEY_KPPLUS }, /* zoom in */
{ 0x6f, 0xa5, KEY_KPMINUS }, /* zoom out */
{ 0x9f, 0xa5, KEY_F18 }, /* capture */
{ 0xaf, 0xa5, KEY_F19 }, /* web */
{ 0x5f, 0xa6, KEY_EMAIL },
{ 0x6f, 0xa6, KEY_PHONE },
{ 0x9f, 0xa6, KEY_PC },
{ 0x5f55, KEY_0 },
{ 0x6f55, KEY_1 },
{ 0x9f55, KEY_2 },
{ 0xaf55, KEY_3 },
{ 0x5f56, KEY_4 },
{ 0x6f56, KEY_5 },
{ 0x9f56, KEY_6 },
{ 0xaf56, KEY_7 },
{ 0x5f59, KEY_8 },
{ 0x6f59, KEY_9 },
{ 0x9f59, KEY_TV },
{ 0xaf59, KEY_AUX },
{ 0x5f5a, KEY_DVD },
{ 0x6f5a, KEY_POWER },
{ 0x9f5a, KEY_MHP }, /* labelled 'Picture' */
{ 0xaf5a, KEY_AUDIO },
{ 0x5f65, KEY_INFO },
{ 0x6f65, KEY_F13 }, /* 16:9 */
{ 0x9f65, KEY_F14 }, /* 14:9 */
{ 0xaf65, KEY_EPG },
{ 0x5f66, KEY_EXIT },
{ 0x6f66, KEY_MENU },
{ 0x9f66, KEY_UP },
{ 0xaf66, KEY_DOWN },
{ 0x5f69, KEY_LEFT },
{ 0x6f69, KEY_RIGHT },
{ 0x9f69, KEY_ENTER },
{ 0xaf69, KEY_CHANNELUP },
{ 0x5f6a, KEY_CHANNELDOWN },
{ 0x6f6a, KEY_VOLUMEUP },
{ 0x9f6a, KEY_VOLUMEDOWN },
{ 0xaf6a, KEY_RED },
{ 0x5f95, KEY_GREEN },
{ 0x6f95, KEY_YELLOW },
{ 0x9f95, KEY_BLUE },
{ 0xaf95, KEY_SUBTITLE },
{ 0x5f96, KEY_F15 }, /* AD */
{ 0x6f96, KEY_TEXT },
{ 0x9f96, KEY_MUTE },
{ 0xaf96, KEY_REWIND },
{ 0x5f99, KEY_STOP },
{ 0x6f99, KEY_PLAY },
{ 0x9f99, KEY_FASTFORWARD },
{ 0xaf99, KEY_F16 }, /* chapter */
{ 0x5f9a, KEY_PAUSE },
{ 0x6f9a, KEY_PLAY },
{ 0x9f9a, KEY_RECORD },
{ 0xaf9a, KEY_F17 }, /* picture in picture */
{ 0x5fa5, KEY_KPPLUS }, /* zoom in */
{ 0x6fa5, KEY_KPMINUS }, /* zoom out */
{ 0x9fa5, KEY_F18 }, /* capture */
{ 0xafa5, KEY_F19 }, /* web */
{ 0x5fa6, KEY_EMAIL },
{ 0x6fa6, KEY_PHONE },
{ 0x9fa6, KEY_PC },
};
static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
......@@ -238,8 +238,8 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
if (key[1] != 0)
{
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (d->props.rc_key_map[i].custom == key[1] &&
d->props.rc_key_map[i].data == key[2]) {
if (rc5_custom(&d->props.rc_key_map[i]) == key[1] &&
rc5_data(&d->props.rc_key_map[i]) == key[2]) {
*event = d->props.rc_key_map[i].event;
*state = REMOTE_KEY_PRESSED;
return 0;
......
......@@ -58,24 +58,24 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
/* remote control */
/* key list for the tiny remote control (Yakumo, don't know about the others) */
static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
{ 0x80, 0x01, KEY_MUTE },
{ 0x80, 0x02, KEY_CHANNELDOWN },
{ 0x80, 0x03, KEY_VOLUMEDOWN },
{ 0x80, 0x04, KEY_1 },
{ 0x80, 0x05, KEY_2 },
{ 0x80, 0x06, KEY_3 },
{ 0x80, 0x07, KEY_4 },
{ 0x80, 0x08, KEY_5 },
{ 0x80, 0x09, KEY_6 },
{ 0x80, 0x0a, KEY_7 },
{ 0x80, 0x0c, KEY_ZOOM },
{ 0x80, 0x0d, KEY_0 },
{ 0x80, 0x0e, KEY_SELECT },
{ 0x80, 0x12, KEY_POWER },
{ 0x80, 0x1a, KEY_CHANNELUP },
{ 0x80, 0x1b, KEY_8 },
{ 0x80, 0x1e, KEY_VOLUMEUP },
{ 0x80, 0x1f, KEY_9 },
{ 0x8001, KEY_MUTE },
{ 0x8002, KEY_CHANNELDOWN },
{ 0x8003, KEY_VOLUMEDOWN },
{ 0x8004, KEY_1 },
{ 0x8005, KEY_2 },
{ 0x8006, KEY_3 },
{ 0x8007, KEY_4 },
{ 0x8008, KEY_5 },
{ 0x8009, KEY_6 },
{ 0x800a, KEY_7 },
{ 0x800c, KEY_ZOOM },
{ 0x800d, KEY_0 },
{ 0x800e, KEY_SELECT },
{ 0x8012, KEY_POWER },
{ 0x801a, KEY_CHANNELUP },
{ 0x801b, KEY_8 },
{ 0x801e, KEY_VOLUMEUP },
{ 0x801f, KEY_9 },
};
static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
......
......@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
return -EINVAL;
}
strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
d->i2c_adap.algo = d->props.i2c_algo;
d->i2c_adap.algo_data = NULL;
......
......@@ -58,6 +58,7 @@
#define USB_VID_GIGABYTE 0x1044
#define USB_VID_YUAN 0x1164
#define USB_VID_XTENSIONS 0x1ae7
#define USB_VID_HUMAX_COEX 0x10b9
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
......@@ -103,6 +104,7 @@
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
#define USB_PID_INTEL_CE9500 0x9500
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_399U_2 0xe400
#define USB_PID_KWORLD_395U 0xe396
#define USB_PID_KWORLD_395U_2 0xe39b
#define USB_PID_KWORLD_395U_3 0xe395
......@@ -252,6 +254,8 @@
#define USB_PID_YUAN_STK7700PH 0x1f08
#define USB_PID_YUAN_PD378S 0x2edc
#define USB_PID_YUAN_MC770 0x0871
#define USB_PID_YUAN_STK7700D 0x1efc
#define USB_PID_YUAN_STK7700D_2 0x1e8c
#define USB_PID_DW2102 0x2102
#define USB_PID_XTENSIONS_XD_380 0x0381
#define USB_PID_TELESTAR_STARSTICK_2 0x8000
......@@ -259,5 +263,7 @@
#define USB_PID_SONY_PLAYTV 0x0003
#define USB_PID_ELGATO_EYETV_DTT 0x0021
#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
#endif
......@@ -8,6 +8,71 @@
#include "dvb-usb-common.h"
#include <linux/usb/input.h>
static int dvb_usb_getkeycode(struct input_dev *dev,
int scancode, int *keycode)
{
struct dvb_usb_device *d = input_get_drvdata(dev);
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
int i;
/* See if we can match the raw key code. */
for (i = 0; i < d->props.rc_key_map_size; i++)
if (keymap[i].scan == scancode) {
*keycode = keymap[i].event;
return 0;
}
/*
* If is there extra space, returns KEY_RESERVED,
* otherwise, input core won't let dvb_usb_setkeycode
* to work
*/
for (i = 0; i < d->props.rc_key_map_size; i++)
if (keymap[i].event == KEY_RESERVED ||
keymap[i].event == KEY_UNKNOWN) {
*keycode = KEY_RESERVED;
return 0;
}
return -EINVAL;
}
static int dvb_usb_setkeycode(struct input_dev *dev,
int scancode, int keycode)
{
struct dvb_usb_device *d = input_get_drvdata(dev);
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
int i;
/* Search if it is replacing an existing keycode */
for (i = 0; i < d->props.rc_key_map_size; i++)
if (keymap[i].scan == scancode) {
keymap[i].event = keycode;
return 0;
}
/* Search if is there a clean entry. If so, use it */
for (i = 0; i < d->props.rc_key_map_size; i++)
if (keymap[i].event == KEY_RESERVED ||
keymap[i].event == KEY_UNKNOWN) {
keymap[i].scan = scancode;
keymap[i].event = keycode;
return 0;
}
/*
* FIXME: Currently, it is not possible to increase the size of
* scancode table. For it to happen, one possibility
* would be to allocate a table with key_map_size + 1,
* copying data, appending the new key on it, and freeing
* the old one - or maybe just allocating some spare space
*/
return -EINVAL;
}
/* Remote-control poll function - called every dib->rc_query_interval ms to see
* whether the remote control has received anything.
*
......@@ -111,6 +176,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
input_dev->dev.parent = &d->udev->dev;
input_dev->getkeycode = dvb_usb_getkeycode;
input_dev->setkeycode = dvb_usb_setkeycode;
/* set the bits for the keys */
deb_rc("key map size: %d\n", d->props.rc_key_map_size);
......@@ -128,6 +195,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
input_dev->rep[REP_PERIOD] = d->props.rc_interval;
input_dev->rep[REP_DELAY] = d->props.rc_interval + 150;
input_set_drvdata(input_dev, d);
err = input_register_device(input_dev);
if (err) {
input_free_device(input_dev);
......@@ -178,8 +247,8 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
}
/* See if we can match the raw key code. */
for (i = 0; i < d->props.rc_key_map_size; i++)
if (keymap[i].custom == keybuf[1] &&
keymap[i].data == keybuf[3]) {
if (rc5_custom(&keymap[i]) == keybuf[1] &&
rc5_data(&keymap[i]) == keybuf[3]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
return 0;
......
......@@ -81,10 +81,25 @@ struct dvb_usb_device_description {
* @event: the input event assigned to key identified by custom and data
*/
struct dvb_usb_rc_key {
u8 custom,data;
u16 scan;
u32 event;
};
static inline u8 rc5_custom(struct dvb_usb_rc_key *key)
{
return (key->scan >> 8) & 0xff;
}
static inline u8 rc5_data(struct dvb_usb_rc_key *key)
{
return key->scan & 0xff;
}
static inline u8 rc5_scan(struct dvb_usb_rc_key *key)
{
return key->scan & 0xffff;
}
struct dvb_usb_device;
struct dvb_usb_adapter;
struct usb_data_stream;
......
This diff is collapsed.
......@@ -140,7 +140,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
goto unlock;
for (i = 0; i < d->props.rc_key_map_size; i++)
if (d->props.rc_key_map[i].data == rc_state[1]) {
if (rc5_data(&d->props.rc_key_map[i]) == rc_state[1]) {
*event = d->props.rc_key_map[i].event;
switch(rc_state[0]) {
......@@ -562,42 +562,42 @@ static struct m920x_inits tvwalkertwin_rc_init [] = {
/* ir keymaps */
static struct dvb_usb_rc_key megasky_rc_keys [] = {
{ 0x0, 0x12, KEY_POWER },
{ 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
{ 0x0, 0x02, KEY_CHANNELUP },
{ 0x0, 0x05, KEY_CHANNELDOWN },
{ 0x0, 0x03, KEY_VOLUMEUP },
{ 0x0, 0x06, KEY_VOLUMEDOWN },
{ 0x0, 0x04, KEY_MUTE },
{ 0x0, 0x07, KEY_OK }, /* TS */
{ 0x0, 0x08, KEY_STOP },
{ 0x0, 0x09, KEY_MENU }, /* swap */
{ 0x0, 0x0a, KEY_REWIND },
{ 0x0, 0x1b, KEY_PAUSE },
{ 0x0, 0x1f, KEY_FASTFORWARD },
{ 0x0, 0x0c, KEY_RECORD },
{ 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
{ 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
{ 0x0012, KEY_POWER },
{ 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
{ 0x0002, KEY_CHANNELUP },
{ 0x0005, KEY_CHANNELDOWN },
{ 0x0003, KEY_VOLUMEUP },
{ 0x0006, KEY_VOLUMEDOWN },
{ 0x0004, KEY_MUTE },
{ 0x0007, KEY_OK }, /* TS */
{ 0x0008, KEY_STOP },
{ 0x0009, KEY_MENU }, /* swap */
{ 0x000a, KEY_REWIND },
{ 0x001b, KEY_PAUSE },
{ 0x001f, KEY_FASTFORWARD },
{ 0x000c, KEY_RECORD },
{ 0x000d, KEY_CAMERA }, /* screenshot */
{ 0x000e, KEY_COFFEE }, /* "MTS" */
};
static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
{ 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
{ 0x0, 0x02, KEY_CAMERA }, /* snapshot */
{ 0x0, 0x03, KEY_MUTE },
{ 0x0, 0x04, KEY_REWIND },
{ 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
{ 0x0, 0x06, KEY_FASTFORWARD },
{ 0x0, 0x07, KEY_RECORD },
{ 0x0, 0x08, KEY_STOP },
{ 0x0, 0x09, KEY_TIME }, /* Timeshift */
{ 0x0, 0x0c, KEY_COFFEE }, /* Recall */
{ 0x0, 0x0e, KEY_CHANNELUP },
{ 0x0, 0x12, KEY_POWER },
{ 0x0, 0x15, KEY_MENU }, /* source */
{ 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
{ 0x0, 0x1a, KEY_CHANNELDOWN },
{ 0x0, 0x1b, KEY_VOLUMEDOWN },
{ 0x0, 0x1e, KEY_VOLUMEUP },
{ 0x0001, KEY_ZOOM }, /* Full Screen */
{ 0x0002, KEY_CAMERA }, /* snapshot */
{ 0x0003, KEY_MUTE },
{ 0x0004, KEY_REWIND },
{ 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
{ 0x0006, KEY_FASTFORWARD },
{ 0x0007, KEY_RECORD },
{ 0x0008, KEY_STOP },
{ 0x0009, KEY_TIME }, /* Timeshift */
{ 0x000c, KEY_COFFEE }, /* Recall */
{ 0x000e, KEY_CHANNELUP },
{ 0x0012, KEY_POWER },
{ 0x0015, KEY_MENU }, /* source */
{ 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
{ 0x001a, KEY_CHANNELDOWN },
{ 0x001b, KEY_VOLUMEDOWN },
{ 0x001e, KEY_VOLUMEUP },
};
/* DVB USB Driver stuff */
......
......@@ -22,51 +22,51 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/* Hauppauge NOVA-T USB2 keys */
static struct dvb_usb_rc_key haupp_rc_keys [] = {
{ 0x1e, 0x00, KEY_0 },
{ 0x1e, 0x01, KEY_1 },
{ 0x1e, 0x02, KEY_2 },
{ 0x1e, 0x03, KEY_3 },
{ 0x1e, 0x04, KEY_4 },
{ 0x1e, 0x05, KEY_5 },
{ 0x1e, 0x06, KEY_6 },
{ 0x1e, 0x07, KEY_7 },
{ 0x1e, 0x08, KEY_8 },
{ 0x1e, 0x09, KEY_9 },
{ 0x1e, 0x0a, KEY_KPASTERISK },
{ 0x1e, 0x0b, KEY_RED },
{ 0x1e, 0x0c, KEY_RADIO },
{ 0x1e, 0x0d, KEY_MENU },
{ 0x1e, 0x0e, KEY_GRAVE }, /* # */
{ 0x1e, 0x0f, KEY_MUTE },
{ 0x1e, 0x10, KEY_VOLUMEUP },
{ 0x1e, 0x11, KEY_VOLUMEDOWN },
{ 0x1e, 0x12, KEY_CHANNEL },
{ 0x1e, 0x14, KEY_UP },
{ 0x1e, 0x15, KEY_DOWN },
{ 0x1e, 0x16, KEY_LEFT },
{ 0x1e, 0x17, KEY_RIGHT },
{ 0x1e, 0x18, KEY_VIDEO },
{ 0x1e, 0x19, KEY_AUDIO },
{ 0x1e, 0x1a, KEY_MEDIA },
{ 0x1e, 0x1b, KEY_EPG },
{ 0x1e, 0x1c, KEY_TV },
{ 0x1e, 0x1e, KEY_NEXT },
{ 0x1e, 0x1f, KEY_BACK },
{ 0x1e, 0x20, KEY_CHANNELUP },
{ 0x1e, 0x21, KEY_CHANNELDOWN },
{ 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
{ 0x1e, 0x25, KEY_OK },
{ 0x1e, 0x29, KEY_BLUE},
{ 0x1e, 0x2e, KEY_GREEN },
{ 0x1e, 0x30, KEY_PAUSE },
{ 0x1e, 0x32, KEY_REWIND },
{ 0x1e, 0x34, KEY_FASTFORWARD },
{ 0x1e, 0x35, KEY_PLAY },
{ 0x1e, 0x36, KEY_STOP },
{ 0x1e, 0x37, KEY_RECORD },
{ 0x1e, 0x38, KEY_YELLOW },
{ 0x1e, 0x3b, KEY_GOTO },
{ 0x1e, 0x3d, KEY_POWER },
{ 0x1e00, KEY_0 },
{ 0x1e01, KEY_1 },
{ 0x1e02, KEY_2 },
{ 0x1e03, KEY_3 },
{ 0x1e04, KEY_4 },
{ 0x1e05, KEY_5 },
{ 0x1e06, KEY_6 },
{ 0x1e07, KEY_7 },
{ 0x1e08, KEY_8 },
{ 0x1e09, KEY_9 },
{ 0x1e0a, KEY_KPASTERISK },
{ 0x1e0b, KEY_RED },
{ 0x1e0c, KEY_RADIO },
{ 0x1e0d, KEY_MENU },
{ 0x1e0e, KEY_GRAVE }, /* # */
{ 0x1e0f, KEY_MUTE },
{ 0x1e10, KEY_VOLUMEUP },
{ 0x1e11, KEY_VOLUMEDOWN },
{ 0x1e12, KEY_CHANNEL },
{ 0x1e14, KEY_UP },
{ 0x1e15, KEY_DOWN },
{ 0x1e16, KEY_LEFT },
{ 0x1e17, KEY_RIGHT },
{ 0x1e18, KEY_VIDEO },
{ 0x1e19, KEY_AUDIO },
{ 0x1e1a, KEY_MEDIA },
{ 0x1e1b, KEY_EPG },
{ 0x1e1c, KEY_TV },
{ 0x1e1e, KEY_NEXT },
{ 0x1e1f, KEY_BACK },
{ 0x1e20, KEY_CHANNELUP },
{ 0x1e21, KEY_CHANNELDOWN },
{ 0x1e24, KEY_LAST }, /* Skip backwards */
{ 0x1e25, KEY_OK },
{ 0x1e29, KEY_BLUE},
{ 0x1e2e, KEY_GREEN },
{ 0x1e30, KEY_PAUSE },
{ 0x1e32, KEY_REWIND },
{ 0x1e34, KEY_FASTFORWARD },
{ 0x1e35, KEY_PLAY },
{ 0x1e36, KEY_STOP },
{ 0x1e37, KEY_RECORD },
{ 0x1e38, KEY_YELLOW },
{ 0x1e3b, KEY_GOTO },
{ 0x1e3d, KEY_POWER },
};
/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
......@@ -92,10 +92,11 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
if (haupp_rc_keys[i].data == data &&
haupp_rc_keys[i].custom == custom) {
if (rc5_data(&haupp_rc_keys[i]) == data &&
rc5_custom(&haupp_rc_keys[i]) == custom) {
deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
deb_rc("c: %x, d: %x\n", rc5_data(&haupp_rc_keys[i]),
rc5_custom(&haupp_rc_keys[i]));
*event = haupp_rc_keys[i].event;
*state = REMOTE_KEY_PRESSED;
......
......@@ -332,32 +332,32 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
}
static struct dvb_usb_rc_key opera1_rc_keys[] = {
{0x5f, 0xa0, KEY_1},
{0x51, 0xaf, KEY_2},
{0x5d, 0xa2, KEY_3},
{0x41, 0xbe, KEY_4},
{0x0b, 0xf5, KEY_5},
{0x43, 0xbd, KEY_6},
{0x47, 0xb8, KEY_7},
{0x49, 0xb6, KEY_8},
{0x05, 0xfa, KEY_9},
{0x45, 0xba, KEY_0},
{0x09, 0xf6, KEY_UP}, /*chanup */
{0x1b, 0xe5, KEY_DOWN}, /*chandown */
{0x5d, 0xa3, KEY_LEFT}, /*voldown */
{0x5f, 0xa1, KEY_RIGHT}, /*volup */
{0x07, 0xf8, KEY_SPACE}, /*tab */
{0x1f, 0xe1, KEY_ENTER}, /*play ok */
{0x1b, 0xe4, KEY_Z}, /*zoom */
{0x59, 0xa6, KEY_M}, /*mute */
{0x5b, 0xa5, KEY_F}, /*tv/f */
{0x19, 0xe7, KEY_R}, /*rec */
{0x01, 0xfe, KEY_S}, /*Stop */
{0x03, 0xfd, KEY_P}, /*pause */
{0x03, 0xfc, KEY_W}, /*<- -> */
{0x07, 0xf9, KEY_C}, /*capture */
{0x47, 0xb9, KEY_Q}, /*exit */
{0x43, 0xbc, KEY_O}, /*power */
{0x5fa0, KEY_1},
{0x51af, KEY_2},
{0x5da2, KEY_3},
{0x41be, KEY_4},
{0x0bf5, KEY_5},
{0x43bd, KEY_6},
{0x47b8, KEY_7},
{0x49b6, KEY_8},
{0x05fa, KEY_9},
{0x45ba, KEY_0},
{0x09f6, KEY_UP}, /*chanup */
{0x1be5, KEY_DOWN}, /*chandown */
{0x5da3, KEY_LEFT}, /*voldown */
{0x5fa1, KEY_RIGHT}, /*volup */
{0x07f8, KEY_SPACE}, /*tab */
{0x1fe1, KEY_ENTER}, /*play ok */
{0x1be4, KEY_Z}, /*zoom */
{0x59a6, KEY_M}, /*mute */
{0x5ba5, KEY_F}, /*tv/f */
{0x19e7, KEY_R}, /*rec */
{0x01fe, KEY_S}, /*Stop */
{0x03fd, KEY_P}, /*pause */
{0x03fc, KEY_W}, /*<- -> */
{0x07f9, KEY_C}, /*capture */
{0x47b9, KEY_Q}, /*exit */
{0x43bc, KEY_O}, /*power */
};
......@@ -405,8 +405,7 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
send_key = (send_key & 0xffff) | 0x0100;
for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
if ((opera1_rc_keys[i].custom * 256 +
opera1_rc_keys[i].data) == (send_key & 0xffff)) {
if (rc5_scan(&opera1_rc_keys[i]) == (send_key & 0xffff)) {
*state = REMOTE_KEY_PRESSED;
*event = opera1_rc_keys[i].event;
opst->last_key_pressed =
......
......@@ -175,8 +175,8 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
/* keys for the enclosed remote control */
static struct dvb_usb_rc_key vp702x_rc_keys[] = {
{ 0x00, 0x01, KEY_1 },
{ 0x00, 0x02, KEY_2 },
{ 0x0001, KEY_1 },
{ 0x0002, KEY_2 },
};
/* remote control stuff (does not work with my box) */
......@@ -198,7 +198,7 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
}
for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++)
if (vp702x_rc_keys[i].custom == key[1]) {
if (rc5_custom(&vp702x_rc_keys[i]) == key[1]) {
*state = REMOTE_KEY_PRESSED;
*event = vp702x_rc_keys[i].event;
break;
......
......@@ -100,56 +100,56 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
/* The keymapping struct. Somehow this should be loaded to the driver, but
* currently it is hardcoded. */
static struct dvb_usb_rc_key vp7045_rc_keys[] = {
{ 0x00, 0x16, KEY_POWER },
{ 0x00, 0x10, KEY_MUTE },
{ 0x00, 0x03, KEY_1 },
{ 0x00, 0x01, KEY_2 },
{ 0x00, 0x06, KEY_3 },
{ 0x00, 0x09, KEY_4 },
{ 0x00, 0x1d, KEY_5 },
{ 0x00, 0x1f, KEY_6 },
{ 0x00, 0x0d, KEY_7 },
{ 0x00, 0x19, KEY_8 },
{ 0x00, 0x1b, KEY_9 },
{ 0x00, 0x15, KEY_0 },
{ 0x00, 0x05, KEY_CHANNELUP },
{ 0x00, 0x02, KEY_CHANNELDOWN },
{ 0x00, 0x1e, KEY_VOLUMEUP },
{ 0x00, 0x0a, KEY_VOLUMEDOWN },
{ 0x00, 0x11, KEY_RECORD },
{ 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
{ 0x00, 0x14, KEY_PLAY },
{ 0x00, 0x1a, KEY_STOP },
{ 0x00, 0x40, KEY_REWIND },
{ 0x00, 0x12, KEY_FASTFORWARD },
{ 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
{ 0x00, 0x4c, KEY_PAUSE },
{ 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
{ 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
{ 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
{ 0x00, 0x1c, KEY_EPG }, /* EPG */
{ 0x00, 0x00, KEY_TAB }, /* Tab */
{ 0x00, 0x48, KEY_INFO }, /* Preview */
{ 0x00, 0x04, KEY_LIST }, /* RecordList */
{ 0x00, 0x0f, KEY_TEXT }, /* Teletext */
{ 0x00, 0x41, KEY_PREVIOUSSONG },
{ 0x00, 0x42, KEY_NEXTSONG },
{ 0x00, 0x4b, KEY_UP },
{ 0x00, 0x51, KEY_DOWN },
{ 0x00, 0x4e, KEY_LEFT },
{ 0x00, 0x52, KEY_RIGHT },
{ 0x00, 0x4f, KEY_ENTER },
{ 0x00, 0x13, KEY_CANCEL },
{ 0x00, 0x4a, KEY_CLEAR },
{ 0x00, 0x54, KEY_PRINT }, /* Capture */
{ 0x00, 0x43, KEY_SUBTITLE }, /* Subtitle/CC */
{ 0x00, 0x08, KEY_VIDEO }, /* A/V */
{ 0x00, 0x07, KEY_SLEEP }, /* Hibernate */
{ 0x00, 0x45, KEY_ZOOM }, /* Zoom+ */
{ 0x00, 0x18, KEY_RED},
{ 0x00, 0x53, KEY_GREEN},
{ 0x00, 0x5e, KEY_YELLOW},
{ 0x00, 0x5f, KEY_BLUE}
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
{ 0x0003, KEY_1 },
{ 0x0001, KEY_2 },
{ 0x0006, KEY_3 },
{ 0x0009, KEY_4 },
{ 0x001d, KEY_5 },
{ 0x001f, KEY_6 },
{ 0x000d, KEY_7 },
{ 0x0019, KEY_8 },
{ 0x001b, KEY_9 },
{ 0x0015, KEY_0 },
{ 0x0005, KEY_CHANNELUP },
{ 0x0002, KEY_CHANNELDOWN },
{ 0x001e, KEY_VOLUMEUP },
{ 0x000a, KEY_VOLUMEDOWN },
{ 0x0011, KEY_RECORD },
{ 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
{ 0x0014, KEY_PLAY },
{ 0x001a, KEY_STOP },
{ 0x0040, KEY_REWIND },
{ 0x0012, KEY_FASTFORWARD },
{ 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
{ 0x004c, KEY_PAUSE },
{ 0x004d, KEY_SCREEN }, /* Full screen mode. */
{ 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
{ 0x000c, KEY_CANCEL }, /* Cancel */
{ 0x001c, KEY_EPG }, /* EPG */
{ 0x0000, KEY_TAB }, /* Tab */
{ 0x0048, KEY_INFO }, /* Preview */
{ 0x0004, KEY_LIST }, /* RecordList */
{ 0x000f, KEY_TEXT }, /* Teletext */
{ 0x0041, KEY_PREVIOUSSONG },
{ 0x0042, KEY_NEXTSONG },
{ 0x004b, KEY_UP },
{ 0x0051, KEY_DOWN },
{ 0x004e, KEY_LEFT },
{ 0x0052, KEY_RIGHT },
{ 0x004f, KEY_ENTER },
{ 0x0013, KEY_CANCEL },
{ 0x004a, KEY_CLEAR },
{ 0x0054, KEY_PRINT }, /* Capture */
{ 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
{ 0x0008, KEY_VIDEO }, /* A/V */
{ 0x0007, KEY_SLEEP }, /* Hibernate */
{ 0x0045, KEY_ZOOM }, /* Zoom+ */
{ 0x0018, KEY_RED},
{ 0x0053, KEY_GREEN},
{ 0x005e, KEY_YELLOW},
{ 0x005f, KEY_BLUE}
};
static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
......@@ -166,7 +166,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
}
for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++)
if (vp7045_rc_keys[i].data == key) {
if (rc5_data(&vp7045_rc_keys[i]) == key) {
*state = REMOTE_KEY_PRESSED;
*event = vp7045_rc_keys[i].event;
break;
......
......@@ -89,15 +89,33 @@ struct avc_response_frame {
u8 operand[509];
};
#define AVC_DEBUG_FCP_SUBACTIONS 1
#define AVC_DEBUG_FCP_PAYLOADS 2
#define AVC_DEBUG_READ_DESCRIPTOR 0x0001
#define AVC_DEBUG_DSIT 0x0002
#define AVC_DEBUG_DSD 0x0004
#define AVC_DEBUG_REGISTER_REMOTE_CONTROL 0x0008
#define AVC_DEBUG_LNB_CONTROL 0x0010
#define AVC_DEBUG_TUNE_QPSK 0x0020
#define AVC_DEBUG_TUNE_QPSK2 0x0040
#define AVC_DEBUG_HOST2CA 0x0080
#define AVC_DEBUG_CA2HOST 0x0100
#define AVC_DEBUG_APPLICATION_PMT 0x4000
#define AVC_DEBUG_FCP_PAYLOADS 0x8000
static int avc_debug;
module_param_named(debug, avc_debug, int, 0644);
MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS)
", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
", or all = -1)");
MODULE_PARM_DESC(debug, "Verbose logging (none = 0"
", FCP subactions"
": READ DESCRIPTOR = " __stringify(AVC_DEBUG_READ_DESCRIPTOR)
", DSIT = " __stringify(AVC_DEBUG_DSIT)
", REGISTER_REMOTE_CONTROL = " __stringify(AVC_DEBUG_REGISTER_REMOTE_CONTROL)
", LNB CONTROL = " __stringify(AVC_DEBUG_LNB_CONTROL)
", TUNE QPSK = " __stringify(AVC_DEBUG_TUNE_QPSK)
", TUNE QPSK2 = " __stringify(AVC_DEBUG_TUNE_QPSK2)
", HOST2CA = " __stringify(AVC_DEBUG_HOST2CA)
", CA2HOST = " __stringify(AVC_DEBUG_CA2HOST)
"; Application sent PMT = " __stringify(AVC_DEBUG_APPLICATION_PMT)
", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
", or a combination, or all = -1)");
static const char *debug_fcp_ctype(unsigned int ctype)
{
......@@ -118,48 +136,70 @@ static const char *debug_fcp_opcode(unsigned int opcode,
const u8 *data, int length)
{
switch (opcode) {
case AVC_OPCODE_VENDOR: break;
case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor";
case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type";
case AVC_OPCODE_DSD: return "DirectSelectData";
default: return "?";
case AVC_OPCODE_VENDOR:
break;
case AVC_OPCODE_READ_DESCRIPTOR:
return avc_debug & AVC_DEBUG_READ_DESCRIPTOR ?
"ReadDescriptor" : NULL;
case AVC_OPCODE_DSIT:
return avc_debug & AVC_DEBUG_DSIT ?
"DirectSelectInfo.Type" : NULL;
case AVC_OPCODE_DSD:
return avc_debug & AVC_DEBUG_DSD ? "DirectSelectData" : NULL;
default:
return "Unknown";
}
if (length < 7 ||
data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
data[5] != SFE_VENDOR_DE_COMPANYID_2)
return "Vendor";
return "Vendor/Unknown";
switch (data[6]) {
case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC";
case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl";
case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK";
case SFE_VENDOR_OPCODE_TUNE_QPSK2: return "TuneQPSK2";
case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA";
case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host";
case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:
return avc_debug & AVC_DEBUG_REGISTER_REMOTE_CONTROL ?
"RegisterRC" : NULL;
case SFE_VENDOR_OPCODE_LNB_CONTROL:
return avc_debug & AVC_DEBUG_LNB_CONTROL ? "LNBControl" : NULL;
case SFE_VENDOR_OPCODE_TUNE_QPSK:
return avc_debug & AVC_DEBUG_TUNE_QPSK ? "TuneQPSK" : NULL;
case SFE_VENDOR_OPCODE_TUNE_QPSK2:
return avc_debug & AVC_DEBUG_TUNE_QPSK2 ? "TuneQPSK2" : NULL;
case SFE_VENDOR_OPCODE_HOST2CA:
return avc_debug & AVC_DEBUG_HOST2CA ? "Host2CA" : NULL;
case SFE_VENDOR_OPCODE_CA2HOST:
return avc_debug & AVC_DEBUG_CA2HOST ? "CA2Host" : NULL;
}
return "Vendor";
return "Vendor/Unknown";
}
static void debug_fcp(const u8 *data, int length)
{
unsigned int subunit_type, subunit_id, op;
const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
unsigned int subunit_type, subunit_id, opcode;
const char *op, *prefix;
prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
subunit_type = data[1] >> 3;
subunit_id = data[1] & 7;
opcode = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
op = debug_fcp_opcode(opcode, data, length);
if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) {
subunit_type = data[1] >> 3;
subunit_id = data[1] & 7;
op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
if (op) {
printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
prefix, subunit_type, subunit_id, length,
debug_fcp_ctype(data[0]),
debug_fcp_opcode(op, data, length));
debug_fcp_ctype(data[0]), op);
if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE,
16, 1, data, length, false);
}
}
if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1,
data, length, false);
static void debug_pmt(char *msg, int length)
{
printk(KERN_INFO "APP PMT -> l=%d\n", length);
print_hex_dump(KERN_INFO, "APP PMT -> ", DUMP_PREFIX_NONE,
16, 1, msg, length, false);
}
static int __avc_write(struct firedtv *fdtv,
......@@ -254,6 +294,26 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length)
return 0;
}
static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
{
int i, n, pos = 1;
for (i = 0, n = 0; i < 16; i++) {
if (test_bit(i, &fdtv->channel_active)) {
operand[pos++] = 0x13; /* flowfunction relay */
operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
operand[pos++] = (fdtv->channel_pid[i] >> 8) & 0x1f;
operand[pos++] = fdtv->channel_pid[i] & 0xff;
operand[pos++] = 0x00; /* tableID */
operand[pos++] = 0x00; /* filter_length */
n++;
}
}
operand[0] = n;
return pos;
}
/*
* tuning command for setting the relative LNB frequency
* (not supported by the AVC standard)
......@@ -316,7 +376,8 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
}
}
static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
struct dvb_frontend_parameters *params,
struct avc_command_frame *c)
{
c->opcode = AVC_OPCODE_DSD;
......@@ -378,13 +439,13 @@ static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
c->operand[20] = 0x00;
c->operand[21] = 0x00;
/* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
c->operand[22] = 0x00;
c->length = 28;
/* Add PIDs to filter */
c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
}
static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
struct dvb_frontend_parameters *params,
struct avc_command_frame *c)
{
struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
......@@ -481,10 +542,9 @@ static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
c->operand[15] = 0x00; /* network_ID[0] */
c->operand[16] = 0x00; /* network_ID[1] */
/* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
c->operand[17] = 0x00;
c->length = 24;
/* Add PIDs to filter */
c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
}
int avc_tuner_dsd(struct firedtv *fdtv,
......@@ -502,8 +562,8 @@ int avc_tuner_dsd(struct firedtv *fdtv,
switch (fdtv->type) {
case FIREDTV_DVB_S:
case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break;
case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break;
case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break;
case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break;
default:
BUG();
}
......@@ -963,6 +1023,9 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
int es_info_length;
int crc32_csum;
if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
debug_pmt(msg, length);
memset(c, 0, sizeof(*c));
c->ctype = AVC_CTYPE_CONTROL;
......
......@@ -81,6 +81,13 @@ config DVB_ZL10036
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_ZL10039
tristate "Zarlink ZL10039 silicon tuner"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_S5H1420
tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C
......
......@@ -31,6 +31,7 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o
obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10036) += zl10036.o
obj-$(CONFIG_DVB_ZL10039) += zl10039.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
......
......@@ -155,7 +155,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet
p->hierarchy_information > HIERARCHY_4)
return -EINVAL;
if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ)
if (p->bandwidth < BANDWIDTH_8_MHZ || p->bandwidth > BANDWIDTH_6_MHZ)
return -EINVAL;
if (p->bandwidth == BANDWIDTH_7_MHZ)
......
......@@ -303,6 +303,7 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
{
s32 N;
s64 F;
u64 dividend;
u8 R, r;
u8 vcodiv;
u8 factor;
......@@ -346,7 +347,10 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
F = freq_hz;
F *= (u64) (R * vcodiv * 262144);
dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
do_div(F, state->config->xtal_khz*1000 * factor * 2);
/* do_div needs an u64 as first argument */
dividend = F;
do_div(dividend, state->config->xtal_khz * 1000 * factor * 2);
F = dividend;
dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
F -= (N + 32) * 262144;
......
......@@ -458,7 +458,7 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
/* check if symbol rate is within limits */
if ((srate > state->frontend.ops.info.symbol_rate_max) ||
(srate < state->frontend.ops.info.symbol_rate_min))
return -EOPNOTSUPP;;
return -EOPNOTSUPP;
/* choose the sampling rate high enough for the required operation,
while optimizing the power consumed by the demodulator */
......
......@@ -167,7 +167,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par
break;
case BAND_SBAND:
LO4_SET_VCO_HFDIV(lo4, 0, 0);
LO4_SET_CTRIM(lo4, 1);;
LO4_SET_CTRIM(lo4, 1);
c = 1;
break;
case BAND_UHF:
......
......@@ -883,7 +883,7 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32
255, 255, 255, 255, 255, 255};
u32 xtal = state->cfg.bw->xtal_hz / 1000;
int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
int k;
int coef_re[8],coef_im[8];
int bw_khz = bw;
......
This diff is collapsed.
......@@ -23,6 +23,10 @@
#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
#define DVB_PLL_OPERA1 13
#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
#define DVB_PLL_SAMSUNG_TDTC9251DH0 15
#define DVB_PLL_SAMSUNG_TBDU18132 16
#define DVB_PLL_SAMSUNG_TBMU24112 17
#define DVB_PLL_TDEE4 18
/**
* Attach a dvb-pll to the supplied frontend structure.
......
This diff is collapsed.
/*
* Support for Legend Silicon DMB-TH demodulator
* LGS8913, LGS8GL5
* Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
* LGS8913, LGS8GL5, LGS8G75
* experimental support LGS8G42, LGS8G52
*
* Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
* Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
* Copyright (C) 2008 Sirius International (Hong Kong) Limited
* Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
*
......@@ -34,6 +34,7 @@
#define LGS8GXX_PROD_LGS8G42 3
#define LGS8GXX_PROD_LGS8G52 4
#define LGS8GXX_PROD_LGS8G54 5
#define LGS8GXX_PROD_LGS8G75 6
struct lgs8gxx_config {
......@@ -70,6 +71,10 @@ struct lgs8gxx_config {
/*IF use Negative center frequency*/
u8 if_neg_center;
/*8G75 internal ADC input range selection*/
/*0: 0.8Vpp, 1: 1.0Vpp, 2: 1.6Vpp, 3: 2.0Vpp*/
u8 adc_vpp;
/* slave address and configuration of the tuner */
u8 tuner_address;
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -367,7 +367,9 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
/* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
nint = fvco / (state->reference << psd2);
/* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference;
nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
<< (9 - psd2),
state->reference);
dprintk(verbose, FE_DEBUG, 1,
"frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
frequency, srate, (unsigned int)g, (unsigned int)odiv,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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