/* Close FE */
if (lfe->lfe_fe_fd > 0 && !lfe->lfe_refcount && lfe->lfe_powersave) {
+ if (linuxdvb_satconf_power_save(lfe->lfe_satconf) > 0) {
+ /* re-arm */
+ mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, sec2mono(1));
+ return;
+ }
linuxdvb_frontend_close_fd(lfe, buf);
return;
}
*/
linuxdvb_satconf_ele_list_t ls_elements;
linuxdvb_satconf_ele_t *ls_last_switch;
+ linuxdvb_diseqc_t *ls_active_diseqc;
int ls_last_switch_pol;
int ls_last_switch_band;
int ls_last_vol;
int ls_last_toneburst;
int ls_last_tone_off;
int ls_last_orbital_pos;
+ int ls_last_queued_pos;
};
/*
int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm);
int (*ld_freq) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, int freq);
int (*ld_match) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm1, dvb_mux_t *lm2);
+ int (*ld_start) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
+ linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls);
int (*ld_tune) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
int vol, int pol, int band, int freq);
- int (*ld_post) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
+ int (*ld_post) (linuxdvb_diseqc_t *ld,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls);
};
void linuxdvb_satconf_post_stop_mux( linuxdvb_satconf_t *ls );
+int linuxdvb_satconf_power_save( linuxdvb_satconf_t *ls );
+
int linuxdvb_satconf_start_mux
( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi, int skip_diseqc );
int vol, int pol, int band, int freq )
{
linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
+ int res;
if (linuxdvb_rotor_check_orbital_pos(lr, lm, ls))
return 0;
/* GotoX */
if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_gotox_class))
- return linuxdvb_rotor_gotox_tune(lr, lm, lsp, ls);
-
+ res = linuxdvb_rotor_gotox_tune(lr, lm, lsp, ls);
/* USALS */
- return linuxdvb_rotor_usals_tune(lr, lm, lsp, ls);
+ else
+ res = linuxdvb_rotor_usals_tune(lr, lm, lsp, ls);
+
+ if (res < 0)
+ return res;
+
+ lsp->ls_last_queued_pos = pos_to_integer(lr->lr_sat_lon);
+ return res;
}
static int
-linuxdvb_rotor_post
+linuxdvb_rotor_start
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls )
{
linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
+ int pos = pos_to_integer(lr->lr_sat_lon);
+ if (lsp->ls_last_queued_pos == pos)
+ return 1;
+ lsp->ls_last_queued_pos = 0;
+ return 0;
+}
+
+static int
+linuxdvb_rotor_post
+ ( linuxdvb_diseqc_t *ld,
+ linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls )
+{
+ linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
lsp->ls_last_orbital_pos = pos_to_integer(lr->lr_sat_lon);
+ lsp->ls_last_queued_pos = 0;
return 0;
}
NULL, linuxdvb_rotor_all[i].idc, conf,
linuxdvb_rotor_all[i].name, ls);
if (ld) {
+ ld->ld_start = linuxdvb_rotor_start;
ld->ld_tune = linuxdvb_rotor_tune;
ld->ld_grace = linuxdvb_rotor_grace;
ld->ld_post = linuxdvb_rotor_post;
( linuxdvb_satconf_t *ls )
{
ls->ls_mmi = NULL;
+}
+
+int
+linuxdvb_satconf_power_save
+ ( linuxdvb_satconf_t *ls )
+{
+ if (ls->ls_active_diseqc) /* wait for the timer to finish things */
+ return 1;
mtimer_disarm(&ls->ls_diseqc_timer);
if (ls->ls_frontend && ls->ls_lnb_poweroff) {
linuxdvb_diseqc_set_volt(ls, -1);
linuxdvb_satconf_reset(ls);
}
+ return 0;
}
int
/* Get beans in a row */
mpegts_mux_instance_t *mmi = ls->ls_mmi;
+
+ if (mmi == NULL && ls->ls_active_diseqc) {
+ /* handle the rotor position update */
+ if (ls->ls_active_diseqc == lse->lse_rotor)
+ lse->lse_rotor->ld_post(lse->lse_rotor, ls, lse);
+ ls->ls_active_diseqc = NULL;
+ linuxdvb_satconf_power_save(ls);
+ return 0;
+ }
+
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend;
dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux;
linuxdvb_diseqc_t *lds[] = {
}
/* Diseqc */
+ ls->ls_active_diseqc = NULL;
for (i = ls->ls_diseqc_idx; i < ARRAY_SIZE(lds); i++) {
if (!lds[i]) continue;
r = lds[i]->ld_tune(lds[i], lm, ls, lse, vol, pol, band, freq);
/* Pending */
if (r != 0) {
+ ls->ls_active_diseqc = lds[i];
tvhtrace(LS_DISEQC, "waiting %d seconds to finish setup for %s", r, lds[i]->ld_type);
mtimer_arm_rel(&ls->ls_diseqc_timer, linuxdvb_satconf_ele_tune_cb, lse, sec2mono(r));
ls->ls_diseqc_idx = i + 1;
/* Do post things (store position for rotor) */
if (lse->lse_rotor)
- lse->lse_rotor->ld_post(lse->lse_rotor, lm, ls, lse);
+ lse->lse_rotor->ld_post(lse->lse_rotor, ls, lse);
/* LNB settings */
/* EN50494 devices have another mechanism to select polarization */
/* Diseqc */
ls->ls_mmi = mmi;
ls->ls_diseqc_idx = 0;
+ if (lse->lse_rotor)
+ if (lse->lse_rotor->ld_start(lse->lse_rotor, (dvb_mux_t *)mmi->mmi_mux, ls, lse))
+ return 0;
+
return linuxdvb_satconf_ele_tune(lse);
}