V4L/DVB (9344): DVB-Core update

Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Manu Abraham 2008-10-14 16:34:07 -03:00 committed by Mauro Carvalho Chehab
parent a12ca6a6e1
commit c59e7870fd
2 changed files with 192 additions and 8 deletions

View file

@ -128,6 +128,7 @@ struct dvb_frontend_private {
unsigned int step_size;
int quality;
unsigned int check_wrapped;
enum dvbfe_search algo_status;
};
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@ -516,6 +517,8 @@ static int dvb_frontend_thread(void *data)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
unsigned long timeout;
fe_status_t s;
enum dvbfe_algo algo;
struct dvb_frontend_parameters *params;
dprintk("%s\n", __func__);
@ -562,23 +565,72 @@ static int dvb_frontend_thread(void *data)
/* do an iteration of the tuning loop */
if (fe->ops.get_frontend_algo) {
if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
/* have we been asked to retune? */
params = NULL;
algo = fe->ops.get_frontend_algo(fe);
switch (algo) {
case DVBFE_ALGO_HW:
dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
params = NULL; /* have we been asked to RETUNE ? */
if (fepriv->state & FESTATE_RETUNE) {
params = &fepriv->parameters;
dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
fepriv->state = FESTATE_TUNED;
}
fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
if (fe->ops.tune)
fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
if (s != fepriv->status) {
dprintk("%s: state changed, adding current state\n", __func__);
dvb_frontend_add_event(fe, s);
fepriv->status = s;
}
} else
break;
case DVBFE_ALGO_SW:
dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
dvb_frontend_swzigzag(fe);
} else
break;
case DVBFE_ALGO_CUSTOM:
params = NULL; /* have we been asked to RETUNE ? */
dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
if (fepriv->state & FESTATE_RETUNE) {
dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
fepriv->state = FESTATE_TUNED;
}
/* Case where we are going to search for a carrier
* User asked us to retune again for some reason, possibly
* requesting a search with a new set of parameters
*/
if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
if (fe->ops.search)
fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters);
/* We did do a search as was requested, the flags are
* now unset as well and has the flags wrt to search.
*/
fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN;
}
/* Track the carrier if the search was successful */
if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
if (fepriv->algo_status & DVBFE_ALGO_SEARCH_SUCCESS)
dprintk("%s: status = DVBFE_ALGO_SEARCH_SUCCESS\n", __func__);
if (fepriv->algo_status & DVBFE_ALGO_SEARCH_FAILED)
fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
fe->ops.read_status(fe, &s);
dvb_frontend_add_event(fe, s); /* update event list */
fepriv->status = s;
if (fe->ops.track)
fe->ops.track(fe, &fepriv->parameters);
}
break;
default:
dprintk("%s: UNDEFINED ALGO !\n", __func__);
break;
}
} else {
dvb_frontend_swzigzag(fe);
}
}
if (dvb_powerdown_on_sleep) {

View file

@ -69,6 +69,125 @@ struct analog_parameters {
u64 std;
};
enum dvbfe_modcod {
DVBFE_MODCOD_DUMMY_PLFRAME = 0,
DVBFE_MODCOD_QPSK_1_4,
DVBFE_MODCOD_QPSK_1_3,
DVBFE_MODCOD_QPSK_2_5,
DVBFE_MODCOD_QPSK_1_2,
DVBFE_MODCOD_QPSK_3_5,
DVBFE_MODCOD_QPSK_2_3,
DVBFE_MODCOD_QPSK_3_4,
DVBFE_MODCOD_QPSK_4_5,
DVBFE_MODCOD_QPSK_5_6,
DVBFE_MODCOD_QPSK_8_9,
DVBFE_MODCOD_QPSK_9_10,
DVBFE_MODCOD_8PSK_3_5,
DVBFE_MODCOD_8PSK_2_3,
DVBFE_MODCOD_8PSK_3_4,
DVBFE_MODCOD_8PSK_5_6,
DVBFE_MODCOD_8PSK_8_9,
DVBFE_MODCOD_8PSK_9_10,
DVBFE_MODCOD_16APSK_2_3,
DVBFE_MODCOD_16APSK_3_4,
DVBFE_MODCOD_16APSK_4_5,
DVBFE_MODCOD_16APSK_5_6,
DVBFE_MODCOD_16APSK_8_9,
DVBFE_MODCOD_16APSK_9_10,
DVBFE_MODCOD_32APSK_3_4,
DVBFE_MODCOD_32APSK_4_5,
DVBFE_MODCOD_32APSK_5_6,
DVBFE_MODCOD_32APSK_8_9,
DVBFE_MODCOD_32APSK_9_10,
DVBFE_MODCOD_RESERVED_1,
DVBFE_MODCOD_BPSK_1_3,
DVBFE_MODCOD_BPSK_1_4,
DVBFE_MODCOD_RESERVED_2
};
enum tuner_param {
DVBFE_TUNER_FREQUENCY = (1 << 0),
DVBFE_TUNER_TUNERSTEP = (1 << 1),
DVBFE_TUNER_IFFREQ = (1 << 2),
DVBFE_TUNER_BANDWIDTH = (1 << 3),
DVBFE_TUNER_REFCLOCK = (1 << 4),
DVBFE_TUNER_IQSENSE = (1 << 5),
DVBFE_TUNER_DUMMY = (1 << 31)
};
/*
* ALGO_HW: (Hardware Algorithm)
* ----------------------------------------------------------------
* Devices that support this algorithm do everything in hardware
* and no software support is needed to handle them.
* Requesting these devices to LOCK is the only thing required,
* device is supposed to do everything in the hardware.
*
* ALGO_SW: (Software Algorithm)
* ----------------------------------------------------------------
* These are dumb devices, that require software to do everything
*
* ALGO_CUSTOM: (Customizable Agorithm)
* ----------------------------------------------------------------
* Devices having this algorithm can be customized to have specific
* algorithms in the frontend driver, rather than simply doing a
* software zig-zag. In this case the zigzag maybe hardware assisted
* or it maybe completely done in hardware. In all cases, usage of
* this algorithm, in conjunction with the search and track
* callbacks, utilizes the driver specific algorithm.
*
* ALGO_RECOVERY: (Recovery Algorithm)
* ----------------------------------------------------------------
* These devices have AUTO recovery capabilities from LOCK failure
*/
enum dvbfe_algo {
DVBFE_ALGO_HW = (1 << 0),
DVBFE_ALGO_SW = (1 << 1),
DVBFE_ALGO_CUSTOM = (1 << 2),
DVBFE_ALGO_RECOVERY = (1 << 31)
};
struct tuner_state {
u32 frequency;
u32 tunerstep;
u32 ifreq;
u32 bandwidth;
u32 iqsense;
u32 refclock;
};
/*
* search callback possible return status
*
* DVBFE_ALGO_SEARCH_SUCCESS
* The frontend search algorithm completed and returned succesfully
*
* DVBFE_ALGO_SEARCH_ASLEEP
* The frontend search algorithm is sleeping
*
* DVBFE_ALGO_SEARCH_FAILED
* The frontend search for a signal failed
*
* DVBFE_ALGO_SEARCH_INVALID
* The frontend search algorith was probably supplied with invalid
* parameters and the search is an invalid one
*
* DVBFE_ALGO_SEARCH_ERROR
* The frontend search algorithm failed due to some error
*
* DVBFE_ALGO_SEARCH_AGAIN
* The frontend search algorithm was requested to search again
*/
enum dvbfe_search {
DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1),
DVBFE_ALGO_SEARCH_FAILED = (1 << 2),
DVBFE_ALGO_SEARCH_INVALID = (1 << 3),
DVBFE_ALGO_SEARCH_AGAIN = (1 << 4),
DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
};
struct dvb_tuner_ops {
struct dvb_tuner_info info;
@ -99,6 +218,13 @@ struct dvb_tuner_ops {
* tuners which require sophisticated tuning loops, controlling each parameter seperately. */
int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
/*
* These are provided seperately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter seperately.
*/
int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
};
struct analog_demod_info {
@ -142,7 +268,7 @@ struct dvb_frontend_ops {
unsigned int *delay,
fe_status_t *status);
/* get frontend tuning algorithm from the module */
int (*get_frontend_algo)(struct dvb_frontend *fe);
enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
/* these two are only used for the swzigzag code */
int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
@ -167,6 +293,12 @@ struct dvb_frontend_ops {
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
/* These callbacks are for devices that implement their own
* tuning algorithms, rather than a simple swzigzag
*/
enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
struct dvb_tuner_ops tuner_ops;
struct analog_demod_ops analog_ops;