xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/aw87xxx/aw_bin_parse.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2 * aw_bin_parse.c
3 *
4 * Copyright (c) 2020 AWINIC Technology CO., LTD
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11 
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/i2c.h>
15 #include <linux/of_gpio.h>
16 #include <linux/delay.h>
17 #include <linux/device.h>
18 #include <linux/firmware.h>
19 #include <linux/slab.h>
20 #include <linux/version.h>
21 #include <linux/input.h>
22 #include <linux/interrupt.h>
23 #include <linux/debugfs.h>
24 #include <linux/miscdevice.h>
25 #include <asm/uaccess.h>
26 #include <linux/regmap.h>
27 #include <linux/timer.h>
28 #include <linux/workqueue.h>
29 #include <linux/hrtimer.h>
30 #include <linux/mutex.h>
31 #include <linux/cdev.h>
32 #include <linux/list.h>
33 #include <linux/string.h>
34 #include "aw_bin_parse.h"
35 
36 #define AWINIC_CODE_VERSION "V0.0.7-V1.0.4"	/* "code version"-"excel version" */
37 
38 #define DEBUG_LOG_LEVEL
39 #ifdef DEBUG_LOG_LEVEL
40 #define DBG(fmt, arg...)   do {\
41 printk("AWINIC_BIN %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
42 } while (0)
43 #define DBG_ERR(fmt, arg...)   do {\
44 printk("AWINIC_BIN_ERR %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
45 } while (0)
46 #else
47 #define DBG(fmt, arg...) do {} while (0)
48 #define DBG_ERR(fmt, arg...) do {} while (0)
49 #endif
50 
51 #define printing_data_code
52 
53 typedef unsigned short int aw_uint16;
54 typedef unsigned long int aw_uint32;
55 
56 #define BigLittleSwap16(A)	((((aw_uint16)(A) & 0xff00) >> 8) | \
57 				 (((aw_uint16)(A) & 0x00ff) << 8))
58 
59 #define BigLittleSwap32(A)	((((aw_uint32)(A) & 0xff000000) >> 24) | \
60 				(((aw_uint32)(A) & 0x00ff0000) >> 8) | \
61 				(((aw_uint32)(A) & 0x0000ff00) << 8) | \
62 				(((aw_uint32)(A) & 0x000000ff) << 24))
63 
64 /**
65 *
66 * Interface function
67 *
68 * return value:
69 *       value = 0 :success;
70 *       value = -1 :check bin header version
71 *       value = -2 :check bin data type
72 *       value = -3 :check sum or check bin data len error
73 *       value = -4 :check data version
74 *       value = -5 :check register num
75 *       value = -6 :check dsp reg num
76 *       value = -7 :check soc app num
77 *       value = -8 :bin is NULL point
78 *
79 **/
80 
81 /********************************************************
82 *
83 * check sum data
84 *
85 ********************************************************/
aw_check_sum(struct aw_bin * bin,int bin_num)86 int aw_check_sum(struct aw_bin *bin, int bin_num)
87 {
88 	unsigned int i = 0;
89 	unsigned int sum_data = 0;
90 	unsigned int check_sum = 0;
91 	char *p_check_sum = NULL;
92 
93 	DBG("enter\n");
94 
95 	p_check_sum =
96 	    &(bin->info.data[(bin->header_info[bin_num].valid_data_addr -
97 			      bin->header_info[bin_num].header_len)]);
98 	DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
99 	check_sum = GET_32_DATA(*(p_check_sum + 3),
100 				*(p_check_sum + 2),
101 				*(p_check_sum + 1), *(p_check_sum));
102 
103 	for (i = 4;
104 	     i <
105 	     bin->header_info[bin_num].bin_data_len +
106 	     bin->header_info[bin_num].header_len; i++) {
107 		sum_data += *(p_check_sum + i);
108 	}
109 	DBG("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n",
110 		bin_num, check_sum, sum_data);
111 	if (sum_data != check_sum) {
112 		p_check_sum = NULL;
113 		DBG_ERR("aw_bin_parse check sum or check bin data len error\n");
114 		DBG_ERR("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n", bin_num, check_sum, sum_data);
115 		return -3;
116 	}
117 	p_check_sum = NULL;
118 
119 	return 0;
120 }
121 
aw_check_data_version(struct aw_bin * bin,int bin_num)122 int aw_check_data_version(struct aw_bin *bin, int bin_num)
123 {
124 	int i = 0;
125 	DBG("enter\n");
126 
127 	for (i = DATA_VERSION_V1; i < DATA_VERSION_MAX; i++) {
128 		if (bin->header_info[bin_num].bin_data_ver == i) {
129 			return 0;
130 		}
131 	}
132 	DBG_ERR("aw_bin_parse Unrecognized this bin data version\n");
133 	return -4;
134 }
135 
aw_check_register_num_v1(struct aw_bin * bin,int bin_num)136 int aw_check_register_num_v1(struct aw_bin *bin, int bin_num)
137 {
138 	unsigned int check_register_num = 0;
139 	unsigned int parse_register_num = 0;
140 	char *p_check_sum = NULL;
141 
142 	DBG("enter\n");
143 
144 	p_check_sum =
145 	    &(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
146 	DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
147 	parse_register_num = GET_32_DATA(*(p_check_sum + 3),
148 					 *(p_check_sum + 2),
149 					 *(p_check_sum + 1), *(p_check_sum));
150 	check_register_num = (bin->header_info[bin_num].bin_data_len - 4) /
151 	    (bin->header_info[bin_num].reg_byte_len +
152 	     bin->header_info[bin_num].data_byte_len);
153 	DBG
154 	    ("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n",
155 	     bin_num, parse_register_num, check_register_num);
156 	if (parse_register_num != check_register_num) {
157 		p_check_sum = NULL;
158 		DBG_ERR("aw_bin_parse register num is error\n");
159 		DBG_ERR("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n", bin_num, parse_register_num, check_register_num);
160 		return -5;
161 	}
162 	bin->header_info[bin_num].reg_num = parse_register_num;
163 	bin->header_info[bin_num].valid_data_len =
164 	    bin->header_info[bin_num].bin_data_len - 4;
165 	p_check_sum = NULL;
166 	bin->header_info[bin_num].valid_data_addr =
167 	    bin->header_info[bin_num].valid_data_addr + 4;
168 	return 0;
169 }
170 
aw_check_dsp_reg_num_v1(struct aw_bin * bin,int bin_num)171 int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num)
172 {
173 	unsigned int check_dsp_reg_num = 0;
174 	unsigned int parse_dsp_reg_num = 0;
175 	char *p_check_sum = NULL;
176 
177 	DBG("enter\n");
178 
179 	p_check_sum =
180 	    &(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
181 	DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
182 	parse_dsp_reg_num = GET_32_DATA(*(p_check_sum + 7),
183 					*(p_check_sum + 6),
184 					*(p_check_sum + 5), *(p_check_sum + 4));
185 	bin->header_info[bin_num].reg_data_byte_len =
186 	    GET_32_DATA(*(p_check_sum + 11), *(p_check_sum + 10),
187 			*(p_check_sum + 9), *(p_check_sum + 8));
188 	check_dsp_reg_num =
189 	    (bin->header_info[bin_num].bin_data_len -
190 	     12) / bin->header_info[bin_num].reg_data_byte_len;
191 	DBG
192 	    ("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n",
193 	     bin_num, parse_dsp_reg_num, check_dsp_reg_num);
194 	if (parse_dsp_reg_num != check_dsp_reg_num) {
195 		p_check_sum = NULL;
196 		DBG_ERR("aw_bin_parse dsp reg num is error\n");
197 		DBG_ERR("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n", bin_num, parse_dsp_reg_num, check_dsp_reg_num);
198 		return -6;
199 	}
200 	bin->header_info[bin_num].download_addr =
201 	    GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
202 			*(p_check_sum + 1), *(p_check_sum));
203 	bin->header_info[bin_num].reg_num = parse_dsp_reg_num;
204 	bin->header_info[bin_num].valid_data_len =
205 	    bin->header_info[bin_num].bin_data_len - 12;
206 	p_check_sum = NULL;
207 	bin->header_info[bin_num].valid_data_addr =
208 	    bin->header_info[bin_num].valid_data_addr + 12;
209 	return 0;
210 }
211 
aw_check_soc_app_num_v1(struct aw_bin * bin,int bin_num)212 int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num)
213 {
214 	unsigned int check_soc_app_num = 0;
215 	unsigned int parse_soc_app_num = 0;
216 	char *p_check_sum = NULL;
217 
218 	DBG("enter\n");
219 
220 	p_check_sum =
221 	    &(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
222 	DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
223 	bin->header_info[bin_num].app_version = GET_32_DATA(*(p_check_sum + 3),
224 							    *(p_check_sum + 2),
225 							    *(p_check_sum + 1),
226 							    *(p_check_sum));
227 	parse_soc_app_num = GET_32_DATA(*(p_check_sum + 11),
228 					*(p_check_sum + 10),
229 					*(p_check_sum + 9), *(p_check_sum + 8));
230 	check_soc_app_num = bin->header_info[bin_num].bin_data_len - 12;
231 	DBG
232 	    ("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n",
233 	     bin_num, parse_soc_app_num, check_soc_app_num);
234 	if (parse_soc_app_num != check_soc_app_num) {
235 		p_check_sum = NULL;
236 		DBG_ERR("aw_bin_parse soc app num is error\n");
237 		DBG_ERR("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n", bin_num, parse_soc_app_num, check_soc_app_num);
238 		return -7;
239 	}
240 	bin->header_info[bin_num].reg_num = parse_soc_app_num;
241 	bin->header_info[bin_num].download_addr =
242 	    GET_32_DATA(*(p_check_sum + 7), *(p_check_sum + 6),
243 			*(p_check_sum + 5), *(p_check_sum + 4));
244 	bin->header_info[bin_num].valid_data_len =
245 	    bin->header_info[bin_num].bin_data_len - 12;
246 	p_check_sum = NULL;
247 	bin->header_info[bin_num].valid_data_addr =
248 	    bin->header_info[bin_num].valid_data_addr + 12;
249 	return 0;
250 }
251 
252 /************************
253 ***
254 ***bin header 1_0_0
255 ***
256 ************************/
aw_get_single_bin_header_1_0_0(struct aw_bin * bin)257 void aw_get_single_bin_header_1_0_0(struct aw_bin *bin)
258 {
259 	int i;
260 	DBG("enter %s\n", __func__);
261 	bin->header_info[bin->all_bin_parse_num].header_len = 60;
262 	bin->header_info[bin->all_bin_parse_num].check_sum =
263 	    GET_32_DATA(*(bin->p_addr + 3), *(bin->p_addr + 2),
264 			*(bin->p_addr + 1), *(bin->p_addr));
265 	bin->header_info[bin->all_bin_parse_num].header_ver =
266 	    GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
267 			*(bin->p_addr + 5), *(bin->p_addr + 4));
268 	bin->header_info[bin->all_bin_parse_num].bin_data_type =
269 	    GET_32_DATA(*(bin->p_addr + 11), *(bin->p_addr + 10),
270 			*(bin->p_addr + 9), *(bin->p_addr + 8));
271 	bin->header_info[bin->all_bin_parse_num].bin_data_ver =
272 	    GET_32_DATA(*(bin->p_addr + 15), *(bin->p_addr + 14),
273 			*(bin->p_addr + 13), *(bin->p_addr + 12));
274 	bin->header_info[bin->all_bin_parse_num].bin_data_len =
275 	    GET_32_DATA(*(bin->p_addr + 19), *(bin->p_addr + 18),
276 			*(bin->p_addr + 17), *(bin->p_addr + 16));
277 	bin->header_info[bin->all_bin_parse_num].ui_ver =
278 	    GET_32_DATA(*(bin->p_addr + 23), *(bin->p_addr + 22),
279 			*(bin->p_addr + 21), *(bin->p_addr + 20));
280 	bin->header_info[bin->all_bin_parse_num].reg_byte_len =
281 	    GET_32_DATA(*(bin->p_addr + 35), *(bin->p_addr + 34),
282 			*(bin->p_addr + 33), *(bin->p_addr + 32));
283 	bin->header_info[bin->all_bin_parse_num].data_byte_len =
284 	    GET_32_DATA(*(bin->p_addr + 39), *(bin->p_addr + 38),
285 			*(bin->p_addr + 37), *(bin->p_addr + 36));
286 	bin->header_info[bin->all_bin_parse_num].device_addr =
287 	    GET_32_DATA(*(bin->p_addr + 43), *(bin->p_addr + 42),
288 			*(bin->p_addr + 41), *(bin->p_addr + 40));
289 	for (i = 0; i < 8; i++) {
290 		bin->header_info[bin->all_bin_parse_num].chip_type[i] =
291 		    *(bin->p_addr + 24 + i);
292 	}
293 	bin->header_info[bin->all_bin_parse_num].reg_num = 0x00000000;
294 	bin->header_info[bin->all_bin_parse_num].reg_data_byte_len = 0x00000000;
295 	bin->header_info[bin->all_bin_parse_num].download_addr = 0x00000000;
296 	bin->header_info[bin->all_bin_parse_num].app_version = 0x00000000;
297 	bin->header_info[bin->all_bin_parse_num].valid_data_len = 0x00000000;
298 	bin->all_bin_parse_num += 1;
299 }
300 
aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num,int bin_serial_num,struct aw_bin * bin)301 int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num,
302 				      struct aw_bin *bin)
303 {
304 	int ret = 0;
305 	unsigned int bin_start_addr = 0;
306 	unsigned int valid_data_len = 0;
307 	DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
308 	if (!bin_serial_num) {
309 		bin_start_addr = GET_32_DATA(*(bin->p_addr + 67),
310 					     *(bin->p_addr + 66),
311 					     *(bin->p_addr + 65),
312 					     *(bin->p_addr + 64));
313 		bin->p_addr += (60 + bin_start_addr);
314 		bin->header_info[bin->all_bin_parse_num].valid_data_addr =
315 		    bin->header_info[bin->all_bin_parse_num -
316 				     1].valid_data_addr + 4 + 8 * bin_num + 60;
317 	} else {
318 		valid_data_len =
319 		    bin->header_info[bin->all_bin_parse_num - 1].bin_data_len;
320 		bin->p_addr += (60 + valid_data_len);
321 		bin->header_info[bin->all_bin_parse_num].valid_data_addr =
322 		    bin->header_info[bin->all_bin_parse_num -
323 				     1].valid_data_addr +
324 		    bin->header_info[bin->all_bin_parse_num - 1].bin_data_len +
325 		    60;
326 	}
327 
328 	ret = aw_parse_bin_header_1_0_0(bin);
329 	return ret;
330 }
331 
332 /* Get the number of bins in multi bins, and set a for loop, loop processing each bin data */
aw_get_multi_bin_header_1_0_0(struct aw_bin * bin)333 int aw_get_multi_bin_header_1_0_0(struct aw_bin *bin)
334 {
335 	int i = 0;
336 	int ret = 0;
337 	unsigned int bin_num = 0;
338 	DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
339 	bin_num = GET_32_DATA(*(bin->p_addr + 63),
340 			      *(bin->p_addr + 62),
341 			      *(bin->p_addr + 61), *(bin->p_addr + 60));
342 	if (bin->multi_bin_parse_num == 1) {
343 		bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
344 	}
345 	aw_get_single_bin_header_1_0_0(bin);
346 
347 	for (i = 0; i < bin_num; i++) {
348 		DBG("aw_bin_parse enter multi bin for is %d\n", i);
349 		ret = aw_parse_each_of_multi_bins_1_0_0(bin_num, i, bin);
350 		if (ret < 0) {
351 			return ret;
352 		}
353 	}
354 	return 0;
355 }
356 
357 /********************************************************
358 *
359 * If the bin framework header version is 1.0.0,
360   determine the data type of bin, and then perform different processing
361   according to the data type
362   If it is a single bin data type, write the data directly into the structure array
363   If it is a multi-bin data type, first obtain the number of bins,
364   and then recursively call the bin frame header processing function
365   according to the bin number to process the frame header information of each bin separately
366 *
367 ********************************************************/
aw_parse_bin_header_1_0_0(struct aw_bin * bin)368 int aw_parse_bin_header_1_0_0(struct aw_bin *bin)
369 {
370 	int ret = 0;
371 	unsigned int bin_data_type;
372 	DBG("enter %s\n", __func__);
373 	bin_data_type = GET_32_DATA(*(bin->p_addr + 11),
374 				    *(bin->p_addr + 10),
375 				    *(bin->p_addr + 9), *(bin->p_addr + 8));
376 	DBG("aw_bin_parse bin_data_type 0x%x\n", bin_data_type);
377 	switch (bin_data_type) {
378 	case DATA_TYPE_REGISTER:
379 	case DATA_TYPE_DSP_REG:
380 	case DATA_TYPE_SOC_APP:
381 		/* Divided into two processing methods,
382 		   one is single bin processing,
383 		   and the other is single bin processing in multi bin */
384 		DBG("aw_bin_parse enter single bin branch\n");
385 		bin->single_bin_parse_num += 1;
386 		DBG("%s bin->single_bin_parse_num is %d\n", __func__,
387 			bin->single_bin_parse_num);
388 		if (!bin->multi_bin_parse_num) {
389 			bin->header_info[bin->
390 					 all_bin_parse_num].valid_data_addr =
391 			    60;
392 		}
393 		aw_get_single_bin_header_1_0_0(bin);
394 		break;
395 	case DATA_TYPE_MULTI_BINS:
396 		/* Get the number of times to enter multi bins */
397 		DBG("aw_bin_parse enter multi bin branch\n");
398 		bin->multi_bin_parse_num += 1;
399 		DBG("%s bin->multi_bin_parse_num is %d\n", __func__,
400 			bin->multi_bin_parse_num);
401 		ret = aw_get_multi_bin_header_1_0_0(bin);
402 		if (ret < 0) {
403 			return ret;
404 		}
405 		break;
406 	default:
407 		DBG_ERR("aw_bin_parse Unrecognized this bin data type\n");
408 		return -2;
409 	}
410 	return 0;
411 }
412 
413 /* get the bin's header version */
aw_check_bin_header_version(struct aw_bin * bin)414 static int aw_check_bin_header_version(struct aw_bin *bin)
415 {
416 	int ret = 0;
417 	unsigned int header_version = 0;
418 
419 	header_version = GET_32_DATA(*(bin->p_addr + 7),
420 				     *(bin->p_addr + 6),
421 				     *(bin->p_addr + 5), *(bin->p_addr + 4));
422 
423 	DBG("aw_bin_parse header_version 0x%x\n", header_version);
424 
425 	/* Write data to the corresponding structure array
426 	   according to different formats of the bin frame header version */
427 	switch (header_version) {
428 	case HEADER_VERSION_1_0_0:
429 		ret = aw_parse_bin_header_1_0_0(bin);
430 		return ret;
431 	default:
432 		DBG_ERR("aw_bin_parse Unrecognized this bin header version \n");
433 		return -1;
434 	}
435 }
436 
aw_parsing_bin_file(struct aw_bin * bin)437 int aw_parsing_bin_file(struct aw_bin *bin)
438 {
439 	int i = 0;
440 	int ret = 0;
441 
442 	DBG("aw_bin_parse code version:%s\n", AWINIC_CODE_VERSION);
443 	if (!bin) {
444 		DBG_ERR("aw_bin_parse bin is NULL\n");
445 		return -8;
446 	}
447 	bin->p_addr = bin->info.data;
448 	bin->all_bin_parse_num = 0;
449 	bin->multi_bin_parse_num = 0;
450 	bin->single_bin_parse_num = 0;
451 
452 	/* filling bins header info */
453 	ret = aw_check_bin_header_version(bin);
454 	if (ret < 0) {
455 		DBG_ERR("aw_bin_parse check bin header version error\n");
456 		return ret;
457 	}
458 	bin->p_addr = NULL;
459 
460 	/* check bin header info */
461 	for (i = 0; i < bin->all_bin_parse_num; i++) {
462 		/* check sum */
463 		ret = aw_check_sum(bin, i);
464 		if (ret < 0) {
465 			DBG_ERR("aw_bin_parse check sum data error\n");
466 			return ret;
467 		}
468 		/* check bin data version */
469 		ret = aw_check_data_version(bin, i);
470 		if (ret < 0) {
471 			DBG_ERR("aw_bin_parse check data version error\n");
472 			return ret;
473 		}
474 		/* check valid data */
475 		if (bin->header_info[i].bin_data_ver == DATA_VERSION_V1) {
476 			/* check register num */
477 			if (bin->header_info[i].bin_data_type ==
478 			    DATA_TYPE_REGISTER) {
479 				ret = aw_check_register_num_v1(bin, i);
480 				if (ret < 0) {
481 					DBG_ERR
482 					    ("aw_bin_parse check register num error\n");
483 					return ret;
484 				}
485 				/* check dsp reg num */
486 			} else if (bin->header_info[i].bin_data_type ==
487 				   DATA_TYPE_DSP_REG) {
488 				ret = aw_check_dsp_reg_num_v1(bin, i);
489 				if (ret < 0) {
490 					DBG_ERR
491 					    ("aw_bin_parse check dsp reg num error\n");
492 					return ret;
493 				}
494 				/* check soc app num */
495 			} else if (bin->header_info[i].bin_data_type ==
496 				   DATA_TYPE_SOC_APP) {
497 				ret = aw_check_soc_app_num_v1(bin, i);
498 				if (ret < 0) {
499 					DBG_ERR
500 					    ("aw_bin_parse check soc app num error\n");
501 					return ret;
502 				}
503 			} else {
504 				bin->header_info[i].valid_data_len =
505 				    bin->header_info[i].bin_data_len;
506 			}
507 		}
508 	}
509 	DBG("aw_bin_parse parsing success\n");
510 
511 	return 0;
512 }
513