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