1 // SPDX-License-Identifier: GPL-2.0-only
3 // aw88395_lib.c -- ACF bin parsing and check library file for aw88395
5 // Copyright (c) 2022-2023 AWINIC Technology CO., LTD
7 // Author: Bruce zhao <zhaolei@awinic.com>
10 #include <linux/crc8.h>
11 #include <linux/i2c.h>
12 #include "aw88395_lib.h"
13 #include "aw88395_device.h"
14 #include "aw88395_reg.h"
16 #define AW88395_CRC8_POLYNOMIAL 0x8C
17 DECLARE_CRC8_TABLE(aw_crc8_table
);
19 static char *profile_name
[AW88395_PROFILE_MAX
] = {
20 "Music", "Voice", "Voip", "Ringtone",
21 "Ringtone_hs", "Lowpower", "Bypass",
22 "Mmi", "Fm", "Notification", "Receiver"
25 static int aw_parse_bin_header(struct aw_device
*aw_dev
, struct aw_bin
*bin
);
27 static int aw_check_sum(struct aw_device
*aw_dev
, struct aw_bin
*bin
, int bin_num
)
29 unsigned char *p_check_sum
;
30 unsigned int sum_data
= 0;
31 unsigned int check_sum
;
34 p_check_sum
= &(bin
->info
.data
[(bin
->header_info
[bin_num
].valid_data_addr
-
35 bin
->header_info
[bin_num
].header_len
)]);
36 len
= bin
->header_info
[bin_num
].bin_data_len
+ bin
->header_info
[bin_num
].header_len
;
37 check_sum
= le32_to_cpup((void *)p_check_sum
);
39 for (i
= 4; i
< len
; i
++)
40 sum_data
+= *(p_check_sum
+ i
);
42 dev_dbg(aw_dev
->dev
, "%s -- check_sum = %p, check_sum = 0x%x, sum_data = 0x%x",
43 __func__
, p_check_sum
, check_sum
, sum_data
);
44 if (sum_data
!= check_sum
) {
45 dev_err(aw_dev
->dev
, "%s. CheckSum Fail.bin_num=%d, CheckSum:0x%x, SumData:0x%x",
46 __func__
, bin_num
, check_sum
, sum_data
);
53 static int aw_check_data_version(struct aw_device
*aw_dev
, struct aw_bin
*bin
, int bin_num
)
55 if (bin
->header_info
[bin_num
].bin_data_ver
< DATA_VERSION_V1
||
56 bin
->header_info
[bin_num
].bin_data_ver
> DATA_VERSION_MAX
) {
57 dev_err(aw_dev
->dev
, "aw_bin_parse Unrecognized this bin data version\n");
64 static int aw_check_register_num(struct aw_device
*aw_dev
, struct aw_bin
*bin
, int bin_num
)
66 struct bin_header_info temp_info
= bin
->header_info
[bin_num
];
67 unsigned int check_register_num
, parse_register_num
;
68 unsigned char *p_check_sum
;
70 p_check_sum
= &(bin
->info
.data
[(temp_info
.valid_data_addr
)]);
72 parse_register_num
= le32_to_cpup((void *)p_check_sum
);
73 check_register_num
= (bin
->header_info
[bin_num
].bin_data_len
- CHECK_REGISTER_NUM_OFFSET
) /
74 (bin
->header_info
[bin_num
].reg_byte_len
+
75 bin
->header_info
[bin_num
].data_byte_len
);
76 dev_dbg(aw_dev
->dev
, "%s,parse_register_num = 0x%x,check_register_num = 0x%x\n",
77 __func__
, parse_register_num
, check_register_num
);
78 if (parse_register_num
!= check_register_num
) {
79 dev_err(aw_dev
->dev
, "%s parse_register_num = 0x%x,check_register_num = 0x%x\n",
80 __func__
, parse_register_num
, check_register_num
);
84 bin
->header_info
[bin_num
].reg_num
= parse_register_num
;
85 bin
->header_info
[bin_num
].valid_data_len
= temp_info
.bin_data_len
- VALID_DATA_LEN
;
86 bin
->header_info
[bin_num
].valid_data_addr
= temp_info
.valid_data_addr
+ VALID_DATA_ADDR
;
91 static int aw_check_dsp_reg_num(struct aw_device
*aw_dev
, struct aw_bin
*bin
, int bin_num
)
93 struct bin_header_info temp_info
= bin
->header_info
[bin_num
];
94 unsigned int check_dsp_reg_num
, parse_dsp_reg_num
;
95 unsigned char *p_check_sum
;
97 p_check_sum
= &(bin
->info
.data
[(temp_info
.valid_data_addr
)]);
99 parse_dsp_reg_num
= le32_to_cpup((void *)(p_check_sum
+ PARSE_DSP_REG_NUM
));
100 bin
->header_info
[bin_num
].reg_data_byte_len
=
101 le32_to_cpup((void *)(p_check_sum
+ REG_DATA_BYTP_LEN
));
102 check_dsp_reg_num
= (bin
->header_info
[bin_num
].bin_data_len
- CHECK_DSP_REG_NUM
) /
103 bin
->header_info
[bin_num
].reg_data_byte_len
;
104 dev_dbg(aw_dev
->dev
, "%s bin_num = %d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x",
105 __func__
, bin_num
, check_dsp_reg_num
, check_dsp_reg_num
);
106 if (parse_dsp_reg_num
!= check_dsp_reg_num
) {
107 dev_err(aw_dev
->dev
, "aw_bin_parse check dsp reg num error\n");
108 dev_err(aw_dev
->dev
, "%s parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x",
109 __func__
, check_dsp_reg_num
, check_dsp_reg_num
);
113 bin
->header_info
[bin_num
].download_addr
= le32_to_cpup((void *)p_check_sum
);
114 bin
->header_info
[bin_num
].reg_num
= parse_dsp_reg_num
;
115 bin
->header_info
[bin_num
].valid_data_len
= temp_info
.bin_data_len
- DSP_VALID_DATA_LEN
;
116 bin
->header_info
[bin_num
].valid_data_addr
= temp_info
.valid_data_addr
+
122 static int aw_check_soc_app_num(struct aw_device
*aw_dev
, struct aw_bin
*bin
, int bin_num
)
124 struct bin_header_info temp_info
= bin
->header_info
[bin_num
];
125 unsigned int check_soc_app_num
, parse_soc_app_num
;
126 unsigned char *p_check_sum
;
128 p_check_sum
= &(bin
->info
.data
[(temp_info
.valid_data_addr
)]);
130 bin
->header_info
[bin_num
].app_version
= le32_to_cpup((void *)p_check_sum
);
131 parse_soc_app_num
= le32_to_cpup((void *)(p_check_sum
+ PARSE_SOC_APP_NUM
));
132 check_soc_app_num
= bin
->header_info
[bin_num
].bin_data_len
- CHECK_SOC_APP_NUM
;
133 dev_dbg(aw_dev
->dev
, "%s bin_num = %d, parse_soc_app_num=0x%x, check_soc_app_num = 0x%x\n",
134 __func__
, bin_num
, parse_soc_app_num
, check_soc_app_num
);
135 if (parse_soc_app_num
!= check_soc_app_num
) {
136 dev_err(aw_dev
->dev
, "%s parse_soc_app_num=0x%x, check_soc_app_num = 0x%x\n",
137 __func__
, parse_soc_app_num
, check_soc_app_num
);
141 bin
->header_info
[bin_num
].reg_num
= parse_soc_app_num
;
142 bin
->header_info
[bin_num
].download_addr
= le32_to_cpup((void *)(p_check_sum
+
144 bin
->header_info
[bin_num
].valid_data_len
= temp_info
.bin_data_len
- APP_VALID_DATA_LEN
;
145 bin
->header_info
[bin_num
].valid_data_addr
= temp_info
.valid_data_addr
+
151 static void aw_get_single_bin_header(struct aw_bin
*bin
)
153 memcpy((void *)&bin
->header_info
[bin
->all_bin_parse_num
], bin
->p_addr
, DATA_LEN
);
155 bin
->header_info
[bin
->all_bin_parse_num
].header_len
= HEADER_LEN
;
156 bin
->all_bin_parse_num
+= 1;
159 static int aw_parse_one_of_multi_bins(struct aw_device
*aw_dev
, unsigned int bin_num
,
160 int bin_serial_num
, struct aw_bin
*bin
)
162 struct bin_header_info aw_bin_header_info
;
163 unsigned int bin_start_addr
;
164 unsigned int valid_data_len
;
166 if (bin
->info
.len
< sizeof(struct bin_header_info
)) {
167 dev_err(aw_dev
->dev
, "bin_header_info size[%d] overflow file size[%d]\n",
168 (int)sizeof(struct bin_header_info
), bin
->info
.len
);
172 aw_bin_header_info
= bin
->header_info
[bin
->all_bin_parse_num
- 1];
173 if (!bin_serial_num
) {
174 bin_start_addr
= le32_to_cpup((void *)(bin
->p_addr
+ START_ADDR_OFFSET
));
175 bin
->p_addr
+= (HEADER_LEN
+ bin_start_addr
);
176 bin
->header_info
[bin
->all_bin_parse_num
].valid_data_addr
=
177 aw_bin_header_info
.valid_data_addr
+ VALID_DATA_ADDR
+ 8 * bin_num
+
178 VALID_DATA_ADDR_OFFSET
;
180 valid_data_len
= aw_bin_header_info
.bin_data_len
;
181 bin
->p_addr
+= (HDADER_LEN
+ valid_data_len
);
182 bin
->header_info
[bin
->all_bin_parse_num
].valid_data_addr
=
183 aw_bin_header_info
.valid_data_addr
+ aw_bin_header_info
.bin_data_len
+
184 VALID_DATA_ADDR_OFFSET
;
187 return aw_parse_bin_header(aw_dev
, bin
);
190 static int aw_get_multi_bin_header(struct aw_device
*aw_dev
, struct aw_bin
*bin
)
192 unsigned int bin_num
, i
;
195 bin_num
= le32_to_cpup((void *)(bin
->p_addr
+ VALID_DATA_ADDR_OFFSET
));
196 if (bin
->multi_bin_parse_num
== 1)
197 bin
->header_info
[bin
->all_bin_parse_num
].valid_data_addr
=
198 VALID_DATA_ADDR_OFFSET
;
200 aw_get_single_bin_header(bin
);
202 for (i
= 0; i
< bin_num
; i
++) {
203 dev_dbg(aw_dev
->dev
, "aw_bin_parse enter multi bin for is %d\n", i
);
204 ret
= aw_parse_one_of_multi_bins(aw_dev
, bin_num
, i
, bin
);
212 static int aw_parse_bin_header(struct aw_device
*aw_dev
, struct aw_bin
*bin
)
214 unsigned int bin_data_type
;
216 if (bin
->info
.len
< sizeof(struct bin_header_info
)) {
217 dev_err(aw_dev
->dev
, "bin_header_info size[%d] overflow file size[%d]\n",
218 (int)sizeof(struct bin_header_info
), bin
->info
.len
);
222 bin_data_type
= le32_to_cpup((void *)(bin
->p_addr
+ BIN_DATA_TYPE_OFFSET
));
223 dev_dbg(aw_dev
->dev
, "aw_bin_parse bin_data_type 0x%x\n", bin_data_type
);
224 switch (bin_data_type
) {
225 case DATA_TYPE_REGISTER
:
226 case DATA_TYPE_DSP_REG
:
227 case DATA_TYPE_SOC_APP
:
228 bin
->single_bin_parse_num
+= 1;
229 dev_dbg(aw_dev
->dev
, "%s bin->single_bin_parse_num is %d\n", __func__
,
230 bin
->single_bin_parse_num
);
231 if (!bin
->multi_bin_parse_num
)
232 bin
->header_info
[bin
->all_bin_parse_num
].valid_data_addr
=
233 VALID_DATA_ADDR_OFFSET
;
234 aw_get_single_bin_header(bin
);
236 case DATA_TYPE_MULTI_BINS
:
237 bin
->multi_bin_parse_num
+= 1;
238 dev_dbg(aw_dev
->dev
, "%s bin->multi_bin_parse_num is %d\n", __func__
,
239 bin
->multi_bin_parse_num
);
240 return aw_get_multi_bin_header(aw_dev
, bin
);
242 dev_dbg(aw_dev
->dev
, "%s There is no corresponding type\n", __func__
);
247 static int aw_check_bin_header_version(struct aw_device
*aw_dev
, struct aw_bin
*bin
)
249 unsigned int header_version
;
251 header_version
= le32_to_cpup((void *)(bin
->p_addr
+ HEADER_VERSION_OFFSET
));
252 dev_dbg(aw_dev
->dev
, "aw_bin_parse header_version 0x%x\n", header_version
);
254 switch (header_version
) {
255 case HEADER_VERSION_V1
:
256 return aw_parse_bin_header(aw_dev
, bin
);
258 dev_err(aw_dev
->dev
, "aw_bin_parse Unrecognized this bin header version\n");
263 static int aw_parsing_bin_file(struct aw_device
*aw_dev
, struct aw_bin
*bin
)
269 dev_err(aw_dev
->dev
, "aw_bin_parse bin is NULL\n");
272 bin
->p_addr
= bin
->info
.data
;
273 bin
->all_bin_parse_num
= 0;
274 bin
->multi_bin_parse_num
= 0;
275 bin
->single_bin_parse_num
= 0;
277 ret
= aw_check_bin_header_version(aw_dev
, bin
);
279 dev_err(aw_dev
->dev
, "aw_bin_parse check bin header version error\n");
283 for (i
= 0; i
< bin
->all_bin_parse_num
; i
++) {
284 ret
= aw_check_sum(aw_dev
, bin
, i
);
286 dev_err(aw_dev
->dev
, "aw_bin_parse check sum data error\n");
289 ret
= aw_check_data_version(aw_dev
, bin
, i
);
291 dev_err(aw_dev
->dev
, "aw_bin_parse check data version error\n");
294 if (bin
->header_info
[i
].bin_data_ver
== DATA_VERSION_V1
) {
295 switch (bin
->header_info
[i
].bin_data_type
) {
296 case DATA_TYPE_REGISTER
:
297 ret
= aw_check_register_num(aw_dev
, bin
, i
);
299 case DATA_TYPE_DSP_REG
:
300 ret
= aw_check_dsp_reg_num(aw_dev
, bin
, i
);
302 case DATA_TYPE_SOC_APP
:
303 ret
= aw_check_soc_app_num(aw_dev
, bin
, i
);
306 bin
->header_info
[i
].valid_data_len
=
307 bin
->header_info
[i
].bin_data_len
;
319 static int aw_dev_parse_raw_reg(unsigned char *data
, unsigned int data_len
,
320 struct aw_prof_desc
*prof_desc
)
322 prof_desc
->sec_desc
[AW88395_DATA_TYPE_REG
].data
= data
;
323 prof_desc
->sec_desc
[AW88395_DATA_TYPE_REG
].len
= data_len
;
325 prof_desc
->prof_st
= AW88395_PROFILE_OK
;
330 static int aw_dev_parse_raw_dsp_cfg(unsigned char *data
, unsigned int data_len
,
331 struct aw_prof_desc
*prof_desc
)
336 swab16_array((u16
*)data
, data_len
>> 1);
338 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].data
= data
;
339 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].len
= data_len
;
341 prof_desc
->prof_st
= AW88395_PROFILE_OK
;
346 static int aw_dev_parse_raw_dsp_fw(unsigned char *data
, unsigned int data_len
,
347 struct aw_prof_desc
*prof_desc
)
352 swab16_array((u16
*)data
, data_len
>> 1);
354 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_FW
].data
= data
;
355 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_FW
].len
= data_len
;
357 prof_desc
->prof_st
= AW88395_PROFILE_OK
;
362 static int aw_dev_prof_parse_multi_bin(struct aw_device
*aw_dev
, unsigned char *data
,
363 unsigned int data_len
, struct aw_prof_desc
*prof_desc
)
365 struct aw_bin
*aw_bin
;
369 aw_bin
= devm_kzalloc(aw_dev
->dev
, data_len
+ sizeof(struct aw_bin
), GFP_KERNEL
);
373 aw_bin
->info
.len
= data_len
;
374 memcpy(aw_bin
->info
.data
, data
, data_len
);
376 ret
= aw_parsing_bin_file(aw_dev
, aw_bin
);
378 dev_err(aw_dev
->dev
, "parse bin failed");
379 goto parse_bin_failed
;
382 for (i
= 0; i
< aw_bin
->all_bin_parse_num
; i
++) {
383 switch (aw_bin
->header_info
[i
].bin_data_type
) {
384 case DATA_TYPE_REGISTER
:
385 prof_desc
->sec_desc
[AW88395_DATA_TYPE_REG
].len
=
386 aw_bin
->header_info
[i
].valid_data_len
;
387 prof_desc
->sec_desc
[AW88395_DATA_TYPE_REG
].data
=
388 data
+ aw_bin
->header_info
[i
].valid_data_addr
;
390 case DATA_TYPE_DSP_REG
:
391 if (aw_bin
->header_info
[i
].valid_data_len
& 0x01) {
393 goto parse_bin_failed
;
396 swab16_array((u16
*)(data
+ aw_bin
->header_info
[i
].valid_data_addr
),
397 aw_bin
->header_info
[i
].valid_data_len
>> 1);
399 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].len
=
400 aw_bin
->header_info
[i
].valid_data_len
;
401 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].data
=
402 data
+ aw_bin
->header_info
[i
].valid_data_addr
;
404 case DATA_TYPE_DSP_FW
:
405 case DATA_TYPE_SOC_APP
:
406 if (aw_bin
->header_info
[i
].valid_data_len
& 0x01) {
408 goto parse_bin_failed
;
411 swab16_array((u16
*)(data
+ aw_bin
->header_info
[i
].valid_data_addr
),
412 aw_bin
->header_info
[i
].valid_data_len
>> 1);
414 prof_desc
->fw_ver
= aw_bin
->header_info
[i
].app_version
;
415 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_FW
].len
=
416 aw_bin
->header_info
[i
].valid_data_len
;
417 prof_desc
->sec_desc
[AW88395_DATA_TYPE_DSP_FW
].data
=
418 data
+ aw_bin
->header_info
[i
].valid_data_addr
;
421 dev_dbg(aw_dev
->dev
, "bin_data_type not found");
425 prof_desc
->prof_st
= AW88395_PROFILE_OK
;
429 devm_kfree(aw_dev
->dev
, aw_bin
);
433 static int aw_dev_parse_reg_bin_with_hdr(struct aw_device
*aw_dev
,
434 uint8_t *data
, uint32_t data_len
, struct aw_prof_desc
*prof_desc
)
436 struct aw_bin
*aw_bin
;
439 aw_bin
= devm_kzalloc(aw_dev
->dev
, data_len
+ sizeof(*aw_bin
), GFP_KERNEL
);
443 aw_bin
->info
.len
= data_len
;
444 memcpy(aw_bin
->info
.data
, data
, data_len
);
446 ret
= aw_parsing_bin_file(aw_dev
, aw_bin
);
448 dev_err(aw_dev
->dev
, "parse bin failed");
449 goto parse_bin_failed
;
452 if ((aw_bin
->all_bin_parse_num
!= 1) ||
453 (aw_bin
->header_info
[0].bin_data_type
!= DATA_TYPE_REGISTER
)) {
454 dev_err(aw_dev
->dev
, "bin num or type error");
456 goto parse_bin_failed
;
459 if (aw_bin
->header_info
[0].valid_data_len
% 4) {
460 dev_err(aw_dev
->dev
, "bin data len get error!");
462 goto parse_bin_failed
;
465 prof_desc
->sec_desc
[AW88395_DATA_TYPE_REG
].data
=
466 data
+ aw_bin
->header_info
[0].valid_data_addr
;
467 prof_desc
->sec_desc
[AW88395_DATA_TYPE_REG
].len
=
468 aw_bin
->header_info
[0].valid_data_len
;
469 prof_desc
->prof_st
= AW88395_PROFILE_OK
;
471 devm_kfree(aw_dev
->dev
, aw_bin
);
477 devm_kfree(aw_dev
->dev
, aw_bin
);
482 static int aw_dev_parse_data_by_sec_type(struct aw_device
*aw_dev
, struct aw_cfg_hdr
*cfg_hdr
,
483 struct aw_cfg_dde
*cfg_dde
, struct aw_prof_desc
*scene_prof_desc
)
485 switch (cfg_dde
->data_type
) {
486 case ACF_SEC_TYPE_REG
:
487 return aw_dev_parse_raw_reg((u8
*)cfg_hdr
+ cfg_dde
->data_offset
,
488 cfg_dde
->data_size
, scene_prof_desc
);
489 case ACF_SEC_TYPE_DSP_CFG
:
490 return aw_dev_parse_raw_dsp_cfg((u8
*)cfg_hdr
+ cfg_dde
->data_offset
,
491 cfg_dde
->data_size
, scene_prof_desc
);
492 case ACF_SEC_TYPE_DSP_FW
:
493 return aw_dev_parse_raw_dsp_fw(
494 (u8
*)cfg_hdr
+ cfg_dde
->data_offset
,
495 cfg_dde
->data_size
, scene_prof_desc
);
496 case ACF_SEC_TYPE_MULTIPLE_BIN
:
497 return aw_dev_prof_parse_multi_bin(
498 aw_dev
, (u8
*)cfg_hdr
+ cfg_dde
->data_offset
,
499 cfg_dde
->data_size
, scene_prof_desc
);
500 case ACF_SEC_TYPE_HDR_REG
:
501 return aw_dev_parse_reg_bin_with_hdr(aw_dev
, (u8
*)cfg_hdr
+ cfg_dde
->data_offset
,
502 cfg_dde
->data_size
, scene_prof_desc
);
504 dev_err(aw_dev
->dev
, "%s cfg_dde->data_type = %d\n", __func__
, cfg_dde
->data_type
);
511 static int aw_dev_parse_dev_type(struct aw_device
*aw_dev
,
512 struct aw_cfg_hdr
*prof_hdr
, struct aw_all_prof_info
*all_prof_info
)
514 struct aw_cfg_dde
*cfg_dde
=
515 (struct aw_cfg_dde
*)((char *)prof_hdr
+ prof_hdr
->hdr_offset
);
519 for (i
= 0; i
< prof_hdr
->ddt_num
; i
++) {
520 if ((aw_dev
->i2c
->adapter
->nr
== cfg_dde
[i
].dev_bus
) &&
521 (aw_dev
->i2c
->addr
== cfg_dde
[i
].dev_addr
) &&
522 (cfg_dde
[i
].type
== AW88395_DEV_TYPE_ID
) &&
523 (cfg_dde
[i
].data_type
!= ACF_SEC_TYPE_MONITOR
)) {
524 if (cfg_dde
[i
].dev_profile
>= AW88395_PROFILE_MAX
) {
525 dev_err(aw_dev
->dev
, "dev_profile [%d] overflow",
526 cfg_dde
[i
].dev_profile
);
530 ret
= aw_dev_parse_data_by_sec_type(aw_dev
, prof_hdr
, &cfg_dde
[i
],
531 &all_prof_info
->prof_desc
[cfg_dde
[i
].dev_profile
]);
533 dev_err(aw_dev
->dev
, "parse failed");
541 dev_dbg(aw_dev
->dev
, "get dev type num is %d, please use default", sec_num
);
542 return AW88395_DEV_TYPE_NONE
;
545 return AW88395_DEV_TYPE_OK
;
548 static int aw_dev_parse_dev_default_type(struct aw_device
*aw_dev
,
549 struct aw_cfg_hdr
*prof_hdr
, struct aw_all_prof_info
*all_prof_info
)
551 struct aw_cfg_dde
*cfg_dde
=
552 (struct aw_cfg_dde
*)((char *)prof_hdr
+ prof_hdr
->hdr_offset
);
556 for (i
= 0; i
< prof_hdr
->ddt_num
; i
++) {
557 if ((aw_dev
->channel
== cfg_dde
[i
].dev_index
) &&
558 (cfg_dde
[i
].type
== AW88395_DEV_DEFAULT_TYPE_ID
) &&
559 (cfg_dde
[i
].data_type
!= ACF_SEC_TYPE_MONITOR
)) {
560 if (cfg_dde
[i
].dev_profile
>= AW88395_PROFILE_MAX
) {
561 dev_err(aw_dev
->dev
, "dev_profile [%d] overflow",
562 cfg_dde
[i
].dev_profile
);
565 ret
= aw_dev_parse_data_by_sec_type(aw_dev
, prof_hdr
, &cfg_dde
[i
],
566 &all_prof_info
->prof_desc
[cfg_dde
[i
].dev_profile
]);
568 dev_err(aw_dev
->dev
, "parse failed");
576 dev_err(aw_dev
->dev
, "get dev default type failed, get num[%d]", sec_num
);
583 static int aw88261_dev_cfg_get_valid_prof(struct aw_device
*aw_dev
,
584 struct aw_all_prof_info all_prof_info
)
586 struct aw_prof_desc
*prof_desc
= all_prof_info
.prof_desc
;
587 struct aw_prof_info
*prof_info
= &aw_dev
->prof_info
;
591 for (i
= 0; i
< AW88395_PROFILE_MAX
; i
++) {
592 if (prof_desc
[i
].prof_st
== AW88395_PROFILE_OK
)
596 dev_dbg(aw_dev
->dev
, "get valid profile:%d", aw_dev
->prof_info
.count
);
598 if (!prof_info
->count
) {
599 dev_err(aw_dev
->dev
, "no profile data");
603 prof_info
->prof_desc
= devm_kcalloc(aw_dev
->dev
,
604 prof_info
->count
, sizeof(struct aw_prof_desc
),
606 if (!prof_info
->prof_desc
)
609 for (i
= 0; i
< AW88395_PROFILE_MAX
; i
++) {
610 if (prof_desc
[i
].prof_st
== AW88395_PROFILE_OK
) {
611 if (num
>= prof_info
->count
) {
612 dev_err(aw_dev
->dev
, "overflow count[%d]",
616 prof_info
->prof_desc
[num
] = prof_desc
[i
];
617 prof_info
->prof_desc
[num
].id
= i
;
625 static int aw88395_dev_cfg_get_valid_prof(struct aw_device
*aw_dev
,
626 struct aw_all_prof_info all_prof_info
)
628 struct aw_prof_desc
*prof_desc
= all_prof_info
.prof_desc
;
629 struct aw_prof_info
*prof_info
= &aw_dev
->prof_info
;
630 struct aw_sec_data_desc
*sec_desc
;
634 for (i
= 0; i
< AW88395_PROFILE_MAX
; i
++) {
635 if (prof_desc
[i
].prof_st
== AW88395_PROFILE_OK
) {
636 sec_desc
= prof_desc
[i
].sec_desc
;
637 if ((sec_desc
[AW88395_DATA_TYPE_REG
].data
!= NULL
) &&
638 (sec_desc
[AW88395_DATA_TYPE_REG
].len
!= 0) &&
639 (sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].data
!= NULL
) &&
640 (sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].len
!= 0) &&
641 (sec_desc
[AW88395_DATA_TYPE_DSP_FW
].data
!= NULL
) &&
642 (sec_desc
[AW88395_DATA_TYPE_DSP_FW
].len
!= 0))
647 dev_dbg(aw_dev
->dev
, "get valid profile:%d", aw_dev
->prof_info
.count
);
649 if (!prof_info
->count
) {
650 dev_err(aw_dev
->dev
, "no profile data");
654 prof_info
->prof_desc
= devm_kcalloc(aw_dev
->dev
,
655 prof_info
->count
, sizeof(struct aw_prof_desc
),
657 if (!prof_info
->prof_desc
)
660 for (i
= 0; i
< AW88395_PROFILE_MAX
; i
++) {
661 if (prof_desc
[i
].prof_st
== AW88395_PROFILE_OK
) {
662 sec_desc
= prof_desc
[i
].sec_desc
;
663 if ((sec_desc
[AW88395_DATA_TYPE_REG
].data
!= NULL
) &&
664 (sec_desc
[AW88395_DATA_TYPE_REG
].len
!= 0) &&
665 (sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].data
!= NULL
) &&
666 (sec_desc
[AW88395_DATA_TYPE_DSP_CFG
].len
!= 0) &&
667 (sec_desc
[AW88395_DATA_TYPE_DSP_FW
].data
!= NULL
) &&
668 (sec_desc
[AW88395_DATA_TYPE_DSP_FW
].len
!= 0)) {
669 if (num
>= prof_info
->count
) {
670 dev_err(aw_dev
->dev
, "overflow count[%d]",
674 prof_info
->prof_desc
[num
] = prof_desc
[i
];
675 prof_info
->prof_desc
[num
].id
= i
;
684 static int aw_dev_load_cfg_by_hdr(struct aw_device
*aw_dev
,
685 struct aw_cfg_hdr
*prof_hdr
)
687 struct aw_all_prof_info
*all_prof_info
;
690 all_prof_info
= devm_kzalloc(aw_dev
->dev
, sizeof(struct aw_all_prof_info
), GFP_KERNEL
);
694 ret
= aw_dev_parse_dev_type(aw_dev
, prof_hdr
, all_prof_info
);
697 } else if (ret
== AW88395_DEV_TYPE_NONE
) {
698 dev_dbg(aw_dev
->dev
, "get dev type num is 0, parse default dev");
699 ret
= aw_dev_parse_dev_default_type(aw_dev
, prof_hdr
, all_prof_info
);
704 switch (aw_dev
->chip_id
) {
705 case AW88395_CHIP_ID
:
706 ret
= aw88395_dev_cfg_get_valid_prof(aw_dev
, *all_prof_info
);
710 case AW88261_CHIP_ID
:
711 ret
= aw88261_dev_cfg_get_valid_prof(aw_dev
, *all_prof_info
);
716 dev_err(aw_dev
->dev
, "valid prof unsupported");
721 aw_dev
->prof_info
.prof_name_list
= profile_name
;
724 devm_kfree(aw_dev
->dev
, all_prof_info
);
728 static int aw_dev_create_prof_name_list_v1(struct aw_device
*aw_dev
)
730 struct aw_prof_info
*prof_info
= &aw_dev
->prof_info
;
731 struct aw_prof_desc
*prof_desc
= prof_info
->prof_desc
;
735 dev_err(aw_dev
->dev
, "prof_desc is NULL");
739 prof_info
->prof_name_list
= devm_kzalloc(aw_dev
->dev
,
740 prof_info
->count
* PROFILE_STR_MAX
,
742 if (!prof_info
->prof_name_list
)
745 for (i
= 0; i
< prof_info
->count
; i
++) {
747 prof_info
->prof_name_list
[i
] = prof_desc
[i
].prf_str
;
748 dev_dbg(aw_dev
->dev
, "prof name is %s", prof_info
->prof_name_list
[i
]);
754 static int aw_get_dde_type_info(struct aw_device
*aw_dev
, struct aw_container
*aw_cfg
)
756 struct aw_cfg_hdr
*cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
757 struct aw_cfg_dde_v1
*cfg_dde
=
758 (struct aw_cfg_dde_v1
*)(aw_cfg
->data
+ cfg_hdr
->hdr_offset
);
763 for (i
= 0; i
< cfg_hdr
->ddt_num
; i
++) {
764 if (cfg_dde
[i
].type
== AW88395_DEV_TYPE_ID
)
767 if (cfg_dde
[i
].type
== AW88395_DEV_DEFAULT_TYPE_ID
)
772 aw_dev
->prof_info
.prof_type
= AW88395_DEV_TYPE_ID
;
773 } else if (default_num
!= 0) {
774 aw_dev
->prof_info
.prof_type
= AW88395_DEV_DEFAULT_TYPE_ID
;
776 dev_err(aw_dev
->dev
, "can't find scene");
783 static int aw_get_dev_scene_count_v1(struct aw_device
*aw_dev
, struct aw_container
*aw_cfg
,
784 unsigned int *scene_num
)
786 struct aw_cfg_hdr
*cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
787 struct aw_cfg_dde_v1
*cfg_dde
=
788 (struct aw_cfg_dde_v1
*)(aw_cfg
->data
+ cfg_hdr
->hdr_offset
);
792 switch (aw_dev
->chip_id
) {
793 case AW88395_CHIP_ID
:
794 for (i
= 0; i
< cfg_hdr
->ddt_num
; ++i
) {
795 if ((cfg_dde
[i
].data_type
== ACF_SEC_TYPE_MULTIPLE_BIN
) &&
796 (aw_dev
->chip_id
== cfg_dde
[i
].chip_id
) &&
797 (aw_dev
->i2c
->adapter
->nr
== cfg_dde
[i
].dev_bus
) &&
798 (aw_dev
->i2c
->addr
== cfg_dde
[i
].dev_addr
))
803 case AW88261_CHIP_ID
:
804 for (i
= 0; i
< cfg_hdr
->ddt_num
; ++i
) {
805 if (((cfg_dde
[i
].data_type
== ACF_SEC_TYPE_REG
) ||
806 (cfg_dde
[i
].data_type
== ACF_SEC_TYPE_HDR_REG
)) &&
807 (aw_dev
->chip_id
== cfg_dde
[i
].chip_id
) &&
808 (aw_dev
->i2c
->adapter
->nr
== cfg_dde
[i
].dev_bus
) &&
809 (aw_dev
->i2c
->addr
== cfg_dde
[i
].dev_addr
))
815 dev_err(aw_dev
->dev
, "unsupported device");
823 static int aw_get_default_scene_count_v1(struct aw_device
*aw_dev
,
824 struct aw_container
*aw_cfg
,
825 unsigned int *scene_num
)
827 struct aw_cfg_hdr
*cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
828 struct aw_cfg_dde_v1
*cfg_dde
=
829 (struct aw_cfg_dde_v1
*)(aw_cfg
->data
+ cfg_hdr
->hdr_offset
);
833 switch (aw_dev
->chip_id
) {
834 case AW88395_CHIP_ID
:
835 for (i
= 0; i
< cfg_hdr
->ddt_num
; ++i
) {
836 if ((cfg_dde
[i
].data_type
== ACF_SEC_TYPE_MULTIPLE_BIN
) &&
837 (aw_dev
->chip_id
== cfg_dde
[i
].chip_id
) &&
838 (aw_dev
->channel
== cfg_dde
[i
].dev_index
))
843 case AW88261_CHIP_ID
:
844 for (i
= 0; i
< cfg_hdr
->ddt_num
; ++i
) {
845 if (((cfg_dde
[i
].data_type
== ACF_SEC_TYPE_REG
) ||
846 (cfg_dde
[i
].data_type
== ACF_SEC_TYPE_HDR_REG
)) &&
847 (aw_dev
->chip_id
== cfg_dde
[i
].chip_id
) &&
848 (aw_dev
->channel
== cfg_dde
[i
].dev_index
))
854 dev_err(aw_dev
->dev
, "unsupported device");
862 static int aw_dev_parse_scene_count_v1(struct aw_device
*aw_dev
,
863 struct aw_container
*aw_cfg
,
868 ret
= aw_get_dde_type_info(aw_dev
, aw_cfg
);
872 switch (aw_dev
->prof_info
.prof_type
) {
873 case AW88395_DEV_TYPE_ID
:
874 ret
= aw_get_dev_scene_count_v1(aw_dev
, aw_cfg
, count
);
876 case AW88395_DEV_DEFAULT_TYPE_ID
:
877 ret
= aw_get_default_scene_count_v1(aw_dev
, aw_cfg
, count
);
880 dev_err(aw_dev
->dev
, "unsupported prof_type[%x]", aw_dev
->prof_info
.prof_type
);
888 static int aw_dev_parse_data_by_sec_type_v1(struct aw_device
*aw_dev
,
889 struct aw_cfg_hdr
*prof_hdr
,
890 struct aw_cfg_dde_v1
*cfg_dde
,
893 struct aw_prof_info
*prof_info
= &aw_dev
->prof_info
;
896 switch (cfg_dde
->data_type
) {
897 case ACF_SEC_TYPE_MULTIPLE_BIN
:
898 ret
= aw_dev_prof_parse_multi_bin(aw_dev
, (u8
*)prof_hdr
+ cfg_dde
->data_offset
,
899 cfg_dde
->data_size
, &prof_info
->prof_desc
[*cur_scene_id
]);
901 dev_err(aw_dev
->dev
, "parse multi bin failed");
904 prof_info
->prof_desc
[*cur_scene_id
].prf_str
= cfg_dde
->dev_profile_str
;
905 prof_info
->prof_desc
[*cur_scene_id
].id
= cfg_dde
->dev_profile
;
908 case ACF_SEC_TYPE_HDR_REG
:
909 ret
= aw_dev_parse_reg_bin_with_hdr(aw_dev
,
910 (uint8_t *)prof_hdr
+ cfg_dde
->data_offset
,
911 cfg_dde
->data_size
, &prof_info
->prof_desc
[*cur_scene_id
]);
913 dev_err(aw_dev
->dev
, "parse reg bin with hdr failed");
916 prof_info
->prof_desc
[*cur_scene_id
].prf_str
= cfg_dde
->dev_profile_str
;
917 prof_info
->prof_desc
[*cur_scene_id
].id
= cfg_dde
->dev_profile
;
921 dev_err(aw_dev
->dev
, "unsupported SEC_TYPE [%d]", cfg_dde
->data_type
);
928 static int aw_dev_parse_dev_type_v1(struct aw_device
*aw_dev
,
929 struct aw_cfg_hdr
*prof_hdr
)
931 struct aw_cfg_dde_v1
*cfg_dde
=
932 (struct aw_cfg_dde_v1
*)((char *)prof_hdr
+ prof_hdr
->hdr_offset
);
933 int cur_scene_id
= 0;
937 for (i
= 0; i
< prof_hdr
->ddt_num
; i
++) {
938 if ((aw_dev
->i2c
->adapter
->nr
== cfg_dde
[i
].dev_bus
) &&
939 (aw_dev
->i2c
->addr
== cfg_dde
[i
].dev_addr
) &&
940 (aw_dev
->chip_id
== cfg_dde
[i
].chip_id
)) {
941 ret
= aw_dev_parse_data_by_sec_type_v1(aw_dev
, prof_hdr
,
942 &cfg_dde
[i
], &cur_scene_id
);
944 dev_err(aw_dev
->dev
, "parse failed");
950 if (cur_scene_id
== 0) {
951 dev_err(aw_dev
->dev
, "get dev type failed, get num [%d]", cur_scene_id
);
958 static int aw_dev_parse_default_type_v1(struct aw_device
*aw_dev
,
959 struct aw_cfg_hdr
*prof_hdr
)
961 struct aw_cfg_dde_v1
*cfg_dde
=
962 (struct aw_cfg_dde_v1
*)((char *)prof_hdr
+ prof_hdr
->hdr_offset
);
963 int cur_scene_id
= 0;
967 for (i
= 0; i
< prof_hdr
->ddt_num
; i
++) {
968 if ((aw_dev
->channel
== cfg_dde
[i
].dev_index
) &&
969 (aw_dev
->chip_id
== cfg_dde
[i
].chip_id
)) {
970 ret
= aw_dev_parse_data_by_sec_type_v1(aw_dev
, prof_hdr
,
971 &cfg_dde
[i
], &cur_scene_id
);
973 dev_err(aw_dev
->dev
, "parse failed");
979 if (cur_scene_id
== 0) {
980 dev_err(aw_dev
->dev
, "get dev default type failed, get num[%d]", cur_scene_id
);
987 static int aw_dev_parse_by_hdr_v1(struct aw_device
*aw_dev
,
988 struct aw_cfg_hdr
*cfg_hdr
)
992 switch (aw_dev
->prof_info
.prof_type
) {
993 case AW88395_DEV_TYPE_ID
:
994 ret
= aw_dev_parse_dev_type_v1(aw_dev
, cfg_hdr
);
996 case AW88395_DEV_DEFAULT_TYPE_ID
:
997 ret
= aw_dev_parse_default_type_v1(aw_dev
, cfg_hdr
);
1000 dev_err(aw_dev
->dev
, "prof type matched failed, get num[%d]",
1001 aw_dev
->prof_info
.prof_type
);
1009 static int aw_dev_load_cfg_by_hdr_v1(struct aw_device
*aw_dev
,
1010 struct aw_container
*aw_cfg
)
1012 struct aw_cfg_hdr
*cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
1013 struct aw_prof_info
*prof_info
= &aw_dev
->prof_info
;
1016 ret
= aw_dev_parse_scene_count_v1(aw_dev
, aw_cfg
, &prof_info
->count
);
1018 dev_err(aw_dev
->dev
, "get scene count failed");
1022 prof_info
->prof_desc
= devm_kcalloc(aw_dev
->dev
,
1023 prof_info
->count
, sizeof(struct aw_prof_desc
),
1025 if (!prof_info
->prof_desc
)
1028 ret
= aw_dev_parse_by_hdr_v1(aw_dev
, cfg_hdr
);
1030 dev_err(aw_dev
->dev
, "parse hdr failed");
1034 ret
= aw_dev_create_prof_name_list_v1(aw_dev
);
1036 dev_err(aw_dev
->dev
, "create prof name list failed");
1043 int aw88395_dev_cfg_load(struct aw_device
*aw_dev
, struct aw_container
*aw_cfg
)
1045 struct aw_cfg_hdr
*cfg_hdr
;
1048 cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
1050 switch (cfg_hdr
->hdr_version
) {
1051 case AW88395_CFG_HDR_VER
:
1052 ret
= aw_dev_load_cfg_by_hdr(aw_dev
, cfg_hdr
);
1054 dev_err(aw_dev
->dev
, "hdr_version[0x%x] parse failed",
1055 cfg_hdr
->hdr_version
);
1059 case AW88395_CFG_HDR_VER_V1
:
1060 ret
= aw_dev_load_cfg_by_hdr_v1(aw_dev
, aw_cfg
);
1062 dev_err(aw_dev
->dev
, "hdr_version[0x%x] parse failed",
1063 cfg_hdr
->hdr_version
);
1068 dev_err(aw_dev
->dev
, "unsupported hdr_version [0x%x]", cfg_hdr
->hdr_version
);
1071 aw_dev
->fw_status
= AW88395_DEV_FW_OK
;
1075 EXPORT_SYMBOL_GPL(aw88395_dev_cfg_load
);
1077 static int aw_dev_check_cfg_by_hdr(struct aw_device
*aw_dev
, struct aw_container
*aw_cfg
)
1079 unsigned int end_data_offset
;
1080 struct aw_cfg_hdr
*cfg_hdr
;
1081 struct aw_cfg_dde
*cfg_dde
;
1082 unsigned int act_data
= 0;
1083 unsigned int hdr_ddt_len
;
1087 cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
1088 /* check file type id is awinic acf file */
1089 if (cfg_hdr
->id
!= ACF_FILE_ID
) {
1090 dev_err(aw_dev
->dev
, "not acf type file");
1094 hdr_ddt_len
= cfg_hdr
->hdr_offset
+ cfg_hdr
->ddt_size
;
1095 if (hdr_ddt_len
> aw_cfg
->len
) {
1096 dev_err(aw_dev
->dev
, "hdr_len with ddt_len [%d] overflow file size[%d]",
1097 cfg_hdr
->hdr_offset
, aw_cfg
->len
);
1101 /* check data size */
1102 cfg_dde
= (struct aw_cfg_dde
*)((char *)aw_cfg
->data
+ cfg_hdr
->hdr_offset
);
1103 act_data
+= hdr_ddt_len
;
1104 for (i
= 0; i
< cfg_hdr
->ddt_num
; i
++)
1105 act_data
+= cfg_dde
[i
].data_size
;
1107 if (act_data
!= aw_cfg
->len
) {
1108 dev_err(aw_dev
->dev
, "act_data[%d] not equal to file size[%d]!",
1109 act_data
, aw_cfg
->len
);
1113 for (i
= 0; i
< cfg_hdr
->ddt_num
; i
++) {
1115 end_data_offset
= cfg_dde
[i
].data_offset
+ cfg_dde
[i
].data_size
;
1116 if (end_data_offset
> aw_cfg
->len
) {
1117 dev_err(aw_dev
->dev
, "ddt_num[%d] end_data_offset[%d] overflow size[%d]",
1118 i
, end_data_offset
, aw_cfg
->len
);
1123 act_crc8
= crc8(aw_crc8_table
, aw_cfg
->data
+ cfg_dde
[i
].data_offset
,
1124 cfg_dde
[i
].data_size
, 0);
1125 if (act_crc8
!= cfg_dde
[i
].data_crc
) {
1126 dev_err(aw_dev
->dev
, "ddt_num[%d] act_crc8:0x%x != data_crc:0x%x",
1127 i
, (u32
)act_crc8
, cfg_dde
[i
].data_crc
);
1135 static int aw_dev_check_acf_by_hdr_v1(struct aw_device
*aw_dev
, struct aw_container
*aw_cfg
)
1137 struct aw_cfg_dde_v1
*cfg_dde
;
1138 unsigned int end_data_offset
;
1139 struct aw_cfg_hdr
*cfg_hdr
;
1140 unsigned int act_data
= 0;
1141 unsigned int hdr_ddt_len
;
1145 cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
1147 /* check file type id is awinic acf file */
1148 if (cfg_hdr
->id
!= ACF_FILE_ID
) {
1149 dev_err(aw_dev
->dev
, "not acf type file");
1153 hdr_ddt_len
= cfg_hdr
->hdr_offset
+ cfg_hdr
->ddt_size
;
1154 if (hdr_ddt_len
> aw_cfg
->len
) {
1155 dev_err(aw_dev
->dev
, "hdrlen with ddt_len [%d] overflow file size[%d]",
1156 cfg_hdr
->hdr_offset
, aw_cfg
->len
);
1160 /* check data size */
1161 cfg_dde
= (struct aw_cfg_dde_v1
*)((char *)aw_cfg
->data
+ cfg_hdr
->hdr_offset
);
1162 act_data
+= hdr_ddt_len
;
1163 for (i
= 0; i
< cfg_hdr
->ddt_num
; i
++)
1164 act_data
+= cfg_dde
[i
].data_size
;
1166 if (act_data
!= aw_cfg
->len
) {
1167 dev_err(aw_dev
->dev
, "act_data[%d] not equal to file size[%d]!",
1168 act_data
, aw_cfg
->len
);
1172 for (i
= 0; i
< cfg_hdr
->ddt_num
; i
++) {
1174 end_data_offset
= cfg_dde
[i
].data_offset
+ cfg_dde
[i
].data_size
;
1175 if (end_data_offset
> aw_cfg
->len
) {
1176 dev_err(aw_dev
->dev
, "ddt_num[%d] end_data_offset[%d] overflow size[%d]",
1177 i
, end_data_offset
, aw_cfg
->len
);
1182 act_crc8
= crc8(aw_crc8_table
, aw_cfg
->data
+ cfg_dde
[i
].data_offset
,
1183 cfg_dde
[i
].data_size
, 0);
1184 if (act_crc8
!= cfg_dde
[i
].data_crc
) {
1185 dev_err(aw_dev
->dev
, "ddt_num[%d] act_crc8:0x%x != data_crc 0x%x",
1186 i
, (u32
)act_crc8
, cfg_dde
[i
].data_crc
);
1194 int aw88395_dev_load_acf_check(struct aw_device
*aw_dev
, struct aw_container
*aw_cfg
)
1196 struct aw_cfg_hdr
*cfg_hdr
;
1199 dev_err(aw_dev
->dev
, "aw_prof is NULL");
1203 if (aw_cfg
->len
< sizeof(struct aw_cfg_hdr
)) {
1204 dev_err(aw_dev
->dev
, "cfg hdr size[%d] overflow file size[%d]",
1205 aw_cfg
->len
, (int)sizeof(struct aw_cfg_hdr
));
1209 crc8_populate_lsb(aw_crc8_table
, AW88395_CRC8_POLYNOMIAL
);
1211 cfg_hdr
= (struct aw_cfg_hdr
*)aw_cfg
->data
;
1212 switch (cfg_hdr
->hdr_version
) {
1213 case AW88395_CFG_HDR_VER
:
1214 return aw_dev_check_cfg_by_hdr(aw_dev
, aw_cfg
);
1215 case AW88395_CFG_HDR_VER_V1
:
1216 return aw_dev_check_acf_by_hdr_v1(aw_dev
, aw_cfg
);
1218 dev_err(aw_dev
->dev
, "unsupported hdr_version [0x%x]", cfg_hdr
->hdr_version
);
1224 EXPORT_SYMBOL_GPL(aw88395_dev_load_acf_check
);
1226 MODULE_DESCRIPTION("AW88395 ACF File Parsing Lib");
1227 MODULE_LICENSE("GPL v2");