xref: /linux/sound/soc/codecs/aw88395/aw88395_lib.c (revision 0526b56cbc3c489642bd6a5fe4b718dea7ef0ee8)
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_data_by_sec_type(struct aw_device *aw_dev, struct aw_cfg_hdr *cfg_hdr,
433 			struct aw_cfg_dde *cfg_dde, struct aw_prof_desc *scene_prof_desc)
434 {
435 	switch (cfg_dde->data_type) {
436 	case ACF_SEC_TYPE_REG:
437 		return aw_dev_parse_raw_reg((u8 *)cfg_hdr + cfg_dde->data_offset,
438 				cfg_dde->data_size, scene_prof_desc);
439 	case ACF_SEC_TYPE_DSP_CFG:
440 		return aw_dev_parse_raw_dsp_cfg((u8 *)cfg_hdr + cfg_dde->data_offset,
441 				cfg_dde->data_size, scene_prof_desc);
442 	case ACF_SEC_TYPE_DSP_FW:
443 		return aw_dev_parse_raw_dsp_fw(
444 				(u8 *)cfg_hdr + cfg_dde->data_offset,
445 				cfg_dde->data_size, scene_prof_desc);
446 	case ACF_SEC_TYPE_MULTIPLE_BIN:
447 		return aw_dev_prof_parse_multi_bin(
448 				aw_dev, (u8 *)cfg_hdr + cfg_dde->data_offset,
449 				cfg_dde->data_size, scene_prof_desc);
450 	default:
451 		dev_err(aw_dev->dev, "%s cfg_dde->data_type = %d\n", __func__, cfg_dde->data_type);
452 		break;
453 	}
454 
455 	return 0;
456 }
457 
458 static int aw_dev_parse_dev_type(struct aw_device *aw_dev,
459 		struct aw_cfg_hdr *prof_hdr, struct aw_all_prof_info *all_prof_info)
460 {
461 	struct aw_cfg_dde *cfg_dde =
462 		(struct aw_cfg_dde *)((char *)prof_hdr + prof_hdr->hdr_offset);
463 	int sec_num = 0;
464 	int ret, i;
465 
466 	for (i = 0; i < prof_hdr->ddt_num; i++) {
467 		if ((aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
468 		    (aw_dev->i2c->addr == cfg_dde[i].dev_addr) &&
469 		    (cfg_dde[i].type == AW88395_DEV_TYPE_ID) &&
470 		    (cfg_dde[i].data_type != ACF_SEC_TYPE_MONITOR)) {
471 			if (cfg_dde[i].dev_profile >= AW88395_PROFILE_MAX) {
472 				dev_err(aw_dev->dev, "dev_profile [%d] overflow",
473 							cfg_dde[i].dev_profile);
474 				return -EINVAL;
475 			}
476 
477 			ret = aw_dev_parse_data_by_sec_type(aw_dev, prof_hdr, &cfg_dde[i],
478 					&all_prof_info->prof_desc[cfg_dde[i].dev_profile]);
479 			if (ret < 0) {
480 				dev_err(aw_dev->dev, "parse failed");
481 				return ret;
482 			}
483 			sec_num++;
484 		}
485 	}
486 
487 	if (sec_num == 0) {
488 		dev_dbg(aw_dev->dev, "get dev type num is %d, please use default", sec_num);
489 		return AW88395_DEV_TYPE_NONE;
490 	}
491 
492 	return AW88395_DEV_TYPE_OK;
493 }
494 
495 static int aw_dev_parse_dev_default_type(struct aw_device *aw_dev,
496 		struct aw_cfg_hdr *prof_hdr, struct aw_all_prof_info *all_prof_info)
497 {
498 	struct aw_cfg_dde *cfg_dde =
499 		(struct aw_cfg_dde *)((char *)prof_hdr + prof_hdr->hdr_offset);
500 	int sec_num = 0;
501 	int ret, i;
502 
503 	for (i = 0; i < prof_hdr->ddt_num; i++) {
504 		if ((aw_dev->channel == cfg_dde[i].dev_index) &&
505 		    (cfg_dde[i].type == AW88395_DEV_DEFAULT_TYPE_ID) &&
506 		    (cfg_dde[i].data_type != ACF_SEC_TYPE_MONITOR)) {
507 			if (cfg_dde[i].dev_profile >= AW88395_PROFILE_MAX) {
508 				dev_err(aw_dev->dev, "dev_profile [%d] overflow",
509 					cfg_dde[i].dev_profile);
510 				return -EINVAL;
511 			}
512 			ret = aw_dev_parse_data_by_sec_type(aw_dev, prof_hdr, &cfg_dde[i],
513 					&all_prof_info->prof_desc[cfg_dde[i].dev_profile]);
514 			if (ret < 0) {
515 				dev_err(aw_dev->dev, "parse failed");
516 				return ret;
517 			}
518 			sec_num++;
519 		}
520 	}
521 
522 	if (sec_num == 0) {
523 		dev_err(aw_dev->dev, "get dev default type failed, get num[%d]", sec_num);
524 		return -EINVAL;
525 	}
526 
527 	return 0;
528 }
529 
530 static int aw_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
531 				struct aw_all_prof_info all_prof_info)
532 {
533 	struct aw_prof_desc *prof_desc = all_prof_info.prof_desc;
534 	struct aw_prof_info *prof_info = &aw_dev->prof_info;
535 	struct aw_sec_data_desc *sec_desc;
536 	int num = 0;
537 	int i;
538 
539 	for (i = 0; i < AW88395_PROFILE_MAX; i++) {
540 		if (prof_desc[i].prof_st == AW88395_PROFILE_OK) {
541 			sec_desc = prof_desc[i].sec_desc;
542 			if ((sec_desc[AW88395_DATA_TYPE_REG].data != NULL) &&
543 			    (sec_desc[AW88395_DATA_TYPE_REG].len != 0) &&
544 			    (sec_desc[AW88395_DATA_TYPE_DSP_CFG].data != NULL) &&
545 			    (sec_desc[AW88395_DATA_TYPE_DSP_CFG].len != 0) &&
546 			    (sec_desc[AW88395_DATA_TYPE_DSP_FW].data != NULL) &&
547 			    (sec_desc[AW88395_DATA_TYPE_DSP_FW].len != 0))
548 				prof_info->count++;
549 		}
550 	}
551 
552 	dev_dbg(aw_dev->dev, "get valid profile:%d", aw_dev->prof_info.count);
553 
554 	if (!prof_info->count) {
555 		dev_err(aw_dev->dev, "no profile data");
556 		return -EPERM;
557 	}
558 
559 	prof_info->prof_desc = devm_kcalloc(aw_dev->dev,
560 					prof_info->count, sizeof(struct aw_prof_desc),
561 					GFP_KERNEL);
562 	if (!prof_info->prof_desc)
563 		return -ENOMEM;
564 
565 	for (i = 0; i < AW88395_PROFILE_MAX; i++) {
566 		if (prof_desc[i].prof_st == AW88395_PROFILE_OK) {
567 			sec_desc = prof_desc[i].sec_desc;
568 			if ((sec_desc[AW88395_DATA_TYPE_REG].data != NULL) &&
569 			    (sec_desc[AW88395_DATA_TYPE_REG].len != 0) &&
570 			    (sec_desc[AW88395_DATA_TYPE_DSP_CFG].data != NULL) &&
571 			    (sec_desc[AW88395_DATA_TYPE_DSP_CFG].len != 0) &&
572 			    (sec_desc[AW88395_DATA_TYPE_DSP_FW].data != NULL) &&
573 			    (sec_desc[AW88395_DATA_TYPE_DSP_FW].len != 0)) {
574 				if (num >= prof_info->count) {
575 					dev_err(aw_dev->dev, "overflow count[%d]",
576 							prof_info->count);
577 					return -EINVAL;
578 				}
579 				prof_info->prof_desc[num] = prof_desc[i];
580 				prof_info->prof_desc[num].id = i;
581 				num++;
582 			}
583 		}
584 	}
585 
586 	return 0;
587 }
588 
589 static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_dev,
590 		struct aw_cfg_hdr *prof_hdr)
591 {
592 	struct aw_all_prof_info *all_prof_info;
593 	int ret;
594 
595 	all_prof_info = devm_kzalloc(aw_dev->dev, sizeof(struct aw_all_prof_info), GFP_KERNEL);
596 	if (!all_prof_info)
597 		return -ENOMEM;
598 
599 	ret = aw_dev_parse_dev_type(aw_dev, prof_hdr, all_prof_info);
600 	if (ret < 0) {
601 		goto exit;
602 	} else if (ret == AW88395_DEV_TYPE_NONE) {
603 		dev_dbg(aw_dev->dev, "get dev type num is 0, parse default dev");
604 		ret = aw_dev_parse_dev_default_type(aw_dev, prof_hdr, all_prof_info);
605 		if (ret < 0)
606 			goto exit;
607 	}
608 
609 	ret = aw_dev_cfg_get_valid_prof(aw_dev, *all_prof_info);
610 	if (ret < 0)
611 		goto exit;
612 
613 	aw_dev->prof_info.prof_name_list = profile_name;
614 
615 exit:
616 	devm_kfree(aw_dev->dev, all_prof_info);
617 	return ret;
618 }
619 
620 static int aw_dev_create_prof_name_list_v1(struct aw_device *aw_dev)
621 {
622 	struct aw_prof_info *prof_info = &aw_dev->prof_info;
623 	struct aw_prof_desc *prof_desc = prof_info->prof_desc;
624 	int i;
625 
626 	if (!prof_desc) {
627 		dev_err(aw_dev->dev, "prof_desc is NULL");
628 		return -EINVAL;
629 	}
630 
631 	prof_info->prof_name_list = devm_kzalloc(aw_dev->dev,
632 					prof_info->count * PROFILE_STR_MAX,
633 					GFP_KERNEL);
634 	if (!prof_info->prof_name_list)
635 		return -ENOMEM;
636 
637 	for (i = 0; i < prof_info->count; i++) {
638 		prof_desc[i].id = i;
639 		prof_info->prof_name_list[i] = prof_desc[i].prf_str;
640 		dev_dbg(aw_dev->dev, "prof name is %s", prof_info->prof_name_list[i]);
641 	}
642 
643 	return 0;
644 }
645 
646 static int aw_get_dde_type_info(struct aw_device *aw_dev, struct aw_container *aw_cfg)
647 {
648 	struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
649 	struct aw_cfg_dde_v1 *cfg_dde =
650 		(struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
651 	int default_num = 0;
652 	int dev_num = 0;
653 	unsigned int i;
654 
655 	for (i = 0; i < cfg_hdr->ddt_num; i++) {
656 		if (cfg_dde[i].type == AW88395_DEV_TYPE_ID)
657 			dev_num++;
658 
659 		if (cfg_dde[i].type == AW88395_DEV_DEFAULT_TYPE_ID)
660 			default_num++;
661 	}
662 
663 	if (dev_num != 0) {
664 		aw_dev->prof_info.prof_type = AW88395_DEV_TYPE_ID;
665 	} else if (default_num != 0) {
666 		aw_dev->prof_info.prof_type = AW88395_DEV_DEFAULT_TYPE_ID;
667 	} else {
668 		dev_err(aw_dev->dev, "can't find scene");
669 		return -EINVAL;
670 	}
671 
672 	return 0;
673 }
674 
675 static int aw_get_dev_scene_count_v1(struct aw_device *aw_dev, struct aw_container *aw_cfg,
676 						unsigned int *scene_num)
677 {
678 	struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
679 	struct aw_cfg_dde_v1 *cfg_dde =
680 		(struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
681 	unsigned int i;
682 
683 	for (i = 0; i < cfg_hdr->ddt_num; ++i) {
684 		if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&
685 		    (aw_dev->chip_id == cfg_dde[i].chip_id) &&
686 		    (aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
687 		    (aw_dev->i2c->addr == cfg_dde[i].dev_addr))
688 			(*scene_num)++;
689 	}
690 
691 	return 0;
692 }
693 
694 static int aw_get_default_scene_count_v1(struct aw_device *aw_dev,
695 						struct aw_container *aw_cfg,
696 						unsigned int *scene_num)
697 {
698 	struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
699 	struct aw_cfg_dde_v1 *cfg_dde =
700 		(struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
701 	unsigned int i;
702 
703 	for (i = 0; i < cfg_hdr->ddt_num; ++i) {
704 		if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&
705 		    (aw_dev->chip_id == cfg_dde[i].chip_id) &&
706 		    (aw_dev->channel == cfg_dde[i].dev_index))
707 			(*scene_num)++;
708 	}
709 
710 	return 0;
711 }
712 
713 static int aw_dev_parse_scene_count_v1(struct aw_device *aw_dev,
714 							struct aw_container *aw_cfg,
715 							unsigned int *count)
716 {
717 	int ret;
718 
719 	ret = aw_get_dde_type_info(aw_dev, aw_cfg);
720 	if (ret < 0)
721 		return ret;
722 
723 	switch (aw_dev->prof_info.prof_type) {
724 	case AW88395_DEV_TYPE_ID:
725 		ret = aw_get_dev_scene_count_v1(aw_dev, aw_cfg, count);
726 		break;
727 	case AW88395_DEV_DEFAULT_TYPE_ID:
728 		ret = aw_get_default_scene_count_v1(aw_dev, aw_cfg, count);
729 		break;
730 	default:
731 		dev_err(aw_dev->dev, "unsupported prof_type[%x]", aw_dev->prof_info.prof_type);
732 		ret = -EINVAL;
733 		break;
734 	}
735 
736 	return ret;
737 }
738 
739 static int aw_dev_parse_data_by_sec_type_v1(struct aw_device *aw_dev,
740 							struct aw_cfg_hdr *prof_hdr,
741 							struct aw_cfg_dde_v1 *cfg_dde,
742 							int *cur_scene_id)
743 {
744 	struct aw_prof_info *prof_info = &aw_dev->prof_info;
745 	int ret;
746 
747 	switch (cfg_dde->data_type) {
748 	case ACF_SEC_TYPE_MULTIPLE_BIN:
749 		ret = aw_dev_prof_parse_multi_bin(aw_dev, (u8 *)prof_hdr + cfg_dde->data_offset,
750 					cfg_dde->data_size, &prof_info->prof_desc[*cur_scene_id]);
751 		if (ret < 0) {
752 			dev_err(aw_dev->dev, "parse multi bin failed");
753 			return ret;
754 		}
755 		prof_info->prof_desc[*cur_scene_id].prf_str = cfg_dde->dev_profile_str;
756 		prof_info->prof_desc[*cur_scene_id].id = cfg_dde->dev_profile;
757 		(*cur_scene_id)++;
758 		break;
759 	default:
760 		dev_err(aw_dev->dev, "unsupported SEC_TYPE [%d]", cfg_dde->data_type);
761 		return -EINVAL;
762 	}
763 
764 	return 0;
765 }
766 
767 static int aw_dev_parse_dev_type_v1(struct aw_device *aw_dev,
768 		struct aw_cfg_hdr *prof_hdr)
769 {
770 	struct aw_cfg_dde_v1 *cfg_dde =
771 		(struct aw_cfg_dde_v1 *)((char *)prof_hdr + prof_hdr->hdr_offset);
772 	int cur_scene_id = 0;
773 	unsigned int i;
774 	int ret;
775 
776 	for (i = 0; i < prof_hdr->ddt_num; i++) {
777 		if ((aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
778 		    (aw_dev->i2c->addr == cfg_dde[i].dev_addr) &&
779 		    (aw_dev->chip_id == cfg_dde[i].chip_id)) {
780 			ret = aw_dev_parse_data_by_sec_type_v1(aw_dev, prof_hdr,
781 							&cfg_dde[i], &cur_scene_id);
782 			if (ret < 0) {
783 				dev_err(aw_dev->dev, "parse failed");
784 				return ret;
785 			}
786 		}
787 	}
788 
789 	if (cur_scene_id == 0) {
790 		dev_err(aw_dev->dev, "get dev type failed, get num [%d]", cur_scene_id);
791 		return -EINVAL;
792 	}
793 
794 	return 0;
795 }
796 
797 static int aw_dev_parse_default_type_v1(struct aw_device *aw_dev,
798 		struct aw_cfg_hdr *prof_hdr)
799 {
800 	struct aw_cfg_dde_v1 *cfg_dde =
801 		(struct aw_cfg_dde_v1 *)((char *)prof_hdr + prof_hdr->hdr_offset);
802 	int cur_scene_id = 0;
803 	unsigned int i;
804 	int ret;
805 
806 	for (i = 0; i < prof_hdr->ddt_num; i++) {
807 		if ((aw_dev->channel == cfg_dde[i].dev_index) &&
808 			(aw_dev->chip_id == cfg_dde[i].chip_id)) {
809 			ret = aw_dev_parse_data_by_sec_type_v1(aw_dev, prof_hdr,
810 							&cfg_dde[i], &cur_scene_id);
811 			if (ret < 0) {
812 				dev_err(aw_dev->dev, "parse failed");
813 				return ret;
814 			}
815 		}
816 	}
817 
818 	if (cur_scene_id == 0) {
819 		dev_err(aw_dev->dev, "get dev default type failed, get num[%d]", cur_scene_id);
820 		return -EINVAL;
821 	}
822 
823 	return 0;
824 }
825 
826 static int aw_dev_parse_by_hdr_v1(struct aw_device *aw_dev,
827 		struct aw_cfg_hdr *cfg_hdr)
828 {
829 	int ret;
830 
831 	switch (aw_dev->prof_info.prof_type) {
832 	case AW88395_DEV_TYPE_ID:
833 		ret = aw_dev_parse_dev_type_v1(aw_dev, cfg_hdr);
834 		break;
835 	case AW88395_DEV_DEFAULT_TYPE_ID:
836 		ret = aw_dev_parse_default_type_v1(aw_dev, cfg_hdr);
837 		break;
838 	default:
839 		dev_err(aw_dev->dev, "prof type matched failed, get num[%d]",
840 			aw_dev->prof_info.prof_type);
841 		ret =  -EINVAL;
842 		break;
843 	}
844 
845 	return ret;
846 }
847 
848 static int aw_dev_load_cfg_by_hdr_v1(struct aw_device *aw_dev,
849 						struct aw_container *aw_cfg)
850 {
851 	struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
852 	struct aw_prof_info *prof_info = &aw_dev->prof_info;
853 	int ret;
854 
855 	ret = aw_dev_parse_scene_count_v1(aw_dev, aw_cfg, &prof_info->count);
856 	if (ret < 0) {
857 		dev_err(aw_dev->dev, "get scene count failed");
858 		return ret;
859 	}
860 
861 	prof_info->prof_desc = devm_kcalloc(aw_dev->dev,
862 					prof_info->count, sizeof(struct aw_prof_desc),
863 					GFP_KERNEL);
864 	if (!prof_info->prof_desc)
865 		return -ENOMEM;
866 
867 	ret = aw_dev_parse_by_hdr_v1(aw_dev, cfg_hdr);
868 	if (ret < 0) {
869 		dev_err(aw_dev->dev, "parse hdr failed");
870 		return ret;
871 	}
872 
873 	ret = aw_dev_create_prof_name_list_v1(aw_dev);
874 	if (ret < 0) {
875 		dev_err(aw_dev->dev, "create prof name list failed");
876 		return ret;
877 	}
878 
879 	return 0;
880 }
881 
882 int aw88395_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg)
883 {
884 	struct aw_cfg_hdr *cfg_hdr;
885 	int ret;
886 
887 	cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
888 
889 	switch (cfg_hdr->hdr_version) {
890 	case AW88395_CFG_HDR_VER:
891 		ret = aw_dev_load_cfg_by_hdr(aw_dev, cfg_hdr);
892 		if (ret < 0) {
893 			dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed",
894 						cfg_hdr->hdr_version);
895 			return ret;
896 		}
897 		break;
898 	case AW88395_CFG_HDR_VER_V1:
899 		ret = aw_dev_load_cfg_by_hdr_v1(aw_dev, aw_cfg);
900 		if (ret < 0) {
901 			dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed",
902 						cfg_hdr->hdr_version);
903 			return ret;
904 		}
905 		break;
906 	default:
907 		dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_version);
908 		return -EINVAL;
909 	}
910 	aw_dev->fw_status = AW88395_DEV_FW_OK;
911 
912 	return 0;
913 }
914 EXPORT_SYMBOL_GPL(aw88395_dev_cfg_load);
915 
916 static int aw_dev_check_cfg_by_hdr(struct aw_device *aw_dev, struct aw_container *aw_cfg)
917 {
918 	unsigned int end_data_offset;
919 	struct aw_cfg_hdr *cfg_hdr;
920 	struct aw_cfg_dde *cfg_dde;
921 	unsigned int act_data = 0;
922 	unsigned int hdr_ddt_len;
923 	unsigned int i;
924 	u8 act_crc8;
925 
926 	cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
927 	/* check file type id is awinic acf file */
928 	if (cfg_hdr->id != ACF_FILE_ID) {
929 		dev_err(aw_dev->dev, "not acf type file");
930 		return -EINVAL;
931 	}
932 
933 	hdr_ddt_len = cfg_hdr->hdr_offset + cfg_hdr->ddt_size;
934 	if (hdr_ddt_len > aw_cfg->len) {
935 		dev_err(aw_dev->dev, "hdr_len with ddt_len [%d] overflow file size[%d]",
936 		cfg_hdr->hdr_offset, aw_cfg->len);
937 		return -EINVAL;
938 	}
939 
940 	/* check data size */
941 	cfg_dde = (struct aw_cfg_dde *)((char *)aw_cfg->data + cfg_hdr->hdr_offset);
942 	act_data += hdr_ddt_len;
943 	for (i = 0; i < cfg_hdr->ddt_num; i++)
944 		act_data += cfg_dde[i].data_size;
945 
946 	if (act_data != aw_cfg->len) {
947 		dev_err(aw_dev->dev, "act_data[%d] not equal to file size[%d]!",
948 			act_data, aw_cfg->len);
949 		return -EINVAL;
950 	}
951 
952 	for (i = 0; i < cfg_hdr->ddt_num; i++) {
953 		/* data check */
954 		end_data_offset = cfg_dde[i].data_offset + cfg_dde[i].data_size;
955 		if (end_data_offset > aw_cfg->len) {
956 			dev_err(aw_dev->dev, "ddt_num[%d] end_data_offset[%d] overflow size[%d]",
957 				i, end_data_offset, aw_cfg->len);
958 			return -EINVAL;
959 		}
960 
961 		/* crc check */
962 		act_crc8 = crc8(aw_crc8_table, aw_cfg->data + cfg_dde[i].data_offset,
963 							cfg_dde[i].data_size, 0);
964 		if (act_crc8 != cfg_dde[i].data_crc) {
965 			dev_err(aw_dev->dev, "ddt_num[%d] act_crc8:0x%x != data_crc:0x%x",
966 				i, (u32)act_crc8, cfg_dde[i].data_crc);
967 			return -EINVAL;
968 		}
969 	}
970 
971 	return 0;
972 }
973 
974 static int aw_dev_check_acf_by_hdr_v1(struct aw_device *aw_dev, struct aw_container *aw_cfg)
975 {
976 	struct aw_cfg_dde_v1 *cfg_dde;
977 	unsigned int end_data_offset;
978 	struct aw_cfg_hdr *cfg_hdr;
979 	unsigned int act_data = 0;
980 	unsigned int hdr_ddt_len;
981 	u8 act_crc8;
982 	int i;
983 
984 	cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
985 
986 	/* check file type id is awinic acf file */
987 	if (cfg_hdr->id != ACF_FILE_ID) {
988 		dev_err(aw_dev->dev, "not acf type file");
989 		return -EINVAL;
990 	}
991 
992 	hdr_ddt_len = cfg_hdr->hdr_offset + cfg_hdr->ddt_size;
993 	if (hdr_ddt_len > aw_cfg->len) {
994 		dev_err(aw_dev->dev, "hdrlen with ddt_len [%d] overflow file size[%d]",
995 		cfg_hdr->hdr_offset, aw_cfg->len);
996 		return -EINVAL;
997 	}
998 
999 	/* check data size */
1000 	cfg_dde = (struct aw_cfg_dde_v1 *)((char *)aw_cfg->data + cfg_hdr->hdr_offset);
1001 	act_data += hdr_ddt_len;
1002 	for (i = 0; i < cfg_hdr->ddt_num; i++)
1003 		act_data += cfg_dde[i].data_size;
1004 
1005 	if (act_data != aw_cfg->len) {
1006 		dev_err(aw_dev->dev, "act_data[%d] not equal to file size[%d]!",
1007 			act_data, aw_cfg->len);
1008 		return -EINVAL;
1009 	}
1010 
1011 	for (i = 0; i < cfg_hdr->ddt_num; i++) {
1012 		/* data check */
1013 		end_data_offset = cfg_dde[i].data_offset + cfg_dde[i].data_size;
1014 		if (end_data_offset > aw_cfg->len) {
1015 			dev_err(aw_dev->dev, "ddt_num[%d] end_data_offset[%d] overflow size[%d]",
1016 				i, end_data_offset, aw_cfg->len);
1017 			return -EINVAL;
1018 		}
1019 
1020 		/* crc check */
1021 		act_crc8 = crc8(aw_crc8_table, aw_cfg->data + cfg_dde[i].data_offset,
1022 									cfg_dde[i].data_size, 0);
1023 		if (act_crc8 != cfg_dde[i].data_crc) {
1024 			dev_err(aw_dev->dev, "ddt_num[%d] act_crc8:0x%x != data_crc 0x%x",
1025 				i, (u32)act_crc8, cfg_dde[i].data_crc);
1026 			return -EINVAL;
1027 		}
1028 	}
1029 
1030 	return 0;
1031 }
1032 
1033 int aw88395_dev_load_acf_check(struct aw_device *aw_dev, struct aw_container *aw_cfg)
1034 {
1035 	struct aw_cfg_hdr *cfg_hdr;
1036 
1037 	if (!aw_cfg) {
1038 		dev_err(aw_dev->dev, "aw_prof is NULL");
1039 		return -EINVAL;
1040 	}
1041 
1042 	if (aw_cfg->len < sizeof(struct aw_cfg_hdr)) {
1043 		dev_err(aw_dev->dev, "cfg hdr size[%d] overflow file size[%d]",
1044 			aw_cfg->len, (int)sizeof(struct aw_cfg_hdr));
1045 		return -EINVAL;
1046 	}
1047 
1048 	crc8_populate_lsb(aw_crc8_table, AW88395_CRC8_POLYNOMIAL);
1049 
1050 	cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
1051 	switch (cfg_hdr->hdr_version) {
1052 	case AW88395_CFG_HDR_VER:
1053 		return aw_dev_check_cfg_by_hdr(aw_dev, aw_cfg);
1054 	case AW88395_CFG_HDR_VER_V1:
1055 		return aw_dev_check_acf_by_hdr_v1(aw_dev, aw_cfg);
1056 	default:
1057 		dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_version);
1058 		return -EINVAL;
1059 	}
1060 
1061 	return 0;
1062 }
1063 EXPORT_SYMBOL_GPL(aw88395_dev_load_acf_check);
1064 
1065 MODULE_DESCRIPTION("AW88395 ACF File Parsing Lib");
1066 MODULE_LICENSE("GPL v2");
1067