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 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 do_div(tmp, p->ts_packets + p->ets_packets); 280 client->legacy_per = tmp; 281 } 282 283 static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, 284 struct sms_stats *p) 285 { 286 struct dvb_frontend *fe = &client->frontend; 287 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 288 289 if (client->prt_dvb_stats) 290 client->prt_dvb_stats(client->debug_data, p); 291 292 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 293 294 /* Update DVB modulation parameters */ 295 c->frequency = p->frequency; 296 client->fe_status = sms_to_status(p->is_demod_locked, 0); 297 c->bandwidth_hz = sms_to_bw(p->bandwidth); 298 c->transmission_mode = sms_to_mode(p->transmission_mode); 299 c->guard_interval = sms_to_guard_interval(p->guard_interval); 300 c->code_rate_HP = sms_to_code_rate(p->code_rate); 301 c->code_rate_LP = sms_to_code_rate(p->lp_code_rate); 302 c->hierarchy = sms_to_hierarchy(p->hierarchy); 303 c->modulation = sms_to_modulation(p->constellation); 304 305 /* update reception data */ 306 c->lna = p->is_external_lna_on ? 1 : 0; 307 308 /* Carrier to noise ratio, in DB */ 309 c->cnr.stat[0].svalue = p->SNR * 1000; 310 311 /* signal Strength, in DBm */ 312 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 313 314 /* PER/BER requires demod lock */ 315 if (!p->is_demod_locked) 316 return; 317 318 /* TS PER */ 319 client->last_per = c->block_error.stat[0].uvalue; 320 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 321 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 322 c->block_error.stat[0].uvalue += p->error_ts_packets; 323 c->block_count.stat[0].uvalue += p->total_ts_packets; 324 325 /* ber */ 326 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 327 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 328 c->post_bit_error.stat[0].uvalue += p->ber_error_count; 329 c->post_bit_count.stat[0].uvalue += p->ber_bit_count; 330 331 /* Legacy PER/BER */ 332 client->legacy_ber = p->ber; 333 }; 334 335 static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, 336 struct sms_isdbt_stats *p) 337 { 338 struct dvb_frontend *fe = &client->frontend; 339 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 340 struct sms_isdbt_layer_stats *lr; 341 int i, n_layers; 342 343 if (client->prt_isdb_stats) 344 client->prt_isdb_stats(client->debug_data, p); 345 346 client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked); 347 348 /* 349 * Firmware 2.1 seems to report only lock status and 350 * signal strength. The signal strength indicator is at the 351 * wrong field. 352 */ 353 if (p->statistics_type == 0) { 354 c->strength.stat[0].uvalue = ((s32)p->transmission_mode) * 1000; 355 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 356 return; 357 } 358 359 /* Update ISDB-T transmission parameters */ 360 c->frequency = p->frequency; 361 c->bandwidth_hz = sms_to_bw(p->bandwidth); 362 c->transmission_mode = sms_to_mode(p->transmission_mode); 363 c->guard_interval = sms_to_guard_interval(p->guard_interval); 364 c->isdbt_partial_reception = p->partial_reception ? 1 : 0; 365 n_layers = p->num_of_layers; 366 if (n_layers < 1) 367 n_layers = 1; 368 if (n_layers > 3) 369 n_layers = 3; 370 c->isdbt_layer_enabled = 0; 371 372 /* update reception data */ 373 c->lna = p->is_external_lna_on ? 1 : 0; 374 375 /* Carrier to noise ratio, in DB */ 376 c->cnr.stat[0].svalue = p->SNR * 1000; 377 378 /* signal Strength, in DBm */ 379 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 380 381 /* PER/BER and per-layer stats require demod lock */ 382 if (!p->is_demod_locked) 383 return; 384 385 client->last_per = c->block_error.stat[0].uvalue; 386 387 /* Clears global counters, as the code below will sum it again */ 388 c->block_error.stat[0].uvalue = 0; 389 c->block_count.stat[0].uvalue = 0; 390 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 391 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 392 c->post_bit_error.stat[0].uvalue = 0; 393 c->post_bit_count.stat[0].uvalue = 0; 394 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 395 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 396 397 for (i = 0; i < n_layers; i++) { 398 lr = &p->layer_info[i]; 399 400 /* Update per-layer transmission parameters */ 401 if (lr->number_of_segments > 0 && lr->number_of_segments < 13) { 402 c->isdbt_layer_enabled |= 1 << i; 403 c->layer[i].segment_count = lr->number_of_segments; 404 } else { 405 continue; 406 } 407 c->layer[i].modulation = sms_to_modulation(lr->constellation); 408 409 /* TS PER */ 410 c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; 411 c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; 412 c->block_error.stat[i + 1].uvalue += lr->error_ts_packets; 413 c->block_count.stat[i + 1].uvalue += lr->total_ts_packets; 414 415 /* Update global PER counter */ 416 c->block_error.stat[0].uvalue += lr->error_ts_packets; 417 c->block_count.stat[0].uvalue += lr->total_ts_packets; 418 419 /* BER */ 420 c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; 421 c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; 422 c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count; 423 c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count; 424 425 /* Update global BER counter */ 426 c->post_bit_error.stat[0].uvalue += lr->ber_error_count; 427 c->post_bit_count.stat[0].uvalue += lr->ber_bit_count; 428 } 429 } 430 431 static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, 432 struct sms_isdbt_stats_ex *p) 433 { 434 struct dvb_frontend *fe = &client->frontend; 435 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 436 struct sms_isdbt_layer_stats *lr; 437 int i, n_layers; 438 439 if (client->prt_isdb_stats_ex) 440 client->prt_isdb_stats_ex(client->debug_data, p); 441 442 /* Update ISDB-T transmission parameters */ 443 c->frequency = p->frequency; 444 client->fe_status = sms_to_status(p->is_demod_locked, 0); 445 c->bandwidth_hz = sms_to_bw(p->bandwidth); 446 c->transmission_mode = sms_to_mode(p->transmission_mode); 447 c->guard_interval = sms_to_guard_interval(p->guard_interval); 448 c->isdbt_partial_reception = p->partial_reception ? 1 : 0; 449 n_layers = p->num_of_layers; 450 if (n_layers < 1) 451 n_layers = 1; 452 if (n_layers > 3) 453 n_layers = 3; 454 c->isdbt_layer_enabled = 0; 455 456 /* update reception data */ 457 c->lna = p->is_external_lna_on ? 1 : 0; 458 459 /* Carrier to noise ratio, in DB */ 460 c->cnr.stat[0].svalue = p->SNR * 1000; 461 462 /* signal Strength, in DBm */ 463 c->strength.stat[0].uvalue = p->in_band_pwr * 1000; 464 465 /* PER/BER and per-layer stats require demod lock */ 466 if (!p->is_demod_locked) 467 return; 468 469 client->last_per = c->block_error.stat[0].uvalue; 470 471 /* Clears global counters, as the code below will sum it again */ 472 c->block_error.stat[0].uvalue = 0; 473 c->block_count.stat[0].uvalue = 0; 474 c->block_error.stat[0].scale = FE_SCALE_COUNTER; 475 c->block_count.stat[0].scale = FE_SCALE_COUNTER; 476 c->post_bit_error.stat[0].uvalue = 0; 477 c->post_bit_count.stat[0].uvalue = 0; 478 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 479 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 480 481 c->post_bit_error.len = n_layers + 1; 482 c->post_bit_count.len = n_layers + 1; 483 c->block_error.len = n_layers + 1; 484 c->block_count.len = n_layers + 1; 485 for (i = 0; i < n_layers; i++) { 486 lr = &p->layer_info[i]; 487 488 /* Update per-layer transmission parameters */ 489 if (lr->number_of_segments > 0 && lr->number_of_segments < 13) { 490 c->isdbt_layer_enabled |= 1 << i; 491 c->layer[i].segment_count = lr->number_of_segments; 492 } else { 493 continue; 494 } 495 c->layer[i].modulation = sms_to_modulation(lr->constellation); 496 497 /* TS PER */ 498 c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; 499 c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; 500 c->block_error.stat[i + 1].uvalue += lr->error_ts_packets; 501 c->block_count.stat[i + 1].uvalue += lr->total_ts_packets; 502 503 /* Update global PER counter */ 504 c->block_error.stat[0].uvalue += lr->error_ts_packets; 505 c->block_count.stat[0].uvalue += lr->total_ts_packets; 506 507 /* ber */ 508 c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; 509 c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; 510 c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count; 511 c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count; 512 513 /* Update global ber counter */ 514 c->post_bit_error.stat[0].uvalue += lr->ber_error_count; 515 c->post_bit_count.stat[0].uvalue += lr->ber_bit_count; 516 } 517 } 518 519 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) 520 { 521 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; 522 struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) (((u8 *) cb->p) 523 + cb->offset); 524 void *p = phdr + 1; 525 struct dvb_frontend *fe = &client->frontend; 526 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 527 bool is_status_update = false; 528 529 switch (phdr->msg_type) { 530 case MSG_SMS_DVBT_BDA_DATA: 531 /* 532 * Only feed data to dvb demux if are there any feed listening 533 * to it and if the device has tuned 534 */ 535 if (client->feed_users && client->has_tuned) 536 dvb_dmx_swfilter(&client->demux, p, 537 cb->size - sizeof(struct sms_msg_hdr)); 538 break; 539 540 case MSG_SMS_RF_TUNE_RES: 541 case MSG_SMS_ISDBT_TUNE_RES: 542 complete(&client->tune_done); 543 break; 544 545 case MSG_SMS_SIGNAL_DETECTED_IND: 546 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | 547 FE_HAS_VITERBI | FE_HAS_SYNC | 548 FE_HAS_LOCK; 549 550 is_status_update = true; 551 break; 552 553 case MSG_SMS_NO_SIGNAL_IND: 554 client->fe_status = 0; 555 556 is_status_update = true; 557 break; 558 559 case MSG_SMS_TRANSMISSION_IND: 560 smsdvb_update_tx_params(client, p); 561 562 is_status_update = true; 563 break; 564 565 case MSG_SMS_HO_PER_SLICES_IND: 566 smsdvb_update_per_slices(client, p); 567 568 is_status_update = true; 569 break; 570 571 case MSG_SMS_GET_STATISTICS_RES: 572 switch (smscore_get_device_mode(client->coredev)) { 573 case DEVICE_MODE_ISDBT: 574 case DEVICE_MODE_ISDBT_BDA: 575 smsdvb_update_isdbt_stats(client, p); 576 break; 577 default: 578 /* Skip sms_msg_statistics_info:request_result field */ 579 smsdvb_update_dvb_stats(client, p + sizeof(u32)); 580 } 581 582 is_status_update = true; 583 break; 584 585 /* Only for ISDB-T */ 586 case MSG_SMS_GET_STATISTICS_EX_RES: 587 /* Skip sms_msg_statistics_info:request_result field? */ 588 smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); 589 is_status_update = true; 590 break; 591 default: 592 sms_info("message not handled"); 593 } 594 smscore_putbuffer(client->coredev, cb); 595 596 if (is_status_update) { 597 if (client->fe_status & FE_HAS_LOCK) { 598 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); 599 if (client->last_per == c->block_error.stat[0].uvalue) 600 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); 601 else 602 sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); 603 client->has_tuned = true; 604 } else { 605 smsdvb_stats_not_ready(fe); 606 client->has_tuned = false; 607 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); 608 } 609 complete(&client->stats_done); 610 } 611 612 return 0; 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 dvb_unregister_adapter(&client->adapter); 627 kfree(client); 628 } 629 630 static void smsdvb_onremove(void *context) 631 { 632 kmutex_lock(&g_smsdvb_clientslock); 633 634 smsdvb_unregister_client((struct smsdvb_client_t *) context); 635 636 kmutex_unlock(&g_smsdvb_clientslock); 637 } 638 639 static int smsdvb_start_feed(struct dvb_demux_feed *feed) 640 { 641 struct smsdvb_client_t *client = 642 container_of(feed->demux, struct smsdvb_client_t, demux); 643 struct sms_msg_data pid_msg; 644 645 sms_debug("add pid %d(%x)", 646 feed->pid, feed->pid); 647 648 client->feed_users++; 649 650 pid_msg.x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 651 pid_msg.x_msg_header.msg_dst_id = HIF_TASK; 652 pid_msg.x_msg_header.msg_flags = 0; 653 pid_msg.x_msg_header.msg_type = MSG_SMS_ADD_PID_FILTER_REQ; 654 pid_msg.x_msg_header.msg_length = sizeof(pid_msg); 655 pid_msg.msg_data[0] = feed->pid; 656 657 return smsclient_sendrequest(client->smsclient, 658 &pid_msg, sizeof(pid_msg)); 659 } 660 661 static int smsdvb_stop_feed(struct dvb_demux_feed *feed) 662 { 663 struct smsdvb_client_t *client = 664 container_of(feed->demux, struct smsdvb_client_t, demux); 665 struct sms_msg_data pid_msg; 666 667 sms_debug("remove pid %d(%x)", 668 feed->pid, feed->pid); 669 670 client->feed_users--; 671 672 pid_msg.x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 673 pid_msg.x_msg_header.msg_dst_id = HIF_TASK; 674 pid_msg.x_msg_header.msg_flags = 0; 675 pid_msg.x_msg_header.msg_type = MSG_SMS_REMOVE_PID_FILTER_REQ; 676 pid_msg.x_msg_header.msg_length = sizeof(pid_msg); 677 pid_msg.msg_data[0] = feed->pid; 678 679 return smsclient_sendrequest(client->smsclient, 680 &pid_msg, sizeof(pid_msg)); 681 } 682 683 static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, 684 void *buffer, size_t size, 685 struct completion *completion) 686 { 687 int rc; 688 689 rc = smsclient_sendrequest(client->smsclient, buffer, size); 690 if (rc < 0) 691 return rc; 692 693 return wait_for_completion_timeout(completion, 694 msecs_to_jiffies(2000)) ? 695 0 : -ETIME; 696 } 697 698 static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) 699 { 700 int rc; 701 struct sms_msg_hdr msg; 702 703 /* Don't request stats too fast */ 704 if (client->get_stats_jiffies && 705 (!time_after(jiffies, client->get_stats_jiffies))) 706 return 0; 707 client->get_stats_jiffies = jiffies + msecs_to_jiffies(100); 708 709 msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 710 msg.msg_dst_id = HIF_TASK; 711 msg.msg_flags = 0; 712 msg.msg_length = sizeof(msg); 713 714 switch (smscore_get_device_mode(client->coredev)) { 715 case DEVICE_MODE_ISDBT: 716 case DEVICE_MODE_ISDBT_BDA: 717 /* 718 * Check for firmware version, to avoid breaking for old cards 719 */ 720 if (client->coredev->fw_version >= 0x800) 721 msg.msg_type = MSG_SMS_GET_STATISTICS_EX_REQ; 722 else 723 msg.msg_type = MSG_SMS_GET_STATISTICS_REQ; 724 break; 725 default: 726 msg.msg_type = MSG_SMS_GET_STATISTICS_REQ; 727 } 728 729 rc = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 730 &client->stats_done); 731 732 return rc; 733 } 734 735 static inline int led_feedback(struct smsdvb_client_t *client) 736 { 737 if (!(client->fe_status & FE_HAS_LOCK)) 738 return sms_board_led_feedback(client->coredev, SMS_LED_OFF); 739 740 return sms_board_led_feedback(client->coredev, 741 (client->legacy_ber == 0) ? 742 SMS_LED_HI : SMS_LED_LO); 743 } 744 745 static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) 746 { 747 int rc; 748 struct smsdvb_client_t *client; 749 client = container_of(fe, struct smsdvb_client_t, frontend); 750 751 rc = smsdvb_send_statistics_request(client); 752 753 *stat = client->fe_status; 754 755 led_feedback(client); 756 757 return rc; 758 } 759 760 static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) 761 { 762 int rc; 763 struct smsdvb_client_t *client; 764 765 client = container_of(fe, struct smsdvb_client_t, frontend); 766 767 rc = smsdvb_send_statistics_request(client); 768 769 *ber = client->legacy_ber; 770 771 led_feedback(client); 772 773 return rc; 774 } 775 776 static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 777 { 778 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 779 int rc; 780 s32 power = (s32) c->strength.stat[0].uvalue; 781 struct smsdvb_client_t *client; 782 783 client = container_of(fe, struct smsdvb_client_t, frontend); 784 785 rc = smsdvb_send_statistics_request(client); 786 787 if (power < -95) 788 *strength = 0; 789 else if (power > -29) 790 *strength = 65535; 791 else 792 *strength = (power + 95) * 65535 / 66; 793 794 led_feedback(client); 795 796 return rc; 797 } 798 799 static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) 800 { 801 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 802 int rc; 803 struct smsdvb_client_t *client; 804 805 client = container_of(fe, struct smsdvb_client_t, frontend); 806 807 rc = smsdvb_send_statistics_request(client); 808 809 /* Preferred scale for SNR with legacy API: 0.1 dB */ 810 *snr = ((u32)c->cnr.stat[0].svalue) / 100; 811 812 led_feedback(client); 813 814 return rc; 815 } 816 817 static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 818 { 819 int rc; 820 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 821 struct smsdvb_client_t *client; 822 823 client = container_of(fe, struct smsdvb_client_t, frontend); 824 825 rc = smsdvb_send_statistics_request(client); 826 827 *ucblocks = c->block_error.stat[0].uvalue; 828 829 led_feedback(client); 830 831 return rc; 832 } 833 834 static int smsdvb_get_tune_settings(struct dvb_frontend *fe, 835 struct dvb_frontend_tune_settings *tune) 836 { 837 sms_debug(""); 838 839 tune->min_delay_ms = 400; 840 tune->step_size = 250000; 841 tune->max_drift = 0; 842 return 0; 843 } 844 845 static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) 846 { 847 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 848 struct smsdvb_client_t *client = 849 container_of(fe, struct smsdvb_client_t, frontend); 850 851 struct { 852 struct sms_msg_hdr msg; 853 u32 Data[3]; 854 } msg; 855 856 int ret; 857 858 client->fe_status = 0; 859 client->event_fe_state = -1; 860 client->event_unc_state = -1; 861 fe->dtv_property_cache.delivery_system = SYS_DVBT; 862 863 msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 864 msg.msg.msg_dst_id = HIF_TASK; 865 msg.msg.msg_flags = 0; 866 msg.msg.msg_type = MSG_SMS_RF_TUNE_REQ; 867 msg.msg.msg_length = sizeof(msg); 868 msg.Data[0] = c->frequency; 869 msg.Data[2] = 12000000; 870 871 sms_info("%s: freq %d band %d", __func__, c->frequency, 872 c->bandwidth_hz); 873 874 switch (c->bandwidth_hz / 1000000) { 875 case 8: 876 msg.Data[1] = BW_8_MHZ; 877 break; 878 case 7: 879 msg.Data[1] = BW_7_MHZ; 880 break; 881 case 6: 882 msg.Data[1] = BW_6_MHZ; 883 break; 884 case 0: 885 return -EOPNOTSUPP; 886 default: 887 return -EINVAL; 888 } 889 /* Disable LNA, if any. An error is returned if no LNA is present */ 890 ret = sms_board_lna_control(client->coredev, 0); 891 if (ret == 0) { 892 fe_status_t status; 893 894 /* tune with LNA off at first */ 895 ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 896 &client->tune_done); 897 898 smsdvb_read_status(fe, &status); 899 900 if (status & FE_HAS_LOCK) 901 return ret; 902 903 /* previous tune didn't lock - enable LNA and tune again */ 904 sms_board_lna_control(client->coredev, 1); 905 } 906 907 return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 908 &client->tune_done); 909 } 910 911 static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) 912 { 913 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 914 struct smsdvb_client_t *client = 915 container_of(fe, struct smsdvb_client_t, frontend); 916 int board_id = smscore_get_board_id(client->coredev); 917 struct sms_board *board = sms_get_board(board_id); 918 enum sms_device_type_st type = board->type; 919 int ret; 920 921 struct { 922 struct sms_msg_hdr msg; 923 u32 Data[4]; 924 } msg; 925 926 fe->dtv_property_cache.delivery_system = SYS_ISDBT; 927 928 msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; 929 msg.msg.msg_dst_id = HIF_TASK; 930 msg.msg.msg_flags = 0; 931 msg.msg.msg_type = MSG_SMS_ISDBT_TUNE_REQ; 932 msg.msg.msg_length = sizeof(msg); 933 934 if (c->isdbt_sb_segment_idx == -1) 935 c->isdbt_sb_segment_idx = 0; 936 937 if (!c->isdbt_layer_enabled) 938 c->isdbt_layer_enabled = 7; 939 940 msg.Data[0] = c->frequency; 941 msg.Data[1] = BW_ISDBT_1SEG; 942 msg.Data[2] = 12000000; 943 msg.Data[3] = c->isdbt_sb_segment_idx; 944 945 if (c->isdbt_partial_reception) { 946 if ((type == SMS_PELE || type == SMS_RIO) && 947 c->isdbt_sb_segment_count > 3) 948 msg.Data[1] = BW_ISDBT_13SEG; 949 else if (c->isdbt_sb_segment_count > 1) 950 msg.Data[1] = BW_ISDBT_3SEG; 951 } else if (type == SMS_PELE || type == SMS_RIO) 952 msg.Data[1] = BW_ISDBT_13SEG; 953 954 c->bandwidth_hz = 6000000; 955 956 sms_info("%s: freq %d segwidth %d segindex %d", __func__, 957 c->frequency, c->isdbt_sb_segment_count, 958 c->isdbt_sb_segment_idx); 959 960 /* Disable LNA, if any. An error is returned if no LNA is present */ 961 ret = sms_board_lna_control(client->coredev, 0); 962 if (ret == 0) { 963 fe_status_t status; 964 965 /* tune with LNA off at first */ 966 ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 967 &client->tune_done); 968 969 smsdvb_read_status(fe, &status); 970 971 if (status & FE_HAS_LOCK) 972 return ret; 973 974 /* previous tune didn't lock - enable LNA and tune again */ 975 sms_board_lna_control(client->coredev, 1); 976 } 977 return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), 978 &client->tune_done); 979 } 980 981 static int smsdvb_set_frontend(struct dvb_frontend *fe) 982 { 983 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 984 struct smsdvb_client_t *client = 985 container_of(fe, struct smsdvb_client_t, frontend); 986 struct smscore_device_t *coredev = client->coredev; 987 988 smsdvb_stats_not_ready(fe); 989 c->strength.stat[0].uvalue = 0; 990 c->cnr.stat[0].uvalue = 0; 991 992 client->has_tuned = false; 993 994 switch (smscore_get_device_mode(coredev)) { 995 case DEVICE_MODE_DVBT: 996 case DEVICE_MODE_DVBT_BDA: 997 return smsdvb_dvbt_set_frontend(fe); 998 case DEVICE_MODE_ISDBT: 999 case DEVICE_MODE_ISDBT_BDA: 1000 return smsdvb_isdbt_set_frontend(fe); 1001 default: 1002 return -EINVAL; 1003 } 1004 } 1005 1006 /* Nothing to do here, as stats are automatically updated */ 1007 static int smsdvb_get_frontend(struct dvb_frontend *fe) 1008 { 1009 return 0; 1010 } 1011 1012 static int smsdvb_init(struct dvb_frontend *fe) 1013 { 1014 struct smsdvb_client_t *client = 1015 container_of(fe, struct smsdvb_client_t, frontend); 1016 1017 sms_board_power(client->coredev, 1); 1018 1019 sms_board_dvb3_event(client, DVB3_EVENT_INIT); 1020 return 0; 1021 } 1022 1023 static int smsdvb_sleep(struct dvb_frontend *fe) 1024 { 1025 struct smsdvb_client_t *client = 1026 container_of(fe, struct smsdvb_client_t, frontend); 1027 1028 sms_board_led_feedback(client->coredev, SMS_LED_OFF); 1029 sms_board_power(client->coredev, 0); 1030 1031 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); 1032 1033 return 0; 1034 } 1035 1036 static void smsdvb_release(struct dvb_frontend *fe) 1037 { 1038 /* do nothing */ 1039 } 1040 1041 static struct dvb_frontend_ops smsdvb_fe_ops = { 1042 .info = { 1043 .name = "Siano Mobile Digital MDTV Receiver", 1044 .frequency_min = 44250000, 1045 .frequency_max = 867250000, 1046 .frequency_stepsize = 250000, 1047 .caps = FE_CAN_INVERSION_AUTO | 1048 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 1049 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 1050 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 1051 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 1052 FE_CAN_GUARD_INTERVAL_AUTO | 1053 FE_CAN_RECOVER | 1054 FE_CAN_HIERARCHY_AUTO, 1055 }, 1056 1057 .release = smsdvb_release, 1058 1059 .set_frontend = smsdvb_set_frontend, 1060 .get_frontend = smsdvb_get_frontend, 1061 .get_tune_settings = smsdvb_get_tune_settings, 1062 1063 .read_status = smsdvb_read_status, 1064 .read_ber = smsdvb_read_ber, 1065 .read_signal_strength = smsdvb_read_signal_strength, 1066 .read_snr = smsdvb_read_snr, 1067 .read_ucblocks = smsdvb_read_ucblocks, 1068 1069 .init = smsdvb_init, 1070 .sleep = smsdvb_sleep, 1071 }; 1072 1073 static int smsdvb_hotplug(struct smscore_device_t *coredev, 1074 struct device *device, int arrival) 1075 { 1076 struct smsclient_params_t params; 1077 struct smsdvb_client_t *client; 1078 int rc; 1079 1080 /* device removal handled by onremove callback */ 1081 if (!arrival) 1082 return 0; 1083 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); 1084 if (!client) { 1085 sms_err("kmalloc() failed"); 1086 return -ENOMEM; 1087 } 1088 1089 /* register dvb adapter */ 1090 rc = dvb_register_adapter(&client->adapter, 1091 sms_get_board( 1092 smscore_get_board_id(coredev))->name, 1093 THIS_MODULE, device, adapter_nr); 1094 if (rc < 0) { 1095 sms_err("dvb_register_adapter() failed %d", rc); 1096 goto adapter_error; 1097 } 1098 1099 /* init dvb demux */ 1100 client->demux.dmx.capabilities = DMX_TS_FILTERING; 1101 client->demux.filternum = 32; /* todo: nova ??? */ 1102 client->demux.feednum = 32; 1103 client->demux.start_feed = smsdvb_start_feed; 1104 client->demux.stop_feed = smsdvb_stop_feed; 1105 1106 rc = dvb_dmx_init(&client->demux); 1107 if (rc < 0) { 1108 sms_err("dvb_dmx_init failed %d", rc); 1109 goto dvbdmx_error; 1110 } 1111 1112 /* init dmxdev */ 1113 client->dmxdev.filternum = 32; 1114 client->dmxdev.demux = &client->demux.dmx; 1115 client->dmxdev.capabilities = 0; 1116 1117 rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); 1118 if (rc < 0) { 1119 sms_err("dvb_dmxdev_init failed %d", rc); 1120 goto dmxdev_error; 1121 } 1122 1123 /* init and register frontend */ 1124 memcpy(&client->frontend.ops, &smsdvb_fe_ops, 1125 sizeof(struct dvb_frontend_ops)); 1126 1127 switch (smscore_get_device_mode(coredev)) { 1128 case DEVICE_MODE_DVBT: 1129 case DEVICE_MODE_DVBT_BDA: 1130 client->frontend.ops.delsys[0] = SYS_DVBT; 1131 break; 1132 case DEVICE_MODE_ISDBT: 1133 case DEVICE_MODE_ISDBT_BDA: 1134 client->frontend.ops.delsys[0] = SYS_ISDBT; 1135 break; 1136 } 1137 1138 rc = dvb_register_frontend(&client->adapter, &client->frontend); 1139 if (rc < 0) { 1140 sms_err("frontend registration failed %d", rc); 1141 goto frontend_error; 1142 } 1143 1144 params.initial_id = 1; 1145 params.data_type = MSG_SMS_DVBT_BDA_DATA; 1146 params.onresponse_handler = smsdvb_onresponse; 1147 params.onremove_handler = smsdvb_onremove; 1148 params.context = client; 1149 1150 rc = smscore_register_client(coredev, ¶ms, &client->smsclient); 1151 if (rc < 0) { 1152 sms_err("smscore_register_client() failed %d", rc); 1153 goto client_error; 1154 } 1155 1156 client->coredev = coredev; 1157 1158 init_completion(&client->tune_done); 1159 init_completion(&client->stats_done); 1160 1161 kmutex_lock(&g_smsdvb_clientslock); 1162 1163 list_add(&client->entry, &g_smsdvb_clients); 1164 1165 kmutex_unlock(&g_smsdvb_clientslock); 1166 1167 client->event_fe_state = -1; 1168 client->event_unc_state = -1; 1169 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); 1170 1171 sms_info("success"); 1172 sms_board_setup(coredev); 1173 1174 if (smsdvb_debugfs_create(client) < 0) 1175 sms_info("failed to create debugfs node"); 1176 1177 return 0; 1178 1179 client_error: 1180 dvb_unregister_frontend(&client->frontend); 1181 1182 frontend_error: 1183 dvb_dmxdev_release(&client->dmxdev); 1184 1185 dmxdev_error: 1186 dvb_dmx_release(&client->demux); 1187 1188 dvbdmx_error: 1189 dvb_unregister_adapter(&client->adapter); 1190 1191 adapter_error: 1192 kfree(client); 1193 return rc; 1194 } 1195 1196 static int __init smsdvb_module_init(void) 1197 { 1198 int rc; 1199 1200 INIT_LIST_HEAD(&g_smsdvb_clients); 1201 kmutex_init(&g_smsdvb_clientslock); 1202 1203 smsdvb_debugfs_register(); 1204 1205 rc = smscore_register_hotplug(smsdvb_hotplug); 1206 1207 sms_debug(""); 1208 1209 return rc; 1210 } 1211 1212 static void __exit smsdvb_module_exit(void) 1213 { 1214 smscore_unregister_hotplug(smsdvb_hotplug); 1215 1216 kmutex_lock(&g_smsdvb_clientslock); 1217 1218 while (!list_empty(&g_smsdvb_clients)) 1219 smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next); 1220 1221 smsdvb_debugfs_unregister(); 1222 1223 kmutex_unlock(&g_smsdvb_clientslock); 1224 } 1225 1226 module_init(smsdvb_module_init); 1227 module_exit(smsdvb_module_exit); 1228 1229 MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); 1230 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); 1231 MODULE_LICENSE("GPL"); 1232