1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * ddbridge-sx8.c: Digital Devices MAX SX8 driver 4 * 5 * Copyright (C) 2018 Digital Devices GmbH 6 * Marcus Metzler <mocm@metzlerbros.de> 7 * Ralph Metzler <rjkm@metzlerbros.de> 8 */ 9 10 #include "ddbridge.h" 11 #include "ddbridge-io.h" 12 #include "ddbridge-mci.h" 13 14 static const u32 MCLK = (1550000000 / 12); 15 static const u32 MAX_LDPC_BITRATE = (720000000); 16 static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6); 17 18 #define SX8_TUNER_NUM 4 19 #define SX8_DEMOD_NUM 8 20 #define SX8_DEMOD_NONE 0xff 21 22 struct sx8_base { 23 struct mci_base mci_base; 24 25 u8 tuner_use_count[SX8_TUNER_NUM]; 26 u32 gain_mode[SX8_TUNER_NUM]; 27 28 u32 used_ldpc_bitrate[SX8_DEMOD_NUM]; 29 u8 demod_in_use[SX8_DEMOD_NUM]; 30 u32 iq_mode; 31 u32 burst_size; 32 u32 direct_mode; 33 }; 34 35 struct sx8 { 36 struct mci mci; 37 38 int first_time_lock; 39 int started; 40 struct mci_result signal_info; 41 42 u32 bb_mode; 43 u32 local_frequency; 44 }; 45 46 static void release(struct dvb_frontend *fe) 47 { 48 struct sx8 *state = fe->demodulator_priv; 49 struct mci_base *mci_base = state->mci.base; 50 51 mci_base->count--; 52 if (mci_base->count == 0) { 53 list_del(&mci_base->mci_list); 54 kfree(mci_base); 55 } 56 kfree(state); 57 } 58 59 static int get_info(struct dvb_frontend *fe) 60 { 61 int stat; 62 struct sx8 *state = fe->demodulator_priv; 63 struct mci_command cmd; 64 65 memset(&cmd, 0, sizeof(cmd)); 66 cmd.command = MCI_CMD_GETSIGNALINFO; 67 cmd.demod = state->mci.demod; 68 stat = ddb_mci_cmd(&state->mci, &cmd, &state->signal_info); 69 return stat; 70 } 71 72 static int get_snr(struct dvb_frontend *fe) 73 { 74 struct sx8 *state = fe->demodulator_priv; 75 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 76 77 p->cnr.len = 1; 78 p->cnr.stat[0].scale = FE_SCALE_DECIBEL; 79 p->cnr.stat[0].svalue = 80 (s64)state->signal_info.dvbs2_signal_info.signal_to_noise 81 * 10; 82 return 0; 83 } 84 85 static int get_strength(struct dvb_frontend *fe) 86 { 87 struct sx8 *state = fe->demodulator_priv; 88 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 89 s32 str; 90 91 str = 100000 - 92 (state->signal_info.dvbs2_signal_info.channel_power 93 * 10 + 108750); 94 p->strength.len = 1; 95 p->strength.stat[0].scale = FE_SCALE_DECIBEL; 96 p->strength.stat[0].svalue = str; 97 return 0; 98 } 99 100 static int read_status(struct dvb_frontend *fe, enum fe_status *status) 101 { 102 int stat; 103 struct sx8 *state = fe->demodulator_priv; 104 struct mci_command cmd; 105 struct mci_result res; 106 107 cmd.command = MCI_CMD_GETSTATUS; 108 cmd.demod = state->mci.demod; 109 stat = ddb_mci_cmd(&state->mci, &cmd, &res); 110 if (stat) 111 return stat; 112 *status = 0x00; 113 get_info(fe); 114 get_strength(fe); 115 if (res.status == SX8_DEMOD_WAIT_MATYPE) 116 *status = 0x0f; 117 if (res.status == SX8_DEMOD_LOCKED) { 118 *status = 0x1f; 119 get_snr(fe); 120 } 121 return stat; 122 } 123 124 static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on) 125 { 126 struct sx8 *state = fe->demodulator_priv; 127 struct mci_base *mci_base = state->mci.base; 128 struct sx8_base *sx8_base = (struct sx8_base *)mci_base; 129 struct mci_command cmd; 130 131 memset(&cmd, 0, sizeof(cmd)); 132 cmd.tuner = state->mci.tuner; 133 cmd.command = on ? SX8_CMD_INPUT_ENABLE : SX8_CMD_INPUT_DISABLE; 134 cmd.sx8_input_enable.flags = sx8_base->gain_mode[state->mci.tuner]; 135 return ddb_mci_cmd(&state->mci, &cmd, NULL); 136 } 137 138 static int stop(struct dvb_frontend *fe) 139 { 140 struct sx8 *state = fe->demodulator_priv; 141 struct mci_base *mci_base = state->mci.base; 142 struct sx8_base *sx8_base = (struct sx8_base *)mci_base; 143 struct mci_command cmd; 144 u32 input = state->mci.tuner; 145 146 memset(&cmd, 0, sizeof(cmd)); 147 if (state->mci.demod != SX8_DEMOD_NONE) { 148 cmd.command = MCI_CMD_STOP; 149 cmd.demod = state->mci.demod; 150 ddb_mci_cmd(&state->mci, &cmd, NULL); 151 if (sx8_base->iq_mode) { 152 cmd.command = SX8_CMD_DISABLE_IQOUTPUT; 153 cmd.demod = state->mci.demod; 154 cmd.output = 0; 155 ddb_mci_cmd(&state->mci, &cmd, NULL); 156 ddb_mci_config(&state->mci, SX8_TSCONFIG_MODE_NORMAL); 157 } 158 } 159 mutex_lock(&mci_base->tuner_lock); 160 sx8_base->tuner_use_count[input]--; 161 if (!sx8_base->tuner_use_count[input]) 162 mci_set_tuner(fe, input, 0); 163 if (state->mci.demod < SX8_DEMOD_NUM) { 164 sx8_base->demod_in_use[state->mci.demod] = 0; 165 state->mci.demod = SX8_DEMOD_NONE; 166 } 167 sx8_base->used_ldpc_bitrate[state->mci.nr] = 0; 168 sx8_base->iq_mode = 0; 169 mutex_unlock(&mci_base->tuner_lock); 170 state->started = 0; 171 return 0; 172 } 173 174 static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config) 175 { 176 struct sx8 *state = fe->demodulator_priv; 177 struct mci_base *mci_base = state->mci.base; 178 struct sx8_base *sx8_base = (struct sx8_base *)mci_base; 179 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 180 u32 used_ldpc_bitrate = 0, free_ldpc_bitrate; 181 u32 used_demods = 0; 182 struct mci_command cmd; 183 u32 input = state->mci.tuner; 184 u32 bits_per_symbol = 0; 185 int i = -1, stat = 0; 186 187 if (p->symbol_rate >= (MCLK / 2)) 188 flags &= ~1; 189 if ((flags & 3) == 0) 190 return -EINVAL; 191 192 if (flags & 2) { 193 u32 tmp = modmask; 194 195 bits_per_symbol = 1; 196 while (tmp & 1) { 197 tmp >>= 1; 198 bits_per_symbol++; 199 } 200 } 201 202 mutex_lock(&mci_base->tuner_lock); 203 if (sx8_base->iq_mode) { 204 stat = -EBUSY; 205 goto unlock; 206 } 207 208 if (sx8_base->direct_mode) { 209 if (p->symbol_rate >= MCLK / 2) { 210 if (state->mci.nr < 4) 211 i = state->mci.nr; 212 } else { 213 i = state->mci.nr; 214 } 215 } else { 216 for (i = 0; i < SX8_DEMOD_NUM; i++) { 217 used_ldpc_bitrate += sx8_base->used_ldpc_bitrate[i]; 218 if (sx8_base->demod_in_use[i]) 219 used_demods++; 220 } 221 if (used_ldpc_bitrate >= MAX_LDPC_BITRATE || 222 ((ts_config & SX8_TSCONFIG_MODE_MASK) > 223 SX8_TSCONFIG_MODE_NORMAL && used_demods > 0)) { 224 stat = -EBUSY; 225 goto unlock; 226 } 227 free_ldpc_bitrate = MAX_LDPC_BITRATE - used_ldpc_bitrate; 228 if (free_ldpc_bitrate > MAX_DEMOD_LDPC_BITRATE) 229 free_ldpc_bitrate = MAX_DEMOD_LDPC_BITRATE; 230 231 while (p->symbol_rate * bits_per_symbol > free_ldpc_bitrate) 232 bits_per_symbol--; 233 if (bits_per_symbol < 2) { 234 stat = -EBUSY; 235 goto unlock; 236 } 237 238 modmask &= ((1 << (bits_per_symbol - 1)) - 1); 239 if (((flags & 0x02) != 0) && modmask == 0) { 240 stat = -EBUSY; 241 goto unlock; 242 } 243 244 i = (p->symbol_rate > (MCLK / 2)) ? 3 : 7; 245 while (i >= 0 && sx8_base->demod_in_use[i]) 246 i--; 247 } 248 249 if (i < 0) { 250 stat = -EBUSY; 251 goto unlock; 252 } 253 sx8_base->demod_in_use[i] = 1; 254 sx8_base->used_ldpc_bitrate[state->mci.nr] = p->symbol_rate 255 * bits_per_symbol; 256 state->mci.demod = i; 257 258 if (!sx8_base->tuner_use_count[input]) 259 mci_set_tuner(fe, input, 1); 260 sx8_base->tuner_use_count[input]++; 261 sx8_base->iq_mode = (ts_config > 1); 262 unlock: 263 mutex_unlock(&mci_base->tuner_lock); 264 if (stat) 265 return stat; 266 memset(&cmd, 0, sizeof(cmd)); 267 268 if (sx8_base->iq_mode) { 269 cmd.command = SX8_CMD_ENABLE_IQOUTPUT; 270 cmd.demod = state->mci.demod; 271 cmd.output = 0; 272 ddb_mci_cmd(&state->mci, &cmd, NULL); 273 ddb_mci_config(&state->mci, ts_config); 274 } 275 if (p->stream_id != NO_STREAM_ID_FILTER && p->stream_id != 0x80000000) 276 flags |= 0x80; 277 dev_dbg(mci_base->dev, "MCI-%d: tuner=%d demod=%d\n", 278 state->mci.nr, state->mci.tuner, state->mci.demod); 279 cmd.command = MCI_CMD_SEARCH_DVBS; 280 cmd.dvbs2_search.flags = flags; 281 cmd.dvbs2_search.s2_modulation_mask = modmask; 282 cmd.dvbs2_search.retry = 2; 283 cmd.dvbs2_search.frequency = p->frequency * 1000; 284 cmd.dvbs2_search.symbol_rate = p->symbol_rate; 285 cmd.dvbs2_search.scrambling_sequence_index = 286 p->scrambling_sequence_index | 0x80000000; 287 cmd.dvbs2_search.input_stream_id = 288 (p->stream_id != NO_STREAM_ID_FILTER) ? p->stream_id : 0; 289 cmd.tuner = state->mci.tuner; 290 cmd.demod = state->mci.demod; 291 cmd.output = state->mci.nr; 292 if (p->stream_id == 0x80000000) 293 cmd.output |= 0x80; 294 stat = ddb_mci_cmd(&state->mci, &cmd, NULL); 295 if (stat) 296 stop(fe); 297 return stat; 298 } 299 300 static int start_iq(struct dvb_frontend *fe, u32 flags, u32 roll_off, 301 u32 ts_config) 302 { 303 struct sx8 *state = fe->demodulator_priv; 304 struct mci_base *mci_base = state->mci.base; 305 struct sx8_base *sx8_base = (struct sx8_base *)mci_base; 306 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 307 u32 used_demods = 0; 308 struct mci_command cmd; 309 u32 input = state->mci.tuner; 310 int i, stat = 0; 311 312 mutex_lock(&mci_base->tuner_lock); 313 if (sx8_base->iq_mode) { 314 stat = -EBUSY; 315 goto unlock; 316 } 317 for (i = 0; i < SX8_DEMOD_NUM; i++) 318 if (sx8_base->demod_in_use[i]) 319 used_demods++; 320 if (used_demods > 0) { 321 stat = -EBUSY; 322 goto unlock; 323 } 324 state->mci.demod = 0; 325 if (!sx8_base->tuner_use_count[input]) 326 mci_set_tuner(fe, input, 1); 327 sx8_base->tuner_use_count[input]++; 328 sx8_base->iq_mode = (ts_config > 1); 329 unlock: 330 mutex_unlock(&mci_base->tuner_lock); 331 if (stat) 332 return stat; 333 334 memset(&cmd, 0, sizeof(cmd)); 335 cmd.command = SX8_CMD_START_IQ; 336 cmd.sx8_start_iq.flags = flags; 337 cmd.sx8_start_iq.roll_off = roll_off; 338 cmd.sx8_start_iq.frequency = p->frequency * 1000; 339 cmd.sx8_start_iq.symbol_rate = p->symbol_rate; 340 cmd.tuner = state->mci.tuner; 341 cmd.demod = state->mci.demod; 342 stat = ddb_mci_cmd(&state->mci, &cmd, NULL); 343 if (stat) 344 stop(fe); 345 ddb_mci_config(&state->mci, ts_config); 346 return stat; 347 } 348 349 static int set_parameters(struct dvb_frontend *fe) 350 { 351 int stat = 0; 352 struct sx8 *state = fe->demodulator_priv; 353 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 354 u32 ts_config = SX8_TSCONFIG_MODE_NORMAL, iq_mode = 0, isi; 355 356 if (state->started) 357 stop(fe); 358 359 isi = p->stream_id; 360 if (isi != NO_STREAM_ID_FILTER) 361 iq_mode = (isi & 0x30000000) >> 28; 362 363 if (iq_mode) 364 ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ); 365 if (iq_mode < 3) { 366 u32 mask; 367 368 switch (p->modulation) { 369 /* uncomment whenever these modulations hit the DVB API 370 * case APSK_256: 371 * mask = 0x7f; 372 * break; 373 * case APSK_128: 374 * mask = 0x3f; 375 * break; 376 * case APSK_64: 377 * mask = 0x1f; 378 * break; 379 */ 380 case APSK_32: 381 mask = 0x0f; 382 break; 383 case APSK_16: 384 mask = 0x07; 385 break; 386 default: 387 mask = 0x03; 388 break; 389 } 390 stat = start(fe, 3, mask, ts_config); 391 } else { 392 stat = start_iq(fe, 0, 4, ts_config); 393 } 394 if (!stat) { 395 state->started = 1; 396 state->first_time_lock = 1; 397 state->signal_info.status = SX8_DEMOD_WAIT_SIGNAL; 398 } 399 400 return stat; 401 } 402 403 static int tune(struct dvb_frontend *fe, bool re_tune, 404 unsigned int mode_flags, 405 unsigned int *delay, enum fe_status *status) 406 { 407 int r; 408 409 if (re_tune) { 410 r = set_parameters(fe); 411 if (r) 412 return r; 413 } 414 r = read_status(fe, status); 415 if (r) 416 return r; 417 418 if (*status & FE_HAS_LOCK) 419 return 0; 420 *delay = HZ / 10; 421 return 0; 422 } 423 424 static enum dvbfe_algo get_algo(struct dvb_frontend *fe) 425 { 426 return DVBFE_ALGO_HW; 427 } 428 429 static int set_input(struct dvb_frontend *fe, int input) 430 { 431 struct sx8 *state = fe->demodulator_priv; 432 struct mci_base *mci_base = state->mci.base; 433 434 if (input >= SX8_TUNER_NUM) 435 return -EINVAL; 436 437 state->mci.tuner = input; 438 dev_dbg(mci_base->dev, "MCI-%d: input=%d\n", state->mci.nr, input); 439 return 0; 440 } 441 442 static struct dvb_frontend_ops sx8_ops = { 443 .delsys = { SYS_DVBS, SYS_DVBS2 }, 444 .info = { 445 .name = "Digital Devices MaxSX8 MCI DVB-S/S2/S2X", 446 .frequency_min_hz = 950 * MHz, 447 .frequency_max_hz = 2150 * MHz, 448 .symbol_rate_min = 100000, 449 .symbol_rate_max = 100000000, 450 .caps = FE_CAN_INVERSION_AUTO | 451 FE_CAN_FEC_AUTO | 452 FE_CAN_QPSK | 453 FE_CAN_2G_MODULATION | 454 FE_CAN_MULTISTREAM, 455 }, 456 .get_frontend_algo = get_algo, 457 .tune = tune, 458 .release = release, 459 .read_status = read_status, 460 }; 461 462 static int init(struct mci *mci) 463 { 464 struct sx8 *state = (struct sx8 *)mci; 465 466 state->mci.demod = SX8_DEMOD_NONE; 467 return 0; 468 } 469 470 const struct mci_cfg ddb_max_sx8_cfg = { 471 .type = 0, 472 .fe_ops = &sx8_ops, 473 .base_size = sizeof(struct sx8_base), 474 .state_size = sizeof(struct sx8), 475 .init = init, 476 .set_input = set_input, 477 }; 478