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