Lines Matching +full:burst +full:- +full:write

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
5 Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
6 Copyright (C) 2006-2007 Georg Acher
7 Copyright (C) 2007-2008 Darron Broad
45 #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
74 /* Select DVB-S demodulator, else DVB-S2 */
115 /* DiSEqC burst */
119 /* DiSEqC tone burst */
128 MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
183 u8 burst; member
190 struct i2c_msg msg = { .addr = state->config->demod_address, in cx24116_writereg()
195 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", in cx24116_writereg()
198 err = i2c_transfer(state->i2c, &msg, 1); in cx24116_writereg()
202 return -EREMOTEIO; in cx24116_writereg()
218 return -ENOMEM; in cx24116_writeregN()
223 msg.addr = state->config->demod_address; in cx24116_writeregN()
229 printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n", in cx24116_writeregN()
232 ret = i2c_transfer(state->i2c, &msg, 1); in cx24116_writeregN()
236 ret = -EREMOTEIO; in cx24116_writeregN()
250 { .addr = state->config->demod_address, .flags = 0, in cx24116_readreg()
252 { .addr = state->config->demod_address, .flags = I2C_M_RD, in cx24116_readreg()
256 ret = i2c_transfer(state->i2c, msg, 2); in cx24116_readreg()
278 state->dnxt.inversion_val = 0x00; in cx24116_set_inversion()
281 state->dnxt.inversion_val = 0x04; in cx24116_set_inversion()
284 state->dnxt.inversion_val = 0x0C; in cx24116_set_inversion()
287 return -EINVAL; in cx24116_set_inversion()
290 state->dnxt.inversion = inversion; in cx24116_set_inversion()
300 * ---- -------- ----------- --------
301 * QPSK FEC_1_2 0x02 0x02+X DVB-S
302 * QPSK FEC_2_3 0x04 0x02+X DVB-S
303 * QPSK FEC_3_4 0x08 0x02+X DVB-S
304 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
305 * QPSK FEC_5_6 0x20 0x02+X DVB-S
306 * QPSK FEC_6_7 0x40 0x02+X DVB-S
307 * QPSK FEC_7_8 0x80 0x02+X DVB-S
308 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
309 * QPSK AUTO 0xff 0x02+X DVB-S
311 * For DVB-S high byte probably represents FEC
314 * on DVB-S and remaining bits represent some
328 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
330 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
331 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
332 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
333 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
334 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
335 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
336 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
337 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
339 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
340 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
341 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
342 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
343 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
344 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
346 * For DVB-S2 low bytes selects both modulator
379 /* NBC-QPSK */
404 int i, ret = -EOPNOTSUPP; in cx24116_lookup_fecmod()
434 state->dnxt.fec = fec; in cx24116_set_fec()
435 state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val; in cx24116_set_fec()
436 state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask; in cx24116_set_fec()
438 state->dnxt.fec_mask, state->dnxt.fec_val); in cx24116_set_fec()
448 if ((rate > state->frontend.ops.info.symbol_rate_max) || in cx24116_set_symbolrate()
449 (rate < state->frontend.ops.info.symbol_rate_min)) { in cx24116_set_symbolrate()
451 return -EOPNOTSUPP; in cx24116_set_symbolrate()
454 state->dnxt.symbol_rate = rate; in cx24116_set_symbolrate()
465 struct cx24116_state *state = fe->demodulator_priv; in cx24116_firmware_ondemand()
473 if (state->skip_fw_load) in cx24116_firmware_ondemand()
481 state->i2c->dev.parent); in cx24116_firmware_ondemand()
492 state->skip_fw_load = 1; in cx24116_firmware_ondemand()
505 state->skip_fw_load = 0; in cx24116_firmware_ondemand()
516 struct cx24116_state *state = fe->demodulator_priv; in cx24116_cmd_execute()
529 /* Write the command */ in cx24116_cmd_execute()
530 for (i = 0; i < cmd->len ; i++) { in cx24116_cmd_execute()
531 dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); in cx24116_cmd_execute()
532 cx24116_writereg(state, i, cmd->args[i]); in cx24116_cmd_execute()
544 return -EREMOTEIO; in cx24116_cmd_execute()
553 struct cx24116_state *state = fe->demodulator_priv; in cx24116_load_firmware()
560 fw->size, in cx24116_load_firmware()
561 fw->data[0], in cx24116_load_firmware()
562 fw->data[1], in cx24116_load_firmware()
563 fw->data[fw->size-2], in cx24116_load_firmware()
564 fw->data[fw->size-1]); in cx24116_load_firmware()
567 if (state->config->reset_device) in cx24116_load_firmware()
568 state->config->reset_device(fe); in cx24116_load_firmware()
592 /* Split firmware to the max I2C write len and write. in cx24116_load_firmware()
593 * Writes whole firmware as one write when i2c_wr_max is set to 0. */ in cx24116_load_firmware()
594 if (state->config->i2c_wr_max) in cx24116_load_firmware()
595 max = state->config->i2c_wr_max; in cx24116_load_firmware()
599 for (remaining = fw->size; remaining > 0; remaining -= max - 1) { in cx24116_load_firmware()
601 if (len > max - 1) in cx24116_load_firmware()
602 len = max - 1; in cx24116_load_firmware()
604 cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining], in cx24116_load_firmware()
646 if (state->config->mpg_clk_pos_pol) in cx24116_load_firmware()
647 cmd.args[0x04] = state->config->mpg_clk_pos_pol; in cx24116_load_firmware()
674 struct cx24116_state *state = fe->demodulator_priv; in cx24116_read_status()
697 struct cx24116_state *state = fe->demodulator_priv; in cx24116_read_ber()
713 struct cx24116_state *state = fe->demodulator_priv; in cx24116_read_signal_strength()
731 *signal_strength = 0 - sig_reading; in cx24116_read_signal_strength()
742 struct cx24116_state *state = fe->demodulator_priv; in cx24116_read_snr_pct()
767 * ESNO, from 0->30db (values 0->300). We provide this value by
772 struct cx24116_state *state = fe->demodulator_priv; in cx24116_read_snr_esno()
794 struct cx24116_state *state = fe->demodulator_priv; in cx24116_read_ucblocks()
807 struct cx24116_state *state = fe->demodulator_priv; in cx24116_clone_params()
808 state->dcur = state->dnxt; in cx24116_clone_params()
814 struct cx24116_state *state = fe->demodulator_priv; in cx24116_wait_for_lnb()
829 return -ETIMEDOUT; /* -EBUSY ? */ in cx24116_wait_for_lnb()
869 return -EINVAL; in cx24116_set_tone()
878 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ in cx24116_set_tone()
898 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ in cx24116_set_tone()
906 struct cx24116_state *state = fe->demodulator_priv; in cx24116_diseqc_init()
925 state->dsec_cmd.args[0x00] = CMD_LNBSEND; in cx24116_diseqc_init()
927 /* DiSEqC burst */ in cx24116_diseqc_init()
928 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; in cx24116_diseqc_init()
931 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; in cx24116_diseqc_init()
932 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; in cx24116_diseqc_init()
934 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; in cx24116_diseqc_init()
937 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; in cx24116_diseqc_init()
940 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS; in cx24116_diseqc_init()
945 /* Send DiSEqC message with derived burst (hack) || previous burst */
949 struct cx24116_state *state = fe->demodulator_priv; in cx24116_send_diseqc_msg()
953 if (d->msg_len > sizeof(d->msg)) in cx24116_send_diseqc_msg()
954 return -EINVAL; in cx24116_send_diseqc_msg()
959 for (i = 0 ; i < d->msg_len ;) { in cx24116_send_diseqc_msg()
960 printk(KERN_INFO "0x%02x", d->msg[i]); in cx24116_send_diseqc_msg()
961 if (++i < d->msg_len) in cx24116_send_diseqc_msg()
968 for (i = 0; i < d->msg_len; i++) in cx24116_send_diseqc_msg()
969 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i]; in cx24116_send_diseqc_msg()
972 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; in cx24116_send_diseqc_msg()
975 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS + in cx24116_send_diseqc_msg()
976 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; in cx24116_send_diseqc_msg()
984 /* Message is sent without burst */ in cx24116_send_diseqc_msg()
985 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; in cx24116_send_diseqc_msg()
989 * Message is sent with derived else cached burst in cx24116_send_diseqc_msg()
991 * WRITE PORT GROUP COMMAND 38 in cx24116_send_diseqc_msg()
1006 if (d->msg_len >= 4 && d->msg[2] == 0x38) in cx24116_send_diseqc_msg()
1007 state->dsec_cmd.args[CX24116_DISEQC_BURST] = in cx24116_send_diseqc_msg()
1008 ((d->msg[3] & 4) >> 2); in cx24116_send_diseqc_msg()
1010 dprintk("%s burst=%d\n", __func__, in cx24116_send_diseqc_msg()
1011 state->dsec_cmd.args[CX24116_DISEQC_BURST]); in cx24116_send_diseqc_msg()
1023 ret = cx24116_cmd_execute(fe, &state->dsec_cmd); in cx24116_send_diseqc_msg()
1033 * 12.5ms burst + in cx24116_send_diseqc_msg()
1036 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + in cx24116_send_diseqc_msg()
1042 /* Send DiSEqC burst */
1044 enum fe_sec_mini_cmd burst) in cx24116_diseqc_send_burst() argument
1046 struct cx24116_state *state = fe->demodulator_priv; in cx24116_diseqc_send_burst()
1049 dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst); in cx24116_diseqc_send_burst()
1051 /* DiSEqC burst */ in cx24116_diseqc_send_burst()
1052 if (burst == SEC_MINI_A) in cx24116_diseqc_send_burst()
1053 state->dsec_cmd.args[CX24116_DISEQC_BURST] = in cx24116_diseqc_send_burst()
1055 else if (burst == SEC_MINI_B) in cx24116_diseqc_send_burst()
1056 state->dsec_cmd.args[CX24116_DISEQC_BURST] = in cx24116_diseqc_send_burst()
1059 return -EINVAL; in cx24116_diseqc_send_burst()
1063 /* Burst is cached */ in cx24116_diseqc_send_burst()
1066 /* Burst is to be sent with cached message */ in cx24116_diseqc_send_burst()
1077 ret = cx24116_cmd_execute(fe, &state->dsec_cmd); in cx24116_diseqc_send_burst()
1088 * 12.5ms burst + in cx24116_diseqc_send_burst()
1091 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60); in cx24116_diseqc_send_burst()
1098 struct cx24116_state *state = fe->demodulator_priv; in cx24116_release()
1118 state->config = config; in cx24116_attach()
1119 state->i2c = i2c; in cx24116_attach()
1131 memcpy(&state->frontend.ops, &cx24116_ops, in cx24116_attach()
1133 state->frontend.demodulator_priv = state; in cx24116_attach()
1134 return &state->frontend; in cx24116_attach()
1145 struct cx24116_state *state = fe->demodulator_priv; in cx24116_initfe()
1168 /* HVR-4000 needs this */ in cx24116_initfe()
1177 struct cx24116_state *state = fe->demodulator_priv; in cx24116_sleep()
1199 /* dvb-core told us to tune, the tv property cache will be complete,
1204 struct cx24116_state *state = fe->demodulator_priv; in cx24116_set_frontend()
1205 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in cx24116_set_frontend()
1212 switch (c->delivery_system) { in cx24116_set_frontend()
1214 dprintk("%s: DVB-S delivery system selected\n", __func__); in cx24116_set_frontend()
1216 /* Only QPSK is supported for DVB-S */ in cx24116_set_frontend()
1217 if (c->modulation != QPSK) { in cx24116_set_frontend()
1219 __func__, c->modulation); in cx24116_set_frontend()
1220 return -EOPNOTSUPP; in cx24116_set_frontend()
1223 /* Pilot doesn't exist in DVB-S, turn bit off */ in cx24116_set_frontend()
1224 state->dnxt.pilot_val = CX24116_PILOT_OFF; in cx24116_set_frontend()
1226 /* DVB-S only supports 0.35 */ in cx24116_set_frontend()
1227 if (c->rolloff != ROLLOFF_35) { in cx24116_set_frontend()
1229 __func__, c->rolloff); in cx24116_set_frontend()
1230 return -EOPNOTSUPP; in cx24116_set_frontend()
1232 state->dnxt.rolloff_val = CX24116_ROLLOFF_035; in cx24116_set_frontend()
1236 dprintk("%s: DVB-S2 delivery system selected\n", __func__); in cx24116_set_frontend()
1239 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, in cx24116_set_frontend()
1242 if (c->modulation != PSK_8 && c->modulation != QPSK) { in cx24116_set_frontend()
1244 __func__, c->modulation); in cx24116_set_frontend()
1245 return -EOPNOTSUPP; in cx24116_set_frontend()
1248 switch (c->pilot) { in cx24116_set_frontend()
1250 state->dnxt.pilot_val = (c->modulation == QPSK) in cx24116_set_frontend()
1255 state->dnxt.pilot_val = CX24116_PILOT_OFF; in cx24116_set_frontend()
1258 state->dnxt.pilot_val = CX24116_PILOT_ON; in cx24116_set_frontend()
1262 __func__, c->pilot); in cx24116_set_frontend()
1263 return -EOPNOTSUPP; in cx24116_set_frontend()
1266 switch (c->rolloff) { in cx24116_set_frontend()
1268 state->dnxt.rolloff_val = CX24116_ROLLOFF_020; in cx24116_set_frontend()
1271 state->dnxt.rolloff_val = CX24116_ROLLOFF_025; in cx24116_set_frontend()
1274 state->dnxt.rolloff_val = CX24116_ROLLOFF_035; in cx24116_set_frontend()
1279 __func__, c->rolloff); in cx24116_set_frontend()
1280 return -EOPNOTSUPP; in cx24116_set_frontend()
1286 __func__, c->delivery_system); in cx24116_set_frontend()
1287 return -EOPNOTSUPP; in cx24116_set_frontend()
1289 state->dnxt.delsys = c->delivery_system; in cx24116_set_frontend()
1290 state->dnxt.modulation = c->modulation; in cx24116_set_frontend()
1291 state->dnxt.frequency = c->frequency; in cx24116_set_frontend()
1292 state->dnxt.pilot = c->pilot; in cx24116_set_frontend()
1293 state->dnxt.rolloff = c->rolloff; in cx24116_set_frontend()
1295 ret = cx24116_set_inversion(state, c->inversion); in cx24116_set_frontend()
1299 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ in cx24116_set_frontend()
1300 ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner); in cx24116_set_frontend()
1304 ret = cx24116_set_symbolrate(state, c->symbol_rate); in cx24116_set_frontend()
1311 dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys); in cx24116_set_frontend()
1312 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation); in cx24116_set_frontend()
1313 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); in cx24116_set_frontend()
1315 state->dcur.pilot, state->dcur.pilot_val); in cx24116_set_frontend()
1318 state->dcur.rolloff, state->dcur.rolloff_val); in cx24116_set_frontend()
1319 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); in cx24116_set_frontend()
1321 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); in cx24116_set_frontend()
1323 state->dcur.inversion, state->dcur.inversion_val); in cx24116_set_frontend()
1326 if (state->config->set_ts_params) in cx24116_set_frontend()
1327 state->config->set_ts_params(fe, 0); in cx24116_set_frontend()
1341 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16; in cx24116_set_frontend()
1342 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8; in cx24116_set_frontend()
1343 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff); in cx24116_set_frontend()
1346 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8; in cx24116_set_frontend()
1347 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff); in cx24116_set_frontend()
1350 cmd.args[0x06] = state->dcur.inversion_val; in cx24116_set_frontend()
1353 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val; in cx24116_set_frontend()
1359 cmd.args[0x0c] = state->dcur.rolloff_val; in cx24116_set_frontend()
1360 cmd.args[0x0d] = state->dcur.fec_mask; in cx24116_set_frontend()
1362 if (state->dcur.symbol_rate > 30000000) { in cx24116_set_frontend()
1382 /* We need to support pilot and non-pilot tuning in the in cx24116_set_frontend()
1415 /* Toggle pilot bit when in auto-pilot */ in cx24116_set_frontend()
1416 if (state->dcur.pilot == PILOT_AUTO) in cx24116_set_frontend()
1418 } while (--retune); in cx24116_set_frontend()
1432 * fe->dtv_property_cache with fepriv->parameters_in, where the in cx24116_tune()
1434 * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is in cx24116_tune()