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