From 558ac33e094f3a47c74a3a66b19cd3616f183184 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 24 May 2005 19:31:10 -0700 Subject: [PATCH] saa6752hs build fix For older gcc's. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa6752hs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index fe6abe34168..1db02268298 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -43,15 +43,15 @@ enum saa6752hs_videoformat { static const struct v4l2_format v4l2_format_table[] = { [SAA6752HS_VF_D1] = { - .fmt.pix.width = 720, .fmt.pix.height = 576 }, + .fmt = { .pix = { .width = 720, .height = 576 }, }, }, [SAA6752HS_VF_2_3_D1] = { - .fmt.pix.width = 480, .fmt.pix.height = 576 }, + .fmt = { .pix = { .width = 480, .height = 576 }, }, }, [SAA6752HS_VF_1_2_D1] = { - .fmt.pix.width = 352, .fmt.pix.height = 576 }, + .fmt = { .pix = { .width = 352, .height = 576 }, }, }, [SAA6752HS_VF_SIF] = { - .fmt.pix.width = 352, .fmt.pix.height = 288 }, + .fmt = { .pix = { .width = 352, .height = 288 }, }, }, [SAA6752HS_VF_UNKNOWN] = { - .fmt.pix.width = 0, .fmt.pix.height = 0}, + .fmt = { .pix = { .width = 0, .height = 0 }, }, }, }; struct saa6752hs_state { -- cgit v1.2.3-70-g09d2 From 5daf05fbf73fc199e7a93a818e504856d07c5586 Mon Sep 17 00:00:00 2001 From: Gerd Knorr Date: Wed, 25 May 2005 12:31:26 -0700 Subject: [PATCH] v4l: bttv i2c oops fix Don't try to access the i2c bus if the register wasn't successful. Signed-off-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/bttv-i2c.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index e3f477dff82..c2368bc832e 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -363,6 +363,9 @@ int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, /* read EEPROM content */ void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) { + memset(eedata, 0, 256); + if (0 != btv->i2c_rc) + return; btv->i2c_client.addr = addr >> 1; tveeprom_read(&btv->i2c_client, eedata, 256); } -- cgit v1.2.3-70-g09d2 From 203fe8b3d1f5b1b527e86f6dbe5b75960acb7f4f Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:48 -0700 Subject: [PATCH] dvb: Fix Mini DiSEqC bug The bug was visible as a warning with gcc-3.4.4 (prerelease) Message: drivers/media/dvb/bt8xx/dst.c:1349: warning: initialization from incompatible pointer type. Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index d047e349d70..2efc6f1caf8 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -915,13 +915,11 @@ static int dst_tone_power_cmd(struct dst_state* state) paket[2] = 0x02; else paket[2] = 0; - if (state->minicmd == SEC_MINI_A) - paket[3] = 0x02; - else - paket[3] = 0; + paket[3] = state->tx_tuna[3]; paket[7] = dst_check_sum (paket, 7); dst_command(state, paket, 8); + return 0; } @@ -1134,6 +1132,29 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) return 0; } +static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) +{ + struct dst_state *state = fe->demodulator_priv; + + if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) + return 0; + + state->minicmd = minicmd; + + switch (minicmd) { + case SEC_MINI_A: + state->tx_tuna[3] = 0x02; + break; + case SEC_MINI_B: + state->tx_tuna[3] = 0xff; + break; + } + dst_tone_power_cmd(state); + + return 0; +} + + static int dst_init(struct dvb_frontend* fe) { struct dst_state* state = (struct dst_state*) fe->demodulator_priv; @@ -1346,7 +1367,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr, - .diseqc_send_burst = dst_set_tone, + .diseqc_send_burst = dst_send_burst, .diseqc_send_master_cmd = dst_set_diseqc, .set_voltage = dst_set_voltage, .set_tone = dst_set_tone, -- cgit v1.2.3-70-g09d2 From 0eac3e486e1f246a9d59fee9251cc69e409cb58e Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:50 -0700 Subject: [PATCH] dvb: Remove unnecessary casts Cleanup unnecessary (and undesirable) casts, demodulator_priv is already a void*. Suggestion from Andrew Morton Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 2efc6f1caf8..e5e8c3e869c 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -978,7 +978,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage); static int dst_write_tuna(struct dvb_frontend* fe) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; int retval; u8 reply; @@ -1046,7 +1046,7 @@ static int dst_write_tuna(struct dvb_frontend* fe) static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; if (state->dst_type == DST_TYPE_IS_TERR) @@ -1064,7 +1064,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { u8 *val; int need_cmd; - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; state->voltage = voltage; @@ -1105,7 +1105,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { u8 *val; - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; state->tone = tone; @@ -1157,7 +1157,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) static int dst_init(struct dvb_frontend* fe) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; @@ -1189,7 +1189,7 @@ static int dst_init(struct dvb_frontend* fe) static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; *status = 0; if (state->diseq_flags & HAS_LOCK) { @@ -1203,7 +1203,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; dst_get_signal(state); *strength = state->decode_strength; @@ -1213,7 +1213,7 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) static int dst_read_snr(struct dvb_frontend* fe, u16* snr) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; dst_get_signal(state); *snr = state->decode_snr; @@ -1223,7 +1223,7 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr) static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; dst_set_freq(state, p->frequency); if (verbose > 4) @@ -1249,7 +1249,7 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; p->frequency = state->decode_freq; p->inversion = state->inversion; @@ -1269,7 +1269,7 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet static void dst_release(struct dvb_frontend* fe) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; kfree(state); } -- cgit v1.2.3-70-g09d2 From 8f6da8f166228c1720d16216a9d82d630c58de57 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:51 -0700 Subject: [PATCH] dvb: Fix LNB power switching Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index e5e8c3e869c..33cca69d67a 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -906,10 +906,7 @@ static int dst_tone_power_cmd(struct dst_state* state) if (state->dst_type == DST_TYPE_IS_TERR) return 0; - if (state->voltage == SEC_VOLTAGE_OFF) - paket[4] = 0; - else - paket[4] = 1; + paket[4] = state->tx_tuna[4]; if (state->tone == SEC_TONE_ON) paket[2] = 0x02; @@ -1062,7 +1059,6 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { - u8 *val; int need_cmd; struct dst_state* state = fe->demodulator_priv; @@ -1072,29 +1068,23 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) return 0; need_cmd = 0; - val = &state->tx_tuna[0]; - val[8] &= ~0x40; switch (voltage) { - case SEC_VOLTAGE_13: - if ((state->diseq_flags & HAS_POWER) == 0) - need_cmd = 1; - state->diseq_flags |= HAS_POWER; - break; + case SEC_VOLTAGE_13: + case SEC_VOLTAGE_18: + if ((state->diseq_flags & HAS_POWER) == 0) + need_cmd = 1; + state->diseq_flags |= HAS_POWER; + state->tx_tuna[4] = 0x01; + break; - case SEC_VOLTAGE_18: - if ((state->diseq_flags & HAS_POWER) == 0) + case SEC_VOLTAGE_OFF: need_cmd = 1; - state->diseq_flags |= HAS_POWER; - val[8] |= 0x40; - break; - - case SEC_VOLTAGE_OFF: - need_cmd = 1; - state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); - break; + state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); + state->tx_tuna[4] = 0x00; + break; - default: - return -EINVAL; + default: + return -EINVAL; } if (need_cmd) dst_tone_power_cmd(state); -- cgit v1.2.3-70-g09d2 From 86360a3edeb6b7b6230dc13ef6835d2851409502 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:51 -0700 Subject: [PATCH] dvb: Fix 22k tone control Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 33cca69d67a..8104240a220 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -907,12 +907,7 @@ static int dst_tone_power_cmd(struct dst_state* state) return 0; paket[4] = state->tx_tuna[4]; - - if (state->tone == SEC_TONE_ON) - paket[2] = 0x02; - else - paket[2] = 0; - + paket[2] = state->tx_tuna[2]; paket[3] = state->tx_tuna[3]; paket[7] = dst_check_sum (paket, 7); dst_command(state, paket, 8); @@ -1094,7 +1089,6 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { - u8 *val; struct dst_state* state = fe->demodulator_priv; state->tone = tone; @@ -1102,20 +1096,17 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) if (state->dst_type == DST_TYPE_IS_TERR) return 0; - val = &state->tx_tuna[0]; - - val[8] &= ~0x1; - switch (tone) { - case SEC_TONE_OFF: - break; + case SEC_TONE_OFF: + state->tx_tuna[2] = 0xff; + break; - case SEC_TONE_ON: - val[8] |= 1; - break; + case SEC_TONE_ON: + state->tx_tuna[2] = 0x02; + break; - default: - return -EINVAL; + default: + return -EINVAL; } dst_tone_power_cmd(state); -- cgit v1.2.3-70-g09d2 From 226d97ec3e47b54ecc13f6ea3c300dc6a1b290c3 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:52 -0700 Subject: [PATCH] dvb: Small cleanup Miscellaneous cleanup Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 8104240a220..1339912c308 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -1041,7 +1041,7 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* struct dst_state* state = fe->demodulator_priv; u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; - if (state->dst_type == DST_TYPE_IS_TERR) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; if (cmd->msg_len == 0 || cmd->msg_len > 4) @@ -1059,7 +1059,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) state->voltage = voltage; - if (state->dst_type == DST_TYPE_IS_TERR) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; need_cmd = 0; @@ -1093,7 +1093,7 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) state->tone = tone; - if (state->dst_type == DST_TYPE_IS_TERR) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; switch (tone) { @@ -1117,7 +1117,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) { struct dst_state *state = fe->demodulator_priv; - if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; state->minicmd = minicmd; -- cgit v1.2.3-70-g09d2 From 56b2293595b2eb52cc2aa2baf92c6cfa8265f9d5 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Wed, 23 Mar 2005 10:01:41 -0800 Subject: [PATCH] class: convert drivers/* to use the new class api instead of class_simple Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 14 +++++++------- drivers/macintosh/adb.c | 9 ++++----- drivers/media/dvb/dvb-core/dvbdev.c | 13 ++++++------- drivers/net/ppp_generic.c | 14 +++++++------- drivers/net/wan/cosa.c | 12 ++++++------ drivers/s390/char/tape_class.c | 10 +++++----- drivers/s390/char/vmlogrdr.c | 10 +++++----- drivers/usb/core/file.c | 12 ++++++------ drivers/video/fbmem.c | 10 +++++----- 9 files changed, 51 insertions(+), 53 deletions(-) (limited to 'drivers/media') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 12dee8e9fbb..04fb606b5dd 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -58,7 +58,7 @@ MODULE_LICENSE("GPL"); /* -------- driver information -------------------------------------- */ -static struct class_simple *capi_class; +static struct class *capi_class; static int capi_major = 68; /* allocated */ #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -1499,20 +1499,20 @@ static int __init capi_init(void) return -EIO; } - capi_class = class_simple_create(THIS_MODULE, "capi"); + capi_class = class_create(THIS_MODULE, "capi"); if (IS_ERR(capi_class)) { unregister_chrdev(capi_major, "capi20"); return PTR_ERR(capi_class); } - class_simple_device_add(capi_class, MKDEV(capi_major, 0), NULL, "capi"); + class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi"); devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, "isdn/capi20"); #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE if (capinc_tty_init() < 0) { - class_simple_device_remove(MKDEV(capi_major, 0)); - class_simple_destroy(capi_class); + class_device_destroy(capi_class, MKDEV(capi_major, 0)); + class_destroy(capi_class); unregister_chrdev(capi_major, "capi20"); return -ENOMEM; } @@ -1539,8 +1539,8 @@ static void __exit capi_exit(void) { proc_exit(); - class_simple_device_remove(MKDEV(capi_major, 0)); - class_simple_destroy(capi_class); + class_device_destroy(capi_class, MKDEV(capi_major, 0)); + class_destroy(capi_class); unregister_chrdev(capi_major, "capi20"); devfs_remove("isdn/capi20"); diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 7297c77f99c..493e2afa191 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -77,7 +77,7 @@ static struct adb_driver *adb_driver_list[] = { NULL }; -static struct class_simple *adb_dev_class; +static struct class *adb_dev_class; struct adb_driver *adb_controller; struct notifier_block *adb_client_list = NULL; @@ -902,9 +902,8 @@ adbdev_init(void) devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb"); - adb_dev_class = class_simple_create(THIS_MODULE, "adb"); - if (IS_ERR(adb_dev_class)) { + adb_dev_class = class_create(THIS_MODULE, "adb"); + if (IS_ERR(adb_dev_class)) return; - } - class_simple_device_add(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb"); + class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb"); } diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 9d9662f4b8e..4b7adca3e28 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -56,8 +56,7 @@ static const char * const dnames[] = { #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) #define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) -struct class_simple *dvb_class; -EXPORT_SYMBOL(dvb_class); +static struct class *dvb_class; static struct dvb_device* dvbdev_find_device (int minor) { @@ -236,8 +235,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, S_IFCHR | S_IRUSR | S_IWUSR, "dvb/adapter%d/%s%d", adap->num, dnames[type], id); - class_simple_device_add(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), - NULL, "dvb%d.%s%d", adap->num, dnames[type], id); + class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), + NULL, "dvb%d.%s%d", adap->num, dnames[type], id); dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, nums2minor(adap->num, type, id), @@ -256,7 +255,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev) devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id); - class_simple_device_remove(MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, + class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, dvbdev->type, dvbdev->id))); list_del (&dvbdev->list_head); @@ -412,7 +411,7 @@ static int __init init_dvbdev(void) devfs_mk_dir("dvb"); - dvb_class = class_simple_create(THIS_MODULE, "dvb"); + dvb_class = class_create(THIS_MODULE, "dvb"); if (IS_ERR(dvb_class)) { retval = PTR_ERR(dvb_class); goto error; @@ -429,7 +428,7 @@ error: static void __exit exit_dvbdev(void) { devfs_remove("dvb"); - class_simple_destroy(dvb_class); + class_destroy(dvb_class); cdev_del(&dvb_device_cdev); unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); } diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ad4b58af6b7..ab726ab4379 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -273,7 +273,7 @@ static int ppp_connect_channel(struct channel *pch, int unit); static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); -static struct class_simple *ppp_class; +static struct class *ppp_class; /* Translates a PPP protocol number to a NP index (NP == network protocol) */ static inline int proto_to_npindex(int proto) @@ -858,12 +858,12 @@ static int __init ppp_init(void) printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); if (!err) { - ppp_class = class_simple_create(THIS_MODULE, "ppp"); + ppp_class = class_create(THIS_MODULE, "ppp"); if (IS_ERR(ppp_class)) { err = PTR_ERR(ppp_class); goto out_chrdev; } - class_simple_device_add(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); + class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "ppp"); if (err) @@ -876,8 +876,8 @@ out: return err; out_class: - class_simple_device_remove(MKDEV(PPP_MAJOR,0)); - class_simple_destroy(ppp_class); + class_device_destroy(ppp_class, MKDEV(PPP_MAJOR,0)); + class_destroy(ppp_class); out_chrdev: unregister_chrdev(PPP_MAJOR, "ppp"); goto out; @@ -2654,8 +2654,8 @@ static void __exit ppp_cleanup(void) if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) printk(KERN_ERR "PPP: failed to unregister PPP device\n"); devfs_remove("ppp"); - class_simple_device_remove(MKDEV(PPP_MAJOR, 0)); - class_simple_destroy(ppp_class); + class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); + class_destroy(ppp_class); } /* diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 921a573372e..7ff814fd65d 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -235,7 +235,7 @@ static int dma[MAX_CARDS+1]; static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, }; /* for class stuff*/ -static struct class_simple *cosa_class; +static struct class *cosa_class; #ifdef MODULE module_param_array(io, int, NULL, 0); @@ -394,19 +394,19 @@ static int __init cosa_init(void) goto out; } devfs_mk_dir("cosa"); - cosa_class = class_simple_create(THIS_MODULE, "cosa"); + cosa_class = class_create(THIS_MODULE, "cosa"); if (IS_ERR(cosa_class)) { err = PTR_ERR(cosa_class); goto out_chrdev; } for (i=0; iclass_device = class_simple_device_add( + tcd->class_device = class_device_create( tape_class, tcd->char_device->dev, device, @@ -101,7 +101,7 @@ void unregister_tape_dev(struct tape_class_device *tcd) &tcd->class_device->dev->kobj, tcd->mode_name ); - class_simple_device_remove(tcd->char_device->dev); + class_device_destroy(tape_class, tcd->char_device->dev); cdev_del(tcd->char_device); kfree(tcd); } @@ -111,14 +111,14 @@ EXPORT_SYMBOL(unregister_tape_dev); static int __init tape_init(void) { - tape_class = class_simple_create(THIS_MODULE, "tape390"); + tape_class = class_create(THIS_MODULE, "tape390"); return 0; } static void __exit tape_exit(void) { - class_simple_destroy(tape_class); + class_destroy(tape_class); tape_class = NULL; } diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index edf50d2bd10..724ad87f061 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -703,7 +703,7 @@ static struct attribute_group vmlogrdr_attr_group = { .attrs = vmlogrdr_attrs, }; -static struct class_simple *vmlogrdr_class; +static struct class *vmlogrdr_class; static struct device_driver vmlogrdr_driver = { .name = "vmlogrdr", .bus = &iucv_bus, @@ -727,7 +727,7 @@ vmlogrdr_register_driver(void) { goto unregdriver; } - vmlogrdr_class = class_simple_create(THIS_MODULE, "vmlogrdr"); + vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); if (IS_ERR(vmlogrdr_class)) { printk(KERN_ERR "vmlogrdr: failed to create class.\n"); ret=PTR_ERR(vmlogrdr_class); @@ -746,7 +746,7 @@ unregdriver: static void vmlogrdr_unregister_driver(void) { - class_simple_destroy(vmlogrdr_class); + class_destroy(vmlogrdr_class); vmlogrdr_class = NULL; driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); driver_unregister(&vmlogrdr_driver); @@ -786,7 +786,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { device_unregister(dev); return ret; } - priv->class_device = class_simple_device_add( + priv->class_device = class_device_create( vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num), dev, @@ -806,7 +806,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) { - class_simple_device_remove(MKDEV(vmlogrdr_major, priv->minor_num)); + class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num)); if (priv->device != NULL) { sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group); device_unregister(priv->device); diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 38ed2220c9f..dfcbd05d0e8 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -68,7 +68,7 @@ static struct file_operations usb_fops = { .open = usb_open, }; -static struct class_simple *usb_class; +static struct class *usb_class; int usb_major_init(void) { @@ -80,9 +80,9 @@ int usb_major_init(void) goto out; } - usb_class = class_simple_create(THIS_MODULE, "usb"); + usb_class = class_create(THIS_MODULE, "usb"); if (IS_ERR(usb_class)) { - err("class_simple_create failed for usb devices"); + err("class_create failed for usb devices"); unregister_chrdev(USB_MAJOR, "usb"); goto out; } @@ -95,7 +95,7 @@ out: void usb_major_cleanup(void) { - class_simple_destroy(usb_class); + class_destroy(usb_class); devfs_remove("usb"); unregister_chrdev(USB_MAJOR, "usb"); } @@ -171,7 +171,7 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->class_dev = class_simple_device_add(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp); + intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp); if (IS_ERR(intf->class_dev)) { spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; @@ -220,7 +220,7 @@ void usb_deregister_dev(struct usb_interface *intf, snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); devfs_remove (name); - class_simple_device_remove(MKDEV(USB_MAJOR, intf->minor)); + class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); intf->class_dev = NULL; intf->minor = -1; } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 7705070191d..8cef020d180 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1040,7 +1040,7 @@ static struct file_operations fb_fops = { #endif }; -static struct class_simple *fb_class; +static struct class *fb_class; /** * register_framebuffer - registers a frame buffer device @@ -1066,7 +1066,7 @@ register_framebuffer(struct fb_info *fb_info) break; fb_info->node = i; - fb_info->class_device = class_simple_device_add(fb_class, MKDEV(FB_MAJOR, i), + fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i), fb_info->device, "fb%d", i); if (IS_ERR(fb_info->class_device)) { /* Not fatal */ @@ -1134,7 +1134,7 @@ unregister_framebuffer(struct fb_info *fb_info) registered_fb[i]=NULL; num_registered_fb--; fb_cleanup_class_device(fb_info); - class_simple_device_remove(MKDEV(FB_MAJOR, i)); + class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); return 0; } @@ -1197,7 +1197,7 @@ fbmem_init(void) if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) printk("unable to get major %d for fb devs\n", FB_MAJOR); - fb_class = class_simple_create(THIS_MODULE, "graphics"); + fb_class = class_create(THIS_MODULE, "graphics"); if (IS_ERR(fb_class)) { printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class)); fb_class = NULL; @@ -1210,7 +1210,7 @@ module_init(fbmem_init); static void __exit fbmem_exit(void) { - class_simple_destroy(fb_class); + class_destroy(fb_class); } module_exit(fbmem_exit); -- cgit v1.2.3-70-g09d2 From b3d5496ea5915fa4848fe307af9f7097f312e932 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 2 Apr 2005 20:31:02 +0200 Subject: [PATCH] I2C: Kill address ranges in non-sensors i2c chip drivers Some months ago, you killed the address ranges mechanism from all sensors i2c chip drivers (both the module parameters and the in-code address lists). I think it was a very good move, as the ranges can easily be replaced by individual addresses, and this allowed for significant cleanups in the i2c core (let alone the impressive size shrink for all these drivers). Unfortunately you did not do the same for non-sensors i2c chip drivers. These need the address ranges even less, so we could get rid of the ranges here as well for another significant i2c core cleanup. Here comes a patch which does just that. Since the process is exactly the same as what you did for the other drivers set already, I did not split this one in parts. A documentation update is included. The change saves 308 bytes in the i2c core, and an average 1382 bytes for chip drivers which use I2C_CLIENT_INSMOD, 126 bytes for those which do not. This change is required if we want to merge the sensors and non-sensors i2c code (and we want to do this). Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Index: gregkh-2.6/Documentation/i2c/writing-clients =================================================================== --- Documentation/i2c/writing-clients | 62 +++++++-------------------------- drivers/acorn/char/pcf8583.c | 3 -- drivers/i2c/chips/isp1301_omap.c | 1 - drivers/i2c/chips/m41t00.c | 3 -- drivers/i2c/chips/rtc8564.c | 3 -- drivers/i2c/i2c-core.c | 35 ------------------- drivers/macintosh/therm_windtunnel.c | 6 ++-- drivers/media/video/adv7170.c | 6 ---- drivers/media/video/adv7175.c | 6 ---- drivers/media/video/bt819.c | 6 ---- drivers/media/video/bt832.c | 4 +-- drivers/media/video/bt856.c | 6 ---- drivers/media/video/msp3400.c | 1 - drivers/media/video/saa5246a.c | 1 - drivers/media/video/saa5249.c | 1 - drivers/media/video/saa7110.c | 6 ---- drivers/media/video/saa7111.c | 6 ---- drivers/media/video/saa7114.c | 6 ---- drivers/media/video/saa7134/saa6752hs.c | 1 - drivers/media/video/saa7185.c | 6 ---- drivers/media/video/tda7432.c | 1 - drivers/media/video/tda9840.c | 1 - drivers/media/video/tda9875.c | 1 - drivers/media/video/tda9887.c | 1 - drivers/media/video/tea6415c.c | 1 - drivers/media/video/tea6420.c | 1 - drivers/media/video/tuner-3036.c | 13 +++---- drivers/media/video/tuner-core.c | 11 +++--- drivers/media/video/tvaudio.c | 1 - drivers/media/video/tveeprom.c | 1 - drivers/media/video/vpx3220.c | 6 ---- drivers/video/matrox/matroxfb_maven.c | 1 - include/linux/i2c.h | 12 ------- 33 files changed, 27 insertions(+), 193 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index ad27511e3c7..f482dae81de 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -171,45 +171,31 @@ The following lists are used internally: normal_i2c: filled in by the module writer. A list of I2C addresses which should normally be examined. - normal_i2c_range: filled in by the module writer. - A list of pairs of I2C addresses, each pair being an inclusive range of - addresses which should normally be examined. probe: insmod parameter. A list of pairs. The first value is a bus number (-1 for any I2C bus), the second is the address. These addresses are also probed, as if they were in the 'normal' list. - probe_range: insmod parameter. - A list of triples. The first value is a bus number (-1 for any I2C bus), - the second and third are addresses. These form an inclusive range of - addresses that are also probed, as if they were in the 'normal' list. ignore: insmod parameter. A list of pairs. The first value is a bus number (-1 for any I2C bus), the second is the I2C address. These addresses are never probed. This parameter overrules 'normal' and 'probe', but not the 'force' lists. - ignore_range: insmod parameter. - A list of triples. The first value is a bus number (-1 for any I2C bus), - the second and third are addresses. These form an inclusive range of - I2C addresses that are never probed. - This parameter overrules 'normal' and 'probe', but not the 'force' lists. force: insmod parameter. A list of pairs. The first value is a bus number (-1 for any I2C bus), the second is the I2C address. A device is blindly assumed to be on the given address, no probing is done. -Fortunately, as a module writer, you just have to define the `normal' -and/or `normal_range' parameters. The complete declaration could look -like this: +Fortunately, as a module writer, you just have to define the `normal_i2c' +parameter. The complete declaration could look like this: - /* Scan 0x20 to 0x2f, 0x37, and 0x40 to 0x4f */ - static unsigned short normal_i2c[] = { 0x37,I2C_CLIENT_END }; - static unsigned short normal_i2c_range[] = { 0x20, 0x2f, 0x40, 0x4f, - I2C_CLIENT_END }; + /* Scan 0x37, and 0x48 to 0x4f */ + static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Magic definition of all other variables and things */ I2C_CLIENT_INSMOD; -Note that you *have* to call the two defined variables `normal_i2c' and -`normal_i2c_range', without any prefix! +Note that you *have* to call the defined variable `normal_i2c', +without any prefix! Probing classes (sensors) @@ -223,39 +209,17 @@ The following lists are used internally. They are all lists of integers. normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END. A list of I2C addresses which should normally be examined. - normal_i2c_range: filled in by the module writer. Terminated by - SENSORS_I2C_END - A list of pairs of I2C addresses, each pair being an inclusive range of - addresses which should normally be examined. normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END. A list of ISA addresses which should normally be examined. - normal_isa_range: filled in by the module writer. Terminated by - SENSORS_ISA_END - A list of triples. The first two elements are ISA addresses, being an - range of addresses which should normally be examined. The third is the - modulo parameter: only addresses which are 0 module this value relative - to the first address of the range are actually considered. probe: insmod parameter. Initialize this list with SENSORS_I2C_END values. A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for the ISA bus, -1 for any I2C bus), the second is the address. These addresses are also probed, as if they were in the 'normal' list. - probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END - values. - A list of triples. The first value is a bus number (SENSORS_ISA_BUS for - the ISA bus, -1 for any I2C bus), the second and third are addresses. - These form an inclusive range of addresses that are also probed, as - if they were in the 'normal' list. ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values. A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for the ISA bus, -1 for any I2C bus), the second is the I2C address. These addresses are never probed. This parameter overrules 'normal' and 'probe', but not the 'force' lists. - ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END - values. - A list of triples. The first value is a bus number (SENSORS_ISA_BUS for - the ISA bus, -1 for any I2C bus), the second and third are addresses. - These form an inclusive range of I2C addresses that are never probed. - This parameter overrules 'normal' and 'probe', but not the 'force' lists. Also used is a list of pointers to sensors_force_data structures: force_data: insmod parameters. A list, ending with an element of which @@ -269,16 +233,14 @@ Also used is a list of pointers to sensors_force_data structures: So we have a generic insmod variabled `force', and chip-specific variables `force_CHIPNAME'. -Fortunately, as a module writer, you just have to define the `normal' -and/or `normal_range' parameters, and define what chip names are used. +Fortunately, as a module writer, you just have to define the `normal_i2c' +and `normal_isa' parameters, and define what chip names are used. The complete declaration could look like this: - /* Scan i2c addresses 0x20 to 0x2f, 0x37, and 0x40 to 0x4f - static unsigned short normal_i2c[] = {0x37,SENSORS_I2C_END}; - static unsigned short normal_i2c_range[] = {0x20,0x2f,0x40,0x4f, - SENSORS_I2C_END}; + /* Scan i2c addresses 0x37, and 0x48 to 0x4f */ + static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Scan ISA address 0x290 */ static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END}; - static unsigned int normal_isa_range[] = {SENSORS_ISA_END}; /* Define chips foo and bar, as well as all module parameters and things */ SENSORS_INSMOD_2(foo,bar); diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c index ad7ae7ab892..141b4c237a5 100644 --- a/drivers/acorn/char/pcf8583.c +++ b/drivers/acorn/char/pcf8583.c @@ -26,11 +26,8 @@ static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_addr, - .normal_i2c_range = ignore, .probe = ignore, - .probe_range = ignore, .ignore = ignore, - .ignore_range = ignore, .force = ignore, }; diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 7f29a8aff16..354a2629567 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -145,7 +145,6 @@ static inline void notresponding(struct isp1301 *isp) static unsigned short normal_i2c[] = { ISP_BASE, ISP_BASE + 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index e771566dffa..5e463c47bfb 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c @@ -40,11 +40,8 @@ static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_addr, - .normal_i2c_range = ignore, .probe = ignore, - .probe_range = ignore, .ignore = ignore, - .ignore_range = ignore, .force = ignore, }; diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c index 5a9deddb626..30f553e7370 100644 --- a/drivers/i2c/chips/rtc8564.c +++ b/drivers/i2c/chips/rtc8564.c @@ -66,11 +66,8 @@ static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_addr, - .normal_i2c_range = ignore, .probe = ignore, - .probe_range = ignore, .ignore = ignore, - .ignore_range = ignore, .force = ignore, }; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a22e53badac..4cc8c9f7211 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -742,18 +742,6 @@ int i2c_probe(struct i2c_adapter *adapter, found = 1; } } - for (i = 0; - !found && (address_data->ignore_range[i] != I2C_CLIENT_END); - i += 3) { - if (((adap_id == address_data->ignore_range[i]) || - ((address_data->ignore_range[i]==ANY_I2C_BUS))) && - (addr >= address_data->ignore_range[i+1]) && - (addr <= address_data->ignore_range[i+2])) { - dev_dbg(&adapter->dev, "found ignore_range parameter for adapter %d, " - "addr %04x\n", adap_id,addr); - found = 1; - } - } if (found) continue; @@ -769,17 +757,6 @@ int i2c_probe(struct i2c_adapter *adapter, } } - for (i = 0; - !found && (address_data->normal_i2c_range[i] != I2C_CLIENT_END); - i += 2) { - if ((addr >= address_data->normal_i2c_range[i]) && - (addr <= address_data->normal_i2c_range[i+1])) { - found = 1; - dev_dbg(&adapter->dev, "found normal i2c_range entry for adapter %d, " - "addr %04x\n", adap_id,addr); - } - } - for (i = 0; !found && (address_data->probe[i] != I2C_CLIENT_END); i += 2) { @@ -791,18 +768,6 @@ int i2c_probe(struct i2c_adapter *adapter, "addr %04x\n", adap_id,addr); } } - for (i = 0; - !found && (address_data->probe_range[i] != I2C_CLIENT_END); - i += 3) { - if (((adap_id == address_data->probe_range[i]) || - (address_data->probe_range[i] == ANY_I2C_BUS)) && - (addr >= address_data->probe_range[i+1]) && - (addr <= address_data->probe_range[i+2])) { - found = 1; - dev_dbg(&adapter->dev, "found probe_range parameter for adapter %d, " - "addr %04x\n", adap_id,addr); - } - } if (!found) continue; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 0bdb47f08c2..61400f04015 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -51,8 +51,10 @@ static int do_probe( struct i2c_adapter *adapter, int addr, int kind); /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ -static unsigned short normal_i2c[] = { 0x49, 0x2c, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { 0x48, 0x4f, 0x2c, 0x2f, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; I2C_CLIENT_INSMOD; diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 80254caa444..e9bf3394296 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -384,21 +384,15 @@ static unsigned short normal_i2c[] = I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 95d0974b0ab..2d5fa44fcd4 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -434,21 +434,15 @@ static unsigned short normal_i2c[] = I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index cf0db2554a8..31d51851bb4 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -500,21 +500,15 @@ static unsigned short normal_i2c[] = { I2C_BT819 >> 1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index efe605a113a..07f72f64c5f 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c @@ -39,8 +39,8 @@ MODULE_LICENSE("GPL"); /* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_BT832_ALT1>>1,I2C_BT832_ALT2>>1,I2C_CLIENT_END}; +static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1, + I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 72c7eb0f8c2..59121a0ec81 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -288,21 +288,15 @@ bt856_command (struct i2c_client *client, * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 7fbb8581a87..09464d624a6 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -147,7 +147,6 @@ static unsigned short normal_i2c[] = { I2C_MSP3400C_ALT >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index ba69f09cbdd..b8054da31ff 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -64,7 +64,6 @@ static struct video_device saa_template; /* Declared near bottom */ /* Addresses to scan */ static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; static struct i2c_client client_template; diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index d74caa139f0..7ffa2e9a9bf 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -132,7 +132,6 @@ static struct video_device saa_template; /* Declared near bottom */ /* Addresses to scan */ static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; static struct i2c_client client_template; diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 64273b43853..90b0a0b34f3 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -463,21 +463,15 @@ static unsigned short normal_i2c[] = { (I2C_SAA7110 >> 1) + 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 0a873112ae2..e305a89f7cd 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -482,21 +482,15 @@ saa7111_command (struct i2c_client *client, * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index e73023695e5..1ca4e70fed7 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -820,21 +820,15 @@ saa7114_command (struct i2c_client *client, */ static unsigned short normal_i2c[] = { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 1db02268298..42c2b565c9f 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -22,7 +22,6 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 5f0b224c3cb..5c623fadc8f 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -380,21 +380,15 @@ saa7185_command (struct i2c_client *client, * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 376a4a439e9..07ba6d3ed08 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -74,7 +74,6 @@ static unsigned short normal_i2c[] = { I2C_TDA7432 >> 1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* Structure of address and subaddresses for the tda7432 */ diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index b5177c6f54f..c29bdfc3244 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -43,7 +43,6 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); /* addresses to scan, found only at 0x42 (7-Bit) */ static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 4f1114c033a..97b113e070f 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -44,7 +44,6 @@ static unsigned short normal_i2c[] = { I2C_TDA9875 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index debef1910c3..7e6e6dd966a 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -33,7 +33,6 @@ static unsigned short normal_i2c[] = { 0x96 >>1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* insmod options */ diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 3ec39550bf4..b44db8a7b94 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -43,7 +43,6 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index bd10710fd90..48d4db7d507 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -40,7 +40,6 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index 6b20aa902a8..bedb15e2f23 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c @@ -34,19 +34,16 @@ static int this_adap; static struct i2c_client client_template; /* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {0x60, 0x61, I2C_CLIENT_END}; +static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { - normal_i2c, normal_i2c_range, - probe, probe_range, - ignore, ignore_range, - force + .normal_i2c = normal_i2c, + .probe = probe, + .ignore = ignore, + .force = force, }; /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 6212388edb7..81882ddab85 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -28,10 +28,8 @@ /* standard i2c insmod options */ static unsigned short normal_i2c[] = { 0x4b, /* tda8290 */ - I2C_CLIENT_END -}; -static unsigned short normal_i2c_range[] = { - 0x60, 0x6f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; @@ -225,9 +223,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) static int tuner_probe(struct i2c_adapter *adap) { if (0 != addr) { - normal_i2c[0] = addr; - normal_i2c_range[0] = addr; - normal_i2c_range[1] = addr; + normal_i2c[0] = addr; + normal_i2c[1] = I2C_CLIENT_END; } this_adap = 0; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 80dc34f18c2..41b635e0d3c 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -148,7 +148,6 @@ static unsigned short normal_i2c[] = { I2C_TDA9874 >> 1, I2C_PIC16C54 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; static struct i2c_driver driver; diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index e1443a0937e..3d216973798 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -482,7 +482,6 @@ static unsigned short normal_i2c[] = { 0xa0 >> 1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; struct i2c_driver i2c_driver_tveeprom; diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 0fd6c9a7091..b97036910fa 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -569,21 +569,15 @@ static unsigned short normal_i2c[] = { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, .probe = probe, - .probe_range = probe_range, .ignore = ignore, - .ignore_range = ignore_range, .force = force }; diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index e529841cd83..67f85344f0c 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c @@ -1230,7 +1230,6 @@ static int maven_shutdown_client(struct i2c_client* clnt) { } static unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { MAVEN_I2CID, MAVEN_I2CID, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; static struct i2c_driver maven_driver; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index ebcd745f4cd..be837b13f29 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -290,11 +290,8 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) */ struct i2c_client_address_data { unsigned short *normal_i2c; - unsigned short *normal_i2c_range; unsigned short *probe; - unsigned short *probe_range; unsigned short *ignore; - unsigned short *ignore_range; unsigned short *force; }; @@ -563,24 +560,15 @@ union i2c_smbus_data { #define I2C_CLIENT_INSMOD \ I2C_CLIENT_MODULE_PARM(probe, \ "List of adapter,address pairs to scan additionally"); \ - I2C_CLIENT_MODULE_PARM(probe_range, \ - "List of adapter,start-addr,end-addr triples to scan " \ - "additionally"); \ I2C_CLIENT_MODULE_PARM(ignore, \ "List of adapter,address pairs not to scan"); \ - I2C_CLIENT_MODULE_PARM(ignore_range, \ - "List of adapter,start-addr,end-addr triples not to " \ - "scan"); \ I2C_CLIENT_MODULE_PARM(force, \ "List of adapter,address pairs to boldly assume " \ "to be present"); \ static struct i2c_client_address_data addr_data = { \ .normal_i2c = normal_i2c, \ - .normal_i2c_range = normal_i2c_range, \ .probe = probe, \ - .probe_range = probe_range, \ .ignore = ignore, \ - .ignore_range = ignore_range, \ .force = force, \ } -- cgit v1.2.3-70-g09d2 From 68cc9d0b714d7d533c0cfc257a62f7f7f4f22a11 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 2 Apr 2005 20:04:41 +0200 Subject: [PATCH] I2C: Merge unused address lists in some video drivers On top of my previous patch which removes the use of address ranges in video i2c drivers, this one can save an additional few bytes of memory. Most of these drivers which do not use I2C_CLIENT_INSMOD initialize the unused address lists in a less than optimal way. This patch simply optimizes this, by using a single one-element list instead of 3 different lists with two elements each. This saves an average 63 bytes on these drivers. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman diff -ruN linux-2.6.12-rc1-bk5.orig/drivers/media/video/adv7170.c linux-2.6.12-rc1-bk5/drivers/media/video/adv7170.c --- drivers/media/video/adv7170.c | 10 ++++------ drivers/media/video/adv7175.c | 10 ++++------ drivers/media/video/bt819.c | 10 ++++------ drivers/media/video/bt856.c | 10 ++++------ drivers/media/video/saa7110.c | 10 ++++------ drivers/media/video/saa7111.c | 10 ++++------ drivers/media/video/saa7114.c | 10 ++++------ drivers/media/video/saa7185.c | 10 ++++------ drivers/media/video/tuner-3036.c | 10 ++++------ drivers/media/video/vpx3220.c | 10 ++++------ 10 files changed, 40 insertions(+), 60 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index e9bf3394296..48989eda240 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -385,15 +385,13 @@ static unsigned short normal_i2c[] = I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_adv7170; diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 2d5fa44fcd4..f898b658637 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -435,15 +435,13 @@ static unsigned short normal_i2c[] = I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_adv7175; diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 31d51851bb4..8733588f6db 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -501,15 +501,13 @@ static unsigned short normal_i2c[] = { I2C_CLIENT_END, }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_bt819; diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 59121a0ec81..a5d529ccf3a 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -289,15 +289,13 @@ bt856_command (struct i2c_client *client, */ static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_bt856; diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 90b0a0b34f3..22d055d8a69 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -464,15 +464,13 @@ static unsigned short normal_i2c[] = { I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_saa7110; diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index e305a89f7cd..fcd897382fc 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -483,15 +483,13 @@ saa7111_command (struct i2c_client *client, */ static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_saa7111; diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index 1ca4e70fed7..2ba997f5ef1 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -821,15 +821,13 @@ saa7114_command (struct i2c_client *client, static unsigned short normal_i2c[] = { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_saa7114; diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 5c623fadc8f..108e7a4a027 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -381,15 +381,13 @@ saa7185_command (struct i2c_client *client, */ static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver i2c_driver_saa7185; diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index bedb15e2f23..51748c6578d 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c @@ -35,15 +35,13 @@ static struct i2c_client client_template; /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force, + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index b97036910fa..5dbd9f6bf35 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -570,15 +570,13 @@ static unsigned short normal_i2c[] = I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .probe = probe, - .ignore = ignore, - .force = force + .probe = &ignore, + .ignore = &ignore, + .force = &ignore, }; static struct i2c_driver vpx3220_i2c_driver; -- cgit v1.2.3-70-g09d2 From b6a235b1186dda0800c8bedc2526830a4a36b44e Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:29 -0700 Subject: [PATCH] dvb: drop obsolete dibusb driver Remove the dibusb driver which has been obsoleted by the generalized dvb-usb driver. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dvb/README.dibusb | 285 ------------ drivers/media/dvb/Kconfig | 1 - drivers/media/dvb/Makefile | 2 +- drivers/media/dvb/dibusb/Kconfig | 62 --- drivers/media/dvb/dibusb/Makefile | 11 - drivers/media/dvb/dibusb/dvb-dibusb-core.c | 558 ------------------------ drivers/media/dvb/dibusb/dvb-dibusb-dvb.c | 185 -------- drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c | 582 ------------------------- drivers/media/dvb/dibusb/dvb-dibusb-firmware.c | 87 ---- drivers/media/dvb/dibusb/dvb-dibusb-remote.c | 316 -------------- drivers/media/dvb/dibusb/dvb-dibusb-usb.c | 303 ------------- drivers/media/dvb/dibusb/dvb-dibusb.h | 327 -------------- drivers/media/dvb/dibusb/dvb-fe-dtt200u.c | 263 ----------- 13 files changed, 1 insertion(+), 2981 deletions(-) delete mode 100644 Documentation/dvb/README.dibusb delete mode 100644 drivers/media/dvb/dibusb/Kconfig delete mode 100644 drivers/media/dvb/dibusb/Makefile delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-core.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-dvb.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-firmware.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-remote.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb-usb.c delete mode 100644 drivers/media/dvb/dibusb/dvb-dibusb.h delete mode 100644 drivers/media/dvb/dibusb/dvb-fe-dtt200u.c (limited to 'drivers/media') diff --git a/Documentation/dvb/README.dibusb b/Documentation/dvb/README.dibusb deleted file mode 100644 index 7a9e958513f..00000000000 --- a/Documentation/dvb/README.dibusb +++ /dev/null @@ -1,285 +0,0 @@ -Documentation for dib3000* frontend drivers and dibusb device driver -==================================================================== - -Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de), - -dibusb and dib3000mb/mc drivers based on GPL code, which has - -Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation, version 2. - - -Supported devices USB1.1 -======================== - -Produced and reselled by Twinhan: ---------------------------------- -- TwinhanDTV USB-Ter DVB-T Device (VP7041) - http://www.twinhan.com/product_terrestrial_3.asp - -- TwinhanDTV Magic Box (VP7041e) - http://www.twinhan.com/product_terrestrial_4.asp - -- HAMA DVB-T USB device - http://www.hama.de/portal/articleId*110620/action*2598 - -- CTS Portable (Chinese Television System) (2) - http://www.2cts.tv/ctsportable/ - -- Unknown USB DVB-T device with vendor ID Hyper-Paltek - - -Produced and reselled by KWorld: --------------------------------- -- KWorld V-Stream XPERT DTV DVB-T USB - http://www.kworld.com.tw/en/product/DVBT-USB/DVBT-USB.html - -- JetWay DTV DVB-T USB - http://www.jetway.com.tw/evisn/product/lcd-tv/DVT-USB/dtv-usb.htm - -- ADSTech Instant TV DVB-T USB - http://www.adstech.com/products/PTV-333/intro/PTV-333_intro.asp?pid=PTV-333 - - -Others: -------- -- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner) - http://82.161.246.249/products-tvbox.html - -- Compro Videomate DVB-U2000 - DVB-T USB (2) - http://www.comprousa.com/products/vmu2000.htm - -- Grandtec USB DVB-T - http://www.grand.com.tw/ - -- Avermedia AverTV DVBT USB (2) - http://www.avermedia.com/ - -- DiBcom USB DVB-T reference device (non-public) - - -Supported devices USB2.0 -======================== -- Twinhan MagicBox II (2) - http://www.twinhan.com/product_terrestrial_7.asp - -- Hanftek UMT-010 (1) - http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529 - -- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1) - http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T - -- Artec T1 USB TVBOX (FX2) (2) - -- Hauppauge WinTV NOVA-T USB2 - http://www.hauppauge.com/ - -- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B) - -- DiBcom USB2.0 DVB-T reference device (non-public) - -1) It is working almost. -2) No test reports received yet. - - -0. NEWS: - 2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron - 2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2 - 2005-01-31 - distorted streaming is finally gone for USB1.1 devices - 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb - - first almost working version for HanfTek UMT-010 - - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010 - 2005-01-10 - refactoring completed, now everything is very delightful - - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a - Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich. - 2004-12-29 - after several days of struggling around bug of no returning URBs fixed. - 2004-12-26 - refactored the dibusb-driver, splitted into separate files - - i2c-probing enabled - 2004-12-06 - possibility for demod i2c-address probing - - new usb IDs (Compro,Artec) - 2004-11-23 - merged changes from DiB3000MC_ver2.1 - - revised the debugging - - possibility to deliver the complete TS for USB2.0 - 2004-11-21 - first working version of the dib3000mc/p frontend driver. - 2004-11-12 - added additional remote control keys. Thanks to Uwe Hanke. - 2004-11-07 - added remote control support. Thanks to David Matthews. - 2004-11-05 - added support for a new devices (Grandtec/Avermedia/Artec) - - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD - - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems - better settled there (added xfer_ops-struct) - - created a common files for frontends (mc/p/mb) - 2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek) - 2004-09-20 - added support for a new device (Compro DVB-U2000), thanks - to Amaury Demol for reporting - - changed usb TS transfer method (several urbs, stopping transfer - before setting a new pid) - 2004-09-13 - added support for a new device (Artec T1 USB TVBOX), thanks - to Christian Motschke for reporting - 2004-09-05 - released the dibusb device and dib3000mb-frontend driver - - (old news for vp7041.c) - 2004-07-15 - found out, by accident, that the device has a TUA6010XS for - PLL - 2004-07-12 - figured out, that the driver should also work with the - CTS Portable (Chinese Television System) - 2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working - properly with firmware extracted from 2.422 - - #if for 2.6.4 (dvb), compile issue - - changed firmware handling, see vp7041.txt sec 1.1 - 2004-07-02 - some tuner modifications, v0.1, cleanups, first public - 2004-06-28 - now using the dvb_dmx_swfilter_packets, everything - runs fine now - 2004-06-27 - able to watch and switching channels (pre-alpha) - - no section filtering yet - 2004-06-06 - first TS received, but kernel oops :/ - 2004-05-14 - firmware loader is working - 2004-05-11 - start writing the driver - -1. How to use? -NOTE: This driver was developed using Linux 2.6.6., -it is working with 2.6.7 and above. - -Linux 2.4.x support is not planned, but patches are very welcome. - -NOTE: I'm using Debian testing, so the following explaination (especially -the hotplug-path) needn't match your system, but probably it will :). - -The driver is included in the kernel since Linux 2.6.10. - -1.1. Firmware - -The USB driver needs to download a firmware to start working. - -You can either use "get_dvb_firmware dibusb" to download the firmware or you -can get it directly via - -for USB1.1 (AN2135) -http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw - -for USB1.1 (AN2235) (a few Artec T1 devices) -http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw - -for USB2.0 (FX2) Hauppauge, DiBcom -http://www.linuxtv.org/downloads/firmware/dvb-dibusb-6.0.0.5.fw - -for USB2.0 ADSTech/Kworld USB2.0 -http://www.linuxtv.org/downloads/firmware/dvb-dibusb-adstech-usb2-1.fw - -for USB2.0 HanfTek -http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw - - -1.2. Compiling - -Since the driver is in the linux kernel, activating the driver in -your favorite config-environment should sufficient. I recommend -to compile the driver as module. Hotplug does the rest. - -1.3. Loading the drivers - -Hotplug is able to load the driver, when it is needed (because you plugged -in the device). - -If you want to enable debug output, you have to load the driver manually and -from withing the dvb-kernel cvs repository. - -first have a look, which debug level are available: - -modinfo dib3000mb -modinfo dib3000-common -modinfo dib3000mc -modinfo dvb-dibusb - -modprobe dib3000-common debug= -modprobe dib3000mb debug= -modprobe dib3000mc debug= -modprobe dvb-dibusb debug= - -should do the trick. - -When the driver is loaded successfully, the firmware file was in -the right place and the device is connected, the "Power"-LED should be -turned on. - -At this point you should be able to start a dvb-capable application. For myself -I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device -in vdr is working now also. - -2. Known problems and bugs - -- Don't remove the USB device while running an DVB application, your system will die. - -2.1. Adding support for devices - -It is not possible to determine the range of devices based on the DiBcom -reference designs. This is because the reference design of DiBcom can be sold -to thirds, without telling DiBcom (so done with the Twinhan VP7041 and -the HAMA device). - -When you think you have a device like this and the driver does not recognizes it, -please send the ****load*.inf and the ****cap*.inf of the Windows driver to me. - -Sometimes the Vendor or Product ID is identical to the ones of Twinhan, even -though it is not a Twinhan device (e.g. HAMA), then please send me the name -of the device. I will add it to this list in order to make this clear to -others. - -If you are familar with C you can also add the VID and PID of the device to -the dvb-dibusb-core.c-file and create a patch and send it over to me or to -the linux-dvb mailing list, _after_ you have tried compiling and modprobing -it. - -2.2. USB1.1 Bandwidth limitation - -Most of the currently supported devices are USB1.1 and thus they have a -maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub. -This is not enough for receiving the complete transport stream of a -DVB-T channel (which can be about 16 MBit/s). Normally this is not a -problem, if you only want to watch TV (this does not apply for HDTV), -but watching a channel while recording another channel on the same -frequency simply does not work very well. This applies to all USB1.1 -DVB-T devices, not just dibusb) - -Update: For the USB1.1 and VDR some work has been done (patches and comments -are still very welcome). Maybe the problem is solved in the meantime because I -now use the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the -linux-dvb software filter is able to get the best of the garbled TS. - -The bug, where the TS is distorted by a heavy usage of the device is gone -definitely. All dibusb-devices I was using (Twinhan, Kworld, DiBcom) are -working like charm now with VDR. Sometimes I even was able to record a channel -and watch another one. - -2.3. Comments - -Patches, comments and suggestions are very very welcome. - -3. Acknowledgements - Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for - providing specs, code and help, on which the dvb-dibusb, dib3000mb and - dib3000mc are based. - - David Matthews for identifying a new device type (Artec T1 with AN2235) - and for extending dibusb with remote control event handling. Thank you. - - Alex Woods for frequently answering question about usb and dvb - stuff, a big thank you. - - Bernd Wagner for helping with huge bug reports and discussions. - - Gunnar Wittich and Joachim von Caron for their trust for giving me - root-shells on their machines to implement support for new devices. - - Some guys on the linux-dvb mailing list for encouraging me - - Peter Schildmann >peter.schildmann-nospam-at-web.de< for his - user-level firmware loader, which saves a lot of time - (when writing the vp7041 driver) - - Ulf Hermenau for helping me out with traditional chinese. - - André Smoktun and Christian Frömmel for supporting me with - hardware and listening to my problems very patient diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 4983e1b1bb1..b81abdfde37 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -29,7 +29,6 @@ comment "Supported USB Adapters" depends on DVB_CORE && USB source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" -source "drivers/media/dvb/dibusb/Kconfig" source "drivers/media/dvb/cinergyT2/Kconfig" comment "Supported FlexCopII (B2C2) Adapters" diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index 520fc390281..d2dd914f777 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -2,4 +2,4 @@ # Makefile for the kernel multimedia device drivers. # -obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/ +obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ diff --git a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig deleted file mode 100644 index 74dfc73ae5b..00000000000 --- a/drivers/media/dvb/dibusb/Kconfig +++ /dev/null @@ -1,62 +0,0 @@ -config DVB_DIBUSB - tristate "DiBcom USB DVB-T devices (see help for a complete device list)" - depends on DVB_CORE && USB - select FW_LOADER - select DVB_DIB3000MB - select DVB_DIB3000MC - select DVB_MT352 - help - Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by - DiBcom (http://www.dibcom.fr) and C&E. - - Devices supported by this driver: - - TwinhanDTV USB-Ter (VP7041) - TwinhanDTV Magic Box (VP7041e) - KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 - Hama DVB-T USB-Box - DiBcom reference devices (non-public) - Ultima Electronic/Artec T1 USB TVBOX - Compro Videomate DVB-U2000 - DVB-T USB - Grandtec DVB-T USB - Avermedia AverTV DVBT USB - Artec T1 USB1.1 and USB2.0 boxes - Yakumo/Typhoon DVB-T USB2.0 - Hanftek UMT-010 USB2.0 - Hauppauge WinTV NOVA-T USB2 - - The VP7041 seems to be identical to "CTS Portable" (Chinese - Television System). - - These devices can be understood as budget ones, they "only" deliver - (a part of) the MPEG2 transport stream. - - A firmware is needed to get the device working. See Documentation/dvb/README.dibusb - details. - - Say Y if you own such a device and want to use it. You should build it as - a module. - -config DVB_DIBUSB_MISDESIGNED_DEVICES - bool "Enable support for some misdesigned (see help) devices, which identify with wrong IDs" - depends on DVB_DIBUSB - help - Somehow Artec/Ultima Electronic forgot to program the eeprom of some of their - USB1.1/USB2.0 devices. - So comes that they identify with the default Vendor and Product ID of the Cypress - CY7C64613 (AN2235) or Cypress FX2. - - Affected device IDs: - 0x0574:0x2235 (Artec T1 USB1.1, cold) - 0x04b4:0x8613 (Artec T1 USB2.0, cold) - 0x0574:0x1002 (Artec T1 USB2.0, warm) - 0x0574:0x2131 (aged DiBcom USB1.1 test device) - - Say Y if your device has one of the mentioned IDs. - -config DVB_DIBCOM_DEBUG - bool "Enable extended debug support for DiBcom USB device" - depends on DVB_DIBUSB - help - Say Y if you want to enable debuging. See modinfo dvb-dibusb for - debug levels. diff --git a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile deleted file mode 100644 index e941c508624..00000000000 --- a/drivers/media/dvb/dibusb/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -dvb-dibusb-objs = dvb-dibusb-core.o \ - dvb-dibusb-dvb.o \ - dvb-dibusb-fe-i2c.o \ - dvb-dibusb-firmware.o \ - dvb-dibusb-remote.o \ - dvb-dibusb-usb.o \ - dvb-fe-dtt200u.o - -obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o - -EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c deleted file mode 100644 index 26235f9247e..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-core.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Driver for mobile USB Budget DVB-T devices based on reference - * design made by DiBcom (http://www.dibcom.fr/) - * - * dvb-dibusb-core.c - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DiBcom, which has - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * Remote control code added by David Matthews (dm@prolingua.co.uk) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * Acknowledgements - * - * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver - * sources, on which this driver (and the dib3000mb/mc/p frontends) are based. - * - * see Documentation/dvb/README.dibusb for more information - */ -#include "dvb-dibusb.h" - -#include - -/* debug */ -int dvb_dibusb_debug; -module_param_named(debug, dvb_dibusb_debug, int, 0644); - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -#define DBSTATUS "" -#else -#define DBSTATUS " (debugging is not enabled)" -#endif -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS); -#undef DBSTATUS - -static int pid_parse; -module_param(pid_parse, int, 0644); -MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0"); - -static int rc_query_interval = 100; -module_param(rc_query_interval, int, 0644); -MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)"); - -static int rc_key_repeat_count = 2; -module_param(rc_key_repeat_count, int, 0644); -MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)"); - -/* Vendor IDs */ -#define USB_VID_ADSTECH 0x06e1 -#define USB_VID_ANCHOR 0x0547 -#define USB_VID_AVERMEDIA 0x14aa -#define USB_VID_COMPRO 0x185b -#define USB_VID_COMPRO_UNK 0x145f -#define USB_VID_CYPRESS 0x04b4 -#define USB_VID_DIBCOM 0x10b8 -#define USB_VID_EMPIA 0xeb1a -#define USB_VID_GRANDTEC 0x5032 -#define USB_VID_HANFTEK 0x15f4 -#define USB_VID_HAUPPAUGE 0x2040 -#define USB_VID_HYPER_PALTEK 0x1025 -#define USB_VID_IMC_NETWORKS 0x13d3 -#define USB_VID_TWINHAN 0x1822 -#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 - -/* Product IDs */ -#define USB_PID_ADSTECH_USB2_COLD 0xa333 -#define USB_PID_ADSTECH_USB2_WARM 0xa334 -#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 -#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 -#define USB_PID_COMPRO_DVBU2000_COLD 0xd000 -#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 -#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c -#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d -#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 -#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 -#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 -#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 -#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 -#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 -#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 -#define USB_PID_KWORLD_VSTREAM_COLD 0x17de -#define USB_PID_KWORLD_VSTREAM_WARM 0x17df -#define USB_PID_TWINHAN_VP7041_COLD 0x3201 -#define USB_PID_TWINHAN_VP7041_WARM 0x3202 -#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 -#define USB_PID_ULTIMA_TVBOX_WARM 0x8106 -#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 -#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 -#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 -#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 -#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 -#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 -#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e -#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f -#define USB_PID_HANFTEK_UMT_010_COLD 0x0001 -#define USB_PID_HANFTEK_UMT_010_WARM 0x0015 -#define USB_PID_YAKUMO_DTT200U_COLD 0x0201 -#define USB_PID_YAKUMO_DTT200U_WARM 0x0301 -#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 -#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 - -/* USB Driver stuff - * table of devices that this driver is working with - * - * ATTENTION: Never ever change the order of this table, the particular - * devices depend on this order - * - * Each entry is used as a reference in the device_struct. Currently this is - * the only non-redundant way of assigning USB ids to actual devices I'm aware - * of, because there is only one place in the code where the assignment of - * vendor and product id is done, here. - */ -static struct usb_device_id dib_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, -/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, -/* 02 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) }, -/* 03 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) }, - -/* 04 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, -/* 05 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, -/* 06 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, -/* 07 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, -/* 08 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, -/* 09 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) }, -/* 10 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) }, -/* 11 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, -/* 12 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, -/* 13 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, -/* 14 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, -/* 15 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, -/* 16 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) }, -/* 17 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) }, -/* 18 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) }, -/* 19 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) }, -/* 20 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) }, -/* 21 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, -/* 22 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, -/* 23 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, -/* 24 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, -/* 25 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, -/* 26 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, -/* 27 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, - -/* 28 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) }, -/* 29 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) }, - -/* 30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) }, -/* 31 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, -/* 32 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, -/* 33 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, -/* - * activate the following define when you have one of the devices and want to - * build it from build-2.6 in dvb-kernel - */ -// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES -#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES -/* 34 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, -/* 35 */ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) }, -/* 36 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) }, -/* 37 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_DIBCOM_ANCHOR_2135_COLD) }, -#endif - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, dib_table); - -static struct dibusb_usb_controller dibusb_usb_ctrl[] = { - { .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, - { .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, - { .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, -}; - -struct dibusb_tuner dibusb_tuner[] = { - { DIBUSB_TUNER_CABLE_THOMSON, - 0x61 - }, - { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5, - 0x60 - }, - { DIBUSB_TUNER_CABLE_LG_TDTP_E102P, - 0x61 - }, - { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5, - 0x60 - }, -}; - -static struct dibusb_demod dibusb_demod[] = { - { DIBUSB_DIB3000MB, - 16, - { 0x8, 0 }, - }, - { DIBUSB_DIB3000MC, - 32, - { 0x9, 0xa, 0xb, 0xc }, - }, - { DIBUSB_MT352, - 254, - { 0xf, 0 }, - }, - { DTT200U_FE, - 8, - { 0xff,0 }, /* there is no i2c bus in this device */ - } -}; - -static struct dibusb_device_class dibusb_device_classes[] = { - { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0], - .firmware = "dvb-dibusb-5.0.0.11.fw", - .pipe_cmd = 0x01, .pipe_data = 0x02, - .urb_count = 7, .urb_buffer_size = 4096, - DIBUSB_RC_NEC_PROTOCOL, - &dibusb_demod[DIBUSB_DIB3000MB], - &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON], - }, - { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1], - "dvb-dibusb-an2235-1.fw", - 0x01, 0x02, - 7, 4096, - DIBUSB_RC_NEC_PROTOCOL, - &dibusb_demod[DIBUSB_DIB3000MB], - &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON], - }, - { DIBUSB2_0,&dibusb_usb_ctrl[2], - "dvb-dibusb-6.0.0.5.fw", - 0x01, 0x06, - 7, 4096, - DIBUSB_RC_NEC_PROTOCOL, - &dibusb_demod[DIBUSB_DIB3000MC], - &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5], - }, - { UMT2_0, &dibusb_usb_ctrl[2], - "dvb-dibusb-umt-2.fw", - 0x01, 0x06, - 20, 512, - DIBUSB_RC_NO, - &dibusb_demod[DIBUSB_MT352], - &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P], - }, - { DIBUSB2_0B,&dibusb_usb_ctrl[2], - "dvb-dibusb-adstech-usb2-1.fw", - 0x01, 0x06, - 7, 4096, - DIBUSB_RC_NEC_PROTOCOL, - &dibusb_demod[DIBUSB_DIB3000MB], - &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON], - }, - { NOVAT_USB2,&dibusb_usb_ctrl[2], - "dvb-dibusb-nova-t-1.fw", - 0x01, 0x06, - 7, 4096, - DIBUSB_RC_HAUPPAUGE_PROTO, - &dibusb_demod[DIBUSB_DIB3000MC], - &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5], - }, - { DTT200U,&dibusb_usb_ctrl[2], - "dvb-dtt200u-1.fw", - 0x01, 0x02, - 7, 4096, - DIBUSB_RC_NO, - &dibusb_demod[DTT200U_FE], - NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */ - }, -}; - -static struct dibusb_usb_device dibusb_devices[] = { - { "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[19], &dib_table[21], NULL}, - { &dib_table[20], &dib_table[22], NULL}, - }, - { "KWorld V-Stream XPERT DTV - DVB-T USB1.1", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[11], NULL }, - { &dib_table[12], NULL }, - }, - { "Grandtec USB1.1 DVB-T", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[13], &dib_table[15], NULL }, - { &dib_table[14], &dib_table[16], NULL }, - }, - { "DiBcom USB1.1 DVB-T reference design (MOD3000)", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[7], NULL }, - { &dib_table[8], NULL }, - }, - { "Artec T1 USB1.1 TVBOX with AN2135", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[23], NULL }, - { &dib_table[24], NULL }, - }, - { "Artec T1 USB1.1 TVBOX with AN2235", - &dibusb_device_classes[DIBUSB1_1_AN2235], - { &dib_table[25], NULL }, - { &dib_table[26], NULL }, - }, - { "Avermedia AverTV DVBT USB1.1", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[0], NULL }, - { &dib_table[1], NULL }, - }, - { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[4], &dib_table[6], NULL}, - { &dib_table[5], NULL }, - }, - { "Unkown USB1.1 DVB-T device ???? please report the name to the author", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[17], NULL }, - { &dib_table[18], NULL }, - }, - { "DiBcom USB2.0 DVB-T reference design (MOD3000P)", - &dibusb_device_classes[DIBUSB2_0], - { &dib_table[9], NULL }, - { &dib_table[10], NULL }, - }, - { "Artec T1 USB2.0 TVBOX (please report the warm ID)", - &dibusb_device_classes[DIBUSB2_0], - { &dib_table[27], NULL }, - { NULL }, - }, - { "Hauppauge WinTV NOVA-T USB2", - &dibusb_device_classes[NOVAT_USB2], - { &dib_table[30], NULL }, - { &dib_table[31], NULL }, - }, - { "DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0", - &dibusb_device_classes[DTT200U], - { &dib_table[2], NULL }, - { &dib_table[3], NULL }, - }, - { "Hanftek UMT-010 DVB-T USB2.0", - &dibusb_device_classes[UMT2_0], - { &dib_table[28], NULL }, - { &dib_table[29], NULL }, - }, - { "KWorld/ADSTech Instant DVB-T USB 2.0", - &dibusb_device_classes[DIBUSB2_0B], - { &dib_table[32], NULL }, - { &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */ - }, -#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES - { "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)", - &dibusb_device_classes[DIBUSB1_1_AN2235], - { &dib_table[34], NULL }, - { NULL }, - }, - { "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)", - &dibusb_device_classes[DTT200U], - { &dib_table[35], NULL }, - { &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */ - }, - { "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs", - &dibusb_device_classes[DIBUSB1_1], - { &dib_table[37], NULL }, - { NULL }, - }, -#endif -}; - -static int dibusb_exit(struct usb_dibusb *dib) -{ - deb_info("init_state before exiting everything: %x\n",dib->init_state); - dibusb_remote_exit(dib); - dibusb_fe_exit(dib); - dibusb_i2c_exit(dib); - dibusb_dvb_exit(dib); - dibusb_urb_exit(dib); - deb_info("init_state should be zero now: %x\n",dib->init_state); - dib->init_state = DIBUSB_STATE_INIT; - kfree(dib); - return 0; -} - -static int dibusb_init(struct usb_dibusb *dib) -{ - int ret = 0; - sema_init(&dib->usb_sem, 1); - sema_init(&dib->i2c_sem, 1); - - dib->init_state = DIBUSB_STATE_INIT; - - if ((ret = dibusb_urb_init(dib)) || - (ret = dibusb_dvb_init(dib)) || - (ret = dibusb_i2c_init(dib))) { - dibusb_exit(dib); - return ret; - } - - if ((ret = dibusb_fe_init(dib))) - err("could not initialize a frontend."); - - if ((ret = dibusb_remote_init(dib))) - err("could not initialize remote control."); - - return 0; -} - -static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev) -{ - int i; - - /* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB - * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad - * idea and make this quirk necessary. - */ - if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) { - info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal."); - for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) { - if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) { - dev = &dibusb_devices[i]; - break; - } - } - } - - return dev; -} - -static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold) -{ - int i,j; - struct dibusb_usb_device *dev = NULL; - *cold = -1; - - for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) { - for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) { - deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct); - if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && - dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { - *cold = 1; - dev = &dibusb_devices[i]; - break; - } - } - - if (dev != NULL) - break; - - for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) { - deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct); - if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && - dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { - *cold = 0; - dev = &dibusb_devices[i]; - break; - } - } - } - - if (dev != NULL) - dev = dibusb_device_class_quirk(udev,dev); - - return dev; -} - -/* - * USB - */ -static int dibusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_dibusb *dib = NULL; - struct dibusb_usb_device *dibdev = NULL; - - int ret = -ENOMEM,cold=0; - - if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) { - err("something went very wrong, " - "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct)); - return -ENODEV; - } - - if (cold == 1) { - info("found a '%s' in cold state, will try to load a firmware",dibdev->name); - ret = dibusb_loadfirmware(udev,dibdev); - } else { - info("found a '%s' in warm state.",dibdev->name); - dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL); - if (dib == NULL) { - err("no memory"); - return ret; - } - memset(dib,0,sizeof(struct usb_dibusb)); - - dib->udev = udev; - dib->dibdev = dibdev; - - /* store parameters to structures */ - dib->rc_query_interval = rc_query_interval; - dib->pid_parse = pid_parse; - dib->rc_key_repeat_count = rc_key_repeat_count; - - usb_set_intfdata(intf, dib); - - ret = dibusb_init(dib); - } - - if (ret == 0) - info("%s successfully initialized and connected.",dibdev->name); - else - info("%s error while loading driver (%d)",dibdev->name,ret); - return ret; -} - -static void dibusb_disconnect(struct usb_interface *intf) -{ - struct usb_dibusb *dib = usb_get_intfdata(intf); - const char *name = DRIVER_DESC; - - usb_set_intfdata(intf,NULL); - if (dib != NULL && dib->dibdev != NULL) { - name = dib->dibdev->name; - dibusb_exit(dib); - } - info("%s successfully deinitialized and disconnected.",name); - -} - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver dibusb_driver = { - .owner = THIS_MODULE, - .name = DRIVER_DESC, - .probe = dibusb_probe, - .disconnect = dibusb_disconnect, - .id_table = dib_table, -}; - -/* module stuff */ -static int __init usb_dibusb_init(void) -{ - int result; - if ((result = usb_register(&dibusb_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit usb_dibusb_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dibusb_driver); -} - -module_init (usb_dibusb_init); -module_exit (usb_dibusb_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c deleted file mode 100644 index 400b439e804..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices - * based on reference design made by DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * see dvb-dibusb-core.c for more copyright details. - * - * This file contains functions for initializing and handling the - * linux-dvb API. - */ -#include "dvb-dibusb.h" - -#include -#include - -static u32 urb_compl_count; - -/* - * MPEG2 TS DVB stuff - */ -void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs) -{ - struct usb_dibusb *dib = urb->context; - - deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status, - urb->actual_length); - - urb_compl_count++; - if (urb_compl_count % 1000 == 0) - deb_info("%d urbs completed so far.\n",urb_compl_count); - - switch (urb->status) { - case 0: /* success */ - case -ETIMEDOUT: /* NAK */ - break; - case -ECONNRESET: /* kill */ - case -ENOENT: - case -ESHUTDOWN: - return; - default: /* error */ - deb_ts("urb completition error %d.", urb->status); - break; - } - - if (dib->feedcount > 0 && urb->actual_length > 0) { - if (dib->init_state & DIBUSB_STATE_DVB) - dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length); - } else - deb_ts("URB dropped because of feedcount.\n"); - - usb_submit_urb(urb,GFP_ATOMIC); -} - -static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) -{ - struct usb_dibusb *dib = dvbdmxfeed->demux->priv; - int newfeedcount; - - if (dib == NULL) - return -ENODEV; - - newfeedcount = dib->feedcount + (onoff ? 1 : -1); - - /* - * stop feed before setting a new pid if there will be no pid anymore - */ - if (newfeedcount == 0) { - deb_ts("stop feeding\n"); - if (dib->xfer_ops.fifo_ctrl != NULL) { - if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) { - err("error while inhibiting fifo."); - return -ENODEV; - } - } - dibusb_streaming(dib,0); - } - - dib->feedcount = newfeedcount; - - /* activate the pid on the device specific pid_filter */ - deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off"); - if (dib->pid_parse && dib->xfer_ops.pid_ctrl != NULL) - dib->xfer_ops.pid_ctrl(dib->fe,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); - - /* - * start the feed if this was the first pid to set and there is still a pid - * for reception. - */ - if (dib->feedcount == onoff && dib->feedcount > 0) { - - deb_ts("controlling pid parser\n"); - if (dib->xfer_ops.pid_parse != NULL) { - if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) { - err("could not handle pid_parser"); - } - } - - deb_ts("start feeding\n"); - if (dib->xfer_ops.fifo_ctrl != NULL) { - if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) { - err("error while enabling fifo."); - return -ENODEV; - } - } - dibusb_streaming(dib,1); - } - return 0; -} - -static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type); - return dibusb_ctrl_feed(dvbdmxfeed,1); -} - -static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type); - return dibusb_ctrl_feed(dvbdmxfeed,0); -} - -int dibusb_dvb_init(struct usb_dibusb *dib) -{ - int ret; - - urb_compl_count = 0; - - if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC, - THIS_MODULE)) < 0) { - deb_info("dvb_register_adapter failed: error %d", ret); - goto err; - } - dib->adapter.priv = dib; - -/* i2c is done in dibusb_i2c_init */ - - dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; - - dib->demux.priv = (void *)dib; - /* get pidcount from demod */ - dib->demux.feednum = dib->demux.filternum = 255; - dib->demux.start_feed = dibusb_start_feed; - dib->demux.stop_feed = dibusb_stop_feed; - dib->demux.write_to_decoder = NULL; - if ((ret = dvb_dmx_init(&dib->demux)) < 0) { - err("dvb_dmx_init failed: error %d",ret); - goto err_dmx; - } - - dib->dmxdev.filternum = dib->demux.filternum; - dib->dmxdev.demux = &dib->demux.dmx; - dib->dmxdev.capabilities = 0; - if ((ret = dvb_dmxdev_init(&dib->dmxdev, &dib->adapter)) < 0) { - err("dvb_dmxdev_init failed: error %d",ret); - goto err_dmx_dev; - } - - dvb_net_init(&dib->adapter, &dib->dvb_net, &dib->demux.dmx); - - goto success; -err_dmx_dev: - dvb_dmx_release(&dib->demux); -err_dmx: - dvb_unregister_adapter(&dib->adapter); -err: - return ret; -success: - dib->init_state |= DIBUSB_STATE_DVB; - return 0; -} - -int dibusb_dvb_exit(struct usb_dibusb *dib) -{ - if (dib->init_state & DIBUSB_STATE_DVB) { - dib->init_state &= ~DIBUSB_STATE_DVB; - deb_info("unregistering DVB part\n"); - dvb_net_release(&dib->dvb_net); - dib->demux.dmx.close(&dib->demux.dmx); - dvb_dmxdev_release(&dib->dmxdev); - dvb_dmx_release(&dib->demux); - dvb_unregister_adapter(&dib->adapter); - } - return 0; -} diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c deleted file mode 100644 index 5a71b88797d..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices - * based on reference design made by DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * see dvb-dibusb-core.c for more copyright details. - * - * This file contains functions for attaching, initializing of an appropriate - * demodulator/frontend. I2C-stuff is also located here. - * - */ -#include "dvb-dibusb.h" - -#include - -static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */ - /* write only ? */ - int wo = (rbuf == NULL || rlen == 0), - len = 2 + wlen + (wo ? 0 : 2); - - sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ; - sndbuf[1] = (addr << 1) | (wo ? 0 : 1); - - memcpy(&sndbuf[2],wbuf,wlen); - - if (!wo) { - sndbuf[wlen+2] = (rlen >> 8) & 0xff; - sndbuf[wlen+3] = rlen & 0xff; - } - - return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen); -} - -/* - * I2C master xfer function - */ -static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num) -{ - struct usb_dibusb *dib = i2c_get_adapdata(adap); - int i; - - if (down_interruptible(&dib->i2c_sem) < 0) - return -EAGAIN; - - if (num > 2) - warn("more than 2 i2c messages at a time is not handled yet. TODO."); - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len, - msg[i+1].buf,msg[i+1].len) < 0) - break; - i++; - } else - if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) - break; - } - - up(&dib->i2c_sem); - return i; -} - -static u32 dibusb_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm dibusb_algo = { - .name = "DiBcom USB i2c algorithm", - .id = I2C_ALGO_BIT, - .master_xfer = dibusb_i2c_xfer, - .functionality = dibusb_i2c_func, -}; - -static int dibusb_general_demod_init(struct dvb_frontend *fe); -static u8 dibusb_general_pll_addr(struct dvb_frontend *fe); -static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]); -static int dibusb_general_pll_set(struct dvb_frontend *fe, - struct dvb_frontend_parameters* params, u8 pll_buf[5]); - -static struct mt352_config mt352_hanftek_umt_010_config = { - .demod_address = 0x1e, - .demod_init = dibusb_general_demod_init, - .pll_set = dibusb_general_pll_set, -}; - -static int dibusb_tuner_quirk(struct usb_dibusb *dib) -{ - switch (dib->dibdev->dev_cl->id) { - case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */ - case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */ - struct dibusb_tuner *t; - u8 b[2] = { 0,0 } ,b2[1]; - struct i2c_msg msg[2] = { - { .flags = 0, .buf = b, .len = 2 }, - { .flags = I2C_M_RD, .buf = b2, .len = 1}, - }; - - t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5]; - - msg[0].addr = msg[1].addr = t->pll_addr; - - if (dib->xfer_ops.tuner_pass_ctrl != NULL) - dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr); - dibusb_i2c_xfer(&dib->i2c_adap,msg,2); - if (dib->xfer_ops.tuner_pass_ctrl != NULL) - dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr); - - if (b2[0] == 0xfe) - info("this device has the Thomson Cable onboard. Which is default."); - else { - dib->tuner = t; - info("this device has the Panasonic ENV77H11D5 onboard."); - } - break; - } - default: - break; - } - return 0; -} - -int dibusb_fe_init(struct usb_dibusb* dib) -{ - struct dib3000_config demod_cfg; - int i; - - if (dib->init_state & DIBUSB_STATE_I2C) { - for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) && - dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) { - - demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i]; - demod_cfg.pll_addr = dibusb_general_pll_addr; - demod_cfg.pll_set = dibusb_general_pll_set; - demod_cfg.pll_init = dibusb_general_pll_init; - - deb_info("demod id: %d %d\n",dib->dibdev->dev_cl->demod->id,DTT200U_FE); - - switch (dib->dibdev->dev_cl->demod->id) { - case DIBUSB_DIB3000MB: - dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops); - break; - case DIBUSB_DIB3000MC: - dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops); - break; - case DIBUSB_MT352: - mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i]; - dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap); - break; - case DTT200U_FE: - dib->fe = dtt200u_fe_attach(dib,&dib->xfer_ops); - break; - } - if (dib->fe != NULL) { - info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]); - break; - } - } - /* if a frontend was found */ - if (dib->fe != NULL) { - if (dib->fe->ops->sleep != NULL) - dib->fe_sleep = dib->fe->ops->sleep; - dib->fe->ops->sleep = dibusb_hw_sleep; - - if (dib->fe->ops->init != NULL ) - dib->fe_init = dib->fe->ops->init; - dib->fe->ops->init = dibusb_hw_wakeup; - - /* setting the default tuner */ - dib->tuner = dib->dibdev->dev_cl->tuner; - - /* check which tuner is mounted on this device, in case this is unsure */ - dibusb_tuner_quirk(dib); - } - } - if (dib->fe == NULL) { - err("A frontend driver was not found for device '%s'.", - dib->dibdev->name); - return -ENODEV; - } else { - if (dvb_register_frontend(&dib->adapter, dib->fe)) { - err("Frontend registration failed."); - if (dib->fe->ops->release) - dib->fe->ops->release(dib->fe); - dib->fe = NULL; - return -ENODEV; - } - } - - return 0; -} - -int dibusb_fe_exit(struct usb_dibusb *dib) -{ - if (dib->fe != NULL) - dvb_unregister_frontend(dib->fe); - return 0; -} - -int dibusb_i2c_init(struct usb_dibusb *dib) -{ - int ret = 0; - - dib->adapter.priv = dib; - - strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, -#else - dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL, -#endif - dib->i2c_adap.algo = &dibusb_algo; - dib->i2c_adap.algo_data = NULL; - dib->i2c_adap.id = I2C_ALGO_BIT; - - i2c_set_adapdata(&dib->i2c_adap, dib); - - if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0) - err("could not add i2c adapter"); - - dib->init_state |= DIBUSB_STATE_I2C; - - return ret; -} - -int dibusb_i2c_exit(struct usb_dibusb *dib) -{ - if (dib->init_state & DIBUSB_STATE_I2C) - i2c_del_adapter(&dib->i2c_adap); - dib->init_state &= ~DIBUSB_STATE_I2C; - return 0; -} - - -/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */ -static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4]) -{ - u32 tfreq = (fep->frequency + 36125000) / 62500; - int vu,p0,p1,p2; - - if (fep->frequency > 403250000) - vu = 1, p2 = 1, p1 = 0, p0 = 1; - else if (fep->frequency > 115750000) - vu = 0, p2 = 1, p1 = 1, p0 = 0; - else if (fep->frequency > 44250000) - vu = 0, p2 = 0, p1 = 1, p0 = 1; - else - return -EINVAL; - - pllbuf[0] = (tfreq >> 8) & 0x7f; - pllbuf[1] = tfreq & 0xff; - pllbuf[2] = 0x8e; - pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0; - return 0; -} - -static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4]) -{ - u32 freq_khz = fep->frequency / 1000; - u32 tfreq = ((freq_khz + 36125)*6 + 500) / 1000; - u8 TA, T210, R210, ctrl1, cp210, p4321; - if (freq_khz > 858000) { - err("frequency cannot be larger than 858 MHz."); - return -EINVAL; - } - - // contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0 - TA = 1; - T210 = 0; - R210 = 0x2; - ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210; - -// ******** CHARGE PUMP CONFIG vs RF FREQUENCIES ***************** - if (freq_khz < 470000) - cp210 = 2; // VHF Low and High band ch E12 to E4 to E12 - else if (freq_khz < 526000) - cp210 = 4; // UHF band Ch E21 to E27 - else // if (freq < 862000000) - cp210 = 5; // UHF band ch E28 to E69 - -//********************* BW select ******************************* - if (freq_khz < 153000) - p4321 = 1; // BW selected for VHF low - else if (freq_khz < 470000) - p4321 = 2; // BW selected for VHF high E5 to E12 - else // if (freq < 862000000) - p4321 = 4; // BW selection for UHF E21 to E69 - - pllbuf[0] = (tfreq >> 8) & 0xff; - pllbuf[1] = (tfreq >> 0) & 0xff; - pllbuf[2] = 0xff & ctrl1; - pllbuf[3] = (cp210 << 5) | (p4321); - - return 0; -} - -/* - * 7 6 5 4 3 2 1 0 - * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0 - * - * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8 - * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0 - * - * Control byte 1 1 T/A=1 T2 T1 T0 R2 R1 R0 - * 1 T/A=0 0 0 ATC AL2 AL1 AL0 - * - * Control byte 2 CP2 CP1 CP0 BS5 BS4 BS3 BS2 BS1 - * - * MA0/1 = programmable address bits - * R/~W = read/write bit (0 for writing) - * N14-0 = programmable LO frequency - * - * T/A = test AGC bit (0 = next 6 bits AGC setting, - * 1 = next 6 bits test and reference divider ratio settings) - * T2-0 = test bits - * R2-0 = reference divider ratio and programmable frequency step - * ATC = AGC current setting and time constant - * ATC = 0: AGC current = 220nA, AGC time constant = 2s - * ATC = 1: AGC current = 9uA, AGC time constant = 50ms - * AL2-0 = AGC take-over point bits - * CP2-0 = charge pump current - * BS5-1 = PMOS ports control bits; - * BSn = 0 corresponding port is off, high-impedance state (at power-on) - * BSn = 1 corresponding port is on - */ -static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4]) -{ - pllbuf[0] = 0x0b; - pllbuf[1] = 0xf5; - pllbuf[2] = 0x85; - pllbuf[3] = 0xab; - return 0; -} - -static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4]) -{ - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = fep->frequency + 36166000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) - cp = 3; - else if (tuner_frequency < 160000000) - cp = 5; - else if (tuner_frequency < 200000000) - cp = 6; - else if (tuner_frequency < 290000000) - cp = 3; - else if (tuner_frequency < 420000000) - cp = 5; - else if (tuner_frequency < 480000000) - cp = 6; - else if (tuner_frequency < 620000000) - cp = 3; - else if (tuner_frequency < 830000000) - cp = 5; - else if (tuner_frequency < 895000000) - cp = 7; - else - return -EINVAL; - - // determine band - if (fep->frequency < 49000000) - return -EINVAL; - else if (fep->frequency < 161000000) - band = 1; - else if (fep->frequency < 444000000) - band = 2; - else if (fep->frequency < 861000000) - band = 4; - else - return -EINVAL; - - // setup PLL filter - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: - case BANDWIDTH_7_MHZ: - filter = 0; - break; - case BANDWIDTH_8_MHZ: - filter = 1; - break; - default: - return -EINVAL; - } - - // calculate divisor - // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000; - - // setup tuner buffer - pllbuf[0] = (tuner_frequency >> 8) & 0x7f; - pllbuf[1] = tuner_frequency & 0xff; - pllbuf[2] = 0xca; - pllbuf[3] = (cp << 5) | (filter << 3) | band; - return 0; -} - -/* - * 7 6 5 4 3 2 1 0 - * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0 - * - * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8 - * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0 - * - * Control byte 1 CP T2 T1 T0 RSA RSB OS - * - * Band Switch byte X X X P4 P3 P2 P1 P0 - * - * Auxiliary byte ATC AL2 AL1 AL0 0 0 0 0 - * - * Address: MA1 MA0 Address - * 0 0 c0 - * 0 1 c2 (always valid) - * 1 0 c4 - * 1 1 c6 - */ -static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4]) -{ - u32 div; - u8 p210, p3; - -#define TUNER_MUL 62500 - - div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL; -// div = ((fep->frequency/1000 + 36166) * 6) / 1000; - - if (fep->frequency < 174500000) - p210 = 1; // not supported by the tdtp_e102p - else if (fep->frequency < 230000000) // VHF - p210 = 2; - else - p210 = 4; - - if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - p3 = 0; - else - p3 = 1; - - pllbuf[0] = (div >> 8) & 0x7f; - pllbuf[1] = div & 0xff; - pllbuf[2] = 0xce; -// pllbuf[2] = 0xcc; - pllbuf[3] = (p3 << 3) | p210; - - return 0; -} - -static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe) -{ - static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d }; - static u8 mt352_reset[] = { 0x50, 0x80 }; - static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; - static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 }; - - static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff }; - static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff }; - static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 }; - static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 }; - static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f }; - - static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; - static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 }; - - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - udelay(2000); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); - mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); - - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); - - mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1)); - mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2)); - mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3)); - mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4)); - mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5)); - - mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); - mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); - - return 0; -} - -static int dibusb_general_demod_init(struct dvb_frontend *fe) -{ - struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; - switch (dib->dibdev->dev_cl->id) { - case UMT2_0: - return lg_tdtp_e102p_mt352_demod_init(fe); - default: /* other device classes do not have device specific demod inits */ - break; - } - return 0; -} - -static u8 dibusb_general_pll_addr(struct dvb_frontend *fe) -{ - struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; - return dib->tuner->pll_addr; -} - -static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4]) -{ - if (pll_buf == NULL) { - struct i2c_msg msg = { - .addr = dib->tuner->pll_addr, - .flags = 0, - .buf = buf, - .len = sizeof(buf) - }; - if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1) - return -EIO; - msleep(1); - } else { - pll_buf[0] = dib->tuner->pll_addr << 1; - memcpy(&pll_buf[1],buf,4); - } - - return 0; -} - -static int dibusb_general_pll_init(struct dvb_frontend *fe, - u8 pll_buf[5]) -{ - struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; - u8 buf[4]; - int ret=0; - switch (dib->tuner->id) { - case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5: - ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf); - break; - default: - break; - } - - if (ret) - return ret; - - return dibusb_pll_i2c_helper(dib,pll_buf,buf); -} - -static int dibusb_general_pll_set(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep, u8 pll_buf[5]) -{ - struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; - u8 buf[4]; - int ret=0; - - switch (dib->tuner->id) { - case DIBUSB_TUNER_CABLE_THOMSON: - ret = thomson_cable_eu_pll_set(fep, buf); - break; - case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5: - ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf); - break; - case DIBUSB_TUNER_CABLE_LG_TDTP_E102P: - ret = lg_tdtp_e102p_tua6034(fep, buf); - break; - case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5: - ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf); - break; - default: - warn("no pll programming routine found for tuner %d.\n",dib->tuner->id); - ret = -ENODEV; - break; - } - - if (ret) - return ret; - - return dibusb_pll_i2c_helper(dib,pll_buf,buf); -} diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c deleted file mode 100644 index 504ba47afdf..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices - * based on reference design made by DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * see dvb-dibusb-core.c for more copyright details. - * - * This file contains functions for downloading the firmware to the device. - */ -#include "dvb-dibusb.h" - -#include -#include - -/* - * load a firmware packet to the device - */ -static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) -{ - return usb_control_msg(udev, usb_sndctrlpipe(udev,0), - 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000); -} - -int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev) -{ - const struct firmware *fw = NULL; - u16 addr; - u8 *b,*p; - int ret = 0,i; - - if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems.", - dibdev->dev_cl->firmware); - return ret; - } - - info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware); - - p = kmalloc(fw->size,GFP_KERNEL); - if (p != NULL) { - u8 reset; - /* - * you cannot use the fw->data as buffer for - * usb_control_msg, a new buffer has to be - * created - */ - memcpy(p,fw->data,fw->size); - - /* stop the CPU */ - reset = 1; - if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1) - err("could not stop the USB controller CPU."); - for(i = 0; p[i+3] == 0 && i < fw->size; ) { - b = (u8 *) &p[i]; - addr = *((u16 *) &b[1]); - - ret = dibusb_writemem(udev,addr,&b[4],b[0]); - - if (ret != b[0]) { - err("error while transferring firmware " - "(transferred size: %d, block size: %d)", - ret,b[0]); - ret = -EINVAL; - break; - } - i += 5 + b[0]; - } - /* length in ret */ - if (ret > 0) - ret = 0; - /* restart the CPU */ - reset = 0; - if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) { - err("could not restart the USB controller CPU."); - ret = -EINVAL; - } - - kfree(p); - } else { - ret = -ENOMEM; - } - release_firmware(fw); - - return ret; -} diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c deleted file mode 100644 index 9dc8b15517b..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices - * based on reference design made by DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * see dvb-dibusb-core.c for more copyright details. - * - * This file contains functions for handling the event device on the software - * side and the remote control on the hardware side. - */ -#include "dvb-dibusb.h" - -/* Table to map raw key codes to key events. This should not be hard-wired - into the kernel. */ -static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] = -{ - /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ - { 0x00, 0xff, 0x16, KEY_POWER }, - { 0x00, 0xff, 0x10, KEY_MUTE }, - { 0x00, 0xff, 0x03, KEY_1 }, - { 0x00, 0xff, 0x01, KEY_2 }, - { 0x00, 0xff, 0x06, KEY_3 }, - { 0x00, 0xff, 0x09, KEY_4 }, - { 0x00, 0xff, 0x1d, KEY_5 }, - { 0x00, 0xff, 0x1f, KEY_6 }, - { 0x00, 0xff, 0x0d, KEY_7 }, - { 0x00, 0xff, 0x19, KEY_8 }, - { 0x00, 0xff, 0x1b, KEY_9 }, - { 0x00, 0xff, 0x15, KEY_0 }, - { 0x00, 0xff, 0x05, KEY_CHANNELUP }, - { 0x00, 0xff, 0x02, KEY_CHANNELDOWN }, - { 0x00, 0xff, 0x1e, KEY_VOLUMEUP }, - { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN }, - { 0x00, 0xff, 0x11, KEY_RECORD }, - { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ - { 0x00, 0xff, 0x14, KEY_PLAY }, - { 0x00, 0xff, 0x1a, KEY_STOP }, - { 0x00, 0xff, 0x40, KEY_REWIND }, - { 0x00, 0xff, 0x12, KEY_FASTFORWARD }, - { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ - { 0x00, 0xff, 0x4c, KEY_PAUSE }, - { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */ - { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ - /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ - { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */ - { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */ - { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */ - { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */ - { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */ - { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */ - /* Key codes for the KWorld/ADSTech/JetWay remote. */ - { 0x86, 0x6b, 0x12, KEY_POWER }, - { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */ - { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */ - { 0x86, 0x6b, 0x0b, KEY_EPG }, - { 0x86, 0x6b, 0x10, KEY_MUTE }, - { 0x86, 0x6b, 0x01, KEY_1 }, - { 0x86, 0x6b, 0x02, KEY_2 }, - { 0x86, 0x6b, 0x03, KEY_3 }, - { 0x86, 0x6b, 0x04, KEY_4 }, - { 0x86, 0x6b, 0x05, KEY_5 }, - { 0x86, 0x6b, 0x06, KEY_6 }, - { 0x86, 0x6b, 0x07, KEY_7 }, - { 0x86, 0x6b, 0x08, KEY_8 }, - { 0x86, 0x6b, 0x09, KEY_9 }, - { 0x86, 0x6b, 0x0a, KEY_0 }, - { 0x86, 0x6b, 0x18, KEY_ZOOM }, - { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */ - { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */ - { 0x86, 0x6b, 0x00, KEY_UNDO }, - { 0x86, 0x6b, 0x1d, KEY_RECORD }, - { 0x86, 0x6b, 0x0d, KEY_STOP }, - { 0x86, 0x6b, 0x0e, KEY_PAUSE }, - { 0x86, 0x6b, 0x16, KEY_PLAY }, - { 0x86, 0x6b, 0x11, KEY_BACK }, - { 0x86, 0x6b, 0x19, KEY_FORWARD }, - { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */ - { 0x86, 0x6b, 0x15, KEY_ESC }, - { 0x86, 0x6b, 0x1a, KEY_UP }, - { 0x86, 0x6b, 0x1e, KEY_DOWN }, - { 0x86, 0x6b, 0x1f, KEY_LEFT }, - { 0x86, 0x6b, 0x1b, KEY_RIGHT }, -}; - -/* Hauppauge NOVA-T USB2 keys */ -static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = { - { 0xddf, KEY_GOTO }, - { 0xdef, KEY_POWER }, - { 0xce7, KEY_TV }, - { 0xcc7, KEY_VIDEO }, - { 0xccf, KEY_AUDIO }, - { 0xcd7, KEY_MEDIA }, - { 0xcdf, KEY_EPG }, - { 0xca7, KEY_UP }, - { 0xc67, KEY_RADIO }, - { 0xcb7, KEY_LEFT }, - { 0xd2f, KEY_OK }, - { 0xcbf, KEY_RIGHT }, - { 0xcff, KEY_BACK }, - { 0xcaf, KEY_DOWN }, - { 0xc6f, KEY_MENU }, - { 0xc87, KEY_VOLUMEUP }, - { 0xc8f, KEY_VOLUMEDOWN }, - { 0xc97, KEY_CHANNEL }, - { 0xc7f, KEY_MUTE }, - { 0xd07, KEY_CHANNELUP }, - { 0xd0f, KEY_CHANNELDOWN }, - { 0xdbf, KEY_RECORD }, - { 0xdb7, KEY_STOP }, - { 0xd97, KEY_REWIND }, - { 0xdaf, KEY_PLAY }, - { 0xda7, KEY_FASTFORWARD }, - { 0xd27, KEY_LAST }, /* Skip backwards */ - { 0xd87, KEY_PAUSE }, - { 0xcf7, KEY_NEXT }, - { 0xc07, KEY_0 }, - { 0xc0f, KEY_1 }, - { 0xc17, KEY_2 }, - { 0xc1f, KEY_3 }, - { 0xc27, KEY_4 }, - { 0xc2f, KEY_5 }, - { 0xc37, KEY_6 }, - { 0xc3f, KEY_7 }, - { 0xc47, KEY_8 }, - { 0xc4f, KEY_9 }, - { 0xc57, KEY_KPASTERISK }, - { 0xc77, KEY_GRAVE }, /* # */ - { 0xc5f, KEY_RED }, - { 0xd77, KEY_GREEN }, - { 0xdc7, KEY_YELLOW }, - { 0xd4f, KEY_BLUE}, -}; - -static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5]) -{ - int i; - switch (rb[0]) { - case DIBUSB_RC_NEC_KEY_PRESSED: - /* rb[1-3] is the actual key, rb[4] is a checksum */ - deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - rb[1], rb[2], rb[3], rb[4]); - - if ((0xff - rb[3]) != rb[4]) { - deb_rc("remote control checksum failed.\n"); - break; - } - - /* See if we can match the raw key code. */ - for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) { - if (nec_rc_keys[i].c0 == rb[1] && - nec_rc_keys[i].c1 == rb[2] && - nec_rc_keys[i].c2 == rb[3]) { - - dib->last_event = nec_rc_keys[i].key; - return 1; - } - } - break; - case DIBUSB_RC_NEC_KEY_REPEATED: - /* rb[1]..rb[4] are always zero.*/ - /* Repeats often seem to occur so for the moment just ignore this. */ - return 0; - case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */ - default: - break; - } - return -1; -} - -static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4]) -{ - u16 raw; - int i,state; - switch (rb[0]) { - case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED: - raw = ((rb[1] & 0x0f) << 8) | rb[2]; - - state = !!(rb[1] & 0x40); - - deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state); - for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) { - if (haupp_rc_keys[i].raw == raw) { - if (dib->last_event == haupp_rc_keys[i].key && - dib->last_state == state) { - deb_rc("key repeat\n"); - return 0; - } else { - dib->last_event = haupp_rc_keys[i].key; - dib->last_state = state; - return 1; - } - } - } - - break; - case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY: - default: - break; - } - return -1; -} - -/* - * Read the remote control and feed the appropriate event. - * NEC protocol is used for remote controls - */ -static int dibusb_read_remote_control(struct usb_dibusb *dib) -{ - u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5]; - int ret,event = 0; - - if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5))) - return ret; - - switch (dib->dibdev->dev_cl->remote_type) { - case DIBUSB_RC_NEC_PROTOCOL: - event = dibusb_key2event_nec(dib,rb); - break; - case DIBUSB_RC_HAUPPAUGE_PROTO: - event = dibusb_key2event_hauppauge(dib,rb); - default: - break; - } - - /* key repeat */ - if (event == 0) - if (++dib->repeat_key_count < dib->rc_key_repeat_count) { - deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count); - event = -1; /* skip this key repeat */ - } - - if (event == 1 || event == 0) { - deb_rc("Translated key 0x%04x\n",event); - - /* Signal down and up events for this key. */ - input_report_key(&dib->rc_input_dev, dib->last_event, 1); - input_report_key(&dib->rc_input_dev, dib->last_event, 0); - input_sync(&dib->rc_input_dev); - - if (event == 1) - dib->repeat_key_count = 0; - } - return 0; -} - -/* Remote-control poll function - called every dib->rc_query_interval ms to see - whether the remote control has received anything. */ -static void dibusb_remote_query(void *data) -{ - struct usb_dibusb *dib = (struct usb_dibusb *) data; - /* TODO: need a lock here. We can simply skip checking for the remote control - if we're busy. */ - dibusb_read_remote_control(dib); - schedule_delayed_work(&dib->rc_query_work, - msecs_to_jiffies(dib->rc_query_interval)); -} - -int dibusb_remote_init(struct usb_dibusb *dib) -{ - int i; - - if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO) - return 0; - - /* Initialise the remote-control structures.*/ - init_input_dev(&dib->rc_input_dev); - - dib->rc_input_dev.evbit[0] = BIT(EV_KEY); - dib->rc_input_dev.keycodesize = sizeof(unsigned char); - dib->rc_input_dev.keycodemax = KEY_MAX; - dib->rc_input_dev.name = DRIVER_DESC " remote control"; - - switch (dib->dibdev->dev_cl->remote_type) { - case DIBUSB_RC_NEC_PROTOCOL: - for (i=0; irc_input_dev.keybit); - break; - case DIBUSB_RC_HAUPPAUGE_PROTO: - for (i=0; irc_input_dev.keybit); - break; - default: - break; - } - - - input_register_device(&dib->rc_input_dev); - - INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib); - - /* Start the remote-control polling. */ - if (dib->rc_query_interval < 40) - dib->rc_query_interval = 100; /* default */ - - info("schedule remote query interval to %d msecs.",dib->rc_query_interval); - schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval)); - - dib->init_state |= DIBUSB_STATE_REMOTE; - - return 0; -} - -int dibusb_remote_exit(struct usb_dibusb *dib) -{ - if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO) - return 0; - - if (dib->init_state & DIBUSB_STATE_REMOTE) { - cancel_delayed_work(&dib->rc_query_work); - flush_scheduled_work(); - input_unregister_device(&dib->rc_input_dev); - } - dib->init_state &= ~DIBUSB_STATE_REMOTE; - return 0; -} diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c deleted file mode 100644 index 642f0596a5b..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices - * based on reference design made by DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * see dvb-dibusb-core.c for more copyright details. - * - * This file contains functions for initializing and handling the - * usb specific stuff. - */ -#include "dvb-dibusb.h" - -#include -#include - -int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf, - u16 rlen) -{ - int actlen,ret = -ENOMEM; - - if (wbuf == NULL || wlen == 0) - return -EINVAL; - - if ((ret = down_interruptible(&dib->usb_sem))) - return ret; - - debug_dump(wbuf,wlen); - - ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev, - dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen, - DIBUSB_I2C_TIMEOUT); - - if (ret) - err("bulk message failed: %d (%d/%d)",ret,wlen,actlen); - else - ret = actlen != wlen ? -1 : 0; - - /* an answer is expected, and no error before */ - if (!ret && rbuf && rlen) { - ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev, - dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen, - DIBUSB_I2C_TIMEOUT); - - if (ret) - err("recv bulk message failed: %d",ret); - else { - deb_alot("rlen: %d\n",rlen); - debug_dump(rbuf,actlen); - } - } - - up(&dib->usb_sem); - return ret; -} - -/* - * Cypress controls - */ -int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len) -{ - return dibusb_readwrite_usb(dib,buf,len,NULL,0); -} - -#if 0 -/* - * #if 0'ing the following functions as they are not in use _now_, - * but probably will be sometime. - */ -/* - * do not use this, just a workaround for a bug, - * which will hopefully never occur :). - */ -int dibusb_interrupt_read_loop(struct usb_dibusb *dib) -{ - u8 b[1] = { DIBUSB_REQ_INTR_READ }; - return dibusb_write_usb(dib,b,1); -} -#endif - -/* - * ioctl for the firmware - */ -static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen) -{ - u8 b[34]; - int size = plen > 32 ? 32 : plen; - memset(b,0,34); - b[0] = DIBUSB_REQ_SET_IOCTL; - b[1] = cmd; - - if (size > 0) - memcpy(&b[2],param,size); - - return dibusb_write_usb(dib,b,34); //2+size); -} - -/* - * ioctl for power control - */ -int dibusb_hw_wakeup(struct dvb_frontend *fe) -{ - struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv; - u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP }; - deb_info("dibusb-device is getting up.\n"); - - switch (dib->dibdev->dev_cl->id) { - case DTT200U: - break; - default: - dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); - break; - } - - if (dib->fe_init) - return dib->fe_init(fe); - - return 0; -} - -int dibusb_hw_sleep(struct dvb_frontend *fe) -{ - struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv; - u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP }; - deb_info("dibusb-device is going to bed.\n"); - /* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */ - switch (dib->dibdev->dev_cl->id) { - case DIBUSB1_1: - case NOVAT_USB2: - case DTT200U: - break; - default: - dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); - break; - } - if (dib->fe_sleep) - return dib->fe_sleep(fe); - - return 0; -} - -int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode) -{ - u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode }; - return dibusb_readwrite_usb(dib,b,2,NULL,0); -} - -static int dibusb_urb_kill(struct usb_dibusb *dib) -{ - int i; -deb_info("trying to kill urbs\n"); - if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) { - for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) { - deb_info("killing URB no. %d.\n",i); - - /* stop the URB */ - usb_kill_urb(dib->urb_list[i]); - } - } else - deb_info(" URBs not killed.\n"); - dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT; - return 0; -} - -static int dibusb_urb_submit(struct usb_dibusb *dib) -{ - int i,ret; - if (dib->init_state & DIBUSB_STATE_URB_INIT) { - for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) { - deb_info("submitting URB no. %d\n",i); - if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) { - err("could not submit buffer urb no. %d - get them all back\n",i); - dibusb_urb_kill(dib); - return ret; - } - dib->init_state |= DIBUSB_STATE_URB_SUBMIT; - } - } - return 0; -} - -int dibusb_streaming(struct usb_dibusb *dib,int onoff) -{ - if (onoff) - dibusb_urb_submit(dib); - else - dibusb_urb_kill(dib); - - switch (dib->dibdev->dev_cl->id) { - case DIBUSB2_0: - case DIBUSB2_0B: - case NOVAT_USB2: - case UMT2_0: - if (onoff) - return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0); - else - return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0); - break; - default: - break; - } - return 0; -} - -int dibusb_urb_init(struct usb_dibusb *dib) -{ - int i,bufsize,def_pid_parse = 1; - - /* - * when reloading the driver w/o replugging the device - * a timeout occures, this helps - */ - usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd)); - usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd)); - usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data)); - - /* allocate the array for the data transfer URBs */ - dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL); - if (dib->urb_list == NULL) - return -ENOMEM; - memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *)); - - dib->init_state |= DIBUSB_STATE_URB_LIST; - - bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size; - deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize); - /* allocate the actual buffer for the URBs */ - if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) { - deb_info("not enough memory.\n"); - return -ENOMEM; - } - deb_info("allocation complete\n"); - memset(dib->buffer,0,bufsize); - - dib->init_state |= DIBUSB_STATE_URB_BUF; - - /* allocate and submit the URBs */ - for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) { - if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) { - return -ENOMEM; - } - - usb_fill_bulk_urb( dib->urb_list[i], dib->udev, - usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data), - &dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size], - dib->dibdev->dev_cl->urb_buffer_size, - dibusb_urb_complete, dib); - - dib->urb_list[i]->transfer_flags = 0; - - dib->init_state |= DIBUSB_STATE_URB_INIT; - } - - /* dib->pid_parse here contains the value of the module parameter */ - /* decide if pid parsing can be deactivated: - * is possible (by device type) and wanted (by user) - */ - switch (dib->dibdev->dev_cl->id) { - case DIBUSB2_0: - case DIBUSB2_0B: - if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) { - def_pid_parse = 0; - info("running at HIGH speed, will deliver the complete TS."); - } else - info("will use pid_parsing."); - break; - default: - break; - } - /* from here on it contains the device and user decision */ - dib->pid_parse = def_pid_parse; - - return 0; -} - -int dibusb_urb_exit(struct usb_dibusb *dib) -{ - int i; - - dibusb_urb_kill(dib); - - if (dib->init_state & DIBUSB_STATE_URB_LIST) { - for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) { - if (dib->urb_list[i] != NULL) { - deb_info("freeing URB no. %d.\n",i); - /* free the URBs */ - usb_free_urb(dib->urb_list[i]); - } - } - /* free the urb array */ - kfree(dib->urb_list); - dib->init_state &= ~DIBUSB_STATE_URB_LIST; - } - - if (dib->init_state & DIBUSB_STATE_URB_BUF) - pci_free_consistent(NULL, - dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count, - dib->buffer,dib->dma_handle); - - dib->init_state &= ~DIBUSB_STATE_URB_BUF; - dib->init_state &= ~DIBUSB_STATE_URB_INIT; - return 0; -} diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h deleted file mode 100644 index c965b64fb1a..00000000000 --- a/drivers/media/dvb/dibusb/dvb-dibusb.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * dvb-dibusb.h - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * for more information see dvb-dibusb-core.c . - */ -#ifndef __DVB_DIBUSB_H__ -#define __DVB_DIBUSB_H__ - -#include -#include -#include - -#include "dvb_frontend.h" -#include "dvb_demux.h" -#include "dvb_net.h" -#include "dmxdev.h" - -#include "dib3000.h" -#include "mt352.h" - -/* debug */ -#ifdef CONFIG_DVB_DIBCOM_DEBUG -#define dprintk(level,args...) \ - do { if ((dvb_dibusb_debug & level)) { printk(args); } } while (0) - -#define debug_dump(b,l) {\ - int i; \ - for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \ - deb_xfer("\n");\ -} - -#else -#define dprintk(args...) -#define debug_dump(b,l) -#endif - -extern int dvb_dibusb_debug; - -/* Version information */ -#define DRIVER_VERSION "0.3" -#define DRIVER_DESC "DiBcom based USB Budget DVB-T device" -#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" - -#define deb_info(args...) dprintk(0x01,args) -#define deb_xfer(args...) dprintk(0x02,args) -#define deb_alot(args...) dprintk(0x04,args) -#define deb_ts(args...) dprintk(0x08,args) -#define deb_err(args...) dprintk(0x10,args) -#define deb_rc(args...) dprintk(0x20,args) - -/* generic log methods - taken from usb.h */ -#undef err -#define err(format, arg...) printk(KERN_ERR "dvb-dibusb: " format "\n" , ## arg) -#undef info -#define info(format, arg...) printk(KERN_INFO "dvb-dibusb: " format "\n" , ## arg) -#undef warn -#define warn(format, arg...) printk(KERN_WARNING "dvb-dibusb: " format "\n" , ## arg) - -struct dibusb_usb_controller { - const char *name; /* name of the usb controller */ - u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */ -}; - -typedef enum { - DIBUSB1_1 = 0, - DIBUSB1_1_AN2235, - DIBUSB2_0, - UMT2_0, - DIBUSB2_0B, - NOVAT_USB2, - DTT200U, -} dibusb_class_t; - -typedef enum { - DIBUSB_TUNER_CABLE_THOMSON = 0, - DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5, - DIBUSB_TUNER_CABLE_LG_TDTP_E102P, - DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5, -} dibusb_tuner_t; - -typedef enum { - DIBUSB_DIB3000MB = 0, - DIBUSB_DIB3000MC, - DIBUSB_MT352, - DTT200U_FE, -} dibusb_demodulator_t; - -typedef enum { - DIBUSB_RC_NO = 0, - DIBUSB_RC_NEC_PROTOCOL, - DIBUSB_RC_HAUPPAUGE_PROTO, -} dibusb_remote_t; - -struct dibusb_tuner { - dibusb_tuner_t id; - - u8 pll_addr; /* tuner i2c address */ -}; -extern struct dibusb_tuner dibusb_tuner[]; - -#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4 -struct dibusb_demod { - dibusb_demodulator_t id; - - int pid_filter_count; /* counter of the internal pid_filter */ - u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */ -}; - -#define DIBUSB_MAX_TUNER_NUM 2 -struct dibusb_device_class { - dibusb_class_t id; - - const struct dibusb_usb_controller *usb_ctrl; /* usb controller */ - const char *firmware; /* valid firmware filenames */ - - int pipe_cmd; /* command pipe (read/write) */ - int pipe_data; /* data pipe */ - - int urb_count; /* number of data URBs to be submitted */ - int urb_buffer_size; /* the size of the buffer for each URB */ - - dibusb_remote_t remote_type; /* does this device have a ir-receiver */ - - struct dibusb_demod *demod; /* which demodulator is mount */ - struct dibusb_tuner *tuner; /* which tuner can be found here */ -}; - -#define DIBUSB_ID_MAX_NUM 15 -struct dibusb_usb_device { - const char *name; /* real name of the box */ - struct dibusb_device_class *dev_cl; /* which dibusb_device_class is this device part of */ - - struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */ - struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */ -}; - -/* a PID for the pid_filter list, when in use */ -struct dibusb_pid -{ - int index; - u16 pid; - int active; -}; - -struct usb_dibusb { - /* usb */ - struct usb_device * udev; - - struct dibusb_usb_device * dibdev; - -#define DIBUSB_STATE_INIT 0x000 -#define DIBUSB_STATE_URB_LIST 0x001 -#define DIBUSB_STATE_URB_BUF 0x002 -#define DIBUSB_STATE_URB_INIT 0x004 -#define DIBUSB_STATE_DVB 0x008 -#define DIBUSB_STATE_I2C 0x010 -#define DIBUSB_STATE_REMOTE 0x020 -#define DIBUSB_STATE_URB_SUBMIT 0x040 - int init_state; - - int feedcount; - struct dib_fe_xfer_ops xfer_ops; - - struct dibusb_tuner *tuner; - - struct urb **urb_list; - u8 *buffer; - dma_addr_t dma_handle; - - /* I2C */ - struct i2c_adapter i2c_adap; - - /* locking */ - struct semaphore usb_sem; - struct semaphore i2c_sem; - - /* dvb */ - struct dvb_adapter adapter; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dvb_net dvb_net; - struct dvb_frontend* fe; - - int (*fe_sleep) (struct dvb_frontend *); - int (*fe_init) (struct dvb_frontend *); - - /* remote control */ - struct input_dev rc_input_dev; - struct work_struct rc_query_work; - int last_event; - int last_state; /* for Hauppauge RC protocol */ - int repeat_key_count; - int rc_key_repeat_count; /* module parameter */ - - /* module parameters */ - int pid_parse; - int rc_query_interval; -}; - -/* commonly used functions in the separated files */ - -/* dvb-dibusb-firmware.c */ -int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev); - -/* dvb-dibusb-remote.c */ -int dibusb_remote_exit(struct usb_dibusb *dib); -int dibusb_remote_init(struct usb_dibusb *dib); - -/* dvb-dibusb-fe-i2c.c */ -int dibusb_fe_init(struct usb_dibusb* dib); -int dibusb_fe_exit(struct usb_dibusb *dib); -int dibusb_i2c_init(struct usb_dibusb *dib); -int dibusb_i2c_exit(struct usb_dibusb *dib); - -/* dvb-dibusb-dvb.c */ -void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs); -int dibusb_dvb_init(struct usb_dibusb *dib); -int dibusb_dvb_exit(struct usb_dibusb *dib); - -/* dvb-dibusb-usb.c */ -int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf, - u16 rlen); -int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len); - -int dibusb_hw_wakeup(struct dvb_frontend *); -int dibusb_hw_sleep(struct dvb_frontend *); -int dibusb_set_streaming_mode(struct usb_dibusb *,u8); -int dibusb_streaming(struct usb_dibusb *,int); - -int dibusb_urb_init(struct usb_dibusb *); -int dibusb_urb_exit(struct usb_dibusb *); - -/* dvb-fe-dtt200u.c */ -struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *,struct dib_fe_xfer_ops *); - -/* i2c and transfer stuff */ -#define DIBUSB_I2C_TIMEOUT 5000 - -/* - * protocol of all dibusb related devices - */ - -/* - * bulk msg to/from endpoint 0x01 - * - * general structure: - * request_byte parameter_bytes - */ - -#define DIBUSB_REQ_START_READ 0x00 -#define DIBUSB_REQ_START_DEMOD 0x01 - -/* - * i2c read - * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word - * bulk read: byte_buffer (length_word bytes) - */ -#define DIBUSB_REQ_I2C_READ 0x02 - -/* - * i2c write - * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes - */ -#define DIBUSB_REQ_I2C_WRITE 0x03 - -/* - * polling the value of the remote control - * bulk write: 0x04 - * bulk read: byte_buffer (5 bytes) - * - * first byte of byte_buffer shows the status (0x00, 0x01, 0x02) - */ -#define DIBUSB_REQ_POLL_REMOTE 0x04 - -#define DIBUSB_RC_NEC_EMPTY 0x00 -#define DIBUSB_RC_NEC_KEY_PRESSED 0x01 -#define DIBUSB_RC_NEC_KEY_REPEATED 0x02 - -/* additional status values for Hauppauge Remote Control Protocol */ -#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01 -#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03 - -/* streaming mode: - * bulk write: 0x05 mode_byte - * - * mode_byte is mostly 0x00 - */ -#define DIBUSB_REQ_SET_STREAMING_MODE 0x05 - -/* interrupt the internal read loop, when blocking */ -#define DIBUSB_REQ_INTR_READ 0x06 - -/* io control - * 0x07 cmd_byte param_bytes - * - * param_bytes can be up to 32 bytes - * - * cmd_byte function parameter name - * 0x00 power mode - * 0x00 sleep - * 0x01 wakeup - * - * 0x01 enable streaming - * 0x02 disable streaming - * - * - */ -#define DIBUSB_REQ_SET_IOCTL 0x07 - -/* IOCTL commands */ - -/* change the power mode in firmware */ -#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00 -#define DIBUSB_IOCTL_POWER_SLEEP 0x00 -#define DIBUSB_IOCTL_POWER_WAKEUP 0x01 - -/* modify streaming of the FX2 */ -#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01 -#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02 - -#endif diff --git a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c b/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c deleted file mode 100644 index 1872aa6d200..00000000000 --- a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the - * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as - * it uses the usb-transfer functions directly (maybe creating a - * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.) - * - * Copyright (C) 2005 Patrick Boettcher - * - * see dvb-dibusb-core.c for copyright details. - */ - -/* guessed protocol description (reverse engineered): - * read - * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1 - * 81 - - * 82 - crash - do not touch - * 83 - crash - do not touch - * 84 - remote control - * 85 - crash - do not touch (OK, stop testing here) - * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) - * 89 - noise-to-signal - * 8a - unkown 1 byte - signal_strength - * 8c - ber ??? - * 8d - ber - * 8e - unc - * - * write - * 02 - bandwidth - * 03 - frequency (divided by 250000) - * 04 - pid table (index pid(7:0) pid(12:8)) - * 05 - reset the pid table - * 08 - demod transfer enabled or not (FX2 transfer is enabled by default) - */ - -#include "dvb-dibusb.h" -#include "dvb_frontend.h" - -struct dtt200u_fe_state { - struct usb_dibusb *dib; - - struct dvb_frontend_parameters fep; - struct dvb_frontend frontend; -}; - -#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what) - -static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw[1] = { 0x81 }; - u8 br[3] = { 0 }; -// u8 bdeb[5] = { 0 }; - - dibusb_readwrite_usb(state->dib,bw,1,br,3); - switch (br[0]) { - case 0x01: - *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - break; - case 0x00: - *stat = 0; - break; - default: - moan("br[0]",0x81); - break; - } - -// bw[0] = 0x88; -// dibusb_readwrite_usb(state->dib,bw,1,bdeb,5); - -// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]); - - return 0; -} -static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw[1] = { 0x8d }; - *ber = 0; - dibusb_readwrite_usb(state->dib,bw,1,(u8*) ber, 3); - return 0; -} - -static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw[1] = { 0x8c }; - *unc = 0; - dibusb_readwrite_usb(state->dib,bw,1,(u8*) unc, 3); - return 0; -} - -static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw[1] = { 0x8a }; - u8 b; - dibusb_readwrite_usb(state->dib,bw,1,&b, 1); - *strength = (b << 8) | b; - return 0; -} - -static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw[1] = { 0x89 }; - u8 br[1] = { 0 }; - dibusb_readwrite_usb(state->dib,bw,1,br,1); - *snr = ((0xff - br[0]) << 8) | (0xff - br[0]); - return 0; -} - -static int dtt200u_fe_init(struct dvb_frontend* fe) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 b[] = { 0x01 }; - return dibusb_write_usb(state->dib,b,1); -} - -static int dtt200u_fe_sleep(struct dvb_frontend* fe) -{ - return dtt200u_fe_init(fe); -} - -static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1500; - tune->step_size = 166667; - tune->max_drift = 166667 * 2; - return 0; -} - -static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u16 freq = fep->frequency / 250000; - u8 bw,bwbuf[2] = { 0x03, 0 }, freqbuf[3] = { 0x02, 0, 0 }; - - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: bw = 8; break; - case BANDWIDTH_7_MHZ: bw = 7; break; - case BANDWIDTH_6_MHZ: bw = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; - } - deb_info("set_frontend\n"); - - bwbuf[1] = bw; - dibusb_write_usb(state->dib,bwbuf,2); - - freqbuf[1] = freq & 0xff; - freqbuf[2] = (freq >> 8) & 0xff; - dibusb_write_usb(state->dib,freqbuf,3); - - memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters)); - - return 0; -} - -static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters)); - return 0; -} - -static void dtt200u_fe_release(struct dvb_frontend* fe) -{ - struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; - kfree(state); -} - -static int dtt200u_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff) -{ - struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; - u8 b_pid[4]; - pid = onoff ? pid : 0; - - b_pid[0] = 0x04; - b_pid[1] = index; - b_pid[2] = pid & 0xff; - b_pid[3] = (pid >> 8) & 0xff; - - dibusb_write_usb(state->dib,b_pid,4); - return 0; -} - -static int dtt200u_fifo_control(struct dvb_frontend *fe, int onoff) -{ - struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; - u8 b_streaming[2] = { 0x08, onoff }; - u8 b_rst_pid[1] = { 0x05 }; - - dibusb_write_usb(state->dib,b_streaming,2); - - if (!onoff) - dibusb_write_usb(state->dib,b_rst_pid,1); - return 0; -} - -static struct dvb_frontend_ops dtt200u_fe_ops; - -struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfer_ops *xfer_ops) -{ - struct dtt200u_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL); - if (state == NULL) - goto error; - memset(state,0,sizeof(struct dtt200u_fe_state)); - - deb_info("attaching frontend dtt200u\n"); - - state->dib = dib; - - state->frontend.ops = &dtt200u_fe_ops; - state->frontend.demodulator_priv = state; - - xfer_ops->fifo_ctrl = dtt200u_fifo_control; - xfer_ops->pid_ctrl = dtt200u_pid_control; - - goto success; -error: - return NULL; -success: - return &state->frontend; -} - -static struct dvb_frontend_ops dtt200u_fe_ops = { - .info = { - .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dtt200u_fe_release, - - .init = dtt200u_fe_init, - .sleep = dtt200u_fe_sleep, - - .set_frontend = dtt200u_fe_set_frontend, - .get_frontend = dtt200u_fe_get_frontend, - .get_tune_settings = dtt200u_fe_get_tune_settings, - - .read_status = dtt200u_fe_read_status, - .read_ber = dtt200u_fe_read_ber, - .read_signal_strength = dtt200u_fe_read_signal_strength, - .read_snr = dtt200u_fe_read_snr, - .read_ucblocks = dtt200u_fe_read_unc_blocks, -}; -- cgit v1.2.3-70-g09d2 From 776338e121b9db3156bfb4e21622a0219bbab9d4 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:35 -0700 Subject: [PATCH] dvb: Add generalized dvb-usb driver Add generalized dvb-usb driver which supports a wide variety of devices. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dvb/README.dvb-usb | 308 ++++++++++++++++++++++++++ drivers/media/dvb/Kconfig | 1 + drivers/media/dvb/Makefile | 2 +- drivers/media/dvb/dvb-usb/Kconfig | 99 +++++++++ drivers/media/dvb/dvb-usb/Makefile | 30 +++ drivers/media/dvb/dvb-usb/a800.c | 176 +++++++++++++++ drivers/media/dvb/dvb-usb/dibusb-common.c | 272 +++++++++++++++++++++++ drivers/media/dvb/dvb-usb/dibusb-mb.c | 316 +++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/dibusb-mc.c | 116 ++++++++++ drivers/media/dvb/dvb-usb/dibusb.h | 122 +++++++++++ drivers/media/dvb/dvb-usb/digitv.c | 282 ++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/digitv.h | 65 ++++++ drivers/media/dvb/dvb-usb/dtt200u-fe.c | 206 +++++++++++++++++ drivers/media/dvb/dvb-usb/dtt200u.c | 171 +++++++++++++++ drivers/media/dvb/dvb-usb/dtt200u.h | 66 ++++++ drivers/media/dvb/dvb-usb/dvb-usb-common.h | 44 ++++ drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | 210 ++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | 100 +++++++++ drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | 118 ++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 83 +++++++ drivers/media/dvb/dvb-usb/dvb-usb-init.c | 211 ++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 175 +++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-urb.c | 211 ++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb.h | 315 ++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/nova-t-usb2.c | 236 ++++++++++++++++++++ drivers/media/dvb/dvb-usb/umt-010.c | 162 ++++++++++++++ drivers/media/dvb/dvb-usb/vp7045-fe.c | 196 +++++++++++++++++ drivers/media/dvb/dvb-usb/vp7045.c | 263 ++++++++++++++++++++++ drivers/media/dvb/dvb-usb/vp7045.h | 78 +++++++ drivers/media/dvb/frontends/dib3000-common.c | 2 +- drivers/media/dvb/frontends/dib3000.h | 5 +- drivers/media/dvb/frontends/dib3000mb.c | 20 +- drivers/media/dvb/frontends/dib3000mb_priv.h | 2 +- drivers/media/dvb/frontends/dib3000mc.c | 29 +-- drivers/media/dvb/frontends/dvb-pll.c | 94 +++++++- drivers/media/dvb/frontends/dvb-pll.h | 9 +- 36 files changed, 4743 insertions(+), 52 deletions(-) create mode 100644 Documentation/dvb/README.dvb-usb create mode 100644 drivers/media/dvb/dvb-usb/Kconfig create mode 100644 drivers/media/dvb/dvb-usb/Makefile create mode 100644 drivers/media/dvb/dvb-usb/a800.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb-common.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb-mb.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb-mc.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb.h create mode 100644 drivers/media/dvb/dvb-usb/digitv.c create mode 100644 drivers/media/dvb/dvb-usb/digitv.h create mode 100644 drivers/media/dvb/dvb-usb/dtt200u-fe.c create mode 100644 drivers/media/dvb/dvb-usb/dtt200u.c create mode 100644 drivers/media/dvb/dvb-usb/dtt200u.h create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-common.h create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-dvb.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-firmware.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-i2c.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-ids.h create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-init.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-remote.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-urb.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb.h create mode 100644 drivers/media/dvb/dvb-usb/nova-t-usb2.c create mode 100644 drivers/media/dvb/dvb-usb/umt-010.c create mode 100644 drivers/media/dvb/dvb-usb/vp7045-fe.c create mode 100644 drivers/media/dvb/dvb-usb/vp7045.c create mode 100644 drivers/media/dvb/dvb-usb/vp7045.h (limited to 'drivers/media') diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb new file mode 100644 index 00000000000..c7ed01b9f8f --- /dev/null +++ b/Documentation/dvb/README.dvb-usb @@ -0,0 +1,308 @@ +Documentation for dvb-usb-framework module and its devices + +Idea behind the dvb-usb-framework +================================= + +In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs and a firmware. + +Quite keen I wanted to put the driver (with some quirks of course) into dibusb. +After reading some specs and doing some USB snooping, it realized, that the +dibusb-driver would be a complete mess afterwards. So I decided to do it in a +different way: With the help of a dvb-usb-framework. + +The framework provides generic functions (mostly kernel API calls), such as: + +- Transport Stream URB handling in conjunction with dvb-demux-feed-control + (bulk and isoc (TODO) are supported) +- registering the device for the DVB-API +- registering an I2C-adapter if applicable +- remote-control/input-device handling +- firmware requesting and loading (currently just for the Cypress USB + controller) +- other functions/methods which can be shared by several drivers (such as + functions for bulk-control-commands) + +The source code of the particular DVB USB devices does just the communication +with the device via the bus. The connection between the DVB-API-functionality +is done via callbacks, assigned in a static device-description (struct +dvb_usb_device) each device-driver has to have. + +For an example have a look in drivers/media/dvb/dvb-usb/vp7045*. + +Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the +ttusb; flexcop-usb already benefits from the generic flexcop-device) to use +the dvb-usb-lib. + +TODO: dynamic enabling and disabling of the pid-filter in regard to number of +feeds requested. + +Supported devices USB1.1 +======================== + +Produced and reselled by Twinhan: +--------------------------------- +- TwinhanDTV USB-Ter DVB-T Device (VP7041) + http://www.twinhan.com/product_terrestrial_3.asp + +- TwinhanDTV Magic Box (VP7041e) + http://www.twinhan.com/product_terrestrial_4.asp + +- HAMA DVB-T USB device + http://www.hama.de/portal/articleId*110620/action*2598 + +- CTS Portable (Chinese Television System) (2) + http://www.2cts.tv/ctsportable/ + +- Unknown USB DVB-T device with vendor ID Hyper-Paltek + + +Produced and reselled by KWorld: +-------------------------------- +- KWorld V-Stream XPERT DTV DVB-T USB + http://www.kworld.com.tw/en/product/DVBT-USB/DVBT-USB.html + +- JetWay DTV DVB-T USB + http://www.jetway.com.tw/evisn/product/lcd-tv/DVT-USB/dtv-usb.htm + +- ADSTech Instant TV DVB-T USB + http://www.adstech.com/products/PTV-333/intro/PTV-333_intro.asp?pid=PTV-333 + + +Others: +------- +- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner) + http://82.161.246.249/products-tvbox.html + +- Compro Videomate DVB-U2000 - DVB-T USB (2) + http://www.comprousa.com/products/vmu2000.htm + +- Grandtec USB DVB-T + http://www.grand.com.tw/ + +- AVerMedia AverTV DVBT USB + http://www.avermedia.com/ + +- DiBcom USB DVB-T reference device (non-public) + + +Supported devices USB2.0-only +============================= +- Twinhan MagicBox II + http://www.twinhan.com/product_terrestrial_7.asp + +- TwinhanDTV Alpha + http://www.twinhan.com/product_terrestrial_8.asp + +- DigitalNow TinyUSB 2 DVB-t Receiver + http://www.digitalnow.com.au/DigitalNow%20tinyUSB2%20Specifications.html + +- Hanftek UMT-010 + http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529 + + +Supported devices USB2.0 and USB1.1 +============================= +- Typhoon/Yakumo/HAMA/Yuan DVB-T mobile USB2.0 + http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T + http://www.yuan.com.tw/en/products/vdo_ub300.html + http://www.hama.de/portal/articleId*114663/action*2563 + http://www.anubisline.com/english/articlec.asp?id=50502&catid=002 + +- Artec T1 USB TVBOX (FX2) (2) + +- Hauppauge WinTV NOVA-T USB2 + http://www.hauppauge.com/ + +- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B) + +- DiBcom USB2.0 DVB-T reference device (non-public) + +- AVerMedia AverTV A800 DVB-T USB2.0 + +1) It is working almost - work-in-progress. +2) No test reports received yet. + +0. History & News: + 2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework + 2005-04-02 - re-enabled and improved remote control code. + 2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb. + 2005-03-30 - first commit of the dvb-usb-module based on the dibusb-source. First device is a new driver for the + TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device. + + (change from dvb-dibusb to dvb-usb) + 2005-03-28 - added support for the AVerMedia AverTV DVB-T USB2.0 device (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia) + 2005-03-14 - added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 + 2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron + 2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2 + 2005-01-31 - distorted streaming is gone for USB1.1 devices + 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb + - first almost working version for HanfTek UMT-010 + - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010 + 2005-01-10 - refactoring completed, now everything is very delightful + - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a + Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich. + 2004-12-29 - after several days of struggling around bug of no returning URBs fixed. + 2004-12-26 - refactored the dibusb-driver, splitted into separate files + - i2c-probing enabled + 2004-12-06 - possibility for demod i2c-address probing + - new usb IDs (Compro, Artec) + 2004-11-23 - merged changes from DiB3000MC_ver2.1 + - revised the debugging + - possibility to deliver the complete TS for USB2.0 + 2004-11-21 - first working version of the dib3000mc/p frontend driver. + 2004-11-12 - added additional remote control keys. Thanks to Uwe Hanke. + 2004-11-07 - added remote control support. Thanks to David Matthews. + 2004-11-05 - added support for a new devices (Grandtec/Avermedia/Artec) + - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD + - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems + better settled there (added xfer_ops-struct) + - created a common files for frontends (mc/p/mb) + 2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek) + 2004-09-20 - added support for a new device (Compro DVB-U2000), thanks + to Amaury Demol for reporting + - changed usb TS transfer method (several urbs, stopping transfer + before setting a new pid) + 2004-09-13 - added support for a new device (Artec T1 USB TVBOX), thanks + to Christian Motschke for reporting + 2004-09-05 - released the dibusb device and dib3000mb-frontend driver + + (old news for vp7041.c) + 2004-07-15 - found out, by accident, that the device has a TUA6010XS for + PLL + 2004-07-12 - figured out, that the driver should also work with the + CTS Portable (Chinese Television System) + 2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working + properly with firmware extracted from 2.422 + - #if for 2.6.4 (dvb), compile issue + - changed firmware handling, see vp7041.txt sec 1.1 + 2004-07-02 - some tuner modifications, v0.1, cleanups, first public + 2004-06-28 - now using the dvb_dmx_swfilter_packets, everything + runs fine now + 2004-06-27 - able to watch and switching channels (pre-alpha) + - no section filtering yet + 2004-06-06 - first TS received, but kernel oops :/ + 2004-05-14 - firmware loader is working + 2004-05-11 - start writing the driver + +1. How to use? +1.1. Firmware + +Most of the USB drivers need to download a firmware to start working. + +for USB1.1 (AN2135) you need: dvb-usb-dibusb-5.0.0.11.fw +for USB2.0 HanfTek: dvb-usb-umt-010-02.fw +for USB2.0 DiBcom: dvb-usb-dibusb-6.0.0.8.fw +for USB2.0 AVerMedia AverTV DVB-T USB2: dvb-usb-avertv-a800-01.fw +for USB2.0 TwinhanDTV Alpha/MagicBox II: dvb-usb-vp7045-01.fw + +The files can be found on http://www.linuxtv.org/download/firmware/ . + +We do not have the permission (yet) to publish the following firmware-files. +You'll need to extract them from the windows drivers. + +You should be able to use "get_dvb_firmware dvb-usb" to get the firmware: + +for USB1.1 (AN2235) (a few Artec T1 devices): dvb-usb-dibusb-an2235-01.fw +for USB2.0 Hauppauge: dvb-usb-nova-t-usb2-01.fw +for USB2.0 ADSTech/Kworld USB2.0: dvb-usb-adstech-usb2-01.fw +for USB2.0 Yakumo/Typhoon/Hama: dvb-usb-dtt200u-01.fw + +1.2. Compiling + +Since the driver is in the linux kernel, activating the driver in +your favorite config-environment should sufficient. I recommend +to compile the driver as module. Hotplug does the rest. + +If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh +load' afterwards. + +1.3. Loading the drivers + +Hotplug is able to load the driver, when it is needed (because you plugged +in the device). + +If you want to enable debug output, you have to load the driver manually and +from withing the dvb-kernel cvs repository. + +first have a look, which debug level are available: + +modinfo dvb-usb +modinfo dvb-usb-vp7045 +etc. + +modprobe dvb-usb debug= +modprobe dvb-usb-vp7045 debug= +etc. + +should do the trick. + +When the driver is loaded successfully, the firmware file was in +the right place and the device is connected, the "Power"-LED should be +turned on. + +At this point you should be able to start a dvb-capable application. I'm use +(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the +long-term test scenario. + +2. Known problems and bugs + +- Don't remove the USB device while running an DVB application, your system + will go crazy or die most likely. + +2.1. Adding support for devices + +TODO + +2.2. USB1.1 Bandwidth limitation + +A lot of the currently supported devices are USB1.1 and thus they have a +maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub. +This is not enough for receiving the complete transport stream of a +DVB-T channel (which is about 16 MBit/s). Normally this is not a +problem, if you only want to watch TV (this does not apply for HDTV), +but watching a channel while recording another channel on the same +frequency simply does not work very well. This applies to all USB1.1 +DVB-T devices, not just the dvb-usb-devices) + +The bug, where the TS is distorted by a heavy usage of the device is gone +definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are +working like charm now with VDR. Sometimes I even was able to record a channel +and watch another one. + +2.3. Comments + +Patches, comments and suggestions are very very welcome. + +3. Acknowledgements + Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for + providing specs, code and help, on which the dvb-dibusb, dib3000mb and + dib3000mc are based. + + David Matthews for identifying a new device type (Artec T1 with AN2235) + and for extending dibusb with remote control event handling. Thank you. + + Alex Woods for frequently answering question about usb and dvb + stuff, a big thank you. + + Bernd Wagner for helping with huge bug reports and discussions. + + Gunnar Wittich and Joachim von Caron for their trust for providing + root-shells on their machines to implement support for new devices. + + Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei + Jung from AVerMedia who kindly provided a special firmware to get the device + up and running in Linux. + + Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by + writing the vp7045-driver. + + Some guys on the linux-dvb mailing list for encouraging me + + Peter Schildmann >peter.schildmann-nospam-at-web.de< for his + user-level firmware loader, which saves a lot of time + (when writing the vp7041 driver) + + Ulf Hermenau for helping me out with traditional chinese. + + André Smoktun and Christian Frömmel for supporting me with + hardware and listening to my problems very patient. diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index b81abdfde37..01387f883cd 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -27,6 +27,7 @@ source "drivers/media/dvb/ttpci/Kconfig" comment "Supported USB Adapters" depends on DVB_CORE && USB +source "drivers/media/dvb/dvb-usb/Kconfig" source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" source "drivers/media/dvb/cinergyT2/Kconfig" diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index d2dd914f777..3c6ff161910 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -2,4 +2,4 @@ # Makefile for the kernel multimedia device drivers. # -obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ +obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig new file mode 100644 index 00000000000..8aa32f6e447 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -0,0 +1,99 @@ +config DVB_USB + tristate "Support for various USB DVB devices" + depends on DVB_CORE && USB + select FW_LOADER + help + By enabling this you will be able to choose the various USB 1.1 and + USB2.0 DVB devices. + + Almost every USB device needs a firmware, please look into + + + Say Y if you own an USB DVB device. + +config DVB_USB_DEBUG + bool "Enable extended debug support for all DVB-USB devices" + depends on DVB_USB + help + Say Y if you want to enable debuging. See modinfo dvb-usb (and the + appropriate drivers) for debug levels. + +config DVB_USB_A800 + tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" + depends on DVB_USB + help + Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. + +config DVB_USB_DIBUSB_MB + tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" + depends on DVB_USB + help + Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by + DiBcom () equipped with a DiB3000M-B demodulator. + + Devices supported by this driver: + TwinhanDTV USB-Ter (VP7041) + TwinhanDTV Magic Box (VP7041e) + KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 + Hama DVB-T USB1.1-Box + DiBcom USB1.1 reference devices (non-public) + Ultima Electronic/Artec T1 USB TVBOX + Compro Videomate DVB-U2000 - DVB-T USB + Grandtec DVB-T USB + Avermedia AverTV DVBT USB1.1 + Artec T1 USB1.1 boxes + + The VP7041 seems to be identical to "CTS Portable" (Chinese + Television System). + + Say Y if you own such a device and want to use it. You should build it as + a module. + +config DVB_USB_DIBUSB_MC + tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" + depends on DVB_USB + help + Support for 2.0 DVB-T receivers based on reference designs made by + DiBcom () equipped with a DiB3000M-C/P demodulator. + + Devices supported by this driver: + DiBcom USB2.0 reference devices (non-public) + Artec T1 USB2.0 boxes + + Say Y if you own such a device and want to use it. You should build it as + a module. + +config DVB_USB_UMT_010 + tristate "HanfTek UMT-010 DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. + +config DVB_USB_DIGITV + tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. + +config DVB_USB_VP7045 + tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the + TwinhanDTV Alpha (stick) (VP-7045), + TwinhanDTV MagicBox II (VP-7046) and + DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers. + +config DVB_USB_NOVA_T_USB2 + tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. + +config DVB_USB_DTT200U + tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. + + The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile new file mode 100644 index 00000000000..d65b50f9abb --- /dev/null +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -0,0 +1,30 @@ +dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o +obj-$(CONFIG_DVB_USB) += dvb-usb.o + +dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o +obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o + +dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o +obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o + +dvb-usb-dibusb-common-objs = dibusb-common.o + +dvb-usb-a800-objs = a800.o +obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o + +dvb-usb-dibusb-mb-objs = dibusb-mb.o +obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o + +dvb-usb-dibusb-mc-objs = dibusb-mc.o +obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o + +dvb-usb-nova-t-usb2-objs = nova-t-usb2.o +obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o + +dvb-usb-umt-010-objs = umt-010.o +obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o + +dvb-usb-digitv-objs = digitv.o +obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o + +EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c new file mode 100644 index 00000000000..a3542935604 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -0,0 +1,176 @@ +/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T + * USB2.0 (A800) DVB-T receiver. + * + * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to + * - AVerMedia who kindly provided information and + * - Glen Harris who suffered from my mistakes during development. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dibusb.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS); +#define deb_rc(args...) dprintk(debug,0x01,args) + +static int a800_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + /* do nothing for the AVerMedia */ + return 0; +} + +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, 0x03, KEY_CHANNELUP }, /* CH UP */ + { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ + { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ + { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ + { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */ + { 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, 0x01, KEY_FIRST }, /* |<< / GREEN */ + { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */ + { 0x02, 0x04, KEY_EPG }, /* EPG */ + { 0x02, 0x15, KEY_MENU }, /* MENU */ +}; + +int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5]; + if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0), + 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5, + 2*HZ) != 5) + return -ENODEV; + + /* call the universal NEC remote processor, to find out the key's state and event */ + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties a800_properties; + +static int a800_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE); +} + +/* do not change the order of the ID table */ +static struct usb_device_id a800_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, a800_table); + +static struct dvb_usb_properties a800_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + + .usb_ctrl = CYPRESS_FX2, + + .firmware = "dvb-usb-avertv-a800-02.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = a800_power_ctrl, + .frontend_attach = dibusb_dib3000mc_frontend_attach, + .tuner_attach = dibusb_dib3000mc_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = a800_rc_keys, + .rc_key_map_size = ARRAY_SIZE(a800_rc_keys), + .rc_query = a800_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "AVerMedia AverTV DVB-T USB 2.0 (A800)", + { &a800_table[0], NULL }, + { &a800_table[1], NULL }, + }, + } +}; + +static struct usb_driver a800_driver = { + .owner = THIS_MODULE, + .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)", + .probe = a800_probe, + .disconnect = dvb_usb_device_exit, + .id_table = a800_table, +}; + +/* module stuff */ +static int __init a800_module_init(void) +{ + int result; + if ((result = usb_register(&a800_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit a800_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&a800_driver); +} + +module_init (a800_module_init); +module_exit (a800_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c new file mode 100644 index 00000000000..63b626f70c8 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -0,0 +1,272 @@ +/* Common methods for dibusb-based-receivers. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dibusb.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS); +MODULE_LICENSE("GPL"); + +#define deb_info(args...) dprintk(debug,0x01,args) + +/* common stuff used by the different dibusb modules */ +int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (d->priv != NULL) { + struct dib_fe_xfer_ops *ops = d->priv; + if (ops->fifo_ctrl != NULL) + if (ops->fifo_ctrl(d->fe,onoff)) { + err("error while controlling the fifo of the demod."); + return -ENODEV; + } + } + return 0; +} +EXPORT_SYMBOL(dibusb_streaming_ctrl); + +int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + if (d->priv != NULL) { + struct dib_fe_xfer_ops *ops = d->priv; + if (d->pid_filtering && ops->pid_ctrl != NULL) + ops->pid_ctrl(d->fe,index,pid,onoff); + } + return 0; +} +EXPORT_SYMBOL(dibusb_pid_filter); + +int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (d->priv != NULL) { + struct dib_fe_xfer_ops *ops = d->priv; + if (ops->pid_parse != NULL) + if (ops->pid_parse(d->fe,onoff) < 0) + err("could not handle pid_parser"); + } + return 0; +} +EXPORT_SYMBOL(dibusb_pid_filter_ctrl); + +int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b[3]; + int ret; + b[0] = DIBUSB_REQ_SET_IOCTL; + b[1] = DIBUSB_IOCTL_CMD_POWER_MODE; + b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP; + ret = dvb_usb_generic_write(d,b,3); + msleep(10); + return ret; +} +EXPORT_SYMBOL(dibusb_power_ctrl); + +int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b[2]; + b[0] = DIBUSB_REQ_SET_IOCTL; + b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; + + dvb_usb_generic_write(d,b,3); + + return dibusb_streaming_ctrl(d,onoff); +} +EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); + +int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (onoff) { + u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP }; + return dvb_usb_generic_write(d,b,3); + } else + return 0; +} +EXPORT_SYMBOL(dibusb2_0_power_ctrl); + +static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */ + /* write only ? */ + int wo = (rbuf == NULL || rlen == 0), + len = 2 + wlen + (wo ? 0 : 2); + + sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ; + sndbuf[1] = (addr << 1) | (wo ? 0 : 1); + + memcpy(&sndbuf[2],wbuf,wlen); + + if (!wo) { + sndbuf[wlen+2] = (rlen >> 8) & 0xff; + sndbuf[wlen+3] = rlen & 0xff; + } + + return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0); +} + +/* + * I2C master xfer function + */ +static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (down_interruptible(&d->i2c_sem) < 0) + return -EAGAIN; + + if (num > 2) + warn("more than 2 i2c messages at a time is not handled yet. TODO."); + + for (i = 0; i < num; i++) { + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, + msg[i+1].buf,msg[i+1].len) < 0) + break; + i++; + } else + if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) + break; + } + + up(&d->i2c_sem); + return i; +} + +static u32 dibusb_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +struct i2c_algorithm dibusb_i2c_algo = { + .name = "DiBcom USB I2C algorithm", + .id = I2C_ALGO_BIT, + .master_xfer = dibusb_i2c_xfer, + .functionality = dibusb_i2c_func, +}; +EXPORT_SYMBOL(dibusb_i2c_algo); + +int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) +{ + u8 wbuf[1] = { offs }; + return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1); +} +EXPORT_SYMBOL(dibusb_read_eeprom_byte); + +int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) +{ + struct dib3000_config demod_cfg; + struct dibusb_state *st = d->priv; + + demod_cfg.pll_set = dvb_usb_pll_set_i2c; + demod_cfg.pll_init = dvb_usb_pll_init_i2c; + + for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) + if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { + d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); + +int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) +{ + d->pll_addr = 0x60; + d->pll_desc = &dvb_pll_env57h1xd5; + return 0; +} +EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); + +/* + * common remote control stuff + */ +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. */ + /* 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 */ + /* 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 }, +}; +EXPORT_SYMBOL(dibusb_rc_keys); + +int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE; + dvb_usb_generic_rw(d,&cmd,1,key,5,0); + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} +EXPORT_SYMBOL(dibusb_rc_query); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c new file mode 100644 index 00000000000..fd103e4746e --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -0,0 +1,316 @@ +/* DVB USB compliant linux driver for mobile DVB-T USB devices based on + * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B) + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * based on GPL code from DiBcom, which has + * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dibusb.h" + +static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) +{ + struct dib3000_config demod_cfg; + struct dibusb_state *st = d->priv; + + demod_cfg.demod_address = 0x8; + demod_cfg.pll_set = dvb_usb_pll_set_i2c; + demod_cfg.pll_init = dvb_usb_pll_init_i2c; + + if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) + return -ENODEV; + + d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; + + return 0; +} + +/* some of the dibusb 1.1 device aren't equipped with the default tuner + * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures + * this out. */ +static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d) +{ + u8 b[2] = { 0,0 }, b2[1]; + int ret = 0; + struct i2c_msg msg[2] = { + { .flags = 0, .buf = b, .len = 2 }, + { .flags = I2C_M_RD, .buf = b2, .len = 1 }, + }; + + /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */ + msg[0].addr = msg[1].addr = 0x60; + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(d->fe,1,msg[0].addr); + + if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) { + err("tuner i2c write failed."); + ret = -EREMOTEIO; + } + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(d->fe,0,msg[0].addr); + + if (b2[0] == 0xfe) { + info("this device has the Thomson Cable onboard. Which is default."); + d->pll_addr = 0x61; + d->pll_desc = &dvb_pll_tua6010xs; + } else { + u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; + info("this device has the Panasonic ENV77H11D5 onboard."); + d->pll_addr = 0x60; + memcpy(d->pll_init,bpll,4); + d->pll_desc = &dvb_pll_tda665x; + } + + return ret; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties dibusb1_1_properties; +static struct dvb_usb_properties dibusb1_1_an2235_properties; +static struct dvb_usb_properties dibusb2_0b_properties; + +static int dibusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 || + dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) || + dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0) + return 0; + + return -EINVAL; +} + +/* do not change the order of the ID table */ +static struct usb_device_id dibusb_dib3000mb_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, +/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, +/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, +/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, +/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, +/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, +/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, +/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, +/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, +/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, +/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, +/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, +/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) }, +/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) }, +/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) }, +/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) }, +/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, +/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, +/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, +/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, +/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, +/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, +/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, +/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, +/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); + +static struct dvb_usb_properties dibusb1_1_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 16, + + .usb_ctrl = CYPRESS_AN2135, + + .firmware = "dvb-usb-dibusb-5.0.0.11.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb_power_ctrl, + .frontend_attach = dibusb_dib3000mb_frontend_attach, + .tuner_attach = dibusb_dib3000mb_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 8, + .devices = { + { "AVerMedia AverTV DVBT USB1.1", + { &dibusb_dib3000mb_table[0], NULL }, + { &dibusb_dib3000mb_table[1], NULL }, + }, + { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)", + { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL}, + { &dibusb_dib3000mb_table[3], NULL }, + }, + { "DiBcom USB1.1 DVB-T reference design (MOD3000)", + { &dibusb_dib3000mb_table[5], NULL }, + { &dibusb_dib3000mb_table[6], NULL }, + }, + { "KWorld V-Stream XPERT DTV - DVB-T USB1.1", + { &dibusb_dib3000mb_table[7], NULL }, + { &dibusb_dib3000mb_table[8], NULL }, + }, + { "Grandtec USB1.1 DVB-T", + { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL }, + { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL }, + }, + { "Unkown USB1.1 DVB-T device ???? please report the name to the author", + { &dibusb_dib3000mb_table[13], NULL }, + { &dibusb_dib3000mb_table[14], NULL }, + }, + { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device", + { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL}, + { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL}, + }, + { "Artec T1 USB1.1 TVBOX with AN2135", + { &dibusb_dib3000mb_table[19], NULL }, + { &dibusb_dib3000mb_table[20], NULL }, + }, + } +}; + +static struct dvb_usb_properties dibusb1_1_an2235_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = CYPRESS_AN2235, + + .firmware = "dvb-usb-dibusb-an2235-01.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb_power_ctrl, + .frontend_attach = dibusb_dib3000mb_frontend_attach, + .tuner_attach = dibusb_dib3000mb_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Artec T1 USB1.1 TVBOX with AN2235", + { &dibusb_dib3000mb_table[20], NULL }, + { &dibusb_dib3000mb_table[21], NULL }, + }, + } +}; + +static struct dvb_usb_properties dibusb2_0b_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = CYPRESS_FX2, + + .firmware = "dvb-usb-adstech-usb2-01.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb2_0_power_ctrl, + .frontend_attach = dibusb_dib3000mb_frontend_attach, + .tuner_attach = dibusb_dib3000mb_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { "KWorld/ADSTech Instant DVB-T USB 2.0", + { &dibusb_dib3000mb_table[23], NULL }, + { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */ + }, + } +}; + +static struct usb_driver dibusb_driver = { + .owner = THIS_MODULE, + .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)", + .probe = dibusb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dibusb_dib3000mb_table, +}; + +/* module stuff */ +static int __init dibusb_module_init(void) +{ + int result; + if ((result = usb_register(&dibusb_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit dibusb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dibusb_driver); +} + +module_init (dibusb_module_init); +module_exit (dibusb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c new file mode 100644 index 00000000000..aad8ed3fe00 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -0,0 +1,116 @@ +/* DVB USB compliant linux driver for mobile DVB-T USB devices based on + * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P) + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * based on GPL code from DiBcom, which has + * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dibusb.h" + +/* USB Driver stuff */ +static struct dvb_usb_properties dibusb_mc_properties; + +static int dibusb_mc_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE); +} + +/* do not change the order of the ID table */ +static struct usb_device_id dibusb_dib3000mc_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) }, +/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); + +static struct dvb_usb_properties dibusb_mc_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-dibusb-6.0.0.8.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb2_0_power_ctrl, + .frontend_attach = dibusb_dib3000mc_frontend_attach, + .tuner_attach = dibusb_dib3000mc_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* FIXME */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { "DiBcom USB2.0 DVB-T reference design (MOD3000P)", + { &dibusb_dib3000mc_table[0], NULL }, + { &dibusb_dib3000mc_table[1], NULL }, + }, + { "Artec T1 USB2.0 TVBOX (please report the warm ID)", + { &dibusb_dib3000mc_table[2], NULL }, + { NULL }, + }, + } +}; + +static struct usb_driver dibusb_mc_driver = { + .owner = THIS_MODULE, + .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices", + .probe = dibusb_mc_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dibusb_dib3000mc_table, +}; + +/* module stuff */ +static int __init dibusb_mc_module_init(void) +{ + int result; + if ((result = usb_register(&dibusb_mc_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit dibusb_mc_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dibusb_mc_driver); +} + +module_init (dibusb_mc_module_init); +module_exit (dibusb_mc_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h new file mode 100644 index 00000000000..6611f62977c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb.h @@ -0,0 +1,122 @@ +/* Header file for all dibusb-based-receivers. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#ifndef _DVB_USB_DIBUSB_H_ +#define _DVB_USB_DIBUSB_H_ + +#define DVB_USB_LOG_PREFIX "dibusb" +#include "dvb-usb.h" + +#include "dib3000.h" + +/* + * protocol of all dibusb related devices + */ + +/* + * bulk msg to/from endpoint 0x01 + * + * general structure: + * request_byte parameter_bytes + */ + +#define DIBUSB_REQ_START_READ 0x00 +#define DIBUSB_REQ_START_DEMOD 0x01 + +/* + * i2c read + * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word + * bulk read: byte_buffer (length_word bytes) + */ +#define DIBUSB_REQ_I2C_READ 0x02 + +/* + * i2c write + * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes + */ +#define DIBUSB_REQ_I2C_WRITE 0x03 + +/* + * polling the value of the remote control + * bulk write: 0x04 + * bulk read: byte_buffer (5 bytes) + */ +#define DIBUSB_REQ_POLL_REMOTE 0x04 + +/* additional status values for Hauppauge Remote Control Protocol */ +#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01 +#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03 + +/* streaming mode: + * bulk write: 0x05 mode_byte + * + * mode_byte is mostly 0x00 + */ +#define DIBUSB_REQ_SET_STREAMING_MODE 0x05 + +/* interrupt the internal read loop, when blocking */ +#define DIBUSB_REQ_INTR_READ 0x06 + +/* io control + * 0x07 cmd_byte param_bytes + * + * param_bytes can be up to 32 bytes + * + * cmd_byte function parameter name + * 0x00 power mode + * 0x00 sleep + * 0x01 wakeup + * + * 0x01 enable streaming + * 0x02 disable streaming + * + * + */ +#define DIBUSB_REQ_SET_IOCTL 0x07 + +/* IOCTL commands */ + +/* change the power mode in firmware */ +#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00 +#define DIBUSB_IOCTL_POWER_SLEEP 0x00 +#define DIBUSB_IOCTL_POWER_WAKEUP 0x01 + +/* modify streaming of the FX2 */ +#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01 +#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02 + +struct dibusb_state { + struct dib_fe_xfer_ops ops; + + /* for RC5 remote control */ + int old_toggle; + int last_repeat_count; +}; + +extern struct i2c_algorithm dibusb_i2c_algo; + +extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *); +extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *); + +extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int); +extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int); +extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int); +extern int dibusb_power_ctrl(struct dvb_usb_device *, int); +extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int); +extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int); + +#define DEFAULT_RC_INTERVAL 150 +//#define DEFAULT_RC_INTERVAL 100000 + +extern struct dvb_usb_rc_key dibusb_rc_keys[]; +extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *); +extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *); + +#endif diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c new file mode 100644 index 00000000000..5acf3fde952 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -0,0 +1,282 @@ +/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0 + * receiver + * + * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and + * Allan Third (allan.third@cs.man.ac.uk) + * + * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "digitv.h" + +#include "mt352.h" +#include "nxt6000.h" + +/* debug */ +int dvb_usb_digitv_debug; +module_param_named(debug,dvb_usb_digitv_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +static int digitv_ctrl_msg(struct dvb_usb_device *d, + u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen) +{ + int wo = (rbuf == NULL || rlen == 0); /* write-only */ + u8 sndbuf[7],rcvbuf[7]; + memset(sndbuf,0,7); memset(rcvbuf,0,7); + + sndbuf[0] = cmd; + sndbuf[1] = vv; + sndbuf[2] = wo ? wlen : rlen; + + if (!wo) { + memcpy(&sndbuf[3],wbuf,wlen); + dvb_usb_generic_write(d,sndbuf,7); + } else { + dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10); + memcpy(&rbuf,&rcvbuf[3],rlen); + } + return 0; +} + +/* I2C */ +static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (down_interruptible(&d->i2c_sem) < 0) + return -EAGAIN; + + if (num > 2) + warn("more than 2 i2c messages at a time is not handled yet. TODO."); + + for (i = 0; i < num; i++) { + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0, + msg[i+1].buf,msg[i+1].len) < 0) + break; + i++; + } else + if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0], + &msg[i].buf[1],msg[i].len-1,NULL,0) < 0) + break; + } + + up(&d->i2c_sem); + return i; +} + +static u32 digitv_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm digitv_i2c_algo = { + .name = "Nebula DigiTV USB I2C algorithm", + .id = I2C_ALGO_BIT, + .master_xfer = digitv_i2c_xfer, + .functionality = digitv_i2c_func, +}; + +/* Callbacks for DVB USB */ +static int digitv_identify_state (struct usb_device *udev, struct + dvb_usb_properties *props, struct dvb_usb_device_description **desc, + int *cold) +{ + *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0; + return 0; +} + +static int digitv_mt352_demod_init(struct dvb_frontend *fe) +{ + static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d }; + static u8 mt352_reset[] = { 0x50, 0x80 }; + static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; + + static u8 mt352_agc_cfg[] = { 0x68, 0xa0 }; + static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 }; + static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; + static u8 mt352_agc_target[] = { 0x67, 0x20 }; + + static u8 mt352_rs_err_per[] = { 0x7c, 0x00, 0x01 }; + static u8 mt352_snr_select[] = { 0x79, 0x00, 0x20 }; + + static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x05 }; + + static u8 mt352_scan_ctl[] = { 0x88, 0x0f }; + static u8 mt352_capt_range[] = { 0x75, 0x32 }; + + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); + mt352_write(fe, mt352_reset, sizeof(mt352_reset)); + msleep(1); + mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); + + mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); + mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); + mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); + mt352_write(fe, mt352_agc_target, sizeof(mt352_agc_target)); + + + mt352_write(fe, mt352_rs_err_per, sizeof(mt352_rs_err_per)); + mt352_write(fe, mt352_snr_select, sizeof(mt352_snr_select)); + + mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); + + mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl)); + mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range)); + + return 0; +} + +static struct mt352_config digitv_mt352_config = { + .demod_address = 0x0, /* ignored by the digitv anyway */ + .demod_init = digitv_mt352_demod_init, + .pll_set = NULL, /* TODO */ +}; + +static struct nxt6000_config digitv_nxt6000_config = { + .demod_address = 0x0, /* ignored by the digitv anyway */ + .clock_inversion = 0x0, + + .pll_init = NULL, + .pll_set = NULL, +}; + +static int digitv_frontend_attach(struct dvb_usb_device *d) +{ + if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL) + return 0; + if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) { + + warn("nxt6000 support is not done yet, in fact you are one of the first " + "person who wants to use this device in Linux. Please report to " + "linux-dvb@linuxtv.org"); + + return 0; + } + return -EIO; +} + +static struct dvb_usb_rc_key digitv_rc_keys[] = { + { 0x00, 0x16, KEY_POWER }, /* dummy key */ +}; + +/* TODO is it really the NEC protocol ? */ +int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5]; + + digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4); + /* TODO state, maybe it is VV ? */ + if (key[1] != 0) + key[0] = 0x01; /* if something is inside the buffer, simulate key press */ + + /* call the universal NEC remote processor, to find out the key's state and event */ + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} + + +/* DVB USB Driver stuff */ +static struct dvb_usb_properties digitv_properties; + +static int digitv_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE); +} + +static struct usb_device_id digitv_table [] = { + { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, digitv_table); + +static struct dvb_usb_properties digitv_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-digitv-01.fw", + + .size_of_priv = 0, + + .streaming_ctrl = NULL, + .pid_filter = NULL, + .pid_filter_ctrl = NULL, + .power_ctrl = NULL, + .frontend_attach = digitv_frontend_attach, + .tuner_attach = NULL, // digitv_tuner_attach, + .read_mac_address = NULL, + + .rc_interval = 1000, + .rc_key_map = digitv_rc_keys, + .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys), + .rc_query = digitv_rc_query, + + .identify_state = digitv_identify_state, + + .i2c_algo = &digitv_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { "Nebula Electronics uDigiTV DVB-T USB2.0)", + { &digitv_table[0], NULL }, + { NULL }, + }, + } +}; + +static struct usb_driver digitv_driver = { + .owner = THIS_MODULE, + .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device", + .probe = digitv_probe, + .disconnect = dvb_usb_device_exit, + .id_table = digitv_table, +}; + +/* module stuff */ +static int __init digitv_module_init(void) +{ + int result; + if ((result = usb_register(&digitv_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit digitv_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&digitv_driver); +} + +module_init (digitv_module_init); +module_exit (digitv_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0"); +MODULE_VERSION("1.0-alpha"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h new file mode 100644 index 00000000000..477ee428a70 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/digitv.h @@ -0,0 +1,65 @@ +#ifndef _DVB_USB_DIGITV_H_ +#define _DVB_USB_DIGITV_H_ + +#define DVB_USB_LOG_PREFIX "digitv" +#include "dvb-usb.h" + +extern int dvb_usb_digitv_debug; +#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) + +/* protocol (from usblogging and the SDK: + * + * Always 7 bytes bulk message(s) for controlling + * + * First byte describes the command. Reads are 2 consecutive transfer (as always). + * + * General structure: + * + * write or first message of a read: + * VV B0 B1 B2 B3 + * + * second message of a read + * VV R0 R1 R2 R3 + * + * whereas 0 < len <= 4 + * + * I2C address is stored somewhere inside the device. + * + * 0x01 read from EEPROM + * VV = offset; B* = 0; R* = value(s) + * + * 0x02 read register of the COFDM + * VV = register; B* = 0; R* = value(s) + * + * 0x05 write register of the COFDM + * VV = register; B* = value(s); + * + * 0x06 write to the tuner (only for NXT6000) + * VV = 0; B* = PLL data; len = 4; + * + * 0x03 read remote control + * VV = 0; B* = 0; len = 4; R* = key + * + * 0x07 write to the remote (don't know why one should this, resetting ?) + * VV = 0; B* = key; len = 4; + * + * 0x08 write remote type + * VV = 0; B[0] = 0x01, len = 4 + * + * 0x09 write device init + * TODO + */ +#define USB_READ_EEPROM 1 + +#define USB_READ_COFDM 2 +#define USB_WRITE_COFDM 5 + +#define USB_WRITE_TUNER 6 + +#define USB_READ_REMOTE 3 +#define USB_WRITE_REMOTE 7 +#define USB_WRITE_REMOTE_TYPE 8 + +#define USB_DEV_INIT 9 + +#endif diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c new file mode 100644 index 00000000000..d17d768038c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -0,0 +1,206 @@ +/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T + * USB2.0 receiver. + * + * Copyright (C) 2005 Patrick Boettcher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dtt200u.h" + +struct dtt200u_fe_state { + struct dvb_usb_device *d; + + struct dvb_frontend_parameters fep; + struct dvb_frontend frontend; +}; + +#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what) + +static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_TUNE_STAT; + u8 br[3] = { 0 }; +// u8 bdeb[5] = { 0 }; + + dvb_usb_generic_rw(state->d,&bw,1,br,3,0); + switch (br[0]) { + case 0x01: + *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + break; + case 0x00: + *stat = 0; + break; + default: + moan("br[0]",GET_TUNE_STAT); + break; + } + +// bw[0] = 0x88; +// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0); + +// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]); + + return 0; +} +static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_BER; + *ber = 0; + dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0); + return 0; +} + +static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_UNK; + *unc = 0; + dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0); + return 0; +} + +static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_SIG_STRENGTH, b; + dvb_usb_generic_rw(state->d,&bw,1,&b,1,0); + *strength = (b << 8) | b; + return 0; +} + +static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_SNR,br; + dvb_usb_generic_rw(state->d,&bw,1,&br,1,0); + *snr = ~((br << 8) | br); + return 0; +} + +static int dtt200u_fe_init(struct dvb_frontend* fe) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 b = RESET_DEMOD; + return dvb_usb_generic_write(state->d,&b,1); +} + +static int dtt200u_fe_sleep(struct dvb_frontend* fe) +{ + return dtt200u_fe_init(fe); +} + +static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1500; + tune->step_size = 166667; + tune->max_drift = 166667 * 2; + return 0; +} + +static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u16 freq = fep->frequency / 250000; + u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 }; + + switch (fep->u.ofdm.bandwidth) { + case BANDWIDTH_8_MHZ: bw = 8; break; + case BANDWIDTH_7_MHZ: bw = 7; break; + case BANDWIDTH_6_MHZ: bw = 6; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: + return -EINVAL; + } + deb_info("set_frontend\n"); + + bwbuf[1] = bw; + dvb_usb_generic_write(state->d,bwbuf,2); + + freqbuf[1] = freq & 0xff; + freqbuf[2] = (freq >> 8) & 0xff; + dvb_usb_generic_write(state->d,freqbuf,3); + + memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters)); + + return 0; +} + +static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters)); + return 0; +} + +static void dtt200u_fe_release(struct dvb_frontend* fe) +{ + struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops dtt200u_fe_ops; + +struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) +{ + struct dtt200u_fe_state* state = NULL; + + /* allocate memory for the internal state */ + state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL); + if (state == NULL) + goto error; + memset(state,0,sizeof(struct dtt200u_fe_state)); + + deb_info("attaching frontend dtt200u\n"); + + state->d = d; + + state->frontend.ops = &dtt200u_fe_ops; + state->frontend.demodulator_priv = state; + + goto success; +error: + return NULL; +success: + return &state->frontend; +} + +static struct dvb_frontend_ops dtt200u_fe_ops = { + .info = { + .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 250000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = dtt200u_fe_release, + + .init = dtt200u_fe_init, + .sleep = dtt200u_fe_sleep, + + .set_frontend = dtt200u_fe_set_frontend, + .get_frontend = dtt200u_fe_get_frontend, + .get_tune_settings = dtt200u_fe_get_tune_settings, + + .read_status = dtt200u_fe_read_status, + .read_ber = dtt200u_fe_read_ber, + .read_signal_strength = dtt200u_fe_read_signal_strength, + .read_snr = dtt200u_fe_read_snr, + .read_ucblocks = dtt200u_fe_read_unc_blocks, +}; diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c new file mode 100644 index 00000000000..fb2b5a2da13 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -0,0 +1,171 @@ +/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T + * USB2.0 receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dtt200u.h" + +/* debug */ +int dvb_usb_dtt200u_debug; +module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); + +static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b_streaming[2] = { SET_TS_CTRL, onoff }; + u8 b_rst_pid = RESET_PID_FILTER; + + dvb_usb_generic_write(d,b_streaming,2); + + if (!onoff) + dvb_usb_generic_write(d,&b_rst_pid,1); + return 0; +} + +static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + u8 b_pid[4]; + pid = onoff ? pid : 0; + + b_pid[0] = SET_PID_FILTER; + b_pid[1] = index; + b_pid[2] = pid & 0xff; + b_pid[3] = (pid >> 8) & 0xff; + + return dvb_usb_generic_write(d,b_pid,4); +} + +/* 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 }, + { 0x00, 0x0c, KEY_ZOOM }, + { 0x80, 0x0d, KEY_0 }, + { 0x00, 0x0e, KEY_SELECT }, + { 0x80, 0x12, KEY_POWER }, + { 0x80, 0x1a, KEY_CHANNELUP }, + { 0x80, 0x1b, KEY_8 }, + { 0x80, 0x1e, KEY_VOLUMEUP }, + { 0x80, 0x1f, KEY_9 }, +}; + +static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd = GET_RC_KEY; + dvb_usb_generic_rw(d,&cmd,1,key,5,0); + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} + +static int dtt200u_frontend_attach(struct dvb_usb_device *d) +{ + d->fe = dtt200u_fe_attach(d); + return 0; +} + +static struct dvb_usb_properties dtt200u_properties; + +static int dtt200u_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE); +} + +static struct usb_device_id dtt200u_usb_table [] = { + { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) }, + { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) }, + { 0 }, +}; +MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); + +static struct dvb_usb_properties dtt200u_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 255, /* It is a guess, but there are at least 10 */ + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-dtt200u-01.fw", + + .streaming_ctrl = dtt200u_streaming_ctrl, + .pid_filter = dtt200u_pid_filter, + .frontend_attach = dtt200u_frontend_attach, + + .rc_interval = 200, + .rc_key_map = dtt200u_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), + .rc_query = dtt200u_rc_query, + + .generic_bulk_ctrl_endpoint = 0x01, + + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)", + .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] }, + .warm_ids = { &dtt200u_usb_table[1], NULL }, + }, + { 0 }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver dtt200u_usb_driver = { + .owner = THIS_MODULE, + .name = "Yakumo/Hama/Typhoon DVB-T USB2.0", + .probe = dtt200u_usb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dtt200u_usb_table, +}; + +/* module stuff */ +static int __init dtt200u_usb_module_init(void) +{ + int result; + if ((result = usb_register(&dtt200u_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit dtt200u_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dtt200u_usb_driver); +} + +module_init(dtt200u_usb_module_init); +module_exit(dtt200u_usb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h new file mode 100644 index 00000000000..ed414207151 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dtt200u.h @@ -0,0 +1,66 @@ +/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T + * USB2.0 receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#ifndef _DVB_USB_DTT200U_H_ +#define _DVB_USB_DTT200U_H_ + +#define DVB_USB_LOG_PREFIX "dtt200u" +#include "dvb-usb.h" + +extern int dvb_usb_dtt200u_debug; +#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args) + +/* guessed protocol description (reverse engineered): + * read + * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1 + * 81 - + * 82 - crash - do not touch + * 83 - crash - do not touch + * 84 - remote control + * 85 - crash - do not touch (OK, stop testing here) + * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) + * 89 - noise-to-signal + * 8a - unkown 1 byte - signal_strength + * 8c - ber ??? + * 8d - ber + * 8e - unc + */ + +#define GET_SPEED 0x00 +#define GET_TUNE_STAT 0x81 +#define GET_RC_KEY 0x84 +#define GET_STATUS 0x88 +#define GET_SNR 0x89 +#define GET_SIG_STRENGTH 0x8a +#define GET_UNK 0x8c +#define GET_BER 0x8d +#define GET_UNC 0x8e + +/* write + * 01 - reset the demod + * 02 - frequency (divided by 250000) + * 03 - bandwidth + * 04 - pid table (index pid(7:0) pid(12:8)) + * 05 - reset the pid table + * 08 - demod transfer enabled or not (FX2 transfer is enabled by default) + */ + +#define RESET_DEMOD 0x01 +#define SET_FREQUENCY 0x02 +#define SET_BANDWIDTH 0x03 +#define SET_PID_FILTER 0x04 +#define RESET_PID_FILTER 0x05 +#define SET_TS_CTRL 0x08 + +extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h new file mode 100644 index 00000000000..67e0d73fbce --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h @@ -0,0 +1,44 @@ +/* dvb-usb-common.h is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * a header file containing prototypes and types for internal use of the dvb-usb-lib + */ +#ifndef _DVB_USB_COMMON_H_ +#define _DVB_USB_COMMON_H_ + +#define DVB_USB_LOG_PREFIX "dvb-usb" +#include "dvb-usb.h" + +extern int dvb_usb_debug; + +#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args) +#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args) +#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args) +#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args) +#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args) +#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args) + +/* commonly used methods */ +extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); + +extern int dvb_usb_urb_submit(struct dvb_usb_device *); +extern int dvb_usb_urb_kill(struct dvb_usb_device *); +extern int dvb_usb_urb_init(struct dvb_usb_device *); +extern int dvb_usb_urb_exit(struct dvb_usb_device *); + +extern int dvb_usb_i2c_init(struct dvb_usb_device *); +extern int dvb_usb_i2c_exit(struct dvb_usb_device *); + +extern int dvb_usb_dvb_init(struct dvb_usb_device *); +extern int dvb_usb_dvb_exit(struct dvb_usb_device *); + +extern int dvb_usb_fe_init(struct dvb_usb_device *); +extern int dvb_usb_fe_exit(struct dvb_usb_device *); + +extern int dvb_usb_remote_init(struct dvb_usb_device *); +extern int dvb_usb_remote_exit(struct dvb_usb_device *); + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c new file mode 100644 index 00000000000..bdd72f77970 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -0,0 +1,210 @@ +/* dvb-usb-dvb.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for initializing and handling the + * linux-dvb API. + */ +#include "dvb-usb-common.h" + +static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) +{ + struct dvb_usb_device *d = dvbdmxfeed->demux->priv; + int newfeedcount,ret; + + if (d == NULL) + return -ENODEV; + + newfeedcount = d->feedcount + (onoff ? 1 : -1); + + /* + * stop feed before setting a new pid if there will be no pid anymore + */ + if (newfeedcount == 0) { + deb_ts("stop feeding\n"); + + if (d->props.streaming_ctrl != NULL) + if ((ret = d->props.streaming_ctrl(d,0))) + err("error while stopping stream."); + + dvb_usb_urb_kill(d); + } + + d->feedcount = newfeedcount; + + /* activate the pid on the device specific pid_filter */ + deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off"); + if (d->props.caps & DVB_USB_HAS_PID_FILTER && + d->pid_filtering && + d->props.pid_filter != NULL) + d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); + + /* start the feed if this was the first feed and there is still a feed + * for reception. + */ + if (d->feedcount == onoff && d->feedcount > 0) { + + deb_ts("controlling pid parser\n"); + if (d->props.caps & DVB_USB_HAS_PID_FILTER && + d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF && + d->props.pid_filter_ctrl != NULL) + if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0) + err("could not handle pid_parser"); + + deb_ts("start feeding\n"); + if (d->props.streaming_ctrl != NULL) + if (d->props.streaming_ctrl(d,1)) { + err("error while enabling fifo."); + return -ENODEV; + } + + dvb_usb_urb_submit(d); + } + return 0; +} + +static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type); + return dvb_usb_ctrl_feed(dvbdmxfeed,1); +} + +static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type); + return dvb_usb_ctrl_feed(dvbdmxfeed,0); +} + +int dvb_usb_dvb_init(struct dvb_usb_device *d) +{ + int ret; + + if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, + d->owner)) < 0) { + deb_info("dvb_register_adapter failed: error %d", ret); + goto err; + } + d->dvb_adap.priv = d; + + if (d->props.read_mac_address) { + if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0) + info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0], + d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2], + d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4], + d->dvb_adap.proposed_mac[5]); + else + err("MAC address reading failed."); + } + + + d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; + d->demux.priv = d; + + d->demux.feednum = d->demux.filternum = d->max_feed_count; + d->demux.start_feed = dvb_usb_start_feed; + d->demux.stop_feed = dvb_usb_stop_feed; + d->demux.write_to_decoder = NULL; + if ((ret = dvb_dmx_init(&d->demux)) < 0) { + err("dvb_dmx_init failed: error %d",ret); + goto err_dmx; + } + + d->dmxdev.filternum = d->demux.filternum; + d->dmxdev.demux = &d->demux.dmx; + d->dmxdev.capabilities = 0; + if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) { + err("dvb_dmxdev_init failed: error %d",ret); + goto err_dmx_dev; + } + + dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); + + goto success; +err_dmx_dev: + dvb_dmx_release(&d->demux); +err_dmx: + dvb_unregister_adapter(&d->dvb_adap); +err: + return ret; +success: + d->state |= DVB_USB_STATE_DVB; + return 0; +} + +int dvb_usb_dvb_exit(struct dvb_usb_device *d) +{ + if (d->state & DVB_USB_STATE_DVB) { + deb_info("unregistering DVB part\n"); + dvb_net_release(&d->dvb_net); + d->demux.dmx.close(&d->demux.dmx); + dvb_dmxdev_release(&d->dmxdev); + dvb_dmx_release(&d->demux); + dvb_unregister_adapter(&d->dvb_adap); + d->state &= ~DVB_USB_STATE_DVB; + } + return 0; +} + +static int dvb_usb_fe_wakeup(struct dvb_frontend *fe) +{ + struct dvb_usb_device *d = fe->dvb->priv; + + if (d->props.power_ctrl) + d->props.power_ctrl(d,1); + + if (d->fe_init) + d->fe_init(fe); + + return 0; +} + +static int dvb_usb_fe_sleep(struct dvb_frontend *fe) +{ + struct dvb_usb_device *d = fe->dvb->priv; + + if (d->fe_sleep) + d->fe_sleep(fe); + + if (d->props.power_ctrl) + d->props.power_ctrl(d,0); + + return 0; +} + +int dvb_usb_fe_init(struct dvb_usb_device* d) +{ + if (d->props.frontend_attach == NULL) { + err("strange '%s' don't want to attach a frontend.",d->desc->name); + return 0; + } + + d->props.frontend_attach(d); + + /* re-assign sleep and wakeup functions */ + if (d->fe != NULL) { + d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup; + d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep; + + if (dvb_register_frontend(&d->dvb_adap, d->fe)) { + err("Frontend registration failed."); + if (d->fe->ops->release) + d->fe->ops->release(d->fe); + d->fe = NULL; + return -ENODEV; + } + } else + err("no frontend was attached by '%s'",d->desc->name); + + if (d->props.tuner_attach != NULL) + d->props.tuner_attach(d); + + return 0; +} + +int dvb_usb_fe_exit(struct dvb_usb_device *d) +{ + if (d->fe != NULL) + dvb_unregister_frontend(d->fe); + return 0; +} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c new file mode 100644 index 00000000000..5244e39770a --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c @@ -0,0 +1,100 @@ +/* dvb-usb-firmware.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices. + * + * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem. + */ +#include "dvb-usb-common.h" + +#include +#include + +struct usb_cypress_controller { + int id; + const char *name; /* name of the usb controller */ + u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */ +}; + +static struct usb_cypress_controller cypress[] = { + { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, + { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, + { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, +}; + +/* + * load a firmware packet to the device + */ +static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) +{ + return usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); +} + +int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type) +{ + const struct firmware *fw = NULL; + u16 addr; + u8 *b,*p; + int ret = 0,i; + + if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) { + err("did not find the firmware file. (%s) " + "Please see linux/Documentation/dvb/ for more details on firmware-problems.", + filename); + return ret; + } + + info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name); + + p = kmalloc(fw->size,GFP_KERNEL); + if (p != NULL) { + u8 reset; + /* + * you cannot use the fw->data as buffer for + * usb_control_msg, a new buffer has to be + * created + */ + memcpy(p,fw->data,fw->size); + + /* stop the CPU */ + reset = 1; + if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) + err("could not stop the USB controller CPU."); + for(i = 0; p[i+3] == 0 && i < fw->size; ) { + b = (u8 *) &p[i]; + addr = cpu_to_le16( *((u16 *) &b[1]) ); + + deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]); + + ret = usb_cypress_writemem(udev,addr,&b[4],b[0]); + + if (ret != b[0]) { + err("error while transferring firmware " + "(transferred size: %d, block size: %d)", + ret,b[0]); + ret = -EINVAL; + break; + } + i += 5 + b[0]; + } + /* length in ret */ + if (ret > 0) + ret = 0; + /* restart the CPU */ + reset = 0; + if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + + kfree(p); + } else { + ret = -ENOMEM; + } + release_firmware(fw); + + return ret; +} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c new file mode 100644 index 00000000000..9f0a8d90d14 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -0,0 +1,118 @@ +/* dvb-usb-i2c.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for (de-)initializing an I2C adapter. + */ +#include "dvb-usb-common.h" + +int dvb_usb_i2c_init(struct dvb_usb_device *d) +{ + int ret = 0; + + if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER)) + return 0; + + if (d->props.i2c_algo == NULL) { + err("no i2c algorithm specified"); + return -EINVAL; + } + + strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE); +#ifdef I2C_ADAP_CLASS_TV_DIGITAL + d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, +#else + d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, +#endif + d->i2c_adap.algo = d->props.i2c_algo; + d->i2c_adap.algo_data = NULL; + d->i2c_adap.id = I2C_ALGO_BIT; + + i2c_set_adapdata(&d->i2c_adap, d); + + if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0) + err("could not add i2c adapter"); + + d->state |= DVB_USB_STATE_I2C; + + return ret; +} + +int dvb_usb_i2c_exit(struct dvb_usb_device *d) +{ + if (d->state & DVB_USB_STATE_I2C) + i2c_del_adapter(&d->i2c_adap); + d->state &= ~DVB_USB_STATE_I2C; + return 0; +} + +int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) +{ + struct dvb_usb_device *d = fe->dvb->priv; + struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; + int ret = 0; + + /* if there is nothing to initialize */ + if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 && + d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00) + return 0; + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,1,d->pll_addr); + + deb_pll("pll init: %x\n",d->pll_addr); + deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], + d->pll_init[2],d->pll_init[3]); + + if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { + err("tuner i2c write failed for pll_init."); + ret = -EREMOTEIO; + } + msleep(1); + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,0,d->pll_addr); + return ret; +} +EXPORT_SYMBOL(dvb_usb_pll_init_i2c); + +int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5]) +{ + struct dvb_usb_device *d = fe->dvb->priv; + + deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); + + b[0] = d->pll_addr << 1; + dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); + + deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); + + return 0; +} +EXPORT_SYMBOL(dvb_usb_pll_set); + +int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_device *d = fe->dvb->priv; + int ret = 0; + u8 b[5]; + struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; + + dvb_usb_pll_set(fe,fep,b); + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,1,d->pll_addr); + + if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { + err("tuner i2c write failed for pll_set."); + ret = -EREMOTEIO; + } + msleep(1); + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,0,d->pll_addr); + + return ret; +} +EXPORT_SYMBOL(dvb_usb_pll_set_i2c); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h new file mode 100644 index 00000000000..bcb34191868 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -0,0 +1,83 @@ +/* dvb-usb-ids.h is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see + * dvb-usb-init.c for copyright information. + * + * a header file containing define's for the USB device supported by the + * various drivers. + */ +#ifndef _DVB_USB_IDS_H_ +#define _DVB_USB_IDS_H_ + +/* Vendor IDs */ +#define USB_VID_ADSTECH 0x06e1 +#define USB_VID_ANCHOR 0x0547 +#define USB_VID_AVERMEDIA_UNK 0x14aa +#define USB_VID_AVERMEDIA 0x07ca +#define USB_VID_COMPRO 0x185b +#define USB_VID_COMPRO_UNK 0x145f +#define USB_VID_CYPRESS 0x04b4 +#define USB_VID_DIBCOM 0x10b8 +#define USB_VID_DVICO 0x0fe9 +#define USB_VID_EMPIA 0xeb1a +#define USB_VID_GRANDTEC 0x5032 +#define USB_VID_HANFTEK 0x15f4 +#define USB_VID_HAUPPAUGE 0x2040 +#define USB_VID_HYPER_PALTEK 0x1025 +#define USB_VID_VISIONPLUS 0x13d3 +#define USB_VID_TWINHAN 0x1822 +#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 + +/* Product IDs */ +#define USB_PID_ADSTECH_USB2_COLD 0xa333 +#define USB_PID_ADSTECH_USB2_WARM 0xa334 +#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 +#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 +#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 +#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801 +#define USB_PID_COMPRO_DVBU2000_COLD 0xd000 +#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 +#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c +#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d +#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 +#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 +#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 +#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 +#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 +#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 +#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 +#define USB_PID_KWORLD_VSTREAM_COLD 0x17de +#define USB_PID_KWORLD_VSTREAM_WARM 0x17df +#define USB_PID_TWINHAN_VP7041_COLD 0x3201 +#define USB_PID_TWINHAN_VP7041_WARM 0x3202 +#define USB_PID_TWINHAN_VP7045_COLD 0x3205 +#define USB_PID_TWINHAN_VP7045_WARM 0x3206 +#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 +#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 +#define USB_PID_TWINHAN_VP7021_COLD 0x3207 +#define USB_PID_TWINHAN_VP7021_WARM 0x3208 +#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 +#define USB_PID_ULTIMA_TVBOX_WARM 0x8106 +#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 +#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 +#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 +#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 +#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 +#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 +#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e +#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f +#define USB_PID_HANFTEK_UMT_010_COLD 0x0001 +#define USB_PID_HANFTEK_UMT_010_WARM 0x0015 +#define USB_PID_DTT200U_COLD 0x0201 +#define USB_PID_DTT200U_WARM 0x0301 +#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 +#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 +#define USB_PID_NEBULA_DIGITV 0x0201 +#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00 +#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10 +#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 +#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 +#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 + + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c new file mode 100644 index 00000000000..3aadec974cf --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -0,0 +1,211 @@ +/* + * DVB USB library - provides a generic interface for a DVB USB device driver. + * + * dvb-usb-init.c + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dvb-usb-common.h" + +/* debug */ +int dvb_usb_debug; +module_param_named(debug,dvb_usb_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS); + +/* general initialization functions */ +int dvb_usb_exit(struct dvb_usb_device *d) +{ + deb_info("state before exiting everything: %x\n",d->state); + dvb_usb_remote_exit(d); + dvb_usb_fe_exit(d); + dvb_usb_i2c_exit(d); + dvb_usb_dvb_exit(d); + dvb_usb_urb_exit(d); + deb_info("state should be zero now: %x\n",d->state); + d->state = DVB_USB_STATE_INIT; + kfree(d->priv); + kfree(d); + return 0; +} + +static int dvb_usb_init(struct dvb_usb_device *d) +{ + int ret = 0; + + sema_init(&d->usb_sem, 1); + sema_init(&d->i2c_sem, 1); + + d->state = DVB_USB_STATE_INIT; + +/* check the capabilites and set appropriate variables */ + +/* speed - when running at FULL speed we need a HW PID filter */ + if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { + err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a HW PID filter)"); + return -ENODEV; + } + + if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) || + (d->props.caps & DVB_USB_NEED_PID_FILTERING)) { + info("will use the device's hw PID filter."); + d->pid_filtering = 1; + d->max_feed_count = d->props.pid_filter_count; + } else { + info("will pass the complete MPEG2 transport stream to the demuxer."); + d->pid_filtering = 0; + d->max_feed_count = 255; + } + + if (d->props.power_ctrl) + d->props.power_ctrl(d,1); + + if ((ret = dvb_usb_urb_init(d)) || + (ret = dvb_usb_dvb_init(d)) || + (ret = dvb_usb_i2c_init(d)) || + (ret = dvb_usb_fe_init(d))) { + dvb_usb_exit(d); + return ret; + } + + if ((ret = dvb_usb_remote_init(d))) + err("could not initialize remote control."); + + if (d->props.power_ctrl) + d->props.power_ctrl(d,0); + + return 0; +} + +/* determine the name and the state of the just found USB device */ +static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold) +{ + int i,j; + struct dvb_usb_device_description *desc = NULL; + *cold = -1; + + for (i = 0; i < props->num_device_descs; i++) { + + for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) { + deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct); + if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && + props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { + *cold = 1; + desc = &props->devices[i]; + break; + } + } + + if (desc != NULL) + break; + + for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) { + deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct); + if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && + props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { + *cold = 0; + desc = &props->devices[i]; + break; + } + } + } + + if (desc != NULL && props->identify_state != NULL) + props->identify_state(udev,props,&desc,cold); + + return desc; +} + +/* + * USB + */ +int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct dvb_usb_device *d = NULL; + struct dvb_usb_device_description *desc = NULL; + + int ret = -ENOMEM,cold=0; + + if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { + deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); + return -ENODEV; + } + + if (cold) { + info("found a '%s' in cold state, will try to load a firmware",desc->name); + ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl); + } else { + info("found a '%s' in warm state.",desc->name); + d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); + if (d == NULL) { + err("no memory for 'struct dvb_usb_device'"); + return ret; + } + memset(d,0,sizeof(struct dvb_usb_device)); + + d->udev = udev; + memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); + d->desc = desc; + d->owner = owner; + + if (d->props.size_of_priv > 0) { + d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); + if (d->priv == NULL) { + err("no memory for priv in 'struct dvb_usb_device'"); + kfree(d); + return -ENOMEM; + } + memset(d->priv,0,d->props.size_of_priv); + } + + usb_set_intfdata(intf, d); + + ret = dvb_usb_init(d); + } + + if (ret == 0) + info("%s successfully initialized and connected.",desc->name); + else + info("%s error while loading driver (%d)",desc->name,ret); + return ret; +} +EXPORT_SYMBOL(dvb_usb_device_init); + +void dvb_usb_device_exit(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + const char *name = "generic DVB-USB module"; + + usb_set_intfdata(intf,NULL); + if (d != NULL && d->desc != NULL) { + name = d->desc->name; + dvb_usb_exit(d); + } + info("%s successfully deinitialized and disconnected.",name); + +} +EXPORT_SYMBOL(dvb_usb_device_exit); + +/* module stuff */ +static int __init dvb_usb_module_init(void) +{ + return 0; +} + +static void __exit dvb_usb_module_exit(void) +{ +} + +module_init (dvb_usb_module_init); +module_exit (dvb_usb_module_exit); + +MODULE_VERSION("0.3"); +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c new file mode 100644 index 00000000000..9f1e23f82ba --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -0,0 +1,175 @@ +/* dvb-usb-remote.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for initializing the the input-device and for handling remote-control-queries. + */ +#include "dvb-usb-common.h" + +/* Remote-control poll function - called every dib->rc_query_interval ms to see + * whether the remote control has received anything. + * + * TODO: Fix the repeat rate of the input device. + */ +static void dvb_usb_read_remote_control(void *data) +{ + struct dvb_usb_device *d = data; + u32 event; + int state; + + /* TODO: need a lock here. We can simply skip checking for the remote control + if we're busy. */ + + if (d->props.rc_query(d,&event,&state)) { + err("error while querying for an remote control event."); + goto schedule; + } + + + switch (state) { + case REMOTE_NO_KEY_PRESSED: + break; + case REMOTE_KEY_PRESSED: + deb_rc("key pressed\n"); + d->last_event = event; + case REMOTE_KEY_REPEAT: + deb_rc("key repeated\n"); + input_event(&d->rc_input_dev, EV_KEY, event, 1); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(&d->rc_input_dev); + break; + default: + break; + } + +/* improved repeat handling ??? + switch (state) { + case REMOTE_NO_KEY_PRESSED: + deb_rc("NO KEY PRESSED\n"); + if (d->last_state != REMOTE_NO_KEY_PRESSED) { + deb_rc("releasing event %d\n",d->last_event); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(&d->rc_input_dev); + } + d->last_state = REMOTE_NO_KEY_PRESSED; + d->last_event = 0; + break; + case REMOTE_KEY_PRESSED: + deb_rc("KEY PRESSED\n"); + deb_rc("pressing event %d\n",event); + + input_event(&d->rc_input_dev, EV_KEY, event, 1); + input_sync(&d->rc_input_dev); + + d->last_event = event; + d->last_state = REMOTE_KEY_PRESSED; + break; + case REMOTE_KEY_REPEAT: + deb_rc("KEY_REPEAT\n"); + if (d->last_state != REMOTE_NO_KEY_PRESSED) { + deb_rc("repeating event %d\n",d->last_event); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2); + input_sync(&d->rc_input_dev); + d->last_state = REMOTE_KEY_REPEAT; + } + default: + break; + } +*/ + +schedule: + schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); +} + +int dvb_usb_remote_init(struct dvb_usb_device *d) +{ + int i; + if (d->props.rc_key_map == NULL) + return 0; + + /* Initialise the remote-control structures.*/ + init_input_dev(&d->rc_input_dev); + + d->rc_input_dev.evbit[0] = BIT(EV_KEY); + d->rc_input_dev.keycodesize = sizeof(unsigned char); + d->rc_input_dev.keycodemax = KEY_MAX; + d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver"; + + /* set the bits for the keys */ + deb_rc("key map size: %d\n",d->props.rc_key_map_size); + for (i = 0; i < d->props.rc_key_map_size; i++) { + deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i); + set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit); + } + + /* Start the remote-control polling. */ + if (d->props.rc_interval < 40) + d->props.rc_interval = 100; /* default */ + + /* setting these two values to non-zero, we have to manage key repeats */ + d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval; + d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150; + + input_register_device(&d->rc_input_dev); + + INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d); + + info("schedule remote query interval to %d msecs.",d->props.rc_interval); + schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); + + d->state |= DVB_USB_STATE_REMOTE; + + return 0; +} + +int dvb_usb_remote_exit(struct dvb_usb_device *d) +{ + if (d->state & DVB_USB_STATE_REMOTE) { + cancel_delayed_work(&d->rc_query_work); + flush_scheduled_work(); + input_unregister_device(&d->rc_input_dev); + } + d->state &= ~DVB_USB_STATE_REMOTE; + return 0; +} + +#define DVB_USB_RC_NEC_EMPTY 0x00 +#define DVB_USB_RC_NEC_KEY_PRESSED 0x01 +#define DVB_USB_RC_NEC_KEY_REPEATED 0x02 +int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, + u8 keybuf[5], u32 *event, int *state) +{ + int i; + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + *event = 0; + *state = REMOTE_NO_KEY_PRESSED; + switch (keybuf[0]) { + case DVB_USB_RC_NEC_EMPTY: + break; + case DVB_USB_RC_NEC_KEY_PRESSED: + if ((u8) ~keybuf[1] != keybuf[2] || + (u8) ~keybuf[3] != keybuf[4]) { + deb_err("remote control checksum failed.\n"); + break; + } + /* See if we can match the raw key code. */ + for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++) + if (keymap[i].custom == keybuf[1] && + keymap[i].data == keybuf[3]) { + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + break; + } + deb_err("key mapping failed - no appropriate key found in keymapping\n"); + break; + case DVB_USB_RC_NEC_KEY_REPEATED: + *state = REMOTE_KEY_REPEAT; + break; + default: + deb_err("unkown type of remote status: %d\n",keybuf[0]); + break; + } + return 0; +} +EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c new file mode 100644 index 00000000000..83d476fb410 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -0,0 +1,211 @@ +/* dvb-usb-urb.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for initializing and handling the + * USB and URB stuff. + */ +#include "dvb-usb-common.h" + +int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, + u16 rlen, int delay_ms) +{ + int actlen,ret = -ENOMEM; + + if (d->props.generic_bulk_ctrl_endpoint == 0) { + err("endpoint for generic control not specified."); + return -EINVAL; + } + + if (wbuf == NULL || wlen == 0) + return -EINVAL; + + if ((ret = down_interruptible(&d->usb_sem))) + return ret; + + debug_dump(wbuf,wlen,deb_xfer); + + ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev, + d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen, + 2*HZ); + + if (ret) + err("bulk message failed: %d (%d/%d)",ret,wlen,actlen); + else + ret = actlen != wlen ? -1 : 0; + + /* an answer is expected, and no error before */ + if (!ret && rbuf && rlen) { + if (delay_ms) + msleep(delay_ms); + + ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev, + d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen, + 2*HZ); + + if (ret) + err("recv bulk message failed: %d",ret); + else + debug_dump(rbuf,actlen,deb_xfer); + } + + up(&d->usb_sem); + return ret; +} +EXPORT_SYMBOL(dvb_usb_generic_rw); + +int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) +{ + return dvb_usb_generic_rw(d,buf,len,NULL,0,0); +} +EXPORT_SYMBOL(dvb_usb_generic_write); + +static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs) +{ + struct dvb_usb_device *d = urb->context; + + deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status, + urb->actual_length); + + switch (urb->status) { + case 0: /* success */ + case -ETIMEDOUT: /* NAK */ + break; + case -ECONNRESET: /* kill */ + case -ENOENT: + case -ESHUTDOWN: + return; + default: /* error */ + deb_ts("urb completition error %d.", urb->status); + break; + } + + if (d->feedcount > 0 && urb->actual_length > 0) { + if (d->state & DVB_USB_STATE_DVB) + dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length); + } else + deb_ts("URB dropped because of feedcount.\n"); + + usb_submit_urb(urb,GFP_ATOMIC); +} + +int dvb_usb_urb_kill(struct dvb_usb_device *d) +{ + int i; + for (i = 0; i < d->urbs_submitted; i++) { + deb_info("killing URB no. %d.\n",i); + + /* stop the URB */ + usb_kill_urb(d->urb_list[i]); + } + d->urbs_submitted = 0; + return 0; +} + +int dvb_usb_urb_submit(struct dvb_usb_device *d) +{ + int i,ret; + for (i = 0; i < d->urbs_initialized; i++) { + deb_info("submitting URB no. %d\n",i); + if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) { + err("could not submit URB no. %d - get them all back\n",i); + dvb_usb_urb_kill(d); + return ret; + } + d->urbs_submitted++; + } + return 0; +} + +static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d) +{ + int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize; + + deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize); + /* allocate the actual buffer for the URBs */ + if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) { + deb_info("not enough memory for urb-buffer allocation.\n"); + return -ENOMEM; + } + deb_info("allocation successful\n"); + memset(d->buffer,0,bufsize); + + d->state |= DVB_USB_STATE_URB_BUF; + + /* allocate the URBs */ + for (i = 0; i < d->props.urb.count; i++) { + if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) { + return -ENOMEM; + } + + usb_fill_bulk_urb( d->urb_list[i], d->udev, + usb_rcvbulkpipe(d->udev,d->props.urb.endpoint), + &d->buffer[i*d->props.urb.u.bulk.buffersize], + d->props.urb.u.bulk.buffersize, + dvb_usb_bulk_urb_complete, d); + + d->urb_list[i]->transfer_flags = 0; + d->urbs_initialized++; + } + return 0; +} + +int dvb_usb_urb_init(struct dvb_usb_device *d) +{ + /* + * when reloading the driver w/o replugging the device + * sometimes a timeout occures, this helps + */ + if (d->props.generic_bulk_ctrl_endpoint != 0) { + usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); + } + usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint)); + + /* allocate the array for the data transfer URBs */ + d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL); + if (d->urb_list == NULL) + return -ENOMEM; + memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *)); + d->state |= DVB_USB_STATE_URB_LIST; + + switch (d->props.urb.type) { + case DVB_USB_BULK: + return dvb_usb_bulk_urb_init(d); + case DVB_USB_ISOC: + err("isochronous transfer not yet implemented in dvb-usb."); + return -EINVAL; + default: + err("unkown URB-type for data transfer."); + return -EINVAL; + } +} + +int dvb_usb_urb_exit(struct dvb_usb_device *d) +{ + int i; + + dvb_usb_urb_kill(d); + + if (d->state & DVB_USB_STATE_URB_LIST) { + for (i = 0; i < d->urbs_initialized; i++) { + if (d->urb_list[i] != NULL) { + deb_info("freeing URB no. %d.\n",i); + /* free the URBs */ + usb_free_urb(d->urb_list[i]); + } + } + d->urbs_initialized = 0; + /* free the urb array */ + kfree(d->urb_list); + d->state &= ~DVB_USB_STATE_URB_LIST; + } + + if (d->state & DVB_USB_STATE_URB_BUF) + usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count, + d->buffer, d->dma_handle); + + d->state &= ~DVB_USB_STATE_URB_BUF; + return 0; +} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h new file mode 100644 index 00000000000..abcee1943f6 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -0,0 +1,315 @@ +/* dvb-usb.h is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * the headerfile, all dvb-usb-drivers have to include. + */ +#ifndef __DVB_USB_H__ +#define __DVB_USB_H__ + +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "dvb_demux.h" +#include "dvb_net.h" +#include "dmxdev.h" + +#include "dvb-pll.h" + +#include "dvb-usb-ids.h" + +/* debug */ +#ifdef CONFIG_DVB_USB_DEBUG +#define dprintk(var,level,args...) \ + do { if ((var & level)) { printk(args); } } while (0) + +#define debug_dump(b,l,func) {\ + int loop_; \ + for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \ + func("\n");\ +} +#define DVB_USB_DEBUG_STATUS +#else +#define dprintk(args...) +#define debug_dump(b,l,func) + +#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)" + +#endif + +/* generic log methods - taken from usb.h */ +#ifndef DVB_USB_LOG_PREFIX + #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)" +#endif + +#undef err +#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) +#undef info +#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) +#undef warn +#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) + +/** + * struct dvb_usb_device_description - name and its according USB IDs + * @name: real name of the box, regardless which DVB USB device class is in use + * @cold_ids: array of struct usb_device_id which describe the device in + * pre-firmware state + * @warm_ids: array of struct usb_device_id which describe the device in + * post-firmware state + * + * Each DVB USB device class can have one or more actual devices, this struct + * assigns a name to it. + */ +struct dvb_usb_device_description { + const char *name; + +#define DVB_USB_ID_MAX_NUM 15 + struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM]; + struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM]; +}; + +/** + * struct dvb_usb_rc_key - a remote control key and its input-event + * @custom: the vendor/custom part of the key + * @data: the actual key part + * @event: the input event assigned to key identified by custom and data + */ +struct dvb_usb_rc_key { + u8 custom,data; + u32 event; +}; + +struct dvb_usb_device; + +/** + * struct dvb_usb_properties - properties of a dvb-usb-device + * @caps: capabilites of the DVB USB device. + * @pid_filter_count: number of PID filter position in the optional hardware + * PID-filter. + * + * @usb_ctrl: which USB device-side controller is in use. Needed for firmware + * download. + * @firmware: name of the firmware file. + * + * @size_of_priv: how many bytes shall be allocated for the private field + * of struct dvb_usb_device. + * + * @power_ctrl: called to enable/disable power of the device. + * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the + * device (not URB submitting/killing). + * @pid_filter_ctrl: called to en/disable the PID filter, if any. + * @pid_filter: called to set/unset a PID for filtering. + * + * @read_mac_address: called to read the MAC address of the device. + * + * @frontend_attach: called to attach the possible frontends (fill fe-field + * of struct dvb_usb_device). + * @tuner_attach: called to attach the correct tuner and to fill pll_addr, + * pll_desc and pll_init_buf of struct dvb_usb_device). + * @identify_state: called to determine the state (cold or warm), when it + * is not distinguishable by the USB IDs. + * + * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable + * remote control handling). + * @rc_key_map_size: number of items in @rc_key_map. + * @rc_query: called to query an event event. + * @rc_interval: time in ms between two queries. + * + * @i2c_algo: i2c_algorithm if the device has I2CoverUSB. + * + * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic + * endpoint which received control messages with bulk transfers. When this + * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write- + * helper functions. + * + * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming. + * Currently only BULK is implemented + * + * @num_device_descs: number of struct dvb_usb_device_description in @devices + * @devices: array of struct dvb_usb_device_description compatibles with these + * properties. + */ +struct dvb_usb_properties { + +#define DVB_USB_HAS_PID_FILTER 0x01 +#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02 +#define DVB_USB_NEED_PID_FILTERING 0x04 +#define DVB_USB_IS_AN_I2C_ADAPTER 0x08 + int caps; + int pid_filter_count; + +#define CYPRESS_AN2135 0 +#define CYPRESS_AN2235 1 +#define CYPRESS_FX2 2 + int usb_ctrl; + const char *firmware; + + int size_of_priv; + + int (*power_ctrl) (struct dvb_usb_device *, int); + int (*streaming_ctrl) (struct dvb_usb_device *, int); + int (*pid_filter_ctrl) (struct dvb_usb_device *, int); + int (*pid_filter) (struct dvb_usb_device *, int, u16, int); + + int (*read_mac_address) (struct dvb_usb_device *, u8 []); + int (*frontend_attach) (struct dvb_usb_device *); + int (*tuner_attach) (struct dvb_usb_device *); + + int (*identify_state) (struct usb_device *, struct dvb_usb_properties *, + struct dvb_usb_device_description **, int *); + +/* remote control properties */ +#define REMOTE_NO_KEY_PRESSED 0x00 +#define REMOTE_KEY_PRESSED 0x01 +#define REMOTE_KEY_REPEAT 0x02 + struct dvb_usb_rc_key *rc_key_map; + int rc_key_map_size; + int (*rc_query) (struct dvb_usb_device *, u32 *, int *); + int rc_interval; + + struct i2c_algorithm *i2c_algo; + + int generic_bulk_ctrl_endpoint; + + struct { +#define DVB_USB_BULK 1 +#define DVB_USB_ISOC 2 + int type; + int count; + int endpoint; + + union { + struct { + int buffersize; /* per URB */ + } bulk; + struct { + int framesperurb; + int framesize; + } isoc; + } u; + } urb; + + int num_device_descs; + struct dvb_usb_device_description devices[8]; +}; + + +/** + * struct dvb_usb_device - object of a DVB USB device + * @props: copy of the struct dvb_usb_properties this device belongs to. + * @desc: pointer to the device's struct dvb_usb_device_description. + * @state: initialization and runtime state of the device. + * + * @udev: pointer to the device's struct usb_device. + * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS- + * streaming. + * @buffer: buffer used to streaming. + * @dma_handle: dma_addr_t for buffer. + * @urbs_initialized: number of URBs initialized. + * @urbs_submitted: number of URBs submitted. + * @feedcount: number of reqested feeds (used for streaming-activation) + * @pid_filtering: is hardware pid_filtering used or not. + * @usb_sem: semaphore of USB control messages (reading needs two messages) + * @i2c_sem: semaphore for i2c-transfers + * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB + * @pll_addr: I2C address of the tuner for programming + * @pll_init: array containing the initialization buffer + * @pll_desc: pointer to the appropriate struct dvb_pll_desc + * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod + * @dvb_adap: device's dvb_adapter. + * @dmxdev: device's dmxdev. + * @demux: device's software demuxer. + * @dvb_net: device's dvb_net interfaces. + * @dvb_frontend: device's frontend. + * @max_feed_count: how many feeds can be handled simultaneously by this + * device + * @fe_sleep: rerouted frontend-sleep function. + * @fe_init: rerouted frontend-init (wakeup) function. + * @rc_input_dev: input device for the remote control. + * @rc_query_work: struct work_struct frequent rc queries + * @last_event: last triggered event + * @last_state: last state (no, pressed, repeat) + * @owner: owner of the dvb_adapter + * @priv: private data of the actual driver (allocate by dvb-usb, size defined + * in size_of_priv of dvb_usb_properties). + */ +struct dvb_usb_device { + struct dvb_usb_properties props; + struct dvb_usb_device_description *desc; + +#define DVB_USB_STATE_INIT 0x000 +#define DVB_USB_STATE_URB_LIST 0x001 +#define DVB_USB_STATE_URB_BUF 0x002 +#define DVB_USB_STATE_DVB 0x004 +#define DVB_USB_STATE_I2C 0x008 +#define DVB_USB_STATE_REMOTE 0x010 +#define DVB_USB_STATE_URB_SUBMIT 0x020 + int state; + + /* usb */ + struct usb_device *udev; + struct urb **urb_list; + u8 *buffer; + dma_addr_t dma_handle; + int urbs_initialized; + int urbs_submitted; + + int feedcount; + int pid_filtering; + + /* locking */ + struct semaphore usb_sem; + + /* i2c */ + struct semaphore i2c_sem; + struct i2c_adapter i2c_adap; + + /* tuner programming information */ + u8 pll_addr; + u8 pll_init[4]; + struct dvb_pll_desc *pll_desc; + int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8); + + /* dvb */ + struct dvb_adapter dvb_adap; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dvb_net dvb_net; + struct dvb_frontend* fe; + int max_feed_count; + + int (*fe_sleep) (struct dvb_frontend *); + int (*fe_init) (struct dvb_frontend *); + + /* remote control */ + struct input_dev rc_input_dev; + struct work_struct rc_query_work; + u32 last_event; + int last_state; + + struct module *owner; + + void *priv; +}; + +extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *); +extern void dvb_usb_device_exit(struct usb_interface *); + +/* the generic read/write method for device control */ +extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int); +extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); + +/* commonly used remote control parsing */ +extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); + +/* commonly used pll init and set functions */ +extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); +extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); +extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); + + +#endif diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c new file mode 100644 index 00000000000..9d83781aef9 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -0,0 +1,236 @@ +/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2 + * DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dibusb.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS); + +#define deb_rc(args...) dprintk(debug,0x01,args) +#define deb_ee(args...) dprintk(debug,0x02,args) + +/* 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 }, +}; + +/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key + * is delivered. No workaround yet, maybe a new firmware. + */ +static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom; + u16 raw; + int i; + struct dibusb_state *st = d->priv; + + dvb_usb_generic_rw(d,cmd,2,key,5,0); + + *state = REMOTE_NO_KEY_PRESSED; + switch (key[0]) { + case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED: + raw = ((key[1] << 8) | key[2]) >> 3; + toggle = !!(raw & 0x800); + data = raw & 0x3f; + custom = (raw >> 6) & 0x1f; + + 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++) { + deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom); + if (haupp_rc_keys[i].data == data && + haupp_rc_keys[i].custom == custom) { + *event = haupp_rc_keys[i].event; + *state = REMOTE_KEY_PRESSED; + if (st->old_toggle == toggle) { + if (st->last_repeat_count++ < 2) + *state = REMOTE_NO_KEY_PRESSED; + } else { + st->last_repeat_count = 0; + st->old_toggle = toggle; + } + break; + } + } + + break; + case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY: + default: + break; + } + + return 0; +} + +static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) +{ + int i; + u8 b; + + mac[0] = 0x00; + mac[1] = 0x0d; + mac[2] = 0xfe; + + /* this is a complete guess, but works for my box */ + for (i = 136; i < 139; i++) { + dibusb_read_eeprom_byte(d,i, &b); + + mac[5 - (i - 136)] = b; + +/* deb_ee("%02x ",b); + if ((i+1) % 16 == 0) + deb_ee("\n");*/ + } + + return 0; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties nova_t_properties; + +static int nova_t_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE); +} + +/* do not change the order of the ID table */ +static struct usb_device_id nova_t_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, nova_t_table); + +static struct dvb_usb_properties nova_t_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-nova-t-usb2-01.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb2_0_power_ctrl, + .frontend_attach = dibusb_dib3000mc_frontend_attach, + .tuner_attach = dibusb_dib3000mc_tuner_attach, + .read_mac_address = nova_t_read_mac_address, + + .rc_interval = 100, + .rc_key_map = haupp_rc_keys, + .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys), + .rc_query = nova_t_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Hauppauge WinTV-NOVA-T usb2", + { &nova_t_table[0], NULL }, + { &nova_t_table[1], NULL }, + }, + } +}; + +static struct usb_driver nova_t_driver = { + .owner = THIS_MODULE, + .name = "Hauppauge WinTV-NOVA-T usb2", + .probe = nova_t_probe, + .disconnect = dvb_usb_device_exit, + .id_table = nova_t_table, +}; + +/* module stuff */ +static int __init nova_t_module_init(void) +{ + int result; + if ((result = usb_register(&nova_t_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit nova_t_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&nova_t_driver); +} + +module_init (nova_t_module_init); +module_exit (nova_t_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c new file mode 100644 index 00000000000..aa560422ce7 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/umt-010.c @@ -0,0 +1,162 @@ +/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0 + * DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "dibusb.h" + +#include "mt352.h" + +static int umt_mt352_demod_init(struct dvb_frontend *fe) +{ + static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d }; + static u8 mt352_reset[] = { 0x50, 0x80 }; + static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; + static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 }; + static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 }; + + static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff }; + static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff }; + static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 }; + static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 }; + static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f }; + + static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; + static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 }; + + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); + udelay(2000); + mt352_write(fe, mt352_reset, sizeof(mt352_reset)); + mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); + + mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); + mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); + + mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1)); + mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2)); + mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3)); + mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4)); + mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5)); + + mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); + mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); + + return 0; +} + +static int umt_mt352_frontend_attach(struct dvb_usb_device *d) +{ + struct mt352_config umt_config; + + memset(&umt_config,0,sizeof(struct mt352_config)); + umt_config.demod_init = umt_mt352_demod_init; + umt_config.demod_address = 0xf; + umt_config.pll_set = dvb_usb_pll_set; + + d->fe = mt352_attach(&umt_config, &d->i2c_adap); + + return 0; +} + +static int umt_tuner_attach (struct dvb_usb_device *d) +{ + d->pll_addr = 0x61; + d->pll_desc = &dvb_pll_tua6034; + return 0; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties umt_properties; + +static int umt_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0) + return 0; + return -EINVAL; +} + +/* do not change the order of the ID table */ +static struct usb_device_id umt_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, umt_table); + +static struct dvb_usb_properties umt_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-umt-010-02.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .power_ctrl = dibusb_power_ctrl, + .frontend_attach = umt_mt352_frontend_attach, + .tuner_attach = umt_tuner_attach, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 20, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Hanftek UMT-010 DVB-T USB2.0", + { &umt_table[0], NULL }, + { &umt_table[1], NULL }, + }, + } +}; + +static struct usb_driver umt_driver = { + .owner = THIS_MODULE, + .name = "HanfTek UMT-010 USB2.0 DVB-T devices", + .probe = umt_probe, + .disconnect = dvb_usb_device_exit, + .id_table = umt_table, +}; + +/* module stuff */ +static int __init umt_module_init(void) +{ + int result; + if ((result = usb_register(&umt_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit umt_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&umt_driver); +} + +module_init (umt_module_init); +module_exit (umt_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c new file mode 100644 index 00000000000..2746edfeccb --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c @@ -0,0 +1,196 @@ +/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0 + * DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + * + */ +#include "vp7045.h" + +/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT + * + * Programming is hidden inside the firmware, so set_frontend is very easy. + * Even though there is a Firmware command that one can use to access the demod + * via its registers. This is used for status information. + */ + +struct vp7045_fe_state { + struct dvb_frontend fe; + struct dvb_usb_device *d; +}; + + +static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u8 s0 = vp7045_read_reg(state->d,0x00), + s1 = vp7045_read_reg(state->d,0x01), + s3 = vp7045_read_reg(state->d,0x03); + + *status = 0; + if (s0 & (1 << 4)) + *status |= FE_HAS_CARRIER; + if (s0 & (1 << 1)) + *status |= FE_HAS_VITERBI; + if (s0 & (1 << 5)) + *status |= FE_HAS_LOCK; + if (s1 & (1 << 1)) + *status |= FE_HAS_SYNC; + if (s3 & (1 << 6)) + *status |= FE_HAS_SIGNAL; + + if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != + (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) + *status &= ~FE_HAS_LOCK; + + return 0; +} + +static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + *ber = (vp7045_read_reg(state->d, 0x0D) << 16) | + (vp7045_read_reg(state->d, 0x0E) << 8) | + vp7045_read_reg(state->d, 0x0F); + return 0; +} + +static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + *unc = (vp7045_read_reg(state->d, 0x10) << 8) | + vp7045_read_reg(state->d, 0x11); + return 0; +} + +static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) | + vp7045_read_reg(state->d, 0x15); + + *strength = ~signal; + return 0; +} + +static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u8 _snr = vp7045_read_reg(state->d, 0x09); + *snr = (_snr << 8) | _snr; + return 0; +} + +static int vp7045_fe_init(struct dvb_frontend* fe) +{ + return 0; +} + +static int vp7045_fe_sleep(struct dvb_frontend* fe) +{ + return 0; +} + +static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 800; + return 0; +} + +static int vp7045_fe_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u8 buf[5]; + u32 freq = fep->frequency / 1000; + + buf[0] = (freq >> 16) & 0xff; + buf[1] = (freq >> 8) & 0xff; + buf[2] = freq & 0xff; + buf[3] = 0; + + switch (fep->u.ofdm.bandwidth) { + case BANDWIDTH_8_MHZ: buf[4] = 8; break; + case BANDWIDTH_7_MHZ: buf[4] = 7; break; + case BANDWIDTH_6_MHZ: buf[4] = 6; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: + return -EINVAL; + } + + vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200); + return 0; +} + +static int vp7045_fe_get_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + return 0; +} + +static void vp7045_fe_release(struct dvb_frontend* fe) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops vp7045_fe_ops; + +struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) +{ + struct vp7045_fe_state *s = kmalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL); + if (s == NULL) + goto error; + memset(s,0,sizeof(struct vp7045_fe_state)); + + s->d = d; + s->fe.ops = &vp7045_fe_ops; + s->fe.demodulator_priv = s; + + goto success; +error: + return NULL; +success: + return &s->fe; +} + + +static struct dvb_frontend_ops vp7045_fe_ops = { + .info = { + .name = "Twinhan VP7045/46 USB DVB-T", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 1000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = vp7045_fe_release, + + .init = vp7045_fe_init, + .sleep = vp7045_fe_sleep, + + .set_frontend = vp7045_fe_set_frontend, + .get_frontend = vp7045_fe_get_frontend, + .get_tune_settings = vp7045_fe_get_tune_settings, + + .read_status = vp7045_fe_read_status, + .read_ber = vp7045_fe_read_ber, + .read_signal_strength = vp7045_fe_read_signal_strength, + .read_snr = vp7045_fe_read_snr, + .read_ucblocks = vp7045_fe_read_unc_blocks, +}; diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c new file mode 100644 index 00000000000..02ecc9a8e3b --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -0,0 +1,263 @@ +/* DVB USB compliant Linux driver for the + * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver + * - DigitalNow TinyUSB2 DVB-t receiver + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "vp7045.h" + +/* debug */ +int dvb_usb_vp7045_debug; +module_param_named(debug,dvb_usb_vp7045_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); + +int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec) +{ + int ret = 0; + u8 inbuf[12] = { 0 }, outbuf[20] = { 0 }; + + outbuf[0] = cmd; + + if (outlen > 19) + outlen = 19; + + if (inlen > 11) + inlen = 11; + + if (out != NULL && outlen > 0) + memcpy(&outbuf[1], out, outlen); + + deb_xfer("out buffer: "); + debug_dump(outbuf,outlen+1,deb_xfer); + + if ((ret = down_interruptible(&d->usb_sem))) + return ret; + + if (usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, + outbuf, 20, 2*HZ) != 20) { + err("USB control message 'out' went wrong."); + ret = -EIO; + goto unlock; + } + + msleep(msec); + + if (usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev,0), + TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, + inbuf, 12, 2*HZ) != 12) { + err("USB control message 'in' went wrong."); + ret = -EIO; + goto unlock; + } + + deb_xfer("in buffer: "); + debug_dump(inbuf,12,deb_xfer); + + if (in != NULL && inlen > 0) + memcpy(in,&inbuf[1],inlen); + +unlock: + up(&d->usb_sem); + + return ret; +} + +u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg) +{ + u8 obuf[2] = { 0 },v; + obuf[1] = reg; + + vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30); + + return v; +} + +static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 v = onoff; + return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150); +} + +/* remote control stuff */ + +/* 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[] = { + /* insert the keys like this. to make the raw keys visible, enable + * debug=0x04 when loading dvb-usb-vp7045. */ + + /* these keys are probably wrong. I don't have a working IR-receiver on my + * vp7045, so I can't test it. Patches are welcome. */ + { 0x00, 0x01, KEY_1 }, + { 0x00, 0x02, KEY_2 }, +}; + +static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state) +{ + u8 key; + int i; + vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20); + + deb_rc("remote query key: %x %d\n",key,key); + + if (key == 0x44) { + *state = REMOTE_NO_KEY_PRESSED; + return 0; + } + + for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++) + if (vp7045_rc_keys[i].data == key) { + *state = REMOTE_KEY_PRESSED; + *key_buf = vp7045_rc_keys[i].event; + break; + } + return 0; +} + +static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset) +{ + int i = 0; + u8 v,br[2]; + for (i=0; i < len; i++) { + v = offset + i; + vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5); + buf[i] = br[1]; + } + deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i); + debug_dump(buf,i,deb_info); + return 0; +} + + +static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +{ + return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR); +} + +static int vp7045_frontend_attach(struct dvb_usb_device *d) +{ + u8 buf[255] = { 0 }; + + vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0); + buf[10] = '\0'; + deb_info("firmware says: %s ",buf); + + vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0); + buf[10] = '\0'; + deb_info("%s ",buf); + + vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0); + buf[10] = '\0'; + deb_info("v%s\n",buf); + +/* Dump the EEPROM */ +/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */ + + d->fe = vp7045_fe_attach(d); + + return 0; +} + +static struct dvb_usb_properties vp7045_properties; + +static int vp7045_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE); +} + +static struct usb_device_id vp7045_usb_table [] = { + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) }, + { 0 }, +}; +MODULE_DEVICE_TABLE(usb, vp7045_usb_table); + +static struct dvb_usb_properties vp7045_properties = { + .caps = 0, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-vp7045-01.fw", + + .power_ctrl = vp7045_power_ctrl, + .frontend_attach = vp7045_frontend_attach, + .read_mac_address = vp7045_read_mac_addr, + + .rc_interval = 400, + .rc_key_map = vp7045_rc_keys, + .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys), + .rc_query = vp7045_rc_query, + + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)", + .cold_ids = { &vp7045_usb_table[0], NULL }, + .warm_ids = { &vp7045_usb_table[1], NULL }, + }, + { .name = "DigitalNow TinyUSB 2 DVB-t Receiver", + .cold_ids = { &vp7045_usb_table[2], NULL }, + .warm_ids = { &vp7045_usb_table[3], NULL }, + }, + { 0 }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver vp7045_usb_driver = { + .owner = THIS_MODULE, + .name = "dvb-usb-vp7045", + .probe = vp7045_usb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = vp7045_usb_table, +}; + +/* module stuff */ +static int __init vp7045_usb_module_init(void) +{ + int result; + if ((result = usb_register(&vp7045_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit vp7045_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&vp7045_usb_driver); +} + +module_init(vp7045_usb_module_init); +module_exit(vp7045_usb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h new file mode 100644 index 00000000000..9ce21a20fa8 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp7045.h @@ -0,0 +1,78 @@ +/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII + * USB2.0 DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#ifndef _DVB_USB_VP7045_H_ +#define _DVB_USB_VP7045_H_ + +#define DVB_USB_LOG_PREFIX "vp7045" +#include "dvb-usb.h" + +extern int dvb_usb_vp7045_debug; +#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args) +#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args) + +/* vp7045 commands */ + +/* Twinhan Vendor requests */ +#define TH_COMMAND_IN 0xC0 +#define TH_COMMAND_OUT 0xC1 + +/* command bytes */ +#define TUNER_REG_READ 0x03 +#define TUNER_REG_WRITE 0x04 + +#define RC_VAL_READ 0x05 + #define RC_NO_KEY 0x44 + +#define SET_TUNER_POWER 0x06 +#define CHECK_TUNER_POWER 0x12 + #define Tuner_Power_ON 1 + #define Tuner_Power_OFF 0 + +#define GET_USB_SPEED 0x07 + #define USB_SPEED_LOW 0 + #define USB_SPEED_FULL 1 + #define USB_SPEED_HIGH 2 + +#define LOCK_TUNER_COMMAND 0x09 + +#define TUNER_SIGNAL_READ 0x0A + +/* FX2 eeprom */ +#define SET_EE_VALUE 0x10 +#define GET_EE_VALUE 0x11 + #define FX2_ID_ADDR 0x00 + #define VID_MSB_ADDR 0x02 + #define VID_LSB_ADDR 0x01 + #define PID_MSB_ADDR 0x04 + #define PID_LSB_ADDR 0x03 + #define MAC_0_ADDR 0x07 + #define MAC_1_ADDR 0x08 + #define MAC_2_ADDR 0x09 + #define MAC_3_ADDR 0x0a + #define MAC_4_ADDR 0x0b + #define MAC_5_ADDR 0x0c + +#define RESET_FX2 0x13 + +#define FW_VERSION_READ 0x0B +#define VENDOR_STRING_READ 0x0C +#define PRODUCT_STRING_READ 0x0D +#define FW_BCD_VERSION_READ 0x14 + +extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d); +extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec); +extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg); + +#endif diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c index 47ab02e133d..1a4f1f7c228 100644 --- a/drivers/media/dvb/frontends/dib3000-common.c +++ b/drivers/media/dvb/frontends/dib3000-common.c @@ -73,7 +73,7 @@ u16 dib3000_seq[2][2][2] = /* fft,gua, inv */ }; MODULE_AUTHOR("Patrick Boettcher config.pll_addr && state->config.pll_set) { - dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); - state->config.pll_set(fe, fep, NULL); - dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); + if (tuner && state->config.pll_set) { + state->config.pll_set(fe, fep); deb_setf("bandwidth: "); switch (ofdm->bandwidth) { @@ -389,11 +385,8 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); - if (state->config.pll_init) { - dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); - state->config.pll_init(fe,NULL); - dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); - } + if (state->config.pll_init) + state->config.pll_init(fe); return 0; } @@ -623,7 +616,7 @@ static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) { struct dib3000_state* state = fe->demodulator_priv; - *unc = rd(DIB3000MB_REG_UNC); + *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE); return 0; } @@ -638,9 +631,6 @@ static int dib3000mb_sleep(struct dvb_frontend* fe) static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { tune->min_delay_ms = 800; - tune->step_size = 166667; - tune->max_drift = 166667 * 2; - return 0; } diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h index 57e61aa5b07..999b1904781 100644 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ b/drivers/media/dvb/frontends/dib3000mb_priv.h @@ -294,7 +294,7 @@ static u16 dib3000mb_reg_filter_coeffs[] = { static u16 dib3000mb_filter_coeffs[] = { 226, 160, 29, - 979, 998, 19, + 979, 998, 19, 22, 1019, 1006, 1022, 12, 6, 1017, 1017, 3, diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 888f10a5e96..cd33705a432 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=s #define deb_getf(args...) dprintk(0x08,args) #define deb_stat(args...) dprintk(0x10,args) -static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr); - static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth) { @@ -463,10 +461,8 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, int search_state,auto_val; u16 val; - if (tuner && state->config.pll_addr && state->config.pll_set) { /* initial call from dvb */ - dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); - state->config.pll_set(fe,fep,NULL); - dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); + if (tuner && state->config.pll_set) { /* initial call from dvb */ + state->config.pll_set(fe,fep); state->last_tuned_freq = fep->frequency; // if (!scanboost) { @@ -554,19 +550,15 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, dib3000mc_set_adp_cfg(state,ofdm->constellation); wr_foreach(dib3000mc_reg_offset, dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); - - } return 0; } static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) { - struct dib3000_state *state; - + struct dib3000_state *state = fe->demodulator_priv; deb_info("init start\n"); - state = fe->demodulator_priv; state->timing_offset = 0; state->timing_offset_comp_done = 0; @@ -649,11 +641,9 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); -/* if (state->config->pll_init) { - dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); - state->config->pll_init(fe,NULL); - dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); - }*/ + if (state->config.pll_init) + state->config.pll_init(fe); + deb_info("init end\n"); return 0; } @@ -688,7 +678,7 @@ static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) { struct dib3000_state* state = fe->demodulator_priv; - *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT); + *unc = rd(DIB3000MC_REG_PACKET_ERRORS); return 0; } @@ -737,10 +727,7 @@ static int dib3000mc_sleep(struct dvb_frontend* fe) static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { - tune->min_delay_ms = 2000; - tune->step_size = 166667; - tune->max_drift = 166667 * 2; - + tune->min_delay_ms = 1000; return 0; } diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 2a3c2ce7b2a..f73b5f48e23 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -1,6 +1,4 @@ /* - * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $ - * * descriptions + helper functions for simple dvb plls. * * (c) 2004 Gerd Knorr [SuSE Labs] @@ -114,6 +112,92 @@ struct dvb_pll_desc dvb_pll_unknown_1 = { }; EXPORT_SYMBOL(dvb_pll_unknown_1); +/* Infineon TUA6010XS + * used in Thomson Cable Tuner + */ +struct dvb_pll_desc dvb_pll_tua6010xs = { + .name = "Infineon TUA6010XS", + .min = 44250000, + .max = 858000000, + .count = 3, + .entries = { + { 115750000, 36125000, 62500, 0x8e, 0x03 }, + { 403250000, 36125000, 62500, 0x8e, 0x06 }, + { 999999999, 36125000, 62500, 0x8e, 0x85 }, + }, +}; +EXPORT_SYMBOL(dvb_pll_tua6010xs); + +/* Panasonic env57h1xd5 (some Philips PLL ?) */ +struct dvb_pll_desc dvb_pll_env57h1xd5 = { + .name = "Panasonic ENV57H1XD5", + .min = 44250000, + .max = 858000000, + .count = 4, + .entries = { + { 153000000, 36291666, 166666, 0xc2, 0x41 }, + { 470000000, 36291666, 166666, 0xc2, 0x42 }, + { 526000000, 36291666, 166666, 0xc2, 0x84 }, + { 999999999, 36291666, 166666, 0xc2, 0xa4 }, + }, +}; +EXPORT_SYMBOL(dvb_pll_env57h1xd5); + +/* Philips TDA6650/TDA6651 + * used in Panasonic ENV77H11D5 + */ +static void tda665x_bw(u8 *buf, int bandwidth) +{ + if (bandwidth == BANDWIDTH_8_MHZ) + buf[3] |= 0x08; +} + +struct dvb_pll_desc dvb_pll_tda665x = { + .name = "Philips TDA6650/TDA6651", + .min = 44250000, + .max = 858000000, + .setbw = tda665x_bw, + .count = 12, + .entries = { + { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, + { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, + { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, + { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, + { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, + { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, + { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, + { 444000000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ }, + { 583834000, 36249333, 166667, 0xca, 0x63 /* 011 0 0 0 11 */ }, + { 793834000, 36249333, 166667, 0xca, 0xa3 /* 101 0 0 0 11 */ }, + { 444834000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ }, + { 861000000, 36249333, 166667, 0xca, 0xe3 /* 111 0 0 0 11 */ }, + } +}; +EXPORT_SYMBOL(dvb_pll_tda665x); + +/* Infineon TUA6034 + * used in LG TDTP E102P + */ +static void tua6034_bw(u8 *buf, int bandwidth) +{ + if (BANDWIDTH_7_MHZ != bandwidth) + buf[3] |= 0x08; +} + +struct dvb_pll_desc dvb_pll_tua6034 = { + .name = "Infineon TUA6034", + .min = 44250000, + .max = 858000000, + .count = 3, + .setbw = tua6034_bw, + .entries = { + { 174500000, 36166667, 62500, 0xce, 0x01 }, + { 230000000, 36166667, 62500, 0xce, 0x02 }, + { 999999999, 36166667, 62500, 0xce, 0x04 }, + }, +}; +EXPORT_SYMBOL(dvb_pll_tua6034); + /* ----------------------------------------------------------- */ /* code */ @@ -160,9 +244,3 @@ EXPORT_SYMBOL(dvb_pll_configure); MODULE_DESCRIPTION("dvb pll library"); MODULE_AUTHOR("Gerd Knorr"); MODULE_LICENSE("GPL"); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index c4c3c56c4a8..b796778624b 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h @@ -1,5 +1,5 @@ /* - * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $ + * descriptions + helper functions for simple dvb plls. */ #ifndef __DVB_PLL_H__ @@ -17,7 +17,7 @@ struct dvb_pll_desc { u32 stepsize; u8 cb1; u8 cb2; - } entries[9]; + } entries[12]; }; extern struct dvb_pll_desc dvb_pll_thomson_dtt7579; @@ -26,6 +26,11 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; extern struct dvb_pll_desc dvb_pll_lg_z201; extern struct dvb_pll_desc dvb_pll_unknown_1; +extern struct dvb_pll_desc dvb_pll_tua6010xs; +extern struct dvb_pll_desc dvb_pll_env57h1xd5; +extern struct dvb_pll_desc dvb_pll_tua6034; +extern struct dvb_pll_desc dvb_pll_tda665x; + int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, u32 freq, int bandwidth); -- cgit v1.2.3-70-g09d2 From f756ead1366092b73467fe3b1fb23f61034e94f9 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:38 -0700 Subject: [PATCH] dvb-usb: fix init error checking Fix error checking during initialization. Thanks to Gerolf Wendland for discovering. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dibusb-mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index fd103e4746e..a0ffbb59fa1 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -81,7 +81,7 @@ static int dibusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 || - dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) || + dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 || dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0) return 0; -- cgit v1.2.3-70-g09d2 From cc89c229d9d7ec63cd33e960c20e75b77bc987d0 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:39 -0700 Subject: [PATCH] dvb: dvb_frontend: use time_after() Use time_after() macro. Signed-off-by: Marcelo Feitoza Parisi Signed-off-by: Domen Puncer Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-core/dvb_frontend.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index d19301d90a0..d6b7a9de471 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -327,7 +328,8 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) return 1; if (fepriv->dvbdev->writers == 1) - if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ) + if (time_after(jiffies, fepriv->release_jiffies + + dvb_shutdown_timeout * HZ)) return 1; return 0; -- cgit v1.2.3-70-g09d2 From 55f51efdb696ff6e9d2056377d05268a97f3d4e4 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:41 -0700 Subject: [PATCH] dvb: flexcop: add BCM3510 ATSC frontend support for Air2PC card Added support for the Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator used in the first generation of Air2PC ATSC PCI-cards/USB-boxes made by B2C2. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/b2c2/Kconfig | 1 + drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 26 +- drivers/media/dvb/b2c2/flexcop-misc.c | 11 +- drivers/media/dvb/b2c2/flexcop-reg.h | 3 +- drivers/media/dvb/frontends/Kconfig | 8 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/bcm3510.c | 853 +++++++++++++++++++++++++++++ drivers/media/dvb/frontends/bcm3510.h | 40 ++ drivers/media/dvb/frontends/bcm3510_priv.h | 460 ++++++++++++++++ 9 files changed, 1389 insertions(+), 14 deletions(-) create mode 100644 drivers/media/dvb/frontends/bcm3510.c create mode 100644 drivers/media/dvb/frontends/bcm3510.h create mode 100644 drivers/media/dvb/frontends/bcm3510_priv.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index 99bd675df95..fafd0ab3a28 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig @@ -6,6 +6,7 @@ config DVB_B2C2_FLEXCOP select DVB_MT312 select DVB_NXT2002 select DVB_STV0297 + select DVB_BCM3510 help Support for the digital TV receiver chip made by B2C2 Inc. included in Technisats PCI cards and USB boxes. diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 71be400e9ae..0410cc96a48 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -10,6 +10,7 @@ #include "stv0299.h" #include "mt352.h" #include "nxt2002.h" +#include "bcm3510.h" #include "stv0297.h" #include "mt312.h" @@ -285,21 +286,25 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front } static struct mt352_config samsung_tdtc9251dh0_config = { - .demod_address = 0x0f, - .demod_init = samsung_tdtc9251dh0_demod_init, - .pll_set = samsung_tdtc9251dh0_pll_set, + .demod_init = samsung_tdtc9251dh0_demod_init, + .pll_set = samsung_tdtc9251dh0_pll_set, }; -static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) +static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) { struct flexcop_device *fc = fe->dvb->priv; return request_firmware(fw, name, fc->dev); } static struct nxt2002_config samsung_tbmv_config = { - .demod_address = 0x0a, - .request_firmware = nxt2002_request_firmware, + .demod_address = 0x0a, + .request_firmware = flexcop_fe_request_firmware, +}; + +static struct bcm3510_config air2pc_atsc_first_gen_config = { + .demod_address = 0x0f, + .request_firmware = flexcop_fe_request_firmware, }; static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) @@ -354,11 +359,16 @@ int flexcop_frontend_init(struct flexcop_device *fc) fc->dev_type = FC_AIR_DVB; info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); } else - /* try the air atsc (nxt2002) */ + /* try the air atsc 2nd generation (nxt2002) */ if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { - fc->dev_type = FC_AIR_ATSC; + fc->dev_type = FC_AIR_ATSC2; info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); } else + /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ + if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { + fc->dev_type = FC_AIR_ATSC1; + info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address); + } else /* try the cable dvb (stv0297) */ if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) { fc->dev_type = FC_CABLE; diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c index 19e06da4677..23082545651 100644 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/drivers/media/dvb/b2c2/flexcop-misc.c @@ -45,11 +45,12 @@ const char *flexcop_revision_names[] = { const char *flexcop_device_names[] = { "Unkown device", - "AirStar 2 DVB-T", - "AirStar 2 ATSC", - "SkyStar 2 DVB-S", - "SkyStar 2 DVB-S (old version)", - "CableStar 2 DVB-C", + "Air2PC/AirStar 2 DVB-T", + "Air2PC/AirStar 2 ATSC 1st generation", + "Air2PC/AirStar 2 ATSC 2nd generation", + "Sky2PC/SkyStar 2 DVB-S", + "Sky2PC/SkyStar 2 DVB-S (old version)", + "Cable2PC/CableStar 2 DVB-C", }; const char *flexcop_bus_names[] = { diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h index 5e131be55cb..75b50f21afe 100644 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/drivers/media/dvb/b2c2/flexcop-reg.h @@ -21,7 +21,8 @@ extern const char *flexcop_revision_names[]; typedef enum { FC_UNK = 0, FC_AIR_DVB, - FC_AIR_ATSC, + FC_AIR_ATSC1, + FC_AIR_ATSC2, FC_SKY, FC_SKY_OLD, FC_CABLE, diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 75fb556ec01..b4fddf513eb 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -173,4 +173,12 @@ config DVB_OR51132 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +config DVB_BCM3510 + tristate "Broadcom BCM3510" + depends on DVB_CORE + select FW_LOADER + help + An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to + support this frontend. + endmenu diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 7f8784870ea..91d6d3576d3 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_DVB_STV0297) += stv0297.o obj-$(CONFIG_DVB_NXT2002) += nxt2002.o obj-$(CONFIG_DVB_OR51211) += or51211.o obj-$(CONFIG_DVB_OR51132) += or51132.o +obj-$(CONFIG_DVB_BCM3510) += bcm3510.o diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c new file mode 100644 index 00000000000..f5fdc5c3e60 --- /dev/null +++ b/drivers/media/dvb/frontends/bcm3510.c @@ -0,0 +1,853 @@ +/* + * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) + * + * Copyright (C) 2001-5, B2C2 inc. + * + * GPL/Linux driver written by Patrick Boettcher + * + * This driver is "hard-coded" to be used with the 1st generation of + * Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming + * (Panasonic CT10S) is located here, which is actually wrong. Unless there is + * another device with a BCM3510, this is no problem. + * + * The driver works also with QAM64 DVB-C, but had an unreasonable high + * UNC. (Tested with the Air2PC ATSC 1st generation) + * + * You'll need a firmware for this driver in order to get it running. It is + * called "dvb-fe-bcm3510-01.fw". + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 675 Mass + * Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "bcm3510.h" +#include "bcm3510_priv.h" + +struct bcm3510_state { + + struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; + const struct bcm3510_config* config; + struct dvb_frontend frontend; + + /* demodulator private data */ + struct semaphore hab_sem; + u8 firmware_loaded:1; + + unsigned long next_status_check; + unsigned long status_check_interval; + struct bcm3510_hab_cmd_status1 status1; + struct bcm3510_hab_cmd_status2 status2; +}; + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able))."); + +#define dprintk(level,x...) if (level & debug) printk(x) +#define dbufout(b,l,m) {\ + int i; \ + for (i = 0; i < l; i++) \ + m("%02x ",b[i]); \ +} +#define deb_info(args...) dprintk(0x01,args) +#define deb_i2c(args...) dprintk(0x02,args) +#define deb_hab(args...) dprintk(0x04,args) + +/* transfer functions */ +static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len) +{ + u8 b[256]; + int err; + struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 }; + + b[0] = reg; + memcpy(&b[1],buf,len); + + deb_i2c("i2c wr %02x: ",reg); + dbufout(buf,len,deb_i2c); + deb_i2c("\n"); + + if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { + + deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n", + __FUNCTION__, state->config->demod_address, reg, err); + return -EREMOTEIO; + } + + return 0; +} + +static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len) +{ + struct i2c_msg msg[] = { + { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } + }; + int err; + + memset(buf,0,len); + + if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { + deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n", + __FUNCTION__, state->config->demod_address, reg, err); + return -EREMOTEIO; + } + deb_i2c("i2c rd %02x: ",reg); + dbufout(buf,len,deb_i2c); + deb_i2c("\n"); + + return 0; +} + +static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v) +{ + return bcm3510_writebytes(state,reg,&v.raw,1); +} + +static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v) +{ + return bcm3510_readbytes(state,reg,&v->raw,1); +} + +/* Host Access Buffer transfers */ +static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len) +{ + bcm3510_register_value v; + int ret,i; + + v.HABADR_a6.HABADR = 0; + if ((ret = bcm3510_writeB(st,0xa6,v)) < 0) + return ret; + + for (i = 0; i < len; i++) { + if ((ret = bcm3510_readB(st,0xa7,&v)) < 0) + return ret; + buf[i] = v.HABDATA_a7; + } + return 0; +} + +static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len) +{ + bcm3510_register_value v,hab; + int ret,i; + unsigned long t; + +/* Check if any previous HAB request still needs to be serviced by the + * Aquisition Processor before sending new request */ + if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) + return ret; + if (v.HABSTAT_a8.HABR) { + deb_info("HAB is running already - clearing it.\n"); + v.HABSTAT_a8.HABR = 0; + bcm3510_writeB(st,0xa8,v); +// return -EBUSY; + } + +/* Send the start HAB Address (automatically incremented after write of + * HABDATA) and write the HAB Data */ + hab.HABADR_a6.HABADR = 0; + if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0) + return ret; + + for (i = 0; i < len; i++) { + hab.HABDATA_a7 = buf[i]; + if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0) + return ret; + } + +/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to + * be written) */ + v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1; + if ((ret = bcm3510_writeB(st,0xa8,v)) < 0) + return ret; + +/* Polling method: Wait until the AP finishes processing the HAB request */ + t = jiffies + 1*HZ; + while (time_before(jiffies, t)) { + deb_info("waiting for HAB to complete\n"); + msleep(10); + if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) + return ret; + + if (!v.HABSTAT_a8.HABR) + return 0; + } + + deb_info("send_request execution timed out.\n"); + return -ETIMEDOUT; +} + +static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen) +{ + u8 ob[olen+2],ib[ilen+2]; + int ret = 0; + + ob[0] = cmd; + ob[1] = msgid; + memcpy(&ob[2],obuf,olen); + + deb_hab("hab snd: "); + dbufout(ob,olen+2,deb_hab); + deb_hab("\n"); + + if (down_interruptible(&st->hab_sem) < 0) + return -EAGAIN; + + if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || + (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0) + goto error; + + deb_hab("hab get: "); + dbufout(ib,ilen+2,deb_hab); + deb_hab("\n"); + + memcpy(ibuf,&ib[2],ilen); +error: + up(&st->hab_sem); + return ret; +} + +#if 0 +/* not needed, we use a semaphore to prevent HAB races */ +static int bcm3510_is_ap_ready(struct bcm3510_state *st) +{ + bcm3510_register_value ap,hab; + int ret; + + if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 || + (ret = bcm3510_readB(st,0xa2,&ap) < 0)) + return ret; + + if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) { + deb_info("AP is busy\n"); + return -EBUSY; + } + + return 0; +} +#endif + +static int bcm3510_bert_reset(struct bcm3510_state *st) +{ + bcm3510_register_value b; + int ret; + + if ((ret < bcm3510_readB(st,0xfa,&b)) < 0) + return ret; + + b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); + b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b); + b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); + b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b); + + /* clear residual bit counter TODO */ + return 0; +} + +static int bcm3510_refresh_state(struct bcm3510_state *st) +{ + if (time_after(jiffies,st->next_status_check)) { + bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1)); + bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2)); + st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; + } + return 0; +} + +static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct bcm3510_state* st = fe->demodulator_priv; + bcm3510_refresh_state(st); + + *status = 0; + if (st->status1.STATUS1.RECEIVER_LOCK) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; + + if (st->status1.STATUS1.FEC_LOCK) + *status |= FE_HAS_VITERBI; + + if (st->status1.STATUS1.OUT_PLL_LOCK) + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; + + if (*status & FE_HAS_LOCK) + st->status_check_interval = 1500; + else /* more frequently checks if no lock has been achieved yet */ + st->status_check_interval = 500; + + deb_info("real_status: %02x\n",*status); + return 0; +} + +static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber) +{ + struct bcm3510_state* st = fe->demodulator_priv; + bcm3510_refresh_state(st); + + *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2; + return 0; +} + +static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc) +{ + struct bcm3510_state* st = fe->demodulator_priv; + bcm3510_refresh_state(st); + *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1; + return 0; +} + +static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength) +{ + struct bcm3510_state* st = fe->demodulator_priv; + s32 t; + + bcm3510_refresh_state(st); + t = st->status2.SIGNAL; + + if (t > 190) + t = 190; + if (t < 90) + t = 90; + + t -= 90; + t = t * 0xff / 100; + /* normalize if necessary */ + *strength = (t << 8) | t; + return 0; +} + +static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr) +{ + struct bcm3510_state* st = fe->demodulator_priv; + bcm3510_refresh_state(st); + + *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8); + return 0; +} + +/* tuner frontend programming */ +static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a) +{ + struct bcm3510_hab_cmd_tune c; + memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune)); + +/* I2C Mode disabled, set 16 control / Data pairs */ + c.length = 0x10; + c.clock_width = 0; +/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to + * logic high (as Configuration) */ + c.misc = 0x10; +/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */ + c.TUNCTL_state = 0x40; + +/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */ + c.ctl_dat[0].ctrl.size = BITS_8; + c.ctl_dat[0].data = 0x80 | bc; + +/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */ + c.ctl_dat[1].ctrl.size = BITS_8; + c.ctl_dat[1].data = 4; + +/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */ + c.ctl_dat[2].ctrl.size = BITS_3; + c.ctl_dat[2].data = 0x20; + +/* control CS0 pin, pulse byte ? */ + c.ctl_dat[3].ctrl.size = BITS_3; + c.ctl_dat[3].ctrl.clk_off = 1; + c.ctl_dat[3].ctrl.cs0 = 1; + c.ctl_dat[3].data = 0x40; + +/* PGM_S18 to PGM_S11 */ + c.ctl_dat[4].ctrl.size = BITS_8; + c.ctl_dat[4].data = n >> 3; + +/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */ + c.ctl_dat[5].ctrl.size = BITS_8; + c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2); + +/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */ + c.ctl_dat[6].ctrl.size = BITS_3; + c.ctl_dat[6].data = (a << 6) & 0xdf; + +/* control CS0 pin, pulse byte ? */ + c.ctl_dat[7].ctrl.size = BITS_3; + c.ctl_dat[7].ctrl.clk_off = 1; + c.ctl_dat[7].ctrl.cs0 = 1; + c.ctl_dat[7].data = 0x40; + +/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */ + c.ctl_dat[8].ctrl.size = BITS_8; + c.ctl_dat[8].data = 0x80; + +/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */ + c.ctl_dat[9].ctrl.size = BITS_8; + c.ctl_dat[9].data = 0x10; + +/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */ + c.ctl_dat[10].ctrl.size = BITS_3; + c.ctl_dat[10].data = 0x20; + +/* pulse byte */ + c.ctl_dat[11].ctrl.size = BITS_3; + c.ctl_dat[11].ctrl.clk_off = 1; + c.ctl_dat[11].ctrl.cs1 = 1; + c.ctl_dat[11].data = 0x40; + +/* PGM_S18 to PGM_S11 */ + c.ctl_dat[12].ctrl.size = BITS_8; + c.ctl_dat[12].data = 0x2a; + +/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */ + c.ctl_dat[13].ctrl.size = BITS_8; + c.ctl_dat[13].data = 0x8e; + +/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */ + c.ctl_dat[14].ctrl.size = BITS_3; + c.ctl_dat[14].data = 0; + +/* Pulse Byte */ + c.ctl_dat[15].ctrl.size = BITS_3; + c.ctl_dat[15].ctrl.clk_off = 1; + c.ctl_dat[15].ctrl.cs1 = 1; + c.ctl_dat[15].data = 0x40; + + return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0); +} + +static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq) +{ + u8 bc,a; + u16 n; + s32 YIntercept,Tfvco1; + + freq /= 1000; + + deb_info("%dkHz:",freq); + /* set Band Switch */ + if (freq <= 168000) + bc = 0x1c; + else if (freq <= 378000) + bc = 0x2c; + else + bc = 0x30; + + if (freq >= 470000) { + freq -= 470001; + YIntercept = 18805; + } else if (freq >= 90000) { + freq -= 90001; + YIntercept = 15005; + } else if (freq >= 76000){ + freq -= 76001; + YIntercept = 14865; + } else { + freq -= 54001; + YIntercept = 14645; + } + + Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10; + + n = Tfvco1 >> 6; + a = Tfvco1 & 0x3f; + + deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a); + if (n >= 16 && n <= 2047) + return bcm3510_tuner_cmd(st,bc,n,a); + + return -EINVAL; +} + +static int bcm3510_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *p) +{ + struct bcm3510_state* st = fe->demodulator_priv; + struct bcm3510_hab_cmd_ext_acquire cmd; + struct bcm3510_hab_cmd_bert_control bert; + int ret; + + memset(&cmd,0,sizeof(cmd)); + switch (p->u.vsb.modulation) { + case QAM_256: + cmd.ACQUIRE0.MODE = 0x1; + cmd.ACQUIRE1.SYM_RATE = 0x1; + cmd.ACQUIRE1.IF_FREQ = 0x1; + break; + case QAM_64: + cmd.ACQUIRE0.MODE = 0x2; + cmd.ACQUIRE1.SYM_RATE = 0x2; + cmd.ACQUIRE1.IF_FREQ = 0x1; + break; +/* case QAM_256: + cmd.ACQUIRE0.MODE = 0x3; + break; + case QAM_128: + cmd.ACQUIRE0.MODE = 0x4; + break; + case QAM_64: + cmd.ACQUIRE0.MODE = 0x5; + break; + case QAM_32: + cmd.ACQUIRE0.MODE = 0x6; + break; + case QAM_16: + cmd.ACQUIRE0.MODE = 0x7; + break;*/ + case VSB_8: + cmd.ACQUIRE0.MODE = 0x8; + cmd.ACQUIRE1.SYM_RATE = 0x0; + cmd.ACQUIRE1.IF_FREQ = 0x0; + break; + case VSB_16: + cmd.ACQUIRE0.MODE = 0x9; + cmd.ACQUIRE1.SYM_RATE = 0x0; + cmd.ACQUIRE1.IF_FREQ = 0x0; + default: + return -EINVAL; + }; + cmd.ACQUIRE0.OFFSET = 0; + cmd.ACQUIRE0.NTSCSWEEP = 1; + cmd.ACQUIRE0.FA = 1; + cmd.ACQUIRE0.BW = 0; + +/* if (enableOffset) { + cmd.IF_OFFSET0 = xx; + cmd.IF_OFFSET1 = xx; + + cmd.SYM_OFFSET0 = xx; + cmd.SYM_OFFSET1 = xx; + if (enableNtscSweep) { + cmd.NTSC_OFFSET0; + cmd.NTSC_OFFSET1; + } + } */ + bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0); + +/* doing it with different MSGIDs, data book and source differs */ + bert.BE = 0; + bert.unused = 0; + bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0); + bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0); + + bcm3510_bert_reset(st); + + if ((ret = bcm3510_set_freq(st,p->frequency)) < 0) + return ret; + + memset(&st->status1,0,sizeof(st->status1)); + memset(&st->status2,0,sizeof(st->status2)); + st->status_check_interval = 500; + +/* Give the AP some time */ + msleep(200); + + return 0; +} + +static int bcm3510_sleep(struct dvb_frontend* fe) +{ + return 0; +} + +static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s) +{ + s->min_delay_ms = 1000; + s->step_size = 0; + s->max_drift = 0; + return 0; +} + +static void bcm3510_release(struct dvb_frontend* fe) +{ + struct bcm3510_state* state = fe->demodulator_priv; + kfree(state); +} + +/* firmware download: + * firmware file is build up like this: + * 16bit addr, 16bit length, 8byte of length + */ +#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw" + +static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len) +{ + int ret = 0,i; + bcm3510_register_value vH, vL,vD; + + vH.MADRH_a9 = addr >> 8; + vL.MADRL_aa = addr; + if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret; + if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret; + + for (i = 0; i < len; i++) { + vD.MDATA_ab = b[i]; + if ((ret = bcm3510_writeB(st,0xab,vD)) < 0) + return ret; + } + + return 0; +} + +static int bcm3510_download_firmware(struct dvb_frontend* fe) +{ + struct bcm3510_state* st = fe->demodulator_priv; + const struct firmware *fw; + u16 addr,len; + u8 *b; + int ret,i; + + deb_info("requesting firmware\n"); + if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) { + err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); + return ret; + } + deb_info("got firmware: %d\n",fw->size); + + b = fw->data; + for (i = 0; i < fw->size;) { + addr = le16_to_cpu( *( (u16 *)&b[i] ) ); + len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); + deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size); + if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { + err("firmware download failed: %d\n",ret); + return ret; + } + i += 4 + len; + } + release_firmware(fw); + deb_info("firmware download successfully completed\n"); + return 0; +} + +static int bcm3510_check_firmware_version(struct bcm3510_state *st) +{ + struct bcm3510_hab_cmd_get_version_info ver; + bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver)); + + deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n", + ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version); + + if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION && + ver.config_version == BCM3510_DEF_CONFIG_VERSION && + ver.demod_version == BCM3510_DEF_DEMOD_VERSION) + return 0; + + deb_info("version check failed\n"); + return -ENODEV; +} + +/* (un)resetting the AP */ +static int bcm3510_reset(struct bcm3510_state *st) +{ + int ret; + unsigned long t; + bcm3510_register_value v; + + bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1; + if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) + return ret; + + t = jiffies + 3*HZ; + while (time_before(jiffies, t)) { + msleep(10); + if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) + return ret; + + if (v.APSTAT1_a2.RESET) + return 0; + } + deb_info("reset timed out\n"); + return -ETIMEDOUT; +} + +static int bcm3510_clear_reset(struct bcm3510_state *st) +{ + bcm3510_register_value v; + int ret; + unsigned long t; + + v.raw = 0; + if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) + return ret; + + t = jiffies + 3*HZ; + while (time_before(jiffies, t)) { + msleep(10); + if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) + return ret; + + /* verify that reset is cleared */ + if (!v.APSTAT1_a2.RESET) + return 0; + } + deb_info("reset clear timed out\n"); + return -ETIMEDOUT; +} + +static int bcm3510_init_cold(struct bcm3510_state *st) +{ + int ret; + bcm3510_register_value v; + + /* read Acquisation Processor status register and check it is not in RUN mode */ + if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) + return ret; + if (v.APSTAT1_a2.RUN) { + deb_info("AP is already running - firmware already loaded.\n"); + return 0; + } + + deb_info("reset?\n"); + if ((ret = bcm3510_reset(st)) < 0) + return ret; + + deb_info("tristate?\n"); + /* tri-state */ + v.TSTCTL_2e.CTL = 0; + if ((ret = bcm3510_writeB(st,0x2e,v)) < 0) + return ret; + + deb_info("firmware?\n"); + if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 || + (ret = bcm3510_clear_reset(st)) < 0) + return ret; + + /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */ + + return 0; +} + +static int bcm3510_init(struct dvb_frontend* fe) +{ + struct bcm3510_state* st = fe->demodulator_priv; + bcm3510_register_value j; + struct bcm3510_hab_cmd_set_agc c; + int ret; + + if ((ret = bcm3510_readB(st,0xca,&j)) < 0) + return ret; + + deb_info("JDEC: %02x\n",j.raw); + + switch (j.JDEC_ca.JDEC) { + case JDEC_WAIT_AT_RAM: + deb_info("attempting to download firmware\n"); + if ((ret = bcm3510_init_cold(st)) < 0) + return ret; + case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */ + deb_info("firmware is loaded\n"); + bcm3510_check_firmware_version(st); + break; + default: + return -ENODEV; + } + + memset(&c,0,1); + c.SEL = 1; + bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0); + + return 0; +} + + +static struct dvb_frontend_ops bcm3510_ops; + +struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, + struct i2c_adapter *i2c) +{ + struct bcm3510_state* state = NULL; + int ret; + bcm3510_register_value v; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct bcm3510_state), GFP_KERNEL); + if (state == NULL) + goto error; + memset(state,0,sizeof(struct bcm3510_state)); + + /* setup the state */ + + state->config = config; + state->i2c = i2c; + memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); + + /* create dvb_frontend */ + state->frontend.ops = &state->ops; + state->frontend.demodulator_priv = state; + + sema_init(&state->hab_sem, 1); + + if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) + goto error; + + deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER); + + if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */ + (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0)) /* warm */ + goto error; + + info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER); + + bcm3510_reset(state); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(bcm3510_attach); + +static struct dvb_frontend_ops bcm3510_ops = { + + .info = { + .name = "Broadcom BCM3510 VSB/QAM frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 803000000, + /* stepsize is just a guess */ + .frequency_stepsize = 0, + .caps = + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_8VSB | FE_CAN_16VSB | + FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 + }, + + .release = bcm3510_release, + + .init = bcm3510_init, + .sleep = bcm3510_sleep, + + .set_frontend = bcm3510_set_frontend, + .get_tune_settings = bcm3510_get_tune_settings, + + .read_status = bcm3510_read_status, + .read_ber = bcm3510_read_ber, + .read_signal_strength = bcm3510_read_signal_strength, + .read_snr = bcm3510_read_snr, + .read_ucblocks = bcm3510_read_unc, +}; + +MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver"); +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h new file mode 100644 index 00000000000..80f5d0953d0 --- /dev/null +++ b/drivers/media/dvb/frontends/bcm3510.h @@ -0,0 +1,40 @@ +/* + * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) + * + * Copyright (C) 2001-5, B2C2 inc. + * + * GPL/Linux driver written by Patrick Boettcher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef BCM3510_H +#define BCM3510_H + +#include +#include + +struct bcm3510_config +{ + /* the demodulator's i2c address */ + u8 demod_address; + + /* request firmware for device */ + int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); +}; + +extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, + struct i2c_adapter* i2c); + +#endif diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h new file mode 100644 index 00000000000..3bb1bc2a04f --- /dev/null +++ b/drivers/media/dvb/frontends/bcm3510_priv.h @@ -0,0 +1,460 @@ +/* + * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) + * + * Copyright (C) 2001-5, B2C2 inc. + * + * GPL/Linux driver written by Patrick Boettcher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __BCM3510_PRIV_H__ +#define __BCM3510_PRIV_H__ + +#define PACKED __attribute__((packed)) + +#undef err +#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg) +#undef info +#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg) +#undef warn +#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg) + + +#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500 +#define BCM3510_SYMBOL_RATE 5381000 + +typedef union { + u8 raw; + + struct { + u8 CTL :8; + } TSTCTL_2e; + + u8 LDCERC_4e; + u8 LDUERC_4f; + u8 LD_BER0_65; + u8 LD_BER1_66; + u8 LD_BER2_67; + u8 LD_BER3_68; + + struct { + u8 RESET :1; + u8 IDLE :1; + u8 STOP :1; + u8 HIRQ0 :1; + u8 HIRQ1 :1; + u8 na0 :1; + u8 HABAV :1; + u8 na1 :1; + } HCTL1_a0; + + struct { + u8 na0 :1; + u8 IDLMSK :1; + u8 STMSK :1; + u8 I0MSK :1; + u8 I1MSK :1; + u8 na1 :1; + u8 HABMSK :1; + u8 na2 :1; + } HCTLMSK_a1; + + struct { + u8 RESET :1; + u8 IDLE :1; + u8 STOP :1; + u8 RUN :1; + u8 HABAV :1; + u8 MEMAV :1; + u8 ALDONE :1; + u8 REIRQ :1; + } APSTAT1_a2; + + struct { + u8 RSTMSK :1; + u8 IMSK :1; + u8 SMSK :1; + u8 RMSK :1; + u8 HABMSK :1; + u8 MAVMSK :1; + u8 ALDMSK :1; + u8 REMSK :1; + } APMSK1_a3; + + u8 APSTAT2_a4; + u8 APMSK2_a5; + + struct { + u8 HABADR :7; + u8 na :1; + } HABADR_a6; + + u8 HABDATA_a7; + + struct { + u8 HABR :1; + u8 LDHABR :1; + u8 APMSK :1; + u8 HMSK :1; + u8 LDMSK :1; + u8 na :3; + } HABSTAT_a8; + + u8 MADRH_a9; + u8 MADRL_aa; + u8 MDATA_ab; + + struct { +#define JDEC_WAIT_AT_RAM 0x7 +#define JDEC_EEPROM_LOAD_WAIT 0x4 + u8 JDEC :3; + u8 na :5; + } JDEC_ca; + + struct { + u8 REV :4; + u8 LAYER :4; + } REVID_e0; + + struct { + u8 unk0 :1; + u8 CNTCTL :1; + u8 BITCNT :1; + u8 unk1 :1; + u8 RESYNC :1; + u8 unk2 :3; + } BERCTL_fa; + + struct { + u8 CSEL0 :1; + u8 CLKED0 :1; + u8 CSEL1 :1; + u8 CLKED1 :1; + u8 CLKLEV :1; + u8 SPIVAR :1; + u8 na :2; + } TUNSET_fc; + + struct { + u8 CLK :1; + u8 DATA :1; + u8 CS0 :1; + u8 CS1 :1; + u8 AGCSEL :1; + u8 na0 :1; + u8 TUNSEL :1; + u8 na1 :1; + } TUNCTL_fd; + + u8 TUNSEL0_fe; + u8 TUNSEL1_ff; + +} bcm3510_register_value; + +/* HAB commands */ + +/* version */ +#define CMD_GET_VERSION_INFO 0x3D +#define MSGID_GET_VERSION_INFO 0x15 +struct bcm3510_hab_cmd_get_version_info { + u8 microcode_version; + u8 script_version; + u8 config_version; + u8 demod_version; +} PACKED; + +#define BCM3510_DEF_MICROCODE_VERSION 0x0E +#define BCM3510_DEF_SCRIPT_VERSION 0x06 +#define BCM3510_DEF_CONFIG_VERSION 0x01 +#define BCM3510_DEF_DEMOD_VERSION 0xB1 + +/* acquire */ +#define CMD_ACQUIRE 0x38 + +#define MSGID_EXT_TUNER_ACQUIRE 0x0A +struct bcm3510_hab_cmd_ext_acquire { + struct { + u8 MODE :4; + u8 BW :1; + u8 FA :1; + u8 NTSCSWEEP :1; + u8 OFFSET :1; + } PACKED ACQUIRE0; /* control_byte */ + + struct { + u8 IF_FREQ :3; + u8 zero0 :1; + u8 SYM_RATE :3; + u8 zero1 :1; + } PACKED ACQUIRE1; /* sym_if */ + + u8 IF_OFFSET0; /* IF_Offset_10hz */ + u8 IF_OFFSET1; + u8 SYM_OFFSET0; /* SymbolRateOffset */ + u8 SYM_OFFSET1; + u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */ + u8 NTSC_OFFSET1; +} PACKED; + +#define MSGID_INT_TUNER_ACQUIRE 0x0B +struct bcm3510_hab_cmd_int_acquire { + struct { + u8 MODE :4; + u8 BW :1; + u8 FA :1; + u8 NTSCSWEEP :1; + u8 OFFSET :1; + } PACKED ACQUIRE0; /* control_byte */ + + struct { + u8 IF_FREQ :3; + u8 zero0 :1; + u8 SYM_RATE :3; + u8 zero1 :1; + } PACKED ACQUIRE1; /* sym_if */ + + u8 TUNER_FREQ0; + u8 TUNER_FREQ1; + u8 TUNER_FREQ2; + u8 TUNER_FREQ3; + u8 IF_OFFSET0; /* IF_Offset_10hz */ + u8 IF_OFFSET1; + u8 SYM_OFFSET0; /* SymbolRateOffset */ + u8 SYM_OFFSET1; + u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */ + u8 NTSC_OFFSET1; +} PACKED; + +/* modes */ +#define BCM3510_QAM16 = 0x01 +#define BCM3510_QAM32 = 0x02 +#define BCM3510_QAM64 = 0x03 +#define BCM3510_QAM128 = 0x04 +#define BCM3510_QAM256 = 0x05 +#define BCM3510_8VSB = 0x0B +#define BCM3510_16VSB = 0x0D + +/* IF_FREQS */ +#define BCM3510_IF_TERRESTRIAL 0x0 +#define BCM3510_IF_CABLE 0x1 +#define BCM3510_IF_USE_CMD 0x7 + +/* SYM_RATE */ +#define BCM3510_SR_8VSB 0x0 /* 5381119 s/sec */ +#define BCM3510_SR_256QAM 0x1 /* 5360537 s/sec */ +#define BCM3510_SR_16QAM 0x2 /* 5056971 s/sec */ +#define BCM3510_SR_MISC 0x3 /* 5000000 s/sec */ +#define BCM3510_SR_USE_CMD 0x7 + +/* special symbol rate */ +#define CMD_SET_VALUE_NOT_LISTED 0x2d +#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c +struct bcm3510_hab_cmd_set_sr_not_listed { + u8 HOST_SYM_RATE0; + u8 HOST_SYM_RATE1; + u8 HOST_SYM_RATE2; + u8 HOST_SYM_RATE3; +} PACKED; + +/* special IF */ +#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d +struct bcm3510_hab_cmd_set_if_freq_not_listed { + u8 HOST_IF_FREQ0; + u8 HOST_IF_FREQ1; + u8 HOST_IF_FREQ2; + u8 HOST_IF_FREQ3; +} PACKED; + +/* auto reacquire */ +#define CMD_AUTO_PARAM 0x2a +#define MSGID_AUTO_REACQUIRE 0x0e +struct bcm3510_hab_cmd_auto_reacquire { + u8 ACQ :1; /* on/off*/ + u8 unused :7; +} PACKED; + +#define MSGID_SET_RF_AGC_SEL 0x12 +struct bcm3510_hab_cmd_set_agc { + u8 LVL :1; + u8 unused :6; + u8 SEL :1; +} PACKED; + +#define MSGID_SET_AUTO_INVERSION 0x14 +struct bcm3510_hab_cmd_auto_inversion { + u8 AI :1; + u8 unused :7; +} PACKED; + + +/* bert control */ +#define CMD_STATE_CONTROL 0x12 +#define MSGID_BERT_CONTROL 0x0e +#define MSGID_BERT_SET 0xfa +struct bcm3510_hab_cmd_bert_control { + u8 BE :1; + u8 unused :7; +} PACKED; + +#define MSGID_TRI_STATE 0x2e +struct bcm3510_hab_cmd_tri_state { + u8 RE :1; /* a/d ram port pins */ + u8 PE :1; /* baud clock pin */ + u8 AC :1; /* a/d clock pin */ + u8 BE :1; /* baud clock pin */ + u8 unused :4; +} PACKED; + + +/* tune */ +#define CMD_TUNE 0x38 +#define MSGID_TUNE 0x16 +struct bcm3510_hab_cmd_tune_ctrl_data_pair { + struct { +#define BITS_8 0x07 +#define BITS_7 0x06 +#define BITS_6 0x05 +#define BITS_5 0x04 +#define BITS_4 0x03 +#define BITS_3 0x02 +#define BITS_2 0x01 +#define BITS_1 0x00 + u8 size :3; + u8 unk :2; + u8 clk_off :1; + u8 cs0 :1; + u8 cs1 :1; + + } PACKED ctrl; + + u8 data; +} PACKED; + +struct bcm3510_hab_cmd_tune { + u8 length; + u8 clock_width; + u8 misc; + u8 TUNCTL_state; + + struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16]; +} PACKED; + +#define CMD_STATUS 0x38 +#define MSGID_STATUS1 0x08 +struct bcm3510_hab_cmd_status1 { + struct { + u8 EQ_MODE :4; + u8 reserved :2; + u8 QRE :1; /* if QSE and the spectrum is inversed */ + u8 QSE :1; /* automatic spectral inversion */ + } PACKED STATUS0; + + struct { + u8 RECEIVER_LOCK :1; + u8 FEC_LOCK :1; + u8 OUT_PLL_LOCK :1; + u8 reserved :5; + } PACKED STATUS1; + + struct { + u8 reserved :2; + u8 BW :1; + u8 NTE :1; /* NTSC filter sweep enabled */ + u8 AQI :1; /* currently acquiring */ + u8 FA :1; /* fast acquisition */ + u8 ARI :1; /* auto reacquire */ + u8 TI :1; /* programming the tuner */ + } PACKED STATUS2; + u8 STATUS3; + u8 SNR_EST0; + u8 SNR_EST1; + u8 TUNER_FREQ0; + u8 TUNER_FREQ1; + u8 TUNER_FREQ2; + u8 TUNER_FREQ3; + u8 SYM_RATE0; + u8 SYM_RATE1; + u8 SYM_RATE2; + u8 SYM_RATE3; + u8 SYM_OFFSET0; + u8 SYM_OFFSET1; + u8 SYM_ERROR0; + u8 SYM_ERROR1; + u8 IF_FREQ0; + u8 IF_FREQ1; + u8 IF_FREQ2; + u8 IF_FREQ3; + u8 IF_OFFSET0; + u8 IF_OFFSET1; + u8 IF_ERROR0; + u8 IF_ERROR1; + u8 NTSC_FILTER0; + u8 NTSC_FILTER1; + u8 NTSC_FILTER2; + u8 NTSC_FILTER3; + u8 NTSC_OFFSET0; + u8 NTSC_OFFSET1; + u8 NTSC_ERROR0; + u8 NTSC_ERROR1; + u8 INT_AGC_LEVEL0; + u8 INT_AGC_LEVEL1; + u8 EXT_AGC_LEVEL0; + u8 EXT_AGC_LEVEL1; +} PACKED; + +#define MSGID_STATUS2 0x14 +struct bcm3510_hab_cmd_status2 { + struct { + u8 EQ_MODE :4; + u8 reserved :2; + u8 QRE :1; + u8 QSR :1; + } PACKED STATUS0; + struct { + u8 RL :1; + u8 FL :1; + u8 OL :1; + u8 reserved :5; + } PACKED STATUS1; + u8 SYMBOL_RATE0; + u8 SYMBOL_RATE1; + u8 SYMBOL_RATE2; + u8 SYMBOL_RATE3; + u8 LDCERC0; + u8 LDCERC1; + u8 LDCERC2; + u8 LDCERC3; + u8 LDUERC0; + u8 LDUERC1; + u8 LDUERC2; + u8 LDUERC3; + u8 LDBER0; + u8 LDBER1; + u8 LDBER2; + u8 LDBER3; + struct { + u8 MODE_TYPE :4; /* acquire mode 0 */ + u8 reservd :4; + } MODE_TYPE; + u8 SNR_EST0; + u8 SNR_EST1; + u8 SIGNAL; +} PACKED; + +#define CMD_SET_RF_BW_NOT_LISTED 0x3f +#define MSGID_SET_RF_BW_NOT_LISTED 0x11 +/* TODO */ + +#endif -- cgit v1.2.3-70-g09d2 From 391cd727eac2e10be7685efd739a3ea9de87393c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:02:43 -0700 Subject: [PATCH] tuner-core.c improvments and Ymec Tvision TVF8533MF support tuner-core.c, tuner.h: - tuner-core changed to support multiple I2C devices used on some adapters; - Kconfig now has an option (CONFIG_TUNER_MULTI_I2C) to enable this new behavor; - By default, even enabling CONFIG_TUNER_MULTI_I2C, tuner-core emulates the old behavor, using first I2C device for both FM and TV; - There is a new i2c command (TUNER_SET_ADDR) to allow tuner clients to select I2C address for FM or TV tuner; - Tuner I2C dettach now generates a warning on syslog if failed. tuner-simple.c: - TVision TVF-8531MF and TVF-5533 MF tuner included. It uses, by default, I2C on 0xC2 address for TV and on 0xC0 for Radio. Both TV and FM Radio mode are working. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/Kconfig | 13 +++++++ drivers/media/video/tuner-core.c | 79 ++++++++++++++++++++++++++++++++++++-- drivers/media/video/tuner-simple.c | 28 +++++++++++++- include/media/tuner.h | 10 +++++ 4 files changed, 126 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6c05fddb69a..8c349706f85 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -7,6 +7,19 @@ menu "Video For Linux" comment "Video Adapters" +config CONFIG_TUNER_MULTI_I2C + bool "Enable support for multiple I2C devices on Video Adapters (EXPERIMENTAL)" + depends on VIDEO_DEV && EXPERIMENTAL + ---help--- + Some video adapters have more than one tuner inside. This patch + enables support for using more than one tuner. This is required + for some cards to allow tunning both video and radio. + It also improves I2C autodetection for these cards. + + Only few tuners currently is supporting this. More to come. + + It is safe to say 'Y' here even if your card has only one I2C tuner. + config VIDEO_BT848 tristate "BT848 Video For Linux" depends on VIDEO_DEV && PCI && I2C diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 81882ddab85..71423ae3b4d 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $ + * $Id: tuner-core.c,v 1.7 2005/05/30 02:02:47 mchehab Exp $ * * i2c tv tuner chip device driver * core core, i.e. kernel interfaces, registering and so on @@ -23,6 +23,11 @@ #include #include +/* + * comment line bellow to return to old behavor, where only one I2C device is supported + */ +/* #define CONFIG_TUNER_MULTI_I2C */ + #define UNSET (-1U) /* standard i2c insmod options */ @@ -53,6 +58,9 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); MODULE_LICENSE("GPL"); static int this_adap; +#ifdef CONFIG_TUNER_MULTI_I2C +static unsigned short tv_tuner, radio_tuner; +#endif static struct i2c_driver driver; static struct i2c_client client_template; @@ -125,6 +133,28 @@ static void set_freq(struct i2c_client *c, unsigned long freq) t->freq = freq; } +#ifdef CONFIG_TUNER_MULTI_I2C +static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) +{ + struct tuner *t = i2c_get_clientdata(c); + + switch (tun_addr->type) { + case V4L2_TUNER_RADIO: + radio_tuner=tun_addr->addr; + tuner_dbg("radio tuner set to I2C address 0x%02x\n",radio_tuner<<1); + + break; + default: + tv_tuner=tun_addr->addr; + tuner_dbg("TV tuner set to I2C address 0x%02x\n",tv_tuner<<1); + break; + } +} +#else +#define set_addr(c,tun_addr) \ + tuner_warn("It is recommended to enable CONFIG_TUNER_MULTI_I2C for this card.\n"); +#endif + static void set_type(struct i2c_client *c, unsigned int type) { struct tuner *t = i2c_get_clientdata(c); @@ -197,8 +227,16 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) { struct tuner *t; +#ifndef CONFIG_TUNER_MULTI_I2C if (this_adap > 0) return -1; +#else + /* by default, first I2C card is both tv and radio tuner */ + if (this_adap == 0) { + tv_tuner = addr; + radio_tuner = addr; + } +#endif this_adap++; client_template.adapter = adap; @@ -228,6 +266,11 @@ static int tuner_probe(struct i2c_adapter *adap) } this_adap = 0; +#ifdef CONFIG_TUNER_MULTI_I2C + tv_tuner = 0; + radio_tuner = 0; +#endif + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tuner_attach); return 0; @@ -236,8 +279,14 @@ static int tuner_probe(struct i2c_adapter *adap) static int tuner_detach(struct i2c_client *client) { struct tuner *t = i2c_get_clientdata(client); + int err; + + err=i2c_detach_client(&t->i2c); + if (err) { + tuner_warn ("Client deregistration failed, client not detached.\n"); + return err; + } - i2c_detach_client(&t->i2c); kfree(t); return 0; } @@ -249,6 +298,17 @@ static int tuner_detach(struct i2c_client *client) tuner_info("ignore v4l1 call\n"); \ return 0; } +#ifdef CONFIG_TUNER_MULTI_I2C +#define CHECK_ADDR(tp,cmd) if (client->addr!=tp) { \ + tuner_info ("Cmd %s to addr 0x%02x rejected.\n",cmd,client->addr<<1); \ + return 0; } +#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ + CHECK_ADDR(radio_tuner,cmd) } else { CHECK_ADDR(tv_tuner,cmd); } +#else +#define CHECK_ADDR(tp,cmd) +#define CHECK_MODE(cmd) +#endif + static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -256,18 +316,23 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) unsigned int *iarg = (int*)arg; switch (cmd) { - /* --- configuration --- */ case TUNER_SET_TYPE: set_type(client,*iarg); break; + case TUNER_SET_ADDR: + set_addr(client,(struct tuner_addr *)arg); + break; case AUDC_SET_RADIO: + CHECK_ADDR(radio_tuner,"AUDC_SET_RADIO"); + if (V4L2_TUNER_RADIO != t->mode) { set_tv_freq(client,400 * 16); t->mode = V4L2_TUNER_RADIO; } break; case AUDC_CONFIG_PINNACLE: + CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE"); switch (*iarg) { case 2: tuner_dbg("pinnacle pal\n"); @@ -295,6 +360,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) }; struct video_channel *vc = arg; + CHECK_ADDR(tv_tuner,"VIDIOCSCHAN"); CHECK_V4L2; t->mode = V4L2_TUNER_ANALOG_TV; if (vc->norm < ARRAY_SIZE(map)) @@ -308,6 +374,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { unsigned long *v = arg; + CHECK_MODE("VIDIOCSFREQ"); CHECK_V4L2; set_freq(client,*v); return 0; @@ -316,6 +383,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct video_tuner *vt = arg; + CHECK_ADDR(radio_tuner,"VIDIOCGTUNER:"); CHECK_V4L2; if (V4L2_TUNER_RADIO == t->mode && t->has_signal) vt->signal = t->has_signal(client); @@ -325,6 +393,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct video_audio *va = arg; + CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO"); CHECK_V4L2; if (V4L2_TUNER_RADIO == t->mode && t->is_stereo) va->mode = t->is_stereo(client) @@ -337,6 +406,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { v4l2_std_id *id = arg; + CHECK_ADDR(tv_tuner,"VIDIOC_S_STD"); SWITCH_V4L2; t->mode = V4L2_TUNER_ANALOG_TV; t->std = *id; @@ -349,6 +419,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_frequency *f = arg; + CHECK_MODE("VIDIOC_S_FREQUENCY"); SWITCH_V4L2; if (V4L2_TUNER_RADIO == f->type && V4L2_TUNER_RADIO != t->mode) @@ -361,6 +432,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_frequency *f = arg; + CHECK_MODE("VIDIOC_G_FREQUENCY"); SWITCH_V4L2; f->type = t->mode; f->frequency = t->freq; @@ -370,6 +442,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_tuner *tuner = arg; + CHECK_MODE("VIDIOC_G_TUNER"); SWITCH_V4L2; if (V4L2_TUNER_RADIO == t->mode && t->has_signal) tuner->signal = t->has_signal(client); diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 48c6ceff1dc..f7305c8d53d 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $ + * $Id: tuner-simple.c,v 1.14 2005/05/30 02:02:47 mchehab Exp $ * * i2c tv tuner chip device driver * controls all those simple 4-control-bytes style tuners. @@ -212,6 +212,11 @@ static struct tunertype tuners[] = { { "Philips FQ1236A MK4", Philips, NTSC, 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, + /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */ + { "Ymec TVision TVF-8531MF", Philips, NTSC, + 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, + { "Ymec TVision TVF-5533MF", Philips, NTSC, + 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); @@ -424,6 +429,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) buffer[2] = tun->config; switch (t->type) { + case TUNER_YMEC_TVF_5533MF: + + /*These values are empirically determinated */ + div = (freq*122)/16 - 20; + buffer[2] = 0x88; /* could be also 0x80 */ + buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */ + break; case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: buffer[3] = 0x19; @@ -458,6 +470,20 @@ int default_tuner_init(struct i2c_client *c) t->type, tuners[t->type].name); strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); + switch (t->type) { + case TUNER_YMEC_TVF_5533MF: + { + struct tuner_addr tun_addr = { V4L2_TUNER_ANALOG_TV, 0xc2>>1 }; + + if (c->driver->command) { + c->driver->command(c, TUNER_SET_ADDR, &tun_addr); + } else { + tuner_warn("Couldn't set TV tuner I2C address to 0x%02x\n",tun_addr.addr<<1); + } + break; + } + } + t->tv_freq = default_set_tv_freq; t->radio_freq = default_set_radio_freq; t->has_signal = tuner_signal; diff --git a/include/media/tuner.h b/include/media/tuner.h index 156a9c51ffe..6d29d8db0c8 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -98,6 +98,9 @@ #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ #define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ +#define TUNER_YMEC_TVF_8531MF 58 +#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ + #define NOTUNER 0 #define PAL 1 /* PAL_BG */ #define PAL_I 2 @@ -121,8 +124,10 @@ #define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */ #define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */ +#define TUNER_SET_ADDR _IOW('T',3,int) /* Chooses tuner I2C address */ #define TDA9887_SET_CONFIG _IOW('t',5,int) + /* tv card specific */ # define TDA9887_PRESENT (1<<0) # define TDA9887_PORT1_INACTIVE (1<<1) @@ -143,6 +148,11 @@ #define I2C_ADDR_TDA8290 0x4b #define I2C_ADDR_TDA8275 0x61 +struct tuner_addr { + enum v4l2_tuner_type type; + unsigned short addr; +}; + struct tuner { /* device */ struct i2c_client i2c; -- cgit v1.2.3-70-g09d2 From a20758fa3238134ec9ac0a7e02446d9861dfe943 Mon Sep 17 00:00:00 2001 From: Gerd Knorr Date: Thu, 23 Jun 2005 22:04:34 -0700 Subject: [PATCH] v4l: saa7134 byteorder fix Fix byteorder bug in the saa7134 driver. With that ObviouslyCorrect[tm] patch applied the driver reportly works on powerpc. Signed-off-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa7134-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index d506cafba8f..73bb5601032 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -340,7 +340,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt, ptr = pt->cpu + startpage; for (i = 0; i < length; i++, list++) for (p = 0; p * 4096 < list->length; p++, ptr++) - *ptr = sg_dma_address(list) - list->offset; + *ptr = cpu_to_le32(sg_dma_address(list) - list->offset); return 0; } -- cgit v1.2.3-70-g09d2 From c9c12b790e1dad2e6c2a9b2e62e97297aa8dd93a Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 23 Jun 2005 22:04:37 -0700 Subject: [PATCH] saa7134: mark little endian ptr > - *ptr = sg_dma_address(list) - list->offset; > + *ptr = cpu_to_le32(sg_dma_address(list) - list->offset); Clearly mark pointers to little-endian things. Signed-off-by: Alexey Dobriyan Acked-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa7134-core.c | 4 ++-- drivers/media/video/saa7134/saa7134.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 73bb5601032..634a2d25f2f 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -316,7 +316,7 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf) int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) { - u32 *cpu; + __le32 *cpu; dma_addr_t dma_addr; cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); @@ -332,7 +332,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt, struct scatterlist *list, unsigned int length, unsigned int startpage) { - u32 *ptr; + __le32 *ptr; unsigned int i,p; BUG_ON(NULL == pt || NULL == pt->cpu); diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index ac90a985323..1363c3e3f8d 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -241,7 +241,7 @@ struct saa7134_dma; /* saa7134 page table */ struct saa7134_pgtable { unsigned int size; - u32 *cpu; + __le32 *cpu; dma_addr_t dma; }; -- cgit v1.2.3-70-g09d2 From d6988588e13616587aa879c2e0bd7cd811705e5d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 23 Jun 2005 22:04:41 -0700 Subject: [PATCH] VIDEO_CX88_DVB must select DVB_CX22702 VIDEO_CX88_DVB must select DVB_CX22702 (due to its cx22702_attach usage). This patch fixes kernel Bugzilla #4594 (http://bugzilla.kernel.org/show_bug.cgi?id=4594). Signed-off-by: Adrian Bunk Acked-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 8c349706f85..f9383e7f34f 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -343,6 +343,7 @@ config VIDEO_CX88_DVB select VIDEO_BUF_DVB select DVB_MT352 select DVB_OR51132 + select DVB_CX22702 ---help--- This adds support for DVB/ATSC cards based on the Connexant 2388x chip. -- cgit v1.2.3-70-g09d2 From 097b750e6c0209b4b951996826ca0bd6707e357a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 23 Jun 2005 22:04:43 -0700 Subject: [PATCH] Fix for cx88-cards.c for DVICO-FusionHDTV 3 GOLD Q This patch allows full analog functionality for the DViCO FusionHDTV3 Gold-Q, 18ac:d820 which has a Conexant cx23882, Thompson7611, and LG 3202. It does NOT yet support digital decoding or digital audio without the internal analog audio jack connected to the sound board, but it works perfectly in analog mode. Signed-off-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/cx88/cx88-cards.c | 31 +++++++++++++++++++++++++++++++ drivers/media/video/cx88/cx88.h | 1 + 2 files changed, 32 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 367624822d7..98e40026aa4 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -435,6 +435,33 @@ struct cx88_board cx88_boards[] = { } #endif }, + [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { + .name = "DViCO - FusionHDTV 3 Gold-Q", + .tuner_type = 52, /* Thomson DDT 7610 ATSC/NTSC - Its actually a 7611 chip, but this works */ + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x0f0d, + },{ + .type = CX88_VMUX_CABLE, + .vmux = 0, + .gpio0 = 0x0f05, + },{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x0f00, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x0f00, + }}, +#if 0 + .ts = { + .type = CX88_TS, + .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */ + } +#endif + }, [CX88_BOARD_HAUPPAUGE_DVB_T1] = { .name = "Hauppauge Nova-T DVB-T", .tuner_type = TUNER_ABSENT, @@ -672,6 +699,10 @@ struct cx88_subid cx88_subids[] = { .subvendor = 0x18ac, .subdevice = 0xd810, .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD, + },{ + .subvendor = 0x18ac, + .subdevice = 0xd820, + .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, },{ .subvendor = 0x18AC, .subdevice = 0xDB00, diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 88eaaaba5ad..0ea24b72d92 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -162,6 +162,7 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_HAUPPAUGE_ROSLYN 24 #define CX88_BOARD_DIGITALLOGIC_MEC 25 #define CX88_BOARD_IODATA_GVBCTV7E 26 +#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 27 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, -- cgit v1.2.3-70-g09d2 From 93b43f13b5bfeac09ef5743edf39eeeee3f4eeae Mon Sep 17 00:00:00 2001 From: Peter Skipworth Date: Thu, 23 Jun 2005 22:04:45 -0700 Subject: [PATCH] BTTV support for Adlink RTV24 capture card The bttv module currently lacks support for the Adlink RTV24 capture card. The following patch adds support for the Adlink RTV24 video capture card to the bttv module. Cc: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/bttv-cards.c | 87 ++++++++++++++++++++++++++++++++++++++++ drivers/media/video/bttv.h | 1 + 2 files changed, 88 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 6334122704a..ca7c993fecb 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -51,6 +51,7 @@ static void avermedia_eeprom(struct bttv *btv); static void osprey_eeprom(struct bttv *btv); static void modtec_eeprom(struct bttv *btv); static void init_PXC200(struct bttv *btv); +static void init_RTV24(struct bttv *btv); static void winview_audio(struct bttv *btv, struct video_audio *v, int set); static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set); @@ -2251,6 +2252,19 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .no_tda9875 = 1, .muxsel_hook = kodicom4400r_muxsel, +}, +{ + /* ---- card 0x86---------------------------------- */ + /* Michael Henson */ + /* Adlink RTV24 with special unlock codes */ + .name = "Adlink RTV24", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 3, 1, 0}, + .tuner_type = -1, + .pll = PLL_28, }}; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -2748,6 +2762,9 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_KODICOM_4400R: kodicom4400r_init(btv); break; + case BTTV_ADLINK_RTV24: + init_RTV24(btv); + break; } /* pll configuration */ @@ -3303,6 +3320,76 @@ static void __devinit init_PXC200(struct bttv *btv) printk(KERN_INFO "PXC200 Initialised.\n"); } +/* ----------------------------------------------------------------------- */ +/* + * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock + * it. This apparently involves the following procedure for each 878 chip: + * + * 1) write 0x00C3FEFF to the GPIO_OUT_EN register + * + * 2) write to GPIO_DATA + * - 0x0E + * - sleep 1ms + * - 0x10 + 0x0E + * - sleep 10ms + * - 0x0E + * read from GPIO_DATA into buf (uint_32) + * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 ) + * error. ERROR_CPLD_Check_Failed stop. + * + * 3) write to GPIO_DATA + * - write 0x4400 + 0x0E + * - sleep 10ms + * - write 0x4410 + 0x0E + * - sleep 1ms + * - write 0x0E + * read from GPIO_DATA into buf (uint_32) + * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 ) + * error. ERROR_CPLD_Check_Failed. + */ +/* ----------------------------------------------------------------------- */ +void init_RTV24(struct bttv *btv) +{ + u32 dataread; + const long watchdog_value = 0x0E; + + printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation in progress\n", + btv->c.nr); + + btwrite(0x00c3feff, BT848_GPIO_OUT_EN); + + btwrite(0 + watchdog_value, BT848_GPIO_DATA); + msleep(1); + btwrite(0x10 + watchdog_value, BT848_GPIO_DATA); + msleep( 10 ); + btwrite(0 + watchdog_value, BT848_GPIO_DATA); + + dataread = btread(BT848_GPIO_DATA); + + if (((dataread >> 18) & 0x01) != 0 || ((dataread >> 19) & 0x01) != 1) { + printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation(1) " + "ERROR_CPLD_Check_Failed (read %d)\n", + btv->c.nr, dataread); + } + + btwrite(0x4400 + watchdog_value, BT848_GPIO_DATA); + msleep(10); + btwrite(0x4410 + watchdog_value, BT848_GPIO_DATA); + msleep(1); + btwrite(watchdog_value, BT848_GPIO_DATA); + msleep(1); + dataread = btread(BT848_GPIO_DATA); + + if (((dataread >> 18) & 0x01) != 0 || ((dataread >> 19) & 0x01) != 0) { + printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation(2) " + "ERROR_CPLD_Check_Failed (read %d)\n", + btv->c.nr, dataread); + return; + } + + printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation complete.\n", + btv->c.nr); +} /* ----------------------------------------------------------------------- */ /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index 8322b66e090..9ec1b566af7 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h @@ -135,6 +135,7 @@ #define BTTV_DVICO_DVBT_LITE 0x80 #define BTTV_TIBET_CS16 0x83 #define BTTV_KODICOM_4400R 0x84 +#define BTTV_ADLINK_RTV24 0x86 /* i2c address list */ #define I2C_TSA5522 0xc2 -- cgit v1.2.3-70-g09d2 From f246a8172a9e403b78c34568f766990f1506a0ab Mon Sep 17 00:00:00 2001 From: Michael Schimek Date: Thu, 23 Jun 2005 22:04:47 -0700 Subject: [PATCH] v4l: saa7134 ntsc vbi fix This patch fixes NTSC VBI capturing in the saa7134 driver. Signed-off-by: Michael H. Schimek Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa7134-vbi.c | 12 ++++---- drivers/media/video/saa7134/saa7134-video.c | 43 +++++++++++++++-------------- drivers/media/video/saa7134/saa7134.h | 7 +++-- 3 files changed, 33 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index 86954cc7c37..03c350ffb2d 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c @@ -60,10 +60,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf, saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8); saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff); saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8); - saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start & 0xff); - saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8); - saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop & 0xff); - saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop >> 8); + saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start_0 & 0xff); + saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start_0 >> 8); + saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop_0 & 0xff); + saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop_0 >> 8); saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff); saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8); @@ -127,7 +127,7 @@ static int buffer_prepare(struct videobuf_queue *q, unsigned int lines, llength, size; int err; - lines = norm->vbi_v_stop - norm->vbi_v_start +1; + lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1; if (lines > VBI_LINE_COUNT) lines = VBI_LINE_COUNT; #if 1 @@ -177,7 +177,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) struct saa7134_dev *dev = fh->dev; int llength,lines; - lines = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1; + lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1; #if 1 llength = VBI_LINE_LENGTH; #else diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 5d66060026f..72f86736a79 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -158,18 +158,20 @@ static struct saa7134_format formats[] = { .h_stop = 719, \ .video_v_start = 24, \ .video_v_stop = 311, \ - .vbi_v_start = 7, \ - .vbi_v_stop = 22, \ + .vbi_v_start_0 = 7, \ + .vbi_v_stop_0 = 22, \ + .vbi_v_start_1 = 319, \ .src_timing = 4 #define NORM_525_60 \ .h_start = 0, \ .h_stop = 703, \ - .video_v_start = 22, \ - .video_v_stop = 22+239, \ - .vbi_v_start = 10, /* FIXME */ \ - .vbi_v_stop = 21, /* FIXME */ \ - .src_timing = 1 + .video_v_start = 23, \ + .video_v_stop = 262, \ + .vbi_v_start_0 = 10, \ + .vbi_v_stop_0 = 21, \ + .vbi_v_start_1 = 273, \ + .src_timing = 7 static struct saa7134_tvnorm tvnorms[] = { { @@ -274,11 +276,12 @@ static struct saa7134_tvnorm tvnorms[] = { .h_start = 0, .h_stop = 719, - .video_v_start = 22, - .video_v_stop = 22+239, - .vbi_v_start = 10, /* FIXME */ - .vbi_v_stop = 21, /* FIXME */ - .src_timing = 1, + .video_v_start = 23, + .video_v_stop = 262, + .vbi_v_start_0 = 10, + .vbi_v_stop_0 = 21, + .vbi_v_start_1 = 273, + .src_timing = 7, .sync_control = 0x18, .luma_control = 0x40, @@ -335,8 +338,8 @@ static const struct v4l2_queryctrl video_ctrls[] = { .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ - .id = V4L2_CID_VFLIP, - .name = "vertical flip", + .id = V4L2_CID_HFLIP, + .name = "Mirror", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -482,7 +485,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) dev->crop_bounds.width = norm->h_stop - norm->h_start +1; dev->crop_defrect.width = norm->h_stop - norm->h_start +1; - dev->crop_bounds.top = (norm->vbi_v_stop+1)*2; + dev->crop_bounds.top = (norm->vbi_v_stop_0+1)*2; dev->crop_defrect.top = norm->video_v_start*2; dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624) - dev->crop_bounds.top; @@ -1064,7 +1067,7 @@ static int get_control(struct saa7134_dev *dev, struct v4l2_control *c) case V4L2_CID_PRIVATE_INVERT: c->value = dev->ctl_invert; break; - case V4L2_CID_VFLIP: + case V4L2_CID_HFLIP: c->value = dev->ctl_mirror; break; case V4L2_CID_PRIVATE_Y_EVEN: @@ -1139,7 +1142,7 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); break; - case V4L2_CID_VFLIP: + case V4L2_CID_HFLIP: dev->ctl_mirror = c->value; restart_overlay = 1; break; @@ -1407,9 +1410,9 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f) f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; f->fmt.vbi.offset = 64 * 4; - f->fmt.vbi.start[0] = norm->vbi_v_start; - f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1; - f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1; + f->fmt.vbi.start[0] = norm->vbi_v_start_0; + f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1; + f->fmt.vbi.start[1] = norm->vbi_v_start_1; f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */ diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 1363c3e3f8d..b808f18890b 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -21,7 +21,7 @@ */ #include -#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12) +#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,13) #include #include @@ -91,9 +91,10 @@ struct saa7134_tvnorm { unsigned int h_stop; unsigned int video_v_start; unsigned int video_v_stop; - unsigned int vbi_v_start; - unsigned int vbi_v_stop; + unsigned int vbi_v_start_0; + unsigned int vbi_v_stop_0; unsigned int src_timing; + unsigned int vbi_v_start_1; }; struct saa7134_tvaudio { -- cgit v1.2.3-70-g09d2 From 59dcd9480d93aebdf41e29c46e6a8b4ceeaca75d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:04:50 -0700 Subject: [PATCH] v4l: PAL-M support fix for CX88 chipsets This patch fixes PAL-M chroma subcarrier frequency (FSC) to its correct value of 3.5756115 MHz and adjusts horizontal total samples for PAL-M, according with formula Line Draw Time / (4*FSC). Signed-off-by: Mauro Carvalho Chehab Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/cx88/cx88-core.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 1ff79b5a883..8c7f5589e92 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -736,6 +736,10 @@ static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm) { static const unsigned int ntsc = 28636360; static const unsigned int pal = 35468950; + static const unsigned int palm = 28604892; + + if (norm->id & V4L2_STD_PAL_M) + return palm; return (norm->id & V4L2_STD_625_50) ? pal : ntsc; } @@ -749,6 +753,11 @@ static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm) static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) { + /* Should always be Line Draw Time / (4*FSC) */ + + if (norm->id & V4L2_STD_PAL_M) + return 909; + return (norm->id & V4L2_STD_625_50) ? 1135 : 910; } -- cgit v1.2.3-70-g09d2 From 239df2e2b0e1f4f69fdf76fb67e865824029e8ab Mon Sep 17 00:00:00 2001 From: Manuel Capinha Date: Thu, 23 Jun 2005 22:04:53 -0700 Subject: [PATCH] v4l: add support for PixelView Ultra Pro The following patch adds support for the PixelView Ultra Pro video capture card in v4l. - It removes the remote control key definitions from ir-kbd-gpio.c and moves them to ir-common.c so that they can be shared between bt878 and cx88 based cards. - The patch also moves the FUSIONHDTV_3_GOLD_Q card from number 27 to 28 to regain compatibility with the V4L cvs. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/common/ir-common.c | 33 +++++++++++++++++++++++++++++++++ drivers/media/video/cx88/cx88-cards.c | 21 +++++++++++++++++++++ drivers/media/video/cx88/cx88-input.c | 7 +++++++ drivers/media/video/cx88/cx88.h | 3 ++- drivers/media/video/ir-kbd-gpio.c | 32 -------------------------------- include/media/ir-common.h | 1 + 6 files changed, 64 insertions(+), 33 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index 84a49d2ec91..e5636ef181b 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c @@ -213,6 +213,39 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL(ir_codes_hauppauge_new); +IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { + [ 2 ] = KEY_KP0, + [ 1 ] = KEY_KP1, + [ 11 ] = KEY_KP2, + [ 27 ] = KEY_KP3, + [ 5 ] = KEY_KP4, + [ 9 ] = KEY_KP5, + [ 21 ] = KEY_KP6, + [ 6 ] = KEY_KP7, + [ 10 ] = KEY_KP8, + [ 18 ] = KEY_KP9, + + [ 3 ] = KEY_TUNER, // TV/FM + [ 7 ] = KEY_SEARCH, // scan + [ 28 ] = KEY_ZOOM, // full screen + [ 30 ] = KEY_POWER, + [ 23 ] = KEY_VOLUMEDOWN, + [ 31 ] = KEY_VOLUMEUP, + [ 20 ] = KEY_CHANNELDOWN, + [ 22 ] = KEY_CHANNELUP, + [ 24 ] = KEY_MUTE, + + [ 0 ] = KEY_LIST, // source + [ 19 ] = KEY_INFO, // loop + [ 16 ] = KEY_LAST, // +100 + [ 13 ] = KEY_CLEAR, // reset + [ 12 ] = BTN_RIGHT, // fun++ + [ 4 ] = BTN_LEFT, // fun-- + [ 14 ] = KEY_GOTO, // function + [ 15 ] = KEY_STOP, // freeze +}; +EXPORT_SYMBOL(ir_codes_pixelview); + /* -------------------------------------------------------------------------- */ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 98e40026aa4..1c036cc36fe 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -628,6 +628,27 @@ struct cx88_board cx88_boards[] = { .gpio1 = 0x0000e07f, }} }, + [CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = { + .name = "PixelView PlayTV Ultra Pro (Stereo)", + .tuner_type = 38, + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0xbf61, // internal decoder + },{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0xbf63, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0xbf63, + }}, + .radio = { + .type = CX88_RADIO, + .gpio0 = 0xbf60, + }, + }, }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index af6ad8cdbdb..fbf21dbe251 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -261,6 +261,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keydown = 0x02; ir->polling = 5; // ms break; + case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: + ir_codes = ir_codes_pixelview; + ir->gpio_addr = MO_GP1_IO; + ir->mask_keycode = 0x1f; + ir->mask_keyup = 0x80; + ir->polling = 1; // ms + break; } if (NULL == ir_codes) { kfree(ir); diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 0ea24b72d92..7fca1f500c5 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -162,7 +162,8 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_HAUPPAUGE_ROSLYN 24 #define CX88_BOARD_DIGITALLOGIC_MEC 25 #define CX88_BOARD_IODATA_GVBCTV7E 26 -#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 27 +#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27 +#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 28 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c index ab6620de4b3..a9d4b2ad14e 100644 --- a/drivers/media/video/ir-kbd-gpio.c +++ b/drivers/media/video/ir-kbd-gpio.c @@ -114,38 +114,6 @@ static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { [ 0x3e ] = KEY_VOLUMEUP, // 'volume +' }; -static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { - [ 2 ] = KEY_KP0, - [ 1 ] = KEY_KP1, - [ 11 ] = KEY_KP2, - [ 27 ] = KEY_KP3, - [ 5 ] = KEY_KP4, - [ 9 ] = KEY_KP5, - [ 21 ] = KEY_KP6, - [ 6 ] = KEY_KP7, - [ 10 ] = KEY_KP8, - [ 18 ] = KEY_KP9, - - [ 3 ] = KEY_TUNER, // TV/FM - [ 7 ] = KEY_SEARCH, // scan - [ 28 ] = KEY_ZOOM, // full screen - [ 30 ] = KEY_POWER, - [ 23 ] = KEY_VOLUMEDOWN, - [ 31 ] = KEY_VOLUMEUP, - [ 20 ] = KEY_CHANNELDOWN, - [ 22 ] = KEY_CHANNELUP, - [ 24 ] = KEY_MUTE, - - [ 0 ] = KEY_LIST, // source - [ 19 ] = KEY_INFO, // loop - [ 16 ] = KEY_LAST, // +100 - [ 13 ] = KEY_CLEAR, // reset - [ 12 ] = BTN_RIGHT, // fun++ - [ 4 ] = BTN_LEFT, // fun-- - [ 14 ] = KEY_GOTO, // function - [ 15 ] = KEY_STOP, // freeze -}; - /* Attila Kondoros */ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 62c963a52d8..b5fa6c585e2 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -50,6 +50,7 @@ extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, IR_KEYTAB_TYPE *ir_codes); -- cgit v1.2.3-70-g09d2 From 80d34362f391840dcb10c0ec261f765871a586f7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 23 Jun 2005 22:04:55 -0700 Subject: [PATCH] DViCO FusionHDTV3 Gold-T documentation fix Even though it says DViCO FusionHDTV3 Gold-Q on the box, Gold-T is printed on the card. This fix corrects the error in all places, and corrects the tuner name Thomson DDT 7611 (ATSC/NTSC) in the documentation. This applies against 2.6.12-rc5-mm2 after applying Manueal Capinha's patch "Add support for PixelView Ultra Pro in v4l" (because of the change from card=27 to card=28) Signed-off-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/video4linux/CARDLIST.cx88 | 2 +- Documentation/video4linux/CARDLIST.tuner | 2 +- drivers/media/video/cx88/cx88-cards.c | 21 +++++---------------- drivers/media/video/cx88/cx88.h | 2 +- 4 files changed, 8 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index a87f752e541..216f705495c 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 @@ -26,4 +26,4 @@ card=24 - Hauppauge WinTV 28xxx (Roslyn) models card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) card=26 - IODATA GV/BCTV7E card=27 - PixelView PlayTV Ultra Pro (Stereo) -card=28 - DViCO - FusionHDTV 3 Gold-Q +card=28 - DViCO - FusionHDTV 3 Gold-T diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index 7f4fd0de441..aeb8df8ce89 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -58,4 +58,4 @@ tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4) tuner=57 - Philips FQ1236A MK4 tuner=58 - Ymec TVision TVF-8531MF tuner=59 - Ymec TVision TVF-5533MF -tuner=60 - Thomson DDT 7611 +tuner=60 - Thomson DDT 7611 (ATSC/NTSC) diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 1c036cc36fe..c3a561e38e5 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -428,16 +428,11 @@ struct cx88_board cx88_boards[] = { .vmux = 2, .gpio0 = 0x0f00, }}, -#if 0 - .ts = { - .type = CX88_TS, - .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */ - } -#endif }, - [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { - .name = "DViCO - FusionHDTV 3 Gold-Q", - .tuner_type = 52, /* Thomson DDT 7610 ATSC/NTSC - Its actually a 7611 chip, but this works */ + [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { + .name = "DViCO - FusionHDTV 3 Gold-T", + .tuner_type = 52, /* Thomson DDT 7611 ATSC/NTSC */ + /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */ .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -455,12 +450,6 @@ struct cx88_board cx88_boards[] = { .vmux = 2, .gpio0 = 0x0f00, }}, -#if 0 - .ts = { - .type = CX88_TS, - .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */ - } -#endif }, [CX88_BOARD_HAUPPAUGE_DVB_T1] = { .name = "Hauppauge Nova-T DVB-T", @@ -723,7 +712,7 @@ struct cx88_subid cx88_subids[] = { },{ .subvendor = 0x18ac, .subdevice = 0xd820, - .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, + .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, },{ .subvendor = 0x18AC, .subdevice = 0xDB00, diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 7fca1f500c5..80ddf9911e2 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -163,7 +163,7 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_DIGITALLOGIC_MEC 25 #define CX88_BOARD_IODATA_GVBCTV7E 26 #define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27 -#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 28 +#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, -- cgit v1.2.3-70-g09d2 From 3c1d0185db6a44b6304c404f4da1a1a98746ca46 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 23 Jun 2005 22:04:56 -0700 Subject: [PATCH] v4l: support tuner for Thomson DDT 7611 (ATSC/NTSC) Add support for tuner#60: Thomson DDT 7611 (ATSC/NTSC) Change tuner in card#28 (DViCO FusionHDTV3 Gold-T) from tuner=52 (Tuner Thomson DDT 7610) to tuner=60 (Tuner Thomson DDT 7611) Signed-off-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/cx88/cx88-cards.c | 2 +- drivers/media/video/tuner-simple.c | 3 +++ include/media/tuner.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index c3a561e38e5..a6763f1a44c 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -431,7 +431,7 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { .name = "DViCO - FusionHDTV 3 Gold-T", - .tuner_type = 52, /* Thomson DDT 7611 ATSC/NTSC */ + .tuner_type = 60, /* Thomson DDT 7611 ATSC/NTSC */ /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */ .input = {{ .type = CX88_VMUX_TELEVISION, diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index f7305c8d53d..866f18dc5b5 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -217,6 +217,9 @@ static struct tunertype tuners[] = { 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, { "Ymec TVision TVF-5533MF", Philips, NTSC, 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, + + { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, + 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); diff --git a/include/media/tuner.h b/include/media/tuner.h index 6d29d8db0c8..cb75f4809c4 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -101,6 +101,8 @@ #define TUNER_YMEC_TVF_8531MF 58 #define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ +#define TUNER_THOMSON_DTT7611 60 + #define NOTUNER 0 #define PAL 1 /* PAL_BG */ #define PAL_I 2 -- cgit v1.2.3-70-g09d2 From 2d03e289ea4b13d78ce55f1ea0b0d45b8f1b34c3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:04:58 -0700 Subject: [PATCH] bttv update This patch synchronizes current bttv support on V4L with linux kernel and adds support to Adlink RTV24 card. It is asked that *every* patch to V4L stuff to be first submitted to video4linux-list@redhat.com. From: "J.A. Magallon" struct bttv defined after usage. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Peter Skipworth Signed-off-by: Nickolay V Shmyrev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/bttv-cards.c | 99 ++++++++++++++++++++++----------------- drivers/media/video/bttv-driver.c | 2 +- drivers/media/video/bttv-i2c.c | 2 +- drivers/media/video/bttv.h | 4 +- drivers/media/video/bttvp.h | 8 ++-- 5 files changed, 63 insertions(+), 52 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index ca7c993fecb..251092e7f19 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -1,5 +1,5 @@ /* - $Id: bttv-cards.c,v 1.47 2005/02/22 14:06:32 kraxel Exp $ + $Id: bttv-cards.c,v 1.49 2005/06/10 17:20:24 mchehab Exp $ bttv-cards.c @@ -2254,17 +2254,18 @@ struct tvcard bttv_tvcards[] = { .muxsel_hook = kodicom4400r_muxsel, }, { - /* ---- card 0x86---------------------------------- */ - /* Michael Henson */ - /* Adlink RTV24 with special unlock codes */ - .name = "Adlink RTV24", - .video_inputs = 4, - .audio_inputs = 1, - .tuner = 0, - .svhs = 2, - .muxsel = { 2, 3, 1, 0}, - .tuner_type = -1, - .pll = PLL_28, + /* ---- card 0x85---------------------------------- */ + /* Michael Henson */ + /* Adlink RTV24 with special unlock codes */ + .name = "Adlink RTV24", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 3, 1, 0}, + .tuner_type = -1, + .pll = PLL_28, + }}; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -2650,6 +2651,10 @@ void __devinit bttv_init_card1(struct bttv *btv) case BTTV_AVDVBT_771: btv->use_i2c_hw = 1; break; + case BTTV_ADLINK_RTV24: + init_RTV24( btv ); + break; + } if (!bttv_tvcards[btv->c.type].has_dvb) bttv_reset_audio(btv); @@ -2762,9 +2767,6 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_KODICOM_4400R: kodicom4400r_init(btv); break; - case BTTV_ADLINK_RTV24: - init_RTV24(btv); - break; } /* pll configuration */ @@ -2801,6 +2803,8 @@ void __devinit bttv_init_card2(struct bttv *btv) } btv->pll.pll_current = -1; + bttv_reset_audio(btv); + /* tuner configuration (from card list / autodetect / insmod option) */ if (UNSET != bttv_tvcards[btv->c.type].tuner_type) if(UNSET == btv->tuner_type) @@ -3320,6 +3324,8 @@ static void __devinit init_PXC200(struct bttv *btv) printk(KERN_INFO "PXC200 Initialised.\n"); } + + /* ----------------------------------------------------------------------- */ /* * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock @@ -3348,49 +3354,54 @@ static void __devinit init_PXC200(struct bttv *btv) * error. ERROR_CPLD_Check_Failed. */ /* ----------------------------------------------------------------------- */ -void init_RTV24(struct bttv *btv) +void +init_RTV24 (struct bttv *btv) { - u32 dataread; - const long watchdog_value = 0x0E; + uint32_t dataRead = 0; + long watchdog_value = 0x0E; - printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation in progress\n", + printk (KERN_INFO + "bttv%d: Adlink RTV-24 initialisation in progress ...\n", btv->c.nr); - btwrite(0x00c3feff, BT848_GPIO_OUT_EN); + btwrite (0x00c3feff, BT848_GPIO_OUT_EN); - btwrite(0 + watchdog_value, BT848_GPIO_DATA); - msleep(1); - btwrite(0x10 + watchdog_value, BT848_GPIO_DATA); - msleep( 10 ); - btwrite(0 + watchdog_value, BT848_GPIO_DATA); + btwrite (0 + watchdog_value, BT848_GPIO_DATA); + msleep (1); + btwrite (0x10 + watchdog_value, BT848_GPIO_DATA); + msleep (10); + btwrite (0 + watchdog_value, BT848_GPIO_DATA); - dataread = btread(BT848_GPIO_DATA); + dataRead = btread (BT848_GPIO_DATA); - if (((dataread >> 18) & 0x01) != 0 || ((dataread >> 19) & 0x01) != 1) { - printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation(1) " - "ERROR_CPLD_Check_Failed (read %d)\n", - btv->c.nr, dataread); + if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) { + printk (KERN_INFO + "bttv%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n", + btv->c.nr, dataRead); } - btwrite(0x4400 + watchdog_value, BT848_GPIO_DATA); - msleep(10); - btwrite(0x4410 + watchdog_value, BT848_GPIO_DATA); - msleep(1); - btwrite(watchdog_value, BT848_GPIO_DATA); - msleep(1); - dataread = btread(BT848_GPIO_DATA); - - if (((dataread >> 18) & 0x01) != 0 || ((dataread >> 19) & 0x01) != 0) { - printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation(2) " - "ERROR_CPLD_Check_Failed (read %d)\n", - btv->c.nr, dataread); + btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA); + msleep (10); + btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA); + msleep (1); + btwrite (watchdog_value, BT848_GPIO_DATA); + msleep (1); + dataRead = btread (BT848_GPIO_DATA); + + if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) { + printk (KERN_INFO + "bttv%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n", + btv->c.nr, dataRead); + return; } - printk(KERN_INFO "bttv%d: Adlink RTV-24 initialisation complete.\n", - btv->c.nr); + printk (KERN_INFO + "bttv%d: Adlink RTV-24 initialisation complete.\n", btv->c.nr); } + + /* ----------------------------------------------------------------------- */ /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ /* diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 033cc5498f2..290289a9975 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -1,5 +1,5 @@ /* - $Id: bttv-driver.c,v 1.37 2005/02/21 13:57:59 kraxel Exp $ + $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $ bttv - Bt848 frame grabber driver diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index c2368bc832e..da448a5f9e9 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -1,5 +1,5 @@ /* - $Id: bttv-i2c.c,v 1.18 2005/02/16 12:14:10 kraxel Exp $ + $Id: bttv-i2c.c,v 1.21 2005/06/10 17:20:24 mchehab Exp $ bttv-i2c.c -- all the i2c code is here diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index 9ec1b566af7..191eaf1714b 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h @@ -1,5 +1,5 @@ /* - * $Id: bttv.h,v 1.17 2005/02/22 14:06:32 kraxel Exp $ + * $Id: bttv.h,v 1.18 2005/05/24 23:41:42 nsh Exp $ * * bttv - Bt848 frame grabber driver * @@ -135,7 +135,7 @@ #define BTTV_DVICO_DVBT_LITE 0x80 #define BTTV_TIBET_CS16 0x83 #define BTTV_KODICOM_4400R 0x84 -#define BTTV_ADLINK_RTV24 0x86 +#define BTTV_ADLINK_RTV24 0x85 /* i2c address list */ #define I2C_TSA5522 0xc2 diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 1a9ba7e1cf5..7b6f1e85602 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h @@ -226,10 +226,6 @@ extern int fini_bttv_i2c(struct bttv *btv); #define dprintk if (bttv_debug >= 1) printk #define d2printk if (bttv_debug >= 2) printk -/* our devices */ -#define BTTV_MAX 16 -extern unsigned int bttv_num; - #define BTTV_MAX_FBUF 0x208000 #define VBIBUF_SIZE (2048*VBI_MAXLINES*2) #define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ @@ -375,6 +371,10 @@ struct bttv { unsigned int users; struct bttv_fh init; }; + +/* our devices */ +#define BTTV_MAX 16 +extern unsigned int bttv_num; extern struct bttv bttvs[BTTV_MAX]; /* private ioctls */ -- cgit v1.2.3-70-g09d2 From b45009b0288a96a3458f4f8e93cb776678d41875 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:05:03 -0700 Subject: [PATCH] v4l: CX88 cards update This patch adds support for various CX88 cards and allows specifying card addresses. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Michael Krufky Signed-off-by: cybercide@f2s.com Signed-off-by: Catalin Climov Signed-off-by: Nickolay V Shmyrev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/cx88/cx88-blackbird.c | 488 ++++++++++++++++++++++++------ drivers/media/video/cx88/cx88-cards.c | 235 +++++++++----- drivers/media/video/cx88/cx88-core.c | 19 +- drivers/media/video/cx88/cx88-dvb.c | 2 +- drivers/media/video/cx88/cx88-i2c.c | 18 +- drivers/media/video/cx88/cx88-input.c | 4 +- drivers/media/video/cx88/cx88-mpeg.c | 52 +++- drivers/media/video/cx88/cx88-reg.h | 3 +- drivers/media/video/cx88/cx88-tvaudio.c | 103 ++++--- drivers/media/video/cx88/cx88-vbi.c | 6 +- drivers/media/video/cx88/cx88-video.c | 59 +++- drivers/media/video/cx88/cx88.h | 23 +- drivers/media/video/ir-kbd-gpio.c | 2 +- 13 files changed, 778 insertions(+), 236 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 46d6778b863..91f8afeded8 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $ + * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $ * * Support for a cx23416 mpeg encoder via cx2388x host port. * "blackbird" reference design. @@ -61,37 +61,304 @@ static LIST_HEAD(cx8802_devlist); #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF -/*Firmware API commands*/ -#define IVTV_API_ENC_PING_FW 0x00000080 -#define IVTV_API_ENC_GETVER 0x000000C4 -#define IVTV_API_ENC_HALT_FW 0x000000C3 -#define IVTV_API_STD_TIMEOUT 0x00010000 /*units??*/ -//#define IVTV_API_ASSIGN_PGM_INDEX_INFO 0x000000c7 -#define IVTV_API_ASSIGN_STREAM_TYPE 0x000000b9 -#define IVTV_API_ASSIGN_OUTPUT_PORT 0x000000bb -#define IVTV_API_ASSIGN_FRAMERATE 0x0000008f -#define IVTV_API_ASSIGN_FRAME_SIZE 0x00000091 -#define IVTV_API_ASSIGN_ASPECT_RATIO 0x00000099 -#define IVTV_API_ASSIGN_BITRATES 0x00000095 -#define IVTV_API_ASSIGN_GOP_PROPERTIES 0x00000097 -#define IVTV_API_ASSIGN_3_2_PULLDOWN 0x000000b1 -#define IVTV_API_ASSIGN_GOP_CLOSURE 0x000000c5 -#define IVTV_API_ASSIGN_AUDIO_PROPERTIES 0x000000bd -#define IVTV_API_ASSIGN_DNR_FILTER_MODE 0x0000009b -#define IVTV_API_ASSIGN_DNR_FILTER_PROPS 0x0000009d -#define IVTV_API_ASSIGN_CORING_LEVELS 0x0000009f -#define IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE 0x000000a1 -#define IVTV_API_ASSIGN_FRAME_DROP_RATE 0x000000d0 -#define IVTV_API_ASSIGN_PLACEHOLDER 0x000000d8 -#define IVTV_API_MUTE_VIDEO 0x000000d9 -#define IVTV_API_MUTE_AUDIO 0x000000da -#define IVTV_API_INITIALIZE_INPUT 0x000000cd -#define IVTV_API_REFRESH_INPUT 0x000000d3 -#define IVTV_API_ASSIGN_NUM_VSYNC_LINES 0x000000d6 -#define IVTV_API_BEGIN_CAPTURE 0x00000081 -//#define IVTV_API_PAUSE_ENCODER 0x000000d2 -//#define IVTV_API_EVENT_NOTIFICATION 0x000000d5 -#define IVTV_API_END_CAPTURE 0x00000082 +/* Firmware API commands */ +/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */ +#define IVTV_API_STD_TIMEOUT 500 + +#define BLACKBIRD_API_PING 0x80 +#define BLACKBIRD_API_BEGIN_CAPTURE 0x81 +enum blackbird_capture_type { + BLACKBIRD_MPEG_CAPTURE, + BLACKBIRD_RAW_CAPTURE, + BLACKBIRD_RAW_PASSTHRU_CAPTURE +}; +enum blackbird_capture_bits { + BLACKBIRD_RAW_BITS_NONE = 0x00, + BLACKBIRD_RAW_BITS_YUV_CAPTURE = 0x01, + BLACKBIRD_RAW_BITS_PCM_CAPTURE = 0x02, + BLACKBIRD_RAW_BITS_VBI_CAPTURE = 0x04, + BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, + BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 +}; +#define BLACKBIRD_API_END_CAPTURE 0x82 +enum blackbird_capture_end { + BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ + BLACKBIRD_END_NOW, /* stop immediately, no irq */ +}; +#define BLACKBIRD_API_SET_AUDIO_ID 0x89 +#define BLACKBIRD_API_SET_VIDEO_ID 0x8B +#define BLACKBIRD_API_SET_PCR_ID 0x8D +#define BLACKBIRD_API_SET_FRAMERATE 0x8F +enum blackbird_framerate { + BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ + BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ +}; +#define BLACKBIRD_API_SET_RESOLUTION 0x91 +#define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95 +enum blackbird_video_bitrate_type { + BLACKBIRD_VIDEO_VBR, + BLACKBIRD_VIDEO_CBR +}; +#define BLACKBIRD_PEAK_RATE_DIVISOR 400 +enum blackbird_mux_rate { + BLACKBIRD_MUX_RATE_DEFAULT, + /* dvd mux rate: multiply by 400 to get the actual rate */ + BLACKBIRD_MUX_RATE_DVD = 25200 +}; +#define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97 +#define BLACKBIRD_API_SET_ASPECT_RATIO 0x99 +enum blackbird_aspect_ratio { + BLACKBIRD_ASPECT_RATIO_FORBIDDEN, + BLACKBIRD_ASPECT_RATIO_1_1_SQUARE, + BLACKBIRD_ASPECT_RATIO_4_3, + BLACKBIRD_ASPECT_RATIO_16_9, + BLACKBIRD_ASPECT_RATIO_221_100, + BLACKBIRD_ASPECT_RATIO_RESERVED +}; +#define BLACKBIRD_API_SET_DNR_MODE 0x9B +enum blackbird_dnr_bits { + BLACKBIRD_DNR_BITS_MANUAL, + BLACKBIRD_DNR_BITS_AUTO_SPATIAL, + BLACKBIRD_DNR_BITS_AUTO_TEMPORAL, + BLACKBIRD_DNR_BITS_AUTO +}; +enum blackbird_median_filter { + BLACKBIRD_MEDIAN_FILTER_DISABLED, + BLACKBIRD_MEDIAN_FILTER_HORIZONTAL, + BLACKBIRD_MEDIAN_FILTER_VERTICAL, + BLACKBIRD_MEDIAN_FILTER_HV, + BLACKBIRD_MEDIAN_FILTER_DIAGONAL +}; +#define BLACKBIRD_API_SET_MANUAL_DNR 0x9D +#define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F +#define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1 +enum blackbird_spatial_filter_luma { + BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED, + BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, + BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT, + BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */ + BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */ +}; +enum blackbird_spatial_filter_chroma { + BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED, + BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */ +}; +#define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1 +enum blackbird_pulldown { + BLACKBIRD_3_2_PULLDOWN_DISABLED, + BLACKBIRD_3_2_PULLDOWN_ENABLED +}; +#define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7 +enum blackbird_vbi_line_bits { + BLACKBIRD_VBI_LINE_BITS_TOP_FIELD, + BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31), + BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF +}; +enum blackbird_vbi_line { + BLACKBIRD_VBI_LINE_DISABLED, + BLACKBIRD_VBI_LINE_ENABLED +}; +enum blackbird_vbi_slicing { + BLACKBIRD_VBI_SLICING_NONE, + BLACKBIRD_VBI_SLICING_CLOSED_CAPTION +}; +#define BLACKBIRD_API_SET_STREAM_TYPE 0xB9 +enum blackbird_stream_type { + BLACKBIRD_STREAM_PROGRAM, + BLACKBIRD_STREAM_TRANSPORT, + BLACKBIRD_STREAM_MPEG1, + BLACKBIRD_STREAM_PES_AV, + BLACKBIRD_STREAM_UNKNOWN4, + BLACKBIRD_STREAM_PES_VIDEO, + BLACKBIRD_STREAM_UNKNOWN6, + BLACKBIRD_STREAM_PES_AUDIO, + BLACKBIRD_STREAM_UNKNOWN8, + BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */ + BLACKBIRD_STREAM_DVD, + BLACKBIRD_STREAM_VCD, + BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */ +}; +#define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB +enum blackbird_stream_port { + BLACKBIRD_OUTPUT_PORT_MEMORY, + BLACKBIRD_OUTPUT_PORT_STREAMING, + BLACKBIRD_OUTPUT_PORT_SERIAL +}; +#define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD +enum blackbird_audio_bits_sample_rate { + BLACKBIRD_AUDIO_BITS_44100HZ, + BLACKBIRD_AUDIO_BITS_48000HZ, + BLACKBIRD_AUDIO_BITS_32000HZ, + BLACKBIRD_AUDIO_BITS_RESERVED_HZ, +}; +enum blackbird_audio_bits_encoding { + BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2, + BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2, +}; +enum blackbird_audio_bits_bitrate_layer_1 { + BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT, + BLACKBIRD_AUDIO_BITS_LAYER_1_32 = 0x01 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_64 = 0x02 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_96 = 0x03 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4, +}; +enum blackbird_audio_bits_bitrate_layer_2 { + BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT, + BLACKBIRD_AUDIO_BITS_LAYER_2_32 = 0x01 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_48 = 0x02 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_56 = 0x03 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_64 = 0x04 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_80 = 0x05 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_96 = 0x06 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4, +}; +enum blackbird_audio_bits_mode { + BLACKBIRD_AUDIO_BITS_STEREO, + BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8, + BLACKBIRD_AUDIO_BITS_DUAL = 0x2 << 8, + BLACKBIRD_AUDIO_BITS_MONO = 0x3 << 8, +}; +enum blackbird_audio_bits_mode_extension { + BLACKBIRD_AUDIO_BITS_BOUND_4, + BLACKBIRD_AUDIO_BITS_BOUND_8 = 0x1 << 10, + BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10, + BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10, +}; +enum blackbird_audio_bits_emphasis { + BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE, + BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15 = 0x1 << 12, + BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED = 0x2 << 12, + BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12, +}; +enum blackbird_audio_bits_crc { + BLACKBIRD_AUDIO_BITS_CRC_OFF, + BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14, +}; +enum blackbird_audio_bits_copyright { + BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF, + BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15, +}; +enum blackbird_audio_bits_original { + BLACKBIRD_AUDIO_BITS_COPY, + BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16, +}; +#define BLACKBIRD_API_HALT 0xC3 +#define BLACKBIRD_API_GET_VERSION 0xC4 +#define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5 +enum blackbird_gop_closure { + BLACKBIRD_GOP_CLOSURE_OFF, + BLACKBIRD_GOP_CLOSURE_ON, +}; +#define BLACKBIRD_API_DATA_XFER_STATUS 0xC6 +enum blackbird_data_xfer_status { + BLACKBIRD_MORE_BUFFERS_FOLLOW, + BLACKBIRD_LAST_BUFFER, +}; +#define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7 +enum blackbird_picture_mask { + BLACKBIRD_PICTURE_MASK_NONE, + BLACKBIRD_PICTURE_MASK_I_FRAMES, + BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, + BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, +}; +#define BLACKBIRD_API_SET_VBI_PARAMS 0xC8 +enum blackbird_vbi_mode_bits { + BLACKBIRD_VBI_BITS_SLICED, + BLACKBIRD_VBI_BITS_RAW, +}; +enum blackbird_vbi_insertion_bits { + BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, + BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, + BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, + BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, + BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, +}; +#define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9 +enum blackbird_dma_unit { + BLACKBIRD_DMA_BYTES, + BLACKBIRD_DMA_FRAMES, +}; +#define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA +#define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB +enum blackbird_dma_transfer_status_bits { + BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, + BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, + BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, +}; +#define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC +#define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD +#define BLACKBIRD_API_SET_FRAMESKIP 0xD0 +#define BLACKBIRD_API_PAUSE 0xD2 +enum blackbird_pause { + BLACKBIRD_PAUSE_ENCODING, + BLACKBIRD_RESUME_ENCODING, +}; +#define BLACKBIRD_API_REFRESH_INPUT 0xD3 +#define BLACKBIRD_API_SET_COPYRIGHT 0xD4 +enum blackbird_copyright { + BLACKBIRD_COPYRIGHT_OFF, + BLACKBIRD_COPYRIGHT_ON, +}; +#define BLACKBIRD_API_SET_NOTIFICATION 0xD5 +enum blackbird_notification_type { + BLACKBIRD_NOTIFICATION_REFRESH, +}; +enum blackbird_notification_status { + BLACKBIRD_NOTIFICATION_OFF, + BLACKBIRD_NOTIFICATION_ON, +}; +enum blackbird_notification_mailbox { + BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, +}; +#define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6 +enum blackbird_field1_lines { + BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ + BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ + BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */ +}; +enum blackbird_field2_lines { + BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */ + BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ + BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ +}; +#define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7 +enum blackbird_custom_data_type { + BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, + BLACKBIRD_CUSTOM_PRIVATE_PACKET, +}; +#define BLACKBIRD_API_MUTE_VIDEO 0xD9 +enum blackbird_mute { + BLACKBIRD_UNMUTE, + BLACKBIRD_MUTE, +}; +enum blackbird_mute_video_mask { + BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00, + BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000, + BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000, +}; +enum blackbird_mute_video_shift { + BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8, + BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, + BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24, +}; +#define BLACKBIRD_API_MUTE_AUDIO 0xDA /* Registers */ #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) @@ -405,68 +672,100 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) return 0; } +/** + Settings used by the windows tv app for PVR2000: +================================================================================================================= +Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode +----------------------------------------------------------------------------------------------------------------- +MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo +MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo +VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo +DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo +DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo +================================================================================================================= +*DB: "DirectBurn" +*/ static void blackbird_codec_settings(struct cx8802_dev *dev) { int bitrate_mode = 1; int bitrate = 7500000; int bitrate_peak = 7500000; +#if 1 + bitrate_mode = BLACKBIRD_VIDEO_CBR; + bitrate = 4000*1024; + bitrate_peak = 4000*1024; +#endif /* assign stream type */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */ - //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */ - //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */ - //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); + /* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */ - /* assign output port */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */ + /* assign output port */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ - /* assign framerate */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0); + /* assign framerate */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); - /* assign frame size */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0, + /* assign frame size */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, dev->height, dev->width); - /* assign aspect ratio */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2); + /* assign aspect ratio */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); - /* assign bitrates */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0, + /* assign bitrates */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0, bitrate_mode, /* mode */ bitrate, /* bps */ - bitrate_peak / 400, /* peak/400 */ - 0, 0x70); /* encoding buffer, ckennedy */ - - /* assign gop properties */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3); - //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1); - - /* assign 3 2 pulldown */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0); - - /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); + bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ + BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ + + /* assign gop properties */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); + + /* assign 3 2 pulldown */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); + + /* assign audio properties */ + /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ + /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); + blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, + BLACKBIRD_AUDIO_BITS_44100HZ | + BLACKBIRD_AUDIO_BITS_LAYER_2 | + BLACKBIRD_AUDIO_BITS_LAYER_2_224 | + BLACKBIRD_AUDIO_BITS_STEREO | + /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ + BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | + BLACKBIRD_AUDIO_BITS_CRC_OFF | + BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | + BLACKBIRD_AUDIO_BITS_COPY + ); /* assign gop closure */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); - /* assign audio properties */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); - /* assign dnr filter mode */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0); + /* assign dnr filter mode */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, + BLACKBIRD_DNR_BITS_MANUAL, + BLACKBIRD_MEDIAN_FILTER_DISABLED + ); - /* assign dnr filter props*/ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0); + /* assign dnr filter props*/ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); - /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255); + /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); - /* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1); + /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, + BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, + BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ + ); - /* assign frame drop rate */ - blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); + /* assign frame drop rate */ + /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ } static int blackbird_initialize_codec(struct cx8802_dev *dev) @@ -476,7 +775,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) int retval; dprintk(1,"Initialize codec\n"); - retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */ + retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ if (retval < 0) { /* ping was not successful, reset and upload firmware */ cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ @@ -491,13 +790,13 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) if (dev->mailbox < 0) return -1; - retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */ + retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ if (retval < 0) { dprintk(0, "ERROR: Firmware ping failed!\n"); return -1; } - retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version); + retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version); if (retval < 0) { dprintk(0, "ERROR: Firmware get encoder version failed!\n"); return -1; @@ -517,25 +816,36 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) blackbird_codec_settings(dev); msleep(1); - //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); - blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); - //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); - blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); + blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); + blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0, + BLACKBIRD_FIELD1_SAA7115, + BLACKBIRD_FIELD1_SAA7115 + ); + + /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0, + BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */ + blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */ msleep(1); - blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0); + blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); msleep(1); - blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0); + blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); msleep(1); - blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */ - //blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */ - msleep(1); + /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */ + blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, + BLACKBIRD_MPEG_CAPTURE, + BLACKBIRD_RAW_BITS_NONE + ); /* start capturing to the host interface */ + msleep(10); - blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0); + blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0); return 0; } @@ -709,7 +1019,12 @@ static int mpeg_release(struct inode *inode, struct file *file) { struct cx8802_fh *fh = file->private_data; - blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13); + /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ + blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, + BLACKBIRD_END_NOW, + BLACKBIRD_MPEG_CAPTURE, + BLACKBIRD_RAW_BITS_NONE + ); /* stop mpeg capture */ if (fh->mpegq.streaming) @@ -908,4 +1223,5 @@ module_exit(blackbird_fini); * Local variables: * c-basic-offset: 8 * End: + * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */ diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index a6763f1a44c..b3fb04356b7 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-cards.c,v 1.66 2005/03/04 09:12:23 kraxel Exp $ + * $Id: cx88-cards.c,v 1.76 2005/06/08 01:28:09 mchehab Exp $ * * device driver for Conexant 2388x based TV cards * card-specific stuff. @@ -35,6 +35,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_UNKNOWN] = { .name = "UNKNOWN/GENERIC", .tuner_type = UNSET, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_COMPOSITE1, .vmux = 0, @@ -52,6 +55,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_HAUPPAUGE] = { .name = "Hauppauge WinTV 34xxx models", .tuner_type = UNSET, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -78,6 +84,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_GDI] = { .name = "GDI Black Gold", .tuner_type = UNSET, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -85,7 +94,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_PIXELVIEW] = { .name = "PixelView", - .tuner_type = 5, + .tuner_type = TUNER_PHILIPS_PAL, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -104,7 +116,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_ATI_WONDER_PRO] = { .name = "ATI TV Wonder Pro", - .tuner_type = 44, + .tuner_type = TUNER_PHILIPS_4IN1, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -122,7 +137,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_WINFAST2000XP_EXPERT] = { .name = "Leadtek Winfast 2000XP Expert", - .tuner_type = 44, + .tuner_type = TUNER_PHILIPS_4IN1, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -156,7 +174,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_AVERTV_303] = { .name = "AverTV Studio 303 (M126)", - .tuner_type = 38, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -179,7 +200,10 @@ struct cx88_board cx88_boards[] = { // added gpio values thanks to Michal // values for PAL from DScaler .name = "MSI TV-@nywhere Master", - .tuner_type = 33, + .tuner_type = TUNER_MT2032, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -206,7 +230,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_WINFAST_DV2000] = { .name = "Leadtek Winfast DV2000", - .tuner_type = 38, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -239,34 +266,40 @@ struct cx88_board cx88_boards[] = { .gpio3 = 0x02000000, }, }, - [CX88_BOARD_LEADTEK_PVR2000] = { + [CX88_BOARD_LEADTEK_PVR2000] = { // gpio values for PAL version from regspy by DScaler - .name = "Leadtek PVR 2000", - .tuner_type = 38, + .name = "Leadtek PVR 2000", + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x0000bde6, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x0000bde6, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x0000bde6, - }}, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0x0000bd62, - }, + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x0000bde2, + },{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x0000bde6, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x0000bde6, + }}, + .radio = { + .type = CX88_RADIO, + .gpio0 = 0x0000bd62, + }, .blackbird = 1, - }, + }, [CX88_BOARD_IODATA_GVVCP3PCI] = { .name = "IODATA GV-VCP3/PCI", .tuner_type = TUNER_ABSENT, - .input = {{ + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .input = {{ .type = CX88_VMUX_COMPOSITE1, .vmux = 0, },{ @@ -279,7 +312,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_PROLINK_PLAYTVPVR] = { .name = "Prolink PlayTV PVR", - .tuner_type = 43, + .tuner_type = TUNER_PHILIPS_FM1236_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -301,8 +337,11 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_ASUS_PVR_416] = { .name = "ASUS PVR-416", - .tuner_type = 43, - .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_PHILIPS_FM1236_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -320,7 +359,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_MSI_TVANYWHERE] = { .name = "MSI TV-@nywhere", - .tuner_type = 33, + .tuner_type = TUNER_MT2032, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -342,6 +384,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_KWORLD_DVB_T] = { .name = "KWorld/VStream XPert DVB-T", .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, @@ -358,6 +403,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { .name = "DVICO FusionHDTV DVB-T1", .tuner_type = TUNER_ABSENT, /* No analog tuner */ + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, @@ -371,7 +419,10 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_KWORLD_LTV883] = { .name = "KWorld LTV883RF", - .tuner_type = 48, + .tuner_type = TUNER_TNF_8831BGFF, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -397,6 +448,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = { .name = "DViCO - FusionHDTV 3 Gold", .tuner_type = TUNER_MICROTUNE_4042FI5, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, /* GPIO[0] resets DT3302 DTV receiver 0 - reset asserted @@ -429,32 +483,13 @@ struct cx88_board cx88_boards[] = { .gpio0 = 0x0f00, }}, }, - [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { - .name = "DViCO - FusionHDTV 3 Gold-T", - .tuner_type = 60, /* Thomson DDT 7611 ATSC/NTSC */ - /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */ - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x0f0d, - },{ - .type = CX88_VMUX_CABLE, - .vmux = 0, - .gpio0 = 0x0f05, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x0f00, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x0f00, - }}, - }, [CX88_BOARD_HAUPPAUGE_DVB_T1] = { - .name = "Hauppauge Nova-T DVB-T", + .name = "Hauppauge Nova-T DVB-T", .tuner_type = TUNER_ABSENT, - .input = {{ + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .input = {{ .type = CX88_VMUX_DVB, .vmux = 0, }}, @@ -463,6 +498,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_CONEXANT_DVB_T1] = { .name = "Conexant DVB-T reference design", .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_DVB, .vmux = 0, @@ -472,6 +510,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_PROVIDEO_PV259] = { .name = "Provideo PV259", .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -481,6 +522,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = { .name = "DVICO FusionHDTV DVB-T Plus", .tuner_type = TUNER_ABSENT, /* No analog tuner */ + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, @@ -495,6 +539,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_DNTV_LIVE_DVB_T] = { .name = "digitalnow DNTV Live! DVB-T", .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, @@ -511,6 +558,9 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_PCHDTV_HD3000] = { .name = "pcHDTV HD3000 HDTV", .tuner_type = TUNER_THOMSON_DTT7610, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -546,8 +596,11 @@ struct cx88_board cx88_boards[] = { [CX88_BOARD_HAUPPAUGE_ROSLYN] = { // entry added by Kaustubh D. Bhalerao // GPIO values obtained from regspy, courtesy Sean Covel - .name = "Hauppauge WinTV 28xxx (Roslyn) models", - .tuner_type = UNSET, + .name = "Hauppauge WinTV 28xxx (Roslyn) models", + .tuner_type = UNSET, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -575,33 +628,37 @@ struct cx88_board cx88_boards[] = { .blackbird = 1, }, [CX88_BOARD_DIGITALLOGIC_MEC] = { - /* params copied over from Leadtek PVR 2000 */ .name = "Digital-Logic MICROSPACE Entertainment Center (MEC)", - /* not sure yet about the tuner type */ - .tuner_type = 38, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0x0000bde6, + .gpio0 = 0x00009d80, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0x0000bde6, + .gpio0 = 0x00009d76, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0x0000bde6, + .gpio0 = 0x00009d76, }}, .radio = { .type = CX88_RADIO, - .gpio0 = 0x0000bd62, + .gpio0 = 0x00009d00, }, .blackbird = 1, }, [CX88_BOARD_IODATA_GVBCTV7E] = { .name = "IODATA GV/BCTV7E", .tuner_type = TUNER_PHILIPS_FQ1286, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, @@ -619,25 +676,54 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = { .name = "PixelView PlayTV Ultra Pro (Stereo)", - .tuner_type = 38, + /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */ + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = TUNER_TEA5767, + .tuner_addr = 0xc2>>1, + .radio_addr = 0xc0>>1, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0xbf61, // internal decoder + .gpio0 = 0xbf61, /* internal decoder */ },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0xbf63, + .gpio0 = 0xbf63, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0xbf63, + .gpio0 = 0xbf63, }}, .radio = { - .type = CX88_RADIO, - .gpio0 = 0xbf60, - }, + .type = CX88_RADIO, + .gpio0 = 0xbf60, + }, }, + [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { + .name = "DViCO - FusionHDTV 3 Gold-T", + .tuner_type = TUNER_THOMSON_DTT7611, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */ + .input = {{ + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x0f0d, + },{ + .type = CX88_VMUX_CABLE, + .vmux = 0, + .gpio0 = 0x0f05, + },{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x0f00, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x0f00, + }}, + }, }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); @@ -976,4 +1062,5 @@ EXPORT_SYMBOL(cx88_card_setup); * Local variables: * c-basic-offset: 8 * End: + * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */ diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 8c7f5589e92..c046a23537d 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $ + * $Id: cx88-core.c,v 1.28 2005/06/12 04:19:19 mchehab Exp $ * * device driver for Conexant 2388x based TV cards * driver core @@ -51,12 +51,15 @@ module_param(latency,int,0444); MODULE_PARM_DESC(latency,"pci latency timer"); static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; +static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; module_param_array(tuner, int, NULL, 0444); +module_param_array(radio, int, NULL, 0444); module_param_array(card, int, NULL, 0444); MODULE_PARM_DESC(tuner,"tuner type"); +MODULE_PARM_DESC(radio,"radio tuner type"); MODULE_PARM_DESC(card,"card type"); static unsigned int nicam = 0; @@ -429,7 +432,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, /* ------------------------------------------------------------------ */ /* debug helper code */ -static int cx88_risc_decode(u32 risc) +int cx88_risc_decode(u32 risc) { static char *instr[16] = { [ RISC_SYNC >> 28 ] = "sync", @@ -1173,8 +1176,20 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) "insmod option" : "autodetected"); core->tuner_type = tuner[core->nr]; + core->radio_type = radio[core->nr]; if (UNSET == core->tuner_type) core->tuner_type = cx88_boards[core->board].tuner_type; + if (UNSET == core->radio_type) + core->radio_type = cx88_boards[core->board].radio_type; + if (!core->tuner_addr) + core->tuner_addr = cx88_boards[core->board].tuner_addr; + if (!core->radio_addr) + core->radio_addr = cx88_boards[core->board].radio_addr; + + printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", + core->tuner_type, core->tuner_addr<<1, + core->radio_type, core->radio_addr<<1); + core->tda9887_conf = cx88_boards[core->board].tda9887_conf; /* init hardware */ diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 9d15d3d5a2b..1a259c3966c 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $ + * $Id: cx88-dvb.c,v 1.33 2005/06/12 04:19:19 mchehab Exp $ * * device driver for Conexant 2388x based TV cards * MPEG Transport Stream (DVB) routines diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 0725b1288f4..e20adefcfc6 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -1,5 +1,5 @@ /* - $Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $ + $Id: cx88-i2c.c,v 1.23 2005/06/12 04:19:19 mchehab Exp $ cx88-i2c.c -- all the i2c code is here @@ -91,6 +91,7 @@ static int cx8800_bit_getsda(void *data) static int attach_inform(struct i2c_client *client) { + struct tuner_addr tun_addr; struct cx88_core *core = i2c_get_adapdata(client->adapter); dprintk(1, "i2c attach [addr=0x%x,client=%s]\n", @@ -98,8 +99,19 @@ static int attach_inform(struct i2c_client *client) if (!client->driver->command) return 0; - if (core->tuner_type != UNSET) - client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type); + if (core->radio_type != UNSET) { + tun_addr.v4l2_tuner = V4L2_TUNER_RADIO; + tun_addr.type = core->radio_type; + tun_addr.addr = core->radio_addr; + client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr); + } + if (core->tuner_type != UNSET) { + tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV; + tun_addr.type = core->tuner_type; + tun_addr.addr = core->tuner_addr; + client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr); + } + if (core->tda9887_conf) client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); return 0; diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index fbf21dbe251..dc0dcf249aa 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $ + * $Id: cx88-input.c,v 1.11 2005/05/22 20:57:56 nsh Exp $ * * Device driver for GPIO attached remote control interfaces * on Conexant 2388x based TV/DVB cards. @@ -235,6 +235,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) /* detect & configure */ switch (core->board) { case CX88_BOARD_DNTV_LIVE_DVB_T: + case CX88_BOARD_KWORLD_DVB_T: ir_codes = ir_codes_dntv_live_dvb_t; ir->gpio_addr = MO_GP1_IO; ir->mask_keycode = 0x1f; @@ -269,6 +270,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->polling = 1; // ms break; } + if (NULL == ir_codes) { kfree(ir); return -ENODEV; diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 07aae1899e1..9ade2ae91e9 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $ + * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $ * * Support for the mpeg transport stream transfers * PCI function #2 of the cx2388x. @@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, { struct cx88_core *core = dev->core; - dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width); + dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], @@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev, q->count = 1; /* enable irqs */ + dprintk( 0, "setting the interrupt mask\n" ); cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); - cx_write(MO_TS_INTMSK, 0x1f0011); + cx_set(MO_TS_INTMSK, 0x1f0011); + //cx_write(MO_TS_INTMSK, 0x0f0011); /* start dma */ - cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ - cx_write(MO_TS_DMACNTRL, 0x11); + cx_set(MO_DEV_CNTRL2, (1<<5)); + cx_set(MO_TS_DMACNTRL, 0x11); return 0; } static int cx8802_stop_dma(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; + dprintk( 0, "cx8802_stop_dma\n" ); /* stop dma */ cx_clear(MO_TS_DMACNTRL, 0x11); @@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, struct cx88_buffer *buf; struct list_head *item; + dprintk( 0, "cx8802_restart_queue\n" ); if (list_empty(&q->active)) + { + dprintk( 0, "cx8802_restart_queue: queue is empty\n" ); return 0; + } buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); dprintk(2,"restart_queue [%p/%d]: restart dma\n", @@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) struct cx88_buffer *prev; struct cx88_dmaqueue *q = &dev->mpegq; + dprintk( 1, "cx8802_buf_queue\n" ); /* add jump to stopper */ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); if (list_empty(&q->active)) { + dprintk( 0, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue,&q->active); cx8802_start_dma(dev, q, buf); buf->vb.state = STATE_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2,"[%p/%d] %s - first active\n", + dprintk(0,"[%p/%d] %s - first active\n", buf, buf->vb.i, __FUNCTION__); + //udelay(100); } else { + dprintk( 1, "queue is not empty - append to active\n" ); prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); list_add_tail(&buf->vb.queue,&q->active); buf->vb.state = STATE_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(2,"[%p/%d] %s - append to active\n", + dprintk( 1, "[%p/%d] %s - append to active\n", buf, buf->vb.i, __FUNCTION__); + //udelay(100); } } @@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); } if (restart) + { + dprintk(0, "restarting queue\n" ); cx8802_restart_queue(dev,q); + } spin_unlock_irqrestore(&dev->slock,flags); } @@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev) { struct cx88_dmaqueue *q = &dev->mpegq; + dprintk( 1, "cx8802_cancel_buffers" ); del_timer_sync(&q->timeout); cx8802_stop_dma(dev); do_cancel_buffers(dev,"cancel",0); @@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data) { struct cx8802_dev *dev = (struct cx8802_dev*)data; - dprintk(1, "%s\n",__FUNCTION__); + dprintk(0, "%s\n",__FUNCTION__); if (debug) cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); @@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) struct cx88_core *core = dev->core; u32 status, mask, count; + dprintk( 1, "cx8802_mpeg_irq\n" ); status = cx_read(MO_TS_INTSTAT); mask = cx_read(MO_TS_INTMSK); if (0 == (status & mask)) return; cx_write(MO_TS_INTSTAT, status); +#if 0 + cx88_print_irqbits(core->name, "irq mpeg ", + cx88_mpeg_irqs, status, mask); +#endif if (debug || (status & mask & ~0xff)) cx88_print_irqbits(core->name, "irq mpeg ", cx88_mpeg_irqs, status, mask); @@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) /* risc1 y */ if (status & 0x01) { + dprintk( 1, "wake up\n" ); spin_lock(&dev->slock); count = cx_read(MO_TS_GPCNT); cx88_wakeup(dev->core, &dev->mpegq, count); @@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) /* other general errors */ if (status & 0x1f0100) { + dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); spin_lock(&dev->slock); cx8802_stop_dma(dev); cx8802_restart_queue(dev,&dev->mpegq); @@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) } } +#define MAX_IRQ_LOOP 10 + static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) { struct cx8802_dev *dev = dev_id; @@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) u32 status; int loop, handled = 0; - for (loop = 0; loop < 10; loop++) { + for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); if (0 == status) goto out; + dprintk( 1, "cx8802_irq\n" ); + dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP ); + dprintk( 1, " status: %d\n", status ); handled = 1; cx_write(MO_PCI_INTSTAT, status); @@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) if (status & 0x04) cx8802_mpeg_irq(dev); }; - if (10 == loop) { + if (MAX_IRQ_LOOP == loop) { + dprintk( 0, "clearing mask\n" ); printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", core->name); cx_write(MO_PCI_INTMSK,0); @@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev) void cx8802_fini_common(struct cx8802_dev *dev) { + dprintk( 2, "cx8802_fini_common\n" ); cx8802_stop_dma(dev); pci_disable_device(dev->pci); @@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) /* stop mpeg dma */ spin_lock(&dev->slock); if (!list_empty(&dev->mpegq.active)) { + dprintk( 2, "suspend\n" ); printk("%s: suspend mpeg\n", core->name); cx8802_stop_dma(dev); del_timer(&dev->mpegq.timeout); @@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common); * Local variables: * c-basic-offset: 8 * End: + * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */ diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h index 8638ce57d84..63ad33f5818 100644 --- a/drivers/media/video/cx88/cx88-reg.h +++ b/drivers/media/video/cx88/cx88-reg.h @@ -1,5 +1,5 @@ /* - $Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $ + $Id: cx88-reg.h,v 1.7 2005/06/03 13:31:51 mchehab Exp $ cx88x-hw.h - CX2388x register offsets @@ -397,6 +397,7 @@ #define AUD_RATE_ADJ4 0x3205e4 #define AUD_RATE_ADJ5 0x3205e8 #define AUD_APB_IN_RATE_ADJ 0x3205ec +#define AUD_I2SCNTL 0x3205ec #define AUD_PHASE_FIX_CTL 0x3205f0 #define AUD_PLL_PRESCALE 0x320600 #define AUD_PLL_DDS 0x320604 diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index f2a9475a2fe..46d78b1dc9b 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -1,5 +1,5 @@ /* - $Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $ + $Id: cx88-tvaudio.c,v 1.36 2005/06/05 05:53:45 mchehab Exp $ cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver @@ -127,7 +127,8 @@ static void set_audio_start(struct cx88_core *core, cx_write(AUD_VOL_CTL, (1 << 6)); // increase level of input by 12dB - cx_write(AUD_AFE_12DB_EN, 0x0001); +// cx_write(AUD_AFE_12DB_EN, 0x0001); + cx_write(AUD_AFE_12DB_EN, 0x0000); // start programming cx_write(AUD_CTL, 0x0000); @@ -143,9 +144,15 @@ static void set_audio_finish(struct cx88_core *core) u32 volume; if (cx88_boards[core->board].blackbird) { + // sets sound input from external adc + cx_set(AUD_CTL, EN_I2SIN_ENABLE); + //cx_write(AUD_I2SINPUTCNTL, 0); + cx_write(AUD_I2SINPUTCNTL, 4); + cx_write(AUD_BAUDRATE, 1); // 'pass-thru mode': this enables the i2s output to the mpeg encoder - cx_set(AUD_CTL, 0x2000); + cx_set(AUD_CTL, EN_I2SOUT_ENABLE); cx_write(AUD_I2SOUTPUTCNTL, 1); + cx_write(AUD_I2SCNTL, 0); //cx_write(AUD_APB_IN_RATE_ADJ, 0); } @@ -707,50 +714,65 @@ static void set_audio_standard_EIAJ(struct cx88_core *core) set_audio_finish(core); } -static void set_audio_standard_FM(struct cx88_core *core) +static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) { -#if 0 /* FIXME */ - switch (dev->audio_properties.FM_deemphasis) - { - case WW_FM_DEEMPH_50: - //Set De-emphasis filter coefficients for 50 usec - cx_write(AUD_DEEMPH0_G0, 0x0C45); - cx_write(AUD_DEEMPH0_A0, 0x6262); - cx_write(AUD_DEEMPH0_B0, 0x1C29); - cx_write(AUD_DEEMPH0_A1, 0x3FC66); - cx_write(AUD_DEEMPH0_B1, 0x399A); - - cx_write(AUD_DEEMPH1_G0, 0x0D80); - cx_write(AUD_DEEMPH1_A0, 0x6262); - cx_write(AUD_DEEMPH1_B0, 0x1C29); - cx_write(AUD_DEEMPH1_A1, 0x3FC66); - cx_write(AUD_DEEMPH1_B1, 0x399A); + static const struct rlist fm_deemph_50[] = { + { AUD_DEEMPH0_G0, 0x0C45 }, + { AUD_DEEMPH0_A0, 0x6262 }, + { AUD_DEEMPH0_B0, 0x1C29 }, + { AUD_DEEMPH0_A1, 0x3FC66}, + { AUD_DEEMPH0_B1, 0x399A }, + + { AUD_DEEMPH1_G0, 0x0D80 }, + { AUD_DEEMPH1_A0, 0x6262 }, + { AUD_DEEMPH1_B0, 0x1C29 }, + { AUD_DEEMPH1_A1, 0x3FC66}, + { AUD_DEEMPH1_B1, 0x399A}, + + { AUD_POLYPH80SCALEFAC, 0x0003}, + { /* end of list */ }, + }; + static const struct rlist fm_deemph_75[] = { + { AUD_DEEMPH0_G0, 0x091B }, + { AUD_DEEMPH0_A0, 0x6B68 }, + { AUD_DEEMPH0_B0, 0x11EC }, + { AUD_DEEMPH0_A1, 0x3FC66}, + { AUD_DEEMPH0_B1, 0x399A }, + + { AUD_DEEMPH1_G0, 0x0AA0 }, + { AUD_DEEMPH1_A0, 0x6B68 }, + { AUD_DEEMPH1_B0, 0x11EC }, + { AUD_DEEMPH1_A1, 0x3FC66}, + { AUD_DEEMPH1_B1, 0x399A}, + + { AUD_POLYPH80SCALEFAC, 0x0003}, + { /* end of list */ }, + }; - break; + /* It is enough to leave default values? */ + static const struct rlist fm_no_deemph[] = { - case WW_FM_DEEMPH_75: - //Set De-emphasis filter coefficients for 75 usec - cx_write(AUD_DEEMPH0_G0, 0x91B ); - cx_write(AUD_DEEMPH0_A0, 0x6B68); - cx_write(AUD_DEEMPH0_B0, 0x11EC); - cx_write(AUD_DEEMPH0_A1, 0x3FC66); - cx_write(AUD_DEEMPH0_B1, 0x399A); + { AUD_POLYPH80SCALEFAC, 0x0003}, + { /* end of list */ }, + }; - cx_write(AUD_DEEMPH1_G0, 0xAA0 ); - cx_write(AUD_DEEMPH1_A0, 0x6B68); - cx_write(AUD_DEEMPH1_B0, 0x11EC); - cx_write(AUD_DEEMPH1_A1, 0x3FC66); - cx_write(AUD_DEEMPH1_B1, 0x399A); + dprintk("%s (status: unknown)\n",__FUNCTION__); + set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO); + switch (deemph) + { + case FM_NO_DEEMPH: + set_audio_registers(core, fm_no_deemph); break; - } -#endif - dprintk("%s (status: unknown)\n",__FUNCTION__); - set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO); + case FM_DEEMPH_50: + set_audio_registers(core, fm_deemph_50); + break; - // AB: 10/2/01: this register is not being reset appropriately on occasion. - cx_write(AUD_POLYPH80SCALEFAC,3); + case FM_DEEMPH_75: + set_audio_registers(core, fm_deemph_75); + break; + } set_audio_finish(core); } @@ -778,7 +800,7 @@ void cx88_set_tvaudio(struct cx88_core *core) set_audio_standard_EIAJ(core); break; case WW_FM: - set_audio_standard_FM(core); + set_audio_standard_FM(core,FM_NO_DEEMPH); break; case WW_SYSTEM_L_AM: set_audio_standard_NICAM_L(core, 1); @@ -1029,4 +1051,5 @@ EXPORT_SYMBOL(cx88_audio_thread); * Local variables: * c-basic-offset: 8 * End: + * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */ diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index 0584ff47638..320d57888bb 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $ + * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $ */ #include #include @@ -47,8 +47,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f) } static int cx8800_start_vbi_dma(struct cx8800_dev *dev, - struct cx88_dmaqueue *q, - struct cx88_buffer *buf) + struct cx88_dmaqueue *q, + struct cx88_buffer *buf) { struct cx88_core *core = dev->core; diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d1f5c92f0ce..e4ca7350df1 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $ + * $Id: cx88-video.c,v 1.63 2005/06/12 04:19:19 mchehab Exp $ * * device driver for Conexant 2388x based TV cards * video4linux video interface @@ -1187,9 +1187,24 @@ static void init_controls(struct cx8800_dev *dev) .id = V4L2_CID_AUDIO_VOLUME, .value = 0x3f, }; + static struct v4l2_control hue = { + .id = V4L2_CID_HUE, + .value = 0x80, + }; + static struct v4l2_control contrast = { + .id = V4L2_CID_CONTRAST, + .value = 0x80, + }; + static struct v4l2_control brightness = { + .id = V4L2_CID_BRIGHTNESS, + .value = 0x80, + }; set_control(dev,&mute); set_control(dev,&volume); + set_control(dev,&hue); + set_control(dev,&contrast); + set_control(dev,&brightness); } /* ------------------------------------------------------------------ */ @@ -1335,6 +1350,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_VBI_CAPTURE | +#if 0 + V4L2_TUNER_CAP_LOW | +#endif #if 0 V4L2_CAP_VIDEO_OVERLAY | #endif @@ -1696,7 +1714,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, sizeof(cap->card)); sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); cap->version = CX88_VERSION_CODE; - cap->capabilities = V4L2_CAP_TUNER; + cap->capabilities = V4L2_CAP_TUNER +#if 0 + | V4L2_TUNER_CAP_LOW +#endif + ; return 0; } case VIDIOC_G_TUNER: @@ -1992,6 +2014,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, { struct cx8800_dev *dev; struct cx88_core *core; + struct tuner_addr tun_addr; int err; dev = kmalloc(sizeof(*dev),GFP_KERNEL); @@ -2065,8 +2088,19 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, request_module("tuner"); if (core->tda9887_conf) request_module("tda9887"); - if (core->tuner_type != UNSET) - cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type); + if (core->radio_type != UNSET) { + tun_addr.v4l2_tuner = V4L2_TUNER_RADIO; + tun_addr.type = core->radio_type; + tun_addr.addr = core->radio_addr; + cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr); + } + if (core->tuner_type != UNSET) { + tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV; + tun_addr.type = core->tuner_type; + tun_addr.addr = core->tuner_addr; + cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr); + } + if (core->tda9887_conf) cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf); @@ -2162,7 +2196,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) { - struct cx8800_dev *dev = pci_get_drvdata(pci_dev); + struct cx8800_dev *dev = pci_get_drvdata(pci_dev); struct cx88_core *core = dev->core; /* stop video+vbi capture */ @@ -2194,7 +2228,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) static int cx8800_resume(struct pci_dev *pci_dev) { - struct cx8800_dev *dev = pci_get_drvdata(pci_dev); + struct cx8800_dev *dev = pci_get_drvdata(pci_dev); struct cx88_core *core = dev->core; if (dev->state.disabled) { @@ -2230,8 +2264,8 @@ static struct pci_device_id cx8800_pci_tbl[] = { { .vendor = 0x14f1, .device = 0x8800, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, },{ /* --- end of list --- */ } @@ -2239,10 +2273,10 @@ static struct pci_device_id cx8800_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl); static struct pci_driver cx8800_pci_driver = { - .name = "cx8800", - .id_table = cx8800_pci_tbl, - .probe = cx8800_initdev, - .remove = __devexit_p(cx8800_finidev), + .name = "cx8800", + .id_table = cx8800_pci_tbl, + .probe = cx8800_initdev, + .remove = __devexit_p(cx8800_finidev), .suspend = cx8800_suspend, .resume = cx8800_resume, @@ -2274,4 +2308,5 @@ module_exit(cx8800_fini); * Local variables: * c-basic-offset: 8 * End: + * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */ diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 80ddf9911e2..ac0dc27bb38 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -1,5 +1,5 @@ /* - * $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $ + * $Id: cx88.h,v 1.62 2005/06/12 04:19:19 mchehab Exp $ * * v4l2 device driver for cx2388x based TV cards * @@ -64,6 +64,13 @@ #define SHADOW_AUD_BAL_CTL 2 #define SHADOW_MAX 2 +/* FM Radio deemphasis type */ +enum cx88_deemph_type { + FM_NO_DEEMPH = 0, + FM_DEEMPH_50, + FM_DEEMPH_75 +}; + /* ----------------------------------------------------------- */ /* tv norms */ @@ -163,7 +170,7 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_DIGITALLOGIC_MEC 25 #define CX88_BOARD_IODATA_GVBCTV7E 26 #define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27 -#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 +#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -187,6 +194,9 @@ struct cx88_input { struct cx88_board { char *name; unsigned int tuner_type; + unsigned int radio_type; + unsigned char tuner_addr; + unsigned char radio_addr; int tda9887_conf; struct cx88_input input[8]; struct cx88_input radio; @@ -257,6 +267,9 @@ struct cx88_core { /* config info -- analog */ unsigned int board; unsigned int tuner_type; + unsigned int radio_type; + unsigned char tuner_addr; + unsigned char radio_addr; unsigned int tda9887_conf; unsigned int has_radio; @@ -422,6 +435,7 @@ struct cx8802_dev { /* ----------------------------------------------------------- */ /* cx88-core.c */ +extern char *cx88_pci_irqs[32]; extern char *cx88_vid_irqs[32]; extern char *cx88_mpeg_irqs[32]; extern void cx88_print_irqbits(char *name, char *tag, char **strings, @@ -473,6 +487,11 @@ extern void cx88_core_put(struct cx88_core *core, /* cx88-vbi.c */ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); +/* +int cx8800_start_vbi_dma(struct cx8800_dev *dev, + struct cx88_dmaqueue *q, + struct cx88_buffer *buf); +*/ int cx8800_stop_vbi_dma(struct cx8800_dev *dev); int cx8800_restart_vbi_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q); diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c index a9d4b2ad14e..a565823330a 100644 --- a/drivers/media/video/ir-kbd-gpio.c +++ b/drivers/media/video/ir-kbd-gpio.c @@ -1,5 +1,5 @@ /* - * $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $ + * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $ * * Copyright (c) 2003 Gerd Knorr * Copyright (c) 2003 Pavel Machek -- cgit v1.2.3-70-g09d2 From 56fc08ca375491b965cb76fad65bfb98973e80d8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:05:07 -0700 Subject: [PATCH] v4l: update for tuner cards and some V4L chips Tuner improvements and additions. TEA5767 FM tuner added. Several small fixes. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Nickolay V Shmyrev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/common/ir-common.c | 39 ++++--- drivers/media/video/bt832.c | 50 +++++---- drivers/media/video/bt832.h | 36 +++---- drivers/media/video/msp3400.c | 13 +-- drivers/media/video/msp3400.h | 4 + drivers/media/video/tda7432.c | 1 + drivers/media/video/tda9875.c | 1 + drivers/media/video/tda9887.c | 41 ++++++- drivers/media/video/tuner-core.c | 212 +++++++++++++++++++++++++------------ drivers/media/video/tuner-simple.c | 52 +++++---- drivers/media/video/tvaudio.c | 2 +- drivers/media/video/tvmixer.c | 4 + include/media/audiochip.h | 4 + include/media/id.h | 4 + include/media/ir-common.h | 2 +- include/media/tuner.h | 23 +++- 16 files changed, 333 insertions(+), 155 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index e5636ef181b..4adb2843f8b 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c @@ -1,5 +1,5 @@ /* - * $Id: ir-common.c,v 1.8 2005/02/22 12:28:40 kraxel Exp $ + * $Id: ir-common.c,v 1.10 2005/05/22 19:23:39 nsh Exp $ * * some common structs and functions to handle infrared remotes via * input layer ... @@ -131,10 +131,10 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { [ 18 ] = KEY_KP0, [ 0 ] = KEY_POWER, - [ 27 ] = KEY_LANGUAGE, //MTS button +// [ 27 ] = MTS button [ 2 ] = KEY_TUNER, // TV/FM [ 30 ] = KEY_VIDEO, - [ 22 ] = KEY_INFO, //display button +// [ 22 ] = display button [ 4 ] = KEY_VOLUMEUP, [ 8 ] = KEY_VOLUMEDOWN, [ 12 ] = KEY_CHANNELUP, @@ -142,7 +142,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { [ 3 ] = KEY_ZOOM, // fullscreen [ 31 ] = KEY_SUBTITLE, // closed caption/teletext [ 32 ] = KEY_SLEEP, - [ 41 ] = KEY_SEARCH, //boss key +// [ 41 ] = boss key [ 20 ] = KEY_MUTE, [ 43 ] = KEY_RED, [ 44 ] = KEY_GREEN, @@ -150,17 +150,17 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { [ 46 ] = KEY_BLUE, [ 24 ] = KEY_KPPLUS, //fine tune + [ 25 ] = KEY_KPMINUS, //fine tune - - [ 42 ] = KEY_ANGLE, //picture in picture - [ 33 ] = KEY_KPDOT, +// [ 42 ] = picture in picture + [ 33 ] = KEY_KPDOT, [ 19 ] = KEY_KPENTER, - [ 17 ] = KEY_AGAIN, //recall +// [ 17 ] = recall [ 34 ] = KEY_BACK, [ 35 ] = KEY_PLAYPAUSE, [ 36 ] = KEY_NEXT, - [ 37 ] = KEY_T, //time shifting +// [ 37 ] = time shifting [ 38 ] = KEY_STOP, - [ 39 ] = KEY_RECORD, - [ 40 ] = KEY_SHUFFLE //snapshot + [ 39 ] = KEY_RECORD +// [ 40 ] = snapshot }; EXPORT_SYMBOL_GPL(ir_codes_winfast); @@ -184,18 +184,30 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { [ 0x07 ] = KEY_KP7, // 7 [ 0x08 ] = KEY_KP8, // 8 [ 0x09 ] = KEY_KP9, // 9 + [ 0x0a ] = KEY_TEXT, // keypad asterisk as well [ 0x0b ] = KEY_RED, // red button - [ 0x0c ] = KEY_OPTION, // black key without text + [ 0x0c ] = KEY_RADIO, // radio [ 0x0d ] = KEY_MENU, // menu + [ 0x0e ] = KEY_SUBTITLE, // also the # key [ 0x0f ] = KEY_MUTE, // mute [ 0x10 ] = KEY_VOLUMEUP, // volume + [ 0x11 ] = KEY_VOLUMEDOWN, // volume - - [ 0x1e ] = KEY_NEXT, // skip >| + [ 0x12 ] = KEY_PREVIOUS, // previous channel + [ 0x14 ] = KEY_UP, // up + [ 0x15 ] = KEY_DOWN, // down + [ 0x16 ] = KEY_LEFT, // left + [ 0x17 ] = KEY_RIGHT, // right + [ 0x18 ] = KEY_VIDEO, // Videos + [ 0x19 ] = KEY_AUDIO, // Music + [ 0x1a ] = KEY_MHP, // Pictures - presume this means "Multimedia Home Platform"- no "PICTURES" key in input.h + [ 0x1b ] = KEY_EPG, // Guide + [ 0x1c ] = KEY_TV, // TV + [ 0x1e ] = KEY_NEXTSONG, // skip >| [ 0x1f ] = KEY_EXIT, // back/exit [ 0x20 ] = KEY_CHANNELUP, // channel / program + [ 0x21 ] = KEY_CHANNELDOWN, // channel / program - [ 0x22 ] = KEY_CHANNEL, // source (old black remote) - [ 0x24 ] = KEY_PREVIOUS, // replay |< + [ 0x24 ] = KEY_PREVIOUSSONG, // replay |< [ 0x25 ] = KEY_ENTER, // OK [ 0x26 ] = KEY_SLEEP, // minimize (old black remote) [ 0x29 ] = KEY_BLUE, // blue key @@ -412,3 +424,4 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase); * c-basic-offset: 8 * End: */ + diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 07f72f64c5f..3bb347d93b9 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c @@ -6,7 +6,7 @@ It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly connected to bt848/bt878 GPIO pins on this purpose. (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets) - + Supported Cards: - Pixelview Rev.4E: 0x8a GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 ! @@ -31,16 +31,16 @@ #include #include -#include "id.h" -#include "audiochip.h" +#include +#include #include "bttv.h" #include "bt832.h" MODULE_LICENSE("GPL"); /* Addresses to scan */ -static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1, - I2C_CLIENT_END }; +static unsigned short normal_i2c[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {I2C_BT832_ALT1>>1,I2C_BT832_ALT2>>1,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* ---------------------------------------------------------------------- */ @@ -95,7 +95,7 @@ int bt832_init(struct i2c_client *i2c_client_s) buf=kmalloc(65,GFP_KERNEL); bt832_hexdump(i2c_client_s,buf); - + if(buf[0x40] != 0x31) { printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); kfree(buf); @@ -135,7 +135,7 @@ int bt832_init(struct i2c_client *i2c_client_s) buf[1]= 0x27 & (~0x01); // Default | !skip if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); - + bt832_hexdump(i2c_client_s,buf); #if 0 @@ -168,8 +168,7 @@ int bt832_init(struct i2c_client *i2c_client_s) -static int bt832_attach(struct i2c_adapter *adap, int addr, - unsigned short flags, int kind) +static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) { struct bt832 *t; @@ -184,27 +183,32 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, return -ENOMEM; memset(t,0,sizeof(*t)); t->client = client_template; - t->client.data = t; + i2c_set_clientdata(&t->client, t); i2c_attach_client(&t->client); if(! bt832_init(&t->client)) { bt832_detach(&t->client); return -1; } - + return 0; } static int bt832_probe(struct i2c_adapter *adap) { +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, bt832_attach); +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) + return i2c_probe(adap, &addr_data, bt832_attach); +#endif return 0; } static int bt832_detach(struct i2c_client *client) { - struct bt832 *t = (struct bt832*)client->data; + struct bt832 *t = i2c_get_clientdata(client); printk("bt832: detach.\n"); i2c_detach_client(client); @@ -215,7 +219,7 @@ static int bt832_detach(struct i2c_client *client) static int bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct bt832 *t = (struct bt832*)client->data; + struct bt832 *t = i2c_get_clientdata(client); printk("bt832: command %x\n",cmd); @@ -249,19 +253,18 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - .name = "bt832", - .flags = I2C_CLIENT_ALLOW_USE, - .driver = &driver, + I2C_DEVNAME("bt832"), + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; -int bt832_init_module(void) +static int __init bt832_init_module(void) { - i2c_add_driver(&driver); - return 0; + return i2c_add_driver(&driver); } -static void bt832_cleanup_module(void) +static void __exit bt832_cleanup_module(void) { i2c_del_driver(&driver); } @@ -269,3 +272,10 @@ static void bt832_cleanup_module(void) module_init(bt832_init_module); module_exit(bt832_cleanup_module); +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h index 7a98c06e0e3..9b6a8d2c96b 100644 --- a/drivers/media/video/bt832.h +++ b/drivers/media/video/bt832.h @@ -1,6 +1,6 @@ /* Bt832 CMOS Camera Video Processor (VP) - The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS + The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS color digital camera directly to video capture devices via an 8-bit, 4:2:2 YUV or YCrCb video interface. @@ -85,7 +85,7 @@ #define BT832_DEVICE_ID 63 # define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31 -/* STMicroelectronivcs VV5404 camera module +/* STMicroelectronivcs VV5404 camera module i2c: 0x20: sensor address i2c: 0xa0: eeprom for ccd defect map */ @@ -256,26 +256,26 @@ For the CCIR-601 standards, the sampling is based on a static orthogonal samplin //=========================================================================== // Timing generator SRAM table values for CCIR601 720x480 NTSC //=========================================================================== -// For NTSC CCIR656 +// For NTSC CCIR656 BYTE BtCard::SRAMTable_NTSC[] = { // SRAM Timing Table for NTSC - 0x0c, 0xc0, 0x00, - 0x00, 0x90, 0xc2, - 0x03, 0x10, 0x03, - 0x06, 0x10, 0x34, - 0x12, 0x12, 0x65, - 0x02, 0x13, 0x24, - 0x19, 0x00, 0x24, - 0x39, 0x00, 0x96, - 0x59, 0x08, 0x93, + 0x0c, 0xc0, 0x00, + 0x00, 0x90, 0xc2, + 0x03, 0x10, 0x03, + 0x06, 0x10, 0x34, + 0x12, 0x12, 0x65, + 0x02, 0x13, 0x24, + 0x19, 0x00, 0x24, + 0x39, 0x00, 0x96, + 0x59, 0x08, 0x93, 0x83, 0x08, 0x97, - 0x03, 0x50, 0x30, - 0xc0, 0x40, 0x30, - 0x86, 0x01, 0x01, - 0xa6, 0x0d, 0x62, - 0x03, 0x11, 0x61, - 0x05, 0x37, 0x30, + 0x03, 0x50, 0x30, + 0xc0, 0x40, 0x30, + 0x86, 0x01, 0x01, + 0xa6, 0x0d, 0x62, + 0x03, 0x11, 0x61, + 0x05, 0x37, 0x30, 0xac, 0x21, 0x50 }; diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 09464d624a6..05b83faa9a0 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -147,6 +147,7 @@ static unsigned short normal_i2c[] = { I2C_MSP3400C_ALT >> 1, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -735,7 +736,6 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout) { DECLARE_WAITQUEUE(wait, current); -again: add_wait_queue(&msp->wq, &wait); if (!kthread_should_stop()) { if (timeout < 0) { @@ -751,12 +751,9 @@ again: #endif } } - + if (current->flags & PF_FREEZE) + refrigerator(PF_FREEZE); remove_wait_queue(&msp->wq, &wait); - - if (try_to_freeze(PF_FREEZE)) - goto again; - return msp->restart; } @@ -1436,7 +1433,7 @@ static int msp_detach(struct i2c_client *client); static int msp_probe(struct i2c_adapter *adap); static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); -static int msp_suspend(struct device * dev, pm_message_t state, u32 level); +static int msp_suspend(struct device * dev, u32 state, u32 level); static int msp_resume(struct device * dev, u32 level); static void msp_wake_thread(struct i2c_client *client); @@ -1841,7 +1838,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int msp_suspend(struct device * dev, pm_message_t state, u32 level) +static int msp_suspend(struct device * dev, u32 state, u32 level) { struct i2c_client *c = container_of(dev, struct i2c_client, dev); diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h index d70a954e13a..023f33056a4 100644 --- a/drivers/media/video/msp3400.h +++ b/drivers/media/video/msp3400.h @@ -1,3 +1,7 @@ +/* + * $Id: msp3400.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $ + */ + #ifndef MSP3400_H #define MSP3400_H diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 07ba6d3ed08..376a4a439e9 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -74,6 +74,7 @@ static unsigned short normal_i2c[] = { I2C_TDA7432 >> 1, I2C_CLIENT_END, }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* Structure of address and subaddresses for the tda7432 */ diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 97b113e070f..4f1114c033a 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -44,6 +44,7 @@ static unsigned short normal_i2c[] = { I2C_TDA9875 >> 1, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 7e6e6dd966a..33d6ee6cde4 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -33,6 +33,7 @@ static unsigned short normal_i2c[] = { 0x96 >>1, I2C_CLIENT_END, }; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* insmod options */ @@ -53,6 +54,7 @@ struct tda9887 { unsigned int config; unsigned int pinnacle_id; unsigned int using_v4l2; + unsigned int radio_mode; }; struct tvnorm { @@ -212,12 +214,22 @@ static struct tvnorm tvnorms[] = { } }; -static struct tvnorm radio = { - .name = "radio", +static struct tvnorm radio_stereo = { + .name = "Radio Stereo", + .b = ( cFmRadio | + cQSS ), + .c = ( cDeemphasisOFF | + cAudioGain6 ), + .e = ( cAudioIF_5_5 | + cRadioIF_38_90 ), +}; + +static struct tvnorm radio_mono = { + .name = "Radio Mono", .b = ( cFmRadio | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 ), + cDeemphasis50), .e = ( cAudioIF_5_5 | cRadioIF_38_90 ), }; @@ -354,7 +366,10 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) int i; if (t->radio) { - norm = &radio; + if (t->radio_mode == V4L2_TUNER_MODE_MONO) + norm = &radio_mono; + else + norm = &radio_stereo; } else { for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { if (tvnorms[i].std & t->std) { @@ -545,11 +560,14 @@ static int tda9887_configure(struct tda9887 *t) memset(buf,0,sizeof(buf)); tda9887_set_tvnorm(t,buf); + buf[1] |= cOutputPort1Inactive; buf[1] |= cOutputPort2Inactive; + if (UNSET != t->pinnacle_id) { tda9887_set_pinnacle(t,buf); } + tda9887_set_config(t,buf); tda9887_set_insmod(t,buf); @@ -592,9 +610,12 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) return -ENOMEM; memset(t,0,sizeof(*t)); + t->client = client_template; t->std = 0; t->pinnacle_id = UNSET; + t->radio_mode = V4L2_TUNER_MODE_STEREO; + i2c_set_clientdata(&t->client, t); i2c_attach_client(&t->client); @@ -733,6 +754,16 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) } break; } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner* tuner = arg; + + if (t->radio) { + t->radio_mode = tuner->audmode; + tda9887_configure (t); + } + break; + } default: /* nothing */ break; @@ -740,7 +771,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level) +static int tda9887_suspend(struct device * dev, u32 state, u32 level) { dprintk("tda9887: suspend\n"); return 0; diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 71423ae3b4d..ba13bfadb52 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-core.c,v 1.7 2005/05/30 02:02:47 mchehab Exp $ + * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $ * * i2c tv tuner chip device driver * core core, i.e. kernel interfaces, registering and so on @@ -26,15 +26,17 @@ /* * comment line bellow to return to old behavor, where only one I2C device is supported */ -/* #define CONFIG_TUNER_MULTI_I2C */ +#define CONFIG_TUNER_MULTI_I2C /**/ #define UNSET (-1U) /* standard i2c insmod options */ static unsigned short normal_i2c[] = { 0x4b, /* tda8290 */ - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + I2C_CLIENT_END +}; +static unsigned short normal_i2c_range[] = { + 0x60, 0x6f, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; @@ -59,7 +61,7 @@ MODULE_LICENSE("GPL"); static int this_adap; #ifdef CONFIG_TUNER_MULTI_I2C -static unsigned short tv_tuner, radio_tuner; +static unsigned short first_tuner, tv_tuner, radio_tuner; #endif static struct i2c_driver driver; @@ -67,7 +69,7 @@ static struct i2c_client client_template; /* ---------------------------------------------------------------------- */ -// Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz +/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */ static void set_tv_freq(struct i2c_client *c, unsigned int freq) { struct tuner *t = i2c_get_clientdata(c); @@ -81,14 +83,26 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) return; } if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { - /* FIXME: better do that chip-specific, but - right now we don't have that in the config - struct and this way is still better than no - check at all */ - tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", - freq/16,freq%16*100/16,tv_range[0],tv_range[1]); - return; + + if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { + /* V4L2_TUNER_CAP_LOW frequency */ + + tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n"); + + t->tv_freq(c,freq>>10); + + return; + } else { + /* FIXME: better do that chip-specific, but + right now we don't have that in the config + struct and this way is still better than no + check at all */ + tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", + freq/16,freq%16*100/16,tv_range[0],tv_range[1]); + return; + } } + tuner_dbg("62.5 Khz freq step selected for TV.\n"); t->tv_freq(c,freq); } @@ -105,11 +119,29 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) return; } if (freq < radio_range[0]*16 || freq > radio_range[1]*16) { - tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", + if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { + /* V4L2_TUNER_CAP_LOW frequency */ + if (t->type == TUNER_TEA5767) { + tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); + t->radio_freq(c,freq>>10); + return; + } + + tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n"); + + tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); + + t->radio_freq(c,freq>>10); + return; + + } else { + tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", freq/16,freq%16*100/16, - radio_range[0],radio_range[1]); - return; + radio_range[0],radio_range[1]); + return; + } } + tuner_dbg("62.5 Khz freq step selected for Radio.\n"); t->radio_freq(c,freq); } @@ -133,34 +165,13 @@ static void set_freq(struct i2c_client *c, unsigned long freq) t->freq = freq; } -#ifdef CONFIG_TUNER_MULTI_I2C -static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) -{ - struct tuner *t = i2c_get_clientdata(c); - - switch (tun_addr->type) { - case V4L2_TUNER_RADIO: - radio_tuner=tun_addr->addr; - tuner_dbg("radio tuner set to I2C address 0x%02x\n",radio_tuner<<1); - - break; - default: - tv_tuner=tun_addr->addr; - tuner_dbg("TV tuner set to I2C address 0x%02x\n",tv_tuner<<1); - break; - } -} -#else -#define set_addr(c,tun_addr) \ - tuner_warn("It is recommended to enable CONFIG_TUNER_MULTI_I2C for this card.\n"); -#endif - static void set_type(struct i2c_client *c, unsigned int type) { struct tuner *t = i2c_get_clientdata(c); + tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); /* sanity check */ - if (type == UNSET || type == TUNER_ABSENT) + if (type == UNSET || type == TUNER_ABSENT) return; if (type >= tuner_count) return; @@ -175,6 +186,7 @@ static void set_type(struct i2c_client *c, unsigned int type) return; t->initialized = 1; + t->type = type; switch (t->type) { case TUNER_MT2032: @@ -189,6 +201,53 @@ static void set_type(struct i2c_client *c, unsigned int type) } } +#ifdef CONFIG_TUNER_MULTI_I2C +#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ + return 0; } else \ + tuner_info ("Cmd %s accepted to "tun"\n",cmd); +#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ + CHECK_ADDR(radio_tuner,cmd,"radio") } else \ + { CHECK_ADDR(tv_tuner,cmd,"TV"); } +#else +#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd); +#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd); +#endif + +#ifdef CONFIG_TUNER_MULTI_I2C + +static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) +{ + /* ADDR_UNSET defaults to first available tuner */ + if ( tun_addr->addr == ADDR_UNSET ) { + if (first_tuner != c->addr) + return; + switch (tun_addr->v4l2_tuner) { + case V4L2_TUNER_RADIO: + radio_tuner=c->addr; + break; + default: + tv_tuner=c->addr; + break; + } + } else { + /* Sets tuner to its configured value */ + switch (tun_addr->v4l2_tuner) { + case V4L2_TUNER_RADIO: + radio_tuner=tun_addr->addr; + if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type); + return; + default: + tv_tuner=tun_addr->addr; + if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type); + return; + } + } + set_type(c,tun_addr->type); +} +#else +#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type) +#endif + static char pal[] = "-"; module_param_string(pal, pal, sizeof(pal), 0644); @@ -233,6 +292,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) #else /* by default, first I2C card is both tv and radio tuner */ if (this_adap == 0) { + first_tuner = addr; tv_tuner = addr; radio_tuner = addr; } @@ -249,11 +309,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) memcpy(&t->i2c,&client_template,sizeof(struct i2c_client)); i2c_set_clientdata(&t->i2c, t); t->type = UNSET; - t->radio_if2 = 10700*1000; // 10.7MHz - FM radio + t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */ i2c_attach_client(&t->i2c); tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); + set_type(&t->i2c, t->type); return 0; } @@ -261,12 +322,14 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) static int tuner_probe(struct i2c_adapter *adap) { if (0 != addr) { - normal_i2c[0] = addr; - normal_i2c[1] = I2C_CLIENT_END; + normal_i2c[0] = addr; + normal_i2c_range[0] = addr; + normal_i2c_range[1] = addr; } this_adap = 0; #ifdef CONFIG_TUNER_MULTI_I2C + first_tuner = 0; tv_tuner = 0; radio_tuner = 0; #endif @@ -298,17 +361,6 @@ static int tuner_detach(struct i2c_client *client) tuner_info("ignore v4l1 call\n"); \ return 0; } -#ifdef CONFIG_TUNER_MULTI_I2C -#define CHECK_ADDR(tp,cmd) if (client->addr!=tp) { \ - tuner_info ("Cmd %s to addr 0x%02x rejected.\n",cmd,client->addr<<1); \ - return 0; } -#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ - CHECK_ADDR(radio_tuner,cmd) } else { CHECK_ADDR(tv_tuner,cmd); } -#else -#define CHECK_ADDR(tp,cmd) -#define CHECK_MODE(cmd) -#endif - static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -320,19 +372,19 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) case TUNER_SET_TYPE: set_type(client,*iarg); break; - case TUNER_SET_ADDR: + case TUNER_SET_TYPE_ADDR: set_addr(client,(struct tuner_addr *)arg); break; case AUDC_SET_RADIO: - CHECK_ADDR(radio_tuner,"AUDC_SET_RADIO"); + t->mode = V4L2_TUNER_RADIO; + CHECK_ADDR(tv_tuner,"AUDC_SET_RADIO","TV"); if (V4L2_TUNER_RADIO != t->mode) { set_tv_freq(client,400 * 16); - t->mode = V4L2_TUNER_RADIO; } break; case AUDC_CONFIG_PINNACLE: - CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE"); + CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE","TV"); switch (*iarg) { case 2: tuner_dbg("pinnacle pal\n"); @@ -360,9 +412,10 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) }; struct video_channel *vc = arg; - CHECK_ADDR(tv_tuner,"VIDIOCSCHAN"); CHECK_V4L2; t->mode = V4L2_TUNER_ANALOG_TV; + CHECK_ADDR(tv_tuner,"VIDIOCSCHAN","TV"); + if (vc->norm < ARRAY_SIZE(map)) t->std = map[vc->norm]; tuner_fixup_std(t); @@ -383,17 +436,27 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct video_tuner *vt = arg; - CHECK_ADDR(radio_tuner,"VIDIOCGTUNER:"); + CHECK_ADDR(radio_tuner,"VIDIOCGTUNER","radio"); CHECK_V4L2; - if (V4L2_TUNER_RADIO == t->mode && t->has_signal) - vt->signal = t->has_signal(client); + if (V4L2_TUNER_RADIO == t->mode) { + if (t->has_signal) + vt->signal = t->has_signal(client); + if (t->is_stereo) { + if (t->is_stereo(client)) + vt-> flags |= VIDEO_TUNER_STEREO_ON; + else + vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON; + } + vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */ + } + return 0; } case VIDIOCGAUDIO: { struct video_audio *va = arg; - CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO"); + CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO","radio"); CHECK_V4L2; if (V4L2_TUNER_RADIO == t->mode && t->is_stereo) va->mode = t->is_stereo(client) @@ -406,9 +469,10 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { v4l2_std_id *id = arg; - CHECK_ADDR(tv_tuner,"VIDIOC_S_STD"); SWITCH_V4L2; t->mode = V4L2_TUNER_ANALOG_TV; + CHECK_ADDR(tv_tuner,"VIDIOC_S_STD","TV"); + t->std = *id; tuner_fixup_std(t); if (t->freq) @@ -444,13 +508,27 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) CHECK_MODE("VIDIOC_G_TUNER"); SWITCH_V4L2; - if (V4L2_TUNER_RADIO == t->mode && t->has_signal) - tuner->signal = t->has_signal(client); + if (V4L2_TUNER_RADIO == t->mode) { + if (t->has_signal) + tuner -> signal = t->has_signal(client); + if (t->is_stereo) { + if (t->is_stereo(client)) { + tuner -> capability |= V4L2_TUNER_CAP_STEREO; + tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO; + } else { + tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO; + } + } + } + /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */ tuner->rangelow = tv_range[0] * 16; - tuner->rangehigh = tv_range[1] * 16; +// tuner->rangehigh = tv_range[1] * 16; +// tuner->rangelow = tv_range[0] * 16384; + tuner->rangehigh = tv_range[1] * 16384; break; } default: + tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); /* nothing */ break; } @@ -458,7 +536,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tuner_suspend(struct device * dev, pm_message_t state, u32 level) +static int tuner_suspend(struct device * dev, u32 state, u32 level) { struct i2c_client *c = container_of(dev, struct i2c_client, dev); struct tuner *t = i2c_get_clientdata(c); diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 866f18dc5b5..539f3055731 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-simple.c,v 1.14 2005/05/30 02:02:47 mchehab Exp $ + * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $ * * i2c tv tuner chip device driver * controls all those simple 4-control-bytes style tuners. @@ -220,7 +220,17 @@ static struct tunertype tuners[] = { { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, + { "Tena TNF9533-D/IF", LGINNOTEK, PAL, + 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623}, + + /* + * This entry is for TEA5767 FM radio only chip used on several boards + * w/TV tuner + */ + { TEA5767_TUNER_NAME, Philips, RADIO, + -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, }; + unsigned const int tuner_count = ARRAY_SIZE(tuners); /* ---------------------------------------------------------------------- */ @@ -231,6 +241,7 @@ static int tuner_getstatus(struct i2c_client *c) if (1 != i2c_master_recv(c,&byte,1)) return 0; + return byte; } @@ -239,17 +250,33 @@ static int tuner_getstatus(struct i2c_client *c) #define TUNER_MODE 0x38 #define TUNER_AFC 0x07 -#define TUNER_STEREO 0x10 /* radio mode */ -#define TUNER_SIGNAL 0x07 /* radio mode */ +#define TUNER_STEREO 0x10 /* radio mode */ +#define TUNER_STEREO_MK3 0x04 /* radio mode */ +#define TUNER_SIGNAL 0x07 /* radio mode */ static int tuner_signal(struct i2c_client *c) { - return (tuner_getstatus(c) & TUNER_SIGNAL)<<13; + return (tuner_getstatus(c) & TUNER_SIGNAL) << 13; } static int tuner_stereo(struct i2c_client *c) { - return (tuner_getstatus (c) & TUNER_STEREO); + int stereo, status; + struct tuner *t = i2c_get_clientdata(c); + + status = tuner_getstatus (c); + + switch (t->type) { + case TUNER_PHILIPS_FM1216ME_MK3: + case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FM1256_IH3: + stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); + break; + default: + stereo = status & TUNER_STEREO; + } + + return stereo; } #if 0 /* unused */ @@ -432,6 +459,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) buffer[2] = tun->config; switch (t->type) { + case TUNER_TENA_9533_DI: case TUNER_YMEC_TVF_5533MF: /*These values are empirically determinated */ @@ -473,20 +501,6 @@ int default_tuner_init(struct i2c_client *c) t->type, tuners[t->type].name); strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); - switch (t->type) { - case TUNER_YMEC_TVF_5533MF: - { - struct tuner_addr tun_addr = { V4L2_TUNER_ANALOG_TV, 0xc2>>1 }; - - if (c->driver->command) { - c->driver->command(c, TUNER_SET_ADDR, &tun_addr); - } else { - tuner_warn("Couldn't set TV tuner I2C address to 0x%02x\n",tun_addr.addr<<1); - } - break; - } - } - t->tv_freq = default_set_tv_freq; t->radio_freq = default_set_radio_freq; t->has_signal = tuner_signal; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 41b635e0d3c..6f5828a9b80 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -148,6 +148,7 @@ static unsigned short normal_i2c[] = { I2C_TDA9874 >> 1, I2C_PIC16C54 >> 1, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; static struct i2c_driver driver; @@ -285,7 +286,6 @@ static int chip_thread(void *data) schedule(); } remove_wait_queue(&chip->wq, &wait); - try_to_freeze(PF_FREEZE); if (chip->done || signal_pending(current)) break; dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c)); diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index eafd7061b31..51b99cdbf29 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c @@ -1,3 +1,7 @@ +/* + * $Id: tvmixer.c,v 1.8 2005/06/12 04:19:19 mchehab Exp $ + */ + #include #include #include diff --git a/include/media/audiochip.h b/include/media/audiochip.h index d3e9e30608d..f345a61c3bd 100644 --- a/include/media/audiochip.h +++ b/include/media/audiochip.h @@ -1,3 +1,7 @@ +/* + * $Id: audiochip.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $ + */ + #ifndef AUDIOCHIP_H #define AUDIOCHIP_H diff --git a/include/media/id.h b/include/media/id.h index 1b0320dc8f7..a39a6423914 100644 --- a/include/media/id.h +++ b/include/media/id.h @@ -1,3 +1,7 @@ +/* + * $Id: id.h,v 1.4 2005/06/12 04:19:19 mchehab Exp $ + */ + /* FIXME: this temporarely, until these are included in linux/i2c-id.h */ /* drivers */ diff --git a/include/media/ir-common.h b/include/media/ir-common.h index b5fa6c585e2..698670547f1 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -1,5 +1,5 @@ /* - * $Id: ir-common.h,v 1.8 2005/02/22 12:28:40 kraxel Exp $ + * $Id: ir-common.h,v 1.9 2005/05/15 19:01:26 mchehab Exp $ * * some common structs and functions to handle infrared remotes via * input layer ... diff --git a/include/media/tuner.h b/include/media/tuner.h index cb75f4809c4..2dd8310901e 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -25,6 +25,8 @@ #include "id.h" +#define ADDR_UNSET (255) + #define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ #define TUNER_PHILIPS_PAL_I 1 #define TUNER_PHILIPS_NTSC 2 @@ -100,6 +102,11 @@ #define TUNER_YMEC_TVF_8531MF 58 #define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ +#define TUNER_THOMSON_DTT7611 60 +#define TUNER_TENA_9533_DI 61 +#define TUNER_TEA5767 62 /* Only FM Radio Tuner */ + +#define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio" #define TUNER_THOMSON_DTT7611 60 @@ -109,6 +116,7 @@ #define NTSC 3 #define SECAM 4 #define ATSC 5 +#define RADIO 6 #define NoTuner 0 #define Philips 1 @@ -124,9 +132,17 @@ #define TCL 11 #define THOMSON 12 +enum v4l_radio_tuner { + TEA5767_LOW_LO_32768 = 0, + TEA5767_HIGH_LO_32768 = 1, + TEA5767_LOW_LO_13MHz = 2, + TEA5767_HIGH_LO_13MHz = 3, +}; + + #define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */ #define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */ -#define TUNER_SET_ADDR _IOW('T',3,int) /* Chooses tuner I2C address */ +#define TUNER_SET_TYPE_ADDR _IOW('T',3,int) /* set tuner type and I2C addr */ #define TDA9887_SET_CONFIG _IOW('t',5,int) @@ -151,8 +167,9 @@ #define I2C_ADDR_TDA8275 0x61 struct tuner_addr { - enum v4l2_tuner_type type; - unsigned short addr; + enum v4l2_tuner_type v4l2_tuner; + unsigned int type; + unsigned short addr; }; struct tuner { -- cgit v1.2.3-70-g09d2 From ac19ecc6fa57b0ea320f01831175ff163f47d6a2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:05:09 -0700 Subject: [PATCH] v4l: update for SAA7134 cards This patch adds support for various SAA7134 cards and brings some fixes. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Fabrice Aeschbacher Signed-off-by: Hermann Pitton . Signed-off-by: Nickolay V Shmyrev Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa6752hs.c | 21 ++-- drivers/media/video/saa7134/saa7134-cards.c | 163 +++++++++++++++++++++++--- drivers/media/video/saa7134/saa7134-core.c | 2 +- drivers/media/video/saa7134/saa7134-dvb.c | 2 +- drivers/media/video/saa7134/saa7134-empress.c | 2 +- drivers/media/video/saa7134/saa7134-i2c.c | 2 +- drivers/media/video/saa7134/saa7134-input.c | 112 +++++++++++++++++- drivers/media/video/saa7134/saa7134-oss.c | 16 ++- drivers/media/video/saa7134/saa7134-tvaudio.c | 21 ++-- drivers/media/video/saa7134/saa7134-vbi.c | 2 +- drivers/media/video/saa7134/saa7134-video.c | 61 ++++------ drivers/media/video/saa7134/saa7134.h | 8 +- drivers/media/video/tveeprom.c | 3 +- drivers/media/video/v4l1-compat.c | 10 +- include/media/tveeprom.h | 4 + 15 files changed, 333 insertions(+), 96 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 42c2b565c9f..d14158b111b 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -22,6 +22,7 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); @@ -41,16 +42,16 @@ enum saa6752hs_videoformat { static const struct v4l2_format v4l2_format_table[] = { - [SAA6752HS_VF_D1] = { - .fmt = { .pix = { .width = 720, .height = 576 }, }, }, - [SAA6752HS_VF_2_3_D1] = { - .fmt = { .pix = { .width = 480, .height = 576 }, }, }, - [SAA6752HS_VF_1_2_D1] = { - .fmt = { .pix = { .width = 352, .height = 576 }, }, }, - [SAA6752HS_VF_SIF] = { - .fmt = { .pix = { .width = 352, .height = 288 }, }, }, - [SAA6752HS_VF_UNKNOWN] = { - .fmt = { .pix = { .width = 0, .height = 0 }, }, }, + [SAA6752HS_VF_D1] = + { .fmt = { .pix = { .width = 720, .height = 576 }}}, + [SAA6752HS_VF_2_3_D1] = + { .fmt = { .pix = { .width = 480, .height = 576 }}}, + [SAA6752HS_VF_1_2_D1] = + { .fmt = { .pix = { .width = 352, .height = 576 }}}, + [SAA6752HS_VF_SIF] = + { .fmt = { .pix = { .width = 352, .height = 288 }}}, + [SAA6752HS_VF_UNKNOWN] = + { .fmt = { .pix = { .width = 0, .height = 0}}}, }; struct saa6752hs_state { diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index c51eb7f078d..0c781e24c44 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -1,6 +1,6 @@ /* - * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $ + * $Id: saa7134-cards.c,v 1.58 2005/06/07 18:05:00 nsh Exp $ * * device driver for philips saa7134 based TV cards * card-specific stuff. @@ -165,7 +165,7 @@ struct saa7134_board saa7134_boards[] = { .inputs = {{ .name = name_tv, .vmux = 1, - .amux = LINE2, + .amux = TV, .tv = 1, },{ .name = name_comp1, @@ -878,7 +878,7 @@ struct saa7134_board saa7134_boards[] = { }, [SAA7134_BOARD_MANLI_MTV002] = { /* Ognjen Nastic */ - .name = "Manli MuchTV M-TV002", + .name = "Manli MuchTV M-TV002/Behold TV 403 FM", .audio_clock = 0x00200000, .tuner_type = TUNER_PHILIPS_PAL, .inputs = {{ @@ -899,14 +899,10 @@ struct saa7134_board saa7134_boards[] = { .name = name_radio, .amux = LINE2, }, - .mute = { - .name = name_mute, - .amux = LINE1, - }, }, [SAA7134_BOARD_MANLI_MTV001] = { /* Ognjen Nastic UNTESTED */ - .name = "Manli MuchTV M-TV001", + .name = "Manli MuchTV M-TV001/Behold TV 401", .audio_clock = 0x00200000, .tuner_type = TUNER_PHILIPS_PAL, .inputs = {{ @@ -923,6 +919,10 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE2, .tv = 1, }}, + .mute = { + .name = name_mute, + .amux = LINE1, + }, }, [SAA7134_BOARD_TG3000TV] = { /* TransGear 3000TV */ @@ -1078,7 +1078,6 @@ struct saa7134_board saa7134_boards[] = { .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FM1256_IH3, .tda9887_conf = TDA9887_PRESENT, - .gpiomask = 0x3, .inputs = {{ .name = name_tv, .vmux = 1, @@ -1285,7 +1284,7 @@ struct saa7134_board saa7134_boards[] = { .gpio =0x8000, } }, - [SAA7134_BOARD_AVERMEDIA_307] = { + [SAA7134_BOARD_AVERMEDIA_STUDIO_307] = { /* Nickolay V. Shmyrev Lots of thanks to Andrey Zolotarev @@ -1323,6 +1322,35 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x01, }, }, + [SAA7134_BOARD_AVERMEDIA_GO_007_FM] = { + .name = "Avermedia AVerTV GO 007 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .gpiomask = 0x00300003, +// .gpiomask = 0x8c240003, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x01, + },{ + .name = name_comp1, + .vmux = 0, + .amux = LINE2, + .gpio = 0x02, + },{ + .name = name_svideo, + .vmux = 6, + .amux = LINE2, + .gpio = 0x02, + }}, + .radio = { + .name = name_radio, + .amux = LINE1, + .gpio = 0x00300001, + }, + }, [SAA7134_BOARD_AVERMEDIA_CARDBUS] = { /* Jon Westgate */ .name = "AVerMedia Cardbus TV/Radio", @@ -1492,7 +1520,6 @@ struct saa7134_board saa7134_boards[] = { .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FQ1216ME, .tda9887_conf = TDA9887_PRESENT, - .gpiomask = 0x3, .inputs = {{ .name = name_tv, .vmux = 1, @@ -1546,7 +1573,82 @@ struct saa7134_board saa7134_boards[] = { // .gpio = 0x4000, }}, }, -}; + [SAA7134_BOARD_AVERMEDIA_307] = { + /* + Davydov Vladimir + */ + .name = "Avermedia AVerTV 307", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 0, + .amux = LINE1, + },{ + .name = name_comp2, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + }, + [SAA7134_BOARD_ADS_INSTANT_TV] = { + .name = "ADS Tech Instant TV (saa7135)", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE2, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + }}, + }, + [SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = { + .name = "Kworld/Tevion V-Stream Xpert TV PVR7134", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_PAL_I, + .gpiomask = 0x0700, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x000, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + .gpio = 0x200, //gpio by DScaler + },{ + .name = name_svideo, + .vmux = 0, + .amux = LINE1, + .gpio = 0x200, + }}, + .radio = { + .name = name_radio, + .amux = LINE1, + .gpio = 0x100, + }, + }, + }; + const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); /* ------------------------------------------------------------------ */ @@ -1663,7 +1765,7 @@ struct pci_device_id saa7134_pci_tbl[] = { .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134, },{ .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .device = PCI_DEVICE_ID_PHILIPS_SAA7135, .subvendor = PCI_VENDOR_ID_ASUSTEK, .subdevice = 0x4845, .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135, @@ -1824,6 +1926,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7134, .subvendor = 0x1461, /* Avermedia Technologies Inc */ .subdevice = 0x9715, + .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_307, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0xa70a, .driver_data = SAA7134_BOARD_AVERMEDIA_307, },{ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -1844,6 +1952,26 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x5168, .subdevice = 0x0306, .driver_data = SAA7134_BOARD_FLYDVBTDUO, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0xf31f, + .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM, + + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7135, + .subvendor = 0x1421, + .subdevice = 0x0350, /* PCI version */ + .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, + + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7135, + .subvendor = 0x1421, + .subdevice = 0x0370, /* cardbus version */ + .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, },{ /* --- boards without eeprom + subsystem ID --- */ @@ -1954,20 +2082,23 @@ int saa7134_board_init1(struct saa7134_dev *dev) dev->has_remote = 1; board_flyvideo(dev); break; - case SAA7134_BOARD_FLYTVPLATINUM_FM: + case SAA7134_BOARD_FLYTVPLATINUM_FM: case SAA7134_BOARD_CINERGY400: case SAA7134_BOARD_CINERGY600: case SAA7134_BOARD_CINERGY600_MK3: case SAA7134_BOARD_ECS_TVP3XP: case SAA7134_BOARD_ECS_TVP3XP_4CB5: case SAA7134_BOARD_MD2819: + case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_305: + case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_307: + case SAA7134_BOARD_AVERMEDIA_GO_007_FM: // case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */ case SAA7134_BOARD_VIDEOMATE_TV_PVR: - dev->has_remote = 1; - break; + case SAA7134_BOARD_MANLI_MTV001: + case SAA7134_BOARD_MANLI_MTV002: case SAA7134_BOARD_AVACSSMARTTV: dev->has_remote = 1; break; diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 634a2d25f2f..f61ed1849a2 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $ + * $Id: saa7134-core.c,v 1.30 2005/05/22 19:23:39 nsh Exp $ * * device driver for philips saa7134 based TV cards * driver core diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index c2873ae029f..aa8e2cf62d5 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $ + * $Id: saa7134-dvb.c,v 1.13 2005/06/12 04:19:19 mchehab Exp $ * * (c) 2004 Gerd Knorr [SuSE Labs] * diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index fa135733690..c85348d0239 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $ + * $Id: saa7134-empress.c,v 1.11 2005/05/22 19:23:39 nsh Exp $ * * (c) 2004 Gerd Knorr [SuSE Labs] * diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 702bb63d981..b6f002e8421 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $ + * $Id: saa7134-i2c.c,v 1.11 2005/06/12 01:36:14 mchehab Exp $ * * device driver for philips saa7134 based TV cards * i2c interface support diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ca50cf531f2..aba2b9de60d 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $ + * $Id: saa7134-input.c,v 1.19 2005/06/07 18:02:26 nsh Exp $ * * handle saa7134 IR remotes via linux kernel input layer. * @@ -308,6 +308,102 @@ static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = { [ 32 ] = KEY_LANGUAGE, [ 33 ] = KEY_SLEEP, }; + +/* Michael Tokarev + http://www.corpit.ru/mjt/beholdTV/remote_control.jpg + keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at + least, and probably other cards too. + The "ascii-art picture" below (in comments, first row + is the keycode in hex, and subsequent row(s) shows + the button labels (several variants when appropriate) + helps to descide which keycodes to assign to the buttons. + */ +static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = { + + /* 0x1c 0x12 * + * FUNCTION POWER * + * FM (|) * + * */ + [ 0x1c ] = KEY_RADIO, /*XXX*/ + [ 0x12 ] = KEY_POWER, + + /* 0x01 0x02 0x03 * + * 1 2 3 * + * * + * 0x04 0x05 0x06 * + * 4 5 6 * + * * + * 0x07 0x08 0x09 * + * 7 8 9 * + * */ + [ 0x01 ] = KEY_KP1, + [ 0x02 ] = KEY_KP2, + [ 0x03 ] = KEY_KP3, + [ 0x04 ] = KEY_KP4, + [ 0x05 ] = KEY_KP5, + [ 0x06 ] = KEY_KP6, + [ 0x07 ] = KEY_KP7, + [ 0x08 ] = KEY_KP8, + [ 0x09 ] = KEY_KP9, + + /* 0x0a 0x00 0x17 * + * RECALL 0 +100 * + * PLUS * + * */ + [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */ + [ 0x00 ] = KEY_KP0, + [ 0x17 ] = KEY_DIGITS, /*XXX*/ + + /* 0x14 0x10 * + * MENU INFO * + * OSD */ + [ 0x14 ] = KEY_MENU, + [ 0x10 ] = KEY_INFO, + + /* 0x0b * + * Up * + * * + * 0x18 0x16 0x0c * + * Left Ok Right * + * * + * 0x015 * + * Down * + * */ + [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */ + [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */ + [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */ + [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */ + [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */ + + /* 0x11 0x0d * + * TV/AV MODE * + * SOURCE STEREO * + * */ + [ 0x11 ] = KEY_TV, /*XXX*/ + [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */ + + /* 0x0f 0x1b 0x1a * + * AUDIO Vol+ Chan+ * + * TIMESHIFT??? * + * * + * 0x0e 0x1f 0x1e * + * SLEEP Vol- Chan- * + * */ + [ 0x0f ] = KEY_AUDIO, + [ 0x1b ] = KEY_VOLUMEUP, + [ 0x1a ] = KEY_CHANNELUP, + [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */ + [ 0x1f ] = KEY_VOLUMEDOWN, + [ 0x1e ] = KEY_CHANNELDOWN, + + /* 0x13 0x19 * + * MUTE SNAPSHOT* + * */ + [ 0x13 ] = KEY_MUTE, + [ 0x19 ] = KEY_RECORD, /*XXX*/ + + // 0x1d unused ? +}; /* ---------------------------------------------------------------------- */ static int build_key(struct saa7134_dev *dev) @@ -379,7 +475,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_FLYVIDEO2000: case SAA7134_BOARD_FLYVIDEO3000: - case SAA7134_BOARD_FLYTVPLATINUM_FM: + case SAA7134_BOARD_FLYTVPLATINUM_FM: ir_codes = flyvideo_codes; mask_keycode = 0xEC00000; mask_keydown = 0x0040000; @@ -405,8 +501,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) polling = 50; // ms break; case SAA7134_BOARD_MD2819: + case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_AVERMEDIA_305: case SAA7134_BOARD_AVERMEDIA_307: + case SAA7134_BOARD_AVERMEDIA_STUDIO_305: + case SAA7134_BOARD_AVERMEDIA_STUDIO_307: + case SAA7134_BOARD_AVERMEDIA_GO_007_FM: ir_codes = md2819_codes; mask_keycode = 0x0007C8; mask_keydown = 0x000010; @@ -415,6 +515,14 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPMODE0, 0x4); saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; + case SAA7134_BOARD_MANLI_MTV001: + case SAA7134_BOARD_MANLI_MTV002: + ir_codes = manli_codes; + mask_keycode = 0x001f00; + mask_keyup = 0x004000; + mask_keydown = 0x002000; + polling = 50; // ms + break; case SAA7134_BOARD_VIDEOMATE_TV_PVR: ir_codes = videomate_tv_pvr_codes; mask_keycode = 0x00003F; diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index 6b6a643bf1c..81732904623 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $ + * $Id: saa7134-oss.c,v 1.14 2005/05/18 22:45:16 hhackmann Exp $ * * device driver for philips saa7134 based TV cards * oss dsp interface @@ -49,7 +49,6 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)"); static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) { - blksize &= ~0xff; if (blksize < 0x100) blksize = 0x100; if (blksize > 0x10000) @@ -57,8 +56,6 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) if (blocks < 2) blocks = 2; - while ((blksize * blocks) & ~PAGE_MASK) - blocks++; if ((blksize * blocks) > 1024*1024) blocks = 1024*1024 / blksize; @@ -79,7 +76,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) BUG(); videobuf_dma_init(&dev->oss.dma); err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, - dev->oss.bufsize >> PAGE_SHIFT); + (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT); if (0 != err) return err; return 0; @@ -163,10 +160,11 @@ static int dsp_rec_start(struct saa7134_dev *dev) fmt |= 0x04; fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; - saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff)); - saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8); - saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16); + saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff)); + saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8); + saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16); saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); + break; case PCI_DEVICE_ID_PHILIPS_SAA7133: case PCI_DEVICE_ID_PHILIPS_SAA7135: @@ -817,7 +815,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) reg = SAA7134_RS_BA1(6); } else { /* even */ - if (0 == (dev->oss.dma_blk & 0x00)) + if (1 == (dev->oss.dma_blk & 0x01)) reg = SAA7134_RS_BA2(6); } if (0 == reg) { diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index ecac13c006d..3617e7f7a41 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $ + * $Id: saa7134-tvaudio.c,v 1.25 2005/06/07 19:00:38 nsh Exp $ * * device driver for philips saa7134 based TV cards * tv audio decoder (fm stereo, nicam, ...) @@ -181,7 +181,8 @@ static void tvaudio_init(struct saa7134_dev *dev) saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff); saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff); saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff); - saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01); + // frame locked audio was reported not to be reliable + saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x02); saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14); saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50); @@ -250,6 +251,11 @@ static void mute_input_7134(struct saa7134_dev *dev) saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel); saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics); saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs); + // for oss, we need to change the clock configuration + if (in->amux == TV) + saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); + else + saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x01); /* switch gpio-connected external audio mux */ if (0 == card(dev).gpiomask) @@ -439,16 +445,15 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au nicam = saa_readb(SAA7134_NICAM_STATUS); dprintk("getstereo: nicam=0x%x\n",nicam); switch (nicam & 0x0b) { + case 0x08: + retval = V4L2_TUNER_SUB_MONO; + break; case 0x09: retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; break; case 0x0a: retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; break; - case 0x08: - default: - retval = V4L2_TUNER_SUB_MONO; - break; } break; } @@ -572,14 +577,14 @@ static int tvaudio_thread(void *data) } else if (0 != dev->last_carrier) { /* no carrier -- try last detected one as fallback */ carrier = dev->last_carrier; - printk(KERN_WARNING "%s/audio: audio carrier scan failed, " + dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, " "using %d.%03d MHz [last detected]\n", dev->name, carrier/1000, carrier%1000); } else { /* no carrier + no fallback -- use default */ carrier = default_carrier; - printk(KERN_WARNING "%s/audio: audio carrier scan failed, " + dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, " "using %d.%03d MHz [default]\n", dev->name, carrier/1000, carrier%1000); } diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index 03c350ffb2d..3c33c591cc8 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $ + * $Id: saa7134-vbi.c,v 1.7 2005/05/24 23:13:06 nsh Exp $ * * device driver for philips saa7134 based TV cards * video4linux video interface diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 72f86736a79..c0a2ee52053 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1,5 +1,5 @@ /* - * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $ + * $Id: saa7134-video.c,v 1.30 2005/06/07 19:00:38 nsh Exp $ * * device driver for philips saa7134 based TV cards * video4linux video interface @@ -31,8 +31,6 @@ #include "saa7134-reg.h" #include "saa7134.h" -#define V4L2_I2C_CLIENTS 1 - /* ------------------------------------------------------------------ */ static unsigned int video_debug = 0; @@ -276,12 +274,12 @@ static struct saa7134_tvnorm tvnorms[] = { .h_start = 0, .h_stop = 719, - .video_v_start = 23, - .video_v_stop = 262, - .vbi_v_start_0 = 10, - .vbi_v_stop_0 = 21, - .vbi_v_start_1 = 273, - .src_timing = 7, + .video_v_start = 23, + .video_v_stop = 262, + .vbi_v_start_0 = 10, + .vbi_v_stop_0 = 21, + .vbi_v_start_1 = 273, + .src_timing = 7, .sync_control = 0x18, .luma_control = 0x40, @@ -524,22 +522,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40); saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80); -#ifdef V4L2_I2C_CLIENTS saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id); -#else - { - /* pass down info to the i2c chips (v4l1) */ - struct video_channel c; - memset(&c,0,sizeof(c)); - c.channel = dev->ctl_input; - c.norm = VIDEO_MODE_PAL; - if (norm->id & V4L2_STD_NTSC) - c.norm = VIDEO_MODE_NTSC; - if (norm->id & V4L2_STD_SECAM) - c.norm = VIDEO_MODE_SECAM; - saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c); - } -#endif } static void video_mux(struct saa7134_dev *dev, int input) @@ -1883,11 +1866,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; down(&dev->lock); dev->ctl_freq = f->frequency; -#ifdef V4L2_I2C_CLIENTS + saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); -#else - saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq); -#endif + saa7134_tvaudio_do_scan(dev); up(&dev->lock); return 0; @@ -2142,16 +2123,19 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, t->rangelow = (int)(65*16); t->rangehigh = (int)(108*16); -#ifdef V4L2_I2C_CLIENTS - saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t); -#else - { - struct video_tuner vt; - memset(&vt,0,sizeof(vt)); - saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt); - t->signal = vt.signal; - } -#endif + saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); + + return 0; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *t = arg; + + if (0 != t->index) + return -EINVAL; + + saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t); + return 0; } case VIDIOC_ENUMINPUT: @@ -2185,7 +2169,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOC_S_AUDIO: - case VIDIOC_S_TUNER: case VIDIOC_S_INPUT: case VIDIOC_S_STD: return 0; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index b808f18890b..d6b1c0d4d0f 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -1,5 +1,5 @@ /* - * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $ + * $Id: saa7134.h,v 1.41 2005/06/07 18:02:26 nsh Exp $ * * v4l2 device driver for philips saa7134 based TV cards * @@ -168,7 +168,7 @@ struct saa7134_format { #define SAA7134_BOARD_SABRENT_SBTTVFM 42 #define SAA7134_BOARD_ZOLID_XPERT_TV7134 43 #define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44 -#define SAA7134_BOARD_AVERMEDIA_307 45 +#define SAA7134_BOARD_AVERMEDIA_STUDIO_307 45 #define SAA7134_BOARD_AVERMEDIA_CARDBUS 46 #define SAA7134_BOARD_CINERGY400_CARDBUS 47 #define SAA7134_BOARD_CINERGY600_MK3 48 @@ -179,6 +179,10 @@ struct saa7134_format { #define SAA7135_BOARD_ASUSTeK_TVFM7135 53 #define SAA7134_BOARD_FLYTVPLATINUM_FM 54 #define SAA7134_BOARD_FLYDVBTDUO 55 +#define SAA7134_BOARD_AVERMEDIA_307 56 +#define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57 +#define SAA7134_BOARD_ADS_INSTANT_TV 58 +#define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 3d216973798..cf069bf0d6a 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -75,7 +75,7 @@ hauppauge_tuner_fmt[] = { 0x00000007, "PAL(B/G)" }, { 0x00001000, "NTSC(M)" }, { 0x00000010, "PAL(I)" }, - { 0x00400000, "SECAM(L/L�)" }, + { 0x00400000, "SECAM(L/L´)" }, { 0x00000e00, "PAL(D/K)" }, { 0x03000000, "ATSC Digital" }, }; @@ -482,6 +482,7 @@ static unsigned short normal_i2c[] = { 0xa0 >> 1, I2C_CLIENT_END, }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; struct i2c_driver i2c_driver_tveeprom; diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index b0d4bcb027d..70ecbdb8027 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c @@ -1,4 +1,6 @@ /* + * $Id: v4l1-compat.c,v 1.9 2005/06/12 04:19:19 mchehab Exp $ + * * Video for Linux Two * Backward Compatibility Layer * @@ -15,14 +17,11 @@ * */ -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - #include #include #include +#include #include #include #include @@ -787,12 +786,15 @@ v4l_compat_translate_ioctl(struct inode *inode, !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) aud->step = qctrl2.step; aud->mode = 0; + + memset(&tun2,0,sizeof(tun2)); err = drv(inode, file, VIDIOC_G_TUNER, &tun2); if (err < 0) { dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err); err = 0; break; } + if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2) aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h index 627603e561a..5c4fe30e8d1 100644 --- a/include/media/tveeprom.h +++ b/include/media/tveeprom.h @@ -1,3 +1,7 @@ +/* + * $Id: tveeprom.h,v 1.2 2005/06/12 04:19:19 mchehab Exp $ + */ + struct tveeprom { u32 has_radio; -- cgit v1.2.3-70-g09d2 From f5bec39639d386e1893dc440dd536761136ab36b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jun 2005 22:05:13 -0700 Subject: [PATCH] v4l: fix I2C detect after normal_i2c_range() This patch is necessary to correct I2C detect after normal_i2c_range removal in gregkh-i2c-i2c-address_range_removal.patch. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/bt832.c | 4 ++-- drivers/media/video/msp3400.c | 1 - drivers/media/video/saa7134/saa6752hs.c | 1 - drivers/media/video/tda7432.c | 1 - drivers/media/video/tda9875.c | 1 - drivers/media/video/tda9887.c | 1 - drivers/media/video/tuner-core.c | 11 ++++------- drivers/media/video/tvaudio.c | 1 - drivers/media/video/tveeprom.c | 1 - 9 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 3bb347d93b9..9a642c7de54 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c @@ -39,8 +39,8 @@ MODULE_LICENSE("GPL"); /* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_BT832_ALT1>>1,I2C_BT832_ALT2>>1,I2C_CLIENT_END}; +static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1, + I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 05b83faa9a0..1b7d38e96f1 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -147,7 +147,6 @@ static unsigned short normal_i2c[] = { I2C_MSP3400C_ALT >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index d14158b111b..e6d0a18833d 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -22,7 +22,6 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 376a4a439e9..07ba6d3ed08 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -74,7 +74,6 @@ static unsigned short normal_i2c[] = { I2C_TDA7432 >> 1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* Structure of address and subaddresses for the tda7432 */ diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 4f1114c033a..97b113e070f 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -44,7 +44,6 @@ static unsigned short normal_i2c[] = { I2C_TDA9875 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 33d6ee6cde4..39773633cc3 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -33,7 +33,6 @@ static unsigned short normal_i2c[] = { 0x96 >>1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END}; I2C_CLIENT_INSMOD; /* insmod options */ diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index ba13bfadb52..eaabfc85870 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -33,10 +33,8 @@ /* standard i2c insmod options */ static unsigned short normal_i2c[] = { 0x4b, /* tda8290 */ - I2C_CLIENT_END -}; -static unsigned short normal_i2c_range[] = { - 0x60, 0x6f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; @@ -322,9 +320,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) static int tuner_probe(struct i2c_adapter *adap) { if (0 != addr) { - normal_i2c[0] = addr; - normal_i2c_range[0] = addr; - normal_i2c_range[1] = addr; + normal_i2c[0] = addr; + normal_i2c[1] = I2C_CLIENT_END; } this_adap = 0; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 6f5828a9b80..5430b25b910 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -148,7 +148,6 @@ static unsigned short normal_i2c[] = { I2C_TDA9874 >> 1, I2C_PIC16C54 >> 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; static struct i2c_driver driver; diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index cf069bf0d6a..0f03c25489f 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -482,7 +482,6 @@ static unsigned short normal_i2c[] = { 0xa0 >> 1, I2C_CLIENT_END, }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; struct i2c_driver i2c_driver_tveeprom; -- cgit v1.2.3-70-g09d2 From 52c1da39534fb382c061de58b65f678ad74b59f5 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 23 Jun 2005 22:05:33 -0700 Subject: [PATCH] make various thing static Another rollup of patches which give various symbols static scope Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/common/saa7146_fops.c | 2 +- drivers/media/video/tvaudio.c | 22 +++++++++++----------- drivers/scsi/hosts.c | 2 +- drivers/scsi/scsi.c | 6 ++++-- drivers/scsi/scsi_debug.c | 2 +- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_priv.h | 4 ---- drivers/scsi/scsi_sysfs.c | 4 ++-- fs/namespace.c | 2 +- fs/reiserfs/stree.c | 2 +- include/linux/irq.h | 1 - include/linux/namespace.h | 1 - include/net/sctp/sm.h | 6 ------ kernel/irq/spurious.c | 2 +- kernel/module.c | 2 +- kernel/power/swsusp.c | 2 +- net/sctp/sm_statefuns.c | 16 ++++++++++++++-- 17 files changed, 40 insertions(+), 38 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index cb826c9adfe..c04fd11526e 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -403,7 +403,7 @@ static struct file_operations video_fops = .llseek = no_llseek, }; -void vv_callback(struct saa7146_dev *dev, unsigned long status) +static void vv_callback(struct saa7146_dev *dev, unsigned long status) { u32 isr = status; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 5430b25b910..9a493bea76d 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1236,17 +1236,17 @@ static int ta8874z_checkit(struct CHIPSTATE *chip) /* audio chip descriptions - struct CHIPDESC */ /* insmod options to enable/disable individual audio chips */ -int tda8425 = 1; -int tda9840 = 1; -int tda9850 = 1; -int tda9855 = 1; -int tda9873 = 1; -int tda9874a = 1; -int tea6300 = 0; // address clash with msp34xx -int tea6320 = 0; // address clash with msp34xx -int tea6420 = 1; -int pic16c54 = 1; -int ta8874z = 0; // address clash with tda9840 +static int tda8425 = 1; +static int tda9840 = 1; +static int tda9850 = 1; +static int tda9855 = 1; +static int tda9873 = 1; +static int tda9874a = 1; +static int tea6300 = 0; // address clash with msp34xx +static int tea6320 = 0; // address clash with msp34xx +static int tea6420 = 1; +static int pic16c54 = 1; +static int ta8874z = 0; // address clash with tda9840 module_param(tda8425, int, 0444); module_param(tda9840, int, 0444); diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ba347576d99..d7a38b6713f 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -56,7 +56,7 @@ static struct class shost_class = { * @shost: pointer to struct Scsi_Host * recovery: recovery requested to run. **/ -void scsi_host_cancel(struct Scsi_Host *shost, int recovery) +static void scsi_host_cancel(struct Scsi_Host *shost, int recovery) { struct scsi_device *sdev; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 5578ae9a9e4..1cb5f7d4f27 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -68,6 +68,8 @@ #include "scsi_priv.h" #include "scsi_logging.h" +static void scsi_done(struct scsi_cmnd *cmd); +static int scsi_retry_command(struct scsi_cmnd *cmd); /* * Definitions and constants. @@ -741,7 +743,7 @@ static DEFINE_PER_CPU(struct list_head, scsi_done_q); * * This function is interrupt context safe. */ -void scsi_done(struct scsi_cmnd *cmd) +static void scsi_done(struct scsi_cmnd *cmd) { /* * We don't have to worry about this one timing out any more. @@ -836,7 +838,7 @@ static void scsi_softirq(struct softirq_action *h) * level drivers should not become re-entrant as a result of * this. */ -int scsi_retry_command(struct scsi_cmnd *cmd) +static int scsi_retry_command(struct scsi_cmnd *cmd) { /* * Restore the SCSI command state. diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index e0208886b45..322b5a41a36 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1783,7 +1783,7 @@ static void __exit scsi_debug_exit(void) device_initcall(scsi_debug_init); module_exit(scsi_debug_exit); -void pseudo_0_release(struct device * dev) +static void pseudo_0_release(struct device * dev) { if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n"); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9f996499fa9..621dee8b8cb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -44,7 +44,7 @@ struct scsi_host_sg_pool { #endif #define SP(x) { x, "sgpool-" #x } -struct scsi_host_sg_pool scsi_sg_pools[] = { +static struct scsi_host_sg_pool scsi_sg_pools[] = { SP(8), SP(16), SP(32), diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index c01580df447..96d4f745975 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -61,8 +61,6 @@ extern void scsi_exit_hosts(void); extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); extern int scsi_setup_command_freelist(struct Scsi_Host *shost); extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); -extern void scsi_done(struct scsi_cmnd *cmd); -extern int scsi_retry_command(struct scsi_cmnd *cmd); extern int scsi_insert_special_req(struct scsi_request *sreq, int); extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, struct scsi_request *sreq); @@ -136,7 +134,6 @@ extern void scsi_exit_sysctl(void); #endif /* CONFIG_SYSCTL */ /* scsi_sysfs.c */ -extern void scsi_device_dev_release(struct device *); extern int scsi_sysfs_add_sdev(struct scsi_device *); extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); @@ -145,7 +142,6 @@ extern void scsi_sysfs_device_initialize(struct scsi_device *); extern int scsi_sysfs_target_initialize(struct scsi_device *); extern struct scsi_transport_template blank_transport_template; -extern struct class sdev_class; extern struct bus_type scsi_bus_type; /* diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 93b41100a6d..beed7fbe1cb 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -150,7 +150,7 @@ static void scsi_device_cls_release(struct class_device *class_dev) put_device(&sdev->sdev_gendev); } -void scsi_device_dev_release(struct device *dev) +static void scsi_device_dev_release(struct device *dev) { struct scsi_device *sdev; struct device *parent; @@ -185,7 +185,7 @@ void scsi_device_dev_release(struct device *dev) put_device(parent); } -struct class sdev_class = { +static struct class sdev_class = { .name = "scsi_device", .release = scsi_device_cls_release, }; diff --git a/fs/namespace.c b/fs/namespace.c index 3b93e5d750e..208c079e9fd 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -337,7 +337,7 @@ int may_umount(struct vfsmount *mnt) EXPORT_SYMBOL(may_umount); -void umount_tree(struct vfsmount *mnt) +static void umount_tree(struct vfsmount *mnt) { struct vfsmount *p; LIST_HEAD(kill); diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index c47f8fd31a2..63158491e15 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -223,7 +223,7 @@ extern struct tree_balance * cur_tb; const struct reiserfs_key MIN_KEY = {0, 0, {{0, 0},}}; /* Maximal possible key. It is never in the tree. */ -const struct reiserfs_key MAX_KEY = { +static const struct reiserfs_key MAX_KEY = { __constant_cpu_to_le32(0xffffffff), __constant_cpu_to_le32(0xffffffff), {{__constant_cpu_to_le32(0xffffffff), diff --git a/include/linux/irq.h b/include/linux/irq.h index 7fc1022be9e..12277799c00 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -88,7 +88,6 @@ extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action); extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret); -extern void report_bad_irq(unsigned int irq, irq_desc_t *desc, int action_ret); extern int can_request_irq(unsigned int irq, unsigned long irqflags); extern void init_irq_proc(void); diff --git a/include/linux/namespace.h b/include/linux/namespace.h index 9eca1558d72..697991b69f9 100644 --- a/include/linux/namespace.h +++ b/include/linux/namespace.h @@ -12,7 +12,6 @@ struct namespace { struct rw_semaphore sem; }; -extern void umount_tree(struct vfsmount *); extern int copy_namespace(int, struct task_struct *); extern void __put_namespace(struct namespace *namespace); diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index a53e08a45e3..88d9fe5975d 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -131,7 +131,6 @@ sctp_state_fn_t sctp_sf_do_ecne; sctp_state_fn_t sctp_sf_ootb; sctp_state_fn_t sctp_sf_pdiscard; sctp_state_fn_t sctp_sf_violation; -sctp_state_fn_t sctp_sf_violation_chunklen; sctp_state_fn_t sctp_sf_discard_chunk; sctp_state_fn_t sctp_sf_do_5_2_1_siminit; sctp_state_fn_t sctp_sf_do_5_2_2_dupinit; @@ -259,11 +258,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, void sctp_chunk_assign_tsn(struct sctp_chunk *); void sctp_chunk_assign_ssn(struct sctp_chunk *); -sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, - __u16 error, - const struct sctp_association *asoc, - struct sctp_transport *transport); - /* Prototypes for statetable processing. */ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index f6297c30690..ba039e827d5 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -45,7 +45,7 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) } } -void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) +static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) { static int count = 100; diff --git a/kernel/module.c b/kernel/module.c index 0494c89a0d2..068e271ab3a 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -730,7 +730,7 @@ static int obsparm_copy_string(const char *val, struct kernel_param *kp) return 0; } -int set_obsolete(const char *val, struct kernel_param *kp) +static int set_obsolete(const char *val, struct kernel_param *kp) { unsigned int min, max; unsigned int size, maxsize; diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 90b3b68dee3..53f9f8720ee 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -81,7 +81,7 @@ static int nr_copy_pages_check; extern char resume_file[]; /* Local variables that should not be affected by save */ -unsigned int nr_copy_pages __nosavedata = 0; +static unsigned int nr_copy_pages __nosavedata = 0; /* Suspend pagedir is allocated before final copy, therefore it must be freed after resume diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 058189684c7..86073df418f 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -92,6 +92,17 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, sctp_cmd_seq_t *commands); static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); +static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, + __u16 error, + const struct sctp_association *asoc, + struct sctp_transport *transport); + +static sctp_disposition_t sctp_sf_violation_chunklen( + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const sctp_subtype_t type, + void *arg, + sctp_cmd_seq_t *commands); /* Small helper function that checks if the chunk length * is of the appropriate length. The 'required_length' argument @@ -2328,7 +2339,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep, * * This is common code called by several sctp_sf_*_abort() functions above. */ -sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, +static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error, const struct sctp_association *asoc, struct sctp_transport *transport) @@ -3687,7 +3698,8 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep, * * Generate an ABORT chunk and terminate the association. */ -sctp_disposition_t sctp_sf_violation_chunklen(const struct sctp_endpoint *ep, +static sctp_disposition_t sctp_sf_violation_chunklen( + const struct sctp_endpoint *ep, const struct sctp_association *asoc, const sctp_subtype_t type, void *arg, -- cgit v1.2.3-70-g09d2 From 5cdb7b48d0d5963e40bb6621bfa7b2d5fddc4562 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 25 Jun 2005 14:54:22 -0700 Subject: [PATCH] cx88 build fix static declaration of cx88_pci_irqs follows non-static. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/cx88/cx88.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index ac0dc27bb38..867e988a5a9 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -435,7 +435,6 @@ struct cx8802_dev { /* ----------------------------------------------------------- */ /* cx88-core.c */ -extern char *cx88_pci_irqs[32]; extern char *cx88_vid_irqs[32]; extern char *cx88_mpeg_irqs[32]; extern void cx88_print_irqbits(char *name, char *tag, char **strings, -- cgit v1.2.3-70-g09d2 From 3e1d1d28d99dabe63c64f7f40f1ca1d646de1f73 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 24 Jun 2005 23:13:50 -0700 Subject: [PATCH] Cleanup patch for process freezing 1. Establish a simple API for process freezing defined in linux/include/sched.h: frozen(process) Check for frozen process freezing(process) Check if a process is being frozen freeze(process) Tell a process to freeze (go to refrigerator) thaw_process(process) Restart process frozen_process(process) Process is frozen now 2. Remove all references to PF_FREEZE and PF_FROZEN from all kernel sources except sched.h 3. Fix numerous locations where try_to_freeze is manually done by a driver 4. Remove the argument that is no longer necessary from two function calls. 5. Some whitespace cleanup 6. Clear potential race in refrigerator (provides an open window of PF_FREEZE cleared before setting PF_FROZEN, recalc_sigpending does not check PF_FROZEN). This patch does not address the problem of freeze_processes() violating the rule that a task may only modify its own flags by setting PF_FREEZE. This is not clean in an SMP environment. freeze(process) is therefore not SMP safe! Signed-off-by: Christoph Lameter Signed-off-by: Linus Torvalds --- Documentation/power/kernel_threads.txt | 3 +- Documentation/power/swsusp.txt | 3 +- arch/frv/kernel/signal.c | 4 +- arch/h8300/kernel/signal.c | 4 +- arch/i386/kernel/io_apic.c | 2 +- arch/i386/kernel/signal.c | 4 +- arch/m32r/kernel/signal.c | 4 +- arch/ppc/kernel/signal.c | 3 +- arch/x86_64/kernel/signal.c | 2 +- drivers/block/pktcdvd.c | 3 +- drivers/ieee1394/ieee1394_core.c | 4 +- drivers/ieee1394/nodemgr.c | 2 +- drivers/input/gameport/gameport.c | 2 +- drivers/input/serio/serio.c | 2 +- drivers/macintosh/therm_adt746x.c | 4 +- drivers/md/md.c | 3 +- drivers/media/dvb/dvb-core/dvb_frontend.c | 3 +- drivers/media/video/msp3400.c | 3 +- drivers/media/video/video-buf-dvb.c | 3 +- drivers/net/8139too.c | 2 +- drivers/net/irda/sir_kthread.c | 3 +- drivers/net/irda/stir4200.c | 4 +- drivers/net/wireless/airo.c | 2 +- drivers/pcmcia/cs.c | 2 +- drivers/pnp/pnpbios/core.c | 2 +- drivers/usb/core/hub.c | 2 +- drivers/usb/gadget/file_storage.c | 3 +- drivers/usb/storage/usb.c | 4 +- drivers/w1/w1.c | 4 +- fs/afs/kafsasyncd.c | 2 +- fs/afs/kafstimod.c | 2 +- fs/jbd/journal.c | 4 +- fs/jfs/jfs_logmgr.c | 4 +- fs/jfs/jfs_txnmgr.c | 8 ++-- fs/lockd/clntproc.c | 2 +- fs/xfs/linux-2.6/xfs_buf.c | 4 +- fs/xfs/linux-2.6/xfs_super.c | 2 +- include/linux/sched.h | 73 +++++++++++++++++++++++++------ kernel/power/process.c | 26 +++++------ kernel/sched.c | 3 +- kernel/signal.c | 5 +-- mm/pdflush.c | 2 +- mm/vmscan.c | 4 +- net/rxrpc/krxiod.c | 2 +- net/rxrpc/krxsecd.c | 2 +- net/rxrpc/krxtimod.c | 2 +- net/sunrpc/svcsock.c | 6 +-- 47 files changed, 126 insertions(+), 113 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/power/kernel_threads.txt b/Documentation/power/kernel_threads.txt index 60b548105ed..fb57784986b 100644 --- a/Documentation/power/kernel_threads.txt +++ b/Documentation/power/kernel_threads.txt @@ -12,8 +12,7 @@ refrigerator. Code to do this looks like this: do { hub_events(); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); } while (!signal_pending(current)); from drivers/usb/core/hub.c::hub_thread() diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt index c7c3459fde4..4e1627cc5b5 100644 --- a/Documentation/power/swsusp.txt +++ b/Documentation/power/swsusp.txt @@ -164,8 +164,7 @@ place where the thread is safe to be frozen (no kernel semaphores should be held at that point and it must be safe to sleep there), and add: - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); If the thread is needed for writing the image to storage, you should instead set the PF_NOFREEZE process flag when creating the thread. diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index d8d8f3d4304..36a2dffc8eb 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c @@ -536,10 +536,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (!user_mode(regs)) return 1; - if (current->flags & PF_FREEZE) { - refrigerator(0); + if (try_to_freeze()) goto no_signal; - } if (!oldset) oldset = ¤t->blocked; diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index a4799d633ef..5aab87eae1f 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c @@ -517,10 +517,8 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) if ((regs->ccr & 0x10)) return 1; - if (current->flags & PF_FREEZE) { - refrigerator(0); + if (try_to_freeze()) goto no_signal; - } current->thread.esp0 = (unsigned long) regs; diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 08540bc4ba3..2451a3a9944 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -573,7 +573,7 @@ static int balanced_irq(void *unused) for ( ; ; ) { set_current_state(TASK_INTERRUPTIBLE); time_remaining = schedule_timeout(time_remaining); - try_to_freeze(PF_FREEZE); + try_to_freeze(); if (time_after(jiffies, prev_balance_time+balanced_irq_interval)) { do_irq_balance(); diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index b9b8f4e20fa..ac5b1e975c5 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -608,10 +608,8 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) if (!user_mode(regs)) return 1; - if (current->flags & PF_FREEZE) { - refrigerator(0); + if (try_to_freeze) goto no_signal; - } if (!oldset) oldset = ¤t->blocked; diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 50311eb07a2..5aef7e406ef 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c @@ -371,10 +371,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (!user_mode(regs)) return 1; - if (current->flags & PF_FREEZE) { - refrigerator(0); + if (try_to_freeze()) goto no_signal; - } if (!oldset) oldset = ¤t->blocked; diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 7c8437da09d..8aaeb6f4e75 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -705,8 +705,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) unsigned long frame, newsp; int signr, ret; - if (current->flags & PF_FREEZE) { - refrigerator(PF_FREEZE); + if (try_to_freeze()) { signr = 0; if (!signal_pending(current)) goto no_signal; diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 98b7ba95d58..98590a989f3 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c @@ -425,7 +425,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (!user_mode(regs)) return 1; - if (try_to_freeze(0)) + if (try_to_freeze()) goto no_signal; if (!oldset) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 7f3d78de265..7b838342f0a 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -1251,8 +1251,7 @@ static int kcdrwd(void *foobar) VPRINTK("kcdrwd: wake up\n"); /* make swsusp happy with our thread */ - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { if (!pkt->sleep_time) diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 2d9a9b74e68..629070b83a3 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -1041,10 +1041,8 @@ static int hpsbpkt_thread(void *__hi) while (1) { if (down_interruptible(&khpsbpkt_sig)) { - if (current->flags & PF_FREEZE) { - refrigerator(0); + if (try_to_freeze()) continue; - } printk("khpsbpkt: received unexpected signal?!\n" ); break; } diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 32abb6dda88..9a46c3b44bf 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -1510,7 +1510,7 @@ static int nodemgr_host_thread(void *__hi) if (down_interruptible(&hi->reset_sem) || down_interruptible(&nodemgr_serialize)) { - if (try_to_freeze(PF_FREEZE)) + if (try_to_freeze()) continue; printk("NodeMgr: received unexpected signal?!\n" ); break; diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index e152d0fa0cd..c77a82e4605 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -439,7 +439,7 @@ static int gameport_thread(void *nothing) do { gameport_handle_events(); wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list)); - try_to_freeze(PF_FREEZE); + try_to_freeze(); } while (!signal_pending(current)); printk(KERN_DEBUG "gameport: kgameportd exiting\n"); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index feab4970406..341824c4852 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -344,7 +344,7 @@ static int serio_thread(void *nothing) do { serio_handle_events(); wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); - try_to_freeze(PF_FREEZE); + try_to_freeze(); } while (!signal_pending(current)); printk(KERN_DEBUG "serio: kseriod exiting\n"); diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 5ba190ce14a..c9ca1118e44 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -328,9 +328,7 @@ static int monitor_task(void *arg) struct thermostat* th = arg; while(!kthread_should_stop()) { - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); - + try_to_freeze(); msleep_interruptible(2000); #ifndef DEBUG diff --git a/drivers/md/md.c b/drivers/md/md.c index 0c6b5b6baff..3802f7a17f1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2976,8 +2976,7 @@ static int md_thread(void * arg) wait_event_interruptible_timeout(thread->wqueue, test_bit(THREAD_WAKEUP, &thread->flags), thread->timeout); - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); clear_bit(THREAD_WAKEUP, &thread->flags); diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index d6b7a9de471..f11daae91cd 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -391,8 +391,7 @@ static int dvb_frontend_thread(void *data) break; } - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); if (down_interruptible(&fepriv->sem)) break; diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 1b7d38e96f1..b4ee9dfe6d4 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -750,8 +750,7 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout) #endif } } - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); remove_wait_queue(&msp->wq, &wait); return msp->restart; } diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c index 5f870075b55..15f5bb48696 100644 --- a/drivers/media/video/video-buf-dvb.c +++ b/drivers/media/video/video-buf-dvb.c @@ -62,8 +62,7 @@ static int videobuf_dvb_thread(void *data) break; if (kthread_should_stop()) break; - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); /* feed buffer data to demux */ if (buf->state == STATE_DONE) diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 047202c4d9a..5a4a08a7c95 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -1606,7 +1606,7 @@ static int rtl8139_thread (void *data) do { timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout); /* make swsusp happy with our thread */ - try_to_freeze(PF_FREEZE); + try_to_freeze(); } while (!signal_pending (current) && (timeout > 0)); if (signal_pending (current)) { diff --git a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c index 18cea109953..c65054364bc 100644 --- a/drivers/net/irda/sir_kthread.c +++ b/drivers/net/irda/sir_kthread.c @@ -135,8 +135,7 @@ static int irda_thread(void *startup) remove_wait_queue(&irda_rq_queue.kick, &wait); /* make swsusp happy with our thread */ - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); run_irda_queue(); } diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 66f488c1371..15f207323d9 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -763,7 +763,7 @@ static int stir_transmit_thread(void *arg) { #ifdef CONFIG_PM /* if suspending, then power off and wait */ - if (unlikely(current->flags & PF_FREEZE)) { + if (unlikely(freezing(current))) { if (stir->receiving) receive_stop(stir); else @@ -771,7 +771,7 @@ static int stir_transmit_thread(void *arg) write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); - refrigerator(PF_FREEZE); + refrigerator(); if (change_speed(stir, stir->speed)) break; diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index fb10a2db63a..d72e0385e4f 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2918,7 +2918,7 @@ static int airo_thread(void *data) { flush_signals(current); /* make swsusp happy with our thread */ - try_to_freeze(PF_FREEZE); + try_to_freeze(); if (test_bit(JOB_DIE, &ai->flags)) break; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index d136b3c8fac..48e4f04530d 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -718,7 +718,7 @@ static int pccardd(void *__skt) } schedule(); - try_to_freeze(PF_FREEZE); + try_to_freeze(); if (!skt->thread) break; diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index e939c93a931..778a324028f 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -182,7 +182,7 @@ static int pnp_dock_thread(void * unused) msleep_interruptible(2000); if(signal_pending(current)) { - if (try_to_freeze(PF_FREEZE)) + if (try_to_freeze()) continue; break; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d2d648ee864..a8d879a85d0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2808,7 +2808,7 @@ static int hub_thread(void *__unused) do { hub_events(); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); - try_to_freeze(PF_FREEZE); + try_to_freeze(); } while (!signal_pending(current)); pr_debug ("%s: khubd exiting\n", usbcore_name); diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 037a7f16382..a9be85103d2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1554,8 +1554,7 @@ static int sleep_thread(struct fsg_dev *fsg) rc = wait_event_interruptible(fsg->thread_wqh, fsg->thread_wakeup_needed); fsg->thread_wakeup_needed = 0; - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); return (rc ? -EINTR : 0); } diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 35c1ca6b5a8..77e7fc258aa 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -847,10 +847,8 @@ retry: wait_event_interruptible_timeout(us->delay_wait, test_bit(US_FLIDX_DISCONNECTING, &us->flags), delay_use * HZ); - if (current->flags & PF_FREEZE) { - refrigerator(PF_FREEZE); + if (try_to_freeze()) goto retry; - } } /* If the device is still connected, perform the scanning */ diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index b460927ec32..312cf3220f1 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -646,7 +646,7 @@ static int w1_control(void *data) while (!control_needs_exit || have_to_wait) { have_to_wait = 0; - try_to_freeze(PF_FREEZE); + try_to_freeze(); msleep_interruptible(w1_timeout * 1000); if (signal_pending(current)) @@ -725,7 +725,7 @@ int w1_process(void *data) allow_signal(SIGTERM); while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { - try_to_freeze(PF_FREEZE); + try_to_freeze(); msleep_interruptible(w1_timeout * 1000); if (signal_pending(current)) diff --git a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c index 6fc88ae8ad9..7ac07d0d47b 100644 --- a/fs/afs/kafsasyncd.c +++ b/fs/afs/kafsasyncd.c @@ -116,7 +116,7 @@ static int kafsasyncd(void *arg) remove_wait_queue(&kafsasyncd_sleepq, &myself); set_current_state(TASK_RUNNING); - try_to_freeze(PF_FREEZE); + try_to_freeze(); /* discard pending signals */ afs_discard_my_signals(); diff --git a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c index 86e710dd057..65bc05ab818 100644 --- a/fs/afs/kafstimod.c +++ b/fs/afs/kafstimod.c @@ -91,7 +91,7 @@ static int kafstimod(void *arg) complete_and_exit(&kafstimod_dead, 0); } - try_to_freeze(PF_FREEZE); + try_to_freeze(); /* discard pending signals */ afs_discard_my_signals(); diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 1e6f2e2ad4a..5e7b4394951 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -167,7 +167,7 @@ loop: } wake_up(&journal->j_wait_done_commit); - if (current->flags & PF_FREEZE) { + if (freezing(current)) { /* * The simpler the better. Flushing journal isn't a * good idea, because that depends on threads that may @@ -175,7 +175,7 @@ loop: */ jbd_debug(1, "Now suspending kjournald\n"); spin_unlock(&journal->j_state_lock); - refrigerator(PF_FREEZE); + refrigerator(); spin_lock(&journal->j_state_lock); } else { /* diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 7c8387ed419..79d07624bfe 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -2359,9 +2359,9 @@ int jfsIOWait(void *arg) lbmStartIO(bp); spin_lock_irq(&log_redrive_lock); } - if (current->flags & PF_FREEZE) { + if (freezing(current)) { spin_unlock_irq(&log_redrive_lock); - refrigerator(PF_FREEZE); + refrigerator(); } else { add_wait_queue(&jfs_IO_thread_wait, &wq); set_current_state(TASK_INTERRUPTIBLE); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 8cbaaff1d5f..121c981ff45 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -2788,9 +2788,9 @@ int jfs_lazycommit(void *arg) /* In case a wakeup came while all threads were active */ jfs_commit_thread_waking = 0; - if (current->flags & PF_FREEZE) { + if (freezing(current)) { LAZY_UNLOCK(flags); - refrigerator(PF_FREEZE); + refrigerator(); } else { DECLARE_WAITQUEUE(wq, current); @@ -2987,9 +2987,9 @@ int jfs_sync(void *arg) /* Add anon_list2 back to anon_list */ list_splice_init(&TxAnchor.anon_list2, &TxAnchor.anon_list); - if (current->flags & PF_FREEZE) { + if (freezing(current)) { TXN_UNLOCK(); - refrigerator(PF_FREEZE); + refrigerator(); } else { DECLARE_WAITQUEUE(wq, current); diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index fd77ed1d710..14b3ce87fa2 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -313,7 +313,7 @@ static int nlm_wait_on_grace(wait_queue_head_t *queue) prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE); if (!signalled ()) { schedule_timeout(NLMCLNT_GRACE_WAIT); - try_to_freeze(PF_FREEZE); + try_to_freeze(); if (!signalled ()) status = 0; } diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index c60e69431e1..df0cba239dd 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1771,9 +1771,9 @@ xfsbufd( INIT_LIST_HEAD(&tmp); do { - if (unlikely(current->flags & PF_FREEZE)) { + if (unlikely(freezing(current))) { xfsbufd_force_sleep = 1; - refrigerator(PF_FREEZE); + refrigerator(); } else { xfsbufd_force_sleep = 0; } diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 5fe9af38aa2..f6dd7de2592 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -483,7 +483,7 @@ xfssyncd( set_current_state(TASK_INTERRUPTIBLE); timeleft = schedule_timeout(timeleft); /* swsusp */ - try_to_freeze(PF_FREEZE); + try_to_freeze(); if (vfsp->vfs_flag & VFS_UMOUNT) break; diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c69682b044..e7fd09b0557 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1245,33 +1245,78 @@ extern void normalize_rt_tasks(void); #endif -/* try_to_freeze - * - * Checks whether we need to enter the refrigerator - * and returns 1 if we did so. - */ #ifdef CONFIG_PM -extern void refrigerator(unsigned long); +/* + * Check if a process has been frozen + */ +static inline int frozen(struct task_struct *p) +{ + return p->flags & PF_FROZEN; +} + +/* + * Check if there is a request to freeze a process + */ +static inline int freezing(struct task_struct *p) +{ + return p->flags & PF_FREEZE; +} + +/* + * Request that a process be frozen + * FIXME: SMP problem. We may not modify other process' flags! + */ +static inline void freeze(struct task_struct *p) +{ + p->flags |= PF_FREEZE; +} + +/* + * Wake up a frozen process + */ +static inline int thaw_process(struct task_struct *p) +{ + if (frozen(p)) { + p->flags &= ~PF_FROZEN; + wake_up_process(p); + return 1; + } + return 0; +} + +/* + * freezing is complete, mark process as frozen + */ +static inline void frozen_process(struct task_struct *p) +{ + p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN; +} + +extern void refrigerator(void); extern int freeze_processes(void); extern void thaw_processes(void); -static inline int try_to_freeze(unsigned long refrigerator_flags) +static inline int try_to_freeze(void) { - if (unlikely(current->flags & PF_FREEZE)) { - refrigerator(refrigerator_flags); + if (freezing(current)) { + refrigerator(); return 1; } else return 0; } #else -static inline void refrigerator(unsigned long flag) {} +static inline int frozen(struct task_struct *p) { return 0; } +static inline int freezing(struct task_struct *p) { return 0; } +static inline void freeze(struct task_struct *p) { BUG(); } +static inline int thaw_process(struct task_struct *p) { return 1; } +static inline void frozen_process(struct task_struct *p) { BUG(); } + +static inline void refrigerator(void) {} static inline int freeze_processes(void) { BUG(); return 0; } static inline void thaw_processes(void) {} -static inline int try_to_freeze(unsigned long refrigerator_flags) -{ - return 0; -} +static inline int try_to_freeze(void) { return 0; } + #endif /* CONFIG_PM */ #endif /* __KERNEL__ */ diff --git a/kernel/power/process.c b/kernel/power/process.c index 78d92dc6a1e..0a086640bcf 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -32,7 +32,7 @@ static inline int freezeable(struct task_struct * p) } /* Refrigerator is place where frozen processes are stored :-). */ -void refrigerator(unsigned long flag) +void refrigerator(void) { /* Hmm, should we be allowed to suspend when there are realtime processes around? */ @@ -41,14 +41,13 @@ void refrigerator(unsigned long flag) current->state = TASK_UNINTERRUPTIBLE; pr_debug("%s entered refrigerator\n", current->comm); printk("="); - current->flags &= ~PF_FREEZE; + frozen_process(current); spin_lock_irq(¤t->sighand->siglock); recalc_sigpending(); /* We sent fake signal, clean it up */ spin_unlock_irq(¤t->sighand->siglock); - current->flags |= PF_FROZEN; - while (current->flags & PF_FROZEN) + while (frozen(current)) schedule(); pr_debug("%s left refrigerator\n", current->comm); current->state = save; @@ -57,10 +56,10 @@ void refrigerator(unsigned long flag) /* 0 = success, else # of processes that we failed to stop */ int freeze_processes(void) { - int todo; - unsigned long start_time; + int todo; + unsigned long start_time; struct task_struct *g, *p; - + printk( "Stopping tasks: " ); start_time = jiffies; do { @@ -70,14 +69,12 @@ int freeze_processes(void) unsigned long flags; if (!freezeable(p)) continue; - if ((p->flags & PF_FROZEN) || + if ((frozen(p)) || (p->state == TASK_TRACED) || (p->state == TASK_STOPPED)) continue; - /* FIXME: smp problem here: we may not access other process' flags - without locking */ - p->flags |= PF_FREEZE; + freeze(p); spin_lock_irqsave(&p->sighand->siglock, flags); signal_wake_up(p, 0); spin_unlock_irqrestore(&p->sighand->siglock, flags); @@ -91,7 +88,7 @@ int freeze_processes(void) return todo; } } while(todo); - + printk( "|\n" ); BUG_ON(in_atomic()); return 0; @@ -106,10 +103,7 @@ void thaw_processes(void) do_each_thread(g, p) { if (!freezeable(p)) continue; - if (p->flags & PF_FROZEN) { - p->flags &= ~PF_FROZEN; - wake_up_process(p); - } else + if (!thaw_process(p)) printk(KERN_INFO " Strange, %s not stopped\n", p->comm ); } while_each_thread(g, p); diff --git a/kernel/sched.c b/kernel/sched.c index 76080d142e3..6fa9ea4ae44 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4174,8 +4174,7 @@ static int migration_thread(void * data) struct list_head *head; migration_req_t *req; - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); spin_lock_irq(&rq->lock); diff --git a/kernel/signal.c b/kernel/signal.c index d1258729a5f..ca1186eef93 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -213,7 +213,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) fastcall void recalc_sigpending_tsk(struct task_struct *t) { if (t->signal->group_stop_count > 0 || - (t->flags & PF_FREEZE) || + (freezing(t)) || PENDING(&t->pending, &t->blocked) || PENDING(&t->signal->shared_pending, &t->blocked)) set_tsk_thread_flag(t, TIF_SIGPENDING); @@ -2231,8 +2231,7 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese, current->state = TASK_INTERRUPTIBLE; timeout = schedule_timeout(timeout); - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(current, &these, &info); current->blocked = current->real_blocked; diff --git a/mm/pdflush.c b/mm/pdflush.c index 38ce279cc8c..d6781951267 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c @@ -105,7 +105,7 @@ static int __pdflush(struct pdflush_work *my_work) spin_unlock_irq(&pdflush_lock); schedule(); - if (try_to_freeze(PF_FREEZE)) { + if (try_to_freeze()) { spin_lock_irq(&pdflush_lock); continue; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 4b8e62a1937..1fa312a8db7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1216,8 +1216,8 @@ static int kswapd(void *p) order = 0; for ( ; ; ) { unsigned long new_order; - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + + try_to_freeze(); prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); new_order = pgdat->kswapd_max_order; diff --git a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c index 2b537f425a1..dada34a77b2 100644 --- a/net/rxrpc/krxiod.c +++ b/net/rxrpc/krxiod.c @@ -138,7 +138,7 @@ static int rxrpc_krxiod(void *arg) _debug("### End Work"); - try_to_freeze(PF_FREEZE); + try_to_freeze(); /* discard pending signals */ rxrpc_discard_my_signals(); diff --git a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c index 6020c89d922..1aadd026d35 100644 --- a/net/rxrpc/krxsecd.c +++ b/net/rxrpc/krxsecd.c @@ -107,7 +107,7 @@ static int rxrpc_krxsecd(void *arg) _debug("### End Inbound Calls"); - try_to_freeze(PF_FREEZE); + try_to_freeze(); /* discard pending signals */ rxrpc_discard_my_signals(); diff --git a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c index 249c2b0290b..3ac81cdd121 100644 --- a/net/rxrpc/krxtimod.c +++ b/net/rxrpc/krxtimod.c @@ -90,7 +90,7 @@ static int krxtimod(void *arg) complete_and_exit(&krxtimod_dead, 0); } - try_to_freeze(PF_FREEZE); + try_to_freeze(); /* discard pending signals */ rxrpc_discard_my_signals(); diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 05907035bc9..56db8f13e6c 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1185,8 +1185,8 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout) arg->page_len = (pages-2)*PAGE_SIZE; arg->len = (pages-1)*PAGE_SIZE; arg->tail[0].iov_len = 0; - - try_to_freeze(PF_FREEZE); + + try_to_freeze(); if (signalled()) return -EINTR; @@ -1227,7 +1227,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout) schedule_timeout(timeout); - try_to_freeze(PF_FREEZE); + try_to_freeze(); spin_lock_bh(&serv->sv_lock); remove_wait_queue(&rqstp->rq_wait, &wait); -- cgit v1.2.3-70-g09d2