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