Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
linuxdvb: unicable - add support for Unicable II (untested)
  • Loading branch information
perexg committed Sep 20, 2016
1 parent 817f67e commit 766f2fd
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 26 deletions.
131 changes: 112 additions & 19 deletions src/input/mpegts/linuxdvb/linuxdvb_en50494.c
Expand Up @@ -53,6 +53,9 @@
#define LINUXDVB_EN50494_SAT_A 0x00
#define LINUXDVB_EN50494_SAT_B 0x01

/* EN50607 */
#define LINUXDVB_EN50607_FRAME_NORMAL 0x70
#define LINUXDVB_EN50607_FRAME_MULTIHOME 0x71

/* **************************************************************************
* Class definition
Expand All @@ -64,7 +67,14 @@ static pthread_mutex_t linuxdvb_en50494_lock;
static const char *
linuxdvb_en50494_class_get_title ( idnode_t *o, const char *lang )
{
static const char *title = N_("Unicable");
static const char *title = N_("Unicable I (EN50494)");
return tvh_gettext_lang(lang, title);
}

static const char *
linuxdvb_en50607_class_get_title ( idnode_t *o, const char *lang )
{
static const char *title = N_("Unicable II (EN50607)");
return tvh_gettext_lang(lang, title);
}

Expand All @@ -91,6 +101,17 @@ linuxdvb_en50494_id_list ( void *o, const char *lang )
}

htsmsg_t *
linuxdvb_en50607_id_list ( void *o, const char *lang )
{
uint32_t i;
htsmsg_t *m = htsmsg_create_list();
for (i = 0; i < 32; i++) {
htsmsg_add_u32(m, NULL, i);
}
return m;
}

static htsmsg_t *
linuxdvb_en50494_pin_list ( void *o, const char *lang )
{
int32_t i;
Expand All @@ -113,6 +134,7 @@ linuxdvb_en50494_pin_list ( void *o, const char *lang )
}

extern const idclass_t linuxdvb_diseqc_class;

const idclass_t linuxdvb_en50494_class =
{
.ic_super = &linuxdvb_diseqc_class,
Expand Down Expand Up @@ -151,6 +173,44 @@ const idclass_t linuxdvb_en50494_class =
}
};

const idclass_t linuxdvb_en50607_class =
{
.ic_super = &linuxdvb_diseqc_class,
.ic_class = "linuxdvb_en50607",
.ic_caption = N_("en50607"),
.ic_get_title = linuxdvb_en50607_class_get_title,
.ic_properties = (const property_t[]) {
{
.type = PT_U16,
.id = "position",
.name = N_("Position"),
.off = offsetof(linuxdvb_en50494_t, le_position),
.list = linuxdvb_en50494_position_list,
},
{
.type = PT_U16,
.id = "frequency",
.name = N_("Frequency"),
.off = offsetof(linuxdvb_en50494_t, le_frequency),
},
{
.type = PT_U16,
.id = "id",
.name = N_("SCR (ID)"),
.off = offsetof(linuxdvb_en50494_t, le_id),
.list = linuxdvb_en50607_id_list,
},
{
.type = PT_U16,
.id = "pin",
.name = N_("PIN"),
.off = offsetof(linuxdvb_en50494_t, le_pin),
.list = linuxdvb_en50494_pin_list,
},
{}
}
};

/* **************************************************************************
* Class methods
* *************************************************************************/
Expand Down Expand Up @@ -198,22 +258,34 @@ linuxdvb_en50494_tune
int vol, int pol, int band, int freq )
{
int ret = 0, i, fd = linuxdvb_satconf_fe_fd(lsp), rfreq;
int ver2 = linuxdvb_unicable_is_en50607(ld->ld_type);
linuxdvb_en50494_t *le = (linuxdvb_en50494_t*) ld;
uint8_t data1, data2, data3;
uint16_t t;

/* tune frequency for the frontend */
if (linuxdvb_en50494_freq0(le, freq, &rfreq, &t))
return -1;
le->le_tune_freq = rfreq;

/* 2 data fields (16bit) */
uint8_t data1, data2;
data1 = (le->le_id & 7) << 5; /* 3bit user-band */
data1 |= (le->le_position & 1) << 4; /* 1bit position (satellite A(0)/B(1)) */
data1 |= (pol & 1) << 3; /* 1bit polarization v(0)/h(1) */
data1 |= (band & 1) << 2; /* 1bit band lower(0)/upper(1) */
data1 |= (t >> 8) & 3; /* 2bit transponder value bit 1-2 */
data2 = t & 0xFF; /* 8bit transponder value bit 3-10 */
if (!ver2) {
/* 2 data fields (16bit) */
data1 = (le->le_id & 7) << 5; /* 3bit user-band */
data1 |= (le->le_position & 1) << 4; /* 1bit position (satellite A(0)/B(1)) */
data1 |= (pol & 1) << 3; /* 1bit polarization v(0)/h(1) */
data1 |= (band & 1) << 2; /* 1bit band lower(0)/upper(1) */
data1 |= (t >> 8) & 3; /* 2bit transponder value bit 1-2 */
data2 = t & 0xff; /* 8bit transponder value bit 3-10 */
data3 = 0;
} else {
/* 3 data fields (24bit) */
data1 = (le->le_id & 0x1f) << 3; /* 5bit user-band */
data1 |= (t >> 8) & 7; /* 3bit transponder value bit 1-3 */
data2 = t & 0xff; /* 8bit transponder value bit 4-11 */
data3 = (le->le_position & 0x3f) << 2; /* 6bit position */
data3 |= (pol & 1) << 1; /* 1bit polarization v(0)/h(1) */
data3 |= band & 1; /* 1bit band lower(0)/upper(1) */
}

/* wait until no other thread is setting up switch.
* when an other thread was blocking, waiting 20ms.
Expand Down Expand Up @@ -247,23 +319,33 @@ linuxdvb_en50494_tune

/* send tune command (with/without pin) */
tvhdebug(LS_EN50494,
"lnb=%i id=%i freq=%i pin=%i v/h=%i l/u=%i f=%i, data=0x%02X%02X",
"lnb=%i id=%i freq=%i pin=%i v/h=%i l/u=%i f=%i, data=0x%02X%02X%02X",
le->le_position, le->le_id, le->le_frequency, le->le_pin, pol,
band, freq, data1, data2);
if (le->le_pin != LINUXDVB_EN50494_NOPIN) {
band, freq, data1, data2, data3);
if (!ver2 && le->le_pin != LINUXDVB_EN50494_NOPIN) {
ret = linuxdvb_diseqc_send(fd,
LINUXDVB_EN50494_FRAME,
LINUXDVB_EN50494_ADDRESS,
LINUXDVB_EN50494_CMD_NORMAL_MULTIHOME,
3,
data1, data2, (uint8_t)le->le_pin);
} else {
} else if (!ver2) {
ret = linuxdvb_diseqc_send(fd,
LINUXDVB_EN50494_FRAME,
LINUXDVB_EN50494_ADDRESS,
LINUXDVB_EN50494_CMD_NORMAL,
2,
data1, data2);
} else if (ver2 && le->le_pin != LINUXDVB_EN50494_NOPIN) {
ret = linuxdvb_diseqc_raw_send(fd,
LINUXDVB_EN50607_FRAME_MULTIHOME,
4,
data1, data2, data3, (uint8_t)le->le_pin);
} else if (ver2) {
ret = linuxdvb_diseqc_raw_send(fd,
LINUXDVB_EN50607_FRAME_NORMAL,
3,
data1, data2, data3);
}
if (ret != 0) {
tvherror(LS_EN50494, "error send tune command");
Expand Down Expand Up @@ -301,7 +383,8 @@ linuxdvb_en50494_list ( void *o, const char *lang )
{
htsmsg_t *m = htsmsg_create_list();
htsmsg_add_str(m, NULL, tvh_gettext_lang(lang, N_("None")));
htsmsg_add_str(m, NULL, tvh_gettext_lang(lang, N_("Generic")));
htsmsg_add_str(m, NULL, tvh_gettext_lang(lang, N_(UNICABLE_I_NAME)));
htsmsg_add_str(m, NULL, tvh_gettext_lang(lang, N_(UNICABLE_II_NAME)));
return m;
}

Expand All @@ -312,14 +395,21 @@ linuxdvb_en50494_create0
linuxdvb_diseqc_t *ld;
linuxdvb_en50494_t *le;

if (strcmp(name ?: "", "Generic"))
if (strcmp(name ?: "", "Generic") &&
strcmp(name ?: "", UNICABLE_I_NAME) &&
strcmp(name ?: "", UNICABLE_II_NAME))
return NULL;

if (port > 1) {
if (linuxdvb_unicable_is_en50494(name) && port > 1) {
tvherror(LS_EN50494, "only 2 ports/positions are possible. given %i", port);
port = 0;
}

if (linuxdvb_unicable_is_en50607(name) && port > 63) {
tvherror(LS_EN50494, "only 64 ports/positions are possible. given %i", port);
port = 0;
}

le = calloc(1, sizeof(linuxdvb_en50494_t));
if (le == NULL)
return NULL;
Expand All @@ -331,10 +421,13 @@ linuxdvb_en50494_create0
le->ld_match = linuxdvb_en50494_match;

ld = linuxdvb_diseqc_create0((linuxdvb_diseqc_t *)le,
NULL, &linuxdvb_en50494_class, conf,
"Generic", ls);
NULL,
linuxdvb_unicable_is_en50607(name) ?
&linuxdvb_en50607_class :
&linuxdvb_en50494_class,
conf, name, ls);
if (ld) {
ld->ld_tune = linuxdvb_en50494_tune;
ld->ld_tune = linuxdvb_en50494_tune;
/* May not needed: ld->ld_grace = linuxdvb_en50494_grace; */
}

Expand Down
16 changes: 15 additions & 1 deletion src/input/mpegts/linuxdvb/linuxdvb_private.h
Expand Up @@ -329,6 +329,9 @@ struct linuxdvb_lnb
int (*lnb_pol) (linuxdvb_lnb_t*, dvb_mux_t*);
};

#define UNICABLE_EN50494 50494
#define UNICABLE_EN50607 50607

struct linuxdvb_en50494
{
linuxdvb_diseqc_t;
Expand Down Expand Up @@ -448,6 +451,10 @@ linuxdvb_diseqc_t *linuxdvb_switch_create0
( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int c, int u );
linuxdvb_diseqc_t *linuxdvb_rotor_create0
( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls );

#define UNICABLE_I_NAME "Unicable I (EN50494)"
#define UNICABLE_II_NAME "Unicable II (EN50607)"

linuxdvb_diseqc_t *linuxdvb_en50494_create0
( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int port );

Expand All @@ -461,11 +468,18 @@ htsmsg_t *linuxdvb_switch_list ( void *o, const char *lang );
htsmsg_t *linuxdvb_rotor_list ( void *o, const char *lang );
htsmsg_t *linuxdvb_en50494_list ( void *o, const char *lang );

htsmsg_t *linuxdvb_en50494_id_list ( void *o, const char *lang );
htsmsg_t *linuxdvb_en50494_id_list ( void *o, const char *lang );
htsmsg_t *linuxdvb_en50607_id_list ( void *o, const char *lang );
htsmsg_t *linuxdvb_en50494_pin_list ( void *o, const char *lang );

static inline int linuxdvb_unicable_is_en50607( const char *str )
{ return strcmp(str, UNICABLE_II_NAME) == 0; }
static inline int linuxdvb_unicable_is_en50494( const char *str )
{ return !linuxdvb_unicable_is_en50607(str); }

void linuxdvb_en50494_init (void);

int linuxdvb_diseqc_raw_send (int fd, uint8_t len, ...);
int
linuxdvb_diseqc_send
(int fd, uint8_t framing, uint8_t addr, uint8_t cmd, uint8_t len, ...);
Expand Down

0 comments on commit 766f2fd

Please sign in to comment.