diff options
| -rw-r--r-- | drivers/media/dvb/siano/smscoreapi.c | 98 |
1 files changed, 84 insertions, 14 deletions
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 398e219d6e55..040a3ff12068 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c | |||
| @@ -33,6 +33,8 @@ | |||
| 33 | 33 | ||
| 34 | #include "smscoreapi.h" | 34 | #include "smscoreapi.h" |
| 35 | #include "sms-cards.h" | 35 | #include "sms-cards.h" |
| 36 | #include "smsir.h" | ||
| 37 | #include "smsendian.h" | ||
| 36 | 38 | ||
| 37 | static int sms_dbg; | 39 | static int sms_dbg; |
| 38 | module_param_named(debug, sms_dbg, int, 0644); | 40 | module_param_named(debug, sms_dbg, int, 0644); |
| @@ -348,6 +350,7 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
| 348 | init_completion(&dev->init_device_done); | 350 | init_completion(&dev->init_device_done); |
| 349 | init_completion(&dev->reload_start_done); | 351 | init_completion(&dev->reload_start_done); |
| 350 | init_completion(&dev->resume_done); | 352 | init_completion(&dev->resume_done); |
| 353 | init_completion(&dev->ir_init_done); | ||
| 351 | 354 | ||
| 352 | /* alloc common buffer */ | 355 | /* alloc common buffer */ |
| 353 | dev->common_buffer_size = params->buffer_size * params->num_buffers; | 356 | dev->common_buffer_size = params->buffer_size * params->num_buffers; |
| @@ -403,6 +406,71 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
| 403 | } | 406 | } |
| 404 | EXPORT_SYMBOL_GPL(smscore_register_device); | 407 | EXPORT_SYMBOL_GPL(smscore_register_device); |
| 405 | 408 | ||
| 409 | |||
| 410 | static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, | ||
| 411 | void *buffer, size_t size, struct completion *completion) { | ||
| 412 | int rc = coredev->sendrequest_handler(coredev->context, buffer, size); | ||
| 413 | if (rc < 0) { | ||
| 414 | sms_info("sendrequest returned error %d", rc); | ||
| 415 | return rc; | ||
| 416 | } | ||
| 417 | |||
| 418 | return wait_for_completion_timeout(completion, | ||
| 419 | msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ? | ||
| 420 | 0 : -ETIME; | ||
| 421 | } | ||
| 422 | |||
| 423 | /** | ||
| 424 | * Starts & enables IR operations | ||
| 425 | * | ||
| 426 | * @return 0 on success, < 0 on error. | ||
| 427 | */ | ||
| 428 | static int smscore_init_ir(struct smscore_device_t *coredev) | ||
| 429 | { | ||
| 430 | int ir_io; | ||
| 431 | int rc; | ||
| 432 | void *buffer; | ||
| 433 | |||
| 434 | coredev->ir.input_dev = NULL; | ||
| 435 | ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; | ||
| 436 | if (ir_io) {/* only if IR port exist we use IR sub-module */ | ||
| 437 | sms_info("IR loading"); | ||
| 438 | rc = sms_ir_init(coredev); | ||
| 439 | |||
| 440 | if (rc != 0) | ||
| 441 | sms_err("Error initialization DTV IR sub-module"); | ||
| 442 | else { | ||
| 443 | buffer = kmalloc(sizeof(struct SmsMsgData_ST2) + | ||
| 444 | SMS_DMA_ALIGNMENT, | ||
| 445 | GFP_KERNEL | GFP_DMA); | ||
| 446 | if (buffer) { | ||
| 447 | struct SmsMsgData_ST2 *msg = | ||
| 448 | (struct SmsMsgData_ST2 *) | ||
| 449 | SMS_ALIGN_ADDRESS(buffer); | ||
| 450 | |||
| 451 | SMS_INIT_MSG(&msg->xMsgHeader, | ||
| 452 | MSG_SMS_START_IR_REQ, | ||
| 453 | sizeof(struct SmsMsgData_ST2)); | ||
| 454 | msg->msgData[0] = coredev->ir.controller; | ||
| 455 | msg->msgData[1] = coredev->ir.timeout; | ||
| 456 | |||
| 457 | smsendian_handle_tx_message( | ||
| 458 | (struct SmsMsgHdr_ST2 *)msg); | ||
| 459 | rc = smscore_sendrequest_and_wait(coredev, msg, | ||
| 460 | msg->xMsgHeader. msgLength, | ||
| 461 | &coredev->ir_init_done); | ||
| 462 | |||
| 463 | kfree(buffer); | ||
| 464 | } else | ||
| 465 | sms_err | ||
| 466 | ("Sending IR initialization message failed"); | ||
| 467 | } | ||
| 468 | } else | ||
| 469 | sms_info("IR port has not been detected"); | ||
| 470 | |||
| 471 | return 0; | ||
| 472 | } | ||
| 473 | |||
| 406 | /** | 474 | /** |
| 407 | * sets initial device mode and notifies client hotplugs that device is ready | 475 | * sets initial device mode and notifies client hotplugs that device is ready |
| 408 | * | 476 | * |
| @@ -423,6 +491,7 @@ int smscore_start_device(struct smscore_device_t *coredev) | |||
| 423 | kmutex_lock(&g_smscore_deviceslock); | 491 | kmutex_lock(&g_smscore_deviceslock); |
| 424 | 492 | ||
| 425 | rc = smscore_notify_callbacks(coredev, coredev->device, 1); | 493 | rc = smscore_notify_callbacks(coredev, coredev->device, 1); |
| 494 | smscore_init_ir(coredev); | ||
| 426 | 495 | ||
| 427 | sms_info("device %p started, rc %d", coredev, rc); | 496 | sms_info("device %p started, rc %d", coredev, rc); |
| 428 | 497 | ||
| @@ -432,20 +501,6 @@ int smscore_start_device(struct smscore_device_t *coredev) | |||
| 432 | } | 501 | } |
| 433 | EXPORT_SYMBOL_GPL(smscore_start_device); | 502 | EXPORT_SYMBOL_GPL(smscore_start_device); |
| 434 | 503 | ||
| 435 | static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, | ||
| 436 | void *buffer, size_t size, | ||
| 437 | struct completion *completion) | ||
| 438 | { | ||
| 439 | int rc = coredev->sendrequest_handler(coredev->context, buffer, size); | ||
| 440 | if (rc < 0) { | ||
| 441 | sms_info("sendrequest returned error %d", rc); | ||
| 442 | return rc; | ||
| 443 | } | ||
| 444 | |||
| 445 | return wait_for_completion_timeout(completion, | ||
| 446 | msecs_to_jiffies(10000)) ? | ||
| 447 | 0 : -ETIME; | ||
| 448 | } | ||
| 449 | 504 | ||
| 450 | static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | 505 | static int smscore_load_firmware_family2(struct smscore_device_t *coredev, |
| 451 | void *buffer, size_t size) | 506 | void *buffer, size_t size) |
| @@ -621,6 +676,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
| 621 | 676 | ||
| 622 | kmutex_lock(&g_smscore_deviceslock); | 677 | kmutex_lock(&g_smscore_deviceslock); |
| 623 | 678 | ||
| 679 | /* Release input device (IR) resources */ | ||
| 680 | sms_ir_exit(coredev); | ||
| 681 | |||
| 624 | smscore_notify_clients(coredev); | 682 | smscore_notify_clients(coredev); |
| 625 | smscore_notify_callbacks(coredev, NULL, 0); | 683 | smscore_notify_callbacks(coredev, NULL, 0); |
| 626 | 684 | ||
| @@ -980,6 +1038,18 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
| 980 | case MSG_SMS_SLEEP_RESUME_COMP_IND: | 1038 | case MSG_SMS_SLEEP_RESUME_COMP_IND: |
| 981 | complete(&coredev->resume_done); | 1039 | complete(&coredev->resume_done); |
| 982 | break; | 1040 | break; |
| 1041 | case MSG_SMS_START_IR_RES: | ||
| 1042 | complete(&coredev->ir_init_done); | ||
| 1043 | break; | ||
| 1044 | case MSG_SMS_IR_SAMPLES_IND: | ||
| 1045 | sms_ir_event(coredev, | ||
| 1046 | (const char *) | ||
| 1047 | ((char *)phdr | ||
| 1048 | + sizeof(struct SmsMsgHdr_ST)), | ||
| 1049 | (int)phdr->msgLength | ||
| 1050 | - sizeof(struct SmsMsgHdr_ST)); | ||
| 1051 | break; | ||
| 1052 | |||
| 983 | default: | 1053 | default: |
| 984 | break; | 1054 | break; |
| 985 | } | 1055 | } |
