diff options
author | Andrew de Quincy <devnull@localhost> | 2004-03-11 18:40:44 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-03-11 18:40:44 +0000 |
commit | 4881f248a09885725d1ad51ec35339ff4db2d81c (patch) | |
tree | f28e1ee6e7e472092c1a2a5e9ea55825c61f7c04 /linux/drivers/media | |
parent | 455c6bb685dcf96d46dc80361513fc6476d541e7 (diff) | |
download | mediapointer-dvb-s2-4881f248a09885725d1ad51ec35339ff4db2d81c.tar.gz mediapointer-dvb-s2-4881f248a09885725d1ad51ec35339ff4db2d81c.tar.bz2 |
Checked in experimental frontend patch
Also some minimal budget-ci CI support implemented (just detection+IRQs)
Diffstat (limited to 'linux/drivers/media')
19 files changed, 443 insertions, 241 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 07be5e758..84e9627aa 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -46,8 +46,8 @@ #define FESTATE_TUNED 16 #define FESTATE_ZIGZAG_FAST 32 #define FESTATE_ZIGZAG_SLOW 64 -#define FESTATE_CLEAN_SETUP 128 -#define FESTATE_SEARCHING (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) +#define FESTATE_DISEQC 128 +#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC) #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) @@ -59,8 +59,8 @@ * FESTATE_TUNED. The frontend has successfully locked on. * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it. * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower. - * FESTATE_CLEAN_SETUP. Used for certain dodgy tuners which need special massaging to lock. - * FESTATE_SEARCHING. When we're searching for a signal using a zigzag scan of any sort. + * FESTATE_DISEQC. A DISEQC command has just been issued. + * FESTATE_WAITFORLOCK. When we're waiting for a lock. * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan. * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan. * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. @@ -69,7 +69,10 @@ static int dvb_frontend_debug = 0; static int dvb_shutdown_timeout = 5; -static int dvb_frequency_bending = 1; +static int dvb_override_frequency_bending = 0; +static int dvb_force_auto_inversion = 0; + +static int do_frequency_bending = 0; #define dprintk if (dvb_frontend_debug) printk @@ -100,9 +103,12 @@ struct dvb_frontend_data { int bending; int lnb_drift; int inversion; - int auto_count; - int started_auto_count; + int auto_step; + int auto_sub_step; + int started_auto_step; int min_delay; + int max_drift; + int step_size; int exit; fe_status_t status; }; @@ -353,78 +359,50 @@ static void update_delay (int *quality, int *delay, int min_delay, int locked) * Performs automatic twiddling of frontend parameters. * * @param fe The frontend concerned. + * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT * @returns Number of complete iterations that have been performed. */ -static int dvb_frontend_autotune(struct dvb_frontend_data *fe) +static int dvb_frontend_autotune(struct dvb_frontend_data *fe, int check_wrapped) { - int stepsize; - int maxdrift; int autoinversion; int ready = 0; - int wrapped = 0; int original_inversion = fe->parameters.inversion; u32 original_frequency = fe->parameters.frequency; dprintk ("%s\n", __FUNCTION__); - // choose step size for zigzag scan - switch(fe->info->type) { - case FE_QPSK: - if (fe->parameters.u.qpsk.symbol_rate < 10000000) { - stepsize = fe->parameters.u.qpsk.symbol_rate / 32000; - maxdrift = 5000; - } else { - stepsize = fe->parameters.u.qpsk.symbol_rate / 16000; - maxdrift = fe->parameters.u.qpsk.symbol_rate / 2000; - } - break; - - case FE_QAM: - stepsize = 1; - maxdrift = 0; // don't want any zigzagging under DVB-C frontends - break; - - case FE_OFDM: - stepsize = fe->info->frequency_stepsize * 2; - maxdrift = (fe->info->frequency_stepsize * 2) + 1; - break; - - default: - printk("Unknown frontend type %i\n", fe->info->type); - return 0; - } - // are we using autoinversion? autoinversion = ((!(fe->info->caps & FE_CAN_INVERSION_AUTO)) && (fe->parameters.inversion == INVERSION_AUTO)); // setup parameters correctly while(!ready) { - // wrap the count if we've reached the maximum drift - fe->lnb_drift = (fe->auto_count / 4) * stepsize; - if (fe->lnb_drift >= maxdrift) { - fe->auto_count = 0; + // calculate the lnb_drift + fe->lnb_drift = fe->auto_step * fe->step_size; + + // wrap the auto_step if we've exceeded the maximum drift + if (fe->lnb_drift > fe->max_drift) { + fe->auto_step = 0; + fe->auto_sub_step = 0; fe->lnb_drift = 0; - wrapped = 1; } - + // perform inversion and +/- zigzag - switch(fe->auto_count % 4) { + switch(fe->auto_sub_step) { case 0: - fe->inversion = INVERSION_OFF; + // try with the current inversion and current drift setting ready = 1; break; case 1: if (!autoinversion) break; - fe->inversion = INVERSION_ON; + fe->inversion = (fe->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF; ready = 1; break; case 2: if (fe->lnb_drift == 0) break; - fe->inversion = INVERSION_OFF; fe->lnb_drift = -fe->lnb_drift; ready = 1; break; @@ -433,32 +411,38 @@ static int dvb_frontend_autotune(struct dvb_frontend_data *fe) if (fe->lnb_drift == 0) break; if (!autoinversion) break; - fe->inversion = INVERSION_ON; + fe->inversion = (fe->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF; fe->lnb_drift = -fe->lnb_drift; ready = 1; break; + + default: + fe->auto_step++; + fe->auto_sub_step = -1; // it'll be incremented to 0 in a moment + break; } - if (!ready) fe->auto_count++; + if (!ready) fe->auto_sub_step++; + } + + // if this attempt would hit where we started, indicate a complete iteration has occurred + if ((fe->auto_step == fe->started_auto_step) && (fe->auto_sub_step == 0) && check_wrapped) { + return 1; } - - // perform frequency bending if enabled - if (dvb_frequency_bending) + + // perform frequency bending if necessary + if ((dvb_override_frequency_bending != 1) && do_frequency_bending) dvb_bend_frequency(fe, 0); - + // set the frontend itself fe->parameters.frequency += fe->lnb_drift + fe->bending; if (autoinversion) fe->parameters.inversion = fe->inversion; dvb_frontend_internal_ioctl (&fe->frontend, FE_SET_FRONTEND, &fe->parameters); fe->parameters.frequency = original_frequency; fe->parameters.inversion = original_inversion; - - // reset frontend IRQ bits to clean error stats - dvb_frontend_internal_ioctl (&fe->frontend, FE_RESET, NULL); - // if we've hit where we started from, indicate a complete iteration has occurred - fe->auto_count++; - if ((fe->auto_count == fe->started_auto_count) || (fe->started_auto_count==0 && wrapped)) return 1; + // normal return + fe->auto_sub_step++; return 0; } @@ -483,8 +467,8 @@ static int dvb_frontend_thread (void *data) unsigned long timeout; char name [15]; int quality = 0, delay = 3*HZ; - int clean_setup_count = 0; fe_status_t s; + int check_wrapped = 0; dprintk ("%s\n", __FUNCTION__); @@ -521,17 +505,17 @@ static int dvb_frontend_thread (void *data) dvb_frontend_add_event (fe, s); // if we're not tuned, and we have a lock, move to the TUNED state - if ((fe->state & FESTATE_SEARCHING) && (s & FE_HAS_LOCK)) { + if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK); fe->state = FESTATE_TUNED; - + // if we're tuned, then we have determined the correct inversion if ((!(fe->info->caps & FE_CAN_INVERSION_AUTO)) && (fe->parameters.inversion == INVERSION_AUTO)) { fe->parameters.inversion = fe->inversion; } continue; } - + // if we are tuned already, check we're still locked if (fe->state & FESTATE_TUNED) { update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK); @@ -542,46 +526,56 @@ static int dvb_frontend_thread (void *data) } else { // if we _WERE_ tuned, but now don't have a lock, need to zigzag fe->state = FESTATE_ZIGZAG_FAST; - fe->started_auto_count = fe->auto_count; + fe->started_auto_step = fe->auto_step; + check_wrapped = 0; // fallthrough } } - // don't actually do anything if we're in the LOSTLOCK state - // and the frontend can recover automatically - if ((fe->state & FESTATE_LOSTLOCK) && (fe->info->caps & FE_CAN_RECOVER)) { + // don't actually do anything if we're in the LOSTLOCK state, the frontend is set to + // FE_CAN_RECOVER, and the max_drift is 0 + if ((fe->state & FESTATE_LOSTLOCK) && + (fe->info->caps & FE_CAN_RECOVER) && (fe->max_drift == 0)) { + update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK); + continue; + } + + // don't do anything if we're in the DISEQC state, since this might be someone + // with a motorized dish controlled by DISEQC. If its actually a re-tune, there will + // be a SET_FRONTEND soon enough. + if (fe->state & FESTATE_DISEQC) { update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK); continue; } - - // if we're in the RETUNE state, set everything up for a brand new scan + + // if we're in the RETUNE state, set everything up for a brand new scan, + // keeping the current inversion setting, as the next tune is _very_ likely + // to require the same if (fe->state & FESTATE_RETUNE) { fe->lnb_drift = 0; - fe->inversion = INVERSION_OFF; - fe->auto_count = 0; - fe->started_auto_count = 0; - clean_setup_count = 0; + fe->auto_step = 0; + fe->auto_sub_step = 0; + fe->started_auto_step = 0; + check_wrapped = 0; } - + // fast zigzag. if ((fe->state & FESTATE_SEARCHING_FAST) || (fe->state & FESTATE_RETUNE)) { delay = fe->min_delay; - - // OK, if we've run out of trials at the fast speed. Drop back to - // slow for the _next_ attempt - if (dvb_frontend_autotune(fe)) { + + // peform a tune + if (dvb_frontend_autotune(fe, check_wrapped)) { + // OK, if we've run out of trials at the fast speed. Drop back to + // slow for the _next_ attempt fe->state = FESTATE_SEARCHING_SLOW; - fe->started_auto_count = fe->auto_count; + fe->started_auto_step = fe->auto_step; continue; } + check_wrapped = 1; - // enter clean setup state after the first tune if necessary. yeuch - if ((!(fe->info->caps & FE_CAN_CLEAN_SETUP)) && (clean_setup_count == 0)) { - fe->state = FESTATE_CLEAN_SETUP; - } - // if we've just retuned, enter the ZIGZAG_FAST state. This ensures - // we cannot return from an FE_SET_FRONTEND before the retune occurs. + // we cannot return from an FE_SET_FRONTEND ioctl before the first frontend + // tune occurs if (fe->state & FESTATE_RETUNE) { fe->state = FESTATE_TUNING_FAST; } @@ -590,18 +584,10 @@ static int dvb_frontend_thread (void *data) // slow zigzag if (fe->state & FESTATE_SEARCHING_SLOW) { update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK); - dvb_frontend_autotune(fe); - } - - // clean setup - if (fe->state & FESTATE_CLEAN_SETUP) { - if ((clean_setup_count < 10) && (!(s & FE_HAS_LOCK))) { - dvb_frontend_internal_ioctl(&fe->frontend, FE_RESET, NULL); - } else { - // return to tuning state - fe->state = FESTATE_TUNING_FAST; - } - clean_setup_count++; + + // Note: don't bother checking for wrapping; we stay in this state + // until we get a lock + dvb_frontend_autotune(fe, 0); } }; @@ -713,8 +699,8 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file, { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend_data *fe = dvbdev->priv; + struct dvb_frontend_tune_settings fetunesettings; int err = 0; - int delay_ms; dprintk ("%s\n", __FUNCTION__); @@ -731,7 +717,7 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file, if (fe->status) dvb_call_frontend_notifiers (fe, 0); dvb_frontend_internal_ioctl (&fe->frontend, cmd, parg); - fe->state = FESTATE_IDLE; + fe->state = FESTATE_DISEQC; break; case FE_SET_FRONTEND: @@ -740,20 +726,40 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file, memcpy (&fe->parameters, parg, sizeof (struct dvb_frontend_parameters)); - delay_ms = dvb_frontend_internal_ioctl(&fe->frontend, FE_GETMINDELAY, &fe->parameters); - if (delay_ms >= 0) fe->min_delay = (delay_ms * HZ) / 1000; - else { + memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); + memcpy(&fetunesettings.parameters, parg, + sizeof (struct dvb_frontend_parameters)); + + // force auto frequency inversion if requested + if (dvb_force_auto_inversion) { + fe->parameters.inversion = INVERSION_AUTO; + fetunesettings.parameters.inversion = INVERSION_AUTO; + } + + // get frontend-specific tuning settings + if (dvb_frontend_internal_ioctl(&fe->frontend, FE_GET_TUNE_SETTINGS, &fetunesettings) == 0) { + fe->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; + fe->max_drift = fetunesettings.max_drift; + fe->step_size = fetunesettings.step_size; + } else { + // default values switch(fe->info->type) { case FE_QPSK: fe->min_delay = HZ/20; // default mindelay of 50ms + fe->step_size = fe->parameters.u.qpsk.symbol_rate / 16000; + fe->max_drift = fe->parameters.u.qpsk.symbol_rate / 2000; break; case FE_QAM: fe->min_delay = HZ/20; // default mindelay of 50ms + fe->step_size = 0; + fe->max_drift = 0; // don't want any zigzagging under DVB-C frontends break; case FE_OFDM: - fe->min_delay = HZ/10; // default mindelay of 100ms + fe->min_delay = HZ/20; // default mindelay of 50ms + fe->step_size = fe->info->frequency_stepsize * 2; + fe->max_drift = (fe->info->frequency_stepsize * 2) + 1; break; } } @@ -764,7 +770,7 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file, case FE_GET_EVENT: err = dvb_frontend_get_event (fe, parg, file->f_flags); break; - + case FE_GET_FRONTEND: memcpy (parg, &fe->parameters, sizeof (struct dvb_frontend_parameters)); @@ -1089,6 +1095,7 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend, fe->frontend.i2c = i2c; fe->frontend.data = data; fe->info = info; + fe->inversion = INVERSION_OFF; list_for_each (entry, &frontend_ioctl_list) { struct dvb_frontend_ioctl_data *ioctl; @@ -1128,6 +1135,9 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend, dvb_register_device (i2c->adapter, &fe->dvbdev, &dvbdev_template, fe, DVB_DEVICE_FRONTEND); + if ((info->caps & FE_NEEDS_BENDING) || (dvb_override_frequency_bending == 2)) + do_frequency_bending = 1; + up (&frontend_mutex); return 0; @@ -1165,7 +1175,10 @@ int dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend, MODULE_PARM(dvb_frontend_debug,"i"); MODULE_PARM(dvb_shutdown_timeout,"i"); -MODULE_PARM(dvb_frequency_bending,"i"); +MODULE_PARM(dvb_override_frequency_bending,"i"); +MODULE_PARM(dvb_force_auto_inversion,"i"); + MODULE_PARM_DESC(dvb_frontend_debug, "enable verbose debug messages"); MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); -MODULE_PARM_DESC(dvb_frequency_bending, "0: disable frequency bending, 1: enable (default)"); +MODULE_PARM_DESC(dvb_override_frequency_bending, "0: normal (default), 1: never use frequency bending, 2: always use frequency bending"); +MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 4ab2f6b0c..affabab88 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -56,15 +56,25 @@ struct dvb_frontend { void *data; /* can be used by hardware module... */ }; +struct dvb_frontend_tune_settings { + int min_delay_ms; + int step_size; + int max_drift; + struct dvb_frontend_parameters parameters; +}; + /** * private frontend command ioctl's. * keep them in sync with the public ones defined in linux/dvb/frontend.h + * + * FE_SLEEP. Ioctl used to put frontend into a low power mode. + * FE_INIT. Ioctl used to initialise the frontend. + * FE_GET_TUNE_SETTINGS. Get the frontend-specific tuning loop settings for the supplied set of parameters. */ #define FE_SLEEP _IO('v', 80) #define FE_INIT _IO('v', 81) -#define FE_RESET _IO('v', 82) -#define FE_GETMINDELAY _IOW('v', 83, struct dvb_frontend_parameters) +#define FE_GET_TUNE_SETTINGS _IOWR('v', 83, struct dvb_frontend_tune_settings) extern int diff --git a/linux/drivers/media/dvb/frontends/alps_tdlb7.c b/linux/drivers/media/dvb/frontends/alps_tdlb7.c index 3c8549f9e..9854d802c 100644 --- a/linux/drivers/media/dvb/frontends/alps_tdlb7.c +++ b/linux/drivers/media/dvb/frontends/alps_tdlb7.c @@ -636,9 +636,6 @@ static int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_SET_FRONTEND: return sp8870_set_frontend(i2c, (struct dvb_frontend_parameters*) arg); - case FE_RESET: - return -EOPNOTSUPP; - case FE_GET_FRONTEND: // FIXME: read known values back from Hardware... return -EOPNOTSUPP; @@ -653,6 +650,15 @@ static int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) } break; + case FE_GET_TUNE_SETTINGS: + { + struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg; + fesettings->min_delay_ms = 50; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; + } + default: return -EOPNOTSUPP; }; diff --git a/linux/drivers/media/dvb/frontends/alps_tdmb7.c b/linux/drivers/media/dvb/frontends/alps_tdmb7.c index 5376dc909..9d5336e44 100644 --- a/linux/drivers/media/dvb/frontends/alps_tdmb7.c +++ b/linux/drivers/media/dvb/frontends/alps_tdmb7.c @@ -50,7 +50,7 @@ static struct dvb_frontend_info tdmb7_info = { .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_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_CLEAN_SETUP | FE_CAN_RECOVER + FE_CAN_RECOVER }; @@ -390,8 +390,14 @@ static int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_INIT: return cx22700_init (i2c); - case FE_RESET: - break; + case FE_GET_TUNE_SETTINGS: + { + struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg; + fesettings->min_delay_ms = 50; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; + } default: return -EOPNOTSUPP; diff --git a/linux/drivers/media/dvb/frontends/at76c651.c b/linux/drivers/media/dvb/frontends/at76c651.c index 51940343b..dd4cd35a8 100644 --- a/linux/drivers/media/dvb/frontends/at76c651.c +++ b/linux/drivers/media/dvb/frontends/at76c651.c @@ -71,9 +71,7 @@ static struct dvb_frontend_info at76c651_info = { FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | - FE_CAN_QAM_256 /* | FE_CAN_QAM_512 | FE_CAN_QAM_1024 */ | - FE_CAN_RECOVER | FE_CAN_CLEAN_SETUP | FE_CAN_MUTE_TS - + FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER }; #if ! defined(__powerpc__) @@ -360,7 +358,8 @@ static int at76c651_set_parameters(struct dvb_i2c_bus *i2c, at76c651_set_symbolrate(i2c, p->u.qam.symbol_rate); at76c651_set_inversion(i2c, p->inversion); at76c651_set_auto_config(i2c); - + at76c651_reset(i2c); + return 0; } @@ -460,8 +459,14 @@ static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_INIT: return at76c651_set_defaults(fe->i2c); - case FE_RESET: - return at76c651_reset(fe->i2c); + case FE_GET_TUNE_SETTINGS: + { + struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg; + fesettings->min_delay_ms = 50; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; + } default: return -ENOIOCTLCMD; diff --git a/linux/drivers/media/dvb/frontends/cx24110.c b/linux/drivers/media/dvb/frontends/cx24110.c index d429bd374..4bec5ff60 100644 --- a/linux/drivers/media/dvb/frontends/cx24110.c +++ b/linux/drivers/media/dvb/frontends/cx24110.c @@ -59,8 +59,7 @@ static struct dvb_frontend_info cx24110_info = { .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_CLEAN_SETUP + FE_CAN_QPSK }; /* fixme: are these values correct? especially ..._tolerance and caps */ @@ -621,11 +620,6 @@ static int cx24110_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_INIT: return cx24110_init (i2c); - case FE_RESET: -/* no idea what to do for this call */ -/* fixme (medium): fill me in */ - break; - case FE_SET_TONE: return cx24110_writereg(i2c,0x76,(cx24110_readreg(i2c,0x76)&~0x10)|((((fe_sec_tone_mode_t) arg)==SEC_TONE_ON)?0x10:0)); case FE_SET_VOLTAGE: diff --git a/linux/drivers/media/dvb/frontends/dst.c b/linux/drivers/media/dvb/frontends/dst.c index 80ea6183f..431ea9253 100644 --- a/linux/drivers/media/dvb/frontends/dst.c +++ b/linux/drivers/media/dvb/frontends/dst.c @@ -963,7 +963,6 @@ struct lkup { {FE_GET_FRONTEND, "FE_GET_FRONTEND:" }, {FE_SLEEP, "FE_SLEEP:" }, {FE_INIT, "FE_INIT:" }, - {FE_RESET, "FE_RESET:" }, {FE_SET_TONE, "FE_SET_TONE:" }, {FE_SET_VOLTAGE, "FE_SET_VOLTAGE:" }, }; @@ -1091,9 +1090,6 @@ static int dst_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) dst_init(dst); break; - case FE_RESET: - break; - case FE_DISEQC_SEND_MASTER_CMD: { struct dvb_diseqc_master_cmd *cmd = (struct dvb_diseqc_master_cmd *)arg; diff --git a/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c b/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c index 132df2ddc..e3f473eec 100644 --- a/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/linux/drivers/media/dvb/frontends/dvb_dummy_fe.c @@ -62,8 +62,7 @@ static struct dvb_frontend_info dvb_c_dummyfe_info = { #endif .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO | - FE_CAN_CLEAN_SETUP + FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO }; static struct dvb_frontend_info dvb_t_dummyfe_info = { @@ -157,9 +156,6 @@ static int dvbdummyfe_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *ar case FE_INIT: return 0; - case FE_RESET: - return 0; - case FE_SET_TONE: return -EOPNOTSUPP; diff --git a/linux/drivers/media/dvb/frontends/grundig_29504-401.c b/linux/drivers/media/dvb/frontends/grundig_29504-401.c index a50af41bd..6aaf86aa4 100644 --- a/linux/drivers/media/dvb/frontends/grundig_29504-401.c +++ b/linux/drivers/media/dvb/frontends/grundig_29504-401.c @@ -48,7 +48,7 @@ struct dvb_frontend_info grundig_29504_401_info = { .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_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_MUTE_TS /*| FE_CAN_CLEAN_SETUP*/ + FE_CAN_MUTE_TS }; diff --git a/linux/drivers/media/dvb/frontends/grundig_29504-491.c b/linux/drivers/media/dvb/frontends/grundig_29504-491.c index a70c769bf..68408c7b4 100644 --- a/linux/drivers/media/dvb/frontends/grundig_29504-491.c +++ b/linux/drivers/media/dvb/frontends/grundig_29504-491.c @@ -52,8 +52,7 @@ static struct dvb_frontend_info grundig_29504_491_info = { FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | - FE_CAN_MUTE_TS | FE_CAN_CLEAN_SETUP + FE_CAN_QPSK | FE_CAN_MUTE_TS }; @@ -398,11 +397,6 @@ static int grundig_29504_491_ioctl (struct dvb_frontend *fe, unsigned int cmd, tda8083_writereg (i2c, 0x00, 0x04); break; - case FE_RESET: - tda8083_writereg (i2c, 0x00, 0x3c); - tda8083_writereg (i2c, 0x00, 0x04); - break; - case FE_DISEQC_SEND_MASTER_CMD: return tda8083_send_diseqc_msg (i2c, arg); diff --git a/linux/drivers/media/dvb/frontends/mt312.c b/linux/drivers/media/dvb/frontends/mt312.c index d8c47b1b9..69ac22d5e 100644 --- a/linux/drivers/media/dvb/frontends/mt312.c +++ b/linux/drivers/media/dvb/frontends/mt312.c @@ -66,8 +66,8 @@ static struct dvb_frontend_info mt312_info = { .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_RECOVER | - FE_CAN_CLEAN_SETUP | FE_CAN_MUTE_TS + FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS | + FE_CAN_RECOVER }; static int mt312_read(struct dvb_i2c_bus *i2c, @@ -570,6 +570,8 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c, if ((ret = mt312_write(i2c, SYM_RATE_H, buf, sizeof(buf))) < 0) return ret; + mt312_reset(i2c, 0); + return 0; } @@ -755,9 +757,15 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) return mt312_init(i2c, (long) fe->data, (u8) 90); else return mt312_init(i2c, (long) fe->data, (u8) 60); - - case FE_RESET: - return mt312_reset(i2c, 0); + + case FE_GET_TUNE_SETTINGS: + { + struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg; + fesettings->min_delay_ms = 50; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; + } default: return -ENOIOCTLCMD; diff --git a/linux/drivers/media/dvb/frontends/mt352.c b/linux/drivers/media/dvb/frontends/mt352.c index ab1e3a1b7..e2c69b2e6 100644 --- a/linux/drivers/media/dvb/frontends/mt352.c +++ b/linux/drivers/media/dvb/frontends/mt352.c @@ -60,7 +60,7 @@ static struct dvb_frontend_info mt352_info = { 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_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_CLEAN_SETUP | + FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS }; diff --git a/linux/drivers/media/dvb/frontends/nxt6000.c b/linux/drivers/media/dvb/frontends/nxt6000.c index 1171d80bf..f32ecfdb8 100644 --- a/linux/drivers/media/dvb/frontends/nxt6000.c +++ b/linux/drivers/media/dvb/frontends/nxt6000.c @@ -52,7 +52,12 @@ static struct dvb_frontend_info nxt6000_info = { .symbol_rate_max = 9360000, /* FIXME */ .symbol_rate_tolerance = 4000, .notifier_delay = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | + FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO, }; struct nxt6000_config { @@ -657,9 +662,6 @@ static int nxt6000_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) nxt6000_setup(fe); break; - case FE_RESET: - break; - case FE_SET_FRONTEND: { struct nxt6000_config *nxt = FE2NXT(fe); diff --git a/linux/drivers/media/dvb/frontends/sp887x.c b/linux/drivers/media/dvb/frontends/sp887x.c index dd6b73728..d0ada2193 100644 --- a/linux/drivers/media/dvb/frontends/sp887x.c +++ b/linux/drivers/media/dvb/frontends/sp887x.c @@ -64,7 +64,8 @@ struct dvb_frontend_info sp887x_info = { .frequency_stepsize = 166666, .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_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_RECOVER }; static int errno; @@ -632,6 +633,15 @@ int sp887x_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) sp887x_writereg(fe, 0xc18, 0x00d); break; + case FE_GET_TUNE_SETTINGS: + { + struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg; + fesettings->min_delay_ms = 50; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; + } + default: return -EOPNOTSUPP; }; diff --git a/linux/drivers/media/dvb/frontends/stv0299.c b/linux/drivers/media/dvb/frontends/stv0299.c index d5eae378a..608323c9b 100644 --- a/linux/drivers/media/dvb/frontends/stv0299.c +++ b/linux/drivers/media/dvb/frontends/stv0299.c @@ -96,8 +96,7 @@ static struct dvb_frontend_info uni0299_info = { .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_QPSK | - FE_CAN_FEC_AUTO | - FE_CAN_CLEAN_SETUP + FE_CAN_FEC_AUTO }; @@ -368,9 +367,14 @@ static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, in if ((freq < 950000) || (freq > 2150000)) return -EINVAL; - divisor = 500; - regcode = 2; - + if (ftype == PHILIPS_SU1278_TSA_TT) { + divisor = 500; + regcode = 2; + } else { + divisor = 125; + regcode = 4; + } + // setup frequency divisor div = (freq + (divisor - 1)) / divisor; // round correctly buf[0] = (div >> 8) & 0x7f; @@ -395,7 +399,8 @@ static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, in case ALPS_BSRU6: addr = 0x61; - buf[3] |= 0xC0; + buf[3] = 0xC4; + if (freq > 1530000) buf[3] = 0xc0; break; default: @@ -923,20 +928,18 @@ static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner case ALPS_BSRU6: default: - if (srate <= 1500000) { aclk = 0xb7; bclk = 0x87; } - else if (srate <= 3000000) { aclk = 0xb7; bclk = 0x8b; } - else if (srate <= 7000000) { aclk = 0xb7; bclk = 0x8f; } - else if (srate <= 14000000) { aclk = 0xb7; bclk = 0x93; } - else if (srate <= 30000000) { aclk = 0xb6; bclk = 0x93; } - else if (srate <= 45000000) { aclk = 0xb4; bclk = 0x91; } - m1 = 0x12; + if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } + else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } + else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } + else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } + else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } + else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } stv0299_writereg (i2c, 0x13, aclk); stv0299_writereg (i2c, 0x14, bclk); stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff); stv0299_writereg (i2c, 0x20, (ratio >> 8) & 0xff); stv0299_writereg (i2c, 0x21, (ratio ) & 0xf0); - stv0299_writereg (i2c, 0x0f, (stv0299_readreg(i2c, 0x0f) & 0xc0) | m1); break; } @@ -979,21 +982,6 @@ static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c, int tuner_type) return srate; } -static int stv0299_check_inversion (struct dvb_i2c_bus *i2c) -{ - dprintk ("%s\n", __FUNCTION__); - - if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) { - dvb_delay(30); - if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) { - u8 val = stv0299_readreg (i2c, 0x0c); - return stv0299_writereg (i2c, 0x0c, val ^ 0x01); - } - } - - return 0; -} - static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { struct dvb_i2c_bus *i2c = fe->i2c; @@ -1093,14 +1081,13 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) } else if (p->inversion == INVERSION_ON) { stv0299_writereg(i2c, 0x0c, stv0299_readreg(i2c, 0x0c) | 1); } else { - // temporary hack until the new dvb_frontend.c becomes mainline - stv0299_check_inversion(i2c); - -// printk("stv0299 does not support auto-inversion\n"); -// return -EINVAL; + printk("stv0299 does not support auto-inversion\n"); + return -EINVAL; } - if (state->tuner_type == PHILIPS_SU1278_TSA_TT) { + switch(state->tuner_type) { + case PHILIPS_SU1278_TSA_TT: + { /* check if we should do a finetune */ int frequency_delta = p->frequency - state->tuner_frequency; int minmax = p->u.qpsk.symbol_rate / 2000; @@ -1118,23 +1105,30 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) // now set them as we want stv0299_writereg (i2c, 0x22, Drot_freq >> 8); stv0299_writereg (i2c, 0x23, Drot_freq); - break; + } else { + /* A "normal" tune is requested */ + pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate); + stv0299_writereg (i2c, 0x32, 0x80); + stv0299_writereg (i2c, 0x22, 0x00); + stv0299_writereg (i2c, 0x23, 0x00); + stv0299_writereg (i2c, 0x32, 0x19); + stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type); + stv0299_set_FEC (i2c, p->u.qpsk.fec_inner); } + break; + } + + default: + pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate); + stv0299_set_FEC (i2c, p->u.qpsk.fec_inner); + stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type); + stv0299_writereg (i2c, 0x22, 0x00); + stv0299_writereg (i2c, 0x23, 0x00); + stv0299_readreg (i2c, 0x23); + stv0299_writereg (i2c, 0x12, 0xb9); + break; } - /* A "normal" tune is requested */ - stv0299_writereg (i2c, 0x32, 0x80); - stv0299_writereg (i2c, 0x22, 0x00); - stv0299_writereg (i2c, 0x23, 0x00); - stv0299_writereg (i2c, 0x32, 0x19); - stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type); - stv0299_set_FEC (i2c, p->u.qpsk.fec_inner); - pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate); - dvb_delay(50); - stv0299_writereg (i2c, 0x22, 0x00); - stv0299_writereg (i2c, 0x23, 0x00); - pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate); - state->tuner_frequency = p->frequency; state->fec_inner = p->u.qpsk.fec_inner; state->symbol_rate = p->u.qpsk.symbol_rate; @@ -1172,10 +1166,17 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) break; case FE_INIT: - state->tuner_frequency = 0; - if (!state->initialised) { - state->initialised = 1; - return stv0299_init (i2c, state->tuner_type); + switch(state->tuner_type) { + case PHILIPS_SU1278_TSA_TT: + state->tuner_frequency = 0; + if (!state->initialised) { + state->initialised = 1; + return stv0299_init (i2c, state->tuner_type); + } + break; + + default: + return stv0299_init (i2c, state->tuner_type); } break; @@ -1191,7 +1192,38 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_SET_VOLTAGE: return stv0299_set_voltage (i2c, (fe_sec_voltage_t) arg); - default: + case FE_GET_TUNE_SETTINGS: + { + struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg; + + switch(state->tuner_type) { + case PHILIPS_SU1278_TSA_TT: + fesettings->min_delay_ms = 50; + if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { + fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; + fesettings->max_drift = 5000; + } else { + fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; + fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; + } + break; + + default: + fesettings->min_delay_ms = 100; + if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { + fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; + fesettings->max_drift = 5000; + } else { + fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; + fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; + } + break; + } + + return 0; + } + + default: return -EOPNOTSUPP; }; diff --git a/linux/drivers/media/dvb/frontends/ves1820.c b/linux/drivers/media/dvb/frontends/ves1820.c index 92aa249ef..410d3c2aa 100644 --- a/linux/drivers/media/dvb/frontends/ves1820.c +++ b/linux/drivers/media/dvb/frontends/ves1820.c @@ -111,8 +111,7 @@ static struct dvb_frontend_info ves1820_info = { #endif .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO | - FE_CAN_CLEAN_SETUP + FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO, }; diff --git a/linux/drivers/media/dvb/frontends/ves1x93.c b/linux/drivers/media/dvb/frontends/ves1x93.c index e6e6ba3fb..e8c1f6ee7 100644 --- a/linux/drivers/media/dvb/frontends/ves1x93.c +++ b/linux/drivers/media/dvb/frontends/ves1x93.c @@ -30,7 +30,8 @@ #include <linux/slab.h> #include "dvb_frontend.h" - +#include "dvb_functions.h" + static int debug = 0; #define dprintk if (debug) printk @@ -67,10 +68,10 @@ static struct dvb_frontend_info ves1x93_info = { */ static u8 init_1893_tab [] = { - 0x01, 0xa4, 0x35, 0x81, 0x2a, 0x0d, 0x55, 0xc4, + 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4, 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xdc, 0x00, + 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 @@ -247,8 +248,16 @@ static int ves1x93_clr_bit (struct dvb_i2c_bus *i2c) { ves1x93_writereg (i2c, 0, init_1x93_tab[0] & 0xfe); ves1x93_writereg (i2c, 0, init_1x93_tab[0]); + dvb_delay(5); + return 0; +} + +static int ves1x93_init_aquire (struct dvb_i2c_bus *i2c) +{ ves1x93_writereg (i2c, 3, 0x00); - return ves1x93_writereg (i2c, 3, init_1x93_tab[3]); + ves1x93_writereg (i2c, 3, init_1x93_tab[3]); + dvb_delay(5); + return 0; } @@ -403,6 +412,30 @@ static int ves1x93_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) } +static int ves1x93_afc (struct dvb_i2c_bus *i2c, u32 freq, u32 srate) +{ + int afc; + + u8 sync = ves1x93_readreg (i2c, 0x0e); + + afc = ((int)((ves1x93_readreg (i2c, 0x0a) << 1) & 0xff))/2; + afc = (afc * (int)(srate/1000/8))/16; + + if (afc) { + + freq -= afc; + + tuner_set_tv_freq (i2c, freq, 0); + + ves1x93_init_aquire (i2c); + + afc = ((int)((ves1x93_readreg (i2c, 0x0a) << 1) & 0xff))/2; + afc = (afc * (int)(srate/1000/8))/16; + } + + return 0; +} + static int ves1x93_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) { switch (voltage) { @@ -497,6 +530,7 @@ static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ves1x93_set_inversion (i2c, p->inversion); ves1x93_set_fec (i2c, p->u.qpsk.fec_inner); ves1x93_set_symbolrate (i2c, p->u.qpsk.symbol_rate); + ves1x93_afc (i2c, p->frequency, p->u.qpsk.symbol_rate); break; } @@ -530,9 +564,6 @@ static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_INIT: return ves1x93_init (i2c); - case FE_RESET: - return ves1x93_clr_bit (i2c); - case FE_SET_TONE: return -EOPNOTSUPP; /* the ves1893 can generate the 22k */ /* let's implement this when we have */ diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 601109de8..21162885b 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -6,6 +6,8 @@ * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM> * partially based on the Siemens DVB driver by Ralph+Marcus Metzler * + * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> + * * 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 @@ -34,44 +36,86 @@ #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/spinlock.h> #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) #include "input_fake.h" #endif +#define DEBIADDR_IR 0x1234 +#define DEBIADDR_CICONTROL 0x0000 +#define DEBIADDR_CIVERSION 0x4000 +#define DEBIADDR_CIIRQCONTROL 0x4000 + struct budget_ci { struct budget budget; struct input_dev input_dev; struct tasklet_struct msp430_irq_tasklet; + spinlock_t debilock; + int ci_present; char ir_dev_name[50]; }; -static u32 budget_debiread4 (struct saa7146_dev *saa, u32 config, int addr, int count) +static u32 budget_debiread (struct budget_ci* budget_ci, u32 config, int addr, int count) { - u32 result = 0; - + struct saa7146_dev *saa = budget_ci->budget.dev; + u32 result = 0; + if (count > 4 || count <= 0) return 0; - if (saa7146_wait_for_debi_done(saa) < 0) + spin_lock(budget_ci->debilock); + + if (saa7146_wait_for_debi_done(saa) < 0) { + spin_unlock(&budget_ci->debilock); return 0; - + } + saa7146_write (saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); - saa7146_write(saa, DEBI_CONFIG, config); + saa7146_write(saa, DEBI_PAGE, 0); saa7146_write(saa, MC2, (2 << 16) | 2); - + saa7146_wait_for_debi_done(saa); - result = saa7146_read(saa, DEBI_AD); + result = saa7146_read(saa, 0x88); result &= (0xffffffffUL >> ((4 - count) * 8)); + spin_unlock(&budget_ci->debilock); return result; } +static u8 budget_debiwrite (struct budget_ci* budget_ci, u32 config, int addr, int count, u32 value) +{ + struct saa7146_dev *saa = budget_ci->budget.dev; + + if (count > 4 || count <= 0) + return 0; + + spin_lock(&budget_ci->debilock); + + if (saa7146_wait_for_debi_done(saa) < 0) { + spin_unlock(&budget_ci->debilock); + return 0; + } + + saa7146_write (saa, DEBI_COMMAND, + (count << 17) | 0x00000 | (addr & 0xffff)); + saa7146_write(saa, DEBI_CONFIG, config); + saa7146_write(saa, DEBI_PAGE, 0); + saa7146_write(saa, DEBI_AD, value); + saa7146_write(saa, MC2, (2 << 16) | 2); + + saa7146_wait_for_debi_done(saa); + + spin_unlock(&budget_ci->debilock); + return 0; +} + + /* from reading the following remotes: Zenith Universal 7 / TV Mode 807 / VCR Mode 837 Hauppauge (from NOVA-CI-s box product) @@ -147,9 +191,8 @@ static void msp430_ir_debounce (unsigned long data) static void msp430_ir_interrupt (unsigned long data) { struct budget_ci *budget_ci = (struct budget_ci*) data; - struct saa7146_dev *saa = budget_ci->budget.dev; struct input_dev *dev = &budget_ci->input_dev; - unsigned int code = budget_debiread4(saa, DEBINOSWAP, 0x1234, 2) >> 8; + unsigned int code = budget_debiread(budget_ci, DEBINOSWAP, DEBIADDR_IR, 2) >> 8; if (code & 0x40) { code &= 0x3f; @@ -217,7 +260,6 @@ static void msp430_ir_deinit (struct budget_ci *budget_ci) saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); if (del_timer(&dev->timer)) input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0); @@ -225,6 +267,58 @@ static void msp430_ir_deinit (struct budget_ci *budget_ci) input_unregister_device(dev); } +static int ciintf_init(struct budget_ci* budget_ci) +{ + struct saa7146_dev *saa = budget_ci->budget.dev; + + // enable DEBI pins +transfers + saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x880 << 16) | 0x880); + + // test if it is there + if ((budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CIVERSION, 1) & 0xa0) != 0xa0) { + saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x880 << 16)); + return -ENODEV; + } + + // reset CI interface + budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0); + dvb_delay(1); + budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 1); + + // clear any CI interrupt status + budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CIIRQCONTROL, 1, 0xC0); + + // FIXME: register CI slot + + // Setup CI slot IRQ + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); + budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0xc1); + + // FIXME: route TS data out to CI interface +// saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); + + // success! + printk("budget_ci: CI interface detected\n"); + budget_ci->ci_present = 1; + return 0; +} + +static void ciintf_deinit(struct budget_ci* budget_ci) +{ + struct saa7146_dev *saa = budget_ci->budget.dev; + + // disable CI interrupts + budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0x1); + saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03); + saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); + + // FIXME: disable TS data stream to CI interface + saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); + + // disable DEBI pins+transfers again + saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x880 << 16)); +} static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr) { @@ -237,6 +331,9 @@ static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr) if (*isr & MASK_10) ttpci_budget_irq10_handler (dev, isr); + + if (*isr & MASK_03) + printk("CI IRQ!!\n"); } @@ -252,6 +349,9 @@ static int budget_ci_attach (struct saa7146_dev* dev, DEB_EE(("budget_ci: %p\n", budget_ci)); + spin_lock_init(budget_ci->debilock); + budget_ci->ci_present = 0; + if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) { kfree (budget_ci); return err; @@ -263,6 +363,8 @@ static int budget_ci_attach (struct saa7146_dev* dev, (unsigned long) budget_ci); msp430_ir_init (budget_ci); + + ciintf_init(budget_ci); return 0; } @@ -272,7 +374,8 @@ static int budget_ci_attach (struct saa7146_dev* dev, static int budget_ci_detach (struct saa7146_dev* dev) { struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv; - int err; + struct saa7146_dev *saa = budget_ci->budget.dev; + int err; err = ttpci_budget_deinit (&budget_ci->budget); @@ -280,6 +383,11 @@ static int budget_ci_detach (struct saa7146_dev* dev) msp430_ir_deinit (budget_ci); + if (budget_ci->ci_present) ciintf_deinit(budget_ci); + + // disable frontend and CI interface + saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); + kfree (budget_ci); return err; @@ -312,7 +420,7 @@ static struct saa7146_extension budget_extension = { .attach = budget_ci_attach, .detach = budget_ci_detach, - .irq_mask = MASK_06 | MASK_10, + .irq_mask = MASK_03 | MASK_06 | MASK_10, .irq_func = budget_ci_irq, }; @@ -333,7 +441,7 @@ module_init(budget_ci_init); module_exit(budget_ci_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Michael Hunold, Jack Thomasson, others"); +MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others"); MODULE_DESCRIPTION("driver for the SAA7146 based so-called " "budget PCI DVB cards w/ CI-module produced by " "Siemens, Technotrend, Hauppauge"); diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 1b75b7af0..591d05389 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1586,10 +1586,6 @@ static int ttusb_dec_2000t_frontend_ioctl(struct dvb_frontend *fe, unsigned int dprintk("%s: FE_INIT\n", __FUNCTION__); break; - case FE_RESET: - dprintk("%s: FE_RESET\n", __FUNCTION__); - break; - default: dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd); return -EINVAL; @@ -1701,10 +1697,6 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, dprintk("%s: FE_INIT\n", __FUNCTION__); break; - case FE_RESET: - dprintk("%s: FE_RESET\n", __FUNCTION__); - break; - case FE_DISEQC_SEND_MASTER_CMD: dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__); break; |