pd-dvb.c revision 5b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89f
1#include "pd-common.h" 2#include <linux/kernel.h> 3#include <linux/usb.h> 4#include <linux/dvb/dmx.h> 5#include <linux/delay.h> 6 7#include "vendorcmds.h" 8#include <linux/sched.h> 9#include <asm/atomic.h> 10 11static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb); 12 13static int dvb_bandwidth[][2] = { 14 { TLG_BW_8, BANDWIDTH_8_MHZ }, 15 { TLG_BW_7, BANDWIDTH_7_MHZ }, 16 { TLG_BW_6, BANDWIDTH_6_MHZ } 17}; 18static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth); 19 20static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb); 21static int poseidon_check_mode_dvbt(struct poseidon *pd) 22{ 23 s32 ret = 0, cmd_status = 0; 24 25 set_current_state(TASK_INTERRUPTIBLE); 26 schedule_timeout(HZ/4); 27 28 ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE); 29 if (ret != 0) 30 return ret; 31 32 ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T); 33 if (ret) 34 return ret; 35 36 /* signal source */ 37 ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status); 38 if (ret|cmd_status) 39 return ret; 40 41 return 0; 42} 43 44/* acquire : 45 * 1 == open 46 * 0 == release 47 */ 48static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) 49{ 50 struct poseidon *pd = fe->demodulator_priv; 51 struct pd_dvb_adapter *pd_dvb; 52 int ret = 0; 53 54 if (!pd) 55 return -ENODEV; 56 57 pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe); 58 if (acquire) { 59 mutex_lock(&pd->lock); 60 if (pd->state & POSEIDON_STATE_DISCONNECT) { 61 ret = -ENODEV; 62 goto open_out; 63 } 64 65 if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) { 66 ret = -EBUSY; 67 goto open_out; 68 } 69 70 usb_autopm_get_interface(pd->interface); 71 if (0 == pd->state) { 72 ret = poseidon_check_mode_dvbt(pd); 73 if (ret < 0) { 74 usb_autopm_put_interface(pd->interface); 75 goto open_out; 76 } 77 pd->state |= POSEIDON_STATE_DVBT; 78 pd_dvb->bandwidth = 0; 79 pd_dvb->prev_freq = 0; 80 } 81 atomic_inc(&pd_dvb->users); 82 kref_get(&pd->kref); 83open_out: 84 mutex_unlock(&pd->lock); 85 } else { 86 dvb_stop_streaming(pd_dvb); 87 88 if (atomic_dec_and_test(&pd_dvb->users)) { 89 mutex_lock(&pd->lock); 90 pd->state &= ~POSEIDON_STATE_DVBT; 91 mutex_unlock(&pd->lock); 92 } 93 kref_put(&pd->kref, poseidon_delete); 94 usb_autopm_put_interface(pd->interface); 95 } 96 return ret; 97} 98 99static void poseidon_fe_release(struct dvb_frontend *fe) 100{ 101 struct poseidon *pd = fe->demodulator_priv; 102 103#ifdef CONFIG_PM 104 pd->pm_suspend = NULL; 105 pd->pm_resume = NULL; 106#endif 107} 108 109static s32 poseidon_fe_sleep(struct dvb_frontend *fe) 110{ 111 return 0; 112} 113 114/* 115 * return true if we can satisfy the conditions, else return false. 116 */ 117static bool check_scan_ok(__u32 freq, int bandwidth, 118 struct pd_dvb_adapter *adapter) 119{ 120 if (bandwidth < 0) 121 return false; 122 123 if (adapter->prev_freq == freq 124 && adapter->bandwidth == bandwidth) { 125 long nl = jiffies - adapter->last_jiffies; 126 unsigned int msec ; 127 128 msec = jiffies_to_msecs(abs(nl)); 129 return msec > 15000 ? true : false; 130 } 131 return true; 132} 133 134/* 135 * Check if the firmware delays too long for an invalid frequency. 136 */ 137static int fw_delay_overflow(struct pd_dvb_adapter *adapter) 138{ 139 long nl = jiffies - adapter->last_jiffies; 140 unsigned int msec ; 141 142 msec = jiffies_to_msecs(abs(nl)); 143 return msec > 800 ? true : false; 144} 145 146static int poseidon_set_fe(struct dvb_frontend *fe, 147 struct dvb_frontend_parameters *fep) 148{ 149 s32 ret = 0, cmd_status = 0; 150 s32 i, bandwidth = -1; 151 struct poseidon *pd = fe->demodulator_priv; 152 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 153 154 if (in_hibernation(pd)) 155 return -EBUSY; 156 157 mutex_lock(&pd->lock); 158 for (i = 0; i < dvb_bandwidth_length; i++) 159 if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1]) 160 bandwidth = dvb_bandwidth[i][0]; 161 162 if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) { 163 ret = send_set_req(pd, TUNE_FREQ_SELECT, 164 fep->frequency / 1000, &cmd_status); 165 if (ret | cmd_status) { 166 log("error line"); 167 goto front_out; 168 } 169 170 ret = send_set_req(pd, DVBT_BANDW_SEL, 171 bandwidth, &cmd_status); 172 if (ret | cmd_status) { 173 log("error line"); 174 goto front_out; 175 } 176 177 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); 178 if (ret | cmd_status) { 179 log("error line"); 180 goto front_out; 181 } 182 183 /* save the context for future */ 184 memcpy(&pd_dvb->fe_param, fep, sizeof(*fep)); 185 pd_dvb->bandwidth = bandwidth; 186 pd_dvb->prev_freq = fep->frequency; 187 pd_dvb->last_jiffies = jiffies; 188 } 189front_out: 190 mutex_unlock(&pd->lock); 191 return ret; 192} 193 194#ifdef CONFIG_PM 195static int pm_dvb_suspend(struct poseidon *pd) 196{ 197 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 198 dvb_stop_streaming(pd_dvb); 199 dvb_urb_cleanup(pd_dvb); 200 msleep(500); 201 return 0; 202} 203 204static int pm_dvb_resume(struct poseidon *pd) 205{ 206 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 207 208 poseidon_check_mode_dvbt(pd); 209 msleep(300); 210 poseidon_set_fe(&pd_dvb->dvb_fe, &pd_dvb->fe_param); 211 212 dvb_start_streaming(pd_dvb); 213 return 0; 214} 215#endif 216 217static s32 poseidon_fe_init(struct dvb_frontend *fe) 218{ 219 struct poseidon *pd = fe->demodulator_priv; 220 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 221 222#ifdef CONFIG_PM 223 pd->pm_suspend = pm_dvb_suspend; 224 pd->pm_resume = pm_dvb_resume; 225#endif 226 memset(&pd_dvb->fe_param, 0, 227 sizeof(struct dvb_frontend_parameters)); 228 return 0; 229} 230 231static int poseidon_get_fe(struct dvb_frontend *fe, 232 struct dvb_frontend_parameters *fep) 233{ 234 struct poseidon *pd = fe->demodulator_priv; 235 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 236 237 memcpy(fep, &pd_dvb->fe_param, sizeof(*fep)); 238 return 0; 239} 240 241static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe, 242 struct dvb_frontend_tune_settings *tune) 243{ 244 tune->min_delay_ms = 1000; 245 return 0; 246} 247 248static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat) 249{ 250 struct poseidon *pd = fe->demodulator_priv; 251 s32 ret = -1, cmd_status; 252 struct tuner_dtv_sig_stat_s status = {}; 253 254 if (in_hibernation(pd)) 255 return -EBUSY; 256 mutex_lock(&pd->lock); 257 258 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T, 259 &status, &cmd_status, sizeof(status)); 260 if (ret | cmd_status) { 261 log("get tuner status error"); 262 goto out; 263 } 264 265 if (debug_mode) 266 log("P : %d, L %d, LB :%d", status.sig_present, 267 status.sig_locked, status.sig_lock_busy); 268 269 if (status.sig_lock_busy) { 270 goto out; 271 } else if (status.sig_present || status.sig_locked) { 272 *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER 273 | FE_HAS_SYNC | FE_HAS_VITERBI; 274 } else { 275 if (fw_delay_overflow(&pd->dvb_data)) 276 *stat |= FE_TIMEDOUT; 277 } 278out: 279 mutex_unlock(&pd->lock); 280 return ret; 281} 282 283static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber) 284{ 285 struct poseidon *pd = fe->demodulator_priv; 286 struct tuner_ber_rate_s tlg_ber = {}; 287 s32 ret = -1, cmd_status; 288 289 mutex_lock(&pd->lock); 290 ret = send_get_req(pd, TUNER_BER_RATE, 0, 291 &tlg_ber, &cmd_status, sizeof(tlg_ber)); 292 if (ret | cmd_status) 293 goto out; 294 *ber = tlg_ber.ber_rate; 295out: 296 mutex_unlock(&pd->lock); 297 return ret; 298} 299 300static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 301{ 302 struct poseidon *pd = fe->demodulator_priv; 303 struct tuner_dtv_sig_stat_s status = {}; 304 s32 ret = 0, cmd_status; 305 306 mutex_lock(&pd->lock); 307 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T, 308 &status, &cmd_status, sizeof(status)); 309 if (ret | cmd_status) 310 goto out; 311 if ((status.sig_present || status.sig_locked) && !status.sig_strength) 312 *strength = 0xFFFF; 313 else 314 *strength = status.sig_strength; 315out: 316 mutex_unlock(&pd->lock); 317 return ret; 318} 319 320static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr) 321{ 322 return 0; 323} 324 325static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) 326{ 327 *unc = 0; 328 return 0; 329} 330 331static struct dvb_frontend_ops poseidon_frontend_ops = { 332 .info = { 333 .name = "Poseidon DVB-T", 334 .type = FE_OFDM, 335 .frequency_min = 174000000, 336 .frequency_max = 862000000, 337 .frequency_stepsize = 62500,/* FIXME */ 338 .caps = FE_CAN_INVERSION_AUTO | 339 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 340 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 341 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 342 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 343 FE_CAN_GUARD_INTERVAL_AUTO | 344 FE_CAN_RECOVER | 345 FE_CAN_HIERARCHY_AUTO, 346 }, 347 348 .release = poseidon_fe_release, 349 350 .init = poseidon_fe_init, 351 .sleep = poseidon_fe_sleep, 352 353 .set_frontend = poseidon_set_fe, 354 .get_frontend = poseidon_get_fe, 355 .get_tune_settings = poseidon_fe_get_tune_settings, 356 357 .read_status = poseidon_read_status, 358 .read_ber = poseidon_read_ber, 359 .read_signal_strength = poseidon_read_signal_strength, 360 .read_snr = poseidon_read_snr, 361 .read_ucblocks = poseidon_read_unc_blocks, 362 363 .ts_bus_ctrl = poseidon_ts_bus_ctrl, 364}; 365 366static void dvb_urb_irq(struct urb *urb) 367{ 368 struct pd_dvb_adapter *pd_dvb = urb->context; 369 int len = urb->transfer_buffer_length; 370 struct dvb_demux *demux = &pd_dvb->demux; 371 s32 ret; 372 373 if (!pd_dvb->is_streaming || urb->status) { 374 if (urb->status == -EPROTO) 375 goto resend; 376 return; 377 } 378 379 if (urb->actual_length == len) 380 dvb_dmx_swfilter(demux, urb->transfer_buffer, len); 381 else if (urb->actual_length == len - 4) { 382 int offset; 383 u8 *buf = urb->transfer_buffer; 384 385 /* 386 * The packet size is 512, 387 * last packet contains 456 bytes tsp data 388 */ 389 for (offset = 456; offset < len; offset += 512) { 390 if (!strncmp(buf + offset, "DVHS", 4)) { 391 dvb_dmx_swfilter(demux, buf, offset); 392 if (len > offset + 52 + 4) { 393 /*16 bytes trailer + 36 bytes padding */ 394 buf += offset + 52; 395 len -= offset + 52 + 4; 396 dvb_dmx_swfilter(demux, buf, len); 397 } 398 break; 399 } 400 } 401 } 402 403resend: 404 ret = usb_submit_urb(urb, GFP_ATOMIC); 405 if (ret) 406 log(" usb_submit_urb failed: error %d", ret); 407} 408 409static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb) 410{ 411 if (pd_dvb->urb_array[0]) 412 return 0; 413 414 alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM, 415 pd_dvb->pd_device->udev, pd_dvb->ep_addr, 416 DVB_URB_BUF_SIZE, GFP_KERNEL, 417 dvb_urb_irq, pd_dvb); 418 return 0; 419} 420 421static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb) 422{ 423 free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM); 424} 425 426static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb) 427{ 428 struct poseidon *pd = pd_dvb->pd_device; 429 int ret = 0; 430 431 if (pd->state & POSEIDON_STATE_DISCONNECT) 432 return -ENODEV; 433 434 mutex_lock(&pd->lock); 435 if (!pd_dvb->is_streaming) { 436 s32 i, cmd_status = 0; 437 /* 438 * Once upon a time, there was a difficult bug lying here. 439 * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); 440 */ 441 442 ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status); 443 if (ret | cmd_status) 444 goto out; 445 446 ret = dvb_urb_init(pd_dvb); 447 if (ret < 0) 448 goto out; 449 450 pd_dvb->is_streaming = 1; 451 for (i = 0; i < DVB_SBUF_NUM; i++) { 452 ret = usb_submit_urb(pd_dvb->urb_array[i], 453 GFP_KERNEL); 454 if (ret) { 455 log(" submit urb error %d", ret); 456 goto out; 457 } 458 } 459 } 460out: 461 mutex_unlock(&pd->lock); 462 return ret; 463} 464 465void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb) 466{ 467 struct poseidon *pd = pd_dvb->pd_device; 468 469 mutex_lock(&pd->lock); 470 if (pd_dvb->is_streaming) { 471 s32 i, ret, cmd_status = 0; 472 473 pd_dvb->is_streaming = 0; 474 475 for (i = 0; i < DVB_SBUF_NUM; i++) 476 if (pd_dvb->urb_array[i]) 477 usb_kill_urb(pd_dvb->urb_array[i]); 478 479 ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, 480 &cmd_status); 481 if (ret | cmd_status) 482 log("error"); 483 } 484 mutex_unlock(&pd->lock); 485} 486 487static int pd_start_feed(struct dvb_demux_feed *feed) 488{ 489 struct pd_dvb_adapter *pd_dvb = feed->demux->priv; 490 int ret = 0; 491 492 if (!pd_dvb) 493 return -1; 494 if (atomic_inc_return(&pd_dvb->active_feed) == 1) 495 ret = dvb_start_streaming(pd_dvb); 496 return ret; 497} 498 499static int pd_stop_feed(struct dvb_demux_feed *feed) 500{ 501 struct pd_dvb_adapter *pd_dvb = feed->demux->priv; 502 503 if (!pd_dvb) 504 return -1; 505 if (atomic_dec_and_test(&pd_dvb->active_feed)) 506 dvb_stop_streaming(pd_dvb); 507 return 0; 508} 509 510DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 511int pd_dvb_usb_device_init(struct poseidon *pd) 512{ 513 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 514 struct dvb_demux *dvbdemux; 515 int ret = 0; 516 517 pd_dvb->ep_addr = 0x82; 518 atomic_set(&pd_dvb->users, 0); 519 atomic_set(&pd_dvb->active_feed, 0); 520 pd_dvb->pd_device = pd; 521 522 ret = dvb_register_adapter(&pd_dvb->dvb_adap, 523 "Poseidon dvbt adapter", 524 THIS_MODULE, 525 NULL /* for hibernation correctly*/, 526 adapter_nr); 527 if (ret < 0) 528 goto error1; 529 530 /* register frontend */ 531 pd_dvb->dvb_fe.demodulator_priv = pd; 532 memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops, 533 sizeof(struct dvb_frontend_ops)); 534 ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe); 535 if (ret < 0) 536 goto error2; 537 538 /* register demux device */ 539 dvbdemux = &pd_dvb->demux; 540 dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; 541 dvbdemux->priv = pd_dvb; 542 dvbdemux->feednum = dvbdemux->filternum = 64; 543 dvbdemux->start_feed = pd_start_feed; 544 dvbdemux->stop_feed = pd_stop_feed; 545 dvbdemux->write_to_decoder = NULL; 546 547 ret = dvb_dmx_init(dvbdemux); 548 if (ret < 0) 549 goto error3; 550 551 pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum; 552 pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx; 553 pd_dvb->dmxdev.capabilities = 0; 554 555 ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap); 556 if (ret < 0) 557 goto error3; 558 return 0; 559 560error3: 561 dvb_unregister_frontend(&pd_dvb->dvb_fe); 562error2: 563 dvb_unregister_adapter(&pd_dvb->dvb_adap); 564error1: 565 return ret; 566} 567 568void pd_dvb_usb_device_exit(struct poseidon *pd) 569{ 570 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 571 572 while (atomic_read(&pd_dvb->users) != 0 573 || atomic_read(&pd_dvb->active_feed) != 0) { 574 set_current_state(TASK_INTERRUPTIBLE); 575 schedule_timeout(HZ); 576 } 577 dvb_dmxdev_release(&pd_dvb->dmxdev); 578 dvb_unregister_frontend(&pd_dvb->dvb_fe); 579 dvb_unregister_adapter(&pd_dvb->dvb_adap); 580 pd_dvb_usb_device_cleanup(pd); 581} 582 583void pd_dvb_usb_device_cleanup(struct poseidon *pd) 584{ 585 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 586 587 dvb_urb_cleanup(pd_dvb); 588} 589 590int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb) 591{ 592 return pd_dvb->dvb_adap.num; 593} 594