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 static 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 static 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 static u32 sms_to_hierarchy_table[] = { 64 [0] = HIERARCHY_NONE, 65 [1] = HIERARCHY_1, 66 [2] = HIERARCHY_2, 67 [3] = HIERARCHY_4, 68 }; 69 70 static 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 break; 144 default: 145 n_layers = 1; 146 } 147 148 /* Global stats */ 149 c->strength.len = 1; 150 c->cnr.len = 1; 151 c->strength.stat[0].scale = FE_SCALE_DECIBEL; 152 c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 153 154 /* Per-layer stats */ 155 c->post_bit_error.len = n_layers; 156 c->post_bit_count.len = n_layers; 157 c->block_error.len = n_layers; 158 c->block_count.len = n_layers; 159 160 /* 161 * Put all of them at FE_SCALE_NOT_AVAILABLE. They're dynamically 162 * changed when the stats become available. 163 */ 164 for (i = 0; i < n_layers; i++) { 165 c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 166 c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 167 c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 168 c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 169 } 170 } 171 172 static inline int sms_to_mode(u32 mode) 173 { 174 switch (mode) { 175 case 2: 176 return TRANSMISSION_MODE_2K; 177 case 4: 178 return TRANSMISSION_MODE_4K; 179 case 8: 180 return TRANSMISSION_MODE_8K; 181 } 182 return TRANSMISSION_MODE_AUTO; 183 } 184 185 static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) 186 { 187 if (is_demod_locked) 188 return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | 189 FE_HAS_SYNC | FE_HAS_LOCK; 190 191 if (is_rf_locked) 192 return FE_HAS_SIGNAL | FE_HAS_CARRIER; 193 194 return 0; 195 } 196 197 static inline u32 sms_to_bw(u32 value) 198 { 199 return value * 1000000; 200 } 201 202 #define convert_from_table(value, table, defval) ({ \ 203 u32 __ret; \ 204 if (value < ARRAY_SIZE(table)) \ 205 __ret = table[value]; \ 206 else \ 207 __ret = defval; \ 208 __ret; \ 209 }) 210 211 #define sms_to_guard_interval(value) \ 212 convert_from_table(value, sms_to_guard_interval_table, \ 213 GUARD_INTERVAL_AUTO); 214 215 #define sms_to_code_rate(value) \ 216 convert_from_table(value, sms_to_code_rate_table, \ 217 FEC_NONE); 218 219 #define sms_to_hierarchy(value) \ 220 convert_from_table(value, sms_to_hierarchy_table, \ 221 FEC_NONE); 222 223 #define sms_to_modulation(value) \ 224 convert_from_table(value, sms_to_modulation_table, \ 225 FEC_NONE); 226 227 static void smsdvb_update_tx_params(struct smsdvb_client_t *client, 228 struct sms_tx_stats *p) 229 { 230 struct dvb_frontend *fe = &client->frontend; 231 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 232 233 c->frequency = p->frequency; 234 client->fe_status = sms_to_status(p->is_demod_locked, 0); 235 c->bandwidth_hz = sms_to_bw(p->bandwidth); 236 c->transmission_mode = sms_to_mode(p->transmission_mode); 237 c->guard_interval = sms_to_guard_interval(p->guard_interval); 238 c->code_rate_HP = sms_to_code_rate(p->code_rate); 239 c->code_rate_LP = sms_to_code_rate(p->lp_code_rate); 240 c->hierarchy = sms_to_hierarchy(p->hierarchy); 241 c->modulation = sms_to_modulation(p->constellation); 242 } 243 244 static void smsdvb_update_per_slices(struct smsdvb_client_t *client, 245 struct RECEPTION_STATISTICS_PER_SLICES_S *p) 246 { 247 struct dvb_frontend *fe = &client->frontend; 248 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 249 u64 tmp; 250 251 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 252 c->modulation = sms_to_modulation(p->constellation); 253 254 /* signal Strength, in DBm */ 255 c->strength.stat[0].uvalue = p->in_band_power * 1000; 256 257 /* Carrier to noise ratio, in DB */ 258 c->cnr.stat[0].svalue = p->snr * 1000; 259 260 /* PER/BER requires demod lock */ 261 if (!p->is_demod_locked) 262 return; 263 264 /* TS PER */ 265 client->last_per = c->block_error.stat[0].uvalue; 266 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 267 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 268 c->block_error.stat[0].uvalue += p->ets_packets; 269 c->block_count.stat[0].uvalue += p->ets_packets + p->ts_packets; 270 271 /* ber */ 272 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 273 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 274 c->post_bit_error.stat[0].uvalue += p->ber_error_count; 275 c->post_bit_count.stat[0].uvalue += p->ber_bit_count; 276 277 /* Legacy PER/BER */ 278 tmp = p->ets_packets * 65535; 279 if (p->ts_packets + p->ets_packets) 280 do_div(tmp, p->ts_packets + p->ets_packets); 281 client->legacy_per = tmp; 282 } 283 284 static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, 285 struct sms_stats *p) 286 { 287 struct dvb_frontend *fe = &client->frontend; 288 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 289 290 if (client->prt_dvb_stats) 291 client->prt_dvb_stats(client->debug_data, p); 292 293 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 294 295 /* Update DVB modulation parameters */ 296 c->frequency = p->frequency; 297 client->fe_status = sms_to_status(p->is_demod_locked, 0); 298 c->bandwidth_hz = sms_to_bw(p->bandwidth); 299 c->transmission_mode = sms_to_mode(p->transmission_mode); 300 c->guard_interval = sms_to_guard_interval(p->guard_interval); 301 c->code_rate_HP = sms_to_code_rate(p->code_rate); 302 c->code_rate_LP = sms_to_code_rate(p->lp_code_rate); 303 c->hierarchy = sms_to_hierarchy(p->hierarchy); 304 c->modulation = sms_to_modulation(p->constellation); 305 306 /* update reception data */ 307 c->lna = p->is_external_lna_on ? 1 : 0; 308 309 /* Carrier to noise ratio, in DB */ 310 c->cnr.stat[0].svalue = p->SNR * 1000; 311 312 /* signal Strength, in DBm */ 313 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 314 315 /* PER/BER requires demod lock */ 316 if (!p->is_demod_locked) 317 return; 318 319 /* TS PER */ 320 client->last_per = c->block_error.stat[0].uvalue; 321 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 322 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 323 c->block_error.stat[0].uvalue += p->error_ts_packets; 324 c->block_count.stat[0].uvalue += p->total_ts_packets; 325 326 /* ber */ 327 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 328 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 329 c->post_bit_error.stat[0].uvalue += p->ber_error_count; 330 c->post_bit_count.stat[0].uvalue += p->ber_bit_count; 331 332 /* Legacy PER/BER */ 333 client->legacy_ber = p->ber; 334 }; 335 336 static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, 337 struct sms_isdbt_stats *p) 338 { 339 struct dvb_frontend *fe = &client->frontend; 340 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 341 struct sms_isdbt_layer_stats *lr; 342 int i, n_layers; 343 344 if (client->prt_isdb_stats) 345 client->prt_isdb_stats(client->debug_data, p); 346 347 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 348 349 /* 350 * Firmware 2.1 seems to report only lock status and 351 * signal strength. The signal strength indicator is at the 352 * wrong field. 353 */ 354 if (p->statistics_type == 0) { 355 c->strength.stat[0].uvalue = ((s32)p->transmission_mode) * 1000; 356 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 357 return; 358 } 359 360 /* Update ISDB-T transmission parameters */ 361 c->frequency = p->frequency; 362 c->bandwidth_hz = sms_to_bw(p->bandwidth); 363 c->transmission_mode = sms_to_mode(p->transmission_mode); 364 c->guard_interval = sms_to_guard_interval(p->guard_interval); 365 c->isdbt_partial_reception = p->partial_reception ? 1 : 0; 366 n_layers = p->num_of_layers; 367 if (n_layers < 1) 368 n_layers = 1; 369 if (n_layers > 3) 370 n_layers = 3; 371 c->isdbt_layer_enabled = 0; 372 373 /* update reception data */ 374 c->lna = p->is_external_lna_on ? 1 : 0; 375 376 /* Carrier to noise ratio, in DB */ 377 c->cnr.stat[0].svalue = p->SNR * 1000; 378 379 /* signal Strength, in DBm */ 380 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 381 382 /* PER/BER and per-layer stats require demod lock */ 383 if (!p->is_demod_locked) 384 return; 385 386 client->last_per = c->block_error.stat[0].uvalue; 387 388 /* Clears global counters, as the code below will sum it again */ 389 c->block_error.stat[0].uvalue = 0; 390 c->block_count.stat[0].uvalue = 0; 391 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 392 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 393 c->post_bit_error.stat[0].uvalue = 0; 394 c->post_bit_count.stat[0].uvalue = 0; 395 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 396 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 397 398 for (i = 0; i < n_layers; i++) { 399 lr = &p->layer_info[i]; 400 401 /* Update per-layer transmission parameters */ 402 if (lr->number_of_segments > 0 && lr->number_of_segments < 13) { 403 c->isdbt_layer_enabled |= 1 << i; 404 c->layer[i].segment_count = lr->number_of_segments; 405 } else { 406 continue; 407 } 408 c->layer[i].modulation = sms_to_modulation(lr->constellation); 409 410 /* TS PER */ 411 c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; 412 c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; 413 c->block_error.stat[i + 1].uvalue += lr->error_ts_packets; 414 c->block_count.stat[i + 1].uvalue += lr->total_ts_packets; 415 416 /* Update global PER counter */ 417 c->block_error.stat[0].uvalue += lr->error_ts_packets; 418 c->block_count.stat[0].uvalue += lr->total_ts_packets; 419 420 /* BER */ 421 c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; 422 c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; 423 c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count; 424 c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count; 425 426 /* Update global BER counter */ 427 c->post_bit_error.stat[0].uvalue += lr->ber_error_count; 428 c->post_bit_count.stat[0].uvalue += lr->ber_bit_count; 429 } 430 } 431 432 static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, 433 struct sms_isdbt_stats_ex *p) 434 { 435 struct dvb_frontend *fe = &client->frontend; 436 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 437 struct sms_isdbt_layer_stats *lr; 438 int i, n_layers; 439 440 if (client->prt_isdb_stats_ex) 441 client->prt_isdb_stats_ex(client->debug_data, p); 442 443 /* Update ISDB-T transmission parameters */ 444 c->frequency = p->frequency; 445 client->fe_status = sms_to_status(p->is_demod_locked, 0); 446 c->bandwidth_hz = sms_to_bw(p->bandwidth); 447 c->transmission_mode = sms_to_mode(p->transmission_mode); 448 c->guard_interval = sms_to_guard_interval(p->guard_interval); 449 c->isdbt_partial_reception = p->partial_reception ? 1 : 0; 450 n_layers = p->num_of_layers; 451 if (n_layers < 1) 452 n_layers = 1; 453 if (n_layers > 3) 454 n_layers = 3; 455 c->isdbt_layer_enabled = 0; 456 457 /* update reception data */ 458 c->lna = p->is_external_lna_on ? 1 : 0; 459 460 /* Carrier to noise ratio, in DB */ 461 c->cnr.stat[0].svalue = p->SNR * 1000; 462 463 /* signal Strength, in DBm */ 464 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 465 466 /* PER/BER and per-layer stats require demod lock */ 467 if (!p->is_demod_locked) 468 return; 469 470 client->last_per = c->block_error.stat[0].uvalue; 471 472 /* Clears global counters, as the code below will sum it again */ 473 c->block_error.stat[0].uvalue = 0; 474 c->block_count.stat[0].uvalue = 0; 475 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 476 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 477 c->post_bit_error.stat[0].uvalue = 0; 478 c->post_bit_count.stat[0].uvalue = 0; 479 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 480 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 481 482 c->post_bit_error.len = n_layers + 1; 483 c->post_bit_count.len = n_layers + 1; 484 c->block_error.len = n_layers + 1; 485 c->block_count.len = n_layers + 1; 486 for (i = 0; i < n_layers; i++) { 487 lr = &p->layer_info[i]; 488 489 /* Update per-layer transmission parameters */ 490 if (lr->number_of_segments > 0 && lr->number_of_segments < 13) { 491 c->isdbt_layer_enabled |= 1 << i; 492 c->layer[i].segment_count = lr->number_of_segments; 493 } else { 494 continue; 495 } 496 c->layer[i].modulation = sms_to_modulation(lr->constellation); 497 498 /* TS PER */ 499 c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; 500 c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; 501 c->block_error.stat[i + 1].uvalue += lr->error_ts_packets; 502 c->block_count.stat[i + 1].uvalue += lr->total_ts_packets; 503 504 /* Update global PER counter */ 505 c->block_error.stat[0].uvalue += lr->error_ts_packets; 506 c->block_count.stat[0].uvalue += lr->total_ts_packets; 507 508 /* ber */ 509 c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; 510 c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; 511 c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count; 512 c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count; 513 514 /* Update global ber counter */ 515 c->post_bit_error.stat[0].uvalue += lr->ber_error_count; 516 c->post_bit_count.stat[0].uvalue += lr->ber_bit_count; 517 } 518 } 519 520 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) 521 { 522 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; 523 struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) (((u8 *) cb->p) 524 + cb->offset); 525 void *p = phdr + 1; 526 struct dvb_frontend *fe = &client->frontend; 527 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 528 bool is_status_update = false; 529 530 switch (phdr->msg_type) { 531 case MSG_SMS_DVBT_BDA_DATA: 532 /* 533 * Only feed data to dvb demux if are there any feed listening 534 * to it and if the device has tuned 535 */ 536 if (client->feed_users && client->has_tuned) 537 dvb_dmx_swfilter(&client->demux, p, 538 cb->size - sizeof(struct sms_msg_hdr)); 539 break; 540 541 case MSG_SMS_RF_TUNE_RES: 542 case MSG_SMS_ISDBT_TUNE_RES: 543 complete(&client->tune_done); 544 break; 545 546 case MSG_SMS_SIGNAL_DETECTED_IND: 547 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | 548 FE_HAS_VITERBI | FE_HAS_SYNC | 549 FE_HAS_LOCK; 550 551 is_status_update = true; 552 break; 553 554 case MSG_SMS_NO_SIGNAL_IND: 555 client->fe_status = 0; 556 557 is_status_update = true; 558 break; 559 560 case MSG_SMS_TRANSMISSION_IND: 561 smsdvb_update_tx_params(client, p); 562 563 is_status_update = true; 564 break; 565 566 case MSG_SMS_HO_PER_SLICES_IND: 567 smsdvb_update_per_slices(client, p); 568 569 is_status_update = true; 570 break; 571 572 case MSG_SMS_GET_STATISTICS_RES: 573 switch (smscore_get_device_mode(client->coredev)) { 574 case DEVICE_MODE_ISDBT: 575 case DEVICE_MODE_ISDBT_BDA: 576 smsdvb_update_isdbt_stats(client, p); 577 break; 578 default: 579 /* Skip sms_msg_statistics_info:request_result field */ 580 smsdvb_update_dvb_stats(client, p + sizeof(u32)); 581 } 582 583 is_status_update = true; 584 break; 585 586 /* Only for ISDB-T */ 587 case MSG_SMS_GET_STATISTICS_EX_RES: 588 /* Skip sms_msg_statistics_info:request_result field? */ 589 smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); 590 is_status_update = true; 591 break; 592 default: 593 sms_info("message not handled"); 594 } 595 smscore_putbuffer(client->coredev, cb); 596 597 if (is_status_update) { 598 if (client->fe_status & FE_HAS_LOCK) { 599 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); 600 if (client->last_per == c->block_error.stat[0].uvalue) 601 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); 602 else 603 sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); 604 client->has_tuned = true; 605 } else { 606 smsdvb_stats_not_ready(fe); 607 client->has_tuned = false; 608 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); 609 } 610 complete(&client->stats_done); 611 } 612 613 return 0; 614 } 615 616 static void smsdvb_unregister_client(struct smsdvb_client_t *client) 617 { 618 /* must be called under clientslock */ 619 620 list_del(&client->entry); 621 622 smsdvb_debugfs_release(client); 623 smscore_unregister_client(client->smsclient); 624 dvb_unregister_frontend(&client->frontend); 625 dvb_dmxdev_release(&client->dmxdev); 626 dvb_dmx_release(&client->demux); 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 sms_debug("add pid %d(%x)", 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 sms_debug("remove pid %d(%x)", 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, fe_status_t *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 sms_debug(""); 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 sms_info("%s: freq %d band %d", __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 fe_status_t 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 sms_info("%s: freq %d segwidth %d segindex %d", __func__, 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 fe_status_t 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 /* Nothing to do here, as stats are automatically updated */ 1008 static int smsdvb_get_frontend(struct dvb_frontend *fe) 1009 { 1010 return 0; 1011 } 1012 1013 static int smsdvb_init(struct dvb_frontend *fe) 1014 { 1015 struct smsdvb_client_t *client = 1016 container_of(fe, struct smsdvb_client_t, frontend); 1017 1018 sms_board_power(client->coredev, 1); 1019 1020 sms_board_dvb3_event(client, DVB3_EVENT_INIT); 1021 return 0; 1022 } 1023 1024 static int smsdvb_sleep(struct dvb_frontend *fe) 1025 { 1026 struct smsdvb_client_t *client = 1027 container_of(fe, struct smsdvb_client_t, frontend); 1028 1029 sms_board_led_feedback(client->coredev, SMS_LED_OFF); 1030 sms_board_power(client->coredev, 0); 1031 1032 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); 1033 1034 return 0; 1035 } 1036 1037 static void smsdvb_release(struct dvb_frontend *fe) 1038 { 1039 /* do nothing */ 1040 } 1041 1042 static struct dvb_frontend_ops smsdvb_fe_ops = { 1043 .info = { 1044 .name = "Siano Mobile Digital MDTV Receiver", 1045 .frequency_min = 44250000, 1046 .frequency_max = 867250000, 1047 .frequency_stepsize = 250000, 1048 .caps = FE_CAN_INVERSION_AUTO | 1049 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 1050 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 1051 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 1052 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 1053 FE_CAN_GUARD_INTERVAL_AUTO | 1054 FE_CAN_RECOVER | 1055 FE_CAN_HIERARCHY_AUTO, 1056 }, 1057 1058 .release = smsdvb_release, 1059 1060 .set_frontend = smsdvb_set_frontend, 1061 .get_frontend = smsdvb_get_frontend, 1062 .get_tune_settings = smsdvb_get_tune_settings, 1063 1064 .read_status = smsdvb_read_status, 1065 .read_ber = smsdvb_read_ber, 1066 .read_signal_strength = smsdvb_read_signal_strength, 1067 .read_snr = smsdvb_read_snr, 1068 .read_ucblocks = smsdvb_read_ucblocks, 1069 1070 .init = smsdvb_init, 1071 .sleep = smsdvb_sleep, 1072 }; 1073 1074 static int smsdvb_hotplug(struct smscore_device_t *coredev, 1075 struct device *device, int arrival) 1076 { 1077 struct smsclient_params_t params; 1078 struct smsdvb_client_t *client; 1079 int rc; 1080 1081 /* device removal handled by onremove callback */ 1082 if (!arrival) 1083 return 0; 1084 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); 1085 if (!client) { 1086 sms_err("kmalloc() failed"); 1087 return -ENOMEM; 1088 } 1089 1090 /* register dvb adapter */ 1091 rc = dvb_register_adapter(&client->adapter, 1092 sms_get_board( 1093 smscore_get_board_id(coredev))->name, 1094 THIS_MODULE, device, adapter_nr); 1095 if (rc < 0) { 1096 sms_err("dvb_register_adapter() failed %d", rc); 1097 goto adapter_error; 1098 } 1099 1100 /* init dvb demux */ 1101 client->demux.dmx.capabilities = DMX_TS_FILTERING; 1102 client->demux.filternum = 32; /* todo: nova ??? */ 1103 client->demux.feednum = 32; 1104 client->demux.start_feed = smsdvb_start_feed; 1105 client->demux.stop_feed = smsdvb_stop_feed; 1106 1107 rc = dvb_dmx_init(&client->demux); 1108 if (rc < 0) { 1109 sms_err("dvb_dmx_init failed %d", rc); 1110 goto dvbdmx_error; 1111 } 1112 1113 /* init dmxdev */ 1114 client->dmxdev.filternum = 32; 1115 client->dmxdev.demux = &client->demux.dmx; 1116 client->dmxdev.capabilities = 0; 1117 1118 rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); 1119 if (rc < 0) { 1120 sms_err("dvb_dmxdev_init failed %d", rc); 1121 goto dmxdev_error; 1122 } 1123 1124 /* init and register frontend */ 1125 memcpy(&client->frontend.ops, &smsdvb_fe_ops, 1126 sizeof(struct dvb_frontend_ops)); 1127 1128 switch (smscore_get_device_mode(coredev)) { 1129 case DEVICE_MODE_DVBT: 1130 case DEVICE_MODE_DVBT_BDA: 1131 client->frontend.ops.delsys[0] = SYS_DVBT; 1132 break; 1133 case DEVICE_MODE_ISDBT: 1134 case DEVICE_MODE_ISDBT_BDA: 1135 client->frontend.ops.delsys[0] = SYS_ISDBT; 1136 break; 1137 } 1138 1139 rc = dvb_register_frontend(&client->adapter, &client->frontend); 1140 if (rc < 0) { 1141 sms_err("frontend registration failed %d", rc); 1142 goto frontend_error; 1143 } 1144 1145 params.initial_id = 1; 1146 params.data_type = MSG_SMS_DVBT_BDA_DATA; 1147 params.onresponse_handler = smsdvb_onresponse; 1148 params.onremove_handler = smsdvb_onremove; 1149 params.context = client; 1150 1151 rc = smscore_register_client(coredev, ¶ms, &client->smsclient); 1152 if (rc < 0) { 1153 sms_err("smscore_register_client() failed %d", rc); 1154 goto client_error; 1155 } 1156 1157 client->coredev = coredev; 1158 1159 init_completion(&client->tune_done); 1160 init_completion(&client->stats_done); 1161 1162 kmutex_lock(&g_smsdvb_clientslock); 1163 1164 list_add(&client->entry, &g_smsdvb_clients); 1165 1166 kmutex_unlock(&g_smsdvb_clientslock); 1167 1168 client->event_fe_state = -1; 1169 client->event_unc_state = -1; 1170 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); 1171 1172 sms_info("success"); 1173 sms_board_setup(coredev); 1174 1175 if (smsdvb_debugfs_create(client) < 0) 1176 sms_info("failed to create debugfs node"); 1177 1178 return 0; 1179 1180 client_error: 1181 dvb_unregister_frontend(&client->frontend); 1182 1183 frontend_error: 1184 dvb_dmxdev_release(&client->dmxdev); 1185 1186 dmxdev_error: 1187 dvb_dmx_release(&client->demux); 1188 1189 dvbdmx_error: 1190 dvb_unregister_adapter(&client->adapter); 1191 1192 adapter_error: 1193 kfree(client); 1194 return rc; 1195 } 1196 1197 static int __init smsdvb_module_init(void) 1198 { 1199 int rc; 1200 1201 INIT_LIST_HEAD(&g_smsdvb_clients); 1202 kmutex_init(&g_smsdvb_clientslock); 1203 1204 smsdvb_debugfs_register(); 1205 1206 rc = smscore_register_hotplug(smsdvb_hotplug); 1207 1208 sms_debug(""); 1209 1210 return rc; 1211 } 1212 1213 static void __exit smsdvb_module_exit(void) 1214 { 1215 smscore_unregister_hotplug(smsdvb_hotplug); 1216 1217 kmutex_lock(&g_smsdvb_clientslock); 1218 1219 while (!list_empty(&g_smsdvb_clients)) 1220 smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next); 1221 1222 smsdvb_debugfs_unregister(); 1223 1224 kmutex_unlock(&g_smsdvb_clientslock); 1225 } 1226 1227 module_init(smsdvb_module_init); 1228 module_exit(smsdvb_module_exit); 1229 1230 MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); 1231 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); 1232 MODULE_LICENSE("GPL"); 1233