1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // aw88395_lib.c -- ACF bin parsing and check library file for aw88395 4 // 5 // Copyright (c) 2022-2023 AWINIC Technology CO., LTD 6 // 7 // Author: Bruce zhao <zhaolei@awinic.com> 8 // 9 10 #include <linux/cleanup.h> 11 #include <linux/crc8.h> 12 #include <linux/i2c.h> 13 #include "aw88395_lib.h" 14 #include "aw88395_device.h" 15 16 #define AW88395_CRC8_POLYNOMIAL 0x8C 17 DECLARE_CRC8_TABLE(aw_crc8_table); 18 19 static char *profile_name[AW88395_PROFILE_MAX] = { 20 "Music", "Voice", "Voip", "Ringtone", 21 "Ringtone_hs", "Lowpower", "Bypass", 22 "Mmi", "Fm", "Notification", "Receiver" 23 }; 24 25 static int aw_parse_bin_header(struct aw_device *aw_dev, struct aw_bin *bin); 26 27 static int aw_check_sum(struct aw_device *aw_dev, struct aw_bin *bin, int bin_num) 28 { 29 unsigned char *p_check_sum; 30 unsigned int sum_data = 0; 31 unsigned int check_sum; 32 unsigned int i, len; 33 34 p_check_sum = &(bin->info.data[(bin->header_info[bin_num].valid_data_addr - 35 bin->header_info[bin_num].header_len)]); 36 len = bin->header_info[bin_num].bin_data_len + bin->header_info[bin_num].header_len; 37 check_sum = le32_to_cpup((void *)p_check_sum); 38 39 for (i = 4; i < len; i++) 40 sum_data += *(p_check_sum + i); 41 42 dev_dbg(aw_dev->dev, "%s -- check_sum = %p, check_sum = 0x%x, sum_data = 0x%x", 43 __func__, p_check_sum, check_sum, sum_data); 44 if (sum_data != check_sum) { 45 dev_err(aw_dev->dev, "%s. CheckSum Fail.bin_num=%d, CheckSum:0x%x, SumData:0x%x", 46 __func__, bin_num, check_sum, sum_data); 47 return -EINVAL; 48 } 49 50 return 0; 51 } 52 53 static int aw_check_data_version(struct aw_device *aw_dev, struct aw_bin *bin, int bin_num) 54 { 55 if (bin->header_info[bin_num].bin_data_ver < DATA_VERSION_V1 || 56 bin->header_info[bin_num].bin_data_ver > DATA_VERSION_MAX) { 57 dev_err(aw_dev->dev, "aw_bin_parse Unrecognized this bin data version\n"); 58 return -EINVAL; 59 } 60 61 return 0; 62 } 63 64 static int aw_check_register_num(struct aw_device *aw_dev, struct aw_bin *bin, int bin_num) 65 { 66 struct bin_header_info temp_info = bin->header_info[bin_num]; 67 unsigned int check_register_num, parse_register_num; 68 unsigned char *p_check_sum; 69 70 p_check_sum = &(bin->info.data[(temp_info.valid_data_addr)]); 71 72 parse_register_num = le32_to_cpup((void *)p_check_sum); 73 check_register_num = (bin->header_info[bin_num].bin_data_len - CHECK_REGISTER_NUM_OFFSET) / 74 (bin->header_info[bin_num].reg_byte_len + 75 bin->header_info[bin_num].data_byte_len); 76 dev_dbg(aw_dev->dev, "%s,parse_register_num = 0x%x,check_register_num = 0x%x\n", 77 __func__, parse_register_num, check_register_num); 78 if (parse_register_num != check_register_num) { 79 dev_err(aw_dev->dev, "%s parse_register_num = 0x%x,check_register_num = 0x%x\n", 80 __func__, parse_register_num, check_register_num); 81 return -EINVAL; 82 } 83 84 bin->header_info[bin_num].reg_num = parse_register_num; 85 bin->header_info[bin_num].valid_data_len = temp_info.bin_data_len - VALID_DATA_LEN; 86 bin->header_info[bin_num].valid_data_addr = temp_info.valid_data_addr + VALID_DATA_ADDR; 87 88 return 0; 89 } 90 91 static int aw_check_dsp_reg_num(struct aw_device *aw_dev, struct aw_bin *bin, int bin_num) 92 { 93 struct bin_header_info temp_info = bin->header_info[bin_num]; 94 unsigned int check_dsp_reg_num, parse_dsp_reg_num; 95 unsigned char *p_check_sum; 96 97 p_check_sum = &(bin->info.data[(temp_info.valid_data_addr)]); 98 99 parse_dsp_reg_num = le32_to_cpup((void *)(p_check_sum + PARSE_DSP_REG_NUM)); 100 bin->header_info[bin_num].reg_data_byte_len = 101 le32_to_cpup((void *)(p_check_sum + REG_DATA_BYTP_LEN)); 102 check_dsp_reg_num = (bin->header_info[bin_num].bin_data_len - CHECK_DSP_REG_NUM) / 103 bin->header_info[bin_num].reg_data_byte_len; 104 dev_dbg(aw_dev->dev, "%s bin_num = %d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x", 105 __func__, bin_num, check_dsp_reg_num, check_dsp_reg_num); 106 if (parse_dsp_reg_num != check_dsp_reg_num) { 107 dev_err(aw_dev->dev, "aw_bin_parse check dsp reg num error\n"); 108 dev_err(aw_dev->dev, "%s parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x", 109 __func__, check_dsp_reg_num, check_dsp_reg_num); 110 return -EINVAL; 111 } 112 113 bin->header_info[bin_num].download_addr = le32_to_cpup((void *)p_check_sum); 114 bin->header_info[bin_num].reg_num = parse_dsp_reg_num; 115 bin->header_info[bin_num].valid_data_len = temp_info.bin_data_len - DSP_VALID_DATA_LEN; 116 bin->header_info[bin_num].valid_data_addr = temp_info.valid_data_addr + 117 DSP_VALID_DATA_ADDR; 118 119 return 0; 120 } 121 122 static int aw_check_soc_app_num(struct aw_device *aw_dev, struct aw_bin *bin, int bin_num) 123 { 124 struct bin_header_info temp_info = bin->header_info[bin_num]; 125 unsigned int check_soc_app_num, parse_soc_app_num; 126 unsigned char *p_check_sum; 127 128 p_check_sum = &(bin->info.data[(temp_info.valid_data_addr)]); 129 130 bin->header_info[bin_num].app_version = le32_to_cpup((void *)p_check_sum); 131 parse_soc_app_num = le32_to_cpup((void *)(p_check_sum + PARSE_SOC_APP_NUM)); 132 check_soc_app_num = bin->header_info[bin_num].bin_data_len - CHECK_SOC_APP_NUM; 133 dev_dbg(aw_dev->dev, "%s bin_num = %d, parse_soc_app_num=0x%x, check_soc_app_num = 0x%x\n", 134 __func__, bin_num, parse_soc_app_num, check_soc_app_num); 135 if (parse_soc_app_num != check_soc_app_num) { 136 dev_err(aw_dev->dev, "%s parse_soc_app_num=0x%x, check_soc_app_num = 0x%x\n", 137 __func__, parse_soc_app_num, check_soc_app_num); 138 return -EINVAL; 139 } 140 141 bin->header_info[bin_num].reg_num = parse_soc_app_num; 142 bin->header_info[bin_num].download_addr = le32_to_cpup((void *)(p_check_sum + 143 APP_DOWNLOAD_ADDR)); 144 bin->header_info[bin_num].valid_data_len = temp_info.bin_data_len - APP_VALID_DATA_LEN; 145 bin->header_info[bin_num].valid_data_addr = temp_info.valid_data_addr + 146 APP_VALID_DATA_ADDR; 147 148 return 0; 149 } 150 151 static void aw_get_single_bin_header(struct aw_bin *bin) 152 { 153 memcpy((void *)&bin->header_info[bin->all_bin_parse_num], bin->p_addr, DATA_LEN); 154 155 bin->header_info[bin->all_bin_parse_num].header_len = HEADER_LEN; 156 bin->all_bin_parse_num += 1; 157 } 158 159 static int aw_parse_one_of_multi_bins(struct aw_device *aw_dev, unsigned int bin_num, 160 int bin_serial_num, struct aw_bin *bin) 161 { 162 struct bin_header_info aw_bin_header_info; 163 unsigned int bin_start_addr; 164 unsigned int valid_data_len; 165 166 if (bin->info.len < sizeof(struct bin_header_info)) { 167 dev_err(aw_dev->dev, "bin_header_info size[%d] overflow file size[%d]\n", 168 (int)sizeof(struct bin_header_info), bin->info.len); 169 return -EINVAL; 170 } 171 172 aw_bin_header_info = bin->header_info[bin->all_bin_parse_num - 1]; 173 if (!bin_serial_num) { 174 bin_start_addr = le32_to_cpup((void *)(bin->p_addr + START_ADDR_OFFSET)); 175 bin->p_addr += (HEADER_LEN + bin_start_addr); 176 bin->header_info[bin->all_bin_parse_num].valid_data_addr = 177 aw_bin_header_info.valid_data_addr + VALID_DATA_ADDR + 8 * bin_num + 178 VALID_DATA_ADDR_OFFSET; 179 } else { 180 valid_data_len = aw_bin_header_info.bin_data_len; 181 bin->p_addr += (HDADER_LEN + valid_data_len); 182 bin->header_info[bin->all_bin_parse_num].valid_data_addr = 183 aw_bin_header_info.valid_data_addr + aw_bin_header_info.bin_data_len + 184 VALID_DATA_ADDR_OFFSET; 185 } 186 187 return aw_parse_bin_header(aw_dev, bin); 188 } 189 190 static int aw_get_multi_bin_header(struct aw_device *aw_dev, struct aw_bin *bin) 191 { 192 unsigned int bin_num, i; 193 int ret; 194 195 bin_num = le32_to_cpup((void *)(bin->p_addr + VALID_DATA_ADDR_OFFSET)); 196 if (bin->multi_bin_parse_num == 1) 197 bin->header_info[bin->all_bin_parse_num].valid_data_addr = 198 VALID_DATA_ADDR_OFFSET; 199 200 aw_get_single_bin_header(bin); 201 202 for (i = 0; i < bin_num; i++) { 203 dev_dbg(aw_dev->dev, "aw_bin_parse enter multi bin for is %d\n", i); 204 ret = aw_parse_one_of_multi_bins(aw_dev, bin_num, i, bin); 205 if (ret < 0) 206 return ret; 207 } 208 209 return 0; 210 } 211 212 static int aw_parse_bin_header(struct aw_device *aw_dev, struct aw_bin *bin) 213 { 214 unsigned int bin_data_type; 215 216 if (bin->info.len < sizeof(struct bin_header_info)) { 217 dev_err(aw_dev->dev, "bin_header_info size[%d] overflow file size[%d]\n", 218 (int)sizeof(struct bin_header_info), bin->info.len); 219 return -EINVAL; 220 } 221 222 bin_data_type = le32_to_cpup((void *)(bin->p_addr + BIN_DATA_TYPE_OFFSET)); 223 dev_dbg(aw_dev->dev, "aw_bin_parse bin_data_type 0x%x\n", bin_data_type); 224 switch (bin_data_type) { 225 case DATA_TYPE_REGISTER: 226 case DATA_TYPE_DSP_REG: 227 case DATA_TYPE_SOC_APP: 228 bin->single_bin_parse_num += 1; 229 dev_dbg(aw_dev->dev, "%s bin->single_bin_parse_num is %d\n", __func__, 230 bin->single_bin_parse_num); 231 if (!bin->multi_bin_parse_num) 232 bin->header_info[bin->all_bin_parse_num].valid_data_addr = 233 VALID_DATA_ADDR_OFFSET; 234 aw_get_single_bin_header(bin); 235 return 0; 236 case DATA_TYPE_MULTI_BINS: 237 bin->multi_bin_parse_num += 1; 238 dev_dbg(aw_dev->dev, "%s bin->multi_bin_parse_num is %d\n", __func__, 239 bin->multi_bin_parse_num); 240 return aw_get_multi_bin_header(aw_dev, bin); 241 default: 242 dev_dbg(aw_dev->dev, "%s There is no corresponding type\n", __func__); 243 return 0; 244 } 245 } 246 247 static int aw_check_bin_header_version(struct aw_device *aw_dev, struct aw_bin *bin) 248 { 249 unsigned int header_version; 250 251 header_version = le32_to_cpup((void *)(bin->p_addr + HEADER_VERSION_OFFSET)); 252 dev_dbg(aw_dev->dev, "aw_bin_parse header_version 0x%x\n", header_version); 253 254 switch (header_version) { 255 case HEADER_VERSION_V1: 256 return aw_parse_bin_header(aw_dev, bin); 257 default: 258 dev_err(aw_dev->dev, "aw_bin_parse Unrecognized this bin header version\n"); 259 return -EINVAL; 260 } 261 } 262 263 static int aw_parsing_bin_file(struct aw_device *aw_dev, struct aw_bin *bin) 264 { 265 int ret = -EINVAL; 266 int i; 267 268 if (!bin) { 269 dev_err(aw_dev->dev, "aw_bin_parse bin is NULL\n"); 270 return ret; 271 } 272 bin->p_addr = bin->info.data; 273 bin->all_bin_parse_num = 0; 274 bin->multi_bin_parse_num = 0; 275 bin->single_bin_parse_num = 0; 276 277 ret = aw_check_bin_header_version(aw_dev, bin); 278 if (ret < 0) { 279 dev_err(aw_dev->dev, "aw_bin_parse check bin header version error\n"); 280 return ret; 281 } 282 283 for (i = 0; i < bin->all_bin_parse_num; i++) { 284 ret = aw_check_sum(aw_dev, bin, i); 285 if (ret < 0) { 286 dev_err(aw_dev->dev, "aw_bin_parse check sum data error\n"); 287 return ret; 288 } 289 ret = aw_check_data_version(aw_dev, bin, i); 290 if (ret < 0) { 291 dev_err(aw_dev->dev, "aw_bin_parse check data version error\n"); 292 return ret; 293 } 294 if (bin->header_info[i].bin_data_ver == DATA_VERSION_V1) { 295 switch (bin->header_info[i].bin_data_type) { 296 case DATA_TYPE_REGISTER: 297 ret = aw_check_register_num(aw_dev, bin, i); 298 break; 299 case DATA_TYPE_DSP_REG: 300 ret = aw_check_dsp_reg_num(aw_dev, bin, i); 301 break; 302 case DATA_TYPE_SOC_APP: 303 ret = aw_check_soc_app_num(aw_dev, bin, i); 304 break; 305 default: 306 bin->header_info[i].valid_data_len = 307 bin->header_info[i].bin_data_len; 308 ret = 0; 309 break; 310 } 311 if (ret < 0) 312 return ret; 313 } 314 } 315 316 return 0; 317 } 318 319 static int aw_dev_parse_raw_reg(unsigned char *data, unsigned int data_len, 320 struct aw_prof_desc *prof_desc) 321 { 322 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data = data; 323 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len = data_len; 324 325 prof_desc->prof_st = AW88395_PROFILE_OK; 326 327 return 0; 328 } 329 330 static int aw_dev_parse_raw_dsp_cfg(unsigned char *data, unsigned int data_len, 331 struct aw_prof_desc *prof_desc) 332 { 333 if (data_len & 0x01) 334 return -EINVAL; 335 336 swab16_array((u16 *)data, data_len >> 1); 337 338 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].data = data; 339 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].len = data_len; 340 341 prof_desc->prof_st = AW88395_PROFILE_OK; 342 343 return 0; 344 } 345 346 static int aw_dev_parse_raw_dsp_fw(unsigned char *data, unsigned int data_len, 347 struct aw_prof_desc *prof_desc) 348 { 349 if (data_len & 0x01) 350 return -EINVAL; 351 352 swab16_array((u16 *)data, data_len >> 1); 353 354 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].data = data; 355 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].len = data_len; 356 357 prof_desc->prof_st = AW88395_PROFILE_OK; 358 359 return 0; 360 } 361 362 static int aw_dev_prof_parse_multi_bin(struct aw_device *aw_dev, unsigned char *data, 363 unsigned int data_len, struct aw_prof_desc *prof_desc) 364 { 365 int ret; 366 int i; 367 368 struct aw_bin *aw_bin __free(kfree) = kzalloc(data_len + sizeof(struct aw_bin), 369 GFP_KERNEL); 370 if (!aw_bin) 371 return -ENOMEM; 372 373 aw_bin->info.len = data_len; 374 memcpy(aw_bin->info.data, data, data_len); 375 376 ret = aw_parsing_bin_file(aw_dev, aw_bin); 377 if (ret < 0) { 378 dev_err(aw_dev->dev, "parse bin failed"); 379 return ret; 380 } 381 382 for (i = 0; i < aw_bin->all_bin_parse_num; i++) { 383 switch (aw_bin->header_info[i].bin_data_type) { 384 case DATA_TYPE_REGISTER: 385 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len = 386 aw_bin->header_info[i].valid_data_len; 387 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data = 388 data + aw_bin->header_info[i].valid_data_addr; 389 break; 390 case DATA_TYPE_DSP_REG: 391 if (aw_bin->header_info[i].valid_data_len & 0x01) 392 return -EINVAL; 393 394 swab16_array((u16 *)(data + aw_bin->header_info[i].valid_data_addr), 395 aw_bin->header_info[i].valid_data_len >> 1); 396 397 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].len = 398 aw_bin->header_info[i].valid_data_len; 399 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].data = 400 data + aw_bin->header_info[i].valid_data_addr; 401 break; 402 case DATA_TYPE_DSP_FW: 403 case DATA_TYPE_SOC_APP: 404 if (aw_bin->header_info[i].valid_data_len & 0x01) 405 return -EINVAL; 406 407 swab16_array((u16 *)(data + aw_bin->header_info[i].valid_data_addr), 408 aw_bin->header_info[i].valid_data_len >> 1); 409 410 prof_desc->fw_ver = aw_bin->header_info[i].app_version; 411 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].len = 412 aw_bin->header_info[i].valid_data_len; 413 prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].data = 414 data + aw_bin->header_info[i].valid_data_addr; 415 break; 416 default: 417 dev_dbg(aw_dev->dev, "bin_data_type not found"); 418 break; 419 } 420 } 421 prof_desc->prof_st = AW88395_PROFILE_OK; 422 423 return 0; 424 } 425 426 static int aw_dev_parse_reg_bin_with_hdr(struct aw_device *aw_dev, 427 uint8_t *data, uint32_t data_len, struct aw_prof_desc *prof_desc) 428 { 429 int ret; 430 431 struct aw_bin *aw_bin __free(kfree) = kzalloc(data_len + sizeof(*aw_bin), 432 GFP_KERNEL); 433 if (!aw_bin) 434 return -ENOMEM; 435 436 aw_bin->info.len = data_len; 437 memcpy(aw_bin->info.data, data, data_len); 438 439 ret = aw_parsing_bin_file(aw_dev, aw_bin); 440 if (ret < 0) { 441 dev_err(aw_dev->dev, "parse bin failed"); 442 return ret; 443 } 444 445 if ((aw_bin->all_bin_parse_num != 1) || 446 (aw_bin->header_info[0].bin_data_type != DATA_TYPE_REGISTER)) { 447 dev_err(aw_dev->dev, "bin num or type error"); 448 return -EINVAL; 449 } 450 451 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data = 452 data + aw_bin->header_info[0].valid_data_addr; 453 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len = 454 aw_bin->header_info[0].valid_data_len; 455 prof_desc->prof_st = AW88395_PROFILE_OK; 456 457 return 0; 458 } 459 460 static int aw_dev_parse_data_by_sec_type(struct aw_device *aw_dev, struct aw_cfg_hdr *cfg_hdr, 461 struct aw_cfg_dde *cfg_dde, struct aw_prof_desc *scene_prof_desc) 462 { 463 switch (cfg_dde->data_type) { 464 case ACF_SEC_TYPE_REG: 465 return aw_dev_parse_raw_reg((u8 *)cfg_hdr + cfg_dde->data_offset, 466 cfg_dde->data_size, scene_prof_desc); 467 case ACF_SEC_TYPE_DSP_CFG: 468 return aw_dev_parse_raw_dsp_cfg((u8 *)cfg_hdr + cfg_dde->data_offset, 469 cfg_dde->data_size, scene_prof_desc); 470 case ACF_SEC_TYPE_DSP_FW: 471 return aw_dev_parse_raw_dsp_fw( 472 (u8 *)cfg_hdr + cfg_dde->data_offset, 473 cfg_dde->data_size, scene_prof_desc); 474 case ACF_SEC_TYPE_MULTIPLE_BIN: 475 return aw_dev_prof_parse_multi_bin( 476 aw_dev, (u8 *)cfg_hdr + cfg_dde->data_offset, 477 cfg_dde->data_size, scene_prof_desc); 478 case ACF_SEC_TYPE_HDR_REG: 479 return aw_dev_parse_reg_bin_with_hdr(aw_dev, (u8 *)cfg_hdr + cfg_dde->data_offset, 480 cfg_dde->data_size, scene_prof_desc); 481 default: 482 dev_err(aw_dev->dev, "%s cfg_dde->data_type = %d\n", __func__, cfg_dde->data_type); 483 break; 484 } 485 486 return 0; 487 } 488 489 static int aw_dev_parse_dev_type(struct aw_device *aw_dev, 490 struct aw_cfg_hdr *prof_hdr, struct aw_all_prof_info *all_prof_info) 491 { 492 struct aw_cfg_dde *cfg_dde = 493 (struct aw_cfg_dde *)((char *)prof_hdr + prof_hdr->hdr_offset); 494 int sec_num = 0; 495 int ret, i; 496 497 for (i = 0; i < prof_hdr->ddt_num; i++) { 498 if ((aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) && 499 (aw_dev->i2c->addr == cfg_dde[i].dev_addr) && 500 (cfg_dde[i].type == AW88395_DEV_TYPE_ID) && 501 (cfg_dde[i].data_type != ACF_SEC_TYPE_MONITOR)) { 502 if (cfg_dde[i].dev_profile >= AW88395_PROFILE_MAX) { 503 dev_err(aw_dev->dev, "dev_profile [%d] overflow", 504 cfg_dde[i].dev_profile); 505 return -EINVAL; 506 } 507 aw_dev->prof_data_type = cfg_dde[i].data_type; 508 ret = aw_dev_parse_data_by_sec_type(aw_dev, prof_hdr, &cfg_dde[i], 509 &all_prof_info->prof_desc[cfg_dde[i].dev_profile]); 510 if (ret < 0) { 511 dev_err(aw_dev->dev, "parse failed"); 512 return ret; 513 } 514 sec_num++; 515 } 516 } 517 518 if (sec_num == 0) { 519 dev_dbg(aw_dev->dev, "get dev type num is %d, please use default", sec_num); 520 return AW88395_DEV_TYPE_NONE; 521 } 522 523 return AW88395_DEV_TYPE_OK; 524 } 525 526 static int aw_dev_parse_dev_default_type(struct aw_device *aw_dev, 527 struct aw_cfg_hdr *prof_hdr, struct aw_all_prof_info *all_prof_info) 528 { 529 struct aw_cfg_dde *cfg_dde = 530 (struct aw_cfg_dde *)((char *)prof_hdr + prof_hdr->hdr_offset); 531 int sec_num = 0; 532 int ret, i; 533 534 for (i = 0; i < prof_hdr->ddt_num; i++) { 535 if ((aw_dev->channel == cfg_dde[i].dev_index) && 536 (cfg_dde[i].type == AW88395_DEV_DEFAULT_TYPE_ID) && 537 (cfg_dde[i].data_type != ACF_SEC_TYPE_MONITOR)) { 538 if (cfg_dde[i].dev_profile >= AW88395_PROFILE_MAX) { 539 dev_err(aw_dev->dev, "dev_profile [%d] overflow", 540 cfg_dde[i].dev_profile); 541 return -EINVAL; 542 } 543 aw_dev->prof_data_type = cfg_dde[i].data_type; 544 ret = aw_dev_parse_data_by_sec_type(aw_dev, prof_hdr, &cfg_dde[i], 545 &all_prof_info->prof_desc[cfg_dde[i].dev_profile]); 546 if (ret < 0) { 547 dev_err(aw_dev->dev, "parse failed"); 548 return ret; 549 } 550 sec_num++; 551 } 552 } 553 554 if (sec_num == 0) { 555 dev_err(aw_dev->dev, "get dev default type failed, get num[%d]", sec_num); 556 return -EINVAL; 557 } 558 559 return 0; 560 } 561 562 static int aw_dev_cfg_get_reg_valid_prof(struct aw_device *aw_dev, 563 struct aw_all_prof_info *all_prof_info) 564 { 565 struct aw_prof_desc *prof_desc = all_prof_info->prof_desc; 566 struct aw_prof_info *prof_info = &aw_dev->prof_info; 567 int num = 0; 568 int i; 569 570 for (i = 0; i < AW88395_PROFILE_MAX; i++) { 571 if (prof_desc[i].prof_st == AW88395_PROFILE_OK) 572 prof_info->count++; 573 } 574 575 dev_dbg(aw_dev->dev, "get valid profile:%d", aw_dev->prof_info.count); 576 577 if (!prof_info->count) { 578 dev_err(aw_dev->dev, "no profile data"); 579 return -EPERM; 580 } 581 582 prof_info->prof_desc = devm_kcalloc(aw_dev->dev, 583 prof_info->count, sizeof(struct aw_prof_desc), 584 GFP_KERNEL); 585 if (!prof_info->prof_desc) 586 return -ENOMEM; 587 588 for (i = 0; i < AW88395_PROFILE_MAX; i++) { 589 if (prof_desc[i].prof_st == AW88395_PROFILE_OK) { 590 if (num >= prof_info->count) { 591 dev_err(aw_dev->dev, "overflow count[%d]", 592 prof_info->count); 593 return -EINVAL; 594 } 595 prof_info->prof_desc[num] = prof_desc[i]; 596 prof_info->prof_desc[num].id = i; 597 num++; 598 } 599 } 600 601 return 0; 602 } 603 604 static int aw_dev_cfg_get_multiple_valid_prof(struct aw_device *aw_dev, 605 struct aw_all_prof_info *all_prof_info) 606 { 607 struct aw_prof_desc *prof_desc = all_prof_info->prof_desc; 608 struct aw_prof_info *prof_info = &aw_dev->prof_info; 609 struct aw_sec_data_desc *sec_desc; 610 int num = 0; 611 int i; 612 613 for (i = 0; i < AW88395_PROFILE_MAX; i++) { 614 if (prof_desc[i].prof_st == AW88395_PROFILE_OK) { 615 sec_desc = prof_desc[i].sec_desc; 616 if ((sec_desc[AW88395_DATA_TYPE_REG].data != NULL) && 617 (sec_desc[AW88395_DATA_TYPE_REG].len != 0) && 618 (sec_desc[AW88395_DATA_TYPE_DSP_CFG].data != NULL) && 619 (sec_desc[AW88395_DATA_TYPE_DSP_CFG].len != 0) && 620 (sec_desc[AW88395_DATA_TYPE_DSP_FW].data != NULL) && 621 (sec_desc[AW88395_DATA_TYPE_DSP_FW].len != 0)) 622 prof_info->count++; 623 } 624 } 625 626 dev_dbg(aw_dev->dev, "get valid profile:%d", aw_dev->prof_info.count); 627 628 if (!prof_info->count) { 629 dev_err(aw_dev->dev, "no profile data"); 630 return -EPERM; 631 } 632 633 prof_info->prof_desc = devm_kcalloc(aw_dev->dev, 634 prof_info->count, sizeof(struct aw_prof_desc), 635 GFP_KERNEL); 636 if (!prof_info->prof_desc) 637 return -ENOMEM; 638 639 for (i = 0; i < AW88395_PROFILE_MAX; i++) { 640 if (prof_desc[i].prof_st == AW88395_PROFILE_OK) { 641 sec_desc = prof_desc[i].sec_desc; 642 if ((sec_desc[AW88395_DATA_TYPE_REG].data != NULL) && 643 (sec_desc[AW88395_DATA_TYPE_REG].len != 0) && 644 (sec_desc[AW88395_DATA_TYPE_DSP_CFG].data != NULL) && 645 (sec_desc[AW88395_DATA_TYPE_DSP_CFG].len != 0) && 646 (sec_desc[AW88395_DATA_TYPE_DSP_FW].data != NULL) && 647 (sec_desc[AW88395_DATA_TYPE_DSP_FW].len != 0)) { 648 if (num >= prof_info->count) { 649 dev_err(aw_dev->dev, "overflow count[%d]", 650 prof_info->count); 651 return -EINVAL; 652 } 653 prof_info->prof_desc[num] = prof_desc[i]; 654 prof_info->prof_desc[num].id = i; 655 num++; 656 } 657 } 658 } 659 660 return 0; 661 } 662 663 static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_dev, 664 struct aw_cfg_hdr *prof_hdr) 665 { 666 int ret; 667 668 struct aw_all_prof_info *all_prof_info __free(kfree) = kzalloc(sizeof(*all_prof_info), 669 GFP_KERNEL); 670 if (!all_prof_info) 671 return -ENOMEM; 672 673 ret = aw_dev_parse_dev_type(aw_dev, prof_hdr, all_prof_info); 674 if (ret < 0) { 675 return ret; 676 } else if (ret == AW88395_DEV_TYPE_NONE) { 677 dev_dbg(aw_dev->dev, "get dev type num is 0, parse default dev"); 678 ret = aw_dev_parse_dev_default_type(aw_dev, prof_hdr, all_prof_info); 679 if (ret < 0) 680 return ret; 681 } 682 683 switch (aw_dev->prof_data_type) { 684 case ACF_SEC_TYPE_MULTIPLE_BIN: 685 ret = aw_dev_cfg_get_multiple_valid_prof(aw_dev, all_prof_info); 686 break; 687 case ACF_SEC_TYPE_HDR_REG: 688 ret = aw_dev_cfg_get_reg_valid_prof(aw_dev, all_prof_info); 689 break; 690 default: 691 dev_err(aw_dev->dev, "unsupport data type\n"); 692 ret = -EINVAL; 693 break; 694 } 695 if (!ret) 696 aw_dev->prof_info.prof_name_list = profile_name; 697 698 return ret; 699 } 700 701 static int aw_dev_create_prof_name_list_v1(struct aw_device *aw_dev) 702 { 703 struct aw_prof_info *prof_info = &aw_dev->prof_info; 704 struct aw_prof_desc *prof_desc = prof_info->prof_desc; 705 int i; 706 707 if (!prof_desc) { 708 dev_err(aw_dev->dev, "prof_desc is NULL"); 709 return -EINVAL; 710 } 711 712 prof_info->prof_name_list = devm_kzalloc(aw_dev->dev, 713 prof_info->count * PROFILE_STR_MAX, 714 GFP_KERNEL); 715 if (!prof_info->prof_name_list) 716 return -ENOMEM; 717 718 for (i = 0; i < prof_info->count; i++) { 719 prof_desc[i].id = i; 720 prof_info->prof_name_list[i] = prof_desc[i].prf_str; 721 dev_dbg(aw_dev->dev, "prof name is %s", prof_info->prof_name_list[i]); 722 } 723 724 return 0; 725 } 726 727 static int aw_get_dde_type_info(struct aw_device *aw_dev, struct aw_container *aw_cfg) 728 { 729 struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 730 struct aw_cfg_dde_v1 *cfg_dde = 731 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset); 732 int default_num = 0; 733 int dev_num = 0; 734 unsigned int i; 735 736 for (i = 0; i < cfg_hdr->ddt_num; i++) { 737 if (cfg_dde[i].type == AW88395_DEV_TYPE_ID) 738 dev_num++; 739 740 if (cfg_dde[i].type == AW88395_DEV_DEFAULT_TYPE_ID) 741 default_num++; 742 } 743 744 if (dev_num != 0) { 745 aw_dev->prof_info.prof_type = AW88395_DEV_TYPE_ID; 746 } else if (default_num != 0) { 747 aw_dev->prof_info.prof_type = AW88395_DEV_DEFAULT_TYPE_ID; 748 } else { 749 dev_err(aw_dev->dev, "can't find scene"); 750 return -EINVAL; 751 } 752 753 return 0; 754 } 755 756 static int aw_get_dev_scene_count_v1(struct aw_device *aw_dev, struct aw_container *aw_cfg, 757 unsigned int *scene_num) 758 { 759 struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 760 struct aw_cfg_dde_v1 *cfg_dde = 761 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset); 762 unsigned int i; 763 764 for (i = 0; i < cfg_hdr->ddt_num; ++i) { 765 if (((cfg_dde[i].data_type == ACF_SEC_TYPE_REG) || 766 (cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG) || 767 (cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN)) && 768 (aw_dev->chip_id == cfg_dde[i].chip_id) && 769 (aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) && 770 (aw_dev->i2c->addr == cfg_dde[i].dev_addr)) 771 (*scene_num)++; 772 } 773 774 if ((*scene_num) == 0) { 775 dev_err(aw_dev->dev, "failed to obtain scene, scenu_num = %d\n", (*scene_num)); 776 return -EINVAL; 777 } 778 779 return 0; 780 } 781 782 static int aw_get_default_scene_count_v1(struct aw_device *aw_dev, 783 struct aw_container *aw_cfg, 784 unsigned int *scene_num) 785 { 786 struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 787 struct aw_cfg_dde_v1 *cfg_dde = 788 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset); 789 unsigned int i; 790 791 792 for (i = 0; i < cfg_hdr->ddt_num; ++i) { 793 if (((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) || 794 (cfg_dde[i].data_type == ACF_SEC_TYPE_REG) || 795 (cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG)) && 796 (aw_dev->chip_id == cfg_dde[i].chip_id) && 797 (aw_dev->channel == cfg_dde[i].dev_index)) 798 (*scene_num)++; 799 } 800 801 if ((*scene_num) == 0) { 802 dev_err(aw_dev->dev, "failed to obtain scene, scenu_num = %d\n", (*scene_num)); 803 return -EINVAL; 804 } 805 806 return 0; 807 } 808 809 static int aw_dev_parse_scene_count_v1(struct aw_device *aw_dev, 810 struct aw_container *aw_cfg, 811 unsigned int *count) 812 { 813 int ret; 814 815 ret = aw_get_dde_type_info(aw_dev, aw_cfg); 816 if (ret < 0) 817 return ret; 818 819 switch (aw_dev->prof_info.prof_type) { 820 case AW88395_DEV_TYPE_ID: 821 ret = aw_get_dev_scene_count_v1(aw_dev, aw_cfg, count); 822 break; 823 case AW88395_DEV_DEFAULT_TYPE_ID: 824 ret = aw_get_default_scene_count_v1(aw_dev, aw_cfg, count); 825 break; 826 default: 827 dev_err(aw_dev->dev, "unsupported prof_type[%x]", aw_dev->prof_info.prof_type); 828 ret = -EINVAL; 829 break; 830 } 831 832 return ret; 833 } 834 835 static int aw_dev_parse_data_by_sec_type_v1(struct aw_device *aw_dev, 836 struct aw_cfg_hdr *prof_hdr, 837 struct aw_cfg_dde_v1 *cfg_dde, 838 int *cur_scene_id) 839 { 840 struct aw_prof_info *prof_info = &aw_dev->prof_info; 841 int ret; 842 843 switch (cfg_dde->data_type) { 844 case ACF_SEC_TYPE_MULTIPLE_BIN: 845 ret = aw_dev_prof_parse_multi_bin(aw_dev, (u8 *)prof_hdr + cfg_dde->data_offset, 846 cfg_dde->data_size, &prof_info->prof_desc[*cur_scene_id]); 847 if (ret < 0) { 848 dev_err(aw_dev->dev, "parse multi bin failed"); 849 return ret; 850 } 851 prof_info->prof_desc[*cur_scene_id].prf_str = cfg_dde->dev_profile_str; 852 prof_info->prof_desc[*cur_scene_id].id = cfg_dde->dev_profile; 853 (*cur_scene_id)++; 854 break; 855 case ACF_SEC_TYPE_HDR_REG: 856 ret = aw_dev_parse_reg_bin_with_hdr(aw_dev, 857 (uint8_t *)prof_hdr + cfg_dde->data_offset, 858 cfg_dde->data_size, &prof_info->prof_desc[*cur_scene_id]); 859 if (ret < 0) { 860 dev_err(aw_dev->dev, "parse reg bin with hdr failed"); 861 return ret; 862 } 863 prof_info->prof_desc[*cur_scene_id].prf_str = cfg_dde->dev_profile_str; 864 prof_info->prof_desc[*cur_scene_id].id = cfg_dde->dev_profile; 865 (*cur_scene_id)++; 866 break; 867 default: 868 dev_err(aw_dev->dev, "unsupported SEC_TYPE [%d]", cfg_dde->data_type); 869 return -EINVAL; 870 } 871 872 return 0; 873 } 874 875 static int aw_dev_parse_dev_type_v1(struct aw_device *aw_dev, 876 struct aw_cfg_hdr *prof_hdr) 877 { 878 struct aw_cfg_dde_v1 *cfg_dde = 879 (struct aw_cfg_dde_v1 *)((char *)prof_hdr + prof_hdr->hdr_offset); 880 int cur_scene_id = 0; 881 unsigned int i; 882 int ret; 883 884 for (i = 0; i < prof_hdr->ddt_num; i++) { 885 if ((aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) && 886 (aw_dev->i2c->addr == cfg_dde[i].dev_addr) && 887 (aw_dev->chip_id == cfg_dde[i].chip_id)) { 888 ret = aw_dev_parse_data_by_sec_type_v1(aw_dev, prof_hdr, 889 &cfg_dde[i], &cur_scene_id); 890 if (ret < 0) { 891 dev_err(aw_dev->dev, "parse failed"); 892 return ret; 893 } 894 } 895 } 896 897 if (cur_scene_id == 0) { 898 dev_err(aw_dev->dev, "get dev type failed, get num [%d]", cur_scene_id); 899 return -EINVAL; 900 } 901 902 return 0; 903 } 904 905 static int aw_dev_parse_default_type_v1(struct aw_device *aw_dev, 906 struct aw_cfg_hdr *prof_hdr) 907 { 908 struct aw_cfg_dde_v1 *cfg_dde = 909 (struct aw_cfg_dde_v1 *)((char *)prof_hdr + prof_hdr->hdr_offset); 910 int cur_scene_id = 0; 911 unsigned int i; 912 int ret; 913 914 for (i = 0; i < prof_hdr->ddt_num; i++) { 915 if ((aw_dev->channel == cfg_dde[i].dev_index) && 916 (aw_dev->chip_id == cfg_dde[i].chip_id)) { 917 ret = aw_dev_parse_data_by_sec_type_v1(aw_dev, prof_hdr, 918 &cfg_dde[i], &cur_scene_id); 919 if (ret < 0) { 920 dev_err(aw_dev->dev, "parse failed"); 921 return ret; 922 } 923 } 924 } 925 926 if (cur_scene_id == 0) { 927 dev_err(aw_dev->dev, "get dev default type failed, get num[%d]", cur_scene_id); 928 return -EINVAL; 929 } 930 931 return 0; 932 } 933 934 static int aw_dev_parse_by_hdr_v1(struct aw_device *aw_dev, 935 struct aw_cfg_hdr *cfg_hdr) 936 { 937 int ret; 938 939 switch (aw_dev->prof_info.prof_type) { 940 case AW88395_DEV_TYPE_ID: 941 ret = aw_dev_parse_dev_type_v1(aw_dev, cfg_hdr); 942 break; 943 case AW88395_DEV_DEFAULT_TYPE_ID: 944 ret = aw_dev_parse_default_type_v1(aw_dev, cfg_hdr); 945 break; 946 default: 947 dev_err(aw_dev->dev, "prof type matched failed, get num[%d]", 948 aw_dev->prof_info.prof_type); 949 ret = -EINVAL; 950 break; 951 } 952 953 return ret; 954 } 955 956 static int aw_dev_load_cfg_by_hdr_v1(struct aw_device *aw_dev, 957 struct aw_container *aw_cfg) 958 { 959 struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 960 struct aw_prof_info *prof_info = &aw_dev->prof_info; 961 int ret; 962 963 ret = aw_dev_parse_scene_count_v1(aw_dev, aw_cfg, &prof_info->count); 964 if (ret < 0) { 965 dev_err(aw_dev->dev, "get scene count failed"); 966 return ret; 967 } 968 969 prof_info->prof_desc = devm_kcalloc(aw_dev->dev, 970 prof_info->count, sizeof(struct aw_prof_desc), 971 GFP_KERNEL); 972 if (!prof_info->prof_desc) 973 return -ENOMEM; 974 975 ret = aw_dev_parse_by_hdr_v1(aw_dev, cfg_hdr); 976 if (ret < 0) { 977 dev_err(aw_dev->dev, "parse hdr failed"); 978 return ret; 979 } 980 981 ret = aw_dev_create_prof_name_list_v1(aw_dev); 982 if (ret < 0) { 983 dev_err(aw_dev->dev, "create prof name list failed"); 984 return ret; 985 } 986 987 return 0; 988 } 989 990 int aw88395_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg) 991 { 992 struct aw_cfg_hdr *cfg_hdr; 993 int ret; 994 995 cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 996 997 switch (cfg_hdr->hdr_version) { 998 case AW88395_CFG_HDR_VER: 999 ret = aw_dev_load_cfg_by_hdr(aw_dev, cfg_hdr); 1000 if (ret < 0) { 1001 dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed", 1002 cfg_hdr->hdr_version); 1003 return ret; 1004 } 1005 break; 1006 case AW88395_CFG_HDR_VER_V1: 1007 ret = aw_dev_load_cfg_by_hdr_v1(aw_dev, aw_cfg); 1008 if (ret < 0) { 1009 dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed", 1010 cfg_hdr->hdr_version); 1011 return ret; 1012 } 1013 break; 1014 default: 1015 dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_version); 1016 return -EINVAL; 1017 } 1018 aw_dev->fw_status = AW88395_DEV_FW_OK; 1019 1020 return 0; 1021 } 1022 EXPORT_SYMBOL_GPL(aw88395_dev_cfg_load); 1023 1024 static int aw_dev_check_cfg_by_hdr(struct aw_device *aw_dev, struct aw_container *aw_cfg) 1025 { 1026 unsigned int end_data_offset; 1027 struct aw_cfg_hdr *cfg_hdr; 1028 struct aw_cfg_dde *cfg_dde; 1029 unsigned int act_data = 0; 1030 unsigned int hdr_ddt_len; 1031 unsigned int i; 1032 u8 act_crc8; 1033 1034 cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 1035 /* check file type id is awinic acf file */ 1036 if (cfg_hdr->id != ACF_FILE_ID) { 1037 dev_err(aw_dev->dev, "not acf type file"); 1038 return -EINVAL; 1039 } 1040 1041 hdr_ddt_len = cfg_hdr->hdr_offset + cfg_hdr->ddt_size; 1042 if (hdr_ddt_len > aw_cfg->len) { 1043 dev_err(aw_dev->dev, "hdr_len with ddt_len [%d] overflow file size[%d]", 1044 cfg_hdr->hdr_offset, aw_cfg->len); 1045 return -EINVAL; 1046 } 1047 1048 /* check data size */ 1049 cfg_dde = (struct aw_cfg_dde *)((char *)aw_cfg->data + cfg_hdr->hdr_offset); 1050 act_data += hdr_ddt_len; 1051 for (i = 0; i < cfg_hdr->ddt_num; i++) 1052 act_data += cfg_dde[i].data_size; 1053 1054 if (act_data != aw_cfg->len) { 1055 dev_err(aw_dev->dev, "act_data[%d] not equal to file size[%d]!", 1056 act_data, aw_cfg->len); 1057 return -EINVAL; 1058 } 1059 1060 for (i = 0; i < cfg_hdr->ddt_num; i++) { 1061 /* data check */ 1062 end_data_offset = cfg_dde[i].data_offset + cfg_dde[i].data_size; 1063 if (end_data_offset > aw_cfg->len) { 1064 dev_err(aw_dev->dev, "ddt_num[%d] end_data_offset[%d] overflow size[%d]", 1065 i, end_data_offset, aw_cfg->len); 1066 return -EINVAL; 1067 } 1068 1069 /* crc check */ 1070 act_crc8 = crc8(aw_crc8_table, aw_cfg->data + cfg_dde[i].data_offset, 1071 cfg_dde[i].data_size, 0); 1072 if (act_crc8 != cfg_dde[i].data_crc) { 1073 dev_err(aw_dev->dev, "ddt_num[%d] act_crc8:0x%x != data_crc:0x%x", 1074 i, (u32)act_crc8, cfg_dde[i].data_crc); 1075 return -EINVAL; 1076 } 1077 } 1078 1079 return 0; 1080 } 1081 1082 static int aw_dev_check_acf_by_hdr_v1(struct aw_device *aw_dev, struct aw_container *aw_cfg) 1083 { 1084 struct aw_cfg_dde_v1 *cfg_dde; 1085 unsigned int end_data_offset; 1086 struct aw_cfg_hdr *cfg_hdr; 1087 unsigned int act_data = 0; 1088 unsigned int hdr_ddt_len; 1089 u8 act_crc8; 1090 int i; 1091 1092 cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 1093 1094 /* check file type id is awinic acf file */ 1095 if (cfg_hdr->id != ACF_FILE_ID) { 1096 dev_err(aw_dev->dev, "not acf type file"); 1097 return -EINVAL; 1098 } 1099 1100 hdr_ddt_len = cfg_hdr->hdr_offset + cfg_hdr->ddt_size; 1101 if (hdr_ddt_len > aw_cfg->len) { 1102 dev_err(aw_dev->dev, "hdrlen with ddt_len [%d] overflow file size[%d]", 1103 cfg_hdr->hdr_offset, aw_cfg->len); 1104 return -EINVAL; 1105 } 1106 1107 /* check data size */ 1108 cfg_dde = (struct aw_cfg_dde_v1 *)((char *)aw_cfg->data + cfg_hdr->hdr_offset); 1109 act_data += hdr_ddt_len; 1110 for (i = 0; i < cfg_hdr->ddt_num; i++) 1111 act_data += cfg_dde[i].data_size; 1112 1113 if (act_data != aw_cfg->len) { 1114 dev_err(aw_dev->dev, "act_data[%d] not equal to file size[%d]!", 1115 act_data, aw_cfg->len); 1116 return -EINVAL; 1117 } 1118 1119 for (i = 0; i < cfg_hdr->ddt_num; i++) { 1120 /* data check */ 1121 end_data_offset = cfg_dde[i].data_offset + cfg_dde[i].data_size; 1122 if (end_data_offset > aw_cfg->len) { 1123 dev_err(aw_dev->dev, "ddt_num[%d] end_data_offset[%d] overflow size[%d]", 1124 i, end_data_offset, aw_cfg->len); 1125 return -EINVAL; 1126 } 1127 1128 /* crc check */ 1129 act_crc8 = crc8(aw_crc8_table, aw_cfg->data + cfg_dde[i].data_offset, 1130 cfg_dde[i].data_size, 0); 1131 if (act_crc8 != cfg_dde[i].data_crc) { 1132 dev_err(aw_dev->dev, "ddt_num[%d] act_crc8:0x%x != data_crc 0x%x", 1133 i, (u32)act_crc8, cfg_dde[i].data_crc); 1134 return -EINVAL; 1135 } 1136 } 1137 1138 return 0; 1139 } 1140 1141 int aw88395_dev_load_acf_check(struct aw_device *aw_dev, struct aw_container *aw_cfg) 1142 { 1143 struct aw_cfg_hdr *cfg_hdr; 1144 1145 if (!aw_cfg) { 1146 dev_err(aw_dev->dev, "aw_prof is NULL"); 1147 return -EINVAL; 1148 } 1149 1150 if (aw_cfg->len < sizeof(struct aw_cfg_hdr)) { 1151 dev_err(aw_dev->dev, "cfg hdr size[%d] overflow file size[%d]", 1152 aw_cfg->len, (int)sizeof(struct aw_cfg_hdr)); 1153 return -EINVAL; 1154 } 1155 1156 crc8_populate_lsb(aw_crc8_table, AW88395_CRC8_POLYNOMIAL); 1157 1158 cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data; 1159 switch (cfg_hdr->hdr_version) { 1160 case AW88395_CFG_HDR_VER: 1161 return aw_dev_check_cfg_by_hdr(aw_dev, aw_cfg); 1162 case AW88395_CFG_HDR_VER_V1: 1163 return aw_dev_check_acf_by_hdr_v1(aw_dev, aw_cfg); 1164 default: 1165 dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_version); 1166 return -EINVAL; 1167 } 1168 1169 return 0; 1170 } 1171 EXPORT_SYMBOL_GPL(aw88395_dev_load_acf_check); 1172 1173 MODULE_DESCRIPTION("AW88395 ACF File Parsing Lib"); 1174 MODULE_LICENSE("GPL v2"); 1175