1*a248dafdSChristopher Ferris /* 2*a248dafdSChristopher Ferris * Copyright (C) 2014 Andrew Duggan 3*a248dafdSChristopher Ferris * Copyright (C) 2014 Synaptics Inc 4*a248dafdSChristopher Ferris * 5*a248dafdSChristopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 6*a248dafdSChristopher Ferris * you may not use this file except in compliance with the License. 7*a248dafdSChristopher Ferris * You may obtain a copy of the License at 8*a248dafdSChristopher Ferris * 9*a248dafdSChristopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 10*a248dafdSChristopher Ferris * 11*a248dafdSChristopher Ferris * Unless required by applicable law or agreed to in writing, software 12*a248dafdSChristopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 13*a248dafdSChristopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*a248dafdSChristopher Ferris * See the License for the specific language governing permissions and 15*a248dafdSChristopher Ferris * limitations under the License. 16*a248dafdSChristopher Ferris */ 17*a248dafdSChristopher Ferris 18*a248dafdSChristopher Ferris #ifndef _RMI4UPDATE_H_ 19*a248dafdSChristopher Ferris #define _RMI4UPDATE_H_ 20*a248dafdSChristopher Ferris 21*a248dafdSChristopher Ferris #include "rmidevice.h" 22*a248dafdSChristopher Ferris #include "firmware_image.h" 23*a248dafdSChristopher Ferris 24*a248dafdSChristopher Ferris #define RMI_BOOTLOADER_ID_SIZE 2 25*a248dafdSChristopher Ferris 26*a248dafdSChristopher Ferris // leon add 27*a248dafdSChristopher Ferris enum v7_status { 28*a248dafdSChristopher Ferris SUCCESS = 0x00, 29*a248dafdSChristopher Ferris DEVICE_NOT_IN_BOOTLOADER_MODE, 30*a248dafdSChristopher Ferris INVALID_PARTITION, 31*a248dafdSChristopher Ferris INVALID_COMMAND, 32*a248dafdSChristopher Ferris INVALID_BLOCK_OFFSET, 33*a248dafdSChristopher Ferris INVALID_TRANSFER, 34*a248dafdSChristopher Ferris NOT_ERASED, 35*a248dafdSChristopher Ferris FLASH_PROGRAMMING_KEY_INCORRECT, 36*a248dafdSChristopher Ferris BAD_PARTITION_TABLE, 37*a248dafdSChristopher Ferris CHECKSUM_FAILED, 38*a248dafdSChristopher Ferris WRITE_PROTECTION = 0x0E, 39*a248dafdSChristopher Ferris FLASH_HARDWARE_FAILURE = 0x1f, 40*a248dafdSChristopher Ferris }; 41*a248dafdSChristopher Ferris 42*a248dafdSChristopher Ferris enum v7_partition_id { 43*a248dafdSChristopher Ferris NONE_PARTITION = 0x00, 44*a248dafdSChristopher Ferris BOOTLOADER_PARTITION = 0x01, 45*a248dafdSChristopher Ferris DEVICE_CONFIG_PARTITION, 46*a248dafdSChristopher Ferris FLASH_CONFIG_PARTITION, 47*a248dafdSChristopher Ferris MANUFACTURING_BLOCK_PARTITION, 48*a248dafdSChristopher Ferris GUEST_SERIALIZATION_PARTITION, 49*a248dafdSChristopher Ferris GLOBAL_PARAMETERS_PARTITION, 50*a248dafdSChristopher Ferris CORE_CODE_PARTITION, 51*a248dafdSChristopher Ferris CORE_CONFIG_PARTITION, 52*a248dafdSChristopher Ferris GUEST_CODE_PARTITION, 53*a248dafdSChristopher Ferris DISPLAY_CONFIG_PARTITION, 54*a248dafdSChristopher Ferris EXTERNAL_TOUCH_AFE_CONFIG_PARTITION, 55*a248dafdSChristopher Ferris UTILITY_PARAMETER_PARTITION, 56*a248dafdSChristopher Ferris FIXED_LOCATION_DATA_PARTITION = 0x0E, 57*a248dafdSChristopher Ferris }; 58*a248dafdSChristopher Ferris 59*a248dafdSChristopher Ferris enum v7_flash_command { 60*a248dafdSChristopher Ferris CMD_V7_IDLE = 0x00, 61*a248dafdSChristopher Ferris CMD_V7_ENTER_BL, 62*a248dafdSChristopher Ferris CMD_V7_READ, 63*a248dafdSChristopher Ferris CMD_V7_WRITE, 64*a248dafdSChristopher Ferris CMD_V7_ERASE, 65*a248dafdSChristopher Ferris CMD_V7_ERASE_AP, 66*a248dafdSChristopher Ferris CMD_V7_SENSOR_ID, 67*a248dafdSChristopher Ferris CMD_V7_SIGNATURE, 68*a248dafdSChristopher Ferris }; 69*a248dafdSChristopher Ferris 70*a248dafdSChristopher Ferris enum bl_version { 71*a248dafdSChristopher Ferris BL_V5 = 5, 72*a248dafdSChristopher Ferris BL_V6 = 6, 73*a248dafdSChristopher Ferris BL_V7 = 7, 74*a248dafdSChristopher Ferris BL_V8 = 8, 75*a248dafdSChristopher Ferris BL_V10 = 10, 76*a248dafdSChristopher Ferris }; 77*a248dafdSChristopher Ferris 78*a248dafdSChristopher Ferris struct f34_v7_query_0 { 79*a248dafdSChristopher Ferris union { 80*a248dafdSChristopher Ferris struct { 81*a248dafdSChristopher Ferris unsigned char subpacket_1_size:3; 82*a248dafdSChristopher Ferris unsigned char has_config_id:1; 83*a248dafdSChristopher Ferris unsigned char f34_query0_b4:1; 84*a248dafdSChristopher Ferris unsigned char has_thqa:1; 85*a248dafdSChristopher Ferris unsigned char f34_query0_b6__7:2; 86*a248dafdSChristopher Ferris } __attribute__((packed));; 87*a248dafdSChristopher Ferris unsigned char data[1]; 88*a248dafdSChristopher Ferris }; 89*a248dafdSChristopher Ferris }; 90*a248dafdSChristopher Ferris 91*a248dafdSChristopher Ferris struct f34_v7_query_1_7 { 92*a248dafdSChristopher Ferris union { 93*a248dafdSChristopher Ferris struct { 94*a248dafdSChristopher Ferris /* query 1 */ 95*a248dafdSChristopher Ferris unsigned char bl_minor_revision; 96*a248dafdSChristopher Ferris unsigned char bl_major_revision; 97*a248dafdSChristopher Ferris 98*a248dafdSChristopher Ferris /* query 2 */ 99*a248dafdSChristopher Ferris unsigned char bl_fw_id_7_0; 100*a248dafdSChristopher Ferris unsigned char bl_fw_id_15_8; 101*a248dafdSChristopher Ferris unsigned char bl_fw_id_23_16; 102*a248dafdSChristopher Ferris unsigned char bl_fw_id_31_24; 103*a248dafdSChristopher Ferris 104*a248dafdSChristopher Ferris /* query 3 */ 105*a248dafdSChristopher Ferris unsigned char minimum_write_size; 106*a248dafdSChristopher Ferris unsigned char block_size_7_0; 107*a248dafdSChristopher Ferris unsigned char block_size_15_8; 108*a248dafdSChristopher Ferris unsigned char flash_page_size_7_0; 109*a248dafdSChristopher Ferris unsigned char flash_page_size_15_8; 110*a248dafdSChristopher Ferris 111*a248dafdSChristopher Ferris /* query 4 */ 112*a248dafdSChristopher Ferris unsigned char adjustable_partition_area_size_7_0; 113*a248dafdSChristopher Ferris unsigned char adjustable_partition_area_size_15_8; 114*a248dafdSChristopher Ferris 115*a248dafdSChristopher Ferris /* query 5 */ 116*a248dafdSChristopher Ferris unsigned char flash_config_length_7_0; 117*a248dafdSChristopher Ferris unsigned char flash_config_length_15_8; 118*a248dafdSChristopher Ferris 119*a248dafdSChristopher Ferris /* query 6 */ 120*a248dafdSChristopher Ferris unsigned char payload_length_7_0; 121*a248dafdSChristopher Ferris unsigned char payload_length_15_8; 122*a248dafdSChristopher Ferris 123*a248dafdSChristopher Ferris /* query 7 */ 124*a248dafdSChristopher Ferris unsigned char f34_query7_b0:1; 125*a248dafdSChristopher Ferris unsigned char has_bootloader:1; 126*a248dafdSChristopher Ferris unsigned char has_device_config:1; 127*a248dafdSChristopher Ferris unsigned char has_flash_config:1; 128*a248dafdSChristopher Ferris unsigned char has_manufacturing_block:1; 129*a248dafdSChristopher Ferris unsigned char has_guest_serialization:1; 130*a248dafdSChristopher Ferris unsigned char has_global_parameters:1; 131*a248dafdSChristopher Ferris unsigned char has_core_code:1; 132*a248dafdSChristopher Ferris unsigned char has_core_config:1; 133*a248dafdSChristopher Ferris unsigned char has_guest_code:1; 134*a248dafdSChristopher Ferris unsigned char has_display_config:1; 135*a248dafdSChristopher Ferris unsigned char f34_query7_b11_13:3; 136*a248dafdSChristopher Ferris unsigned char has_fld:1; 137*a248dafdSChristopher Ferris unsigned char f34_query7_b15:1; 138*a248dafdSChristopher Ferris unsigned char f34_query7_b16__23; 139*a248dafdSChristopher Ferris unsigned char f34_query7_b24__31; 140*a248dafdSChristopher Ferris } __attribute__((packed));; 141*a248dafdSChristopher Ferris unsigned char data[21]; 142*a248dafdSChristopher Ferris }; 143*a248dafdSChristopher Ferris }; 144*a248dafdSChristopher Ferris 145*a248dafdSChristopher Ferris struct partition_tbl 146*a248dafdSChristopher Ferris { 147*a248dafdSChristopher Ferris union { 148*a248dafdSChristopher Ferris struct { 149*a248dafdSChristopher Ferris unsigned short partition_id; 150*a248dafdSChristopher Ferris unsigned short partition_len; 151*a248dafdSChristopher Ferris unsigned short partition_addr; 152*a248dafdSChristopher Ferris unsigned short partition_prop; 153*a248dafdSChristopher Ferris } __attribute__((packed));; 154*a248dafdSChristopher Ferris unsigned char data[8]; 155*a248dafdSChristopher Ferris }; 156*a248dafdSChristopher Ferris }; 157*a248dafdSChristopher Ferris // leon end 158*a248dafdSChristopher Ferris 159*a248dafdSChristopher Ferris class RMI4Update 160*a248dafdSChristopher Ferris { 161*a248dafdSChristopher Ferris public: RMI4Update(RMIDevice & device,FirmwareImage & firmwareImage)162*a248dafdSChristopher Ferris RMI4Update(RMIDevice & device, FirmwareImage & firmwareImage) : m_device(device), 163*a248dafdSChristopher Ferris m_firmwareImage(firmwareImage), m_writeBlockWithCmd(true) 164*a248dafdSChristopher Ferris { 165*a248dafdSChristopher Ferris m_IsErased = false; 166*a248dafdSChristopher Ferris m_hasCoreCode = false; 167*a248dafdSChristopher Ferris m_hasCoreConfig = false; 168*a248dafdSChristopher Ferris m_hasFlashConfig = false; 169*a248dafdSChristopher Ferris m_hasFLD = false; 170*a248dafdSChristopher Ferris m_hasGlobalParameters = false; 171*a248dafdSChristopher Ferris } 172*a248dafdSChristopher Ferris int UpdateFirmware(bool force = false, bool performLockdown = false); 173*a248dafdSChristopher Ferris 174*a248dafdSChristopher Ferris private: 175*a248dafdSChristopher Ferris int DisableNonessentialInterupts(); 176*a248dafdSChristopher Ferris int FindUpdateFunctions(); 177*a248dafdSChristopher Ferris int ReadFlashConfig(); 178*a248dafdSChristopher Ferris int rmi4update_poll(); 179*a248dafdSChristopher Ferris int ReadF34QueriesV7(); 180*a248dafdSChristopher Ferris int ReadF34Queries(); 181*a248dafdSChristopher Ferris int ReadF34Controls(); 182*a248dafdSChristopher Ferris int WriteBootloaderID(); 183*a248dafdSChristopher Ferris int EnterFlashProgrammingV7(); 184*a248dafdSChristopher Ferris int EraseFirmwareV7(); 185*a248dafdSChristopher Ferris int EraseFlashConfigV10(); 186*a248dafdSChristopher Ferris int EraseCoreCodeV10(); 187*a248dafdSChristopher Ferris int WriteFirmwareV7(); 188*a248dafdSChristopher Ferris int WriteCoreConfigV7(); 189*a248dafdSChristopher Ferris int WriteFlashConfigV7(); 190*a248dafdSChristopher Ferris int WriteFLDV7(); 191*a248dafdSChristopher Ferris int WriteGlobalParametersV7(); 192*a248dafdSChristopher Ferris int EnterFlashProgramming(); 193*a248dafdSChristopher Ferris int WriteBlocks(unsigned char *block, unsigned short count, unsigned char cmd); 194*a248dafdSChristopher Ferris int WaitForIdle(int timeout_ms, bool readF34OnSucess = true); GetFirmwareSize()195*a248dafdSChristopher Ferris int GetFirmwareSize() { return m_blockSize * m_fwBlockCount; } GetConfigSize()196*a248dafdSChristopher Ferris int GetConfigSize() { return m_blockSize * m_configBlockCount; } 197*a248dafdSChristopher Ferris int WriteSignatureV7(enum signature_BLv7 signature_partition, unsigned char* data, int offset); 198*a248dafdSChristopher Ferris bool IsBLv87(); 199*a248dafdSChristopher Ferris int ReadMSL(); 200*a248dafdSChristopher Ferris 201*a248dafdSChristopher Ferris private: 202*a248dafdSChristopher Ferris RMIDevice & m_device; 203*a248dafdSChristopher Ferris FirmwareImage & m_firmwareImage; 204*a248dafdSChristopher Ferris 205*a248dafdSChristopher Ferris RMIFunction m_f01; 206*a248dafdSChristopher Ferris RMIFunction m_f34; 207*a248dafdSChristopher Ferris 208*a248dafdSChristopher Ferris unsigned char m_deviceStatus; 209*a248dafdSChristopher Ferris unsigned char m_bootloaderID[RMI_BOOTLOADER_ID_SIZE]; 210*a248dafdSChristopher Ferris bool m_writeBlockWithCmd; 211*a248dafdSChristopher Ferris 212*a248dafdSChristopher Ferris /* F34 Controls */ 213*a248dafdSChristopher Ferris unsigned char m_f34Command; 214*a248dafdSChristopher Ferris unsigned char m_f34Status; 215*a248dafdSChristopher Ferris bool m_programEnabled; 216*a248dafdSChristopher Ferris 217*a248dafdSChristopher Ferris /* F34 Query */ 218*a248dafdSChristopher Ferris bool m_hasNewRegmap; 219*a248dafdSChristopher Ferris bool m_unlocked; 220*a248dafdSChristopher Ferris bool m_hasConfigID; 221*a248dafdSChristopher Ferris unsigned short m_blockSize; 222*a248dafdSChristopher Ferris unsigned short m_fwBlockCount; 223*a248dafdSChristopher Ferris unsigned short m_configBlockCount; 224*a248dafdSChristopher Ferris /* for BL_V7 */ 225*a248dafdSChristopher Ferris unsigned short m_flashConfigLength; 226*a248dafdSChristopher Ferris unsigned short m_payloadLength; 227*a248dafdSChristopher Ferris unsigned short m_guestBlockCount; 228*a248dafdSChristopher Ferris struct partition_tbl *m_partitionCore; 229*a248dafdSChristopher Ferris struct partition_tbl *m_partitionConfig; 230*a248dafdSChristopher Ferris struct partition_tbl *m_partitionGuest; 231*a248dafdSChristopher Ferris unsigned char m_flashStatus; 232*a248dafdSChristopher Ferris unsigned char m_flashCmd; 233*a248dafdSChristopher Ferris unsigned char m_inBLmode; 234*a248dafdSChristopher Ferris unsigned long m_buildID; 235*a248dafdSChristopher Ferris unsigned char *m_guestData; 236*a248dafdSChristopher Ferris bool m_hasCoreCode; 237*a248dafdSChristopher Ferris bool m_hasCoreConfig; 238*a248dafdSChristopher Ferris bool m_hasFlashConfig; 239*a248dafdSChristopher Ferris bool m_hasGlobalParameters; 240*a248dafdSChristopher Ferris /* BL_V7 end */ 241*a248dafdSChristopher Ferris 242*a248dafdSChristopher Ferris /* BL v8.7 */ 243*a248dafdSChristopher Ferris unsigned short m_MSL; 244*a248dafdSChristopher Ferris /* BL v8.7 end */ 245*a248dafdSChristopher Ferris 246*a248dafdSChristopher Ferris /* for BL V10 */ 247*a248dafdSChristopher Ferris bool m_hasFLD; 248*a248dafdSChristopher Ferris /* BL_V7 end */ 249*a248dafdSChristopher Ferris 250*a248dafdSChristopher Ferris unsigned short m_f34StatusAddr; 251*a248dafdSChristopher Ferris enum bl_version m_blVersion; 252*a248dafdSChristopher Ferris 253*a248dafdSChristopher Ferris bool m_IsErased; 254*a248dafdSChristopher Ferris }; 255*a248dafdSChristopher Ferris 256*a248dafdSChristopher Ferris #endif // _RMI4UPDATE_H_ 257