Commit ea71c62b authored by Daniel Scheller's avatar Daniel Scheller Committed by Mauro Carvalho Chehab

media: dvb-frontends/stv0910: add multistream (ISI) and PLS capabilities

Implements stream_id filter and scrambling code setup in start() and also
sets FE_CAN_MULTISTREAM in frontend_ops. This enables the driver to
properly receive and handle multistream transponders, functionality has
been reported working fine by testers with access to such streams, in
conjunction with VDR on the userspace side.

The code snippet originates from the original vendor's dddvb driver
package and has been made working properly with the current in-kernel
DVB core API.
Signed-off-by: default avatarDaniel Scheller <d.scheller@gmx.net>
Tested-by: default avatarRichard Scobie <r.scobie@clear.net.nz>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 13c81489
...@@ -119,6 +119,8 @@ struct stv { ...@@ -119,6 +119,8 @@ struct stv {
int is_standard_broadcast; int is_standard_broadcast;
int is_vcm; int is_vcm;
u32 cur_scrambling_code;
u32 last_bernumerator; u32 last_bernumerator;
u32 last_berdenominator; u32 last_berdenominator;
u8 berscale; u8 berscale;
...@@ -965,6 +967,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) ...@@ -965,6 +967,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p)
s32 freq; s32 freq;
u8 reg_dmdcfgmd; u8 reg_dmdcfgmd;
u16 symb; u16 symb;
u32 scrambling_code = 1;
if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) if (p->symbol_rate < 100000 || p->symbol_rate > 70000000)
return -EINVAL; return -EINVAL;
...@@ -978,6 +981,28 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) ...@@ -978,6 +981,28 @@ static int start(struct stv *state, struct dtv_frontend_properties *p)
init_search_param(state); init_search_param(state);
if (p->stream_id != NO_STREAM_ID_FILTER) {
/* Backwards compatibility to "crazy" API.
* PRBS X root cannot be 0, so this should always work.
*/
if (p->stream_id & 0xffffff00)
scrambling_code = p->stream_id >> 8;
write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff,
p->stream_id & 0xff);
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff,
0xff);
}
if (scrambling_code != state->cur_scrambling_code) {
write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
scrambling_code & 0xff);
write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
(scrambling_code >> 8) & 0xff);
write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
(scrambling_code >> 16) & 0x07);
state->cur_scrambling_code = scrambling_code;
}
if (p->symbol_rate <= 1000000) { /* SR <=1Msps */ if (p->symbol_rate <= 1000000) { /* SR <=1Msps */
state->demod_timeout = 3000; state->demod_timeout = 3000;
state->fec_timeout = 2000; state->fec_timeout = 2000;
...@@ -1597,7 +1622,8 @@ static struct dvb_frontend_ops stv0910_ops = { ...@@ -1597,7 +1622,8 @@ static struct dvb_frontend_ops stv0910_ops = {
.caps = FE_CAN_INVERSION_AUTO | .caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_AUTO | FE_CAN_FEC_AUTO |
FE_CAN_QPSK | FE_CAN_QPSK |
FE_CAN_2G_MODULATION FE_CAN_2G_MODULATION |
FE_CAN_MULTISTREAM
}, },
.sleep = sleep, .sleep = sleep,
.release = release, .release = release,
...@@ -1655,6 +1681,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ...@@ -1655,6 +1681,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c,
state->search_range = 16000000; state->search_range = 16000000;
state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */ state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */
state->receive_mode = RCVMODE_NONE; state->receive_mode = RCVMODE_NONE;
state->cur_scrambling_code = (~0U);
state->single = cfg->single ? 1 : 0; state->single = cfg->single ? 1 : 0;
base = match_base(i2c, cfg->adr); base = match_base(i2c, cfg->adr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment