1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /**************************************************************** 3 4 Siano Mobile Silicon, Inc. 5 MDTV receiver kernel modules. 6 Copyright (C) 2006-2008, Uri Shkolnik 7 8 9 ****************************************************************/ 10 11 #include "smscoreapi.h" 12 13 #include <linux/module.h> 14 #include <linux/slab.h> 15 #include <linux/init.h> 16 #include <asm/div64.h> 17 18 #include <media/dmxdev.h> 19 #include <media/dvbdev.h> 20 #include <media/dvb_demux.h> 21 #include <media/dvb_frontend.h> 22 23 #include "sms-cards.h" 24 25 #include "smsdvb.h" 26 27 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 28 29 static struct list_head g_smsdvb_clients; 30 static struct mutex g_smsdvb_clientslock; 31 32 static u32 sms_to_guard_interval_table[] = { 33 [0] = GUARD_INTERVAL_1_32, 34 [1] = GUARD_INTERVAL_1_16, 35 [2] = GUARD_INTERVAL_1_8, 36 [3] = GUARD_INTERVAL_1_4, 37 }; 38 39 static u32 sms_to_code_rate_table[] = { 40 [0] = FEC_1_2, 41 [1] = FEC_2_3, 42 [2] = FEC_3_4, 43 [3] = FEC_5_6, 44 [4] = FEC_7_8, 45 }; 46 47 48 static u32 sms_to_hierarchy_table[] = { 49 [0] = HIERARCHY_NONE, 50 [1] = HIERARCHY_1, 51 [2] = HIERARCHY_2, 52 [3] = HIERARCHY_4, 53 }; 54 55 static u32 sms_to_modulation_table[] = { 56 [0] = QPSK, 57 [1] = QAM_16, 58 [2] = QAM_64, 59 [3] = DQPSK, 60 }; 61 62 63 /* Events that may come from DVB v3 adapter */ 64 static void sms_board_dvb3_event(struct smsdvb_client_t *client, 65 enum SMS_DVB3_EVENTS event) { 66 67 struct smscore_device_t *coredev = client->coredev; 68 switch (event) { 69 case DVB3_EVENT_INIT: 70 pr_debug("DVB3_EVENT_INIT\n"); 71 sms_board_event(coredev, BOARD_EVENT_BIND); 72 break; 73 case DVB3_EVENT_SLEEP: 74 pr_debug("DVB3_EVENT_SLEEP\n"); 75 sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); 76 break; 77 case DVB3_EVENT_HOTPLUG: 78 pr_debug("DVB3_EVENT_HOTPLUG\n"); 79 sms_board_event(coredev, BOARD_EVENT_POWER_INIT); 80 break; 81 case DVB3_EVENT_FE_LOCK: 82 if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { 83 client->event_fe_state = DVB3_EVENT_FE_LOCK; 84 pr_debug("DVB3_EVENT_FE_LOCK\n"); 85 sms_board_event(coredev, BOARD_EVENT_FE_LOCK); 86 } 87 break; 88 case DVB3_EVENT_FE_UNLOCK: 89 if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { 90 client->event_fe_state = DVB3_EVENT_FE_UNLOCK; 91 pr_debug("DVB3_EVENT_FE_UNLOCK\n"); 92 sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); 93 } 94 break; 95 case DVB3_EVENT_UNC_OK: 96 if (client->event_unc_state != DVB3_EVENT_UNC_OK) { 97 client->event_unc_state = DVB3_EVENT_UNC_OK; 98 pr_debug("DVB3_EVENT_UNC_OK\n"); 99 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); 100 } 101 break; 102 case DVB3_EVENT_UNC_ERR: 103 if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { 104 client->event_unc_state = DVB3_EVENT_UNC_ERR; 105 pr_debug("DVB3_EVENT_UNC_ERR\n"); 106 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); 107 } 108 break; 109 110 default: 111 pr_err("Unknown dvb3 api event\n"); 112 break; 113 } 114 } 115 116 static void smsdvb_stats_not_ready(struct dvb_frontend *fe) 117 { 118 struct smsdvb_client_t *client = 119 container_of(fe, struct smsdvb_client_t, frontend); 120 struct smscore_device_t *coredev = client->coredev; 121 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 122 int i, n_layers; 123 124 switch (smscore_get_device_mode(coredev)) { 125 case DEVICE_MODE_ISDBT: 126 case DEVICE_MODE_ISDBT_BDA: 127 n_layers = 4; 128 break; 129 default: 130 n_layers = 1; 131 } 132 133 /* Global stats */ 134 c->strength.len = 1; 135 c->cnr.len = 1; 136 c->strength.stat[0].scale = FE_SCALE_DECIBEL; 137 c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 138 139 /* Per-layer stats */ 140 c->post_bit_error.len = n_layers; 141 c->post_bit_count.len = n_layers; 142 c->block_error.len = n_layers; 143 c->block_count.len = n_layers; 144 145 /* 146 * Put all of them at FE_SCALE_NOT_AVAILABLE. They're dynamically 147 * changed when the stats become available. 148 */ 149 for (i = 0; i < n_layers; i++) { 150 c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 151 c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 152 c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 153 c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 154 } 155 } 156 157 static inline int sms_to_mode(u32 mode) 158 { 159 switch (mode) { 160 case 2: 161 return TRANSMISSION_MODE_2K; 162 case 4: 163 return TRANSMISSION_MODE_4K; 164 case 8: 165 return TRANSMISSION_MODE_8K; 166 } 167 return TRANSMISSION_MODE_AUTO; 168 } 169 170 static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) 171 { 172 if (is_demod_locked) 173 return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | 174 FE_HAS_SYNC | FE_HAS_LOCK; 175 176 if (is_rf_locked) 177 return FE_HAS_SIGNAL | FE_HAS_CARRIER; 178 179 return 0; 180 } 181 182 static inline u32 sms_to_bw(u32 value) 183 { 184 return value * 1000000; 185 } 186 187 #define convert_from_table(value, table, defval) ({ \ 188 u32 __ret; \ 189 if (value < ARRAY_SIZE(table)) \ 190 __ret = table[value]; \ 191 else \ 192 __ret = defval; \ 193 __ret; \ 194 }) 195 196 #define sms_to_guard_interval(value) \ 197 convert_from_table(value, sms_to_guard_interval_table, \ 198 GUARD_INTERVAL_AUTO); 199 200 #define sms_to_code_rate(value) \ 201 convert_from_table(value, sms_to_code_rate_table, \ 202 FEC_NONE); 203 204 #define sms_to_hierarchy(value) \ 205 convert_from_table(value, sms_to_hierarchy_table, \ 206 FEC_NONE); 207 208 #define sms_to_modulation(value) \ 209 convert_from_table(value, sms_to_modulation_table, \ 210 FEC_NONE); 211 212 static void smsdvb_update_tx_params(struct smsdvb_client_t *client, 213 struct sms_tx_stats *p) 214 { 215 struct dvb_frontend *fe = &client->frontend; 216 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 217 218 c->frequency = p->frequency; 219 client->fe_status = sms_to_status(p->is_demod_locked, 0); 220 c->bandwidth_hz = sms_to_bw(p->bandwidth); 221 c->transmission_mode = sms_to_mode(p->transmission_mode); 222 c->guard_interval = sms_to_guard_interval(p->guard_interval); 223 c->code_rate_HP = sms_to_code_rate(p->code_rate); 224 c->code_rate_LP = sms_to_code_rate(p->lp_code_rate); 225 c->hierarchy = sms_to_hierarchy(p->hierarchy); 226 c->modulation = sms_to_modulation(p->constellation); 227 } 228 229 static void smsdvb_update_per_slices(struct smsdvb_client_t *client, 230 struct RECEPTION_STATISTICS_PER_SLICES_S *p) 231 { 232 struct dvb_frontend *fe = &client->frontend; 233 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 234 u64 tmp; 235 236 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 237 c->modulation = sms_to_modulation(p->constellation); 238 239 /* signal Strength, in DBm */ 240 c->strength.stat[0].uvalue = p->in_band_power * 1000; 241 242 /* Carrier to noise ratio, in DB */ 243 c->cnr.stat[0].svalue = p->snr * 1000; 244 245 /* PER/BER requires demod lock */ 246 if (!p->is_demod_locked) 247 return; 248 249 /* TS PER */ 250 client->last_per = c->block_error.stat[0].uvalue; 251 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 252 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 253 c->block_error.stat[0].uvalue += p->ets_packets; 254 c->block_count.stat[0].uvalue += p->ets_packets + p->ts_packets; 255 256 /* ber */ 257 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 258 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 259 c->post_bit_error.stat[0].uvalue += p->ber_error_count; 260 c->post_bit_count.stat[0].uvalue += p->ber_bit_count; 261 262 /* Legacy PER/BER */ 263 tmp = p->ets_packets * 65535ULL; 264 if (p->ts_packets + p->ets_packets) 265 do_div(tmp, p->ts_packets + p->ets_packets); 266 client->legacy_per = tmp; 267 } 268 269 static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, 270 struct sms_stats *p) 271 { 272 struct dvb_frontend *fe = &client->frontend; 273 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 274 275 if (client->prt_dvb_stats) 276 client->prt_dvb_stats(client->debug_data, p); 277 278 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 279 280 /* Update DVB modulation parameters */ 281 c->frequency = p->frequency; 282 client->fe_status = sms_to_status(p->is_demod_locked, 0); 283 c->bandwidth_hz = sms_to_bw(p->bandwidth); 284 c->transmission_mode = sms_to_mode(p->transmission_mode); 285 c->guard_interval = sms_to_guard_interval(p->guard_interval); 286 c->code_rate_HP = sms_to_code_rate(p->code_rate); 287 c->code_rate_LP = sms_to_code_rate(p->lp_code_rate); 288 c->hierarchy = sms_to_hierarchy(p->hierarchy); 289 c->modulation = sms_to_modulation(p->constellation); 290 291 /* update reception data */ 292 c->lna = p->is_external_lna_on ? 1 : 0; 293 294 /* Carrier to noise ratio, in DB */ 295 c->cnr.stat[0].svalue = p->SNR * 1000; 296 297 /* signal Strength, in DBm */ 298 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 299 300 /* PER/BER requires demod lock */ 301 if (!p->is_demod_locked) 302 return; 303 304 /* TS PER */ 305 client->last_per = c->block_error.stat[0].uvalue; 306 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 307 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 308 c->block_error.stat[0].uvalue += p->error_ts_packets; 309 c->block_count.stat[0].uvalue += p->total_ts_packets; 310 311 /* ber */ 312 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 313 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 314 c->post_bit_error.stat[0].uvalue += p->ber_error_count; 315 c->post_bit_count.stat[0].uvalue += p->ber_bit_count; 316 317 /* Legacy PER/BER */ 318 client->legacy_ber = p->ber; 319 }; 320 321 static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, 322 struct sms_isdbt_stats *p) 323 { 324 struct dvb_frontend *fe = &client->frontend; 325 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 326 struct sms_isdbt_layer_stats *lr; 327 int i, n_layers; 328 329 if (client->prt_isdb_stats) 330 client->prt_isdb_stats(client->debug_data, p); 331 332 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 333 334 /* 335 * Firmware 2.1 seems to report only lock status and 336 * signal strength. The signal strength indicator is at the 337 * wrong field. 338 */ 339 if (p->statistics_type == 0) { 340 c->strength.stat[0].uvalue = ((s32)p->transmission_mode) * 1000; 341 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 342 return; 343 } 344 345 /* Update ISDB-T transmission parameters */ 346 c->frequency = p->frequency; 347 c->bandwidth_hz = sms_to_bw(p->bandwidth); 348 c->transmission_mode = sms_to_mode(p->transmission_mode); 349 c->guard_interval = sms_to_guard_interval(p->guard_interval); 350 c->isdbt_partial_reception = p->partial_reception ? 1 : 0; 351 n_layers = p->num_of_layers; 352 if (n_layers < 1) 353 n_layers = 1; 354 if (n_layers > 3) 355 n_layers = 3; 356 c->isdbt_layer_enabled = 0; 357 358 /* update reception data */ 359 c->lna = p->is_external_lna_on ? 1 : 0; 360 361 /* Carrier to noise ratio, in DB */ 362 c->cnr.stat[0].svalue = p->SNR * 1000; 363 364 /* signal Strength, in DBm */ 365 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 366 367 /* PER/BER and per-layer stats require demod lock */ 368 if (!p->is_demod_locked) 369 return; 370 371 client->last_per = c->block_error.stat[0].uvalue; 372 373 /* Clears global counters, as the code below will sum it again */ 374 c->block_error.stat[0].uvalue = 0; 375 c->block_count.stat[0].uvalue = 0; 376 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 377 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 378 c->post_bit_error.stat[0].uvalue = 0; 379 c->post_bit_count.stat[0].uvalue = 0; 380 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 381 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 382 383 for (i = 0; i < n_layers; i++) { 384 lr = &p->layer_info[i]; 385 386 /* Update per-layer transmission parameters */ 387 if (lr->number_of_segments > 0 && lr->number_of_segments < 13) { 388 c->isdbt_layer_enabled |= 1 << i; 389 c->layer[i].segment_count = lr->number_of_segments; 390 } else { 391 continue; 392 } 393 c->layer[i].modulation = sms_to_modulation(lr->constellation); 394 395 /* TS PER */ 396 c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; 397 c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; 398 c->block_error.stat[i + 1].uvalue += lr->error_ts_packets; 399 c->block_count.stat[i + 1].uvalue += lr->total_ts_packets; 400 401 /* Update global PER counter */ 402 c->block_error.stat[0].uvalue += lr->error_ts_packets; 403 c->block_count.stat[0].uvalue += lr->total_ts_packets; 404 405 /* BER */ 406 c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; 407 c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; 408 c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count; 409 c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count; 410 411 /* Update global BER counter */ 412 c->post_bit_error.stat[0].uvalue += lr->ber_error_count; 413 c->post_bit_count.stat[0].uvalue += lr->ber_bit_count; 414 } 415 } 416 417 static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, 418 struct sms_isdbt_stats_ex *p) 419 { 420 struct dvb_frontend *fe = &client->frontend; 421 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 422 struct sms_isdbt_layer_stats *lr; 423 int i, n_layers; 424 425 if (client->prt_isdb_stats_ex) 426 client->prt_isdb_stats_ex(client->debug_data, p); 427 428 /* Update ISDB-T transmission parameters */ 429 c->frequency = p->frequency; 430 client->fe_status = sms_to_status(p->is_demod_locked, 0); 431 c->bandwidth_hz = sms_to_bw(p->bandwidth); 432 c->transmission_mode = sms_to_mode(p->transmission_mode); 433 c->guard_interval = sms_to_guard_interval(p->guard_interval); 434 c->isdbt_partial_reception = p->partial_reception ? 1 : 0; 435 n_layers = p->num_of_layers; 436 if (n_layers < 1) 437 n_layers = 1; 438 if (n_layers > 3) 439 n_layers = 3; 440 c->isdbt_layer_enabled = 0; 441 442 /* update reception data */ 443 c->lna = p->is_external_lna_on ? 1 : 0; 444 445 /* Carrier to noise ratio, in DB */ 446 c->cnr.stat[0].svalue = p->SNR * 1000; 447 448 /* signal Strength, in DBm */ 449 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 450 451 /* PER/BER and per-layer stats require demod lock */ 452 if (!p->is_demod_locked) 453 return; 454 455 client->last_per = c->block_error.stat[0].uvalue; 456 457 /* Clears global counters, as the code below will sum it again */ 458 c->block_error.stat[0].uvalue = 0; 459 c->block_count.stat[0].uvalue = 0; 460 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 461 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 462 c->post_bit_error.stat[0].uvalue = 0; 463 c->post_bit_count.stat[0].uvalue = 0; 464 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 465 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 466 467 c->post_bit_error.len = n_layers + 1; 468 c->post_bit_count.len = n_layers + 1; 469 c->block_error.len = n_layers + 1; 470 c->block_count.len = n_layers + 1; 471 for (i = 0; i < n_layers; i++) { 472 lr = &p->layer_info[i]; 473 474 /* Update per-layer transmission parameters */ 475 if (lr->number_of_segments > 0 && lr->number_of_segments < 13) { 476 c->isdbt_layer_enabled |= 1 << i; 477 c->layer[i].segment_count = lr->number_of_segments; 478 } else { 479 continue; 480 } 481 c->layer[i].modulation = sms_to_modulation(lr->constellation); 482 483 /* TS PER */ 484 c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; 485 c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; 486 c->block_error.stat[i + 1].uvalue += lr->error_ts_packets; 487 c->block_count.stat[i + 1].uvalue += lr->total_ts_packets; 488 489 /* Update global PER counter */ 490 c->block_error.stat[0].uvalue += lr->error_ts_packets; 491 c->block_count.stat[0].uvalue += lr->total_ts_packets; 492 493 /* ber */ 494 c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; 495 c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; 496 c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count; 497 c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count; 498 499 /* Update global ber counter */ 500 c->post_bit_error.stat[0].uvalue += lr->ber_error_count; 501 c->post_bit_count.stat[0].uvalue += lr->ber_bit_count; 502 } 503 } 504 505 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) 506 { 507 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; 508 struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) (((u8 *) cb->p) 509 + cb->offset); 510 void *p = phdr + 1; 511 struct dvb_frontend *fe = &client->frontend; 512 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 513 bool is_status_update = false; 514 515 switch (phdr->msg_type) { 516 case MSG_SMS_DVBT_BDA_DATA: 517 /* 518 * Only feed data to dvb demux if are there any feed listening 519 * to it and if the device has tuned 520 */ 521 if (client->feed_users && client->has_tuned) 522 dvb_dmx_swfilter(&client->demux, p, 523 cb->size - sizeof(struct sms_msg_hdr)); 524 break; 525 526 case MSG_SMS_RF_TUNE_RES: 527 case MSG_SMS_ISDBT_TUNE_RES: 528 complete(&client->tune_done); 529 break; 530 531 case MSG_SMS_SIGNAL_DETECTED_IND: 532 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | 533 FE_HAS_VITERBI | FE_HAS_SYNC | 534 FE_HAS_LOCK; 535 536 is_status_update = true; 537 break; 538 539 case MSG_SMS_NO_SIGNAL_IND: 540 client->fe_status = 0; 541 542 is_status_update = true; 543 break; 544 545 case MSG_SMS_TRANSMISSION_IND: 546 smsdvb_update_tx_params(client, p); 547 548 is_status_update = true; 549 break; 550 551 case MSG_SMS_HO_PER_SLICES_IND: 552 smsdvb_update_per_slices(client, p); 553 554 is_status_update = true; 555 break; 556 557 case MSG_SMS_GET_STATISTICS_RES: 558 switch (smscore_get_device_mode(client->coredev)) { 559 case DEVICE_MODE_ISDBT: 560 case DEVICE_MODE_ISDBT_BDA: 561 smsdvb_update_isdbt_stats(client, p); 562 break; 563 default: 564 /* Skip sms_msg_statistics_info:request_result field */ 565 smsdvb_update_dvb_stats(client, p + sizeof(u32)); 566 } 567 568 is_status_update = true; 569 break; 570 571 /* Only for ISDB-T */ 572 case MSG_SMS_GET_STATISTICS_EX_RES: 573 /* Skip sms_msg_statistics_info:request_result field? */ 574 smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); 575 is_status_update = true; 576 break; 577 default: 578 pr_debug("message not handled\n"); 579 } 580 smscore_putbuffer(client->coredev, cb); 581 582 if (is_status_update) { 583 if (client->fe_status & FE_HAS_LOCK) { 584 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); 585 if (client->last_per == c->block_error.stat[0].uvalue) 586 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); 587 else 588 sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); 589 client->has_tuned = true; 590 } else { 591 smsdvb_stats_not_ready(fe); 592 client->has_tuned = false; 593 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); 594 } 595 complete(&client->stats_done); 596 } 597 598 return 0; 599 } 600 601 static void smsdvb_media_device_unregister(struct smsdvb_client_t *client) 602 { 603 #ifdef CONFIG_MEDIA_CONTROLLER_DVB 604 struct smscore_device_t *coredev = client->coredev; 605 606 if (!coredev->media_dev) 607 return; 608 media_device_unregister(coredev->media_dev); 609 media_device_cleanup(coredev->media_dev); 610 kfree(coredev->media_dev); 611 coredev->media_dev = NULL; 612 #endif 613 } 614 615 static void smsdvb_unregister_client(struct smsdvb_client_t *client) 616 { 617 /* must be called under clientslock */ 618 619 list_del(&client->entry); 620 621 smsdvb_debugfs_release(client); 622 smscore_unregister_client(client->smsclient); 623 dvb_unregister_frontend(&client->frontend); 624 dvb_dmxdev_release(&client->dmxdev); 625 dvb_dmx_release(&client->demux); 626 smsdvb_media_device_unregister(client); 627 dvb_unregister_adapter(&client->adapter); 628 kfree(client); 629 } 630 631 static void smsdvb_onremove(void *context) 632 { 633 kmutex_lock(&g_smsdvb_clientslock); 634 635 smsdvb_unregister_client((struct smsdvb_client_t *) context); 636 637 kmutex_unlock(&g_smsdvb_clientslock); 638 } 639 640 static int smsdvb_start_feed(struct dvb_demux_feed *feed) 641 { 642 struct smsdvb_client_t *client = 643 container_of(feed->demux, struct smsdvb_client_t, demux); 644 struct sms_msg_data pid_msg; 645 646 pr_debug("add pid %d(%x)\n", 647 feed->pid, feed->pid); 648 649 client->feed_users++; 650 651 pid_msg.x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 652 pid_msg.x_msg_header.msg_dst_id = HIF_TASK; 653 pid_msg.x_msg_header.msg_flags = 0; 654 pid_msg.x_msg_header.msg_type = MSG_SMS_ADD_PID_FILTER_REQ; 655 pid_msg.x_msg_header.msg_length = sizeof(pid_msg); 656 pid_msg.msg_data[0] = feed->pid; 657 658 return smsclient_sendrequest(client->smsclient, 659 &pid_msg, sizeof(pid_msg)); 660 } 661 662 static int smsdvb_stop_feed(struct dvb_demux_feed *feed) 663 { 664 struct smsdvb_client_t *client = 665 container_of(feed->demux, struct smsdvb_client_t, demux); 666 struct sms_msg_data pid_msg; 667 668 pr_debug("remove pid %d(%x)\n", 669 feed->pid, feed->pid); 670 671 client->feed_users--; 672 673 pid_msg.x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 674 pid_msg.x_msg_header.msg_dst_id = HIF_TASK; 675 pid_msg.x_msg_header.msg_flags = 0; 676 pid_msg.x_msg_header.msg_type = MSG_SMS_REMOVE_PID_FILTER_REQ; 677 pid_msg.x_msg_header.msg_length = sizeof(pid_msg); 678 pid_msg.msg_data[0] = feed->pid; 679 680 return smsclient_sendrequest(client->smsclient, 681 &pid_msg, sizeof(pid_msg)); 682 } 683 684 static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, 685 void *buffer, size_t size, 686 struct completion *completion) 687 { 688 int rc; 689 690 rc = smsclient_sendrequest(client->smsclient, buffer, size); 691 if (rc < 0) 692 return rc; 693 694 return wait_for_completion_timeout(completion, 695 msecs_to_jiffies(2000)) ? 696 0 : -ETIME; 697 } 698 699 static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) 700 { 701 int rc; 702 struct sms_msg_hdr msg; 703 704 /* Don't request stats too fast */ 705 if (client->get_stats_jiffies && 706 (!time_after(jiffies, client->get_stats_jiffies))) 707 return 0; 708 client->get_stats_jiffies = jiffies + msecs_to_jiffies(100); 709 710 msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 711 msg.msg_dst_id = HIF_TASK; 712 msg.msg_flags = 0; 713 msg.msg_length = sizeof(msg); 714 715 switch (smscore_get_device_mode(client->coredev)) { 716 case DEVICE_MODE_ISDBT: 717 case DEVICE_MODE_ISDBT_BDA: 718 /* 719 * Check for firmware version, to avoid breaking for old cards 720 */ 721 if (client->coredev->fw_version >= 0x800) 722 msg.msg_type = MSG_SMS_GET_STATISTICS_EX_REQ; 723 else 724 msg.msg_type = MSG_SMS_GET_STATISTICS_REQ; 725 break; 726 default: 727 msg.msg_type = MSG_SMS_GET_STATISTICS_REQ; 728 } 729 730 rc = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 731 &client->stats_done); 732 733 return rc; 734 } 735 736 static inline int led_feedback(struct smsdvb_client_t *client) 737 { 738 if (!(client->fe_status & FE_HAS_LOCK)) 739 return sms_board_led_feedback(client->coredev, SMS_LED_OFF); 740 741 return sms_board_led_feedback(client->coredev, 742 (client->legacy_ber == 0) ? 743 SMS_LED_HI : SMS_LED_LO); 744 } 745 746 static int smsdvb_read_status(struct dvb_frontend *fe, enum fe_status *stat) 747 { 748 int rc; 749 struct smsdvb_client_t *client; 750 client = container_of(fe, struct smsdvb_client_t, frontend); 751 752 rc = smsdvb_send_statistics_request(client); 753 754 *stat = client->fe_status; 755 756 led_feedback(client); 757 758 return rc; 759 } 760 761 static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) 762 { 763 int rc; 764 struct smsdvb_client_t *client; 765 766 client = container_of(fe, struct smsdvb_client_t, frontend); 767 768 rc = smsdvb_send_statistics_request(client); 769 770 *ber = client->legacy_ber; 771 772 led_feedback(client); 773 774 return rc; 775 } 776 777 static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 778 { 779 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 780 int rc; 781 s32 power = (s32) c->strength.stat[0].uvalue; 782 struct smsdvb_client_t *client; 783 784 client = container_of(fe, struct smsdvb_client_t, frontend); 785 786 rc = smsdvb_send_statistics_request(client); 787 788 if (power < -95) 789 *strength = 0; 790 else if (power > -29) 791 *strength = 65535; 792 else 793 *strength = (power + 95) * 65535 / 66; 794 795 led_feedback(client); 796 797 return rc; 798 } 799 800 static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) 801 { 802 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 803 int rc; 804 struct smsdvb_client_t *client; 805 806 client = container_of(fe, struct smsdvb_client_t, frontend); 807 808 rc = smsdvb_send_statistics_request(client); 809 810 /* Preferred scale for SNR with legacy API: 0.1 dB */ 811 *snr = ((u32)c->cnr.stat[0].svalue) / 100; 812 813 led_feedback(client); 814 815 return rc; 816 } 817 818 static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 819 { 820 int rc; 821 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 822 struct smsdvb_client_t *client; 823 824 client = container_of(fe, struct smsdvb_client_t, frontend); 825 826 rc = smsdvb_send_statistics_request(client); 827 828 *ucblocks = c->block_error.stat[0].uvalue; 829 830 led_feedback(client); 831 832 return rc; 833 } 834 835 static int smsdvb_get_tune_settings(struct dvb_frontend *fe, 836 struct dvb_frontend_tune_settings *tune) 837 { 838 pr_debug("\n"); 839 840 tune->min_delay_ms = 400; 841 tune->step_size = 250000; 842 tune->max_drift = 0; 843 return 0; 844 } 845 846 static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) 847 { 848 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 849 struct smsdvb_client_t *client = 850 container_of(fe, struct smsdvb_client_t, frontend); 851 852 struct { 853 struct sms_msg_hdr msg; 854 u32 Data[3]; 855 } msg; 856 857 int ret; 858 859 client->fe_status = 0; 860 client->event_fe_state = -1; 861 client->event_unc_state = -1; 862 fe->dtv_property_cache.delivery_system = SYS_DVBT; 863 864 msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 865 msg.msg.msg_dst_id = HIF_TASK; 866 msg.msg.msg_flags = 0; 867 msg.msg.msg_type = MSG_SMS_RF_TUNE_REQ; 868 msg.msg.msg_length = sizeof(msg); 869 msg.Data[0] = c->frequency; 870 msg.Data[2] = 12000000; 871 872 pr_debug("%s: freq %d band %d\n", __func__, c->frequency, 873 c->bandwidth_hz); 874 875 switch (c->bandwidth_hz / 1000000) { 876 case 8: 877 msg.Data[1] = BW_8_MHZ; 878 break; 879 case 7: 880 msg.Data[1] = BW_7_MHZ; 881 break; 882 case 6: 883 msg.Data[1] = BW_6_MHZ; 884 break; 885 case 0: 886 return -EOPNOTSUPP; 887 default: 888 return -EINVAL; 889 } 890 /* Disable LNA, if any. An error is returned if no LNA is present */ 891 ret = sms_board_lna_control(client->coredev, 0); 892 if (ret == 0) { 893 enum fe_status status; 894 895 /* tune with LNA off at first */ 896 ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 897 &client->tune_done); 898 899 smsdvb_read_status(fe, &status); 900 901 if (status & FE_HAS_LOCK) 902 return ret; 903 904 /* previous tune didn't lock - enable LNA and tune again */ 905 sms_board_lna_control(client->coredev, 1); 906 } 907 908 return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 909 &client->tune_done); 910 } 911 912 static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) 913 { 914 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 915 struct smsdvb_client_t *client = 916 container_of(fe, struct smsdvb_client_t, frontend); 917 int board_id = smscore_get_board_id(client->coredev); 918 struct sms_board *board = sms_get_board(board_id); 919 enum sms_device_type_st type = board->type; 920 int ret; 921 922 struct { 923 struct sms_msg_hdr msg; 924 u32 Data[4]; 925 } msg; 926 927 fe->dtv_property_cache.delivery_system = SYS_ISDBT; 928 929 msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 930 msg.msg.msg_dst_id = HIF_TASK; 931 msg.msg.msg_flags = 0; 932 msg.msg.msg_type = MSG_SMS_ISDBT_TUNE_REQ; 933 msg.msg.msg_length = sizeof(msg); 934 935 if (c->isdbt_sb_segment_idx == -1) 936 c->isdbt_sb_segment_idx = 0; 937 938 if (!c->isdbt_layer_enabled) 939 c->isdbt_layer_enabled = 7; 940 941 msg.Data[0] = c->frequency; 942 msg.Data[1] = BW_ISDBT_1SEG; 943 msg.Data[2] = 12000000; 944 msg.Data[3] = c->isdbt_sb_segment_idx; 945 946 if (c->isdbt_partial_reception) { 947 if ((type == SMS_PELE || type == SMS_RIO) && 948 c->isdbt_sb_segment_count > 3) 949 msg.Data[1] = BW_ISDBT_13SEG; 950 else if (c->isdbt_sb_segment_count > 1) 951 msg.Data[1] = BW_ISDBT_3SEG; 952 } else if (type == SMS_PELE || type == SMS_RIO) 953 msg.Data[1] = BW_ISDBT_13SEG; 954 955 c->bandwidth_hz = 6000000; 956 957 pr_debug("freq %d segwidth %d segindex %d\n", 958 c->frequency, c->isdbt_sb_segment_count, 959 c->isdbt_sb_segment_idx); 960 961 /* Disable LNA, if any. An error is returned if no LNA is present */ 962 ret = sms_board_lna_control(client->coredev, 0); 963 if (ret == 0) { 964 enum fe_status status; 965 966 /* tune with LNA off at first */ 967 ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 968 &client->tune_done); 969 970 smsdvb_read_status(fe, &status); 971 972 if (status & FE_HAS_LOCK) 973 return ret; 974 975 /* previous tune didn't lock - enable LNA and tune again */ 976 sms_board_lna_control(client->coredev, 1); 977 } 978 return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 979 &client->tune_done); 980 } 981 982 static int smsdvb_set_frontend(struct dvb_frontend *fe) 983 { 984 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 985 struct smsdvb_client_t *client = 986 container_of(fe, struct smsdvb_client_t, frontend); 987 struct smscore_device_t *coredev = client->coredev; 988 989 smsdvb_stats_not_ready(fe); 990 c->strength.stat[0].uvalue = 0; 991 c->cnr.stat[0].uvalue = 0; 992 993 client->has_tuned = false; 994 995 switch (smscore_get_device_mode(coredev)) { 996 case DEVICE_MODE_DVBT: 997 case DEVICE_MODE_DVBT_BDA: 998 return smsdvb_dvbt_set_frontend(fe); 999 case DEVICE_MODE_ISDBT: 1000 case DEVICE_MODE_ISDBT_BDA: 1001 return smsdvb_isdbt_set_frontend(fe); 1002 default: 1003 return -EINVAL; 1004 } 1005 } 1006 1007 static int smsdvb_init(struct dvb_frontend *fe) 1008 { 1009 struct smsdvb_client_t *client = 1010 container_of(fe, struct smsdvb_client_t, frontend); 1011 1012 sms_board_power(client->coredev, 1); 1013 1014 sms_board_dvb3_event(client, DVB3_EVENT_INIT); 1015 return 0; 1016 } 1017 1018 static int smsdvb_sleep(struct dvb_frontend *fe) 1019 { 1020 struct smsdvb_client_t *client = 1021 container_of(fe, struct smsdvb_client_t, frontend); 1022 1023 sms_board_led_feedback(client->coredev, SMS_LED_OFF); 1024 sms_board_power(client->coredev, 0); 1025 1026 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); 1027 1028 return 0; 1029 } 1030 1031 static void smsdvb_release(struct dvb_frontend *fe) 1032 { 1033 /* do nothing */ 1034 } 1035 1036 static const struct dvb_frontend_ops smsdvb_fe_ops = { 1037 .info = { 1038 .name = "Siano Mobile Digital MDTV Receiver", 1039 .frequency_min_hz = 44250 * kHz, 1040 .frequency_max_hz = 867250 * kHz, 1041 .frequency_stepsize_hz = 250 * kHz, 1042 .caps = FE_CAN_INVERSION_AUTO | 1043 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 1044 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 1045 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 1046 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 1047 FE_CAN_GUARD_INTERVAL_AUTO | 1048 FE_CAN_RECOVER | 1049 FE_CAN_HIERARCHY_AUTO, 1050 }, 1051 1052 .release = smsdvb_release, 1053 1054 .set_frontend = smsdvb_set_frontend, 1055 .get_tune_settings = smsdvb_get_tune_settings, 1056 1057 .read_status = smsdvb_read_status, 1058 .read_ber = smsdvb_read_ber, 1059 .read_signal_strength = smsdvb_read_signal_strength, 1060 .read_snr = smsdvb_read_snr, 1061 .read_ucblocks = smsdvb_read_ucblocks, 1062 1063 .init = smsdvb_init, 1064 .sleep = smsdvb_sleep, 1065 }; 1066 1067 static int smsdvb_hotplug(struct smscore_device_t *coredev, 1068 struct device *device, int arrival) 1069 { 1070 struct smsclient_params_t params; 1071 struct smsdvb_client_t *client; 1072 int rc; 1073 1074 /* device removal handled by onremove callback */ 1075 if (!arrival) 1076 return 0; 1077 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); 1078 if (!client) 1079 return -ENOMEM; 1080 1081 /* register dvb adapter */ 1082 rc = dvb_register_adapter(&client->adapter, 1083 sms_get_board( 1084 smscore_get_board_id(coredev))->name, 1085 THIS_MODULE, device, adapter_nr); 1086 if (rc < 0) { 1087 pr_err("dvb_register_adapter() failed %d\n", rc); 1088 goto adapter_error; 1089 } 1090 dvb_register_media_controller(&client->adapter, coredev->media_dev); 1091 1092 /* init dvb demux */ 1093 client->demux.dmx.capabilities = DMX_TS_FILTERING; 1094 client->demux.filternum = 32; /* todo: nova ??? */ 1095 client->demux.feednum = 32; 1096 client->demux.start_feed = smsdvb_start_feed; 1097 client->demux.stop_feed = smsdvb_stop_feed; 1098 1099 rc = dvb_dmx_init(&client->demux); 1100 if (rc < 0) { 1101 pr_err("dvb_dmx_init failed %d\n", rc); 1102 goto dvbdmx_error; 1103 } 1104 1105 /* init dmxdev */ 1106 client->dmxdev.filternum = 32; 1107 client->dmxdev.demux = &client->demux.dmx; 1108 client->dmxdev.capabilities = 0; 1109 1110 rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); 1111 if (rc < 0) { 1112 pr_err("dvb_dmxdev_init failed %d\n", rc); 1113 goto dmxdev_error; 1114 } 1115 1116 /* init and register frontend */ 1117 memcpy(&client->frontend.ops, &smsdvb_fe_ops, 1118 sizeof(struct dvb_frontend_ops)); 1119 1120 switch (smscore_get_device_mode(coredev)) { 1121 case DEVICE_MODE_DVBT: 1122 case DEVICE_MODE_DVBT_BDA: 1123 client->frontend.ops.delsys[0] = SYS_DVBT; 1124 break; 1125 case DEVICE_MODE_ISDBT: 1126 case DEVICE_MODE_ISDBT_BDA: 1127 client->frontend.ops.delsys[0] = SYS_ISDBT; 1128 break; 1129 } 1130 1131 rc = dvb_register_frontend(&client->adapter, &client->frontend); 1132 if (rc < 0) { 1133 pr_err("frontend registration failed %d\n", rc); 1134 goto frontend_error; 1135 } 1136 1137 params.initial_id = 1; 1138 params.data_type = MSG_SMS_DVBT_BDA_DATA; 1139 params.onresponse_handler = smsdvb_onresponse; 1140 params.onremove_handler = smsdvb_onremove; 1141 params.context = client; 1142 1143 rc = smscore_register_client(coredev, ¶ms, &client->smsclient); 1144 if (rc < 0) { 1145 pr_err("smscore_register_client() failed %d\n", rc); 1146 goto client_error; 1147 } 1148 1149 client->coredev = coredev; 1150 1151 init_completion(&client->tune_done); 1152 init_completion(&client->stats_done); 1153 1154 kmutex_lock(&g_smsdvb_clientslock); 1155 1156 list_add(&client->entry, &g_smsdvb_clients); 1157 1158 kmutex_unlock(&g_smsdvb_clientslock); 1159 1160 client->event_fe_state = -1; 1161 client->event_unc_state = -1; 1162 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); 1163 1164 sms_board_setup(coredev); 1165 1166 if (smsdvb_debugfs_create(client) < 0) 1167 pr_info("failed to create debugfs node\n"); 1168 1169 rc = dvb_create_media_graph(&client->adapter, true); 1170 if (rc < 0) { 1171 pr_err("dvb_create_media_graph failed %d\n", rc); 1172 goto media_graph_error; 1173 } 1174 1175 pr_info("DVB interface registered.\n"); 1176 return 0; 1177 1178 media_graph_error: 1179 smsdvb_debugfs_release(client); 1180 1181 client_error: 1182 dvb_unregister_frontend(&client->frontend); 1183 1184 frontend_error: 1185 dvb_dmxdev_release(&client->dmxdev); 1186 1187 dmxdev_error: 1188 dvb_dmx_release(&client->demux); 1189 1190 dvbdmx_error: 1191 smsdvb_media_device_unregister(client); 1192 dvb_unregister_adapter(&client->adapter); 1193 1194 adapter_error: 1195 kfree(client); 1196 return rc; 1197 } 1198 1199 static int __init smsdvb_module_init(void) 1200 { 1201 int rc; 1202 1203 INIT_LIST_HEAD(&g_smsdvb_clients); 1204 kmutex_init(&g_smsdvb_clientslock); 1205 1206 smsdvb_debugfs_register(); 1207 1208 rc = smscore_register_hotplug(smsdvb_hotplug); 1209 1210 pr_debug("\n"); 1211 1212 return rc; 1213 } 1214 1215 static void __exit smsdvb_module_exit(void) 1216 { 1217 smscore_unregister_hotplug(smsdvb_hotplug); 1218 1219 kmutex_lock(&g_smsdvb_clientslock); 1220 1221 while (!list_empty(&g_smsdvb_clients)) 1222 smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next); 1223 1224 smsdvb_debugfs_unregister(); 1225 1226 kmutex_unlock(&g_smsdvb_clientslock); 1227 } 1228 1229 module_init(smsdvb_module_init); 1230 module_exit(smsdvb_module_exit); 1231 1232 MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); 1233 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); 1234 MODULE_LICENSE("GPL"); 1235