aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-03-06 10:15:08 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-21 06:40:05 -0400
commit018b0c6f8acb5819591f3b43b51fc342af548c82 (patch)
treea5831567bc09f0117c2aca5a32dc4043a16d5921
parent7333839505d568e0e69a6d02a3ee0f455b6c37a5 (diff)
[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>
-rw-r--r--drivers/media/common/siano/smscoreapi.c348
-rw-r--r--drivers/media/common/siano/smscoreapi.h8
2 files changed, 220 insertions, 136 deletions
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 7b5d81a30cdf..d489701c3842 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -683,6 +683,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
683 /* init completion events */ 683 /* init completion events */
684 init_completion(&dev->version_ex_done); 684 init_completion(&dev->version_ex_done);
685 init_completion(&dev->data_download_done); 685 init_completion(&dev->data_download_done);
686 init_completion(&dev->data_validity_done);
686 init_completion(&dev->trigger_done); 687 init_completion(&dev->trigger_done);
687 init_completion(&dev->init_device_done); 688 init_completion(&dev->init_device_done);
688 init_completion(&dev->reload_start_done); 689 init_completion(&dev->reload_start_done);
@@ -753,7 +754,13 @@ EXPORT_SYMBOL_GPL(smscore_register_device);
753 754
754static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, 755static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
755 void *buffer, size_t size, struct completion *completion) { 756 void *buffer, size_t size, struct completion *completion) {
756 int rc = coredev->sendrequest_handler(coredev->context, buffer, size); 757 int rc;
758
759 if (completion == NULL)
760 return -EINVAL;
761 init_completion(completion);
762
763 rc = coredev->sendrequest_handler(coredev->context, buffer, size);
757 if (rc < 0) { 764 if (rc < 0) {
758 sms_info("sendrequest returned error %d", rc); 765 sms_info("sendrequest returned error %d", rc);
759 return rc; 766 return rc;
@@ -850,8 +857,9 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
850 void *buffer, size_t size) 857 void *buffer, size_t size)
851{ 858{
852 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; 859 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
853 struct SmsMsgHdr_ST *msg; 860 struct SmsMsgData_ST4 *msg;
854 u32 mem_address; 861 u32 mem_address, calc_checksum = 0;
862 u32 i, *ptr;
855 u8 *payload = firmware->Payload; 863 u8 *payload = firmware->Payload;
856 int rc = 0; 864 int rc = 0;
857 firmware->StartAddress = le32_to_cpu(firmware->StartAddress); 865 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
@@ -874,34 +882,35 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
874 882
875 if (coredev->mode != DEVICE_MODE_NONE) { 883 if (coredev->mode != DEVICE_MODE_NONE) {
876 sms_debug("sending reload command."); 884 sms_debug("sending reload command.");
877 SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, 885 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_START_REQ,
878 sizeof(struct SmsMsgHdr_ST)); 886 sizeof(struct SmsMsgHdr_ST));
879 rc = smscore_sendrequest_and_wait(coredev, msg, 887 rc = smscore_sendrequest_and_wait(coredev, msg,
880 msg->msgLength, 888 msg->xMsgHeader.msgLength,
881 &coredev->reload_start_done); 889 &coredev->reload_start_done);
890 if (rc < 0) {
891 sms_err("device reload failed, rc %d", rc);
892 goto exit_fw_download;
893 }
882 mem_address = *(u32 *) &payload[20]; 894 mem_address = *(u32 *) &payload[20];
883 } 895 }
884 896
897 for (i = 0, ptr = (u32 *)firmware->Payload; i < firmware->Length/4 ;
898 i++, ptr++)
899 calc_checksum += *ptr;
900
885 while (size && rc >= 0) { 901 while (size && rc >= 0) {
886 struct SmsDataDownload_ST *DataMsg = 902 struct SmsDataDownload_ST *DataMsg =
887 (struct SmsDataDownload_ST *) msg; 903 (struct SmsDataDownload_ST *) msg;
888 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); 904 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
889 905
890 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, 906 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_DOWNLOAD_REQ,
891 (u16)(sizeof(struct SmsMsgHdr_ST) + 907 (u16)(sizeof(struct SmsMsgHdr_ST) +
892 sizeof(u32) + payload_size)); 908 sizeof(u32) + payload_size));
893 909
894 DataMsg->MemAddr = mem_address; 910 DataMsg->MemAddr = mem_address;
895 memcpy(DataMsg->Payload, payload, payload_size); 911 memcpy(DataMsg->Payload, payload, payload_size);
896 912
897 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && 913 rc = smscore_sendrequest_and_wait(coredev, DataMsg,
898 (coredev->mode == DEVICE_MODE_NONE))
899 rc = coredev->sendrequest_handler(
900 coredev->context, DataMsg,
901 DataMsg->xMsgHeader.msgLength);
902 else
903 rc = smscore_sendrequest_and_wait(
904 coredev, DataMsg,
905 DataMsg->xMsgHeader.msgLength, 914 DataMsg->xMsgHeader.msgLength,
906 &coredev->data_download_done); 915 &coredev->data_download_done);
907 916
@@ -910,44 +919,65 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
910 mem_address += payload_size; 919 mem_address += payload_size;
911 } 920 }
912 921
913 if (rc >= 0) { 922 if (rc < 0)
914 if (coredev->mode == DEVICE_MODE_NONE) { 923 goto exit_fw_download;
915 struct SmsMsgData_ST *TriggerMsg = 924
916 (struct SmsMsgData_ST *) msg; 925 sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x",
917 926 calc_checksum);
918 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, 927 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_VALIDITY_REQ,
919 sizeof(struct SmsMsgHdr_ST) + 928 sizeof(msg->xMsgHeader) +
920 sizeof(u32) * 5); 929 sizeof(u32) * 3);
921 930 msg->msgData[0] = firmware->StartAddress;
922 TriggerMsg->msgData[0] = firmware->StartAddress; 931 /* Entry point */
923 /* Entry point */ 932 msg->msgData[1] = firmware->Length;
924 TriggerMsg->msgData[1] = 5; /* Priority */ 933 msg->msgData[2] = 0; /* Regular checksum*/
925 TriggerMsg->msgData[2] = 0x200; /* Stack size */ 934 smsendian_handle_tx_message(msg);
926 TriggerMsg->msgData[3] = 0; /* Parameter */ 935 rc = smscore_sendrequest_and_wait(coredev, msg,
927 TriggerMsg->msgData[4] = 4; /* Task ID */ 936 msg->xMsgHeader.msgLength,
928 937 &coredev->data_validity_done);
929 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { 938 if (rc < 0)
930 rc = coredev->sendrequest_handler( 939 goto exit_fw_download;
931 coredev->context, TriggerMsg, 940
932 TriggerMsg->xMsgHeader.msgLength); 941 if (coredev->mode == DEVICE_MODE_NONE) {
933 msleep(100); 942 struct SmsMsgData_ST *TriggerMsg =
934 } else 943 (struct SmsMsgData_ST *) msg;
935 rc = smscore_sendrequest_and_wait( 944
936 coredev, TriggerMsg, 945 sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ");
946 SMS_INIT_MSG(&msg->xMsgHeader,
947 MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
948 sizeof(struct SmsMsgHdr_ST) +
949 sizeof(u32) * 5);
950
951 TriggerMsg->msgData[0] = firmware->StartAddress;
952 /* Entry point */
953 TriggerMsg->msgData[1] = 6; /* Priority */
954 TriggerMsg->msgData[2] = 0x200; /* Stack size */
955 TriggerMsg->msgData[3] = 0; /* Parameter */
956 TriggerMsg->msgData[4] = 4; /* Task ID */
957
958 smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg);
959 rc = smscore_sendrequest_and_wait(coredev, TriggerMsg,
937 TriggerMsg->xMsgHeader.msgLength, 960 TriggerMsg->xMsgHeader.msgLength,
938 &coredev->trigger_done); 961 &coredev->trigger_done);
939 } else { 962 } else {
940 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, 963 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_EXEC_REQ,
941 sizeof(struct SmsMsgHdr_ST)); 964 sizeof(struct SmsMsgHdr_ST));
942 965 smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg);
943 rc = coredev->sendrequest_handler(coredev->context, 966 rc = coredev->sendrequest_handler(coredev->context, msg,
944 msg, msg->msgLength); 967 msg->xMsgHeader.msgLength);
945 }
946 msleep(500);
947 } 968 }
948 969
949 sms_debug("rc=%d, postload=%p ", rc, 970 if (rc < 0)
950 coredev->postload_handler); 971 goto exit_fw_download;
972
973 /*
974 * backward compatibility - wait to device_ready_done for
975 * not more than 400 ms
976 */
977 msleep(400);
978
979exit_fw_download:
980 sms_debug("rc=%d, postload=0x%p ", rc, coredev->postload_handler);
951 981
952 kfree(msg); 982 kfree(msg);
953 983
@@ -956,6 +986,10 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
956 rc; 986 rc;
957} 987}
958 988
989
990static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
991 int mode, int lookup);
992
959/** 993/**
960 * loads specified firmware into a buffer and calls device loadfirmware_handler 994 * loads specified firmware into a buffer and calls device loadfirmware_handler
961 * 995 *
@@ -967,41 +1001,43 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
967 * @return 0 on success, <0 on error. 1001 * @return 0 on success, <0 on error.
968 */ 1002 */
969static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, 1003static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
970 char *filename, 1004 int mode, int lookup,
971 loadfirmware_t loadfirmware_handler) 1005 loadfirmware_t loadfirmware_handler)
972{ 1006{
973 int rc = -ENOENT; 1007 int rc = -ENOENT;
1008 u8 *fw_buf;
1009 u32 fw_buf_size;
974 const struct firmware *fw; 1010 const struct firmware *fw;
975 u8 *fw_buffer;
976 1011
977 if (loadfirmware_handler == NULL && !(coredev->device_flags & 1012 char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup);
978 SMS_DEVICE_FAMILY2)) 1013 if (!strcmp(fw_filename, "none"))
1014 return -ENOENT;
1015
1016 if (loadfirmware_handler == NULL && !(coredev->device_flags
1017 & SMS_DEVICE_FAMILY2))
979 return -EINVAL; 1018 return -EINVAL;
980 1019
981 rc = request_firmware(&fw, filename, coredev->device); 1020 rc = request_firmware(&fw, fw_filename, coredev->device);
982 if (rc < 0) { 1021 if (rc < 0) {
983 sms_info("failed to open \"%s\"", filename); 1022 sms_info("failed to open \"%s\"", fw_filename);
984 return rc; 1023 return rc;
985 } 1024 }
986 sms_info("read FW %s, size=%zd", filename, fw->size); 1025 sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
987 fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), 1026 fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
988 GFP_KERNEL | GFP_DMA); 1027 GFP_KERNEL | GFP_DMA);
989 if (fw_buffer) { 1028 if (!fw_buf) {
990 memcpy(fw_buffer, fw->data, fw->size);
991
992 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
993 smscore_load_firmware_family2(coredev,
994 fw_buffer,
995 fw->size) :
996 loadfirmware_handler(coredev->context,
997 fw_buffer, fw->size);
998
999 kfree(fw_buffer);
1000 } else {
1001 sms_info("failed to allocate firmware buffer"); 1029 sms_info("failed to allocate firmware buffer");
1002 rc = -ENOMEM; 1030 return -ENOMEM;
1003 } 1031 }
1032 memcpy(fw_buf, fw->data, fw->size);
1033 fw_buf_size = fw->size;
1034
1035 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
1036 smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
1037 : loadfirmware_handler(coredev->context, fw_buf,
1038 fw_buf_size);
1004 1039
1040 kfree(fw_buf);
1005 release_firmware(fw); 1041 release_firmware(fw);
1006 1042
1007 return rc; 1043 return rc;
@@ -1050,7 +1086,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
1050 1086
1051 sms_info("waiting for %d buffer(s)", 1087 sms_info("waiting for %d buffer(s)",
1052 coredev->num_buffers - num_buffers); 1088 coredev->num_buffers - num_buffers);
1089 kmutex_unlock(&g_smscore_deviceslock);
1053 msleep(100); 1090 msleep(100);
1091 kmutex_lock(&g_smscore_deviceslock);
1054 } 1092 }
1055 1093
1056 sms_info("freed %d buffers", num_buffers); 1094 sms_info("freed %d buffers", num_buffers);
@@ -1107,30 +1145,73 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
1107} 1145}
1108 1146
1109static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { 1147static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
1110 /*Stellar NOVA A0 Nova B0 VEGA*/ 1148 /*Stellar, NOVA A0, Nova B0, VEGA, VENICE, MING, PELE, RIO, DENVER_1530, DENVER_2160 */
1111 /*DVBT*/ 1149 /*DVBT*/
1112 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 1150 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" },
1113 /*DVBH*/ 1151 /*DVBH*/
1114 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 1152 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvbh_rio.inp", "none", "none" },
1115 /*TDMB*/ 1153 /*TDMB*/
1116 {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, 1154 { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none", "none", "none", "none", "none", "none", "tdmb_denver.inp" },
1117 /*DABIP*/ 1155 /*DABIP*/
1118 {"none", "none", "none", "none"}, 1156 { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" },
1119 /*BDA*/ 1157 /*DVBT_BDA*/
1120 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 1158 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" },
1121 /*ISDBT*/ 1159 /*ISDBT*/
1122 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, 1160 { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" },
1123 /*ISDBTBDA*/ 1161 /*ISDBT_BDA*/
1124 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, 1162 { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" },
1125 /*CMMB*/ 1163 /*CMMB*/
1126 {"none", "none", "none", "cmmb_vega_12mhz.inp"} 1164 { "none", "none", "none", "cmmb_vega_12mhz.inp", "cmmb_venice_12mhz.inp", "cmmb_ming_app.inp", "none", "none", "none", "none" },
1165 /*RAW - not supported*/
1166 { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" },
1167 /*FM*/
1168 { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" },
1169 /*FM_BDA*/
1170 { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" },
1171 /*ATSC*/
1172 { "none", "none", "none", "none", "none", "none", "none", "none", "atsc_denver.inp", "none" }
1127}; 1173};
1128 1174
1129static inline char *sms_get_fw_name(struct smscore_device_t *coredev, 1175/**
1130 int mode, enum sms_device_type_st type) 1176 * get firmware file name from one of the two mechanisms : sms_boards or
1177 * smscore_fw_lkup.
1178 * @param coredev pointer to a coredev object returned by
1179 * smscore_register_device
1180 * @param mode requested mode of operation
1181 * @param lookup if 1, always get the fw filename from smscore_fw_lkup
1182 * table. if 0, try first to get from sms_boards
1183 *
1184 * @return 0 on success, <0 on error.
1185 */
1186static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
1187 int mode, int lookup)
1131{ 1188{
1132 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; 1189 char **fw;
1133 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; 1190 int board_id = smscore_get_board_id(coredev);
1191 enum sms_device_type_st type = smscore_registry_gettype(coredev->devpath);
1192
1193 if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) {
1194 sms_debug("trying to get fw name from lookup table mode %d type %d",
1195 mode, type);
1196 return smscore_fw_lkup[mode][type];
1197 }
1198
1199 sms_debug("trying to get fw name from sms_boards board_id %d mode %d",
1200 board_id, mode);
1201 fw = sms_get_board(board_id)->fw;
1202 if (fw == NULL) {
1203 sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d",
1204 mode, type);
1205 return smscore_fw_lkup[mode][type];
1206 }
1207
1208 if (fw[mode] == NULL) {
1209 sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d",
1210 mode, type);
1211 return smscore_fw_lkup[mode][type];
1212 }
1213
1214 return fw[mode];
1134} 1215}
1135 1216
1136/** 1217/**
@@ -1145,9 +1226,7 @@ static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
1145 */ 1226 */
1146int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) 1227int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
1147{ 1228{
1148 void *buffer;
1149 int rc = 0; 1229 int rc = 0;
1150 enum sms_device_type_st type;
1151 1230
1152 sms_debug("set device mode to %d", mode); 1231 sms_debug("set device mode to %d", mode);
1153 if (coredev->device_flags & SMS_DEVICE_FAMILY2) { 1232 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
@@ -1172,55 +1251,30 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
1172 } 1251 }
1173 1252
1174 if (!(coredev->modes_supported & (1 << mode))) { 1253 if (!(coredev->modes_supported & (1 << mode))) {
1175 char *fw_filename;
1176
1177 type = smscore_registry_gettype(coredev->devpath);
1178 fw_filename = sms_get_fw_name(coredev, mode, type);
1179
1180 rc = smscore_load_firmware_from_file(coredev, 1254 rc = smscore_load_firmware_from_file(coredev,
1181 fw_filename, NULL); 1255 mode, 0, NULL);
1182 if (rc < 0) {
1183 sms_warn("error %d loading firmware: %s, "
1184 "trying again with default firmware",
1185 rc, fw_filename);
1186 1256
1187 /* try again with the default firmware */ 1257 /*
1188 fw_filename = smscore_fw_lkup[mode][type]; 1258 * try again with the default firmware -
1259 * get the fw filename from look-up table
1260 */
1261 if (rc < 0) {
1262 sms_debug("error %d loading firmware, trying again with default firmware",
1263 rc);
1189 rc = smscore_load_firmware_from_file(coredev, 1264 rc = smscore_load_firmware_from_file(coredev,
1190 fw_filename, NULL); 1265 mode, 1,
1191 1266 NULL);
1192 if (rc < 0) { 1267 if (rc < 0) {
1193 sms_warn("error %d loading " 1268 sms_debug("error %d loading firmware",
1194 "firmware: %s", rc, 1269 rc);
1195 fw_filename);
1196 return rc; 1270 return rc;
1197 } 1271 }
1198 } 1272 }
1199 sms_log("firmware download success: %s", fw_filename); 1273 if (rc >= 0)
1200 } else 1274 sms_info("firmware download success");
1201 sms_info("mode %d supported by running "
1202 "firmware", mode);
1203
1204 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
1205 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
1206 if (buffer) {
1207 struct SmsMsgData_ST *msg =
1208 (struct SmsMsgData_ST *)
1209 SMS_ALIGN_ADDRESS(buffer);
1210
1211 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
1212 sizeof(struct SmsMsgData_ST));
1213 msg->msgData[0] = mode;
1214
1215 rc = smscore_sendrequest_and_wait(
1216 coredev, msg, msg->xMsgHeader.msgLength,
1217 &coredev->init_device_done);
1218
1219 kfree(buffer);
1220 } else { 1275 } else {
1221 sms_err("Could not allocate buffer for " 1276 sms_info("mode %d is already supported by running firmware",
1222 "init device message."); 1277 mode);
1223 rc = -ENOMEM;
1224 } 1278 }
1225 } else { 1279 } else {
1226 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { 1280 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)
1239 } 1293 }
1240 1294
1241 if (rc >= 0) { 1295 if (rc >= 0) {
1296 char *buffer;
1242 coredev->mode = mode; 1297 coredev->mode = mode;
1243 coredev->device_flags &= ~SMS_DEVICE_NOT_READY; 1298 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
1299
1300 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
1301 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
1302 if (buffer) {
1303 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer);
1304
1305 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
1306 sizeof(struct SmsMsgData_ST));
1307 msg->msgData[0] = mode;
1308
1309 rc = smscore_sendrequest_and_wait(
1310 coredev, msg, msg->xMsgHeader.msgLength,
1311 &coredev->init_device_done);
1312
1313 kfree(buffer);
1314 }
1244 } 1315 }
1245 1316
1246 if (rc < 0) 1317 if (rc < 0)
@@ -1371,6 +1442,15 @@ void smscore_onresponse(struct smscore_device_t *coredev,
1371 case MSG_SW_RELOAD_START_RES: 1442 case MSG_SW_RELOAD_START_RES:
1372 complete(&coredev->reload_start_done); 1443 complete(&coredev->reload_start_done);
1373 break; 1444 break;
1445 case MSG_SMS_DATA_VALIDITY_RES:
1446 {
1447 struct SmsMsgData_ST *validity = (struct SmsMsgData_ST *) phdr;
1448
1449 sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x",
1450 validity->msgData[0]);
1451 complete(&coredev->data_validity_done);
1452 break;
1453 }
1374 case MSG_SMS_DATA_DOWNLOAD_RES: 1454 case MSG_SMS_DATA_DOWNLOAD_RES:
1375 complete(&coredev->data_download_done); 1455 complete(&coredev->data_download_done);
1376 break; 1456 break;
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
index f1440a55cb4d..91db8536c2b0 100644
--- a/drivers/media/common/siano/smscoreapi.h
+++ b/drivers/media/common/siano/smscoreapi.h
@@ -162,6 +162,7 @@ struct smscore_device_t {
162 162
163 /* host <--> device messages */ 163 /* host <--> device messages */
164 struct completion version_ex_done, data_download_done, trigger_done; 164 struct completion version_ex_done, data_download_done, trigger_done;
165 struct completion data_validity_done, device_ready_done;
165 struct completion init_device_done, reload_start_done, resume_done; 166 struct completion init_device_done, reload_start_done, resume_done;
166 struct completion gpio_configuration_done, gpio_set_level_done; 167 struct completion gpio_configuration_done, gpio_set_level_done;
167 struct completion gpio_get_level_done, ir_init_done; 168 struct completion gpio_get_level_done, ir_init_done;
@@ -594,6 +595,11 @@ struct SmsMsgData_ST2 {
594 u32 msgData[2]; 595 u32 msgData[2];
595}; 596};
596 597
598struct SmsMsgData_ST4 {
599 struct SmsMsgHdr_ST xMsgHeader;
600 u32 msgData[4];
601};
602
597struct SmsDataDownload_ST { 603struct SmsDataDownload_ST {
598 struct SmsMsgHdr_ST xMsgHeader; 604 struct SmsMsgHdr_ST xMsgHeader;
599 u32 MemAddr; 605 u32 MemAddr;
@@ -998,8 +1004,6 @@ extern void smscore_onresponse(struct smscore_device_t *coredev,
998extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); 1004extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
999extern int smscore_map_common_buffer(struct smscore_device_t *coredev, 1005extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
1000 struct vm_area_struct *vma); 1006 struct vm_area_struct *vma);
1001extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
1002 int mode, char *filename);
1003extern int smscore_send_fw_file(struct smscore_device_t *coredev, 1007extern int smscore_send_fw_file(struct smscore_device_t *coredev,
1004 u8 *ufwbuf, int size); 1008 u8 *ufwbuf, int size);
1005 1009