[media] siano: make load firmware logic to work with newer firmwares
There are new firmwares for sms2xxx devices. Change the firmware load logic to handle those newer firmwares and devices. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
7333839505
commit
018b0c6f8a
2 changed files with 217 additions and 133 deletions
|
@ -683,6 +683,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
|
||||||
/* init completion events */
|
/* init completion events */
|
||||||
init_completion(&dev->version_ex_done);
|
init_completion(&dev->version_ex_done);
|
||||||
init_completion(&dev->data_download_done);
|
init_completion(&dev->data_download_done);
|
||||||
|
init_completion(&dev->data_validity_done);
|
||||||
init_completion(&dev->trigger_done);
|
init_completion(&dev->trigger_done);
|
||||||
init_completion(&dev->init_device_done);
|
init_completion(&dev->init_device_done);
|
||||||
init_completion(&dev->reload_start_done);
|
init_completion(&dev->reload_start_done);
|
||||||
|
@ -753,7 +754,13 @@ EXPORT_SYMBOL_GPL(smscore_register_device);
|
||||||
|
|
||||||
static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
|
static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
|
||||||
void *buffer, size_t size, struct completion *completion) {
|
void *buffer, size_t size, struct completion *completion) {
|
||||||
int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
|
int rc;
|
||||||
|
|
||||||
|
if (completion == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
init_completion(completion);
|
||||||
|
|
||||||
|
rc = coredev->sendrequest_handler(coredev->context, buffer, size);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sms_info("sendrequest returned error %d", rc);
|
sms_info("sendrequest returned error %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -850,8 +857,9 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
|
||||||
void *buffer, size_t size)
|
void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
|
struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
|
||||||
struct SmsMsgHdr_ST *msg;
|
struct SmsMsgData_ST4 *msg;
|
||||||
u32 mem_address;
|
u32 mem_address, calc_checksum = 0;
|
||||||
|
u32 i, *ptr;
|
||||||
u8 *payload = firmware->Payload;
|
u8 *payload = firmware->Payload;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
|
firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
|
||||||
|
@ -874,34 +882,35 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
|
||||||
|
|
||||||
if (coredev->mode != DEVICE_MODE_NONE) {
|
if (coredev->mode != DEVICE_MODE_NONE) {
|
||||||
sms_debug("sending reload command.");
|
sms_debug("sending reload command.");
|
||||||
SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
|
SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_START_REQ,
|
||||||
sizeof(struct SmsMsgHdr_ST));
|
sizeof(struct SmsMsgHdr_ST));
|
||||||
rc = smscore_sendrequest_and_wait(coredev, msg,
|
rc = smscore_sendrequest_and_wait(coredev, msg,
|
||||||
msg->msgLength,
|
msg->xMsgHeader.msgLength,
|
||||||
&coredev->reload_start_done);
|
&coredev->reload_start_done);
|
||||||
|
if (rc < 0) {
|
||||||
|
sms_err("device reload failed, rc %d", rc);
|
||||||
|
goto exit_fw_download;
|
||||||
|
}
|
||||||
mem_address = *(u32 *) &payload[20];
|
mem_address = *(u32 *) &payload[20];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0, ptr = (u32 *)firmware->Payload; i < firmware->Length/4 ;
|
||||||
|
i++, ptr++)
|
||||||
|
calc_checksum += *ptr;
|
||||||
|
|
||||||
while (size && rc >= 0) {
|
while (size && rc >= 0) {
|
||||||
struct SmsDataDownload_ST *DataMsg =
|
struct SmsDataDownload_ST *DataMsg =
|
||||||
(struct SmsDataDownload_ST *) msg;
|
(struct SmsDataDownload_ST *) msg;
|
||||||
int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
|
int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
|
||||||
|
|
||||||
SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
|
SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_DOWNLOAD_REQ,
|
||||||
(u16)(sizeof(struct SmsMsgHdr_ST) +
|
(u16)(sizeof(struct SmsMsgHdr_ST) +
|
||||||
sizeof(u32) + payload_size));
|
sizeof(u32) + payload_size));
|
||||||
|
|
||||||
DataMsg->MemAddr = mem_address;
|
DataMsg->MemAddr = mem_address;
|
||||||
memcpy(DataMsg->Payload, payload, payload_size);
|
memcpy(DataMsg->Payload, payload, payload_size);
|
||||||
|
|
||||||
if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
|
rc = smscore_sendrequest_and_wait(coredev, DataMsg,
|
||||||
(coredev->mode == DEVICE_MODE_NONE))
|
|
||||||
rc = coredev->sendrequest_handler(
|
|
||||||
coredev->context, DataMsg,
|
|
||||||
DataMsg->xMsgHeader.msgLength);
|
|
||||||
else
|
|
||||||
rc = smscore_sendrequest_and_wait(
|
|
||||||
coredev, DataMsg,
|
|
||||||
DataMsg->xMsgHeader.msgLength,
|
DataMsg->xMsgHeader.msgLength,
|
||||||
&coredev->data_download_done);
|
&coredev->data_download_done);
|
||||||
|
|
||||||
|
@ -910,44 +919,65 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
|
||||||
mem_address += payload_size;
|
mem_address += payload_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc >= 0) {
|
if (rc < 0)
|
||||||
if (coredev->mode == DEVICE_MODE_NONE) {
|
goto exit_fw_download;
|
||||||
struct SmsMsgData_ST *TriggerMsg =
|
|
||||||
(struct SmsMsgData_ST *) msg;
|
|
||||||
|
|
||||||
SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
|
sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x",
|
||||||
sizeof(struct SmsMsgHdr_ST) +
|
calc_checksum);
|
||||||
sizeof(u32) * 5);
|
SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_VALIDITY_REQ,
|
||||||
|
sizeof(msg->xMsgHeader) +
|
||||||
|
sizeof(u32) * 3);
|
||||||
|
msg->msgData[0] = firmware->StartAddress;
|
||||||
|
/* Entry point */
|
||||||
|
msg->msgData[1] = firmware->Length;
|
||||||
|
msg->msgData[2] = 0; /* Regular checksum*/
|
||||||
|
smsendian_handle_tx_message(msg);
|
||||||
|
rc = smscore_sendrequest_and_wait(coredev, msg,
|
||||||
|
msg->xMsgHeader.msgLength,
|
||||||
|
&coredev->data_validity_done);
|
||||||
|
if (rc < 0)
|
||||||
|
goto exit_fw_download;
|
||||||
|
|
||||||
TriggerMsg->msgData[0] = firmware->StartAddress;
|
if (coredev->mode == DEVICE_MODE_NONE) {
|
||||||
/* Entry point */
|
struct SmsMsgData_ST *TriggerMsg =
|
||||||
TriggerMsg->msgData[1] = 5; /* Priority */
|
(struct SmsMsgData_ST *) msg;
|
||||||
TriggerMsg->msgData[2] = 0x200; /* Stack size */
|
|
||||||
TriggerMsg->msgData[3] = 0; /* Parameter */
|
|
||||||
TriggerMsg->msgData[4] = 4; /* Task ID */
|
|
||||||
|
|
||||||
if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
|
sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ");
|
||||||
rc = coredev->sendrequest_handler(
|
SMS_INIT_MSG(&msg->xMsgHeader,
|
||||||
coredev->context, TriggerMsg,
|
MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
|
||||||
TriggerMsg->xMsgHeader.msgLength);
|
sizeof(struct SmsMsgHdr_ST) +
|
||||||
msleep(100);
|
sizeof(u32) * 5);
|
||||||
} else
|
|
||||||
rc = smscore_sendrequest_and_wait(
|
TriggerMsg->msgData[0] = firmware->StartAddress;
|
||||||
coredev, TriggerMsg,
|
/* Entry point */
|
||||||
|
TriggerMsg->msgData[1] = 6; /* Priority */
|
||||||
|
TriggerMsg->msgData[2] = 0x200; /* Stack size */
|
||||||
|
TriggerMsg->msgData[3] = 0; /* Parameter */
|
||||||
|
TriggerMsg->msgData[4] = 4; /* Task ID */
|
||||||
|
|
||||||
|
smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg);
|
||||||
|
rc = smscore_sendrequest_and_wait(coredev, TriggerMsg,
|
||||||
TriggerMsg->xMsgHeader.msgLength,
|
TriggerMsg->xMsgHeader.msgLength,
|
||||||
&coredev->trigger_done);
|
&coredev->trigger_done);
|
||||||
} else {
|
} else {
|
||||||
SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
|
SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_EXEC_REQ,
|
||||||
sizeof(struct SmsMsgHdr_ST));
|
sizeof(struct SmsMsgHdr_ST));
|
||||||
|
smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg);
|
||||||
rc = coredev->sendrequest_handler(coredev->context,
|
rc = coredev->sendrequest_handler(coredev->context, msg,
|
||||||
msg, msg->msgLength);
|
msg->xMsgHeader.msgLength);
|
||||||
}
|
|
||||||
msleep(500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sms_debug("rc=%d, postload=%p ", rc,
|
if (rc < 0)
|
||||||
coredev->postload_handler);
|
goto exit_fw_download;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* backward compatibility - wait to device_ready_done for
|
||||||
|
* not more than 400 ms
|
||||||
|
*/
|
||||||
|
msleep(400);
|
||||||
|
|
||||||
|
exit_fw_download:
|
||||||
|
sms_debug("rc=%d, postload=0x%p ", rc, coredev->postload_handler);
|
||||||
|
|
||||||
kfree(msg);
|
kfree(msg);
|
||||||
|
|
||||||
|
@ -956,6 +986,10 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
|
||||||
rc;
|
rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
|
||||||
|
int mode, int lookup);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* loads specified firmware into a buffer and calls device loadfirmware_handler
|
* loads specified firmware into a buffer and calls device loadfirmware_handler
|
||||||
*
|
*
|
||||||
|
@ -967,41 +1001,43 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
|
||||||
* @return 0 on success, <0 on error.
|
* @return 0 on success, <0 on error.
|
||||||
*/
|
*/
|
||||||
static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
|
static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
|
||||||
char *filename,
|
int mode, int lookup,
|
||||||
loadfirmware_t loadfirmware_handler)
|
loadfirmware_t loadfirmware_handler)
|
||||||
{
|
{
|
||||||
int rc = -ENOENT;
|
int rc = -ENOENT;
|
||||||
|
u8 *fw_buf;
|
||||||
|
u32 fw_buf_size;
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
u8 *fw_buffer;
|
|
||||||
|
|
||||||
if (loadfirmware_handler == NULL && !(coredev->device_flags &
|
char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup);
|
||||||
SMS_DEVICE_FAMILY2))
|
if (!strcmp(fw_filename, "none"))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (loadfirmware_handler == NULL && !(coredev->device_flags
|
||||||
|
& SMS_DEVICE_FAMILY2))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rc = request_firmware(&fw, filename, coredev->device);
|
rc = request_firmware(&fw, fw_filename, coredev->device);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sms_info("failed to open \"%s\"", filename);
|
sms_info("failed to open \"%s\"", fw_filename);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
sms_info("read FW %s, size=%zd", filename, fw->size);
|
sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
|
||||||
fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
|
fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
|
||||||
GFP_KERNEL | GFP_DMA);
|
GFP_KERNEL | GFP_DMA);
|
||||||
if (fw_buffer) {
|
if (!fw_buf) {
|
||||||
memcpy(fw_buffer, fw->data, fw->size);
|
|
||||||
|
|
||||||
rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
|
|
||||||
smscore_load_firmware_family2(coredev,
|
|
||||||
fw_buffer,
|
|
||||||
fw->size) :
|
|
||||||
loadfirmware_handler(coredev->context,
|
|
||||||
fw_buffer, fw->size);
|
|
||||||
|
|
||||||
kfree(fw_buffer);
|
|
||||||
} else {
|
|
||||||
sms_info("failed to allocate firmware buffer");
|
sms_info("failed to allocate firmware buffer");
|
||||||
rc = -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
memcpy(fw_buf, fw->data, fw->size);
|
||||||
|
fw_buf_size = fw->size;
|
||||||
|
|
||||||
|
rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
|
||||||
|
smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
|
||||||
|
: loadfirmware_handler(coredev->context, fw_buf,
|
||||||
|
fw_buf_size);
|
||||||
|
|
||||||
|
kfree(fw_buf);
|
||||||
release_firmware(fw);
|
release_firmware(fw);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -1050,7 +1086,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
|
||||||
|
|
||||||
sms_info("waiting for %d buffer(s)",
|
sms_info("waiting for %d buffer(s)",
|
||||||
coredev->num_buffers - num_buffers);
|
coredev->num_buffers - num_buffers);
|
||||||
|
kmutex_unlock(&g_smscore_deviceslock);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
kmutex_lock(&g_smscore_deviceslock);
|
||||||
}
|
}
|
||||||
|
|
||||||
sms_info("freed %d buffers", num_buffers);
|
sms_info("freed %d buffers", num_buffers);
|
||||||
|
@ -1107,30 +1145,73 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
|
static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
|
||||||
/*Stellar NOVA A0 Nova B0 VEGA*/
|
/*Stellar, NOVA A0, Nova B0, VEGA, VENICE, MING, PELE, RIO, DENVER_1530, DENVER_2160 */
|
||||||
/*DVBT*/
|
/*DVBT*/
|
||||||
{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
|
{ "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" },
|
||||||
/*DVBH*/
|
/*DVBH*/
|
||||||
{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
|
{ "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvbh_rio.inp", "none", "none" },
|
||||||
/*TDMB*/
|
/*TDMB*/
|
||||||
{"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
|
{ "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none", "none", "none", "none", "none", "none", "tdmb_denver.inp" },
|
||||||
/*DABIP*/
|
/*DABIP*/
|
||||||
{"none", "none", "none", "none"},
|
{ "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" },
|
||||||
/*BDA*/
|
/*DVBT_BDA*/
|
||||||
{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
|
{ "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" },
|
||||||
/*ISDBT*/
|
/*ISDBT*/
|
||||||
{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
|
{ "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" },
|
||||||
/*ISDBTBDA*/
|
/*ISDBT_BDA*/
|
||||||
{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
|
{ "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" },
|
||||||
/*CMMB*/
|
/*CMMB*/
|
||||||
{"none", "none", "none", "cmmb_vega_12mhz.inp"}
|
{ "none", "none", "none", "cmmb_vega_12mhz.inp", "cmmb_venice_12mhz.inp", "cmmb_ming_app.inp", "none", "none", "none", "none" },
|
||||||
|
/*RAW - not supported*/
|
||||||
|
{ "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" },
|
||||||
|
/*FM*/
|
||||||
|
{ "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" },
|
||||||
|
/*FM_BDA*/
|
||||||
|
{ "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" },
|
||||||
|
/*ATSC*/
|
||||||
|
{ "none", "none", "none", "none", "none", "none", "none", "none", "atsc_denver.inp", "none" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
|
/**
|
||||||
int mode, enum sms_device_type_st type)
|
* get firmware file name from one of the two mechanisms : sms_boards or
|
||||||
|
* smscore_fw_lkup.
|
||||||
|
* @param coredev pointer to a coredev object returned by
|
||||||
|
* smscore_register_device
|
||||||
|
* @param mode requested mode of operation
|
||||||
|
* @param lookup if 1, always get the fw filename from smscore_fw_lkup
|
||||||
|
* table. if 0, try first to get from sms_boards
|
||||||
|
*
|
||||||
|
* @return 0 on success, <0 on error.
|
||||||
|
*/
|
||||||
|
static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
|
||||||
|
int mode, int lookup)
|
||||||
{
|
{
|
||||||
char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
|
char **fw;
|
||||||
return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
|
int board_id = smscore_get_board_id(coredev);
|
||||||
|
enum sms_device_type_st type = smscore_registry_gettype(coredev->devpath);
|
||||||
|
|
||||||
|
if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) {
|
||||||
|
sms_debug("trying to get fw name from lookup table mode %d type %d",
|
||||||
|
mode, type);
|
||||||
|
return smscore_fw_lkup[mode][type];
|
||||||
|
}
|
||||||
|
|
||||||
|
sms_debug("trying to get fw name from sms_boards board_id %d mode %d",
|
||||||
|
board_id, mode);
|
||||||
|
fw = sms_get_board(board_id)->fw;
|
||||||
|
if (fw == NULL) {
|
||||||
|
sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d",
|
||||||
|
mode, type);
|
||||||
|
return smscore_fw_lkup[mode][type];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fw[mode] == NULL) {
|
||||||
|
sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d",
|
||||||
|
mode, type);
|
||||||
|
return smscore_fw_lkup[mode][type];
|
||||||
|
}
|
||||||
|
|
||||||
|
return fw[mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1145,9 +1226,7 @@ static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
|
||||||
*/
|
*/
|
||||||
int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
|
int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
|
||||||
{
|
{
|
||||||
void *buffer;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
enum sms_device_type_st type;
|
|
||||||
|
|
||||||
sms_debug("set device mode to %d", mode);
|
sms_debug("set device mode to %d", mode);
|
||||||
if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
|
if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
|
||||||
|
@ -1172,55 +1251,30 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(coredev->modes_supported & (1 << mode))) {
|
if (!(coredev->modes_supported & (1 << mode))) {
|
||||||
char *fw_filename;
|
|
||||||
|
|
||||||
type = smscore_registry_gettype(coredev->devpath);
|
|
||||||
fw_filename = sms_get_fw_name(coredev, mode, type);
|
|
||||||
|
|
||||||
rc = smscore_load_firmware_from_file(coredev,
|
rc = smscore_load_firmware_from_file(coredev,
|
||||||
fw_filename, NULL);
|
mode, 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try again with the default firmware -
|
||||||
|
* get the fw filename from look-up table
|
||||||
|
*/
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sms_warn("error %d loading firmware: %s, "
|
sms_debug("error %d loading firmware, trying again with default firmware",
|
||||||
"trying again with default firmware",
|
rc);
|
||||||
rc, fw_filename);
|
|
||||||
|
|
||||||
/* try again with the default firmware */
|
|
||||||
fw_filename = smscore_fw_lkup[mode][type];
|
|
||||||
rc = smscore_load_firmware_from_file(coredev,
|
rc = smscore_load_firmware_from_file(coredev,
|
||||||
fw_filename, NULL);
|
mode, 1,
|
||||||
|
NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sms_warn("error %d loading "
|
sms_debug("error %d loading firmware",
|
||||||
"firmware: %s", rc,
|
rc);
|
||||||
fw_filename);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sms_log("firmware download success: %s", fw_filename);
|
if (rc >= 0)
|
||||||
} else
|
sms_info("firmware download success");
|
||||||
sms_info("mode %d supported by running "
|
|
||||||
"firmware", mode);
|
|
||||||
|
|
||||||
buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
|
|
||||||
SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
|
|
||||||
if (buffer) {
|
|
||||||
struct SmsMsgData_ST *msg =
|
|
||||||
(struct SmsMsgData_ST *)
|
|
||||||
SMS_ALIGN_ADDRESS(buffer);
|
|
||||||
|
|
||||||
SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
|
|
||||||
sizeof(struct SmsMsgData_ST));
|
|
||||||
msg->msgData[0] = mode;
|
|
||||||
|
|
||||||
rc = smscore_sendrequest_and_wait(
|
|
||||||
coredev, msg, msg->xMsgHeader.msgLength,
|
|
||||||
&coredev->init_device_done);
|
|
||||||
|
|
||||||
kfree(buffer);
|
|
||||||
} else {
|
} else {
|
||||||
sms_err("Could not allocate buffer for "
|
sms_info("mode %d is already supported by running firmware",
|
||||||
"init device message.");
|
mode);
|
||||||
rc = -ENOMEM;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
|
if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
|
||||||
|
@ -1239,8 +1293,25 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
|
char *buffer;
|
||||||
coredev->mode = mode;
|
coredev->mode = mode;
|
||||||
coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
|
coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
|
||||||
|
|
||||||
|
buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
|
||||||
|
SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
|
||||||
|
if (buffer) {
|
||||||
|
struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer);
|
||||||
|
|
||||||
|
SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
|
||||||
|
sizeof(struct SmsMsgData_ST));
|
||||||
|
msg->msgData[0] = mode;
|
||||||
|
|
||||||
|
rc = smscore_sendrequest_and_wait(
|
||||||
|
coredev, msg, msg->xMsgHeader.msgLength,
|
||||||
|
&coredev->init_device_done);
|
||||||
|
|
||||||
|
kfree(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
@ -1371,6 +1442,15 @@ void smscore_onresponse(struct smscore_device_t *coredev,
|
||||||
case MSG_SW_RELOAD_START_RES:
|
case MSG_SW_RELOAD_START_RES:
|
||||||
complete(&coredev->reload_start_done);
|
complete(&coredev->reload_start_done);
|
||||||
break;
|
break;
|
||||||
|
case MSG_SMS_DATA_VALIDITY_RES:
|
||||||
|
{
|
||||||
|
struct SmsMsgData_ST *validity = (struct SmsMsgData_ST *) phdr;
|
||||||
|
|
||||||
|
sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x",
|
||||||
|
validity->msgData[0]);
|
||||||
|
complete(&coredev->data_validity_done);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MSG_SMS_DATA_DOWNLOAD_RES:
|
case MSG_SMS_DATA_DOWNLOAD_RES:
|
||||||
complete(&coredev->data_download_done);
|
complete(&coredev->data_download_done);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -162,6 +162,7 @@ struct smscore_device_t {
|
||||||
|
|
||||||
/* host <--> device messages */
|
/* host <--> device messages */
|
||||||
struct completion version_ex_done, data_download_done, trigger_done;
|
struct completion version_ex_done, data_download_done, trigger_done;
|
||||||
|
struct completion data_validity_done, device_ready_done;
|
||||||
struct completion init_device_done, reload_start_done, resume_done;
|
struct completion init_device_done, reload_start_done, resume_done;
|
||||||
struct completion gpio_configuration_done, gpio_set_level_done;
|
struct completion gpio_configuration_done, gpio_set_level_done;
|
||||||
struct completion gpio_get_level_done, ir_init_done;
|
struct completion gpio_get_level_done, ir_init_done;
|
||||||
|
@ -594,6 +595,11 @@ struct SmsMsgData_ST2 {
|
||||||
u32 msgData[2];
|
u32 msgData[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SmsMsgData_ST4 {
|
||||||
|
struct SmsMsgHdr_ST xMsgHeader;
|
||||||
|
u32 msgData[4];
|
||||||
|
};
|
||||||
|
|
||||||
struct SmsDataDownload_ST {
|
struct SmsDataDownload_ST {
|
||||||
struct SmsMsgHdr_ST xMsgHeader;
|
struct SmsMsgHdr_ST xMsgHeader;
|
||||||
u32 MemAddr;
|
u32 MemAddr;
|
||||||
|
@ -998,8 +1004,6 @@ extern void smscore_onresponse(struct smscore_device_t *coredev,
|
||||||
extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
|
extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
|
||||||
extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
|
extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
|
||||||
struct vm_area_struct *vma);
|
struct vm_area_struct *vma);
|
||||||
extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
|
|
||||||
int mode, char *filename);
|
|
||||||
extern int smscore_send_fw_file(struct smscore_device_t *coredev,
|
extern int smscore_send_fw_file(struct smscore_device_t *coredev,
|
||||||
u8 *ufwbuf, int size);
|
u8 *ufwbuf, int size);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue