1 /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <fcntl.h> 36 #include <errno.h> 37 #include <cutils/properties.h> 38 #include "loc_target.h" 39 #include "loc_log.h" 40 #include <platform_lib_includes.h> 41 42 #define APQ8064_ID_1 "109" 43 #define APQ8064_ID_2 "153" 44 #define MPQ8064_ID_1 "130" 45 #define MSM8930_ID_1 "142" 46 #define MSM8930_ID_2 "116" 47 #define APQ8030_ID_1 "157" 48 #define APQ8074_ID_1 "184" 49 50 #define LINE_LEN 100 51 #define STR_LIQUID "Liquid" 52 #define STR_SURF "Surf" 53 #define STR_MTP "MTP" 54 #define STR_APQ "apq" 55 #define STR_SDC "sdc" // alternative string for APQ targets 56 #define STR_QCS "qcs" // string for Gen9 APQ targets 57 #define STR_MSM "msm" 58 #define STR_SDM "sdm" // alternative string for MSM targets 59 #define STR_APQ_NO_WGR "baseband_apq_nowgr" 60 #define STR_AUTO "auto" 61 #define IS_STR_END(c) ((c) == '\0' || (c) == '\n' || (c) == '\r') 62 #define LENGTH(s) (sizeof(s) - 1) 63 #define GPS_CHECK_NO_ERROR 0 64 #define GPS_CHECK_NO_GPS_HW 1 65 66 static unsigned int gTarget = (unsigned int)-1; 67 68 static int read_a_line(const char * file_path, char * line, int line_size) 69 { 70 FILE *fp; 71 int result = 0; 72 73 * line = '\0'; 74 fp = fopen(file_path, "r" ); 75 if( fp == NULL ) { 76 LOC_LOGE("open failed: %s: %s\n", file_path, strerror(errno)); 77 result = -1; 78 } else { 79 int len; 80 fgets(line, line_size, fp); 81 len = strlen(line); 82 len = len < line_size - 1? len : line_size - 1; 83 line[len] = '\0'; 84 LOC_LOGD("cat %s: %s", file_path, line); 85 fclose(fp); 86 } 87 return result; 88 } 89 90 /*The character array passed to this function should have length 91 of atleast PROPERTY_VALUE_MAX*/ 92 void loc_get_target_baseband(char *baseband, int array_length) 93 { 94 if(baseband && (array_length >= PROPERTY_VALUE_MAX)) { 95 property_get("ro.baseband", baseband, ""); 96 LOC_LOGD("%s:%d]: Baseband: %s\n", __func__, __LINE__, baseband); 97 } 98 else { 99 LOC_LOGE("%s:%d]: NULL parameter or array length less than PROPERTY_VALUE_MAX\n", 100 __func__, __LINE__); 101 } 102 } 103 104 /*The character array passed to this function should have length 105 of atleast PROPERTY_VALUE_MAX*/ 106 void loc_get_platform_name(char *platform_name, int array_length) 107 { 108 if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) { 109 property_get("ro.board.platform", platform_name, ""); 110 LOC_LOGD("%s:%d]: Target name: %s\n", __func__, __LINE__, platform_name); 111 } 112 else { 113 LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n", 114 __func__, __LINE__); 115 } 116 } 117 118 /*The character array passed to this function should have length 119 of atleast PROPERTY_VALUE_MAX*/ 120 void loc_get_auto_platform_name(char *platform_name, int array_length) 121 { 122 if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) { 123 property_get("ro.hardware.type", platform_name, ""); 124 LOC_LOGD("%s:%d]: Autoplatform name: %s\n", __func__, __LINE__, platform_name); 125 } 126 else { 127 LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n", 128 __func__, __LINE__); 129 } 130 } 131 132 unsigned int loc_get_target(void) 133 { 134 if (gTarget != (unsigned int)-1) 135 return gTarget; 136 137 static const char hw_platform[] = "/sys/devices/soc0/hw_platform"; 138 static const char id[] = "/sys/devices/soc0/soc_id"; 139 static const char hw_platform_dep[] = 140 "/sys/devices/system/soc/soc0/hw_platform"; 141 static const char id_dep[] = "/sys/devices/system/soc/soc0/id"; 142 static const char mdm[] = "/target"; // mdm target we are using 143 144 char rd_hw_platform[LINE_LEN]; 145 char rd_id[LINE_LEN]; 146 char rd_mdm[LINE_LEN]; 147 char baseband[LINE_LEN]; 148 char rd_auto_platform[LINE_LEN]; 149 150 loc_get_target_baseband(baseband, sizeof(baseband)); 151 152 if (!access(hw_platform, F_OK)) { 153 read_a_line(hw_platform, rd_hw_platform, LINE_LEN); 154 } else { 155 read_a_line(hw_platform_dep, rd_hw_platform, LINE_LEN); 156 } 157 if (!access(id, F_OK)) { 158 read_a_line(id, rd_id, LINE_LEN); 159 } else { 160 read_a_line(id_dep, rd_id, LINE_LEN); 161 } 162 163 /*check automotive platform*/ 164 loc_get_auto_platform_name(rd_auto_platform, sizeof(rd_auto_platform)); 165 if( !memcmp(rd_auto_platform, STR_AUTO, LENGTH(STR_AUTO)) ) 166 { 167 gTarget = TARGET_AUTO; 168 goto detected; 169 } 170 171 if( !memcmp(baseband, STR_APQ_NO_WGR, LENGTH(STR_APQ_NO_WGR)) ){ 172 173 gTarget = TARGET_NO_GNSS; 174 goto detected; 175 } 176 177 if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) || 178 !memcmp(baseband, STR_SDC, LENGTH(STR_SDC)) || 179 !memcmp(baseband, STR_QCS, LENGTH(STR_QCS)) ) { 180 181 if( !memcmp(rd_id, MPQ8064_ID_1, LENGTH(MPQ8064_ID_1)) 182 && IS_STR_END(rd_id[LENGTH(MPQ8064_ID_1)]) ) 183 gTarget = TARGET_NO_GNSS; 184 else 185 gTarget = TARGET_APQ_SA; 186 } else if (((!memcmp(rd_hw_platform, STR_LIQUID, LENGTH(STR_LIQUID)) 187 && IS_STR_END(rd_hw_platform[LENGTH(STR_LIQUID)])) || 188 (!memcmp(rd_hw_platform, STR_SURF, LENGTH(STR_SURF)) 189 && IS_STR_END(rd_hw_platform[LENGTH(STR_SURF)])) || 190 (!memcmp(rd_hw_platform, STR_MTP, LENGTH(STR_MTP)) 191 && IS_STR_END(rd_hw_platform[LENGTH(STR_MTP)]))) && 192 !read_a_line( mdm, rd_mdm, LINE_LEN)) { 193 gTarget = TARGET_MDM; 194 } else if( (!memcmp(rd_id, MSM8930_ID_1, LENGTH(MSM8930_ID_1)) 195 && IS_STR_END(rd_id[LENGTH(MSM8930_ID_1)])) || 196 (!memcmp(rd_id, MSM8930_ID_2, LENGTH(MSM8930_ID_2)) 197 && IS_STR_END(rd_id[LENGTH(MSM8930_ID_2)])) ) { 198 gTarget = TARGET_MSM_NO_SSC; 199 } else if ( !memcmp(baseband, STR_MSM, LENGTH(STR_MSM)) || 200 !memcmp(baseband, STR_SDM, LENGTH(STR_SDM)) ) { 201 gTarget = TARGET_DEFAULT; 202 } else { 203 gTarget = TARGET_UNKNOWN; 204 } 205 206 detected: 207 LOC_LOGW("HAL: %s returned %d", __FUNCTION__, gTarget); 208 return gTarget; 209 } 210 211 /*Reads the property ro.lean to identify if this is a lean target 212 Returns: 213 0 if not a lean and mean target 214 1 if this is a lean and mean target 215 */ 216 int loc_identify_lean_target() 217 { 218 int ret = 0; 219 char lean_target[PROPERTY_VALUE_MAX]; 220 property_get("ro.lean", lean_target, ""); 221 LOC_LOGD("%s:%d]: lean target: %s\n", __func__, __LINE__, lean_target); 222 return !(strncmp(lean_target, "true", PROPERTY_VALUE_MAX)); 223 } 224