linuxdvb: improve diseqc switch handling, cleanups

This commit is contained in:
Jaroslav Kysela 2015-03-22 16:40:58 +01:00
parent c61be4ed90
commit 93f3f6fbdd
6 changed files with 84 additions and 79 deletions

View file

@ -158,16 +158,11 @@ const idclass_t linuxdvb_en50494_class =
static int
linuxdvb_en50494_tune
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc, int vol )
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc,
int vol, int pol, int band, int freq )
{
int ret = 0, i, fd = linuxdvb_satconf_fe_fd(lsp);
linuxdvb_en50494_t *le = (linuxdvb_en50494_t*) ld;
linuxdvb_lnb_t *lnb = sc->lse_lnb;
/* band & polarization */
uint8_t pol = lnb->lnb_pol(lnb, lm);
uint8_t band = lnb->lnb_band(lnb, lm);
uint32_t freq = lnb->lnb_freq(lnb, lm);
/* transponder value - t*/
uint16_t t = round((( (freq / 1000) + 2 + le->le_frequency) / 4) - 350);

View file

@ -111,16 +111,10 @@ linuxdvb_lnb_inverted_pol
static int
linuxdvb_lnb_standard_tune
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
int vol, int pol, int band, int freq )
{
/* en50494 does not use the voltage tune. this is happend in the switch */
if (ls->lse_en50494)
return 0;
/* note: differentiate between linuxdvb_lnb_standard_pol / linuxdvb_lnb_inverted_pol */
int pol = ((linuxdvb_lnb_t*)ld)->lnb_pol((linuxdvb_lnb_t*)ld, lm);
return linuxdvb_diseqc_set_volt(ls->lse_parent, pol);
return linuxdvb_diseqc_set_volt(ls->lse_parent, vol);
}
/*
@ -160,20 +154,6 @@ linuxdvb_lnb_bandstack_pol
return 0;
}
static int
linuxdvb_lnb_bandstack_tune
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
{
int pol = linuxdvb_lnb_bandstack_pol((linuxdvb_lnb_t*)ld, lm);
/* en50494 does not use the voltage tune. this is happend in the switch */
if (ls->lse_en50494)
return 0;
return linuxdvb_diseqc_set_volt(ls->lse_parent, pol);
}
/* **************************************************************************
* Static list
* *************************************************************************/
@ -312,7 +292,7 @@ struct linuxdvb_lnb_conf linuxdvb_lnb_all[] = {
{
{ {
.ld_type = "DBS Bandstack",
.ld_tune = linuxdvb_lnb_bandstack_tune,
.ld_tune = linuxdvb_lnb_standard_tune,
},
.lnb_freq = linuxdvb_lnb_bandstack_freq,
.lnb_band = linuxdvb_lnb_bandstack_band,

View file

@ -168,6 +168,8 @@ struct linuxdvb_satconf
*/
linuxdvb_satconf_ele_list_t ls_elements;
linuxdvb_satconf_ele_t *ls_last_switch;
int ls_last_switch_pol;
int ls_last_switch_band;
int ls_last_vol;
int ls_last_toneburst;
int ls_last_tone_off;
@ -214,7 +216,8 @@ struct linuxdvb_diseqc
linuxdvb_satconf_ele_t *ld_satconf;
int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm);
int (*ld_tune) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int pol);
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,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls);
};

View file

@ -401,7 +401,8 @@ linuxdvb_rotor_usals_tune
static int
linuxdvb_rotor_tune
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
int vol, int pol, int band, int freq )
{
linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;

View file

@ -720,7 +720,7 @@ static void linuxdvb_satconf_ele_tune_cb ( void *o );
static int
linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
{
int r, i, b, pol;
int r, i, vol, pol, band, freq;
uint32_t f;
linuxdvb_satconf_t *ls = lse->lse_parent;
@ -737,10 +737,18 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
(linuxdvb_diseqc_t*)lse->lse_lnb
};
if (!lse->lse_en50494) {
pol = (lse->lse_lnb) ? lse->lse_lnb->lnb_pol(lse->lse_lnb, lm) & 0x1 : 0;
if (lse->lse_lnb) {
pol = lse->lse_lnb->lnb_pol (lse->lse_lnb, lm) & 0x1;
band = lse->lse_lnb->lnb_band(lse->lse_lnb, lm) & 0x1;
freq = lse->lse_lnb->lnb_freq(lse->lse_lnb, lm);
} else {
pol = 0; /* 13V */
tvherror("linuxdvb", "LNB is not defined!!!");
return -1;
}
if (!lse->lse_en50494) {
vol = pol;
} else {
vol = 0; /* 13V */
}
/*
@ -753,7 +761,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
if (!lse->lse_en50494 || lse->lse_switch || lse->lse_rotor) {
if (ls->ls_diseqc_full) {
ls->ls_last_tone_off = 0; /* force */
if (linuxdvb_satconf_start(ls, 0, pol))
if (linuxdvb_satconf_start(ls, 0, vol))
return -1;
}
}
@ -761,7 +769,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
/* Diseqc */
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, pol);
r = lds[i]->ld_tune(lds[i], lm, ls, lse, vol, pol, band, freq);
/* Error */
if (r < 0) return r;
@ -781,23 +789,21 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
/* LNB settings */
/* EN50494 devices have another mechanism to select polarization */
if (!lse->lse_en50494) {
/* Set the voltage */
if (linuxdvb_diseqc_set_volt(ls, pol))
return -1;
}
/* Set the voltage */
if (linuxdvb_diseqc_set_volt(ls, vol))
return -1;
/* Set the tone (en50494 don't use tone) */
if (!lse->lse_en50494) {
b = lse->lse_lnb->lnb_band(lse->lse_lnb, lm);
if (ls->ls_diseqc_full || ls->ls_last_tone_off != b + 1) {
if (ls->ls_last_tone_off != band + 1) {
ls->ls_last_tone_off = 0;
tvhtrace("diseqc", "set diseqc tone %s", b ? "on" : "off");
if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, b ? SEC_TONE_ON : SEC_TONE_OFF)) {
tvhtrace("diseqc", "set diseqc tone %s", band ? "on" : "off");
if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, band ? SEC_TONE_ON : SEC_TONE_OFF)) {
tvherror("diseqc", "failed to set diseqc tone (e=%s)", strerror(errno));
return -1;
}
ls->ls_last_tone_off = b + 1;
ls->ls_last_tone_off = band + 1;
usleep(20000); // Allow LNB to settle before tuning
}
}
@ -806,7 +812,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
/* use en50494 tuning frequency, if needed (not channel frequency) */
f = lse->lse_en50494
? ((linuxdvb_en50494_t*)lse->lse_en50494)->le_tune_freq
: lse->lse_lnb->lnb_freq(lse->lse_lnb, lm);
: freq;
return linuxdvb_frontend_tune1(lfe, mmi, f);
}

