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