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