Merge tag 'powerpc-6.6-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[platform/kernel/linux-starfive.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_bin->header_info[0].valid_data_len % 4) {
460                 dev_err(aw_dev->dev, "bin data len get error!");
461                 ret = -EINVAL;
462                 goto parse_bin_failed;
463         }
464
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;
470
471         devm_kfree(aw_dev->dev, aw_bin);
472         aw_bin = NULL;
473
474         return 0;
475
476 parse_bin_failed:
477         devm_kfree(aw_dev->dev, aw_bin);
478         aw_bin = NULL;
479         return ret;
480 }
481
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)
484 {
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);
503         default:
504                 dev_err(aw_dev->dev, "%s cfg_dde->data_type = %d\n", __func__, cfg_dde->data_type);
505                 break;
506         }
507
508         return 0;
509 }
510
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)
513 {
514         struct aw_cfg_dde *cfg_dde =
515                 (struct aw_cfg_dde *)((char *)prof_hdr + prof_hdr->hdr_offset);
516         int sec_num = 0;
517         int ret, i;
518
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);
527                                 return -EINVAL;
528                         }
529
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]);
532                         if (ret < 0) {
533                                 dev_err(aw_dev->dev, "parse failed");
534                                 return ret;
535                         }
536                         sec_num++;
537                 }
538         }
539
540         if (sec_num == 0) {
541                 dev_dbg(aw_dev->dev, "get dev type num is %d, please use default", sec_num);
542                 return AW88395_DEV_TYPE_NONE;
543         }
544
545         return AW88395_DEV_TYPE_OK;
546 }
547
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)
550 {
551         struct aw_cfg_dde *cfg_dde =
552                 (struct aw_cfg_dde *)((char *)prof_hdr + prof_hdr->hdr_offset);
553         int sec_num = 0;
554         int ret, i;
555
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);
563                                 return -EINVAL;
564                         }
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]);
567                         if (ret < 0) {
568                                 dev_err(aw_dev->dev, "parse failed");
569                                 return ret;
570                         }
571                         sec_num++;
572                 }
573         }
574
575         if (sec_num == 0) {
576                 dev_err(aw_dev->dev, "get dev default type failed, get num[%d]", sec_num);
577                 return -EINVAL;
578         }
579
580         return 0;
581 }
582
583 static int aw88261_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
584                                 struct aw_all_prof_info all_prof_info)
585 {
586         struct aw_prof_desc *prof_desc = all_prof_info.prof_desc;
587         struct aw_prof_info *prof_info = &aw_dev->prof_info;
588         int num = 0;
589         int i;
590
591         for (i = 0; i < AW88395_PROFILE_MAX; i++) {
592                 if (prof_desc[i].prof_st == AW88395_PROFILE_OK)
593                         prof_info->count++;
594         }
595
596         dev_dbg(aw_dev->dev, "get valid profile:%d", aw_dev->prof_info.count);
597
598         if (!prof_info->count) {
599                 dev_err(aw_dev->dev, "no profile data");
600                 return -EPERM;
601         }
602
603         prof_info->prof_desc = devm_kcalloc(aw_dev->dev,
604                                         prof_info->count, sizeof(struct aw_prof_desc),
605                                         GFP_KERNEL);
606         if (!prof_info->prof_desc)
607                 return -ENOMEM;
608
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]",
613                                                 prof_info->count);
614                                 return -EINVAL;
615                         }
616                         prof_info->prof_desc[num] = prof_desc[i];
617                         prof_info->prof_desc[num].id = i;
618                         num++;
619                 }
620         }
621
622         return 0;
623 }
624
625 static int aw88395_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
626                                 struct aw_all_prof_info all_prof_info)
627 {
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;
631         int num = 0;
632         int i;
633
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))
643                                 prof_info->count++;
644                 }
645         }
646
647         dev_dbg(aw_dev->dev, "get valid profile:%d", aw_dev->prof_info.count);
648
649         if (!prof_info->count) {
650                 dev_err(aw_dev->dev, "no profile data");
651                 return -EPERM;
652         }
653
654         prof_info->prof_desc = devm_kcalloc(aw_dev->dev,
655                                         prof_info->count, sizeof(struct aw_prof_desc),
656                                         GFP_KERNEL);
657         if (!prof_info->prof_desc)
658                 return -ENOMEM;
659
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]",
671                                                         prof_info->count);
672                                         return -EINVAL;
673                                 }
674                                 prof_info->prof_desc[num] = prof_desc[i];
675                                 prof_info->prof_desc[num].id = i;
676                                 num++;
677                         }
678                 }
679         }
680
681         return 0;
682 }
683
684 static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_dev,
685                 struct aw_cfg_hdr *prof_hdr)
686 {
687         struct aw_all_prof_info *all_prof_info;
688         int ret;
689
690         all_prof_info = devm_kzalloc(aw_dev->dev, sizeof(struct aw_all_prof_info), GFP_KERNEL);
691         if (!all_prof_info)
692                 return -ENOMEM;
693
694         ret = aw_dev_parse_dev_type(aw_dev, prof_hdr, all_prof_info);
695         if (ret < 0) {
696                 goto exit;
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);
700                 if (ret < 0)
701                         goto exit;
702         }
703
704         switch (aw_dev->chip_id) {
705         case AW88395_CHIP_ID:
706                 ret = aw88395_dev_cfg_get_valid_prof(aw_dev, *all_prof_info);
707                 if (ret < 0)
708                         goto exit;
709                 break;
710         case AW88261_CHIP_ID:
711                 ret = aw88261_dev_cfg_get_valid_prof(aw_dev, *all_prof_info);
712                 if (ret < 0)
713                         goto exit;
714                 break;
715         default:
716                 dev_err(aw_dev->dev, "valid prof unsupported");
717                 ret = -EINVAL;
718                 break;
719         }
720
721         aw_dev->prof_info.prof_name_list = profile_name;
722
723 exit:
724         devm_kfree(aw_dev->dev, all_prof_info);
725         return ret;
726 }
727
728 static int aw_dev_create_prof_name_list_v1(struct aw_device *aw_dev)
729 {
730         struct aw_prof_info *prof_info = &aw_dev->prof_info;
731         struct aw_prof_desc *prof_desc = prof_info->prof_desc;
732         int i;
733
734         if (!prof_desc) {
735                 dev_err(aw_dev->dev, "prof_desc is NULL");
736                 return -EINVAL;
737         }
738
739         prof_info->prof_name_list = devm_kzalloc(aw_dev->dev,
740                                         prof_info->count * PROFILE_STR_MAX,
741                                         GFP_KERNEL);
742         if (!prof_info->prof_name_list)
743                 return -ENOMEM;
744
745         for (i = 0; i < prof_info->count; i++) {
746                 prof_desc[i].id = 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]);
749         }
750
751         return 0;
752 }
753
754 static int aw_get_dde_type_info(struct aw_device *aw_dev, struct aw_container *aw_cfg)
755 {
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);
759         int default_num = 0;
760         int dev_num = 0;
761         unsigned int i;
762
763         for (i = 0; i < cfg_hdr->ddt_num; i++) {
764                 if (cfg_dde[i].type == AW88395_DEV_TYPE_ID)
765                         dev_num++;
766
767                 if (cfg_dde[i].type == AW88395_DEV_DEFAULT_TYPE_ID)
768                         default_num++;
769         }
770
771         if (dev_num != 0) {
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;
775         } else {
776                 dev_err(aw_dev->dev, "can't find scene");
777                 return -EINVAL;
778         }
779
780         return 0;
781 }
782
783 static int aw_get_dev_scene_count_v1(struct aw_device *aw_dev, struct aw_container *aw_cfg,
784                                                 unsigned int *scene_num)
785 {
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);
789         unsigned int i;
790         int ret;
791
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))
799                                 (*scene_num)++;
800                 }
801                 ret = 0;
802                 break;
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))
810                                 (*scene_num)++;
811                 }
812                 ret = 0;
813                 break;
814         default:
815                 dev_err(aw_dev->dev, "unsupported device");
816                 ret = -EINVAL;
817                 break;
818         }
819
820         return ret;
821 }
822
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)
826 {
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);
830         unsigned int i;
831         int ret;
832
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))
839                                 (*scene_num)++;
840                 }
841                 ret = 0;
842                 break;
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))
849                                 (*scene_num)++;
850                 }
851                 ret = 0;
852                 break;
853         default:
854                 dev_err(aw_dev->dev, "unsupported device");
855                 ret = -EINVAL;
856                 break;
857         }
858
859         return ret;
860 }
861
862 static int aw_dev_parse_scene_count_v1(struct aw_device *aw_dev,
863                                                         struct aw_container *aw_cfg,
864                                                         unsigned int *count)
865 {
866         int ret;
867
868         ret = aw_get_dde_type_info(aw_dev, aw_cfg);
869         if (ret < 0)
870                 return ret;
871
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);
875                 break;
876         case AW88395_DEV_DEFAULT_TYPE_ID:
877                 ret = aw_get_default_scene_count_v1(aw_dev, aw_cfg, count);
878                 break;
879         default:
880                 dev_err(aw_dev->dev, "unsupported prof_type[%x]", aw_dev->prof_info.prof_type);
881                 ret = -EINVAL;
882                 break;
883         }
884
885         return ret;
886 }
887
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,
891                                                         int *cur_scene_id)
892 {
893         struct aw_prof_info *prof_info = &aw_dev->prof_info;
894         int ret;
895
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]);
900                 if (ret < 0) {
901                         dev_err(aw_dev->dev, "parse multi bin failed");
902                         return ret;
903                 }
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;
906                 (*cur_scene_id)++;
907                 break;
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]);
912                 if (ret < 0) {
913                         dev_err(aw_dev->dev, "parse reg bin with hdr failed");
914                         return ret;
915                 }
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;
918                 (*cur_scene_id)++;
919                 break;
920         default:
921                 dev_err(aw_dev->dev, "unsupported SEC_TYPE [%d]", cfg_dde->data_type);
922                 return -EINVAL;
923         }
924
925         return 0;
926 }
927
928 static int aw_dev_parse_dev_type_v1(struct aw_device *aw_dev,
929                 struct aw_cfg_hdr *prof_hdr)
930 {
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;
934         unsigned int i;
935         int ret;
936
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);
943                         if (ret < 0) {
944                                 dev_err(aw_dev->dev, "parse failed");
945                                 return ret;
946                         }
947                 }
948         }
949
950         if (cur_scene_id == 0) {
951                 dev_err(aw_dev->dev, "get dev type failed, get num [%d]", cur_scene_id);
952                 return -EINVAL;
953         }
954
955         return 0;
956 }
957
958 static int aw_dev_parse_default_type_v1(struct aw_device *aw_dev,
959                 struct aw_cfg_hdr *prof_hdr)
960 {
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;
964         unsigned int i;
965         int ret;
966
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);
972                         if (ret < 0) {
973                                 dev_err(aw_dev->dev, "parse failed");
974                                 return ret;
975                         }
976                 }
977         }
978
979         if (cur_scene_id == 0) {
980                 dev_err(aw_dev->dev, "get dev default type failed, get num[%d]", cur_scene_id);
981                 return -EINVAL;
982         }
983
984         return 0;
985 }
986
987 static int aw_dev_parse_by_hdr_v1(struct aw_device *aw_dev,
988                 struct aw_cfg_hdr *cfg_hdr)
989 {
990         int ret;
991
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);
995                 break;
996         case AW88395_DEV_DEFAULT_TYPE_ID:
997                 ret = aw_dev_parse_default_type_v1(aw_dev, cfg_hdr);
998                 break;
999         default:
1000                 dev_err(aw_dev->dev, "prof type matched failed, get num[%d]",
1001                         aw_dev->prof_info.prof_type);
1002                 ret =  -EINVAL;
1003                 break;
1004         }
1005
1006         return ret;
1007 }
1008
1009 static int aw_dev_load_cfg_by_hdr_v1(struct aw_device *aw_dev,
1010                                                 struct aw_container *aw_cfg)
1011 {
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;
1014         int ret;
1015
1016         ret = aw_dev_parse_scene_count_v1(aw_dev, aw_cfg, &prof_info->count);
1017         if (ret < 0) {
1018                 dev_err(aw_dev->dev, "get scene count failed");
1019                 return ret;
1020         }
1021
1022         prof_info->prof_desc = devm_kcalloc(aw_dev->dev,
1023                                         prof_info->count, sizeof(struct aw_prof_desc),
1024                                         GFP_KERNEL);
1025         if (!prof_info->prof_desc)
1026                 return -ENOMEM;
1027
1028         ret = aw_dev_parse_by_hdr_v1(aw_dev, cfg_hdr);
1029         if (ret < 0) {
1030                 dev_err(aw_dev->dev, "parse hdr failed");
1031                 return ret;
1032         }
1033
1034         ret = aw_dev_create_prof_name_list_v1(aw_dev);
1035         if (ret < 0) {
1036                 dev_err(aw_dev->dev, "create prof name list failed");
1037                 return ret;
1038         }
1039
1040         return 0;
1041 }
1042
1043 int aw88395_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg)
1044 {
1045         struct aw_cfg_hdr *cfg_hdr;
1046         int ret;
1047
1048         cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
1049
1050         switch (cfg_hdr->hdr_version) {
1051         case AW88395_CFG_HDR_VER:
1052                 ret = aw_dev_load_cfg_by_hdr(aw_dev, cfg_hdr);
1053                 if (ret < 0) {
1054                         dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed",
1055                                                 cfg_hdr->hdr_version);
1056                         return ret;
1057                 }
1058                 break;
1059         case AW88395_CFG_HDR_VER_V1:
1060                 ret = aw_dev_load_cfg_by_hdr_v1(aw_dev, aw_cfg);
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         default:
1068                 dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_version);
1069                 return -EINVAL;
1070         }
1071         aw_dev->fw_status = AW88395_DEV_FW_OK;
1072
1073         return 0;
1074 }
1075 EXPORT_SYMBOL_GPL(aw88395_dev_cfg_load);
1076
1077 static int aw_dev_check_cfg_by_hdr(struct aw_device *aw_dev, struct aw_container *aw_cfg)
1078 {
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;
1084         unsigned int i;
1085         u8 act_crc8;
1086
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");
1091                 return -EINVAL;
1092         }
1093
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);
1098                 return -EINVAL;
1099         }
1100
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;
1106
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);
1110                 return -EINVAL;
1111         }
1112
1113         for (i = 0; i < cfg_hdr->ddt_num; i++) {
1114                 /* data check */
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);
1119                         return -EINVAL;
1120                 }
1121
1122                 /* crc check */
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);
1128                         return -EINVAL;
1129                 }
1130         }
1131
1132         return 0;
1133 }
1134
1135 static int aw_dev_check_acf_by_hdr_v1(struct aw_device *aw_dev, struct aw_container *aw_cfg)
1136 {
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;
1142         u8 act_crc8;
1143         int i;
1144
1145         cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
1146
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");
1150                 return -EINVAL;
1151         }
1152
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);
1157                 return -EINVAL;
1158         }
1159
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;
1165
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);
1169                 return -EINVAL;
1170         }
1171
1172         for (i = 0; i < cfg_hdr->ddt_num; i++) {
1173                 /* data check */
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);
1178                         return -EINVAL;
1179                 }
1180
1181                 /* crc check */
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);
1187                         return -EINVAL;
1188                 }
1189         }
1190
1191         return 0;
1192 }
1193
1194 int aw88395_dev_load_acf_check(struct aw_device *aw_dev, struct aw_container *aw_cfg)
1195 {
1196         struct aw_cfg_hdr *cfg_hdr;
1197
1198         if (!aw_cfg) {
1199                 dev_err(aw_dev->dev, "aw_prof is NULL");
1200                 return -EINVAL;
1201         }
1202
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));
1206                 return -EINVAL;
1207         }
1208
1209         crc8_populate_lsb(aw_crc8_table, AW88395_CRC8_POLYNOMIAL);
1210
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);
1217         default:
1218                 dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_version);
1219                 return -EINVAL;
1220         }
1221
1222         return 0;
1223 }
1224 EXPORT_SYMBOL_GPL(aw88395_dev_load_acf_check);
1225
1226 MODULE_DESCRIPTION("AW88395 ACF File Parsing Lib");
1227 MODULE_LICENSE("GPL v2");