View file

@ -43,6 +43,8 @@ typedef struct linuxdvb_switch
int ls_toneburst;
int ls_committed;
int ls_uncommitted;
int ls_uncommitted_first;
int ls_sleep_time; /* in ms */
} linuxdvb_switch_t;
@ -134,6 +136,18 @@ const idclass_t linuxdvb_switch_class =
.off = offsetof(linuxdvb_switch_t, ls_toneburst),
.list = linuxdvb_switch_class_toneburst_list
},
{
.type = PT_BOOL,
.id = "preferun",
.name = "Uncommited First",
.off = offsetof(linuxdvb_switch_t, ls_uncommitted_first),
},
{
.type = PT_INT,
.id = "sleeptime",
.name = "Cmd Delay Time (ms) (10-500)",
.off = offsetof(linuxdvb_switch_t, ls_sleep_time)
},
{}
}
};
@ -145,60 +159,66 @@ const idclass_t linuxdvb_switch_class =
static int
linuxdvb_switch_tune
( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp,
linuxdvb_satconf_ele_t *sc, int vol )
linuxdvb_satconf_ele_t *sc, int vol, int pol, int band, int freq )
{
int i, com, r1 = 0, r2 = 0;
int pol, band;
int i, com, r1 = 0, r2 = 0, slp;
int fd = linuxdvb_satconf_fe_fd(lsp);
linuxdvb_switch_t *ls = (linuxdvb_switch_t*)ld;
if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc) {
if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc ||
(ls->ls_committed >= 0 &&
(pol + 1 != lsp->ls_last_switch_pol ||
band + 1 != lsp->ls_last_switch_band))) {
lsp->ls_last_switch = NULL;
if (linuxdvb_satconf_start(lsp, 1, vol))
if (linuxdvb_satconf_start(lsp, 1, pol))
return -1;
pol = (sc->lse_lnb) ? sc->lse_lnb->lnb_pol (sc->lse_lnb, lm) & 0x1 : 0;
band = (sc->lse_lnb) ? sc->lse_lnb->lnb_band(sc->lse_lnb, lm) & 0x1 : 0;
com = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band;
/* Single committed (before repeats) */
if (ls->ls_committed >= 0) {
if (lsp->ls_diseqc_repeats > 0) {
r2 = 1;
if (linuxdvb_diseqc_send(fd, 0xE0, 0x10, 0x38, 1, com))
return -1;
usleep(25000); // 25ms
}
}
com = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band;
slp = ls->ls_sleep_time > 10 ?
MAX(500, MIN(25, ls->ls_sleep_time)) * 1000 :
25000;
/* Repeats */
for (i = 0; i <= lsp->ls_diseqc_repeats; i++) {
/* Uncommitted */
if (ls->ls_uncommitted >= 0) {
if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x39, 1,
0xF0 | ls->ls_uncommitted))
return -1;
usleep(25000);
}
if (ls->ls_uncommitted_first)
/* Uncommitted */
if (ls->ls_uncommitted >= 0) {
if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1,
0xF0 | ls->ls_uncommitted))
return -1;
usleep(slp);
}
/* Committed */
if (ls->ls_committed >= 0) {
if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x38, 1, com))
if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x38, 1, com))
return -1;
usleep(25000);
usleep(slp);
}
if (!ls->ls_uncommitted_first) {
/* Uncommitted */
if (ls->ls_uncommitted >= 0) {
if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1,
0xF0 | ls->ls_uncommitted))
return -1;
usleep(slp);
}
}
/* repeat flag */
r1 = r2 = 1;
}
lsp->ls_last_switch = sc;
lsp->ls_last_switch = sc;
lsp->ls_last_switch_pol = pol + 1;
lsp->ls_last_switch_band = band + 1;
/* port was changed, new LNB has not received toneburst yet */
lsp->ls_last_toneburst = 0;
lsp->ls_last_toneburst = 0;
}
/* Tone burst */