xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/aw87xxx/aw_acf_bin.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * aw_acf_bin.c
3  *
4  * Copyright (c) 2021 AWINIC Technology CO., LTD
5  *
6  * Author: Barry <zhaozhongbo@awinic.com>
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  */
13 
14 #include <linux/module.h>
15 #include <asm/uaccess.h>
16 #include <linux/delay.h>
17 #include <linux/slab.h>
18 #include <linux/kernel.h>
19 #include <linux/fs.h>
20 #include <linux/device.h>
21 #include <linux/kernel.h>
22 #include <linux/vmalloc.h>
23 #include "aw87xxx.h"
24 #include "aw_acf_bin.h"
25 #include "aw_monitor.h"
26 #include "aw_log.h"
27 #include "aw_bin_parse.h"
28 
29 static char *g_profile_name[] = {"Music", "Voice", "Voip",
30 		"Ringtone", "Ringtone_hs", "Lowpower", "Bypass", "Mmi",
31 		"Fm", "Notification", "Receiver", "Off"};
32 
33 static char *g_power_off_name[] = {"Off", "OFF", "off", "oFF", "power_down"};
34 
aw_get_prof_name(int profile)35 static char *aw_get_prof_name(int profile)
36 {
37 	if (profile < 0 || profile >= AW_PROFILE_MAX)
38 		return "NULL";
39 	else
40 		return g_profile_name[profile];
41 }
42 
43 /*************************************************************************
44  *
45  *acf check
46  *
47  *************************************************************************/
aw_crc8_check(const unsigned char * data,unsigned int data_size)48 static int aw_crc8_check(const unsigned char *data, unsigned int data_size)
49 
50 {
51 	unsigned char crc_value = 0x00;
52 	unsigned char *pdata;
53 	int i;
54 	unsigned char pdatabuf = 0;
55 
56 	pdata = (unsigned char *)data;
57 
58 	while (data_size--) {
59 		pdatabuf = *pdata++;
60 		for (i = 0; i < 8; i++) {
61 			if ((crc_value ^ (pdatabuf)) & 0x01) {
62 				crc_value ^= 0x18;
63 				crc_value >>= 1;
64 				crc_value |= 0x80;
65 			} else {
66 				crc_value >>= 1;
67 			}
68 			pdatabuf >>= 1;
69 		}
70 	}
71 
72 	return (int)crc_value;
73 }
74 
aw_check_file_id(struct device * dev,char * fw_data,int32_t file_id)75 static int aw_check_file_id(struct device *dev,
76 		char *fw_data, int32_t file_id)
77 {
78 	int32_t *acf_file_id = NULL;
79 
80 	acf_file_id = (int32_t *)fw_data;
81 	if (*acf_file_id != file_id) {
82 		AW_DEV_LOGE(dev, "file id [%x] check failed", *acf_file_id);
83 		return -ENFILE;
84 	}
85 
86 	return 0;
87 }
88 
aw_check_header_size(struct device * dev,char * fw_data,size_t fw_size)89 static int aw_check_header_size(struct device *dev,
90 			char *fw_data, size_t fw_size)
91 {
92 	if (fw_size < sizeof(struct aw_acf_hdr)) {
93 		AW_DEV_LOGE(dev, "acf size check failed,size less-than aw_acf_hdr");
94 		return -ENOEXEC;
95 	}
96 
97 	return 0;
98 }
99 
100 /***************************************************************************
101  * V0.0.0.1 version acf check
102  **************************************************************************/
aw_check_ddt_size_v_0_0_0_1(struct device * dev,char * fw_data)103 static int aw_check_ddt_size_v_0_0_0_1(struct device *dev, char *fw_data)
104 {
105 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)fw_data;
106 	struct aw_acf_dde *acf_dde = NULL;
107 
108 	acf_dde = (struct aw_acf_dde *)(fw_data + acf_hdr->ddt_offset);
109 
110 	/* check ddt_size in acf_header is aqual to ddt_num multiply by dde_size */
111 	if (acf_hdr->ddt_size != acf_hdr->dde_num * sizeof(struct aw_acf_dde)) {
112 		AW_DEV_LOGE(dev, "acf ddt size check failed");
113 		return -EINVAL;
114 	}
115 
116 	return 0;
117 }
118 
aw_check_data_size_v_0_0_0_1(struct device * dev,char * fw_data,size_t fw_size)119 static int aw_check_data_size_v_0_0_0_1(struct device *dev,
120 		char *fw_data, size_t fw_size)
121 {
122 	int i = 0;
123 	size_t data_size = 0;
124 	struct aw_acf_hdr *acf_hdr = NULL;
125 	struct aw_acf_dde *acf_dde = NULL;
126 
127 	acf_hdr = (struct aw_acf_hdr *)fw_data;
128 	acf_dde = (struct aw_acf_dde *)(fw_data + acf_hdr->ddt_offset);
129 
130 	for (i = 0; i < acf_hdr->dde_num; ++i) {
131 		if (acf_dde[i].data_size % 2) {
132 			AW_DEV_LOGE(dev, "acf dde[%d].data_size[%d],dev_name[%s],data_type[%d], data_size check failed",
133 				i, acf_dde[i].data_size, acf_dde[i].dev_name,
134 				acf_dde[i].data_type);
135 			return -EINVAL;
136 		}
137 		data_size += acf_dde[i].data_size;
138 	}
139 
140 	/* Verify that the file size is equal to the header size plus */
141 	/* the table size and data size */
142 	if (fw_size != data_size + sizeof(struct aw_acf_hdr) + acf_hdr->ddt_size) {
143 		AW_DEV_LOGE(dev, "acf size check failed");
144 		AW_DEV_LOGE(dev, "fw_size=%ld,hdr_size and ddt size and data size =%ld",
145 			(u_long)fw_size, (u_long)(data_size + sizeof(struct aw_acf_hdr) +
146 			acf_hdr->ddt_size));
147 		return -EINVAL;
148 	}
149 
150 	return 0;
151 }
152 
aw_check_data_crc_v_0_0_0_1(struct device * dev,char * fw_data)153 static int aw_check_data_crc_v_0_0_0_1(struct device *dev, char *fw_data)
154 {
155 	int i = 0;
156 	size_t crc_val = 0;
157 	char *data = NULL;
158 	struct aw_acf_hdr *acf_hdr = NULL;
159 	struct aw_acf_dde *acf_dde = NULL;
160 
161 	acf_hdr = (struct aw_acf_hdr *)fw_data;
162 	acf_dde = (struct aw_acf_dde *)(fw_data + acf_hdr->ddt_offset);
163 
164 	for (i = 0; i < acf_hdr->dde_num; ++i) {
165 		data = fw_data + acf_dde[i].data_offset;
166 		crc_val = aw_crc8_check(data, acf_dde[i].data_size);
167 		if (crc_val != acf_dde[i].data_crc) {
168 			AW_DEV_LOGE(dev, "acf dde_crc check failed");
169 			return -EINVAL;
170 		}
171 	}
172 
173 	return 0;
174 }
175 
aw_check_profile_id_v_0_0_0_1(struct device * dev,char * fw_data)176 static int aw_check_profile_id_v_0_0_0_1(struct device *dev, char *fw_data)
177 {
178 	int i = 0;
179 	struct aw_acf_hdr *acf_hdr = NULL;
180 	struct aw_acf_dde *acf_dde = NULL;
181 
182 	acf_hdr = (struct aw_acf_hdr *)fw_data;
183 	acf_dde = (struct aw_acf_dde *)(fw_data + acf_hdr->ddt_offset);
184 
185 	for (i = 0; i < acf_hdr->dde_num; ++i) {
186 		if (acf_dde[i].data_type == AW_MONITOR)
187 			continue;
188 		if (acf_dde[i].dev_profile > AW_PROFILE_MAX) {
189 			AW_DEV_LOGE(dev, "parse profile_id[%d] failed", acf_dde[i].dev_profile);
190 			return -EINVAL;
191 		}
192 	}
193 
194 	return 0;
195 }
aw_check_data_v_0_0_0_1(struct device * dev,char * fw_data,size_t size)196 static int aw_check_data_v_0_0_0_1(struct device *dev,
197 			char *fw_data, size_t size)
198 {
199 	int ret = -1;
200 
201 	/* check file type id is awinic acf file */
202 	ret = aw_check_file_id(dev, fw_data, AW_ACF_FILE_ID);
203 	if (ret < 0)
204 		return ret;
205 
206 	/* check ddt_size in header is equal to all ddt aize */
207 	ret = aw_check_ddt_size_v_0_0_0_1(dev, fw_data);
208 	if (ret < 0)
209 		return ret;
210 
211 	/* Verify that the file size is equal to the header size plus */
212 	/* the table size and data size */
213 	ret = aw_check_data_size_v_0_0_0_1(dev, fw_data, size);
214 	if (ret < 0)
215 		return ret;
216 
217 	/* check crc in is equal to dde data crc */
218 	ret = aw_check_data_crc_v_0_0_0_1(dev, fw_data);
219 	if (ret < 0)
220 		return ret;
221 
222 	/* check profile id is in profile_id_max */
223 	ret = aw_check_profile_id_v_0_0_0_1(dev, fw_data);
224 	if (ret < 0)
225 		return ret;
226 
227 	AW_DEV_LOGI(dev, "acf fimware check succeed");
228 
229 	return 0;
230 }
231 
232 /***************************************************************************
233  * V1.0.0.0 version acf chack
234  **************************************************************************/
aw_check_ddt_size_v_1_0_0_0(struct device * dev,char * fw_data)235 static int aw_check_ddt_size_v_1_0_0_0(struct device *dev, char *fw_data)
236 {
237 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)fw_data;
238 	struct aw_acf_dde_v_1_0_0_0 *acf_dde = NULL;
239 
240 	acf_dde = (struct aw_acf_dde_v_1_0_0_0 *)(fw_data + acf_hdr->ddt_offset);
241 
242 	/* check ddt_size in acf_header is aqual to ddt_num multiply by dde_size */
243 	if (acf_hdr->ddt_size != acf_hdr->dde_num * sizeof(struct aw_acf_dde_v_1_0_0_0)) {
244 		AW_DEV_LOGE(dev, "acf ddt size check failed");
245 		return -EINVAL;
246 	}
247 
248 	return 0;
249 }
250 
aw_check_data_size_v_1_0_0_0(struct device * dev,char * fw_data,size_t fw_size)251 static int aw_check_data_size_v_1_0_0_0(struct device *dev,
252 		char *fw_data, size_t fw_size)
253 {
254 	int i = 0;
255 	size_t data_size = 0;
256 	struct aw_acf_hdr *acf_hdr = NULL;
257 	struct aw_acf_dde_v_1_0_0_0 *acf_dde = NULL;
258 
259 	acf_hdr = (struct aw_acf_hdr *)fw_data;
260 	acf_dde = (struct aw_acf_dde_v_1_0_0_0 *)(fw_data + acf_hdr->ddt_offset);
261 
262 	for (i = 0; i < acf_hdr->dde_num; ++i) {
263 		if (acf_dde[i].data_size % 2) {
264 			AW_DEV_LOGE(dev, "acf dde[%d].data_size[%d],dev_name[%s],data_type[%d], data_size check failed",
265 				i, acf_dde[i].data_size, acf_dde[i].dev_name,
266 				acf_dde[i].data_type);
267 			return -EINVAL;
268 		}
269 		data_size += acf_dde[i].data_size;
270 	}
271 
272 	/* Verify that the file size is equal to the header size plus */
273 	/* the table size and data size */
274 	if (fw_size != data_size + sizeof(struct aw_acf_hdr) + acf_hdr->ddt_size) {
275 		AW_DEV_LOGE(dev, "acf size check failed");
276 		AW_DEV_LOGE(dev, "fw_size=%ld,hdr_size and ddt size and data size =%ld",
277 			(u_long)fw_size, (u_long)(data_size + sizeof(struct aw_acf_hdr) +
278 			acf_hdr->ddt_size));
279 		return -EINVAL;
280 	}
281 
282 	return 0;
283 }
284 
aw_check_data_crc_v_1_0_0_0(struct device * dev,char * fw_data)285 static int aw_check_data_crc_v_1_0_0_0(struct device *dev, char *fw_data)
286 {
287 	int i = 0;
288 	size_t crc_val = 0;
289 	char *data = NULL;
290 	struct aw_acf_hdr *acf_hdr = NULL;
291 	struct aw_acf_dde_v_1_0_0_0 *acf_dde = NULL;
292 
293 	acf_hdr = (struct aw_acf_hdr *)fw_data;
294 	acf_dde = (struct aw_acf_dde_v_1_0_0_0 *)(fw_data + acf_hdr->ddt_offset);
295 
296 	for (i = 0; i < acf_hdr->dde_num; ++i) {
297 		data = fw_data + acf_dde[i].data_offset;
298 		crc_val = aw_crc8_check(data, acf_dde[i].data_size);
299 		if (crc_val != acf_dde[i].data_crc) {
300 			AW_DEV_LOGE(dev, "acf dde_crc check failed");
301 			return -EINVAL;
302 		}
303 	}
304 
305 	return 0;
306 }
307 
aw_check_data_v_1_0_0_0(struct device * dev,char * fw_data,size_t size)308 static int aw_check_data_v_1_0_0_0(struct device *dev,
309 			char *fw_data, size_t size)
310 {
311 	int ret = -1;
312 
313 	/* check file type id is awinic acf file */
314 	ret = aw_check_file_id(dev, fw_data, AW_ACF_FILE_ID);
315 	if (ret < 0)
316 		return ret;
317 
318 	/* check ddt_size in header is equal to all ddt aize */
319 	ret = aw_check_ddt_size_v_1_0_0_0(dev, fw_data);
320 	if (ret < 0)
321 		return ret;
322 
323 	/* Verify that the file size is equal to the header size plus */
324 	/* the table size and data size */
325 	ret = aw_check_data_size_v_1_0_0_0(dev, fw_data, size);
326 	if (ret < 0)
327 		return ret;
328 
329 	/* check crc in is equal to dde data crc */
330 	ret = aw_check_data_crc_v_1_0_0_0(dev, fw_data);
331 	if (ret < 0)
332 		return ret;
333 
334 	AW_DEV_LOGI(dev, "acf fimware check succeed");
335 
336 	return 0;
337 }
338 
339 /***************************************************************************
340  * acf chack API
341  **************************************************************************/
aw_check_acf_firmware(struct device * dev,char * fw_data,size_t size)342 static int aw_check_acf_firmware(struct device *dev,
343 			char *fw_data, size_t size)
344 {
345 	int ret = -1;
346 	struct aw_acf_hdr *acf_hdr = NULL;
347 
348 	if (fw_data == NULL) {
349 		AW_DEV_LOGE(dev, "fw_data is NULL,fw_data check failed");
350 		return -ENODATA;
351 	}
352 
353 	/* check file size is less-than header size */
354 	ret = aw_check_header_size(dev, fw_data, size);
355 	if (ret < 0)
356 		return ret;
357 
358 	acf_hdr = (struct aw_acf_hdr *)fw_data;
359 	AW_DEV_LOGI(dev, "project name: [%s]", acf_hdr->project);
360 	AW_DEV_LOGI(dev, "custom name: [%s]", acf_hdr->custom);
361 	AW_DEV_LOGI(dev, "version name: [%s]", acf_hdr->version);
362 	AW_DEV_LOGI(dev, "author_id: [%d]", acf_hdr->author_id);
363 
364 	switch (acf_hdr->hdr_version) {
365 	case AW_ACF_HDR_VER_0_0_0_1:
366 		return aw_check_data_v_0_0_0_1(dev, fw_data, size);
367 	case AW_ACF_HDR_VER_1_0_0_0:
368 		return aw_check_data_v_1_0_0_0(dev, fw_data, size);
369 	default:
370 		AW_DEV_LOGE(dev, "unsupported hdr_version [0x%x]",
371 			acf_hdr->hdr_version);
372 		return -EINVAL;
373 	}
374 
375 	return ret;
376 }
377 
378 
379 
380 /*************************************************************************
381  *
382  *acf parse
383  *
384  *************************************************************************/
aw_parse_raw_reg(struct device * dev,uint8_t * data,uint32_t data_len,struct aw_prof_desc * prof_desc)385 static int aw_parse_raw_reg(struct device *dev, uint8_t *data,
386 		uint32_t data_len, struct aw_prof_desc *prof_desc)
387 {
388 	AW_DEV_LOGD(dev, "data_size:%d enter", data_len);
389 
390 	prof_desc->data_container.data = data;
391 	prof_desc->data_container.len = data_len;
392 
393 	prof_desc->prof_st = AW_PROFILE_OK;
394 
395 	return 0;
396 }
397 
aw_parse_reg_with_hdr(struct device * dev,uint8_t * data,uint32_t data_len,struct aw_prof_desc * prof_desc)398 static int aw_parse_reg_with_hdr(struct device *dev, uint8_t *data,
399 			 uint32_t data_len, struct aw_prof_desc *prof_desc)
400 {
401 	struct aw_bin *aw_bin = NULL;
402 	int ret = -1;
403 
404 	AW_DEV_LOGD(dev, "data_size:%d enter", data_len);
405 
406 	aw_bin = kzalloc(data_len + sizeof(struct aw_bin), GFP_KERNEL);
407 	if (aw_bin == NULL) {
408 		AW_DEV_LOGE(dev, "devm_kzalloc aw_bin failed");
409 		return -ENOMEM;
410 	}
411 
412 	aw_bin->info.len = data_len;
413 	memcpy(aw_bin->info.data, data, data_len);
414 
415 	ret = aw_parsing_bin_file(aw_bin);
416 	if (ret < 0) {
417 		AW_DEV_LOGE(dev, "parse bin failed");
418 		goto parse_bin_failed;
419 	}
420 
421 	if ((aw_bin->all_bin_parse_num != 1) ||
422 		(aw_bin->header_info[0].bin_data_type != DATA_TYPE_REGISTER)) {
423 		AW_DEV_LOGE(dev, "bin num or type error");
424 		goto parse_bin_failed;
425 	}
426 
427 	prof_desc->data_container.data =
428 				data + aw_bin->header_info[0].valid_data_addr;
429 	prof_desc->data_container.len = aw_bin->header_info[0].valid_data_len;
430 	prof_desc->prof_st = AW_PROFILE_OK;
431 
432 	kfree(aw_bin);
433 	aw_bin = NULL;
434 
435 	return 0;
436 
437 parse_bin_failed:
438 	kfree(aw_bin);
439 	aw_bin = NULL;
440 	return ret;
441 }
442 
aw_parse_monitor_config(struct device * dev,char * monitor_data,uint32_t data_len)443 static int aw_parse_monitor_config(struct device *dev,
444 				char *monitor_data, uint32_t data_len)
445 {
446 	int ret = -1;
447 
448 	if (monitor_data == NULL || data_len == 0) {
449 		AW_DEV_LOGE(dev, "no data to parse");
450 		return -EBFONT;
451 	}
452 
453 	ret = aw_monitor_bin_parse(dev, monitor_data, data_len);
454 	if (ret < 0) {
455 		AW_DEV_LOGE(dev, "monitor_config parse failed");
456 		return ret;
457 	}
458 
459 	AW_DEV_LOGI(dev, "monitor_bin parse succeed");
460 
461 	return 0;
462 }
463 
aw_check_prof_str_is_off(char * profile_name)464 static int aw_check_prof_str_is_off(char *profile_name)
465 {
466 	int i = 0;
467 
468 	for (i = 0; i < AW_POWER_OFF_NAME_SUPPORT_COUNT; i++) {
469 		if (strnstr(profile_name, g_power_off_name[i],
470 				strlen(profile_name) + 1))
471 			return 0;
472 	}
473 
474 	return -EINVAL;
475 }
476 
477 /***************************************************************************
478  * V0.0.0.1 version acf paese
479  **************************************************************************/
aw_check_product_name_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_acf_dde * prof_hdr)480 static int aw_check_product_name_v_0_0_0_1(struct device *dev,
481 				struct acf_bin_info *acf_info,
482 				struct aw_acf_dde *prof_hdr)
483 {
484 	int i = 0;
485 
486 	for (i = 0; i < acf_info->product_cnt; i++) {
487 		if (0 == strcmp(acf_info->product_tab[i], prof_hdr->dev_name)) {
488 			AW_DEV_LOGD(dev, "bin_dev_name:%s",
489 				prof_hdr->dev_name);
490 			return 0;
491 		}
492 	}
493 
494 	return -ENXIO;
495 }
496 
aw_check_data_type_is_monitor_v_0_0_0_1(struct device * dev,struct aw_acf_dde * prof_hdr)497 static int aw_check_data_type_is_monitor_v_0_0_0_1(struct device *dev,
498 				struct aw_acf_dde *prof_hdr)
499 {
500 	if (prof_hdr->data_type == AW_MONITOR) {
501 		AW_DEV_LOGD(dev, "bin data is monitor");
502 		return 0;
503 	}
504 
505 	return -ENXIO;
506 }
507 
aw_parse_data_by_sec_type_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_acf_dde * prof_hdr,struct aw_prof_desc * profile_prof_desc)508 static int aw_parse_data_by_sec_type_v_0_0_0_1(struct device *dev,
509 				struct acf_bin_info *acf_info,
510 				struct aw_acf_dde *prof_hdr,
511 				struct aw_prof_desc *profile_prof_desc)
512 {
513 	int ret = -1;
514 	char *cfg_data = acf_info->fw_data + prof_hdr->data_offset;
515 
516 	switch (prof_hdr->data_type) {
517 	case AW_BIN_TYPE_REG:
518 		snprintf(profile_prof_desc->dev_name, sizeof(prof_hdr->dev_name),
519 			"%s", prof_hdr->dev_name);
520 		profile_prof_desc->prof_name = aw_get_prof_name(prof_hdr->dev_profile);
521 		AW_DEV_LOGD(dev, "parse reg type data enter,profile=%s",
522 			aw_get_prof_name(prof_hdr->dev_profile));
523 		ret =  aw_parse_raw_reg(dev, cfg_data, prof_hdr->data_size,
524 					profile_prof_desc);
525 		break;
526 	case AW_BIN_TYPE_HDR_REG:
527 		snprintf(profile_prof_desc->dev_name, sizeof(prof_hdr->dev_name),
528 			"%s", prof_hdr->dev_name);
529 		profile_prof_desc->prof_name = aw_get_prof_name(prof_hdr->dev_profile);
530 		AW_DEV_LOGD(dev, "parse hdr_reg type data enter,profile=%s",
531 			aw_get_prof_name(prof_hdr->dev_profile));
532 		ret = aw_parse_reg_with_hdr(dev, cfg_data,
533 					prof_hdr->data_size,
534 					profile_prof_desc);
535 		break;
536 	case AW_MONITOR:
537 		AW_DEV_LOGD(dev, "parse monitor type data enter");
538 		ret = aw_parse_monitor_config(dev, cfg_data,
539 					prof_hdr->data_size);
540 		break;
541 	}
542 
543 	return ret;
544 }
545 
aw_parse_dev_type_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_all_prof_info * all_prof_info)546 static int aw_parse_dev_type_v_0_0_0_1(struct device *dev,
547 		struct acf_bin_info *acf_info, struct aw_all_prof_info *all_prof_info)
548 {
549 	int i = 0;
550 	int ret = -1;
551 	int sec_num = 0;
552 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
553 	struct aw_prof_desc *prof_desc = NULL;
554 	struct aw_acf_dde *acf_dde =
555 		(struct aw_acf_dde *)(acf_info->fw_data + acf_info->acf_hdr.ddt_offset);
556 
557 	AW_DEV_LOGD(dev, "enter");
558 
559 	for (i = 0; i < acf_info->acf_hdr.dde_num; i++) {
560 		if ((acf_info->aw_dev->i2c_bus == acf_dde[i].dev_bus) &&
561 			(acf_info->aw_dev->i2c_addr == acf_dde[i].dev_addr) &&
562 			(acf_dde[i].type == AW_DDE_DEV_TYPE_ID)) {
563 
564 			ret = aw_check_product_name_v_0_0_0_1(dev, acf_info, &acf_dde[i]);
565 			if (ret < 0)
566 				continue;
567 
568 			ret = aw_check_data_type_is_monitor_v_0_0_0_1(dev, &acf_dde[i]);
569 			if (ret == 0) {
570 				prof_desc = NULL;
571 			} else {
572 				prof_desc = &all_prof_info->prof_desc[acf_dde[i].dev_profile];
573 			}
574 
575 			if (acf_dde[i].dev_profile == AW_PROFILE_OFF && !soft_off_enable) {
576 				AW_DEV_LOGE(dev, "profile off is not allowed");
577 				return -EINVAL;
578 			}
579 
580 			ret = aw_parse_data_by_sec_type_v_0_0_0_1(dev, acf_info, &acf_dde[i],
581 				prof_desc);
582 			if (ret < 0) {
583 				AW_DEV_LOGE(dev, "parse dev type data failed");
584 				return ret;
585 			}
586 			sec_num++;
587 		}
588 	}
589 
590 	if (sec_num == 0) {
591 		AW_DEV_LOGD(dev, "get dev type num is %d, please use default",
592 			sec_num);
593 		return AW_DEV_TYPE_NONE;
594 	}
595 
596 	return AW_DEV_TYPE_OK;
597 }
598 
aw_parse_default_type_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_all_prof_info * all_prof_info)599 static int aw_parse_default_type_v_0_0_0_1(struct device *dev,
600 	struct acf_bin_info *acf_info, struct aw_all_prof_info *all_prof_info)
601 {
602 	int i = 0;
603 	int ret = -1;
604 	int sec_num = 0;
605 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
606 	struct aw_prof_desc *prof_desc = NULL;
607 	struct aw_acf_dde *acf_dde =
608 		(struct aw_acf_dde *)(acf_info->fw_data + acf_info->acf_hdr.ddt_offset);
609 
610 	AW_DEV_LOGD(dev, "enter");
611 
612 	for (i = 0; i < acf_info->acf_hdr.dde_num; i++) {
613 		if ((acf_info->dev_index == acf_dde[i].dev_index) &&
614 			(acf_dde[i].type == AW_DDE_DEV_DEFAULT_TYPE_ID)) {
615 
616 			ret = aw_check_product_name_v_0_0_0_1(dev, acf_info, &acf_dde[i]);
617 			if (ret < 0)
618 				continue;
619 
620 			ret = aw_check_data_type_is_monitor_v_0_0_0_1(dev, &acf_dde[i]);
621 			if (ret == 0) {
622 				prof_desc = NULL;
623 			} else {
624 				prof_desc = &all_prof_info->prof_desc[acf_dde[i].dev_profile];
625 			}
626 
627 			if (acf_dde[i].dev_profile == AW_PROFILE_OFF && !soft_off_enable) {
628 				AW_DEV_LOGE(dev, "profile off is not allowed");
629 				return -EINVAL;
630 			}
631 
632 			ret = aw_parse_data_by_sec_type_v_0_0_0_1(dev, acf_info, &acf_dde[i],
633 				prof_desc);
634 			if (ret < 0) {
635 				AW_DEV_LOGE(dev, "parse default type data failed");
636 				return ret;
637 			}
638 			sec_num++;
639 		}
640 	}
641 
642 	if (sec_num == 0) {
643 		AW_DEV_LOGE(dev, "get dev default type failed, get num[%d]",
644 			sec_num);
645 		return -EINVAL;
646 	}
647 
648 	return 0;
649 }
650 
aw_get_prof_count_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_all_prof_info * all_prof_info)651 static int aw_get_prof_count_v_0_0_0_1(struct device *dev,
652 				struct acf_bin_info *acf_info,
653 				struct aw_all_prof_info *all_prof_info)
654 {
655 	int i = 0;
656 	int prof_count = 0;
657 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
658 	struct aw_prof_desc *prof_desc = all_prof_info->prof_desc;
659 
660 	for (i = 0; i < AW_PROFILE_MAX; i++) {
661 		if (i == AW_PROFILE_OFF) {
662 			if (!soft_off_enable && prof_desc[i].prof_st == AW_PROFILE_OK) {
663 				AW_DEV_LOGE(dev, "profile_off is not allowed");
664 				return -EINVAL;
665 			} else if (soft_off_enable && prof_desc[i].prof_st == AW_PROFILE_WAIT) {
666 				AW_DEV_LOGE(dev, "profile [Off] is necessary,but not found");
667 				return -EINVAL;
668 			} else {
669 				prof_count++;
670 			}
671 		} else {
672 			if (prof_desc[i].prof_st == AW_PROFILE_OK)
673 				prof_count++;
674 		}
675 	}
676 
677 	AW_DEV_LOGI(dev, "get profile count=[%d]", prof_count);
678 	return prof_count;
679 }
680 
aw_set_prof_off_info_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_all_prof_info * all_prof_info,int index)681 static int aw_set_prof_off_info_v_0_0_0_1(struct device *dev,
682 				struct acf_bin_info *acf_info,
683 				struct aw_all_prof_info *all_prof_info,
684 				int index)
685 {
686 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
687 	struct aw_prof_desc *prof_desc = all_prof_info->prof_desc;
688 	struct aw_prof_info *prof_info = &acf_info->prof_info;
689 
690 	if (index >= prof_info->count) {
691 		AW_DEV_LOGE(dev, "index[%d] is out of table,profile count[%d]",
692 			index, prof_info->count);
693 		return -EINVAL;
694 	}
695 
696 	if (soft_off_enable && prof_desc[AW_PROFILE_OFF].prof_st == AW_PROFILE_OK) {
697 		prof_info->prof_desc[index] = prof_desc[AW_PROFILE_OFF];
698 		AW_DEV_LOGI(dev, "product=[%s]----profile=[%s]",
699 			prof_info->prof_desc[index].dev_name,
700 			aw_get_prof_name(AW_PROFILE_OFF));
701 	} else if (!soft_off_enable) {
702 		memset(&prof_info->prof_desc[index].data_container, 0,
703 			sizeof(struct aw_data_container));
704 		prof_info->prof_desc[index].prof_st = AW_PROFILE_WAIT;
705 		prof_info->prof_desc[index].prof_name = aw_get_prof_name(AW_PROFILE_OFF);
706 		AW_DEV_LOGI(dev, "set default power_off with no data to profile");
707 	} else {
708 		AW_DEV_LOGE(dev, "not init default power_off config");
709 		return -EINVAL;
710 	}
711 
712 	return 0;
713 }
714 
715 
aw_get_vaild_prof_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info,struct aw_all_prof_info * all_prof_info)716 static int aw_get_vaild_prof_v_0_0_0_1(struct device *dev,
717 				struct acf_bin_info *acf_info,
718 				struct aw_all_prof_info *all_prof_info)
719 {
720 	int i = 0;
721 	int ret = 0;
722 	int index = 0;
723 	struct aw_prof_desc *prof_desc = all_prof_info->prof_desc;
724 	struct aw_prof_info *prof_info = &acf_info->prof_info;
725 
726 	prof_info->count = 0;
727 	ret = aw_get_prof_count_v_0_0_0_1(dev, acf_info, all_prof_info);
728 	if (ret < 0)
729 		return ret;
730 	prof_info->count = ret;
731 	prof_info->prof_desc = devm_kzalloc(dev,
732 			prof_info->count * sizeof(struct aw_prof_desc),
733 			GFP_KERNEL);
734 	if (prof_info->prof_desc == NULL) {
735 		AW_DEV_LOGE(dev, "prof_desc kzalloc failed");
736 		return -ENOMEM;
737 	}
738 
739 	for (i = 0; i < AW_PROFILE_MAX; i++) {
740 		if (i != AW_PROFILE_OFF && prof_desc[i].prof_st == AW_PROFILE_OK) {
741 			if (index >= prof_info->count) {
742 				AW_DEV_LOGE(dev, "get profile index[%d] overflow count[%d]",
743 						index, prof_info->count);
744 				return -ENOMEM;
745 			}
746 			prof_info->prof_desc[index] = prof_desc[i];
747 			AW_DEV_LOGI(dev, "product=[%s]----profile=[%s]",
748 				prof_info->prof_desc[index].dev_name,
749 				aw_get_prof_name(i));
750 			index++;
751 		}
752 	}
753 
754 	ret = aw_set_prof_off_info_v_0_0_0_1(dev, acf_info, all_prof_info, index);
755 	if (ret < 0)
756 		return ret;
757 
758 	AW_DEV_LOGD(dev, "get vaild profile succeed");
759 	return 0;
760 }
761 
aw_set_prof_name_list_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info)762 static int aw_set_prof_name_list_v_0_0_0_1(struct device *dev,
763 				struct acf_bin_info *acf_info)
764 {
765 	int i = 0;
766 	int count = acf_info->prof_info.count;
767 	struct aw_prof_info *prof_info = &acf_info->prof_info;
768 
769 	prof_info->prof_name_list = (char (*)[AW_PROFILE_STR_MAX])devm_kzalloc(dev,
770 		count * (AW_PROFILE_STR_MAX), GFP_KERNEL);
771 	if (prof_info->prof_name_list == NULL) {
772 		AW_DEV_LOGE(dev, "prof_name_list devm_kzalloc failed");
773 		return -ENOMEM;
774 	}
775 
776 	for (i = 0; i < count; ++i) {
777 		snprintf(prof_info->prof_name_list[i], AW_PROFILE_STR_MAX, "%s",
778 			prof_info->prof_desc[i].prof_name);
779 		AW_DEV_LOGI(dev, "index=[%d], profile_name=[%s]",
780 				i, prof_info->prof_name_list[i]);
781 	}
782 
783 	return 0;
784 }
785 
aw_parse_acf_v_0_0_0_1(struct device * dev,struct acf_bin_info * acf_info)786 static int aw_parse_acf_v_0_0_0_1(struct device *dev,
787 		struct acf_bin_info *acf_info)
788 
789 {
790 	int ret = 0;
791 	struct aw_all_prof_info all_prof_info;
792 
793 	AW_DEV_LOGD(dev, "enter");
794 	acf_info->prof_info.status = AW_ACF_WAIT;
795 
796 	memset(&all_prof_info, 0, sizeof(struct aw_all_prof_info));
797 
798 	ret = aw_parse_dev_type_v_0_0_0_1(dev, acf_info, &all_prof_info);
799 	if (ret < 0) {
800 		return ret;
801 	} else if (ret == AW_DEV_TYPE_NONE) {
802 		AW_DEV_LOGD(dev, "get dev type num is 0, parse default dev type");
803 		ret = aw_parse_default_type_v_0_0_0_1(dev, acf_info, &all_prof_info);
804 		if (ret < 0)
805 			return ret;
806 	}
807 
808 	ret = aw_get_vaild_prof_v_0_0_0_1(dev, acf_info, &all_prof_info);
809 	if (ret < 0) {
810 		aw_acf_profile_free(dev, acf_info);
811 		AW_DEV_LOGE(dev,  "hdr_cersion[0x%x] parse failed",
812 					acf_info->acf_hdr.hdr_version);
813 		return ret;
814 	}
815 
816 	ret = aw_set_prof_name_list_v_0_0_0_1(dev, acf_info);
817 	if (ret < 0) {
818 		aw_acf_profile_free(dev, acf_info);
819 		AW_DEV_LOGE(dev,  "creat prof_id_and_name_list failed");
820 		return ret;
821 	}
822 
823 	acf_info->prof_info.status = AW_ACF_UPDATE;
824 	AW_DEV_LOGI(dev, "acf parse success");
825 	return 0;
826 }
827 
828 /***************************************************************************
829  * V1.0.0.0 version acf paese
830  **************************************************************************/
aw_check_product_name_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info,struct aw_acf_dde_v_1_0_0_0 * prof_hdr)831 static int aw_check_product_name_v_1_0_0_0(struct device *dev,
832 				struct acf_bin_info *acf_info,
833 				struct aw_acf_dde_v_1_0_0_0 *prof_hdr)
834 {
835 	int i = 0;
836 
837 	for (i = 0; i < acf_info->product_cnt; i++) {
838 		if (0 == strcmp(acf_info->product_tab[i], prof_hdr->dev_name)) {
839 			AW_DEV_LOGI(dev, "bin_dev_name:%s", prof_hdr->dev_name);
840 			return 0;
841 		}
842 	}
843 
844 	return -ENXIO;
845 }
846 
aw_print_prof_off_name_can_support_v_1_0_0_0(struct device * dev)847 static void aw_print_prof_off_name_can_support_v_1_0_0_0(struct device *dev)
848 {
849 	int i = 0;
850 
851 	for (i = 0; i < AW_POWER_OFF_NAME_SUPPORT_COUNT; i++)
852 		AW_DEV_LOGI(dev, "support prof_off_name have string:[%s]", g_power_off_name[i]);
853 }
854 
aw_get_dde_type_info_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)855 static int aw_get_dde_type_info_v_1_0_0_0(struct device *dev,
856 					struct acf_bin_info *acf_info)
857 {
858 	int i;
859 	int dev_num = 0;
860 	int default_num = 0;
861 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data;
862 	struct aw_prof_info *prof_info = &acf_info->prof_info;
863 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
864 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset);
865 
866 	prof_info->prof_type = AW_DEV_NONE_TYPE_ID;
867 	for (i = 0; i < acf_hdr->dde_num; i++) {
868 		if (acf_dde[i].type == AW_DDE_DEV_TYPE_ID)
869 			dev_num++;
870 		if (acf_dde[i].type == AW_DDE_DEV_DEFAULT_TYPE_ID)
871 			default_num++;
872 	}
873 
874 	if (!(dev_num || default_num)) {
875 		AW_DEV_LOGE(dev, "can't find scene");
876 		return -EINVAL;
877 	}
878 
879 	if (dev_num != 0)
880 		prof_info->prof_type = AW_DDE_DEV_TYPE_ID;
881 	else if (default_num != 0)
882 		prof_info->prof_type = AW_DDE_DEV_DEFAULT_TYPE_ID;
883 
884 	return 0;
885 }
886 
887 
aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)888 static int aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device *dev,
889 						struct acf_bin_info *acf_info)
890 {
891 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
892 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data;
893 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
894 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset);
895 	int i = 0;
896 	int ret = 0;
897 	int found_off_prof_flag = 0;
898 	int count = acf_info->prof_info.count;
899 
900 	for (i = 0; i < acf_hdr->dde_num; ++i) {
901 		if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) ||
902 		(acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) &&
903 		((acf_info->aw_dev->i2c_bus == acf_dde[i].dev_bus) &&
904 		(acf_info->aw_dev->i2c_addr == acf_dde[i].dev_addr)) &&
905 		(acf_info->aw_dev->chipid == acf_dde[i].chip_id)) {
906 
907 			ret = aw_check_product_name_v_1_0_0_0(dev, acf_info, &acf_dde[i]);
908 			if (ret < 0)
909 				continue;
910 
911 			ret = aw_check_prof_str_is_off(acf_dde[i].dev_profile_str);
912 			if (ret == 0) {
913 				found_off_prof_flag = AW_PROFILE_OK;
914 				if (soft_off_enable) {
915 					count++;
916 				} else {
917 					AW_DEV_LOGE(dev, "profile_off is not allowed");
918 					return -EINVAL;
919 				}
920 			} else {
921 				count++;
922 			}
923 		}
924 	}
925 
926 	if (count == 0) {
927 		AW_DEV_LOGE(dev, "can't find profile");
928 		return -EINVAL;
929 	}
930 
931 	if (!found_off_prof_flag && soft_off_enable) {
932 		AW_DEV_LOGE(dev, "profile power off is necessary,but not found");
933 		aw_print_prof_off_name_can_support_v_1_0_0_0(dev);
934 		return -EINVAL;
935 	}
936 
937 	if (!found_off_prof_flag && !soft_off_enable) {
938 		count++;
939 		AW_DEV_LOGD(dev, "set no config power off profile in count");
940 	}
941 
942 	acf_info->prof_info.count = count;
943 	AW_DEV_LOGI(dev, "profile dev_type profile count is %d", acf_info->prof_info.count);
944 	return 0;
945 }
946 
aw_parse_get_default_type_prof_count_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)947 static int aw_parse_get_default_type_prof_count_v_1_0_0_0(struct device *dev,
948 						struct acf_bin_info *acf_info)
949 {
950 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
951 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data;
952 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
953 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset);
954 	int i = 0;
955 	int ret = 0;
956 	int found_off_prof_flag = 0;
957 	int count = acf_info->prof_info.count;
958 
959 	for (i = 0; i < acf_hdr->dde_num; ++i) {
960 		if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) ||
961 		(acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) &&
962 		(acf_info->dev_index == acf_dde[i].dev_index) &&
963 		(acf_info->aw_dev->chipid == acf_dde[i].chip_id)) {
964 
965 			ret = aw_check_product_name_v_1_0_0_0(dev, acf_info, &acf_dde[i]);
966 			if (ret < 0)
967 				continue;
968 
969 			ret = aw_check_prof_str_is_off(acf_dde[i].dev_profile_str);
970 			if (ret == 0) {
971 				found_off_prof_flag = AW_PROFILE_OK;
972 				if (soft_off_enable) {
973 					count++;
974 				} else {
975 					AW_DEV_LOGE(dev, "profile_off is not allowed");
976 					return -EINVAL;
977 				}
978 			} else {
979 				count++;
980 			}
981 		}
982 	}
983 
984 	if (count == 0) {
985 		AW_DEV_LOGE(dev, "can't find profile");
986 		return -EINVAL;
987 	}
988 
989 	if (!found_off_prof_flag && soft_off_enable) {
990 		AW_DEV_LOGE(dev, "profile power off is necessary,but not found");
991 		aw_print_prof_off_name_can_support_v_1_0_0_0(dev);
992 		return -EINVAL;
993 	}
994 
995 	if (!found_off_prof_flag && !soft_off_enable) {
996 		count++;
997 		AW_DEV_LOGD(dev, "set no config power off profile in count");
998 	}
999 
1000 	acf_info->prof_info.count = count;
1001 	AW_DEV_LOGI(dev, "profile default_type profile count is %d", acf_info->prof_info.count);
1002 	return 0;
1003 }
1004 
aw_parse_get_profile_count_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1005 static int aw_parse_get_profile_count_v_1_0_0_0(struct device *dev,
1006 						struct acf_bin_info *acf_info)
1007 {
1008 	int ret = 0;
1009 
1010 	ret = aw_get_dde_type_info_v_1_0_0_0(dev, acf_info);
1011 	if (ret < 0)
1012 		return ret;
1013 
1014 	if (acf_info->prof_info.prof_type == AW_DDE_DEV_TYPE_ID) {
1015 		ret = aw_parse_get_dev_type_prof_count_v_1_0_0_0(dev, acf_info);
1016 		if (ret < 0) {
1017 			AW_DEV_LOGE(dev, "parse dev_type profile count failed");
1018 			return ret;
1019 		}
1020 	} else if (acf_info->prof_info.prof_type == AW_DDE_DEV_DEFAULT_TYPE_ID) {
1021 		ret = aw_parse_get_default_type_prof_count_v_1_0_0_0(dev, acf_info);
1022 		if (ret < 0) {
1023 			AW_DEV_LOGE(dev, "parse default_type profile count failed");
1024 			return ret;
1025 		}
1026 	} else {
1027 		AW_DEV_LOGE(dev, "unsupport prof_type[0x%x]",
1028 			acf_info->prof_info.prof_type);
1029 		return -EINVAL;
1030 	}
1031 
1032 	AW_DEV_LOGI(dev, "profile count is %d", acf_info->prof_info.count);
1033 	return 0;
1034 }
1035 
aw_parse_dev_type_prof_name_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1036 static int aw_parse_dev_type_prof_name_v_1_0_0_0(struct device *dev,
1037 				struct acf_bin_info *acf_info)
1038 {
1039 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data;
1040 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
1041 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset);
1042 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1043 	int i, ret, list_index = 0;
1044 
1045 	for (i = 0; i < acf_hdr->dde_num; ++i) {
1046 		if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) ||
1047 		(acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) &&
1048 		(acf_info->aw_dev->i2c_bus == acf_dde[i].dev_bus) &&
1049 		(acf_info->aw_dev->i2c_addr == acf_dde[i].dev_addr) &&
1050 		(acf_info->aw_dev->chipid == acf_dde[i].chip_id)) {
1051 			if (list_index > prof_info->count) {
1052 				AW_DEV_LOGE(dev, "%s:Alrealdy set list_index [%d], redundant profile [%s]exist\n",
1053 					__func__, list_index,
1054 					acf_dde[i].dev_profile_str);
1055 				return -EINVAL;
1056 			}
1057 
1058 			ret = aw_check_product_name_v_1_0_0_0(dev, acf_info, &acf_dde[i]);
1059 			if (ret < 0)
1060 				continue;
1061 
1062 			snprintf(prof_info->prof_name_list[list_index], AW_PROFILE_STR_MAX, "%s",
1063 				acf_dde[i].dev_profile_str);
1064 			AW_DEV_LOGI(dev, "profile_name=[%s]",
1065 					prof_info->prof_name_list[list_index]);
1066 			list_index++;
1067 		}
1068 	}
1069 
1070 	return 0;
1071 }
1072 
aw_parse_default_type_prof_name_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1073 static int aw_parse_default_type_prof_name_v_1_0_0_0(struct device *dev,
1074 				struct acf_bin_info *acf_info)
1075 {
1076 	struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data;
1077 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
1078 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset);
1079 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1080 	int i, ret, list_index = 0;
1081 
1082 	for (i = 0; i < acf_hdr->dde_num; ++i) {
1083 		if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) ||
1084 		(acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) &&
1085 		(acf_info->dev_index == acf_dde[i].dev_index) &&
1086 		(acf_info->aw_dev->chipid == acf_dde[i].chip_id)) {
1087 			if (list_index > prof_info->count) {
1088 				AW_DEV_LOGE(dev, "%s:Alrealdy set list_index [%d], redundant profile [%s]exist\n",
1089 					__func__, list_index,
1090 					acf_dde[i].dev_profile_str);
1091 				return -EINVAL;
1092 			}
1093 
1094 			ret = aw_check_product_name_v_1_0_0_0(dev, acf_info, &acf_dde[i]);
1095 			if (ret < 0)
1096 				continue;
1097 
1098 			snprintf(prof_info->prof_name_list[list_index], AW_PROFILE_STR_MAX, "%s",
1099 				acf_dde[i].dev_profile_str);
1100 			AW_DEV_LOGI(dev, "profile_name=[%s]",
1101 					prof_info->prof_name_list[list_index]);
1102 			list_index++;
1103 		}
1104 	}
1105 
1106 	return 0;
1107 }
1108 
aw_parse_prof_name_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1109 static int aw_parse_prof_name_v_1_0_0_0(struct device *dev,
1110 						struct acf_bin_info *acf_info)
1111 {
1112 	int ret = 0;
1113 	int count = acf_info->prof_info.count;
1114 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1115 
1116 	prof_info->prof_name_list = (char (*)[AW_PROFILE_STR_MAX])devm_kzalloc(dev,
1117 		count * (AW_PROFILE_STR_MAX), GFP_KERNEL);
1118 	if (prof_info->prof_name_list == NULL) {
1119 		AW_DEV_LOGE(dev, "prof_name_list devm_kzalloc failed");
1120 		return -ENOMEM;
1121 	}
1122 
1123 	if (acf_info->prof_info.prof_type == AW_DDE_DEV_TYPE_ID) {
1124 		ret = aw_parse_dev_type_prof_name_v_1_0_0_0(dev, acf_info);
1125 		if (ret < 0) {
1126 			AW_DEV_LOGE(dev, "parse dev_type profile count failed");
1127 			return ret;
1128 		}
1129 	} else if (acf_info->prof_info.prof_type == AW_DDE_DEV_DEFAULT_TYPE_ID) {
1130 		ret = aw_parse_default_type_prof_name_v_1_0_0_0(dev, acf_info);
1131 		if (ret < 0) {
1132 			AW_DEV_LOGE(dev, "parse default_type profile count failed");
1133 			return ret;
1134 		}
1135 	} else {
1136 		AW_DEV_LOGE(dev, "unsupport prof_type[0x%x]",
1137 			acf_info->prof_info.prof_type);
1138 		return -EINVAL;
1139 	}
1140 
1141 	AW_DEV_LOGI(dev, "profile name parse succeed");
1142 	return 0;
1143 }
1144 
1145 
aw_search_prof_index_from_list_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info,struct aw_prof_desc ** prof_desc,struct aw_acf_dde_v_1_0_0_0 * prof_hdr)1146 static int aw_search_prof_index_from_list_v_1_0_0_0(struct device *dev,
1147 				struct acf_bin_info *acf_info,
1148 				struct aw_prof_desc **prof_desc,
1149 				struct aw_acf_dde_v_1_0_0_0 *prof_hdr)
1150 {
1151 	int i = 0;
1152 	int count = acf_info->prof_info.count;
1153 	char (*prof_name_list)[AW_PROFILE_STR_MAX] = acf_info->prof_info.prof_name_list;
1154 
1155 	for (i = 0; i < count; i++) {
1156 		if (!strncmp(prof_name_list[i], prof_hdr->dev_profile_str, AW_PROFILE_STR_MAX)) {
1157 			*prof_desc = &(acf_info->prof_info.prof_desc[i]);
1158 			return 0;
1159 		}
1160 	}
1161 
1162 	if (i == count)
1163 		AW_DEV_LOGE(dev, "not find prof_id and prof_name in list");
1164 
1165 	return -EINVAL;
1166 }
1167 
aw_parse_data_by_sec_type_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info,struct aw_acf_dde_v_1_0_0_0 * prof_hdr)1168 static int aw_parse_data_by_sec_type_v_1_0_0_0(struct device *dev,
1169 				struct acf_bin_info *acf_info,
1170 				struct aw_acf_dde_v_1_0_0_0 *prof_hdr)
1171 {
1172 	int ret = -1;
1173 	char *cfg_data = acf_info->fw_data + prof_hdr->data_offset;
1174 	struct aw_prof_desc *prof_desc = NULL;
1175 
1176 	ret = aw_search_prof_index_from_list_v_1_0_0_0(dev, acf_info, &prof_desc, prof_hdr);
1177 	if (ret < 0)
1178 		return ret;
1179 
1180 	switch (prof_hdr->data_type) {
1181 	case AW_BIN_TYPE_REG:
1182 		snprintf(prof_desc->dev_name, sizeof(prof_hdr->dev_name),
1183 			"%s", prof_hdr->dev_name);
1184 		AW_DEV_LOGI(dev, "parse reg type data enter,product=[%s],prof_id=[%d],prof_name=[%s]",
1185 			prof_hdr->dev_name, prof_hdr->dev_profile,
1186 			prof_hdr->dev_profile_str);
1187 		prof_desc->prof_name = prof_hdr->dev_profile_str;
1188 		ret =  aw_parse_raw_reg(dev, cfg_data, prof_hdr->data_size,
1189 					prof_desc);
1190 		break;
1191 	case AW_BIN_TYPE_HDR_REG:
1192 		snprintf(prof_desc->dev_name, sizeof(prof_hdr->dev_name),
1193 			"%s", prof_hdr->dev_name);
1194 		AW_DEV_LOGI(dev, "parse hdr_reg type data enter,product=[%s],prof_id=[%d],prof_name=[%s]",
1195 			prof_hdr->dev_name, prof_hdr->dev_profile,
1196 			prof_hdr->dev_profile_str);
1197 		prof_desc->prof_name = prof_hdr->dev_profile_str;
1198 		ret = aw_parse_reg_with_hdr(dev, cfg_data,
1199 				prof_hdr->data_size, prof_desc);
1200 		break;
1201 	}
1202 
1203 	return ret;
1204 }
1205 
aw_parse_dev_type_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1206 static int aw_parse_dev_type_v_1_0_0_0(struct device *dev,
1207 				struct acf_bin_info *acf_info)
1208 {
1209 	int i = 0;
1210 	int ret;
1211 	int parse_prof_count = 0;
1212 	char *cfg_data = NULL;
1213 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
1214 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_info->acf_hdr.ddt_offset);
1215 
1216 	AW_DEV_LOGD(dev, "enter");
1217 
1218 	for (i = 0; i < acf_info->acf_hdr.dde_num; i++) {
1219 		if ((acf_dde[i].type == AW_DDE_DEV_TYPE_ID) &&
1220 		(acf_info->aw_dev->i2c_bus == acf_dde[i].dev_bus) &&
1221 		(acf_info->aw_dev->i2c_addr == acf_dde[i].dev_addr) &&
1222 		(acf_info->aw_dev->chipid == acf_dde[i].chip_id)) {
1223 			ret = aw_check_product_name_v_1_0_0_0(dev, acf_info, &acf_dde[i]);
1224 			if (ret < 0)
1225 				continue;
1226 
1227 			if (acf_dde[i].data_type == AW_MONITOR) {
1228 				cfg_data = acf_info->fw_data + acf_dde[i].data_offset;
1229 				AW_DEV_LOGD(dev, "parse monitor type data enter");
1230 				ret = aw_parse_monitor_config(dev, cfg_data,
1231 					acf_dde[i].data_size);
1232 			} else {
1233 				ret = aw_parse_data_by_sec_type_v_1_0_0_0(dev, acf_info,
1234 					&acf_dde[i]);
1235 				if (ret < 0)
1236 					AW_DEV_LOGE(dev, "parse dev type data failed");
1237 				else
1238 					parse_prof_count++;
1239 			}
1240 		}
1241 	}
1242 
1243 	if (parse_prof_count == 0) {
1244 		AW_DEV_LOGE(dev, "get dev type num is %d, parse failed", parse_prof_count);
1245 		return -EINVAL;
1246 	}
1247 
1248 	return AW_DEV_TYPE_OK;
1249 }
1250 
aw_parse_default_type_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1251 static int aw_parse_default_type_v_1_0_0_0(struct device *dev,
1252 				struct acf_bin_info *acf_info)
1253 {
1254 	int i = 0;
1255 	int ret;
1256 	int parse_prof_count = 0;
1257 	char *cfg_data = NULL;
1258 	struct aw_acf_dde_v_1_0_0_0 *acf_dde =
1259 		(struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_info->acf_hdr.ddt_offset);
1260 
1261 	AW_DEV_LOGD(dev, "enter");
1262 
1263 	for (i = 0; i < acf_info->acf_hdr.dde_num; i++) {
1264 		if ((acf_dde[i].type == AW_DDE_DEV_DEFAULT_TYPE_ID) &&
1265 		(acf_info->dev_index == acf_dde[i].dev_index) &&
1266 		(acf_info->aw_dev->chipid == acf_dde[i].chip_id)) {
1267 			ret = aw_check_product_name_v_1_0_0_0(dev, acf_info, &acf_dde[i]);
1268 			if (ret < 0)
1269 				continue;
1270 
1271 			if (acf_dde[i].data_type == AW_MONITOR) {
1272 				cfg_data = acf_info->fw_data + acf_dde[i].data_offset;
1273 				AW_DEV_LOGD(dev, "parse monitor type data enter");
1274 				ret = aw_parse_monitor_config(dev, cfg_data,
1275 					acf_dde[i].data_size);
1276 			} else {
1277 				ret = aw_parse_data_by_sec_type_v_1_0_0_0(dev, acf_info,
1278 					&acf_dde[i]);
1279 				if (ret < 0)
1280 					AW_DEV_LOGE(dev, "parse default type data failed");
1281 				else
1282 					parse_prof_count++;
1283 			}
1284 		}
1285 	}
1286 
1287 	if (parse_prof_count == 0) {
1288 		AW_DEV_LOGE(dev, "get default type num is %d,parse failed", parse_prof_count);
1289 		return -EINVAL;
1290 	}
1291 
1292 	return AW_DEV_TYPE_OK;
1293 }
1294 
aw_parse_by_hdr_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1295 static int aw_parse_by_hdr_v_1_0_0_0(struct device *dev,
1296 				struct acf_bin_info *acf_info)
1297 {
1298 	int ret;
1299 
1300 	if (acf_info->prof_info.prof_type == AW_DDE_DEV_TYPE_ID) {
1301 		ret = aw_parse_dev_type_v_1_0_0_0(dev, acf_info);
1302 		if (ret < 0)
1303 			return ret;
1304 	} else if (acf_info->prof_info.prof_type == AW_DDE_DEV_DEFAULT_TYPE_ID) {
1305 		ret = aw_parse_default_type_v_1_0_0_0(dev, acf_info);
1306 		if (ret < 0)
1307 			return ret;
1308 	}
1309 
1310 	return 0;
1311 }
1312 
aw_set_prof_off_info_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1313 static int aw_set_prof_off_info_v_1_0_0_0(struct device *dev,
1314 						struct acf_bin_info *acf_info)
1315 {
1316 	uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable;
1317 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1318 	int i = 0;
1319 	int ret = 0;
1320 
1321 	for (i = 0; i < prof_info->count; ++i) {
1322 		if (!(prof_info->prof_desc[i].prof_st) && !soft_off_enable) {
1323 			snprintf(prof_info->prof_name_list[i], AW_PROFILE_STR_MAX, "%s",
1324 					g_power_off_name[0]);
1325 			prof_info->prof_desc[i].prof_name = prof_info->prof_name_list[i];
1326 			prof_info->prof_desc[i].prof_st = AW_PROFILE_WAIT;
1327 			memset(&prof_info->prof_desc[i].data_container, 0,
1328 					sizeof(struct aw_data_container));
1329 			return 0;
1330 		}
1331 
1332 		ret = aw_check_prof_str_is_off(prof_info->prof_name_list[i]);
1333 		if (ret == 0) {
1334 			AW_DEV_LOGD(dev, "found profile off,data_len=[%d]",
1335 				prof_info->prof_desc[i].data_container.len);
1336 			return 0;
1337 		}
1338 	}
1339 
1340 	AW_DEV_LOGE(dev, "index[%d] is out of table,profile count[%d]",
1341 		i, prof_info->count);
1342 	return -EINVAL;
1343 }
1344 
aw_parse_acf_v_1_0_0_0(struct device * dev,struct acf_bin_info * acf_info)1345 static int aw_parse_acf_v_1_0_0_0(struct device *dev,
1346 		struct acf_bin_info *acf_info)
1347 
1348 {
1349 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1350 	int ret;
1351 
1352 	ret = aw_parse_get_profile_count_v_1_0_0_0(dev, acf_info);
1353 	if (ret < 0) {
1354 		AW_DEV_LOGE(dev, "get profile count failed");
1355 		return ret;
1356 	}
1357 
1358 	ret = aw_parse_prof_name_v_1_0_0_0(dev, acf_info);
1359 	if (ret < 0) {
1360 		AW_DEV_LOGE(dev, "get profile count failed");
1361 		return ret;
1362 	}
1363 
1364 	acf_info->prof_info.prof_desc = devm_kzalloc(dev,
1365 		prof_info->count * sizeof(struct aw_prof_desc), GFP_KERNEL);
1366 	if (acf_info->prof_info.prof_desc == NULL) {
1367 		AW_DEV_LOGE(dev, "prof_desc devm_kzalloc failed");
1368 		return -ENOMEM;
1369 	}
1370 
1371 	ret = aw_parse_by_hdr_v_1_0_0_0(dev, acf_info);
1372 	if (ret < 0) {
1373 		AW_DEV_LOGE(dev, "parse data failed");
1374 		return ret;
1375 	}
1376 
1377 	ret = aw_set_prof_off_info_v_1_0_0_0(dev, acf_info);
1378 	if (ret < 0) {
1379 		AW_DEV_LOGE(dev, "set profile off info failed");
1380 		return ret;
1381 	}
1382 
1383 	prof_info->status = AW_ACF_UPDATE;
1384 	AW_DEV_LOGI(dev, "acf paese succeed");
1385 	return 0;
1386 }
1387 
1388 
1389 /*************************************************************************
1390  *
1391  *acf parse API
1392  *
1393  *************************************************************************/
aw_acf_profile_free(struct device * dev,struct acf_bin_info * acf_info)1394 void aw_acf_profile_free(struct device *dev, struct acf_bin_info *acf_info)
1395 {
1396 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1397 
1398 	prof_info->count = 0;
1399 	prof_info->status = AW_ACF_WAIT;
1400 	memset(&acf_info->acf_hdr, 0, sizeof(struct aw_acf_hdr));
1401 
1402 	if (prof_info->prof_desc) {
1403 		devm_kfree(dev, prof_info->prof_desc);
1404 		prof_info->prof_desc = NULL;
1405 	}
1406 
1407 	if (prof_info->prof_name_list) {
1408 		devm_kfree(dev, prof_info->prof_name_list);
1409 		prof_info->prof_name_list = NULL;
1410 	}
1411 
1412 	if (acf_info->fw_data) {
1413 		vfree(acf_info->fw_data);
1414 		acf_info->fw_data = NULL;
1415 	}
1416 }
1417 
aw_acf_parse(struct device * dev,struct acf_bin_info * acf_info)1418 int aw_acf_parse(struct device *dev, struct acf_bin_info *acf_info)
1419 {
1420 	int ret = 0;
1421 
1422 	AW_DEV_LOGD(dev, "enter");
1423 	acf_info->prof_info.status = AW_ACF_WAIT;
1424 	ret = aw_check_acf_firmware(dev, acf_info->fw_data,
1425 					acf_info->fw_size);
1426 	if (ret < 0) {
1427 		AW_DEV_LOGE(dev, "load firmware check failed");
1428 		return -EINVAL;
1429 	}
1430 
1431 	memcpy(&acf_info->acf_hdr, acf_info->fw_data,
1432 		sizeof(struct aw_acf_hdr));
1433 
1434 	switch (acf_info->acf_hdr.hdr_version) {
1435 	case AW_ACF_HDR_VER_0_0_0_1:
1436 		return aw_parse_acf_v_0_0_0_1(dev, acf_info);
1437 	case AW_ACF_HDR_VER_1_0_0_0:
1438 		return aw_parse_acf_v_1_0_0_0(dev, acf_info);
1439 	default:
1440 		AW_DEV_LOGE(dev, "unsupported hdr_version [0x%x]",
1441 			acf_info->acf_hdr.hdr_version);
1442 		return -EINVAL;
1443 	}
1444 
1445 	return ret;
1446 }
1447 
aw_acf_get_prof_desc_form_name(struct device * dev,struct acf_bin_info * acf_info,char * profile_name)1448 struct aw_prof_desc *aw_acf_get_prof_desc_form_name(struct device *dev,
1449 			struct acf_bin_info *acf_info, char *profile_name)
1450 {
1451 	int i = 0;
1452 	struct aw_prof_desc *prof_desc = NULL;
1453 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1454 
1455 	AW_DEV_LOGD(dev, "enter");
1456 
1457 	if (!acf_info->prof_info.status) {
1458 		AW_DEV_LOGE(dev, "profile_cfg not load");
1459 		return NULL;
1460 	}
1461 
1462 	for (i = 0; i < prof_info->count; i++) {
1463 		if (!strncmp(profile_name, prof_info->prof_desc[i].prof_name,
1464 				AW_PROFILE_STR_MAX)) {
1465 			prof_desc = &prof_info->prof_desc[i];
1466 			break;
1467 		}
1468 	}
1469 
1470 	if (i == prof_info->count) {
1471 		AW_DEV_LOGE(dev, "profile not found");
1472 		return NULL;
1473 	}
1474 
1475 	AW_DEV_LOGI(dev, "get prof desc down");
1476 	return prof_desc;
1477 }
1478 
aw_acf_get_prof_index_form_name(struct device * dev,struct acf_bin_info * acf_info,char * profile_name)1479 int aw_acf_get_prof_index_form_name(struct device *dev,
1480 			struct acf_bin_info *acf_info, char *profile_name)
1481 {
1482 	int i = 0;
1483 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1484 
1485 	if (!acf_info->prof_info.status) {
1486 		AW_DEV_LOGE(dev, "profile_cfg not load");
1487 		return -EINVAL;
1488 	}
1489 
1490 	for (i = 0; i < prof_info->count; i++) {
1491 		if (!strncmp(profile_name, prof_info->prof_name_list[i],
1492 				AW_PROFILE_STR_MAX)) {
1493 			return i;
1494 		}
1495 	}
1496 
1497 	AW_DEV_LOGE(dev, "profile_index not found");
1498 	return -EINVAL;
1499 }
1500 
aw_acf_get_prof_name_form_index(struct device * dev,struct acf_bin_info * acf_info,int index)1501 char *aw_acf_get_prof_name_form_index(struct device *dev,
1502 			struct acf_bin_info *acf_info, int index)
1503 {
1504 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1505 
1506 	if (!acf_info->prof_info.status) {
1507 		AW_DEV_LOGE(dev, "profile_cfg not load");
1508 		return NULL;
1509 	}
1510 
1511 	if (index >= prof_info->count  || index < 0) {
1512 		AW_DEV_LOGE(dev, "profile_index out of table");
1513 		return NULL;
1514 	}
1515 
1516 	return prof_info->prof_desc[index].prof_name;
1517 }
1518 
1519 
aw_acf_get_profile_count(struct device * dev,struct acf_bin_info * acf_info)1520 int aw_acf_get_profile_count(struct device *dev,
1521 			struct acf_bin_info *acf_info)
1522 {
1523 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1524 
1525 	if (!acf_info->prof_info.status) {
1526 		AW_DEV_LOGE(dev, "profile_cfg not load");
1527 		return -EINVAL;
1528 	}
1529 
1530 	if (prof_info->count > 0) {
1531 		return prof_info->count;
1532 	}
1533 
1534 	return -EINVAL;
1535 }
1536 
aw_acf_get_prof_off_name(struct device * dev,struct acf_bin_info * acf_info)1537 char *aw_acf_get_prof_off_name(struct device *dev,
1538 			struct acf_bin_info *acf_info)
1539 {
1540 	int i = 0;
1541 	int ret = 0;
1542 	struct aw_prof_info *prof_info = &acf_info->prof_info;
1543 
1544 	if (!acf_info->prof_info.status) {
1545 		AW_DEV_LOGE(dev, "profile_cfg not load");
1546 		return NULL;
1547 	}
1548 
1549 	for (i = 0; i < prof_info->count; i++) {
1550 		ret  = aw_check_prof_str_is_off(prof_info->prof_name_list[i]);
1551 		if (ret == 0)
1552 			return prof_info->prof_name_list[i];
1553 	}
1554 
1555 	return NULL;
1556 }
1557 
aw_acf_init(struct aw_device * aw_dev,struct acf_bin_info * acf_info,int index)1558 void aw_acf_init(struct aw_device *aw_dev, struct acf_bin_info *acf_info, int index)
1559 {
1560 
1561 	acf_info->load_count = 0;
1562 	acf_info->prof_info.status = AW_ACF_WAIT;
1563 	acf_info->dev_index = index;
1564 	acf_info->aw_dev = aw_dev;
1565 	acf_info->product_cnt = aw_dev->product_cnt;
1566 	acf_info->product_tab = aw_dev->product_tab;
1567 	acf_info->prof_info.prof_desc = NULL;
1568 	acf_info->fw_data = NULL;
1569 	acf_info->fw_size = 0;
1570 }
1571 
1572