1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // tasdevice-fmw.c -- TASDEVICE firmware support
4 //
5 // Copyright 2023 Texas Instruments, Inc.
6 //
7 // Author: Shenghao Ding <shenghao-ding@ti.com>
8
9 #include <linux/crc8.h>
10 #include <linux/firmware.h>
11 #include <linux/i2c.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_gpio.h>
17 #include <linux/of_irq.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/tlv.h>
23 #include <sound/tas2781.h>
24
25
26 #define ERROR_PRAM_CRCCHK 0x0000000
27 #define ERROR_YRAM_CRCCHK 0x0000001
28 #define PPC_DRIVER_CRCCHK 0x00000200
29
30 #define TAS2781_SA_COEFF_SWAP_REG TASDEVICE_REG(0, 0x35, 0x2c)
31 #define TAS2781_YRAM_BOOK1 140
32 #define TAS2781_YRAM1_PAGE 42
33 #define TAS2781_YRAM1_START_REG 88
34
35 #define TAS2781_YRAM2_START_PAGE 43
36 #define TAS2781_YRAM2_END_PAGE 49
37 #define TAS2781_YRAM2_START_REG 8
38 #define TAS2781_YRAM2_END_REG 127
39
40 #define TAS2781_YRAM3_PAGE 50
41 #define TAS2781_YRAM3_START_REG 8
42 #define TAS2781_YRAM3_END_REG 27
43
44 /*should not include B0_P53_R44-R47 */
45 #define TAS2781_YRAM_BOOK2 0
46 #define TAS2781_YRAM4_START_PAGE 50
47 #define TAS2781_YRAM4_END_PAGE 60
48
49 #define TAS2781_YRAM5_PAGE 61
50 #define TAS2781_YRAM5_START_REG TAS2781_YRAM3_START_REG
51 #define TAS2781_YRAM5_END_REG TAS2781_YRAM3_END_REG
52
53 #define TASDEVICE_MAXPROGRAM_NUM_KERNEL 5
54 #define TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS 64
55 #define TASDEVICE_MAXCONFIG_NUM_KERNEL 10
56 #define MAIN_ALL_DEVICES_1X 0x01
57 #define MAIN_DEVICE_A_1X 0x02
58 #define MAIN_DEVICE_B_1X 0x03
59 #define MAIN_DEVICE_C_1X 0x04
60 #define MAIN_DEVICE_D_1X 0x05
61 #define COEFF_DEVICE_A_1X 0x12
62 #define COEFF_DEVICE_B_1X 0x13
63 #define COEFF_DEVICE_C_1X 0x14
64 #define COEFF_DEVICE_D_1X 0x15
65 #define PRE_DEVICE_A_1X 0x22
66 #define PRE_DEVICE_B_1X 0x23
67 #define PRE_DEVICE_C_1X 0x24
68 #define PRE_DEVICE_D_1X 0x25
69 #define PRE_SOFTWARE_RESET_DEVICE_A 0x41
70 #define PRE_SOFTWARE_RESET_DEVICE_B 0x42
71 #define PRE_SOFTWARE_RESET_DEVICE_C 0x43
72 #define PRE_SOFTWARE_RESET_DEVICE_D 0x44
73 #define POST_SOFTWARE_RESET_DEVICE_A 0x45
74 #define POST_SOFTWARE_RESET_DEVICE_B 0x46
75 #define POST_SOFTWARE_RESET_DEVICE_C 0x47
76 #define POST_SOFTWARE_RESET_DEVICE_D 0x48
77
78 struct tas_crc {
79 unsigned char offset;
80 unsigned char len;
81 };
82
83 static const char deviceNumber[TASDEVICE_DSP_TAS_MAX_DEVICE] = {
84 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4
85 };
86
tasdevice_add_config(struct tasdevice_priv * tas_priv,unsigned char * config_data,unsigned int config_size,int * status)87 static struct tasdevice_config_info *tasdevice_add_config(
88 struct tasdevice_priv *tas_priv, unsigned char *config_data,
89 unsigned int config_size, int *status)
90 {
91 struct tasdevice_config_info *cfg_info;
92 struct tasdev_blk_data **bk_da;
93 unsigned int config_offset = 0;
94 unsigned int i;
95
96 /* In most projects are many audio cases, such as music, handfree,
97 * receiver, games, audio-to-haptics, PMIC record, bypass mode,
98 * portrait, landscape, etc. Even in multiple audios, one or
99 * two of the chips will work for the special case, such as
100 * ultrasonic application. In order to support these variable-numbers
101 * of audio cases, flexible configs have been introduced in the
102 * dsp firmware.
103 */
104 cfg_info = kzalloc(sizeof(struct tasdevice_config_info), GFP_KERNEL);
105 if (!cfg_info) {
106 *status = -ENOMEM;
107 goto out;
108 }
109
110 if (tas_priv->rcabin.fw_hdr.binary_version_num >= 0x105) {
111 if (config_offset + 64 > (int)config_size) {
112 *status = -EINVAL;
113 dev_err(tas_priv->dev, "add conf: Out of boundary\n");
114 goto out;
115 }
116 config_offset += 64;
117 }
118
119 if (config_offset + 4 > (int)config_size) {
120 *status = -EINVAL;
121 dev_err(tas_priv->dev, "add config: Out of boundary\n");
122 goto out;
123 }
124
125 /* convert data[offset], data[offset + 1], data[offset + 2] and
126 * data[offset + 3] into host
127 */
128 cfg_info->nblocks =
129 be32_to_cpup((__be32 *)&config_data[config_offset]);
130 config_offset += 4;
131
132 /* Several kinds of dsp/algorithm firmwares can run on tas2781,
133 * the number and size of blk are not fixed and different among
134 * these firmwares.
135 */
136 bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks,
137 sizeof(struct tasdev_blk_data *), GFP_KERNEL);
138 if (!bk_da) {
139 *status = -ENOMEM;
140 goto out;
141 }
142 cfg_info->real_nblocks = 0;
143 for (i = 0; i < cfg_info->nblocks; i++) {
144 if (config_offset + 12 > config_size) {
145 *status = -EINVAL;
146 dev_err(tas_priv->dev,
147 "%s: Out of boundary: i = %d nblocks = %u!\n",
148 __func__, i, cfg_info->nblocks);
149 break;
150 }
151 bk_da[i] = kzalloc(sizeof(struct tasdev_blk_data), GFP_KERNEL);
152 if (!bk_da[i]) {
153 *status = -ENOMEM;
154 break;
155 }
156
157 bk_da[i]->dev_idx = config_data[config_offset];
158 config_offset++;
159
160 bk_da[i]->block_type = config_data[config_offset];
161 config_offset++;
162
163 if (bk_da[i]->block_type == TASDEVICE_BIN_BLK_PRE_POWER_UP) {
164 if (bk_da[i]->dev_idx == 0)
165 cfg_info->active_dev =
166 (1 << tas_priv->ndev) - 1;
167 else
168 cfg_info->active_dev |= 1 <<
169 (bk_da[i]->dev_idx - 1);
170
171 }
172 bk_da[i]->yram_checksum =
173 be16_to_cpup((__be16 *)&config_data[config_offset]);
174 config_offset += 2;
175 bk_da[i]->block_size =
176 be32_to_cpup((__be32 *)&config_data[config_offset]);
177 config_offset += 4;
178
179 bk_da[i]->n_subblks =
180 be32_to_cpup((__be32 *)&config_data[config_offset]);
181
182 config_offset += 4;
183
184 if (config_offset + bk_da[i]->block_size > config_size) {
185 *status = -EINVAL;
186 dev_err(tas_priv->dev,
187 "%s: Out of boundary: i = %d blks = %u!\n",
188 __func__, i, cfg_info->nblocks);
189 break;
190 }
191 /* instead of kzalloc+memcpy */
192 bk_da[i]->regdata = kmemdup(&config_data[config_offset],
193 bk_da[i]->block_size, GFP_KERNEL);
194 if (!bk_da[i]->regdata) {
195 *status = -ENOMEM;
196 goto out;
197 }
198
199 config_offset += bk_da[i]->block_size;
200 cfg_info->real_nblocks += 1;
201 }
202
203 out:
204 return cfg_info;
205 }
206
tasdevice_rca_parser(void * context,const struct firmware * fmw)207 int tasdevice_rca_parser(void *context, const struct firmware *fmw)
208 {
209 struct tasdevice_priv *tas_priv = context;
210 struct tasdevice_config_info **cfg_info;
211 struct tasdevice_rca_hdr *fw_hdr;
212 struct tasdevice_rca *rca;
213 unsigned int total_config_sz = 0;
214 unsigned char *buf;
215 int offset = 0;
216 int ret = 0;
217 int i;
218
219 rca = &(tas_priv->rcabin);
220 fw_hdr = &(rca->fw_hdr);
221 if (!fmw || !fmw->data) {
222 dev_err(tas_priv->dev, "Failed to read %s\n",
223 tas_priv->rca_binaryname);
224 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
225 ret = -EINVAL;
226 goto out;
227 }
228 buf = (unsigned char *)fmw->data;
229
230 fw_hdr->img_sz = be32_to_cpup((__be32 *)&buf[offset]);
231 offset += 4;
232 if (fw_hdr->img_sz != fmw->size) {
233 dev_err(tas_priv->dev,
234 "File size not match, %d %u", (int)fmw->size,
235 fw_hdr->img_sz);
236 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
237 ret = -EINVAL;
238 goto out;
239 }
240
241 fw_hdr->checksum = be32_to_cpup((__be32 *)&buf[offset]);
242 offset += 4;
243 fw_hdr->binary_version_num = be32_to_cpup((__be32 *)&buf[offset]);
244 if (fw_hdr->binary_version_num < 0x103) {
245 dev_err(tas_priv->dev, "File version 0x%04x is too low",
246 fw_hdr->binary_version_num);
247 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
248 ret = -EINVAL;
249 goto out;
250 }
251 offset += 4;
252 fw_hdr->drv_fw_version = be32_to_cpup((__be32 *)&buf[offset]);
253 offset += 8;
254 fw_hdr->plat_type = buf[offset];
255 offset += 1;
256 fw_hdr->dev_family = buf[offset];
257 offset += 1;
258 fw_hdr->reserve = buf[offset];
259 offset += 1;
260 fw_hdr->ndev = buf[offset];
261 offset += 1;
262 if (fw_hdr->ndev != tas_priv->ndev) {
263 dev_err(tas_priv->dev,
264 "ndev(%u) in rcabin mismatch ndev(%u) in DTS\n",
265 fw_hdr->ndev, tas_priv->ndev);
266 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
267 ret = -EINVAL;
268 goto out;
269 }
270 if (offset + TASDEVICE_DEVICE_SUM > fw_hdr->img_sz) {
271 dev_err(tas_priv->dev, "rca_ready: Out of boundary!\n");
272 ret = -EINVAL;
273 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
274 goto out;
275 }
276
277 for (i = 0; i < TASDEVICE_DEVICE_SUM; i++, offset++)
278 fw_hdr->devs[i] = buf[offset];
279
280 fw_hdr->nconfig = be32_to_cpup((__be32 *)&buf[offset]);
281 offset += 4;
282
283 for (i = 0; i < TASDEVICE_CONFIG_SUM; i++) {
284 fw_hdr->config_size[i] = be32_to_cpup((__be32 *)&buf[offset]);
285 offset += 4;
286 total_config_sz += fw_hdr->config_size[i];
287 }
288
289 if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
290 dev_err(tas_priv->dev, "Bin file error!\n");
291 ret = -EINVAL;
292 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
293 goto out;
294 }
295
296 cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL);
297 if (!cfg_info) {
298 ret = -ENOMEM;
299 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
300 goto out;
301 }
302 rca->cfg_info = cfg_info;
303 rca->ncfgs = 0;
304 for (i = 0; i < (int)fw_hdr->nconfig; i++) {
305 rca->ncfgs += 1;
306 cfg_info[i] = tasdevice_add_config(tas_priv, &buf[offset],
307 fw_hdr->config_size[i], &ret);
308 if (ret) {
309 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
310 goto out;
311 }
312 offset += (int)fw_hdr->config_size[i];
313 }
314 out:
315 return ret;
316 }
317 EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, SND_SOC_TAS2781_FMWLIB);
318
fw_parse_block_data_kernel(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block,const struct firmware * fmw,int offset)319 static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw,
320 struct tasdev_blk *block, const struct firmware *fmw, int offset)
321 {
322 const unsigned char *data = fmw->data;
323
324 if (offset + 16 > fmw->size) {
325 dev_err(tas_fmw->dev, "%s: File Size error\n", __func__);
326 offset = -EINVAL;
327 goto out;
328 }
329
330 /* convert data[offset], data[offset + 1], data[offset + 2] and
331 * data[offset + 3] into host
332 */
333 block->type = be32_to_cpup((__be32 *)&data[offset]);
334 offset += 4;
335
336 block->is_pchksum_present = data[offset];
337 offset++;
338
339 block->pchksum = data[offset];
340 offset++;
341
342 block->is_ychksum_present = data[offset];
343 offset++;
344
345 block->ychksum = data[offset];
346 offset++;
347
348 block->blk_size = be32_to_cpup((__be32 *)&data[offset]);
349 offset += 4;
350
351 block->nr_subblocks = be32_to_cpup((__be32 *)&data[offset]);
352 offset += 4;
353
354 if (offset + block->blk_size > fmw->size) {
355 dev_err(tas_fmw->dev, "%s: nSublocks error\n", __func__);
356 offset = -EINVAL;
357 goto out;
358 }
359 /* instead of kzalloc+memcpy */
360 block->data = kmemdup(&data[offset], block->blk_size, GFP_KERNEL);
361 if (!block->data) {
362 offset = -ENOMEM;
363 goto out;
364 }
365 offset += block->blk_size;
366
367 out:
368 return offset;
369 }
370
fw_parse_data_kernel(struct tasdevice_fw * tas_fmw,struct tasdevice_data * img_data,const struct firmware * fmw,int offset)371 static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw,
372 struct tasdevice_data *img_data, const struct firmware *fmw,
373 int offset)
374 {
375 const unsigned char *data = fmw->data;
376 struct tasdev_blk *blk;
377 unsigned int i;
378
379 if (offset + 4 > fmw->size) {
380 dev_err(tas_fmw->dev, "%s: File Size error\n", __func__);
381 offset = -EINVAL;
382 goto out;
383 }
384 img_data->nr_blk = be32_to_cpup((__be32 *)&data[offset]);
385 offset += 4;
386
387 img_data->dev_blks = kcalloc(img_data->nr_blk,
388 sizeof(struct tasdev_blk), GFP_KERNEL);
389 if (!img_data->dev_blks) {
390 offset = -ENOMEM;
391 goto out;
392 }
393
394 for (i = 0; i < img_data->nr_blk; i++) {
395 blk = &(img_data->dev_blks[i]);
396 offset = fw_parse_block_data_kernel(tas_fmw, blk, fmw, offset);
397 if (offset < 0) {
398 offset = -EINVAL;
399 break;
400 }
401 }
402
403 out:
404 return offset;
405 }
406
fw_parse_program_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)407 static int fw_parse_program_data_kernel(
408 struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw,
409 const struct firmware *fmw, int offset)
410 {
411 struct tasdevice_prog *program;
412 unsigned int i;
413
414 for (i = 0; i < tas_fmw->nr_programs; i++) {
415 program = &(tas_fmw->programs[i]);
416 if (offset + 72 > fmw->size) {
417 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
418 offset = -EINVAL;
419 goto out;
420 }
421 /*skip 72 unused byts*/
422 offset += 72;
423
424 offset = fw_parse_data_kernel(tas_fmw, &(program->dev_data),
425 fmw, offset);
426 if (offset < 0)
427 goto out;
428 }
429
430 out:
431 return offset;
432 }
433
fw_parse_configuration_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)434 static int fw_parse_configuration_data_kernel(
435 struct tasdevice_priv *tas_priv,
436 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
437 {
438 const unsigned char *data = fmw->data;
439 struct tasdevice_config *config;
440 unsigned int i;
441
442 for (i = 0; i < tas_fmw->nr_configurations; i++) {
443 config = &(tas_fmw->configs[i]);
444 if (offset + 80 > fmw->size) {
445 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
446 offset = -EINVAL;
447 goto out;
448 }
449 memcpy(config->name, &data[offset], 64);
450 /*skip extra 16 bytes*/
451 offset += 80;
452
453 offset = fw_parse_data_kernel(tas_fmw, &(config->dev_data),
454 fmw, offset);
455 if (offset < 0)
456 goto out;
457 }
458
459 out:
460 return offset;
461 }
462
fw_parse_variable_header_kernel(struct tasdevice_priv * tas_priv,const struct firmware * fmw,int offset)463 static int fw_parse_variable_header_kernel(
464 struct tasdevice_priv *tas_priv, const struct firmware *fmw,
465 int offset)
466 {
467 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
468 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
469 struct tasdevice_prog *program;
470 struct tasdevice_config *config;
471 const unsigned char *buf = fmw->data;
472 unsigned short max_confs;
473 unsigned int i;
474
475 if (offset + 12 + 4 * TASDEVICE_MAXPROGRAM_NUM_KERNEL > fmw->size) {
476 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
477 offset = -EINVAL;
478 goto out;
479 }
480 fw_hdr->device_family = be16_to_cpup((__be16 *)&buf[offset]);
481 if (fw_hdr->device_family != 0) {
482 dev_err(tas_priv->dev, "%s:not TAS device\n", __func__);
483 offset = -EINVAL;
484 goto out;
485 }
486 offset += 2;
487 fw_hdr->device = be16_to_cpup((__be16 *)&buf[offset]);
488 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
489 fw_hdr->device == 6) {
490 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
491 offset = -EINVAL;
492 goto out;
493 }
494 offset += 2;
495 fw_hdr->ndev = deviceNumber[fw_hdr->device];
496
497 if (fw_hdr->ndev != tas_priv->ndev) {
498 dev_err(tas_priv->dev,
499 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n",
500 __func__, fw_hdr->ndev, tas_priv->ndev);
501 offset = -EINVAL;
502 goto out;
503 }
504
505 tas_fmw->nr_programs = be32_to_cpup((__be32 *)&buf[offset]);
506 offset += 4;
507
508 if (tas_fmw->nr_programs == 0 || tas_fmw->nr_programs >
509 TASDEVICE_MAXPROGRAM_NUM_KERNEL) {
510 dev_err(tas_priv->dev, "mnPrograms is invalid\n");
511 offset = -EINVAL;
512 goto out;
513 }
514
515 tas_fmw->programs = kcalloc(tas_fmw->nr_programs,
516 sizeof(struct tasdevice_prog), GFP_KERNEL);
517 if (!tas_fmw->programs) {
518 offset = -ENOMEM;
519 goto out;
520 }
521
522 for (i = 0; i < tas_fmw->nr_programs; i++) {
523 program = &(tas_fmw->programs[i]);
524 program->prog_size = be32_to_cpup((__be32 *)&buf[offset]);
525 offset += 4;
526 }
527
528 /* Skip the unused prog_size */
529 offset += 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs);
530
531 tas_fmw->nr_configurations = be32_to_cpup((__be32 *)&buf[offset]);
532 offset += 4;
533
534 /* The max number of config in firmware greater than 4 pieces of
535 * tas2781s is different from the one lower than 4 pieces of
536 * tas2781s.
537 */
538 max_confs = (fw_hdr->ndev >= 4) ?
539 TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS :
540 TASDEVICE_MAXCONFIG_NUM_KERNEL;
541 if (tas_fmw->nr_configurations == 0 ||
542 tas_fmw->nr_configurations > max_confs) {
543 dev_err(tas_priv->dev, "%s: Conf is invalid\n", __func__);
544 offset = -EINVAL;
545 goto out;
546 }
547
548 if (offset + 4 * max_confs > fmw->size) {
549 dev_err(tas_priv->dev, "%s: mpConfigurations err\n", __func__);
550 offset = -EINVAL;
551 goto out;
552 }
553
554 tas_fmw->configs = kcalloc(tas_fmw->nr_configurations,
555 sizeof(struct tasdevice_config), GFP_KERNEL);
556 if (!tas_fmw->configs) {
557 offset = -ENOMEM;
558 goto out;
559 }
560
561 for (i = 0; i < tas_fmw->nr_programs; i++) {
562 config = &(tas_fmw->configs[i]);
563 config->cfg_size = be32_to_cpup((__be32 *)&buf[offset]);
564 offset += 4;
565 }
566
567 /* Skip the unused configs */
568 offset += 4 * (max_confs - tas_fmw->nr_programs);
569
570 out:
571 return offset;
572 }
573
tasdevice_process_block(void * context,unsigned char * data,unsigned char dev_idx,int sublocksize)574 static int tasdevice_process_block(void *context, unsigned char *data,
575 unsigned char dev_idx, int sublocksize)
576 {
577 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context;
578 int subblk_offset, chn, chnend, rc;
579 unsigned char subblk_typ = data[1];
580 int blktyp = dev_idx & 0xC0;
581 int idx = dev_idx & 0x3F;
582 bool is_err = false;
583
584 if (idx) {
585 chn = idx - 1;
586 chnend = idx;
587 } else {
588 chn = 0;
589 chnend = tas_priv->ndev;
590 }
591
592 for (; chn < chnend; chn++) {
593 if (tas_priv->tasdevice[chn].is_loading == false)
594 continue;
595
596 is_err = false;
597 subblk_offset = 2;
598 switch (subblk_typ) {
599 case TASDEVICE_CMD_SING_W: {
600 int i;
601 unsigned short len = be16_to_cpup((__be16 *)&data[2]);
602
603 subblk_offset += 2;
604 if (subblk_offset + 4 * len > sublocksize) {
605 dev_err(tas_priv->dev,
606 "process_block: Out of boundary\n");
607 is_err = true;
608 break;
609 }
610
611 for (i = 0; i < len; i++) {
612 rc = tasdevice_dev_write(tas_priv, chn,
613 TASDEVICE_REG(data[subblk_offset],
614 data[subblk_offset + 1],
615 data[subblk_offset + 2]),
616 data[subblk_offset + 3]);
617 if (rc < 0) {
618 is_err = true;
619 dev_err(tas_priv->dev,
620 "process_block: single write error\n");
621 }
622 subblk_offset += 4;
623 }
624 }
625 break;
626 case TASDEVICE_CMD_BURST: {
627 unsigned short len = be16_to_cpup((__be16 *)&data[2]);
628
629 subblk_offset += 2;
630 if (subblk_offset + 4 + len > sublocksize) {
631 dev_err(tas_priv->dev,
632 "%s: BST Out of boundary\n",
633 __func__);
634 is_err = true;
635 break;
636 }
637 if (len % 4) {
638 dev_err(tas_priv->dev,
639 "%s:Bst-len(%u)not div by 4\n",
640 __func__, len);
641 break;
642 }
643
644 rc = tasdevice_dev_bulk_write(tas_priv, chn,
645 TASDEVICE_REG(data[subblk_offset],
646 data[subblk_offset + 1],
647 data[subblk_offset + 2]),
648 &(data[subblk_offset + 4]), len);
649 if (rc < 0) {
650 is_err = true;
651 dev_err(tas_priv->dev,
652 "%s: bulk_write error = %d\n",
653 __func__, rc);
654 }
655 subblk_offset += (len + 4);
656 }
657 break;
658 case TASDEVICE_CMD_DELAY: {
659 unsigned int sleep_time = 0;
660
661 if (subblk_offset + 2 > sublocksize) {
662 dev_err(tas_priv->dev,
663 "%s: delay Out of boundary\n",
664 __func__);
665 is_err = true;
666 break;
667 }
668 sleep_time = be16_to_cpup((__be16 *)&data[2]) * 1000;
669 usleep_range(sleep_time, sleep_time + 50);
670 subblk_offset += 2;
671 }
672 break;
673 case TASDEVICE_CMD_FIELD_W:
674 if (subblk_offset + 6 > sublocksize) {
675 dev_err(tas_priv->dev,
676 "%s: bit write Out of boundary\n",
677 __func__);
678 is_err = true;
679 break;
680 }
681 rc = tasdevice_dev_update_bits(tas_priv, chn,
682 TASDEVICE_REG(data[subblk_offset + 2],
683 data[subblk_offset + 3],
684 data[subblk_offset + 4]),
685 data[subblk_offset + 1],
686 data[subblk_offset + 5]);
687 if (rc < 0) {
688 is_err = true;
689 dev_err(tas_priv->dev,
690 "%s: update_bits error = %d\n",
691 __func__, rc);
692 }
693 subblk_offset += 6;
694 break;
695 default:
696 break;
697 }
698 if (is_err == true && blktyp != 0) {
699 if (blktyp == 0x80) {
700 tas_priv->tasdevice[chn].cur_prog = -1;
701 tas_priv->tasdevice[chn].cur_conf = -1;
702 } else
703 tas_priv->tasdevice[chn].cur_conf = -1;
704 }
705 }
706
707 return subblk_offset;
708 }
709
tasdevice_select_cfg_blk(void * pContext,int conf_no,unsigned char block_type)710 void tasdevice_select_cfg_blk(void *pContext, int conf_no,
711 unsigned char block_type)
712 {
713 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) pContext;
714 struct tasdevice_rca *rca = &(tas_priv->rcabin);
715 struct tasdevice_config_info **cfg_info = rca->cfg_info;
716 struct tasdev_blk_data **blk_data;
717 int j, k, chn, chnend;
718
719 if (conf_no >= rca->ncfgs || conf_no < 0 || !cfg_info) {
720 dev_err(tas_priv->dev, "conf_no should be not more than %u\n",
721 rca->ncfgs);
722 return;
723 }
724 blk_data = cfg_info[conf_no]->blk_data;
725
726 for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) {
727 unsigned int length = 0, rc = 0;
728
729 if (block_type > 5 || block_type < 2) {
730 dev_err(tas_priv->dev,
731 "block_type should be in range from 2 to 5\n");
732 break;
733 }
734 if (block_type != blk_data[j]->block_type)
735 continue;
736
737 for (k = 0; k < (int)blk_data[j]->n_subblks; k++) {
738 if (blk_data[j]->dev_idx) {
739 chn = blk_data[j]->dev_idx - 1;
740 chnend = blk_data[j]->dev_idx;
741 } else {
742 chn = 0;
743 chnend = tas_priv->ndev;
744 }
745 for (; chn < chnend; chn++)
746 tas_priv->tasdevice[chn].is_loading = true;
747
748 rc = tasdevice_process_block(tas_priv,
749 blk_data[j]->regdata + length,
750 blk_data[j]->dev_idx,
751 blk_data[j]->block_size - length);
752 length += rc;
753 if (blk_data[j]->block_size < length) {
754 dev_err(tas_priv->dev,
755 "%s: %u %u out of boundary\n",
756 __func__, length,
757 blk_data[j]->block_size);
758 break;
759 }
760 }
761 if (length != blk_data[j]->block_size)
762 dev_err(tas_priv->dev, "%s: %u %u size is not same\n",
763 __func__, length, blk_data[j]->block_size);
764 }
765 }
766 EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, SND_SOC_TAS2781_FMWLIB);
767
tasdevice_load_block_kernel(struct tasdevice_priv * tasdevice,struct tasdev_blk * block)768 static int tasdevice_load_block_kernel(
769 struct tasdevice_priv *tasdevice, struct tasdev_blk *block)
770 {
771 struct tasdevice_dspfw_hdr *fw_hdr = &(tasdevice->fmw->fw_hdr);
772 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr);
773 const unsigned int blk_size = block->blk_size;
774 unsigned int i, length;
775 unsigned char *data = block->data;
776 unsigned char dev_idx = 0;
777
778 if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781) {
779 switch (block->type) {
780 case MAIN_ALL_DEVICES_1X:
781 dev_idx = 0x80;
782 break;
783 case MAIN_DEVICE_A_1X:
784 dev_idx = 0x81;
785 break;
786 case COEFF_DEVICE_A_1X:
787 case PRE_DEVICE_A_1X:
788 case PRE_SOFTWARE_RESET_DEVICE_A:
789 case POST_SOFTWARE_RESET_DEVICE_A:
790 dev_idx = 0xC1;
791 break;
792 case MAIN_DEVICE_B_1X:
793 dev_idx = 0x82;
794 break;
795 case COEFF_DEVICE_B_1X:
796 case PRE_DEVICE_B_1X:
797 case PRE_SOFTWARE_RESET_DEVICE_B:
798 case POST_SOFTWARE_RESET_DEVICE_B:
799 dev_idx = 0xC2;
800 break;
801 case MAIN_DEVICE_C_1X:
802 dev_idx = 0x83;
803 break;
804 case COEFF_DEVICE_C_1X:
805 case PRE_DEVICE_C_1X:
806 case PRE_SOFTWARE_RESET_DEVICE_C:
807 case POST_SOFTWARE_RESET_DEVICE_C:
808 dev_idx = 0xC3;
809 break;
810 case MAIN_DEVICE_D_1X:
811 dev_idx = 0x84;
812 break;
813 case COEFF_DEVICE_D_1X:
814 case PRE_DEVICE_D_1X:
815 case PRE_SOFTWARE_RESET_DEVICE_D:
816 case POST_SOFTWARE_RESET_DEVICE_D:
817 dev_idx = 0xC4;
818 break;
819 default:
820 dev_info(tasdevice->dev,
821 "%s: load block: Other Type = 0x%02x\n",
822 __func__, block->type);
823 break;
824 }
825 } else if (fw_fixed_hdr->ppcver >=
826 PPC3_VERSION) {
827 switch (block->type) {
828 case MAIN_ALL_DEVICES_1X:
829 dev_idx = 0x80;
830 break;
831 case MAIN_DEVICE_A_1X:
832 dev_idx = 0x81;
833 break;
834 case COEFF_DEVICE_A_1X:
835 case PRE_DEVICE_A_1X:
836 dev_idx = 0xC1;
837 break;
838 case MAIN_DEVICE_B_1X:
839 dev_idx = 0x82;
840 break;
841 case COEFF_DEVICE_B_1X:
842 case PRE_DEVICE_B_1X:
843 dev_idx = 0xC2;
844 break;
845 case MAIN_DEVICE_C_1X:
846 dev_idx = 0x83;
847 break;
848 case COEFF_DEVICE_C_1X:
849 case PRE_DEVICE_C_1X:
850 dev_idx = 0xC3;
851 break;
852 case MAIN_DEVICE_D_1X:
853 dev_idx = 0x84;
854 break;
855 case COEFF_DEVICE_D_1X:
856 case PRE_DEVICE_D_1X:
857 dev_idx = 0xC4;
858 break;
859 default:
860 dev_info(tasdevice->dev,
861 "%s: load block: Other Type = 0x%02x\n",
862 __func__, block->type);
863 break;
864 }
865 } else {
866 switch (block->type) {
867 case MAIN_ALL_DEVICES:
868 dev_idx = 0|0x80;
869 break;
870 case MAIN_DEVICE_A:
871 dev_idx = 0x81;
872 break;
873 case COEFF_DEVICE_A:
874 case PRE_DEVICE_A:
875 dev_idx = 0xC1;
876 break;
877 case MAIN_DEVICE_B:
878 dev_idx = 0x82;
879 break;
880 case COEFF_DEVICE_B:
881 case PRE_DEVICE_B:
882 dev_idx = 0xC2;
883 break;
884 case MAIN_DEVICE_C:
885 dev_idx = 0x83;
886 break;
887 case COEFF_DEVICE_C:
888 case PRE_DEVICE_C:
889 dev_idx = 0xC3;
890 break;
891 case MAIN_DEVICE_D:
892 dev_idx = 0x84;
893 break;
894 case COEFF_DEVICE_D:
895 case PRE_DEVICE_D:
896 dev_idx = 0xC4;
897 break;
898 default:
899 dev_info(tasdevice->dev,
900 "%s: load block: Other Type = 0x%02x\n",
901 __func__, block->type);
902 break;
903 }
904 }
905
906 for (i = 0, length = 0; i < block->nr_subblocks; i++) {
907 int rc = tasdevice_process_block(tasdevice, data + length,
908 dev_idx, blk_size - length);
909 if (rc < 0) {
910 dev_err(tasdevice->dev,
911 "%s: %u %u sublock write error\n",
912 __func__, length, blk_size);
913 break;
914 }
915 length += (unsigned int)rc;
916 if (blk_size < length) {
917 dev_err(tasdevice->dev, "%s: %u %u out of boundary\n",
918 __func__, length, blk_size);
919 break;
920 }
921 }
922
923 return 0;
924 }
925
fw_parse_variable_hdr(struct tasdevice_priv * tas_priv,struct tasdevice_dspfw_hdr * fw_hdr,const struct firmware * fmw,int offset)926 static int fw_parse_variable_hdr(struct tasdevice_priv
927 *tas_priv, struct tasdevice_dspfw_hdr *fw_hdr,
928 const struct firmware *fmw, int offset)
929 {
930 const unsigned char *buf = fmw->data;
931 int len = strlen((char *)&buf[offset]);
932
933 len++;
934
935 if (offset + len + 8 > fmw->size) {
936 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
937 offset = -EINVAL;
938 goto out;
939 }
940
941 offset += len;
942
943 fw_hdr->device_family = be32_to_cpup((__be32 *)&buf[offset]);
944 if (fw_hdr->device_family != 0) {
945 dev_err(tas_priv->dev, "%s: not TAS device\n", __func__);
946 offset = -EINVAL;
947 goto out;
948 }
949 offset += 4;
950
951 fw_hdr->device = be32_to_cpup((__be32 *)&buf[offset]);
952 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
953 fw_hdr->device == 6) {
954 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
955 offset = -EINVAL;
956 goto out;
957 }
958 offset += 4;
959 fw_hdr->ndev = deviceNumber[fw_hdr->device];
960
961 out:
962 return offset;
963 }
964
fw_parse_variable_header_git(struct tasdevice_priv * tas_priv,const struct firmware * fmw,int offset)965 static int fw_parse_variable_header_git(struct tasdevice_priv
966 *tas_priv, const struct firmware *fmw, int offset)
967 {
968 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
969 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
970
971 offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset);
972 if (offset < 0)
973 goto out;
974 if (fw_hdr->ndev != tas_priv->ndev) {
975 dev_err(tas_priv->dev,
976 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n",
977 __func__, fw_hdr->ndev, tas_priv->ndev);
978 offset = -EINVAL;
979 }
980
981 out:
982 return offset;
983 }
984
fw_parse_block_data(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block,const struct firmware * fmw,int offset)985 static int fw_parse_block_data(struct tasdevice_fw *tas_fmw,
986 struct tasdev_blk *block, const struct firmware *fmw, int offset)
987 {
988 unsigned char *data = (unsigned char *)fmw->data;
989 int n;
990
991 if (offset + 8 > fmw->size) {
992 dev_err(tas_fmw->dev, "%s: Type error\n", __func__);
993 offset = -EINVAL;
994 goto out;
995 }
996 block->type = be32_to_cpup((__be32 *)&data[offset]);
997 offset += 4;
998
999 if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) {
1000 if (offset + 8 > fmw->size) {
1001 dev_err(tas_fmw->dev, "PChkSumPresent error\n");
1002 offset = -EINVAL;
1003 goto out;
1004 }
1005 block->is_pchksum_present = data[offset];
1006 offset++;
1007
1008 block->pchksum = data[offset];
1009 offset++;
1010
1011 block->is_ychksum_present = data[offset];
1012 offset++;
1013
1014 block->ychksum = data[offset];
1015 offset++;
1016 } else {
1017 block->is_pchksum_present = 0;
1018 block->is_ychksum_present = 0;
1019 }
1020
1021 block->nr_cmds = be32_to_cpup((__be32 *)&data[offset]);
1022 offset += 4;
1023
1024 n = block->nr_cmds * 4;
1025 if (offset + n > fmw->size) {
1026 dev_err(tas_fmw->dev,
1027 "%s: File Size(%lu) error offset = %d n = %d\n",
1028 __func__, (unsigned long)fmw->size, offset, n);
1029 offset = -EINVAL;
1030 goto out;
1031 }
1032 /* instead of kzalloc+memcpy */
1033 block->data = kmemdup(&data[offset], n, GFP_KERNEL);
1034 if (!block->data) {
1035 offset = -ENOMEM;
1036 goto out;
1037 }
1038 offset += n;
1039
1040 out:
1041 return offset;
1042 }
1043
1044 /* When parsing error occurs, all the memory resource will be released
1045 * in the end of tasdevice_rca_ready.
1046 */
fw_parse_data(struct tasdevice_fw * tas_fmw,struct tasdevice_data * img_data,const struct firmware * fmw,int offset)1047 static int fw_parse_data(struct tasdevice_fw *tas_fmw,
1048 struct tasdevice_data *img_data, const struct firmware *fmw,
1049 int offset)
1050 {
1051 const unsigned char *data = (unsigned char *)fmw->data;
1052 struct tasdev_blk *blk;
1053 unsigned int i;
1054 int n;
1055
1056 if (offset + 64 > fmw->size) {
1057 dev_err(tas_fmw->dev, "%s: Name error\n", __func__);
1058 offset = -EINVAL;
1059 goto out;
1060 }
1061 memcpy(img_data->name, &data[offset], 64);
1062 offset += 64;
1063
1064 n = strlen((char *)&data[offset]);
1065 n++;
1066 if (offset + n + 2 > fmw->size) {
1067 dev_err(tas_fmw->dev, "%s: Description error\n", __func__);
1068 offset = -EINVAL;
1069 goto out;
1070 }
1071 offset += n;
1072 img_data->nr_blk = be16_to_cpup((__be16 *)&data[offset]);
1073 offset += 2;
1074
1075 img_data->dev_blks = kcalloc(img_data->nr_blk,
1076 sizeof(struct tasdev_blk), GFP_KERNEL);
1077 if (!img_data->dev_blks) {
1078 offset = -ENOMEM;
1079 goto out;
1080 }
1081 for (i = 0; i < img_data->nr_blk; i++) {
1082 blk = &(img_data->dev_blks[i]);
1083 offset = fw_parse_block_data(tas_fmw, blk, fmw, offset);
1084 if (offset < 0) {
1085 offset = -EINVAL;
1086 goto out;
1087 }
1088 }
1089
1090 out:
1091 return offset;
1092 }
1093
1094 /* When parsing error occurs, all the memory resource will be released
1095 * in the end of tasdevice_rca_ready.
1096 */
fw_parse_program_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1097 static int fw_parse_program_data(struct tasdevice_priv *tas_priv,
1098 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1099 {
1100 unsigned char *buf = (unsigned char *)fmw->data;
1101 struct tasdevice_prog *program;
1102 int i;
1103
1104 if (offset + 2 > fmw->size) {
1105 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1106 offset = -EINVAL;
1107 goto out;
1108 }
1109 tas_fmw->nr_programs = be16_to_cpup((__be16 *)&buf[offset]);
1110 offset += 2;
1111
1112 if (tas_fmw->nr_programs == 0) {
1113 /*Not error in calibration Data file, return directly*/
1114 dev_info(tas_priv->dev, "%s: No Programs data, maybe calbin\n",
1115 __func__);
1116 goto out;
1117 }
1118
1119 tas_fmw->programs =
1120 kcalloc(tas_fmw->nr_programs, sizeof(struct tasdevice_prog),
1121 GFP_KERNEL);
1122 if (!tas_fmw->programs) {
1123 offset = -ENOMEM;
1124 goto out;
1125 }
1126 for (i = 0; i < tas_fmw->nr_programs; i++) {
1127 int n = 0;
1128
1129 program = &(tas_fmw->programs[i]);
1130 if (offset + 64 > fmw->size) {
1131 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
1132 offset = -EINVAL;
1133 goto out;
1134 }
1135 offset += 64;
1136
1137 n = strlen((char *)&buf[offset]);
1138 /* skip '\0' and 5 unused bytes */
1139 n += 6;
1140 if (offset + n > fmw->size) {
1141 dev_err(tas_priv->dev, "Description err\n");
1142 offset = -EINVAL;
1143 goto out;
1144 }
1145
1146 offset += n;
1147
1148 offset = fw_parse_data(tas_fmw, &(program->dev_data), fmw,
1149 offset);
1150 if (offset < 0)
1151 goto out;
1152 }
1153
1154 out:
1155 return offset;
1156 }
1157
1158 /* When parsing error occurs, all the memory resource will be released
1159 * in the end of tasdevice_rca_ready.
1160 */
fw_parse_configuration_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1161 static int fw_parse_configuration_data(
1162 struct tasdevice_priv *tas_priv,
1163 struct tasdevice_fw *tas_fmw,
1164 const struct firmware *fmw, int offset)
1165 {
1166 unsigned char *data = (unsigned char *)fmw->data;
1167 struct tasdevice_config *config;
1168 unsigned int i;
1169 int n;
1170
1171 if (offset + 2 > fmw->size) {
1172 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1173 offset = -EINVAL;
1174 goto out;
1175 }
1176 tas_fmw->nr_configurations = be16_to_cpup((__be16 *)&data[offset]);
1177 offset += 2;
1178
1179 if (tas_fmw->nr_configurations == 0) {
1180 dev_err(tas_priv->dev, "%s: Conf is zero\n", __func__);
1181 /*Not error for calibration Data file, return directly*/
1182 goto out;
1183 }
1184 tas_fmw->configs = kcalloc(tas_fmw->nr_configurations,
1185 sizeof(struct tasdevice_config), GFP_KERNEL);
1186 if (!tas_fmw->configs) {
1187 offset = -ENOMEM;
1188 goto out;
1189 }
1190 for (i = 0; i < tas_fmw->nr_configurations; i++) {
1191 config = &(tas_fmw->configs[i]);
1192 if (offset + 64 > fmw->size) {
1193 dev_err(tas_priv->dev, "File Size err\n");
1194 offset = -EINVAL;
1195 goto out;
1196 }
1197 memcpy(config->name, &data[offset], 64);
1198 offset += 64;
1199
1200 n = strlen((char *)&data[offset]);
1201 n += 15;
1202 if (offset + n > fmw->size) {
1203 dev_err(tas_priv->dev, "Description err\n");
1204 offset = -EINVAL;
1205 goto out;
1206 }
1207
1208 offset += n;
1209
1210 offset = fw_parse_data(tas_fmw, &(config->dev_data),
1211 fmw, offset);
1212 if (offset < 0)
1213 goto out;
1214 }
1215
1216 out:
1217 return offset;
1218 }
1219
check_inpage_yram_rg(struct tas_crc * cd,unsigned char reg,unsigned char len)1220 static bool check_inpage_yram_rg(struct tas_crc *cd,
1221 unsigned char reg, unsigned char len)
1222 {
1223 bool in = false;
1224
1225
1226 if (reg <= TAS2781_YRAM5_END_REG &&
1227 reg >= TAS2781_YRAM5_START_REG) {
1228 if (reg + len > TAS2781_YRAM5_END_REG)
1229 cd->len = TAS2781_YRAM5_END_REG - reg + 1;
1230 else
1231 cd->len = len;
1232 cd->offset = reg;
1233 in = true;
1234 } else if (reg < TAS2781_YRAM5_START_REG) {
1235 if (reg + len > TAS2781_YRAM5_START_REG) {
1236 cd->offset = TAS2781_YRAM5_START_REG;
1237 cd->len = len - TAS2781_YRAM5_START_REG + reg;
1238 in = true;
1239 }
1240 }
1241
1242 return in;
1243 }
1244
check_inpage_yram_bk1(struct tas_crc * cd,unsigned char page,unsigned char reg,unsigned char len)1245 static bool check_inpage_yram_bk1(struct tas_crc *cd,
1246 unsigned char page, unsigned char reg, unsigned char len)
1247 {
1248 bool in = false;
1249
1250 if (page == TAS2781_YRAM1_PAGE) {
1251 if (reg >= TAS2781_YRAM1_START_REG) {
1252 cd->offset = reg;
1253 cd->len = len;
1254 in = true;
1255 } else if (reg + len > TAS2781_YRAM1_START_REG) {
1256 cd->offset = TAS2781_YRAM1_START_REG;
1257 cd->len = len - TAS2781_YRAM1_START_REG + reg;
1258 in = true;
1259 }
1260 } else if (page == TAS2781_YRAM3_PAGE)
1261 in = check_inpage_yram_rg(cd, reg, len);
1262
1263 return in;
1264 }
1265
1266 /* Return Code:
1267 * true -- the registers are in the inpage yram
1268 * false -- the registers are NOT in the inpage yram
1269 */
check_inpage_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1270 static bool check_inpage_yram(struct tas_crc *cd, unsigned char book,
1271 unsigned char page, unsigned char reg, unsigned char len)
1272 {
1273 bool in = false;
1274
1275 if (book == TAS2781_YRAM_BOOK1) {
1276 in = check_inpage_yram_bk1(cd, page, reg, len);
1277 goto end;
1278 }
1279 if (book == TAS2781_YRAM_BOOK2 && page == TAS2781_YRAM5_PAGE)
1280 in = check_inpage_yram_rg(cd, reg, len);
1281
1282 end:
1283 return in;
1284 }
1285
check_inblock_yram_bk(struct tas_crc * cd,unsigned char page,unsigned char reg,unsigned char len)1286 static bool check_inblock_yram_bk(struct tas_crc *cd,
1287 unsigned char page, unsigned char reg, unsigned char len)
1288 {
1289 bool in = false;
1290
1291 if ((page >= TAS2781_YRAM4_START_PAGE &&
1292 page <= TAS2781_YRAM4_END_PAGE) ||
1293 (page >= TAS2781_YRAM2_START_PAGE &&
1294 page <= TAS2781_YRAM2_END_PAGE)) {
1295 if (reg <= TAS2781_YRAM2_END_REG &&
1296 reg >= TAS2781_YRAM2_START_REG) {
1297 cd->offset = reg;
1298 cd->len = len;
1299 in = true;
1300 } else if (reg < TAS2781_YRAM2_START_REG) {
1301 if (reg + len - 1 >= TAS2781_YRAM2_START_REG) {
1302 cd->offset = TAS2781_YRAM2_START_REG;
1303 cd->len = reg + len - TAS2781_YRAM2_START_REG;
1304 in = true;
1305 }
1306 }
1307 }
1308
1309 return in;
1310 }
1311
1312 /* Return Code:
1313 * true -- the registers are in the inblock yram
1314 * false -- the registers are NOT in the inblock yram
1315 */
check_inblock_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1316 static bool check_inblock_yram(struct tas_crc *cd, unsigned char book,
1317 unsigned char page, unsigned char reg, unsigned char len)
1318 {
1319 bool in = false;
1320
1321 if (book == TAS2781_YRAM_BOOK1 || book == TAS2781_YRAM_BOOK2)
1322 in = check_inblock_yram_bk(cd, page, reg, len);
1323
1324 return in;
1325 }
1326
check_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1327 static bool check_yram(struct tas_crc *cd, unsigned char book,
1328 unsigned char page, unsigned char reg, unsigned char len)
1329 {
1330 bool in;
1331
1332 in = check_inpage_yram(cd, book, page, reg, len);
1333 if (in)
1334 goto end;
1335 in = check_inblock_yram(cd, book, page, reg, len);
1336
1337 end:
1338 return in;
1339 }
1340
tasdev_multibytes_chksum(struct tasdevice_priv * tasdevice,unsigned short chn,unsigned char book,unsigned char page,unsigned char reg,unsigned int len)1341 static int tasdev_multibytes_chksum(struct tasdevice_priv *tasdevice,
1342 unsigned short chn, unsigned char book, unsigned char page,
1343 unsigned char reg, unsigned int len)
1344 {
1345 struct tas_crc crc_data;
1346 unsigned char crc_chksum = 0;
1347 unsigned char nBuf1[128];
1348 int ret = 0;
1349 int i;
1350 bool in;
1351
1352 if ((reg + len - 1) > 127) {
1353 ret = -EINVAL;
1354 dev_err(tasdevice->dev, "firmware error\n");
1355 goto end;
1356 }
1357
1358 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG))
1359 && (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG))
1360 && (reg == TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG))
1361 && (len == 4)) {
1362 /*DSP swap command, pass */
1363 ret = 0;
1364 goto end;
1365 }
1366
1367 in = check_yram(&crc_data, book, page, reg, len);
1368 if (!in)
1369 goto end;
1370
1371 if (len == 1) {
1372 dev_err(tasdevice->dev, "firmware error\n");
1373 ret = -EINVAL;
1374 goto end;
1375 }
1376
1377 ret = tasdevice_dev_bulk_read(tasdevice, chn,
1378 TASDEVICE_REG(book, page, crc_data.offset),
1379 nBuf1, crc_data.len);
1380 if (ret < 0)
1381 goto end;
1382
1383 for (i = 0; i < crc_data.len; i++) {
1384 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG))
1385 && (page == TASDEVICE_PAGE_ID(
1386 TAS2781_SA_COEFF_SWAP_REG))
1387 && ((i + crc_data.offset)
1388 >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG))
1389 && ((i + crc_data.offset)
1390 <= (TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG)
1391 + 4)))
1392 /*DSP swap command, bypass */
1393 continue;
1394 else
1395 crc_chksum += crc8(tasdevice->crc8_lkp_tbl, &nBuf1[i],
1396 1, 0);
1397 }
1398
1399 ret = crc_chksum;
1400
1401 end:
1402 return ret;
1403 }
1404
do_singlereg_checksum(struct tasdevice_priv * tasdevice,unsigned short chl,unsigned char book,unsigned char page,unsigned char reg,unsigned char val)1405 static int do_singlereg_checksum(struct tasdevice_priv *tasdevice,
1406 unsigned short chl, unsigned char book, unsigned char page,
1407 unsigned char reg, unsigned char val)
1408 {
1409 struct tas_crc crc_data;
1410 unsigned int nData1;
1411 int ret = 0;
1412 bool in;
1413
1414 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG))
1415 && (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG))
1416 && (reg >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG))
1417 && (reg <= (TASDEVICE_PAGE_REG(
1418 TAS2781_SA_COEFF_SWAP_REG) + 4))) {
1419 /*DSP swap command, pass */
1420 ret = 0;
1421 goto end;
1422 }
1423
1424 in = check_yram(&crc_data, book, page, reg, 1);
1425 if (!in)
1426 goto end;
1427 ret = tasdevice_dev_read(tasdevice, chl,
1428 TASDEVICE_REG(book, page, reg), &nData1);
1429 if (ret < 0)
1430 goto end;
1431
1432 if (nData1 != val) {
1433 dev_err(tasdevice->dev,
1434 "B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1435 book, page, reg, val, nData1);
1436 tasdevice->tasdevice[chl].err_code |= ERROR_YRAM_CRCCHK;
1437 ret = -EAGAIN;
1438 goto end;
1439 }
1440
1441 ret = crc8(tasdevice->crc8_lkp_tbl, &val, 1, 0);
1442
1443 end:
1444 return ret;
1445 }
1446
set_err_prg_cfg(unsigned int type,struct tasdevice * dev)1447 static void set_err_prg_cfg(unsigned int type, struct tasdevice *dev)
1448 {
1449 if ((type == MAIN_ALL_DEVICES) || (type == MAIN_DEVICE_A)
1450 || (type == MAIN_DEVICE_B) || (type == MAIN_DEVICE_C)
1451 || (type == MAIN_DEVICE_D))
1452 dev->cur_prog = -1;
1453 else
1454 dev->cur_conf = -1;
1455 }
1456
tasdev_bytes_chksum(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn,unsigned char book,unsigned char page,unsigned char reg,unsigned int len,unsigned char val,unsigned char * crc_chksum)1457 static int tasdev_bytes_chksum(struct tasdevice_priv *tas_priv,
1458 struct tasdev_blk *block, int chn, unsigned char book,
1459 unsigned char page, unsigned char reg, unsigned int len,
1460 unsigned char val, unsigned char *crc_chksum)
1461 {
1462 int ret;
1463
1464 if (len > 1)
1465 ret = tasdev_multibytes_chksum(tas_priv, chn, book, page, reg,
1466 len);
1467 else
1468 ret = do_singlereg_checksum(tas_priv, chn, book, page, reg,
1469 val);
1470
1471 if (ret > 0) {
1472 *crc_chksum += (unsigned char)ret;
1473 goto end;
1474 }
1475
1476 if (ret != -EAGAIN)
1477 goto end;
1478
1479 block->nr_retry--;
1480 if (block->nr_retry > 0)
1481 goto end;
1482
1483 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]);
1484
1485 end:
1486 return ret;
1487 }
1488
tasdev_multibytes_wr(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn,unsigned char book,unsigned char page,unsigned char reg,unsigned char * data,unsigned int len,unsigned int * nr_cmds,unsigned char * crc_chksum)1489 static int tasdev_multibytes_wr(struct tasdevice_priv *tas_priv,
1490 struct tasdev_blk *block, int chn, unsigned char book,
1491 unsigned char page, unsigned char reg, unsigned char *data,
1492 unsigned int len, unsigned int *nr_cmds,
1493 unsigned char *crc_chksum)
1494 {
1495 int ret;
1496
1497 if (len > 1) {
1498 ret = tasdevice_dev_bulk_write(tas_priv, chn,
1499 TASDEVICE_REG(book, page, reg), data + 3, len);
1500 if (ret < 0)
1501 goto end;
1502 if (block->is_ychksum_present)
1503 ret = tasdev_bytes_chksum(tas_priv, block, chn,
1504 book, page, reg, len, 0, crc_chksum);
1505 } else {
1506 ret = tasdevice_dev_write(tas_priv, chn,
1507 TASDEVICE_REG(book, page, reg), data[3]);
1508 if (ret < 0)
1509 goto end;
1510 if (block->is_ychksum_present)
1511 ret = tasdev_bytes_chksum(tas_priv, block, chn, book,
1512 page, reg, 1, data[3], crc_chksum);
1513 }
1514
1515 if (!block->is_ychksum_present || ret >= 0) {
1516 *nr_cmds += 1;
1517 if (len >= 2)
1518 *nr_cmds += ((len - 2) / 4) + 1;
1519 }
1520
1521 end:
1522 return ret;
1523 }
1524
tasdev_block_chksum(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn)1525 static int tasdev_block_chksum(struct tasdevice_priv *tas_priv,
1526 struct tasdev_blk *block, int chn)
1527 {
1528 unsigned int nr_value;
1529 int ret;
1530
1531 ret = tasdevice_dev_read(tas_priv, chn, TASDEVICE_I2CChecksum,
1532 &nr_value);
1533 if (ret < 0) {
1534 dev_err(tas_priv->dev, "%s: Chn %d\n", __func__, chn);
1535 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]);
1536 goto end;
1537 }
1538
1539 if ((nr_value & 0xff) != block->pchksum) {
1540 dev_err(tas_priv->dev, "%s: Blk PChkSum Chn %d ", __func__,
1541 chn);
1542 dev_err(tas_priv->dev, "PChkSum = 0x%x, Reg = 0x%x\n",
1543 block->pchksum, (nr_value & 0xff));
1544 tas_priv->tasdevice[chn].err_code |= ERROR_PRAM_CRCCHK;
1545 ret = -EAGAIN;
1546 block->nr_retry--;
1547
1548 if (block->nr_retry <= 0)
1549 set_err_prg_cfg(block->type,
1550 &tas_priv->tasdevice[chn]);
1551 } else
1552 tas_priv->tasdevice[chn].err_code &= ~ERROR_PRAM_CRCCHK;
1553
1554 end:
1555 return ret;
1556 }
1557
tasdev_load_blk(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn)1558 static int tasdev_load_blk(struct tasdevice_priv *tas_priv,
1559 struct tasdev_blk *block, int chn)
1560 {
1561 unsigned int sleep_time;
1562 unsigned int len;
1563 unsigned int nr_cmds;
1564 unsigned char *data = block->data;
1565 unsigned char crc_chksum = 0;
1566 unsigned char offset;
1567 unsigned char book;
1568 unsigned char page;
1569 unsigned char val;
1570 int ret = 0;
1571
1572 while (block->nr_retry > 0) {
1573 if (block->is_pchksum_present) {
1574 ret = tasdevice_dev_write(tas_priv, chn,
1575 TASDEVICE_I2CChecksum, 0);
1576 if (ret < 0)
1577 break;
1578 }
1579
1580 if (block->is_ychksum_present)
1581 crc_chksum = 0;
1582
1583 nr_cmds = 0;
1584
1585 while (nr_cmds < block->nr_cmds) {
1586 data = block->data + nr_cmds * 4;
1587
1588 book = data[0];
1589 page = data[1];
1590 offset = data[2];
1591 val = data[3];
1592
1593 nr_cmds++;
1594 /*Single byte write*/
1595 if (offset <= 0x7F) {
1596 ret = tasdevice_dev_write(tas_priv, chn,
1597 TASDEVICE_REG(book, page, offset),
1598 val);
1599 if (ret < 0)
1600 goto end;
1601 if (block->is_ychksum_present) {
1602 ret = tasdev_bytes_chksum(tas_priv,
1603 block, chn, book, page, offset,
1604 1, val, &crc_chksum);
1605 if (ret < 0)
1606 break;
1607 }
1608 continue;
1609 }
1610 /*sleep command*/
1611 if (offset == 0x81) {
1612 /*book -- data[0] page -- data[1]*/
1613 sleep_time = ((book << 8) + page)*1000;
1614 usleep_range(sleep_time, sleep_time + 50);
1615 continue;
1616 }
1617 /*Multiple bytes write*/
1618 if (offset == 0x85) {
1619 data += 4;
1620 len = (book << 8) + page;
1621 book = data[0];
1622 page = data[1];
1623 offset = data[2];
1624 ret = tasdev_multibytes_wr(tas_priv,
1625 block, chn, book, page, offset, data,
1626 len, &nr_cmds, &crc_chksum);
1627 if (ret < 0)
1628 break;
1629 }
1630 }
1631 if (ret == -EAGAIN) {
1632 if (block->nr_retry > 0)
1633 continue;
1634 } else if (ret < 0) /*err in current device, skip it*/
1635 break;
1636
1637 if (block->is_pchksum_present) {
1638 ret = tasdev_block_chksum(tas_priv, block, chn);
1639 if (ret == -EAGAIN) {
1640 if (block->nr_retry > 0)
1641 continue;
1642 } else if (ret < 0) /*err in current device, skip it*/
1643 break;
1644 }
1645
1646 if (block->is_ychksum_present) {
1647 /* TBD, open it when FW ready */
1648 dev_err(tas_priv->dev,
1649 "Blk YChkSum: FW = 0x%x, YCRC = 0x%x\n",
1650 block->ychksum, crc_chksum);
1651
1652 tas_priv->tasdevice[chn].err_code &=
1653 ~ERROR_YRAM_CRCCHK;
1654 ret = 0;
1655 }
1656 /*skip current blk*/
1657 break;
1658 }
1659
1660 end:
1661 return ret;
1662 }
1663
tasdevice_load_block(struct tasdevice_priv * tas_priv,struct tasdev_blk * block)1664 static int tasdevice_load_block(struct tasdevice_priv *tas_priv,
1665 struct tasdev_blk *block)
1666 {
1667 int chnend = 0;
1668 int ret = 0;
1669 int chn = 0;
1670 int rc = 0;
1671
1672 switch (block->type) {
1673 case MAIN_ALL_DEVICES:
1674 chn = 0;
1675 chnend = tas_priv->ndev;
1676 break;
1677 case MAIN_DEVICE_A:
1678 case COEFF_DEVICE_A:
1679 case PRE_DEVICE_A:
1680 chn = 0;
1681 chnend = 1;
1682 break;
1683 case MAIN_DEVICE_B:
1684 case COEFF_DEVICE_B:
1685 case PRE_DEVICE_B:
1686 chn = 1;
1687 chnend = 2;
1688 break;
1689 case MAIN_DEVICE_C:
1690 case COEFF_DEVICE_C:
1691 case PRE_DEVICE_C:
1692 chn = 2;
1693 chnend = 3;
1694 break;
1695 case MAIN_DEVICE_D:
1696 case COEFF_DEVICE_D:
1697 case PRE_DEVICE_D:
1698 chn = 3;
1699 chnend = 4;
1700 break;
1701 default:
1702 dev_dbg(tas_priv->dev, "load blk: Other Type = 0x%02x\n",
1703 block->type);
1704 break;
1705 }
1706
1707 for (; chn < chnend; chn++) {
1708 block->nr_retry = 6;
1709 if (tas_priv->tasdevice[chn].is_loading == false)
1710 continue;
1711 ret = tasdev_load_blk(tas_priv, block, chn);
1712 if (ret < 0)
1713 dev_err(tas_priv->dev, "dev %d, Blk (%d) load error\n",
1714 chn, block->type);
1715 rc |= ret;
1716 }
1717
1718 return rc;
1719 }
1720
dspfw_default_callback(struct tasdevice_priv * tas_priv,unsigned int drv_ver,unsigned int ppcver)1721 static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
1722 unsigned int drv_ver, unsigned int ppcver)
1723 {
1724 int rc = 0;
1725
1726 if (drv_ver == 0x100) {
1727 if (ppcver >= PPC3_VERSION) {
1728 tas_priv->fw_parse_variable_header =
1729 fw_parse_variable_header_kernel;
1730 tas_priv->fw_parse_program_data =
1731 fw_parse_program_data_kernel;
1732 tas_priv->fw_parse_configuration_data =
1733 fw_parse_configuration_data_kernel;
1734 tas_priv->tasdevice_load_block =
1735 tasdevice_load_block_kernel;
1736 } else {
1737 switch (ppcver) {
1738 case 0x00:
1739 tas_priv->fw_parse_variable_header =
1740 fw_parse_variable_header_git;
1741 tas_priv->fw_parse_program_data =
1742 fw_parse_program_data;
1743 tas_priv->fw_parse_configuration_data =
1744 fw_parse_configuration_data;
1745 tas_priv->tasdevice_load_block =
1746 tasdevice_load_block;
1747 break;
1748 default:
1749 dev_err(tas_priv->dev,
1750 "%s: PPCVer must be 0x0 or 0x%02x",
1751 __func__, PPC3_VERSION);
1752 dev_err(tas_priv->dev, " Current:0x%02x\n",
1753 ppcver);
1754 rc = -EINVAL;
1755 break;
1756 }
1757 }
1758 } else {
1759 dev_err(tas_priv->dev,
1760 "DrvVer must be 0x0, 0x230 or above 0x230 ");
1761 dev_err(tas_priv->dev, "current is 0x%02x\n", drv_ver);
1762 rc = -EINVAL;
1763 }
1764
1765 return rc;
1766 }
1767
load_calib_data(struct tasdevice_priv * tas_priv,struct tasdevice_data * dev_data)1768 static int load_calib_data(struct tasdevice_priv *tas_priv,
1769 struct tasdevice_data *dev_data)
1770 {
1771 struct tasdev_blk *block;
1772 unsigned int i;
1773 int ret = 0;
1774
1775 for (i = 0; i < dev_data->nr_blk; i++) {
1776 block = &(dev_data->dev_blks[i]);
1777 ret = tasdevice_load_block(tas_priv, block);
1778 if (ret < 0)
1779 break;
1780 }
1781
1782 return ret;
1783 }
1784
fw_parse_header(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1785 static int fw_parse_header(struct tasdevice_priv *tas_priv,
1786 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1787 {
1788 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
1789 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr);
1790 const unsigned char magic_number[] = { 0x35, 0x35, 0x35, 0x32 };
1791 const unsigned char *buf = (unsigned char *)fmw->data;
1792
1793 if (offset + 92 > fmw->size) {
1794 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1795 offset = -EINVAL;
1796 goto out;
1797 }
1798 if (memcmp(&buf[offset], magic_number, 4)) {
1799 dev_err(tas_priv->dev, "%s: Magic num NOT match\n", __func__);
1800 offset = -EINVAL;
1801 goto out;
1802 }
1803 offset += 4;
1804
1805 /* Convert data[offset], data[offset + 1], data[offset + 2] and
1806 * data[offset + 3] into host
1807 */
1808 fw_fixed_hdr->fwsize = be32_to_cpup((__be32 *)&buf[offset]);
1809 offset += 4;
1810 if (fw_fixed_hdr->fwsize != fmw->size) {
1811 dev_err(tas_priv->dev, "File size not match, %lu %u",
1812 (unsigned long)fmw->size, fw_fixed_hdr->fwsize);
1813 offset = -EINVAL;
1814 goto out;
1815 }
1816 offset += 4;
1817 fw_fixed_hdr->ppcver = be32_to_cpup((__be32 *)&buf[offset]);
1818 offset += 8;
1819 fw_fixed_hdr->drv_ver = be32_to_cpup((__be32 *)&buf[offset]);
1820 offset += 72;
1821
1822 out:
1823 return offset;
1824 }
1825
fw_parse_variable_hdr_cal(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1826 static int fw_parse_variable_hdr_cal(struct tasdevice_priv *tas_priv,
1827 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1828 {
1829 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
1830
1831 offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset);
1832 if (offset < 0)
1833 goto out;
1834 if (fw_hdr->ndev != 1) {
1835 dev_err(tas_priv->dev,
1836 "%s: calbin must be 1, but currently ndev(%u)\n",
1837 __func__, fw_hdr->ndev);
1838 offset = -EINVAL;
1839 }
1840
1841 out:
1842 return offset;
1843 }
1844
1845 /* When calibrated data parsing error occurs, DSP can still work with default
1846 * calibrated data, memory resource related to calibrated data will be
1847 * released in the tasdevice_codec_remove.
1848 */
fw_parse_calibration_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1849 static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv,
1850 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1851 {
1852 struct tasdevice_calibration *calibration;
1853 unsigned char *data = (unsigned char *)fmw->data;
1854 unsigned int i, n;
1855
1856 if (offset + 2 > fmw->size) {
1857 dev_err(tas_priv->dev, "%s: Calibrations error\n", __func__);
1858 offset = -EINVAL;
1859 goto out;
1860 }
1861 tas_fmw->nr_calibrations = be16_to_cpup((__be16 *)&data[offset]);
1862 offset += 2;
1863
1864 if (tas_fmw->nr_calibrations != 1) {
1865 dev_err(tas_priv->dev,
1866 "%s: only supports one calibration (%d)!\n",
1867 __func__, tas_fmw->nr_calibrations);
1868 goto out;
1869 }
1870
1871 tas_fmw->calibrations = kcalloc(tas_fmw->nr_calibrations,
1872 sizeof(struct tasdevice_calibration), GFP_KERNEL);
1873 if (!tas_fmw->calibrations) {
1874 offset = -ENOMEM;
1875 goto out;
1876 }
1877 for (i = 0; i < tas_fmw->nr_calibrations; i++) {
1878 if (offset + 64 > fmw->size) {
1879 dev_err(tas_priv->dev, "Calibrations error\n");
1880 offset = -EINVAL;
1881 goto out;
1882 }
1883 calibration = &(tas_fmw->calibrations[i]);
1884 offset += 64;
1885
1886 n = strlen((char *)&data[offset]);
1887 /* skip '\0' and 2 unused bytes */
1888 n += 3;
1889 if (offset + n > fmw->size) {
1890 dev_err(tas_priv->dev, "Description err\n");
1891 offset = -EINVAL;
1892 goto out;
1893 }
1894 offset += n;
1895
1896 offset = fw_parse_data(tas_fmw, &(calibration->dev_data), fmw,
1897 offset);
1898 if (offset < 0)
1899 goto out;
1900 }
1901
1902 out:
1903 return offset;
1904 }
1905
tas2781_load_calibration(void * context,char * file_name,unsigned short i)1906 int tas2781_load_calibration(void *context, char *file_name,
1907 unsigned short i)
1908 {
1909 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context;
1910 struct tasdevice *tasdev = &(tas_priv->tasdevice[i]);
1911 const struct firmware *fw_entry;
1912 struct tasdevice_fw *tas_fmw;
1913 struct firmware fmw;
1914 int offset = 0;
1915 int ret;
1916
1917 ret = request_firmware(&fw_entry, file_name, tas_priv->dev);
1918 if (ret) {
1919 dev_err(tas_priv->dev, "%s: Request firmware %s failed\n",
1920 __func__, file_name);
1921 goto out;
1922 }
1923
1924 if (!fw_entry->size) {
1925 dev_err(tas_priv->dev, "%s: file read error: size = %lu\n",
1926 __func__, (unsigned long)fw_entry->size);
1927 ret = -EINVAL;
1928 goto out;
1929 }
1930 fmw.size = fw_entry->size;
1931 fmw.data = fw_entry->data;
1932
1933 tas_fmw = tasdev->cali_data_fmw = kzalloc(sizeof(struct tasdevice_fw),
1934 GFP_KERNEL);
1935 if (!tasdev->cali_data_fmw) {
1936 ret = -ENOMEM;
1937 goto out;
1938 }
1939 tas_fmw->dev = tas_priv->dev;
1940 offset = fw_parse_header(tas_priv, tas_fmw, &fmw, offset);
1941 if (offset == -EINVAL) {
1942 dev_err(tas_priv->dev, "fw_parse_header EXIT!\n");
1943 ret = offset;
1944 goto out;
1945 }
1946 offset = fw_parse_variable_hdr_cal(tas_priv, tas_fmw, &fmw, offset);
1947 if (offset == -EINVAL) {
1948 dev_err(tas_priv->dev,
1949 "%s: fw_parse_variable_header_cal EXIT!\n", __func__);
1950 ret = offset;
1951 goto out;
1952 }
1953 offset = fw_parse_program_data(tas_priv, tas_fmw, &fmw, offset);
1954 if (offset < 0) {
1955 dev_err(tas_priv->dev, "fw_parse_program_data EXIT!\n");
1956 ret = offset;
1957 goto out;
1958 }
1959 offset = fw_parse_configuration_data(tas_priv, tas_fmw, &fmw, offset);
1960 if (offset < 0) {
1961 dev_err(tas_priv->dev, "fw_parse_configuration_data EXIT!\n");
1962 ret = offset;
1963 goto out;
1964 }
1965 offset = fw_parse_calibration_data(tas_priv, tas_fmw, &fmw, offset);
1966 if (offset < 0) {
1967 dev_err(tas_priv->dev, "fw_parse_calibration_data EXIT!\n");
1968 ret = offset;
1969 goto out;
1970 }
1971
1972 out:
1973 if (fw_entry)
1974 release_firmware(fw_entry);
1975
1976 return ret;
1977 }
1978 EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, SND_SOC_TAS2781_FMWLIB);
1979
tasdevice_dspfw_ready(const struct firmware * fmw,void * context)1980 static int tasdevice_dspfw_ready(const struct firmware *fmw,
1981 void *context)
1982 {
1983 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
1984 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr;
1985 struct tasdevice_fw *tas_fmw;
1986 int offset = 0;
1987 int ret = 0;
1988
1989 if (!fmw || !fmw->data) {
1990 dev_err(tas_priv->dev, "%s: Failed to read firmware %s\n",
1991 __func__, tas_priv->coef_binaryname);
1992 ret = -EINVAL;
1993 goto out;
1994 }
1995
1996 tas_priv->fmw = kzalloc(sizeof(struct tasdevice_fw), GFP_KERNEL);
1997 if (!tas_priv->fmw) {
1998 ret = -ENOMEM;
1999 goto out;
2000 }
2001 tas_fmw = tas_priv->fmw;
2002 tas_fmw->dev = tas_priv->dev;
2003 offset = fw_parse_header(tas_priv, tas_fmw, fmw, offset);
2004
2005 if (offset == -EINVAL) {
2006 ret = -EINVAL;
2007 goto out;
2008 }
2009 fw_fixed_hdr = &(tas_fmw->fw_hdr.fixed_hdr);
2010 /* Support different versions of firmware */
2011 switch (fw_fixed_hdr->drv_ver) {
2012 case 0x301:
2013 case 0x302:
2014 case 0x502:
2015 tas_priv->fw_parse_variable_header =
2016 fw_parse_variable_header_kernel;
2017 tas_priv->fw_parse_program_data =
2018 fw_parse_program_data_kernel;
2019 tas_priv->fw_parse_configuration_data =
2020 fw_parse_configuration_data_kernel;
2021 tas_priv->tasdevice_load_block =
2022 tasdevice_load_block_kernel;
2023 break;
2024 case 0x202:
2025 case 0x400:
2026 tas_priv->fw_parse_variable_header =
2027 fw_parse_variable_header_git;
2028 tas_priv->fw_parse_program_data =
2029 fw_parse_program_data;
2030 tas_priv->fw_parse_configuration_data =
2031 fw_parse_configuration_data;
2032 tas_priv->tasdevice_load_block =
2033 tasdevice_load_block;
2034 break;
2035 default:
2036 ret = dspfw_default_callback(tas_priv,
2037 fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver);
2038 if (ret)
2039 goto out;
2040 break;
2041 }
2042
2043 offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset);
2044 if (offset < 0) {
2045 ret = offset;
2046 goto out;
2047 }
2048 offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw,
2049 offset);
2050 if (offset < 0) {
2051 ret = offset;
2052 goto out;
2053 }
2054 offset = tas_priv->fw_parse_configuration_data(tas_priv,
2055 tas_fmw, fmw, offset);
2056 if (offset < 0)
2057 ret = offset;
2058
2059 out:
2060 return ret;
2061 }
2062
tasdevice_dsp_parser(void * context)2063 int tasdevice_dsp_parser(void *context)
2064 {
2065 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context;
2066 const struct firmware *fw_entry;
2067 int ret;
2068
2069 ret = request_firmware(&fw_entry, tas_priv->coef_binaryname,
2070 tas_priv->dev);
2071 if (ret) {
2072 dev_err(tas_priv->dev, "%s: load %s error\n", __func__,
2073 tas_priv->coef_binaryname);
2074 goto out;
2075 }
2076
2077 ret = tasdevice_dspfw_ready(fw_entry, tas_priv);
2078 release_firmware(fw_entry);
2079 fw_entry = NULL;
2080
2081 out:
2082 return ret;
2083 }
2084 EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, SND_SOC_TAS2781_FMWLIB);
2085
tas2781_clear_calfirmware(struct tasdevice_fw * tas_fmw)2086 static void tas2781_clear_calfirmware(struct tasdevice_fw *tas_fmw)
2087 {
2088 struct tasdevice_calibration *calibration;
2089 struct tasdev_blk *block;
2090 struct tasdevice_data *im;
2091 unsigned int blks;
2092 int i;
2093
2094 if (!tas_fmw->calibrations)
2095 goto out;
2096
2097 for (i = 0; i < tas_fmw->nr_calibrations; i++) {
2098 calibration = &(tas_fmw->calibrations[i]);
2099 if (!calibration)
2100 continue;
2101
2102 im = &(calibration->dev_data);
2103
2104 if (!im->dev_blks)
2105 continue;
2106
2107 for (blks = 0; blks < im->nr_blk; blks++) {
2108 block = &(im->dev_blks[blks]);
2109 if (!block)
2110 continue;
2111 kfree(block->data);
2112 }
2113 kfree(im->dev_blks);
2114 }
2115 kfree(tas_fmw->calibrations);
2116 out:
2117 kfree(tas_fmw);
2118 }
2119
tasdevice_calbin_remove(void * context)2120 void tasdevice_calbin_remove(void *context)
2121 {
2122 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2123 struct tasdevice *tasdev;
2124 int i;
2125
2126 if (!tas_priv)
2127 return;
2128
2129 for (i = 0; i < tas_priv->ndev; i++) {
2130 tasdev = &(tas_priv->tasdevice[i]);
2131 if (!tasdev->cali_data_fmw)
2132 continue;
2133 tas2781_clear_calfirmware(tasdev->cali_data_fmw);
2134 tasdev->cali_data_fmw = NULL;
2135 }
2136 }
2137 EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, SND_SOC_TAS2781_FMWLIB);
2138
tasdevice_config_info_remove(void * context)2139 void tasdevice_config_info_remove(void *context)
2140 {
2141 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2142 struct tasdevice_rca *rca = &(tas_priv->rcabin);
2143 struct tasdevice_config_info **ci = rca->cfg_info;
2144 int i, j;
2145
2146 if (!ci)
2147 return;
2148 for (i = 0; i < rca->ncfgs; i++) {
2149 if (!ci[i])
2150 continue;
2151 if (ci[i]->blk_data) {
2152 for (j = 0; j < (int)ci[i]->real_nblocks; j++) {
2153 if (!ci[i]->blk_data[j])
2154 continue;
2155 kfree(ci[i]->blk_data[j]->regdata);
2156 kfree(ci[i]->blk_data[j]);
2157 }
2158 kfree(ci[i]->blk_data);
2159 }
2160 kfree(ci[i]);
2161 }
2162 kfree(ci);
2163 }
2164 EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, SND_SOC_TAS2781_FMWLIB);
2165
tasdevice_load_data(struct tasdevice_priv * tas_priv,struct tasdevice_data * dev_data)2166 static int tasdevice_load_data(struct tasdevice_priv *tas_priv,
2167 struct tasdevice_data *dev_data)
2168 {
2169 struct tasdev_blk *block;
2170 unsigned int i;
2171 int ret = 0;
2172
2173 for (i = 0; i < dev_data->nr_blk; i++) {
2174 block = &(dev_data->dev_blks[i]);
2175 ret = tas_priv->tasdevice_load_block(tas_priv, block);
2176 if (ret < 0)
2177 break;
2178 }
2179
2180 return ret;
2181 }
2182
tasdevice_select_tuningprm_cfg(void * context,int prm_no,int cfg_no,int rca_conf_no)2183 int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
2184 int cfg_no, int rca_conf_no)
2185 {
2186 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2187 struct tasdevice_rca *rca = &(tas_priv->rcabin);
2188 struct tasdevice_config_info **cfg_info = rca->cfg_info;
2189 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2190 struct tasdevice_prog *program;
2191 struct tasdevice_config *conf;
2192 int prog_status = 0;
2193 int status, i;
2194
2195 if (!tas_fmw) {
2196 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2197 goto out;
2198 }
2199
2200 if (cfg_no >= tas_fmw->nr_configurations) {
2201 dev_err(tas_priv->dev,
2202 "%s: cfg(%d) is not in range of conf %u\n",
2203 __func__, cfg_no, tas_fmw->nr_configurations);
2204 goto out;
2205 }
2206
2207 if (prm_no >= tas_fmw->nr_programs) {
2208 dev_err(tas_priv->dev,
2209 "%s: prm(%d) is not in range of Programs %u\n",
2210 __func__, prm_no, tas_fmw->nr_programs);
2211 goto out;
2212 }
2213
2214 if (rca_conf_no >= rca->ncfgs || rca_conf_no < 0 ||
2215 !cfg_info) {
2216 dev_err(tas_priv->dev,
2217 "conf_no:%d should be in range from 0 to %u\n",
2218 rca_conf_no, rca->ncfgs-1);
2219 goto out;
2220 }
2221
2222 conf = &(tas_fmw->configs[cfg_no]);
2223 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2224 if (cfg_info[rca_conf_no]->active_dev & (1 << i)) {
2225 if (tas_priv->tasdevice[i].cur_prog != prm_no
2226 || tas_priv->force_fwload_status) {
2227 tas_priv->tasdevice[i].cur_conf = -1;
2228 tas_priv->tasdevice[i].is_loading = true;
2229 prog_status++;
2230 }
2231 } else
2232 tas_priv->tasdevice[i].is_loading = false;
2233 tas_priv->tasdevice[i].is_loaderr = false;
2234 }
2235
2236 if (prog_status) {
2237 program = &(tas_fmw->programs[prm_no]);
2238 tasdevice_load_data(tas_priv, &(program->dev_data));
2239 for (i = 0; i < tas_priv->ndev; i++) {
2240 if (tas_priv->tasdevice[i].is_loaderr == true)
2241 continue;
2242 else if (tas_priv->tasdevice[i].is_loaderr == false
2243 && tas_priv->tasdevice[i].is_loading == true) {
2244 struct tasdevice_fw *cal_fmw =
2245 tas_priv->tasdevice[i].cali_data_fmw;
2246
2247 if (cal_fmw) {
2248 struct tasdevice_calibration
2249 *cal = cal_fmw->calibrations;
2250
2251 if (cal)
2252 load_calib_data(tas_priv,
2253 &(cal->dev_data));
2254 }
2255 tas_priv->tasdevice[i].cur_prog = prm_no;
2256 }
2257 }
2258 }
2259
2260 for (i = 0, status = 0; i < tas_priv->ndev; i++) {
2261 if (tas_priv->tasdevice[i].cur_conf != cfg_no
2262 && (cfg_info[rca_conf_no]->active_dev & (1 << i))
2263 && (tas_priv->tasdevice[i].is_loaderr == false)) {
2264 status++;
2265 tas_priv->tasdevice[i].is_loading = true;
2266 } else
2267 tas_priv->tasdevice[i].is_loading = false;
2268 }
2269
2270 if (status) {
2271 status = 0;
2272 tasdevice_load_data(tas_priv, &(conf->dev_data));
2273 for (i = 0; i < tas_priv->ndev; i++) {
2274 if (tas_priv->tasdevice[i].is_loaderr == true) {
2275 status |= 1 << (i + 4);
2276 continue;
2277 } else if (tas_priv->tasdevice[i].is_loaderr == false
2278 && tas_priv->tasdevice[i].is_loading == true)
2279 tas_priv->tasdevice[i].cur_conf = cfg_no;
2280 }
2281 } else
2282 dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n",
2283 __func__, cfg_no);
2284
2285 status |= cfg_info[rca_conf_no]->active_dev;
2286
2287 out:
2288 return prog_status;
2289 }
2290 EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg,
2291 SND_SOC_TAS2781_FMWLIB);
2292
tasdevice_prmg_load(void * context,int prm_no)2293 int tasdevice_prmg_load(void *context, int prm_no)
2294 {
2295 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2296 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2297 struct tasdevice_prog *program;
2298 int prog_status = 0;
2299 int i;
2300
2301 if (!tas_fmw) {
2302 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2303 goto out;
2304 }
2305
2306 if (prm_no >= tas_fmw->nr_programs) {
2307 dev_err(tas_priv->dev,
2308 "%s: prm(%d) is not in range of Programs %u\n",
2309 __func__, prm_no, tas_fmw->nr_programs);
2310 goto out;
2311 }
2312
2313 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2314 if (tas_priv->tasdevice[i].cur_prog != prm_no) {
2315 tas_priv->tasdevice[i].cur_conf = -1;
2316 tas_priv->tasdevice[i].is_loading = true;
2317 prog_status++;
2318 }
2319 }
2320
2321 if (prog_status) {
2322 program = &(tas_fmw->programs[prm_no]);
2323 tasdevice_load_data(tas_priv, &(program->dev_data));
2324 for (i = 0; i < tas_priv->ndev; i++) {
2325 if (tas_priv->tasdevice[i].is_loaderr == true)
2326 continue;
2327 else if (tas_priv->tasdevice[i].is_loaderr == false
2328 && tas_priv->tasdevice[i].is_loading == true)
2329 tas_priv->tasdevice[i].cur_prog = prm_no;
2330 }
2331 }
2332
2333 out:
2334 return prog_status;
2335 }
2336 EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, SND_SOC_TAS2781_FMWLIB);
2337
tasdevice_prmg_calibdata_load(void * context,int prm_no)2338 int tasdevice_prmg_calibdata_load(void *context, int prm_no)
2339 {
2340 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2341 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2342 struct tasdevice_prog *program;
2343 int prog_status = 0;
2344 int i;
2345
2346 if (!tas_fmw) {
2347 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2348 goto out;
2349 }
2350
2351 if (prm_no >= tas_fmw->nr_programs) {
2352 dev_err(tas_priv->dev,
2353 "%s: prm(%d) is not in range of Programs %u\n",
2354 __func__, prm_no, tas_fmw->nr_programs);
2355 goto out;
2356 }
2357
2358 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2359 if (tas_priv->tasdevice[i].cur_prog != prm_no) {
2360 tas_priv->tasdevice[i].cur_conf = -1;
2361 tas_priv->tasdevice[i].is_loading = true;
2362 prog_status++;
2363 }
2364 tas_priv->tasdevice[i].is_loaderr = false;
2365 }
2366
2367 if (prog_status) {
2368 program = &(tas_fmw->programs[prm_no]);
2369 tasdevice_load_data(tas_priv, &(program->dev_data));
2370 for (i = 0; i < tas_priv->ndev; i++) {
2371 if (tas_priv->tasdevice[i].is_loaderr == true)
2372 continue;
2373 else if (tas_priv->tasdevice[i].is_loaderr == false
2374 && tas_priv->tasdevice[i].is_loading == true) {
2375 struct tasdevice_fw *cal_fmw =
2376 tas_priv->tasdevice[i].cali_data_fmw;
2377
2378 if (cal_fmw) {
2379 struct tasdevice_calibration *cal =
2380 cal_fmw->calibrations;
2381
2382 if (cal)
2383 load_calib_data(tas_priv,
2384 &(cal->dev_data));
2385 }
2386 tas_priv->tasdevice[i].cur_prog = prm_no;
2387 }
2388 }
2389 }
2390
2391 out:
2392 return prog_status;
2393 }
2394 EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_calibdata_load,
2395 SND_SOC_TAS2781_FMWLIB);
2396
tasdevice_tuning_switch(void * context,int state)2397 void tasdevice_tuning_switch(void *context, int state)
2398 {
2399 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2400 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2401 int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
2402
2403 if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
2404 dev_err(tas_priv->dev, "DSP bin file not loaded\n");
2405 return;
2406 }
2407
2408 if (state == 0) {
2409 if (tas_priv->cur_prog < tas_fmw->nr_programs) {
2410 /*dsp mode or tuning mode*/
2411 profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
2412 tasdevice_select_tuningprm_cfg(tas_priv,
2413 tas_priv->cur_prog, tas_priv->cur_conf,
2414 profile_cfg_id);
2415 }
2416
2417 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
2418 TASDEVICE_BIN_BLK_PRE_POWER_UP);
2419 } else
2420 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
2421 TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
2422 }
2423 EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch,
2424 SND_SOC_TAS2781_FMWLIB);
2425
2426 MODULE_DESCRIPTION("Texas Firmware Support");
2427 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");
2428 MODULE_LICENSE("GPL");
2429