1 // SPDX-License-Identifier: GPL-2.0
3 // tas2781-fmwlib.c -- TASDEVICE firmware support
5 // Copyright 2023 - 2024 Texas Instruments, Inc.
7 // Author: Shenghao Ding <shenghao-ding@ti.com>
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>
16 #include <linux/of_irq.h>
17 #include <linux/regmap.h>
18 #include <linux/slab.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/tlv.h>
22 #include <sound/tas2781.h>
23 #include <linux/unaligned.h>
25 #define ERROR_PRAM_CRCCHK 0x0000000
26 #define ERROR_YRAM_CRCCHK 0x0000001
27 #define PPC_DRIVER_CRCCHK 0x00000200
29 #define TAS2781_SA_COEFF_SWAP_REG TASDEVICE_REG(0, 0x35, 0x2c)
30 #define TAS2781_YRAM_BOOK1 140
31 #define TAS2781_YRAM1_PAGE 42
32 #define TAS2781_YRAM1_START_REG 88
34 #define TAS2781_YRAM2_START_PAGE 43
35 #define TAS2781_YRAM2_END_PAGE 49
36 #define TAS2781_YRAM2_START_REG 8
37 #define TAS2781_YRAM2_END_REG 127
39 #define TAS2781_YRAM3_PAGE 50
40 #define TAS2781_YRAM3_START_REG 8
41 #define TAS2781_YRAM3_END_REG 27
43 /*should not include B0_P53_R44-R47 */
44 #define TAS2781_YRAM_BOOK2 0
45 #define TAS2781_YRAM4_START_PAGE 50
46 #define TAS2781_YRAM4_END_PAGE 60
48 #define TAS2781_YRAM5_PAGE 61
49 #define TAS2781_YRAM5_START_REG TAS2781_YRAM3_START_REG
50 #define TAS2781_YRAM5_END_REG TAS2781_YRAM3_END_REG
52 #define TASDEVICE_MAXPROGRAM_NUM_KERNEL 5
53 #define TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS 64
54 #define TASDEVICE_MAXCONFIG_NUM_KERNEL 10
55 #define MAIN_ALL_DEVICES_1X 0x01
56 #define MAIN_DEVICE_A_1X 0x02
57 #define MAIN_DEVICE_B_1X 0x03
58 #define MAIN_DEVICE_C_1X 0x04
59 #define MAIN_DEVICE_D_1X 0x05
60 #define COEFF_DEVICE_A_1X 0x12
61 #define COEFF_DEVICE_B_1X 0x13
62 #define COEFF_DEVICE_C_1X 0x14
63 #define COEFF_DEVICE_D_1X 0x15
64 #define PRE_DEVICE_A_1X 0x22
65 #define PRE_DEVICE_B_1X 0x23
66 #define PRE_DEVICE_C_1X 0x24
67 #define PRE_DEVICE_D_1X 0x25
68 #define PRE_SOFTWARE_RESET_DEVICE_A 0x41
69 #define PRE_SOFTWARE_RESET_DEVICE_B 0x42
70 #define PRE_SOFTWARE_RESET_DEVICE_C 0x43
71 #define PRE_SOFTWARE_RESET_DEVICE_D 0x44
72 #define POST_SOFTWARE_RESET_DEVICE_A 0x45
73 #define POST_SOFTWARE_RESET_DEVICE_B 0x46
74 #define POST_SOFTWARE_RESET_DEVICE_C 0x47
75 #define POST_SOFTWARE_RESET_DEVICE_D 0x48
82 struct blktyp_devidx_map
{
84 unsigned char dev_idx
;
87 static const char deviceNumber
[TASDEVICE_DSP_TAS_MAX_DEVICE
] = {
88 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4
91 /* fixed m68k compiling issue: mapping table can save code field */
92 static const struct blktyp_devidx_map ppc3_tas2781_mapping_table
[] = {
93 { MAIN_ALL_DEVICES_1X
, 0x80 },
94 { MAIN_DEVICE_A_1X
, 0x81 },
95 { COEFF_DEVICE_A_1X
, 0xC1 },
96 { PRE_DEVICE_A_1X
, 0xC1 },
97 { PRE_SOFTWARE_RESET_DEVICE_A
, 0xC1 },
98 { POST_SOFTWARE_RESET_DEVICE_A
, 0xC1 },
99 { MAIN_DEVICE_B_1X
, 0x82 },
100 { COEFF_DEVICE_B_1X
, 0xC2 },
101 { PRE_DEVICE_B_1X
, 0xC2 },
102 { PRE_SOFTWARE_RESET_DEVICE_B
, 0xC2 },
103 { POST_SOFTWARE_RESET_DEVICE_B
, 0xC2 },
104 { MAIN_DEVICE_C_1X
, 0x83 },
105 { COEFF_DEVICE_C_1X
, 0xC3 },
106 { PRE_DEVICE_C_1X
, 0xC3 },
107 { PRE_SOFTWARE_RESET_DEVICE_C
, 0xC3 },
108 { POST_SOFTWARE_RESET_DEVICE_C
, 0xC3 },
109 { MAIN_DEVICE_D_1X
, 0x84 },
110 { COEFF_DEVICE_D_1X
, 0xC4 },
111 { PRE_DEVICE_D_1X
, 0xC4 },
112 { PRE_SOFTWARE_RESET_DEVICE_D
, 0xC4 },
113 { POST_SOFTWARE_RESET_DEVICE_D
, 0xC4 },
116 static const struct blktyp_devidx_map ppc3_mapping_table
[] = {
117 { MAIN_ALL_DEVICES_1X
, 0x80 },
118 { MAIN_DEVICE_A_1X
, 0x81 },
119 { COEFF_DEVICE_A_1X
, 0xC1 },
120 { PRE_DEVICE_A_1X
, 0xC1 },
121 { MAIN_DEVICE_B_1X
, 0x82 },
122 { COEFF_DEVICE_B_1X
, 0xC2 },
123 { PRE_DEVICE_B_1X
, 0xC2 },
124 { MAIN_DEVICE_C_1X
, 0x83 },
125 { COEFF_DEVICE_C_1X
, 0xC3 },
126 { PRE_DEVICE_C_1X
, 0xC3 },
127 { MAIN_DEVICE_D_1X
, 0x84 },
128 { COEFF_DEVICE_D_1X
, 0xC4 },
129 { PRE_DEVICE_D_1X
, 0xC4 },
132 static const struct blktyp_devidx_map non_ppc3_mapping_table
[] = {
133 { MAIN_ALL_DEVICES
, 0x80 },
134 { MAIN_DEVICE_A
, 0x81 },
135 { COEFF_DEVICE_A
, 0xC1 },
136 { PRE_DEVICE_A
, 0xC1 },
137 { MAIN_DEVICE_B
, 0x82 },
138 { COEFF_DEVICE_B
, 0xC2 },
139 { PRE_DEVICE_B
, 0xC2 },
140 { MAIN_DEVICE_C
, 0x83 },
141 { COEFF_DEVICE_C
, 0xC3 },
142 { PRE_DEVICE_C
, 0xC3 },
143 { MAIN_DEVICE_D
, 0x84 },
144 { COEFF_DEVICE_D
, 0xC4 },
145 { PRE_DEVICE_D
, 0xC4 },
148 static struct tasdevice_config_info
*tasdevice_add_config(
149 struct tasdevice_priv
*tas_priv
, unsigned char *config_data
,
150 unsigned int config_size
, int *status
)
152 struct tasdevice_config_info
*cfg_info
;
153 struct tasdev_blk_data
**bk_da
;
154 unsigned int config_offset
= 0;
157 /* In most projects are many audio cases, such as music, handfree,
158 * receiver, games, audio-to-haptics, PMIC record, bypass mode,
159 * portrait, landscape, etc. Even in multiple audios, one or
160 * two of the chips will work for the special case, such as
161 * ultrasonic application. In order to support these variable-numbers
162 * of audio cases, flexible configs have been introduced in the
165 cfg_info
= kzalloc(sizeof(struct tasdevice_config_info
), GFP_KERNEL
);
171 if (tas_priv
->rcabin
.fw_hdr
.binary_version_num
>= 0x105) {
172 if (config_offset
+ 64 > (int)config_size
) {
174 dev_err(tas_priv
->dev
, "add conf: Out of boundary\n");
180 if (config_offset
+ 4 > (int)config_size
) {
182 dev_err(tas_priv
->dev
, "add config: Out of boundary\n");
186 /* convert data[offset], data[offset + 1], data[offset + 2] and
187 * data[offset + 3] into host
189 cfg_info
->nblocks
= get_unaligned_be32(&config_data
[config_offset
]);
192 /* Several kinds of dsp/algorithm firmwares can run on tas2781,
193 * the number and size of blk are not fixed and different among
196 bk_da
= cfg_info
->blk_data
= kcalloc(cfg_info
->nblocks
,
197 sizeof(struct tasdev_blk_data
*), GFP_KERNEL
);
202 cfg_info
->real_nblocks
= 0;
203 for (i
= 0; i
< cfg_info
->nblocks
; i
++) {
204 if (config_offset
+ 12 > config_size
) {
206 dev_err(tas_priv
->dev
,
207 "%s: Out of boundary: i = %d nblocks = %u!\n",
208 __func__
, i
, cfg_info
->nblocks
);
211 bk_da
[i
] = kzalloc(sizeof(struct tasdev_blk_data
), GFP_KERNEL
);
217 bk_da
[i
]->dev_idx
= config_data
[config_offset
];
220 bk_da
[i
]->block_type
= config_data
[config_offset
];
223 if (bk_da
[i
]->block_type
== TASDEVICE_BIN_BLK_PRE_POWER_UP
) {
224 if (bk_da
[i
]->dev_idx
== 0)
225 cfg_info
->active_dev
=
226 (1 << tas_priv
->ndev
) - 1;
228 cfg_info
->active_dev
|= 1 <<
229 (bk_da
[i
]->dev_idx
- 1);
232 bk_da
[i
]->yram_checksum
=
233 get_unaligned_be16(&config_data
[config_offset
]);
235 bk_da
[i
]->block_size
=
236 get_unaligned_be32(&config_data
[config_offset
]);
239 bk_da
[i
]->n_subblks
=
240 get_unaligned_be32(&config_data
[config_offset
]);
244 if (config_offset
+ bk_da
[i
]->block_size
> config_size
) {
246 dev_err(tas_priv
->dev
,
247 "%s: Out of boundary: i = %d blks = %u!\n",
248 __func__
, i
, cfg_info
->nblocks
);
251 /* instead of kzalloc+memcpy */
252 bk_da
[i
]->regdata
= kmemdup(&config_data
[config_offset
],
253 bk_da
[i
]->block_size
, GFP_KERNEL
);
254 if (!bk_da
[i
]->regdata
) {
259 config_offset
+= bk_da
[i
]->block_size
;
260 cfg_info
->real_nblocks
+= 1;
267 int tasdevice_rca_parser(void *context
, const struct firmware
*fmw
)
269 struct tasdevice_priv
*tas_priv
= context
;
270 struct tasdevice_config_info
**cfg_info
;
271 struct tasdevice_rca_hdr
*fw_hdr
;
272 struct tasdevice_rca
*rca
;
273 unsigned int total_config_sz
= 0;
279 rca
= &(tas_priv
->rcabin
);
280 fw_hdr
= &(rca
->fw_hdr
);
281 if (!fmw
|| !fmw
->data
) {
282 dev_err(tas_priv
->dev
, "Failed to read %s\n",
283 tas_priv
->rca_binaryname
);
284 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
288 buf
= (unsigned char *)fmw
->data
;
290 fw_hdr
->img_sz
= get_unaligned_be32(&buf
[offset
]);
292 if (fw_hdr
->img_sz
!= fmw
->size
) {
293 dev_err(tas_priv
->dev
,
294 "File size not match, %d %u", (int)fmw
->size
,
296 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
301 fw_hdr
->checksum
= get_unaligned_be32(&buf
[offset
]);
303 fw_hdr
->binary_version_num
= get_unaligned_be32(&buf
[offset
]);
304 if (fw_hdr
->binary_version_num
< 0x103) {
305 dev_err(tas_priv
->dev
, "File version 0x%04x is too low",
306 fw_hdr
->binary_version_num
);
307 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
312 fw_hdr
->drv_fw_version
= get_unaligned_be32(&buf
[offset
]);
314 fw_hdr
->plat_type
= buf
[offset
];
316 fw_hdr
->dev_family
= buf
[offset
];
318 fw_hdr
->reserve
= buf
[offset
];
320 fw_hdr
->ndev
= buf
[offset
];
322 if (fw_hdr
->ndev
!= tas_priv
->ndev
) {
323 dev_err(tas_priv
->dev
,
324 "ndev(%u) in rcabin mismatch ndev(%u) in DTS\n",
325 fw_hdr
->ndev
, tas_priv
->ndev
);
326 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
330 if (offset
+ TASDEVICE_DEVICE_SUM
> fw_hdr
->img_sz
) {
331 dev_err(tas_priv
->dev
, "rca_ready: Out of boundary!\n");
333 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
337 for (i
= 0; i
< TASDEVICE_DEVICE_SUM
; i
++, offset
++)
338 fw_hdr
->devs
[i
] = buf
[offset
];
340 fw_hdr
->nconfig
= get_unaligned_be32(&buf
[offset
]);
343 for (i
= 0; i
< TASDEVICE_CONFIG_SUM
; i
++) {
344 fw_hdr
->config_size
[i
] = get_unaligned_be32(&buf
[offset
]);
346 total_config_sz
+= fw_hdr
->config_size
[i
];
349 if (fw_hdr
->img_sz
- total_config_sz
!= (unsigned int)offset
) {
350 dev_err(tas_priv
->dev
, "Bin file error!\n");
352 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
356 cfg_info
= kcalloc(fw_hdr
->nconfig
, sizeof(*cfg_info
), GFP_KERNEL
);
359 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
362 rca
->cfg_info
= cfg_info
;
364 for (i
= 0; i
< (int)fw_hdr
->nconfig
; i
++) {
366 cfg_info
[i
] = tasdevice_add_config(tas_priv
, &buf
[offset
],
367 fw_hdr
->config_size
[i
], &ret
);
369 tas_priv
->fw_state
= TASDEVICE_DSP_FW_FAIL
;
372 offset
+= (int)fw_hdr
->config_size
[i
];
377 EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser
, SND_SOC_TAS2781_FMWLIB
);
379 /* fixed m68k compiling issue: mapping table can save code field */
380 static unsigned char map_dev_idx(struct tasdevice_fw
*tas_fmw
,
381 struct tasdev_blk
*block
)
384 struct blktyp_devidx_map
*p
=
385 (struct blktyp_devidx_map
*)non_ppc3_mapping_table
;
386 struct tasdevice_dspfw_hdr
*fw_hdr
= &(tas_fmw
->fw_hdr
);
387 struct tasdevice_fw_fixed_hdr
*fw_fixed_hdr
= &(fw_hdr
->fixed_hdr
);
389 int i
, n
= ARRAY_SIZE(non_ppc3_mapping_table
);
390 unsigned char dev_idx
= 0;
392 if (fw_fixed_hdr
->ppcver
>= PPC3_VERSION_TAS2781
) {
393 p
= (struct blktyp_devidx_map
*)ppc3_tas2781_mapping_table
;
394 n
= ARRAY_SIZE(ppc3_tas2781_mapping_table
);
395 } else if (fw_fixed_hdr
->ppcver
>= PPC3_VERSION
) {
396 p
= (struct blktyp_devidx_map
*)ppc3_mapping_table
;
397 n
= ARRAY_SIZE(ppc3_mapping_table
);
400 for (i
= 0; i
< n
; i
++) {
401 if (block
->type
== p
[i
].blktyp
) {
402 dev_idx
= p
[i
].dev_idx
;
410 static int fw_parse_block_data_kernel(struct tasdevice_fw
*tas_fmw
,
411 struct tasdev_blk
*block
, const struct firmware
*fmw
, int offset
)
413 const unsigned char *data
= fmw
->data
;
415 if (offset
+ 16 > fmw
->size
) {
416 dev_err(tas_fmw
->dev
, "%s: File Size error\n", __func__
);
421 /* convert data[offset], data[offset + 1], data[offset + 2] and
422 * data[offset + 3] into host
424 block
->type
= get_unaligned_be32(&data
[offset
]);
427 block
->is_pchksum_present
= data
[offset
];
430 block
->pchksum
= data
[offset
];
433 block
->is_ychksum_present
= data
[offset
];
436 block
->ychksum
= data
[offset
];
439 block
->blk_size
= get_unaligned_be32(&data
[offset
]);
442 block
->nr_subblocks
= get_unaligned_be32(&data
[offset
]);
445 /* fixed m68k compiling issue:
446 * 1. mapping table can save code field.
447 * 2. storing the dev_idx as a member of block can reduce unnecessary
448 * time and system resource comsumption of dev_idx mapping every
449 * time the block data writing to the dsp.
451 block
->dev_idx
= map_dev_idx(tas_fmw
, block
);
453 if (offset
+ block
->blk_size
> fmw
->size
) {
454 dev_err(tas_fmw
->dev
, "%s: nSublocks error\n", __func__
);
458 /* instead of kzalloc+memcpy */
459 block
->data
= kmemdup(&data
[offset
], block
->blk_size
, GFP_KERNEL
);
464 offset
+= block
->blk_size
;
470 static int fw_parse_data_kernel(struct tasdevice_fw
*tas_fmw
,
471 struct tasdevice_data
*img_data
, const struct firmware
*fmw
,
474 const unsigned char *data
= fmw
->data
;
475 struct tasdev_blk
*blk
;
478 if (offset
+ 4 > fmw
->size
) {
479 dev_err(tas_fmw
->dev
, "%s: File Size error\n", __func__
);
483 img_data
->nr_blk
= get_unaligned_be32(&data
[offset
]);
486 img_data
->dev_blks
= kcalloc(img_data
->nr_blk
,
487 sizeof(struct tasdev_blk
), GFP_KERNEL
);
488 if (!img_data
->dev_blks
) {
493 for (i
= 0; i
< img_data
->nr_blk
; i
++) {
494 blk
= &(img_data
->dev_blks
[i
]);
495 offset
= fw_parse_block_data_kernel(tas_fmw
, blk
, fmw
, offset
);
506 static int fw_parse_program_data_kernel(
507 struct tasdevice_priv
*tas_priv
, struct tasdevice_fw
*tas_fmw
,
508 const struct firmware
*fmw
, int offset
)
510 struct tasdevice_prog
*program
;
513 for (i
= 0; i
< tas_fmw
->nr_programs
; i
++) {
514 program
= &(tas_fmw
->programs
[i
]);
515 if (offset
+ 72 > fmw
->size
) {
516 dev_err(tas_priv
->dev
, "%s: mpName error\n", __func__
);
520 /*skip 72 unused byts*/
523 offset
= fw_parse_data_kernel(tas_fmw
, &(program
->dev_data
),
533 static int fw_parse_configuration_data_kernel(
534 struct tasdevice_priv
*tas_priv
,
535 struct tasdevice_fw
*tas_fmw
, const struct firmware
*fmw
, int offset
)
537 const unsigned char *data
= fmw
->data
;
538 struct tasdevice_config
*config
;
541 for (i
= 0; i
< tas_fmw
->nr_configurations
; i
++) {
542 config
= &(tas_fmw
->configs
[i
]);
543 if (offset
+ 80 > fmw
->size
) {
544 dev_err(tas_priv
->dev
, "%s: mpName error\n", __func__
);
548 memcpy(config
->name
, &data
[offset
], 64);
549 /*skip extra 16 bytes*/
552 offset
= fw_parse_data_kernel(tas_fmw
, &(config
->dev_data
),
562 static int fw_parse_variable_header_kernel(
563 struct tasdevice_priv
*tas_priv
, const struct firmware
*fmw
,
566 struct tasdevice_fw
*tas_fmw
= tas_priv
->fmw
;
567 struct tasdevice_dspfw_hdr
*fw_hdr
= &(tas_fmw
->fw_hdr
);
568 struct tasdevice_prog
*program
;
569 struct tasdevice_config
*config
;
570 const unsigned char *buf
= fmw
->data
;
571 unsigned short max_confs
;
574 if (offset
+ 12 + 4 * TASDEVICE_MAXPROGRAM_NUM_KERNEL
> fmw
->size
) {
575 dev_err(tas_priv
->dev
, "%s: File Size error\n", __func__
);
579 fw_hdr
->device_family
= get_unaligned_be16(&buf
[offset
]);
580 if (fw_hdr
->device_family
!= 0) {
581 dev_err(tas_priv
->dev
, "%s:not TAS device\n", __func__
);
586 fw_hdr
->device
= get_unaligned_be16(&buf
[offset
]);
587 if (fw_hdr
->device
>= TASDEVICE_DSP_TAS_MAX_DEVICE
||
588 fw_hdr
->device
== 6) {
589 dev_err(tas_priv
->dev
, "Unsupported dev %d\n", fw_hdr
->device
);
594 fw_hdr
->ndev
= deviceNumber
[fw_hdr
->device
];
596 if (fw_hdr
->ndev
!= tas_priv
->ndev
) {
597 dev_err(tas_priv
->dev
,
598 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n",
599 __func__
, fw_hdr
->ndev
, tas_priv
->ndev
);
604 tas_fmw
->nr_programs
= get_unaligned_be32(&buf
[offset
]);
607 if (tas_fmw
->nr_programs
== 0 || tas_fmw
->nr_programs
>
608 TASDEVICE_MAXPROGRAM_NUM_KERNEL
) {
609 dev_err(tas_priv
->dev
, "mnPrograms is invalid\n");
614 tas_fmw
->programs
= kcalloc(tas_fmw
->nr_programs
,
615 sizeof(struct tasdevice_prog
), GFP_KERNEL
);
616 if (!tas_fmw
->programs
) {
621 for (i
= 0; i
< tas_fmw
->nr_programs
; i
++) {
622 program
= &(tas_fmw
->programs
[i
]);
623 program
->prog_size
= get_unaligned_be32(&buf
[offset
]);
627 /* Skip the unused prog_size */
628 offset
+= 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL
- tas_fmw
->nr_programs
);
630 tas_fmw
->nr_configurations
= get_unaligned_be32(&buf
[offset
]);
633 /* The max number of config in firmware greater than 4 pieces of
634 * tas2781s is different from the one lower than 4 pieces of
637 max_confs
= (fw_hdr
->ndev
>= 4) ?
638 TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS
:
639 TASDEVICE_MAXCONFIG_NUM_KERNEL
;
640 if (tas_fmw
->nr_configurations
== 0 ||
641 tas_fmw
->nr_configurations
> max_confs
) {
642 dev_err(tas_priv
->dev
, "%s: Conf is invalid\n", __func__
);
647 if (offset
+ 4 * max_confs
> fmw
->size
) {
648 dev_err(tas_priv
->dev
, "%s: mpConfigurations err\n", __func__
);
653 tas_fmw
->configs
= kcalloc(tas_fmw
->nr_configurations
,
654 sizeof(struct tasdevice_config
), GFP_KERNEL
);
655 if (!tas_fmw
->configs
) {
660 for (i
= 0; i
< tas_fmw
->nr_programs
; i
++) {
661 config
= &(tas_fmw
->configs
[i
]);
662 config
->cfg_size
= get_unaligned_be32(&buf
[offset
]);
666 /* Skip the unused configs */
667 offset
+= 4 * (max_confs
- tas_fmw
->nr_programs
);
673 static int tasdevice_process_block(void *context
, unsigned char *data
,
674 unsigned char dev_idx
, int sublocksize
)
676 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*)context
;
677 int subblk_offset
, chn
, chnend
, rc
;
678 unsigned char subblk_typ
= data
[1];
679 int blktyp
= dev_idx
& 0xC0;
680 int idx
= dev_idx
& 0x3F;
688 chnend
= tas_priv
->ndev
;
691 for (; chn
< chnend
; chn
++) {
692 if (tas_priv
->tasdevice
[chn
].is_loading
== false)
697 switch (subblk_typ
) {
698 case TASDEVICE_CMD_SING_W
: {
700 unsigned short len
= get_unaligned_be16(&data
[2]);
703 if (subblk_offset
+ 4 * len
> sublocksize
) {
704 dev_err(tas_priv
->dev
,
705 "process_block: Out of boundary\n");
710 for (i
= 0; i
< len
; i
++) {
711 rc
= tasdevice_dev_write(tas_priv
, chn
,
712 TASDEVICE_REG(data
[subblk_offset
],
713 data
[subblk_offset
+ 1],
714 data
[subblk_offset
+ 2]),
715 data
[subblk_offset
+ 3]);
718 dev_err(tas_priv
->dev
,
719 "process_block: single write error\n");
725 case TASDEVICE_CMD_BURST
: {
726 unsigned short len
= get_unaligned_be16(&data
[2]);
729 if (subblk_offset
+ 4 + len
> sublocksize
) {
730 dev_err(tas_priv
->dev
,
731 "%s: BST Out of boundary\n",
737 dev_err(tas_priv
->dev
,
738 "%s:Bst-len(%u)not div by 4\n",
743 rc
= tasdevice_dev_bulk_write(tas_priv
, chn
,
744 TASDEVICE_REG(data
[subblk_offset
],
745 data
[subblk_offset
+ 1],
746 data
[subblk_offset
+ 2]),
747 &(data
[subblk_offset
+ 4]), len
);
750 dev_err(tas_priv
->dev
,
751 "%s: bulk_write error = %d\n",
754 subblk_offset
+= (len
+ 4);
757 case TASDEVICE_CMD_DELAY
: {
758 unsigned int sleep_time
= 0;
760 if (subblk_offset
+ 2 > sublocksize
) {
761 dev_err(tas_priv
->dev
,
762 "%s: delay Out of boundary\n",
767 sleep_time
= get_unaligned_be16(&data
[2]) * 1000;
768 usleep_range(sleep_time
, sleep_time
+ 50);
772 case TASDEVICE_CMD_FIELD_W
:
773 if (subblk_offset
+ 6 > sublocksize
) {
774 dev_err(tas_priv
->dev
,
775 "%s: bit write Out of boundary\n",
780 rc
= tasdevice_dev_update_bits(tas_priv
, chn
,
781 TASDEVICE_REG(data
[subblk_offset
+ 2],
782 data
[subblk_offset
+ 3],
783 data
[subblk_offset
+ 4]),
784 data
[subblk_offset
+ 1],
785 data
[subblk_offset
+ 5]);
788 dev_err(tas_priv
->dev
,
789 "%s: update_bits error = %d\n",
797 if (is_err
== true && blktyp
!= 0) {
798 if (blktyp
== 0x80) {
799 tas_priv
->tasdevice
[chn
].cur_prog
= -1;
800 tas_priv
->tasdevice
[chn
].cur_conf
= -1;
802 tas_priv
->tasdevice
[chn
].cur_conf
= -1;
806 return subblk_offset
;
809 void tasdevice_select_cfg_blk(void *pContext
, int conf_no
,
810 unsigned char block_type
)
812 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) pContext
;
813 struct tasdevice_rca
*rca
= &(tas_priv
->rcabin
);
814 struct tasdevice_config_info
**cfg_info
= rca
->cfg_info
;
815 struct tasdev_blk_data
**blk_data
;
816 int j
, k
, chn
, chnend
;
818 if (conf_no
>= rca
->ncfgs
|| conf_no
< 0 || !cfg_info
) {
819 dev_err(tas_priv
->dev
, "conf_no should be not more than %u\n",
823 blk_data
= cfg_info
[conf_no
]->blk_data
;
825 for (j
= 0; j
< (int)cfg_info
[conf_no
]->real_nblocks
; j
++) {
826 unsigned int length
= 0, rc
= 0;
828 if (block_type
> 5 || block_type
< 2) {
829 dev_err(tas_priv
->dev
,
830 "block_type should be in range from 2 to 5\n");
833 if (block_type
!= blk_data
[j
]->block_type
)
836 for (k
= 0; k
< (int)blk_data
[j
]->n_subblks
; k
++) {
837 if (blk_data
[j
]->dev_idx
) {
838 chn
= blk_data
[j
]->dev_idx
- 1;
839 chnend
= blk_data
[j
]->dev_idx
;
842 chnend
= tas_priv
->ndev
;
844 for (; chn
< chnend
; chn
++)
845 tas_priv
->tasdevice
[chn
].is_loading
= true;
847 rc
= tasdevice_process_block(tas_priv
,
848 blk_data
[j
]->regdata
+ length
,
849 blk_data
[j
]->dev_idx
,
850 blk_data
[j
]->block_size
- length
);
852 if (blk_data
[j
]->block_size
< length
) {
853 dev_err(tas_priv
->dev
,
854 "%s: %u %u out of boundary\n",
856 blk_data
[j
]->block_size
);
860 if (length
!= blk_data
[j
]->block_size
)
861 dev_err(tas_priv
->dev
, "%s: %u %u size is not same\n",
862 __func__
, length
, blk_data
[j
]->block_size
);
865 EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk
, SND_SOC_TAS2781_FMWLIB
);
867 static int tasdevice_load_block_kernel(
868 struct tasdevice_priv
*tasdevice
, struct tasdev_blk
*block
)
870 const unsigned int blk_size
= block
->blk_size
;
871 unsigned int i
, length
;
872 unsigned char *data
= block
->data
;
874 for (i
= 0, length
= 0; i
< block
->nr_subblocks
; i
++) {
875 int rc
= tasdevice_process_block(tasdevice
, data
+ length
,
876 block
->dev_idx
, blk_size
- length
);
878 dev_err(tasdevice
->dev
,
879 "%s: %u %u sublock write error\n",
880 __func__
, length
, blk_size
);
883 length
+= (unsigned int)rc
;
884 if (blk_size
< length
) {
885 dev_err(tasdevice
->dev
, "%s: %u %u out of boundary\n",
886 __func__
, length
, blk_size
);
894 static int fw_parse_variable_hdr(struct tasdevice_priv
895 *tas_priv
, struct tasdevice_dspfw_hdr
*fw_hdr
,
896 const struct firmware
*fmw
, int offset
)
898 const unsigned char *buf
= fmw
->data
;
899 int len
= strlen((char *)&buf
[offset
]);
903 if (offset
+ len
+ 8 > fmw
->size
) {
904 dev_err(tas_priv
->dev
, "%s: File Size error\n", __func__
);
911 fw_hdr
->device_family
= get_unaligned_be32(&buf
[offset
]);
912 if (fw_hdr
->device_family
!= 0) {
913 dev_err(tas_priv
->dev
, "%s: not TAS device\n", __func__
);
919 fw_hdr
->device
= get_unaligned_be32(&buf
[offset
]);
920 if (fw_hdr
->device
>= TASDEVICE_DSP_TAS_MAX_DEVICE
||
921 fw_hdr
->device
== 6) {
922 dev_err(tas_priv
->dev
, "Unsupported dev %d\n", fw_hdr
->device
);
927 fw_hdr
->ndev
= deviceNumber
[fw_hdr
->device
];
933 static int fw_parse_variable_header_git(struct tasdevice_priv
934 *tas_priv
, const struct firmware
*fmw
, int offset
)
936 struct tasdevice_fw
*tas_fmw
= tas_priv
->fmw
;
937 struct tasdevice_dspfw_hdr
*fw_hdr
= &(tas_fmw
->fw_hdr
);
939 offset
= fw_parse_variable_hdr(tas_priv
, fw_hdr
, fmw
, offset
);
942 if (fw_hdr
->ndev
!= tas_priv
->ndev
) {
943 dev_err(tas_priv
->dev
,
944 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n",
945 __func__
, fw_hdr
->ndev
, tas_priv
->ndev
);
953 static int fw_parse_block_data(struct tasdevice_fw
*tas_fmw
,
954 struct tasdev_blk
*block
, const struct firmware
*fmw
, int offset
)
956 unsigned char *data
= (unsigned char *)fmw
->data
;
959 if (offset
+ 8 > fmw
->size
) {
960 dev_err(tas_fmw
->dev
, "%s: Type error\n", __func__
);
964 block
->type
= get_unaligned_be32(&data
[offset
]);
967 if (tas_fmw
->fw_hdr
.fixed_hdr
.drv_ver
>= PPC_DRIVER_CRCCHK
) {
968 if (offset
+ 8 > fmw
->size
) {
969 dev_err(tas_fmw
->dev
, "PChkSumPresent error\n");
973 block
->is_pchksum_present
= data
[offset
];
976 block
->pchksum
= data
[offset
];
979 block
->is_ychksum_present
= data
[offset
];
982 block
->ychksum
= data
[offset
];
985 block
->is_pchksum_present
= 0;
986 block
->is_ychksum_present
= 0;
989 block
->nr_cmds
= get_unaligned_be32(&data
[offset
]);
992 n
= block
->nr_cmds
* 4;
993 if (offset
+ n
> fmw
->size
) {
994 dev_err(tas_fmw
->dev
,
995 "%s: File Size(%lu) error offset = %d n = %d\n",
996 __func__
, (unsigned long)fmw
->size
, offset
, n
);
1000 /* instead of kzalloc+memcpy */
1001 block
->data
= kmemdup(&data
[offset
], n
, GFP_KERNEL
);
1012 /* When parsing error occurs, all the memory resource will be released
1013 * in the end of tasdevice_rca_ready.
1015 static int fw_parse_data(struct tasdevice_fw
*tas_fmw
,
1016 struct tasdevice_data
*img_data
, const struct firmware
*fmw
,
1019 const unsigned char *data
= (unsigned char *)fmw
->data
;
1020 struct tasdev_blk
*blk
;
1024 if (offset
+ 64 > fmw
->size
) {
1025 dev_err(tas_fmw
->dev
, "%s: Name error\n", __func__
);
1029 memcpy(img_data
->name
, &data
[offset
], 64);
1032 n
= strlen((char *)&data
[offset
]);
1034 if (offset
+ n
+ 2 > fmw
->size
) {
1035 dev_err(tas_fmw
->dev
, "%s: Description error\n", __func__
);
1040 img_data
->nr_blk
= get_unaligned_be16(&data
[offset
]);
1043 img_data
->dev_blks
= kcalloc(img_data
->nr_blk
,
1044 sizeof(struct tasdev_blk
), GFP_KERNEL
);
1045 if (!img_data
->dev_blks
) {
1049 for (i
= 0; i
< img_data
->nr_blk
; i
++) {
1050 blk
= &(img_data
->dev_blks
[i
]);
1051 offset
= fw_parse_block_data(tas_fmw
, blk
, fmw
, offset
);
1062 /* When parsing error occurs, all the memory resource will be released
1063 * in the end of tasdevice_rca_ready.
1065 static int fw_parse_program_data(struct tasdevice_priv
*tas_priv
,
1066 struct tasdevice_fw
*tas_fmw
, const struct firmware
*fmw
, int offset
)
1068 unsigned char *buf
= (unsigned char *)fmw
->data
;
1069 struct tasdevice_prog
*program
;
1072 if (offset
+ 2 > fmw
->size
) {
1073 dev_err(tas_priv
->dev
, "%s: File Size error\n", __func__
);
1077 tas_fmw
->nr_programs
= get_unaligned_be16(&buf
[offset
]);
1080 if (tas_fmw
->nr_programs
== 0) {
1081 /*Not error in calibration Data file, return directly*/
1082 dev_info(tas_priv
->dev
, "%s: No Programs data, maybe calbin\n",
1088 kcalloc(tas_fmw
->nr_programs
, sizeof(struct tasdevice_prog
),
1090 if (!tas_fmw
->programs
) {
1094 for (i
= 0; i
< tas_fmw
->nr_programs
; i
++) {
1097 program
= &(tas_fmw
->programs
[i
]);
1098 if (offset
+ 64 > fmw
->size
) {
1099 dev_err(tas_priv
->dev
, "%s: mpName error\n", __func__
);
1105 n
= strlen((char *)&buf
[offset
]);
1106 /* skip '\0' and 5 unused bytes */
1108 if (offset
+ n
> fmw
->size
) {
1109 dev_err(tas_priv
->dev
, "Description err\n");
1116 offset
= fw_parse_data(tas_fmw
, &(program
->dev_data
), fmw
,
1126 /* When parsing error occurs, all the memory resource will be released
1127 * in the end of tasdevice_rca_ready.
1129 static int fw_parse_configuration_data(
1130 struct tasdevice_priv
*tas_priv
,
1131 struct tasdevice_fw
*tas_fmw
,
1132 const struct firmware
*fmw
, int offset
)
1134 unsigned char *data
= (unsigned char *)fmw
->data
;
1135 struct tasdevice_config
*config
;
1139 if (offset
+ 2 > fmw
->size
) {
1140 dev_err(tas_priv
->dev
, "%s: File Size error\n", __func__
);
1144 tas_fmw
->nr_configurations
= get_unaligned_be16(&data
[offset
]);
1147 if (tas_fmw
->nr_configurations
== 0) {
1148 dev_err(tas_priv
->dev
, "%s: Conf is zero\n", __func__
);
1149 /*Not error for calibration Data file, return directly*/
1152 tas_fmw
->configs
= kcalloc(tas_fmw
->nr_configurations
,
1153 sizeof(struct tasdevice_config
), GFP_KERNEL
);
1154 if (!tas_fmw
->configs
) {
1158 for (i
= 0; i
< tas_fmw
->nr_configurations
; i
++) {
1159 config
= &(tas_fmw
->configs
[i
]);
1160 if (offset
+ 64 > fmw
->size
) {
1161 dev_err(tas_priv
->dev
, "File Size err\n");
1165 memcpy(config
->name
, &data
[offset
], 64);
1168 n
= strlen((char *)&data
[offset
]);
1170 if (offset
+ n
> fmw
->size
) {
1171 dev_err(tas_priv
->dev
, "Description err\n");
1178 offset
= fw_parse_data(tas_fmw
, &(config
->dev_data
),
1188 static bool check_inpage_yram_rg(struct tas_crc
*cd
,
1189 unsigned char reg
, unsigned char len
)
1194 if (reg
<= TAS2781_YRAM5_END_REG
&&
1195 reg
>= TAS2781_YRAM5_START_REG
) {
1196 if (reg
+ len
> TAS2781_YRAM5_END_REG
)
1197 cd
->len
= TAS2781_YRAM5_END_REG
- reg
+ 1;
1202 } else if (reg
< TAS2781_YRAM5_START_REG
) {
1203 if (reg
+ len
> TAS2781_YRAM5_START_REG
) {
1204 cd
->offset
= TAS2781_YRAM5_START_REG
;
1205 cd
->len
= len
- TAS2781_YRAM5_START_REG
+ reg
;
1213 static bool check_inpage_yram_bk1(struct tas_crc
*cd
,
1214 unsigned char page
, unsigned char reg
, unsigned char len
)
1218 if (page
== TAS2781_YRAM1_PAGE
) {
1219 if (reg
>= TAS2781_YRAM1_START_REG
) {
1223 } else if (reg
+ len
> TAS2781_YRAM1_START_REG
) {
1224 cd
->offset
= TAS2781_YRAM1_START_REG
;
1225 cd
->len
= len
- TAS2781_YRAM1_START_REG
+ reg
;
1228 } else if (page
== TAS2781_YRAM3_PAGE
)
1229 in
= check_inpage_yram_rg(cd
, reg
, len
);
1235 * true -- the registers are in the inpage yram
1236 * false -- the registers are NOT in the inpage yram
1238 static bool check_inpage_yram(struct tas_crc
*cd
, unsigned char book
,
1239 unsigned char page
, unsigned char reg
, unsigned char len
)
1243 if (book
== TAS2781_YRAM_BOOK1
) {
1244 in
= check_inpage_yram_bk1(cd
, page
, reg
, len
);
1247 if (book
== TAS2781_YRAM_BOOK2
&& page
== TAS2781_YRAM5_PAGE
)
1248 in
= check_inpage_yram_rg(cd
, reg
, len
);
1254 static bool check_inblock_yram_bk(struct tas_crc
*cd
,
1255 unsigned char page
, unsigned char reg
, unsigned char len
)
1259 if ((page
>= TAS2781_YRAM4_START_PAGE
&&
1260 page
<= TAS2781_YRAM4_END_PAGE
) ||
1261 (page
>= TAS2781_YRAM2_START_PAGE
&&
1262 page
<= TAS2781_YRAM2_END_PAGE
)) {
1263 if (reg
<= TAS2781_YRAM2_END_REG
&&
1264 reg
>= TAS2781_YRAM2_START_REG
) {
1268 } else if (reg
< TAS2781_YRAM2_START_REG
) {
1269 if (reg
+ len
- 1 >= TAS2781_YRAM2_START_REG
) {
1270 cd
->offset
= TAS2781_YRAM2_START_REG
;
1271 cd
->len
= reg
+ len
- TAS2781_YRAM2_START_REG
;
1281 * true -- the registers are in the inblock yram
1282 * false -- the registers are NOT in the inblock yram
1284 static bool check_inblock_yram(struct tas_crc
*cd
, unsigned char book
,
1285 unsigned char page
, unsigned char reg
, unsigned char len
)
1289 if (book
== TAS2781_YRAM_BOOK1
|| book
== TAS2781_YRAM_BOOK2
)
1290 in
= check_inblock_yram_bk(cd
, page
, reg
, len
);
1295 static bool check_yram(struct tas_crc
*cd
, unsigned char book
,
1296 unsigned char page
, unsigned char reg
, unsigned char len
)
1300 in
= check_inpage_yram(cd
, book
, page
, reg
, len
);
1303 in
= check_inblock_yram(cd
, book
, page
, reg
, len
);
1309 static int tasdev_multibytes_chksum(struct tasdevice_priv
*tasdevice
,
1310 unsigned short chn
, unsigned char book
, unsigned char page
,
1311 unsigned char reg
, unsigned int len
)
1313 struct tas_crc crc_data
;
1314 unsigned char crc_chksum
= 0;
1315 unsigned char nBuf1
[128];
1320 if ((reg
+ len
- 1) > 127) {
1322 dev_err(tasdevice
->dev
, "firmware error\n");
1326 if ((book
== TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG
))
1327 && (page
== TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG
))
1328 && (reg
== TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG
))
1330 /*DSP swap command, pass */
1335 in
= check_yram(&crc_data
, book
, page
, reg
, len
);
1340 dev_err(tasdevice
->dev
, "firmware error\n");
1345 ret
= tasdevice_dev_bulk_read(tasdevice
, chn
,
1346 TASDEVICE_REG(book
, page
, crc_data
.offset
),
1347 nBuf1
, crc_data
.len
);
1351 for (i
= 0; i
< crc_data
.len
; i
++) {
1352 if ((book
== TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG
))
1353 && (page
== TASDEVICE_PAGE_ID(
1354 TAS2781_SA_COEFF_SWAP_REG
))
1355 && ((i
+ crc_data
.offset
)
1356 >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG
))
1357 && ((i
+ crc_data
.offset
)
1358 <= (TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG
)
1360 /*DSP swap command, bypass */
1363 crc_chksum
+= crc8(tasdevice
->crc8_lkp_tbl
, &nBuf1
[i
],
1373 static int do_singlereg_checksum(struct tasdevice_priv
*tasdevice
,
1374 unsigned short chl
, unsigned char book
, unsigned char page
,
1375 unsigned char reg
, unsigned char val
)
1377 struct tas_crc crc_data
;
1378 unsigned int nData1
;
1382 if ((book
== TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG
))
1383 && (page
== TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG
))
1384 && (reg
>= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG
))
1385 && (reg
<= (TASDEVICE_PAGE_REG(
1386 TAS2781_SA_COEFF_SWAP_REG
) + 4))) {
1387 /*DSP swap command, pass */
1392 in
= check_yram(&crc_data
, book
, page
, reg
, 1);
1395 ret
= tasdevice_dev_read(tasdevice
, chl
,
1396 TASDEVICE_REG(book
, page
, reg
), &nData1
);
1400 if (nData1
!= val
) {
1401 dev_err(tasdevice
->dev
,
1402 "B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1403 book
, page
, reg
, val
, nData1
);
1404 tasdevice
->tasdevice
[chl
].err_code
|= ERROR_YRAM_CRCCHK
;
1409 ret
= crc8(tasdevice
->crc8_lkp_tbl
, &val
, 1, 0);
1415 static void set_err_prg_cfg(unsigned int type
, struct tasdevice
*dev
)
1417 if ((type
== MAIN_ALL_DEVICES
) || (type
== MAIN_DEVICE_A
)
1418 || (type
== MAIN_DEVICE_B
) || (type
== MAIN_DEVICE_C
)
1419 || (type
== MAIN_DEVICE_D
))
1425 static int tasdev_bytes_chksum(struct tasdevice_priv
*tas_priv
,
1426 struct tasdev_blk
*block
, int chn
, unsigned char book
,
1427 unsigned char page
, unsigned char reg
, unsigned int len
,
1428 unsigned char val
, unsigned char *crc_chksum
)
1433 ret
= tasdev_multibytes_chksum(tas_priv
, chn
, book
, page
, reg
,
1436 ret
= do_singlereg_checksum(tas_priv
, chn
, book
, page
, reg
,
1440 *crc_chksum
+= (unsigned char)ret
;
1448 if (block
->nr_retry
> 0)
1451 set_err_prg_cfg(block
->type
, &tas_priv
->tasdevice
[chn
]);
1457 static int tasdev_multibytes_wr(struct tasdevice_priv
*tas_priv
,
1458 struct tasdev_blk
*block
, int chn
, unsigned char book
,
1459 unsigned char page
, unsigned char reg
, unsigned char *data
,
1460 unsigned int len
, unsigned int *nr_cmds
,
1461 unsigned char *crc_chksum
)
1466 ret
= tasdevice_dev_bulk_write(tas_priv
, chn
,
1467 TASDEVICE_REG(book
, page
, reg
), data
+ 3, len
);
1470 if (block
->is_ychksum_present
)
1471 ret
= tasdev_bytes_chksum(tas_priv
, block
, chn
,
1472 book
, page
, reg
, len
, 0, crc_chksum
);
1474 ret
= tasdevice_dev_write(tas_priv
, chn
,
1475 TASDEVICE_REG(book
, page
, reg
), data
[3]);
1478 if (block
->is_ychksum_present
)
1479 ret
= tasdev_bytes_chksum(tas_priv
, block
, chn
, book
,
1480 page
, reg
, 1, data
[3], crc_chksum
);
1483 if (!block
->is_ychksum_present
|| ret
>= 0) {
1486 *nr_cmds
+= ((len
- 2) / 4) + 1;
1493 static int tasdev_block_chksum(struct tasdevice_priv
*tas_priv
,
1494 struct tasdev_blk
*block
, int chn
)
1496 unsigned int nr_value
;
1499 ret
= tasdevice_dev_read(tas_priv
, chn
, TASDEVICE_I2CChecksum
,
1502 dev_err(tas_priv
->dev
, "%s: Chn %d\n", __func__
, chn
);
1503 set_err_prg_cfg(block
->type
, &tas_priv
->tasdevice
[chn
]);
1507 if ((nr_value
& 0xff) != block
->pchksum
) {
1508 dev_err(tas_priv
->dev
, "%s: Blk PChkSum Chn %d ", __func__
,
1510 dev_err(tas_priv
->dev
, "PChkSum = 0x%x, Reg = 0x%x\n",
1511 block
->pchksum
, (nr_value
& 0xff));
1512 tas_priv
->tasdevice
[chn
].err_code
|= ERROR_PRAM_CRCCHK
;
1516 if (block
->nr_retry
<= 0)
1517 set_err_prg_cfg(block
->type
,
1518 &tas_priv
->tasdevice
[chn
]);
1520 tas_priv
->tasdevice
[chn
].err_code
&= ~ERROR_PRAM_CRCCHK
;
1526 static int tasdev_load_blk(struct tasdevice_priv
*tas_priv
,
1527 struct tasdev_blk
*block
, int chn
)
1529 unsigned int sleep_time
;
1531 unsigned int nr_cmds
;
1532 unsigned char *data
;
1533 unsigned char crc_chksum
= 0;
1534 unsigned char offset
;
1540 while (block
->nr_retry
> 0) {
1541 if (block
->is_pchksum_present
) {
1542 ret
= tasdevice_dev_write(tas_priv
, chn
,
1543 TASDEVICE_I2CChecksum
, 0);
1548 if (block
->is_ychksum_present
)
1553 while (nr_cmds
< block
->nr_cmds
) {
1554 data
= block
->data
+ nr_cmds
* 4;
1562 /*Single byte write*/
1563 if (offset
<= 0x7F) {
1564 ret
= tasdevice_dev_write(tas_priv
, chn
,
1565 TASDEVICE_REG(book
, page
, offset
),
1569 if (block
->is_ychksum_present
) {
1570 ret
= tasdev_bytes_chksum(tas_priv
,
1571 block
, chn
, book
, page
, offset
,
1572 1, val
, &crc_chksum
);
1579 if (offset
== 0x81) {
1580 /*book -- data[0] page -- data[1]*/
1581 sleep_time
= ((book
<< 8) + page
)*1000;
1582 usleep_range(sleep_time
, sleep_time
+ 50);
1585 /*Multiple bytes write*/
1586 if (offset
== 0x85) {
1588 len
= (book
<< 8) + page
;
1592 ret
= tasdev_multibytes_wr(tas_priv
,
1593 block
, chn
, book
, page
, offset
, data
,
1594 len
, &nr_cmds
, &crc_chksum
);
1599 if (ret
== -EAGAIN
) {
1600 if (block
->nr_retry
> 0)
1602 } else if (ret
< 0) /*err in current device, skip it*/
1605 if (block
->is_pchksum_present
) {
1606 ret
= tasdev_block_chksum(tas_priv
, block
, chn
);
1607 if (ret
== -EAGAIN
) {
1608 if (block
->nr_retry
> 0)
1610 } else if (ret
< 0) /*err in current device, skip it*/
1614 if (block
->is_ychksum_present
) {
1615 /* TBD, open it when FW ready */
1616 dev_err(tas_priv
->dev
,
1617 "Blk YChkSum: FW = 0x%x, YCRC = 0x%x\n",
1618 block
->ychksum
, crc_chksum
);
1620 tas_priv
->tasdevice
[chn
].err_code
&=
1624 /*skip current blk*/
1632 static int tasdevice_load_block(struct tasdevice_priv
*tas_priv
,
1633 struct tasdev_blk
*block
)
1640 switch (block
->type
) {
1641 case MAIN_ALL_DEVICES
:
1643 chnend
= tas_priv
->ndev
;
1646 case COEFF_DEVICE_A
:
1652 case COEFF_DEVICE_B
:
1658 case COEFF_DEVICE_C
:
1664 case COEFF_DEVICE_D
:
1670 dev_dbg(tas_priv
->dev
, "load blk: Other Type = 0x%02x\n",
1675 for (; chn
< chnend
; chn
++) {
1676 block
->nr_retry
= 6;
1677 if (tas_priv
->tasdevice
[chn
].is_loading
== false)
1679 ret
= tasdev_load_blk(tas_priv
, block
, chn
);
1681 dev_err(tas_priv
->dev
, "dev %d, Blk (%d) load error\n",
1689 static int dspfw_default_callback(struct tasdevice_priv
*tas_priv
,
1690 unsigned int drv_ver
, unsigned int ppcver
)
1694 if (drv_ver
== 0x100) {
1695 if (ppcver
>= PPC3_VERSION
) {
1696 tas_priv
->fw_parse_variable_header
=
1697 fw_parse_variable_header_kernel
;
1698 tas_priv
->fw_parse_program_data
=
1699 fw_parse_program_data_kernel
;
1700 tas_priv
->fw_parse_configuration_data
=
1701 fw_parse_configuration_data_kernel
;
1702 tas_priv
->tasdevice_load_block
=
1703 tasdevice_load_block_kernel
;
1707 tas_priv
->fw_parse_variable_header
=
1708 fw_parse_variable_header_git
;
1709 tas_priv
->fw_parse_program_data
=
1710 fw_parse_program_data
;
1711 tas_priv
->fw_parse_configuration_data
=
1712 fw_parse_configuration_data
;
1713 tas_priv
->tasdevice_load_block
=
1714 tasdevice_load_block
;
1717 dev_err(tas_priv
->dev
,
1718 "%s: PPCVer must be 0x0 or 0x%02x",
1719 __func__
, PPC3_VERSION
);
1720 dev_err(tas_priv
->dev
, " Current:0x%02x\n",
1727 dev_err(tas_priv
->dev
,
1728 "DrvVer must be 0x0, 0x230 or above 0x230 ");
1729 dev_err(tas_priv
->dev
, "current is 0x%02x\n", drv_ver
);
1736 static int load_calib_data(struct tasdevice_priv
*tas_priv
,
1737 struct tasdevice_data
*dev_data
)
1739 struct tasdev_blk
*block
;
1743 for (i
= 0; i
< dev_data
->nr_blk
; i
++) {
1744 block
= &(dev_data
->dev_blks
[i
]);
1745 ret
= tasdevice_load_block(tas_priv
, block
);
1753 static int fw_parse_header(struct tasdevice_priv
*tas_priv
,
1754 struct tasdevice_fw
*tas_fmw
, const struct firmware
*fmw
, int offset
)
1756 struct tasdevice_dspfw_hdr
*fw_hdr
= &(tas_fmw
->fw_hdr
);
1757 struct tasdevice_fw_fixed_hdr
*fw_fixed_hdr
= &(fw_hdr
->fixed_hdr
);
1758 static const unsigned char magic_number
[] = { 0x35, 0x35, 0x35, 0x32 };
1759 const unsigned char *buf
= (unsigned char *)fmw
->data
;
1761 if (offset
+ 92 > fmw
->size
) {
1762 dev_err(tas_priv
->dev
, "%s: File Size error\n", __func__
);
1766 if (memcmp(&buf
[offset
], magic_number
, 4)) {
1767 dev_err(tas_priv
->dev
, "%s: Magic num NOT match\n", __func__
);
1773 /* Convert data[offset], data[offset + 1], data[offset + 2] and
1774 * data[offset + 3] into host
1776 fw_fixed_hdr
->fwsize
= get_unaligned_be32(&buf
[offset
]);
1778 if (fw_fixed_hdr
->fwsize
!= fmw
->size
) {
1779 dev_err(tas_priv
->dev
, "File size not match, %lu %u",
1780 (unsigned long)fmw
->size
, fw_fixed_hdr
->fwsize
);
1785 fw_fixed_hdr
->ppcver
= get_unaligned_be32(&buf
[offset
]);
1787 fw_fixed_hdr
->drv_ver
= get_unaligned_be32(&buf
[offset
]);
1794 static int fw_parse_variable_hdr_cal(struct tasdevice_priv
*tas_priv
,
1795 struct tasdevice_fw
*tas_fmw
, const struct firmware
*fmw
, int offset
)
1797 struct tasdevice_dspfw_hdr
*fw_hdr
= &(tas_fmw
->fw_hdr
);
1799 offset
= fw_parse_variable_hdr(tas_priv
, fw_hdr
, fmw
, offset
);
1802 if (fw_hdr
->ndev
!= 1) {
1803 dev_err(tas_priv
->dev
,
1804 "%s: calbin must be 1, but currently ndev(%u)\n",
1805 __func__
, fw_hdr
->ndev
);
1813 /* When calibrated data parsing error occurs, DSP can still work with default
1814 * calibrated data, memory resource related to calibrated data will be
1815 * released in the tasdevice_codec_remove.
1817 static int fw_parse_calibration_data(struct tasdevice_priv
*tas_priv
,
1818 struct tasdevice_fw
*tas_fmw
, const struct firmware
*fmw
, int offset
)
1820 struct tasdevice_calibration
*calibration
;
1821 unsigned char *data
= (unsigned char *)fmw
->data
;
1824 if (offset
+ 2 > fmw
->size
) {
1825 dev_err(tas_priv
->dev
, "%s: Calibrations error\n", __func__
);
1829 tas_fmw
->nr_calibrations
= get_unaligned_be16(&data
[offset
]);
1832 if (tas_fmw
->nr_calibrations
!= 1) {
1833 dev_err(tas_priv
->dev
,
1834 "%s: only supports one calibration (%d)!\n",
1835 __func__
, tas_fmw
->nr_calibrations
);
1839 tas_fmw
->calibrations
= kcalloc(tas_fmw
->nr_calibrations
,
1840 sizeof(struct tasdevice_calibration
), GFP_KERNEL
);
1841 if (!tas_fmw
->calibrations
) {
1845 for (i
= 0; i
< tas_fmw
->nr_calibrations
; i
++) {
1846 if (offset
+ 64 > fmw
->size
) {
1847 dev_err(tas_priv
->dev
, "Calibrations error\n");
1851 calibration
= &(tas_fmw
->calibrations
[i
]);
1854 n
= strlen((char *)&data
[offset
]);
1855 /* skip '\0' and 2 unused bytes */
1857 if (offset
+ n
> fmw
->size
) {
1858 dev_err(tas_priv
->dev
, "Description err\n");
1864 offset
= fw_parse_data(tas_fmw
, &(calibration
->dev_data
), fmw
,
1874 int tas2781_load_calibration(void *context
, char *file_name
,
1877 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*)context
;
1878 struct tasdevice
*tasdev
= &(tas_priv
->tasdevice
[i
]);
1879 const struct firmware
*fw_entry
= NULL
;
1880 struct tasdevice_fw
*tas_fmw
;
1881 struct firmware fmw
;
1885 ret
= request_firmware(&fw_entry
, file_name
, tas_priv
->dev
);
1887 dev_err(tas_priv
->dev
, "%s: Request firmware %s failed\n",
1888 __func__
, file_name
);
1892 if (!fw_entry
->size
) {
1893 dev_err(tas_priv
->dev
, "%s: file read error: size = %lu\n",
1894 __func__
, (unsigned long)fw_entry
->size
);
1898 fmw
.size
= fw_entry
->size
;
1899 fmw
.data
= fw_entry
->data
;
1901 tas_fmw
= tasdev
->cali_data_fmw
= kzalloc(sizeof(struct tasdevice_fw
),
1903 if (!tasdev
->cali_data_fmw
) {
1907 tas_fmw
->dev
= tas_priv
->dev
;
1908 offset
= fw_parse_header(tas_priv
, tas_fmw
, &fmw
, offset
);
1909 if (offset
== -EINVAL
) {
1910 dev_err(tas_priv
->dev
, "fw_parse_header EXIT!\n");
1914 offset
= fw_parse_variable_hdr_cal(tas_priv
, tas_fmw
, &fmw
, offset
);
1915 if (offset
== -EINVAL
) {
1916 dev_err(tas_priv
->dev
,
1917 "%s: fw_parse_variable_header_cal EXIT!\n", __func__
);
1921 offset
= fw_parse_program_data(tas_priv
, tas_fmw
, &fmw
, offset
);
1923 dev_err(tas_priv
->dev
, "fw_parse_program_data EXIT!\n");
1927 offset
= fw_parse_configuration_data(tas_priv
, tas_fmw
, &fmw
, offset
);
1929 dev_err(tas_priv
->dev
, "fw_parse_configuration_data EXIT!\n");
1933 offset
= fw_parse_calibration_data(tas_priv
, tas_fmw
, &fmw
, offset
);
1935 dev_err(tas_priv
->dev
, "fw_parse_calibration_data EXIT!\n");
1942 release_firmware(fw_entry
);
1946 EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration
, SND_SOC_TAS2781_FMWLIB
);
1948 static int tasdevice_dspfw_ready(const struct firmware
*fmw
,
1951 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) context
;
1952 struct tasdevice_fw_fixed_hdr
*fw_fixed_hdr
;
1953 struct tasdevice_fw
*tas_fmw
;
1957 if (!fmw
|| !fmw
->data
) {
1958 dev_err(tas_priv
->dev
, "%s: Failed to read firmware %s\n",
1959 __func__
, tas_priv
->coef_binaryname
);
1964 tas_priv
->fmw
= kzalloc(sizeof(struct tasdevice_fw
), GFP_KERNEL
);
1965 if (!tas_priv
->fmw
) {
1969 tas_fmw
= tas_priv
->fmw
;
1970 tas_fmw
->dev
= tas_priv
->dev
;
1971 offset
= fw_parse_header(tas_priv
, tas_fmw
, fmw
, offset
);
1973 if (offset
== -EINVAL
) {
1977 fw_fixed_hdr
= &(tas_fmw
->fw_hdr
.fixed_hdr
);
1978 /* Support different versions of firmware */
1979 switch (fw_fixed_hdr
->drv_ver
) {
1984 tas_priv
->fw_parse_variable_header
=
1985 fw_parse_variable_header_kernel
;
1986 tas_priv
->fw_parse_program_data
=
1987 fw_parse_program_data_kernel
;
1988 tas_priv
->fw_parse_configuration_data
=
1989 fw_parse_configuration_data_kernel
;
1990 tas_priv
->tasdevice_load_block
=
1991 tasdevice_load_block_kernel
;
1996 tas_priv
->fw_parse_variable_header
=
1997 fw_parse_variable_header_git
;
1998 tas_priv
->fw_parse_program_data
=
1999 fw_parse_program_data
;
2000 tas_priv
->fw_parse_configuration_data
=
2001 fw_parse_configuration_data
;
2002 tas_priv
->tasdevice_load_block
=
2003 tasdevice_load_block
;
2006 ret
= dspfw_default_callback(tas_priv
,
2007 fw_fixed_hdr
->drv_ver
, fw_fixed_hdr
->ppcver
);
2013 offset
= tas_priv
->fw_parse_variable_header(tas_priv
, fmw
, offset
);
2018 offset
= tas_priv
->fw_parse_program_data(tas_priv
, tas_fmw
, fmw
,
2024 offset
= tas_priv
->fw_parse_configuration_data(tas_priv
,
2025 tas_fmw
, fmw
, offset
);
2033 int tasdevice_dsp_parser(void *context
)
2035 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*)context
;
2036 const struct firmware
*fw_entry
;
2039 ret
= request_firmware(&fw_entry
, tas_priv
->coef_binaryname
,
2042 dev_err(tas_priv
->dev
, "%s: load %s error\n", __func__
,
2043 tas_priv
->coef_binaryname
);
2047 ret
= tasdevice_dspfw_ready(fw_entry
, tas_priv
);
2048 release_firmware(fw_entry
);
2054 EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser
, SND_SOC_TAS2781_FMWLIB
);
2056 static void tas2781_clear_calfirmware(struct tasdevice_fw
*tas_fmw
)
2058 struct tasdevice_calibration
*calibration
;
2059 struct tasdev_blk
*block
;
2060 struct tasdevice_data
*im
;
2064 if (!tas_fmw
->calibrations
)
2067 for (i
= 0; i
< tas_fmw
->nr_calibrations
; i
++) {
2068 calibration
= &(tas_fmw
->calibrations
[i
]);
2072 im
= &(calibration
->dev_data
);
2077 for (blks
= 0; blks
< im
->nr_blk
; blks
++) {
2078 block
= &(im
->dev_blks
[blks
]);
2083 kfree(im
->dev_blks
);
2085 kfree(tas_fmw
->calibrations
);
2090 void tasdevice_calbin_remove(void *context
)
2092 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) context
;
2093 struct tasdevice
*tasdev
;
2099 for (i
= 0; i
< tas_priv
->ndev
; i
++) {
2100 tasdev
= &(tas_priv
->tasdevice
[i
]);
2101 if (!tasdev
->cali_data_fmw
)
2103 tas2781_clear_calfirmware(tasdev
->cali_data_fmw
);
2104 tasdev
->cali_data_fmw
= NULL
;
2107 EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove
, SND_SOC_TAS2781_FMWLIB
);
2109 void tasdevice_config_info_remove(void *context
)
2111 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) context
;
2112 struct tasdevice_rca
*rca
= &(tas_priv
->rcabin
);
2113 struct tasdevice_config_info
**ci
= rca
->cfg_info
;
2118 for (i
= 0; i
< rca
->ncfgs
; i
++) {
2121 if (ci
[i
]->blk_data
) {
2122 for (j
= 0; j
< (int)ci
[i
]->real_nblocks
; j
++) {
2123 if (!ci
[i
]->blk_data
[j
])
2125 kfree(ci
[i
]->blk_data
[j
]->regdata
);
2126 kfree(ci
[i
]->blk_data
[j
]);
2128 kfree(ci
[i
]->blk_data
);
2134 EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove
, SND_SOC_TAS2781_FMWLIB
);
2136 static int tasdevice_load_data(struct tasdevice_priv
*tas_priv
,
2137 struct tasdevice_data
*dev_data
)
2139 struct tasdev_blk
*block
;
2143 for (i
= 0; i
< dev_data
->nr_blk
; i
++) {
2144 block
= &(dev_data
->dev_blks
[i
]);
2145 ret
= tas_priv
->tasdevice_load_block(tas_priv
, block
);
2153 static void tasdev_load_calibrated_data(struct tasdevice_priv
*priv
, int i
)
2155 struct tasdevice_fw
*cal_fmw
= priv
->tasdevice
[i
].cali_data_fmw
;
2156 struct calidata
*cali_data
= &priv
->cali_data
;
2157 struct cali_reg
*p
= &cali_data
->cali_reg_array
;
2158 unsigned char *data
= cali_data
->data
;
2159 struct tasdevice_calibration
*cal
;
2160 int k
= i
* (cali_data
->cali_dat_sz_per_dev
+ 1);
2163 /* Load the calibrated data from cal bin file */
2164 if (!priv
->is_user_space_calidata
&& cal_fmw
) {
2165 cal
= cal_fmw
->calibrations
;
2168 load_calib_data(priv
, &cal
->dev_data
);
2171 if (!priv
->is_user_space_calidata
)
2173 /* load calibrated data from user space */
2175 dev_err(priv
->dev
, "%s: no cal-data for dev %d from usr-spc\n",
2181 rc
= tasdevice_dev_bulk_write(priv
, i
, p
->r0_reg
, &(data
[k
]), 4);
2183 dev_err(priv
->dev
, "chn %d r0_reg bulk_wr err = %d\n", i
, rc
);
2187 rc
= tasdevice_dev_bulk_write(priv
, i
, p
->r0_low_reg
, &(data
[k
]), 4);
2189 dev_err(priv
->dev
, "chn %d r0_low_reg err = %d\n", i
, rc
);
2193 rc
= tasdevice_dev_bulk_write(priv
, i
, p
->invr0_reg
, &(data
[k
]), 4);
2195 dev_err(priv
->dev
, "chn %d invr0_reg err = %d\n", i
, rc
);
2199 rc
= tasdevice_dev_bulk_write(priv
, i
, p
->pow_reg
, &(data
[k
]), 4);
2201 dev_err(priv
->dev
, "chn %d pow_reg bulk_wr err = %d\n", i
, rc
);
2205 rc
= tasdevice_dev_bulk_write(priv
, i
, p
->tlimit_reg
, &(data
[k
]), 4);
2207 dev_err(priv
->dev
, "chn %d tlimit_reg err = %d\n", i
, rc
);
2212 int tasdevice_select_tuningprm_cfg(void *context
, int prm_no
,
2213 int cfg_no
, int rca_conf_no
)
2215 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) context
;
2216 struct tasdevice_rca
*rca
= &(tas_priv
->rcabin
);
2217 struct tasdevice_config_info
**cfg_info
= rca
->cfg_info
;
2218 struct tasdevice_fw
*tas_fmw
= tas_priv
->fmw
;
2219 struct tasdevice_prog
*program
;
2220 struct tasdevice_config
*conf
;
2221 int prog_status
= 0;
2225 dev_err(tas_priv
->dev
, "%s: Firmware is NULL\n", __func__
);
2229 if (cfg_no
>= tas_fmw
->nr_configurations
) {
2230 dev_err(tas_priv
->dev
,
2231 "%s: cfg(%d) is not in range of conf %u\n",
2232 __func__
, cfg_no
, tas_fmw
->nr_configurations
);
2236 if (prm_no
>= tas_fmw
->nr_programs
) {
2237 dev_err(tas_priv
->dev
,
2238 "%s: prm(%d) is not in range of Programs %u\n",
2239 __func__
, prm_no
, tas_fmw
->nr_programs
);
2243 if (rca_conf_no
>= rca
->ncfgs
|| rca_conf_no
< 0 ||
2245 dev_err(tas_priv
->dev
,
2246 "conf_no:%d should be in range from 0 to %u\n",
2247 rca_conf_no
, rca
->ncfgs
-1);
2251 for (i
= 0, prog_status
= 0; i
< tas_priv
->ndev
; i
++) {
2252 if (cfg_info
[rca_conf_no
]->active_dev
& (1 << i
)) {
2254 && (tas_priv
->tasdevice
[i
].cur_prog
!= prm_no
2255 || tas_priv
->force_fwload_status
)) {
2256 tas_priv
->tasdevice
[i
].cur_conf
= -1;
2257 tas_priv
->tasdevice
[i
].is_loading
= true;
2261 tas_priv
->tasdevice
[i
].is_loading
= false;
2262 tas_priv
->tasdevice
[i
].is_loaderr
= false;
2266 program
= &(tas_fmw
->programs
[prm_no
]);
2267 tasdevice_load_data(tas_priv
, &(program
->dev_data
));
2268 for (i
= 0; i
< tas_priv
->ndev
; i
++) {
2269 if (tas_priv
->tasdevice
[i
].is_loaderr
== true)
2271 if (tas_priv
->tasdevice
[i
].is_loaderr
== false &&
2272 tas_priv
->tasdevice
[i
].is_loading
== true)
2273 tas_priv
->tasdevice
[i
].cur_prog
= prm_no
;
2277 for (i
= 0, status
= 0; i
< tas_priv
->ndev
; i
++) {
2279 && tas_priv
->tasdevice
[i
].cur_conf
!= cfg_no
2280 && (cfg_info
[rca_conf_no
]->active_dev
& (1 << i
))
2281 && (tas_priv
->tasdevice
[i
].is_loaderr
== false)) {
2283 tas_priv
->tasdevice
[i
].is_loading
= true;
2285 tas_priv
->tasdevice
[i
].is_loading
= false;
2289 conf
= &(tas_fmw
->configs
[cfg_no
]);
2291 tasdevice_load_data(tas_priv
, &(conf
->dev_data
));
2292 for (i
= 0; i
< tas_priv
->ndev
; i
++) {
2293 if (tas_priv
->tasdevice
[i
].is_loaderr
== true) {
2294 status
|= BIT(i
+ 4);
2298 if (tas_priv
->tasdevice
[i
].is_loaderr
== false &&
2299 tas_priv
->tasdevice
[i
].is_loading
== true) {
2300 tasdev_load_calibrated_data(tas_priv
, i
);
2301 tas_priv
->tasdevice
[i
].cur_conf
= cfg_no
;
2305 dev_dbg(tas_priv
->dev
, "%s: Unneeded loading dsp conf %d\n",
2309 status
|= cfg_info
[rca_conf_no
]->active_dev
;
2314 EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg
,
2315 SND_SOC_TAS2781_FMWLIB
);
2317 int tasdevice_prmg_load(void *context
, int prm_no
)
2319 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) context
;
2320 struct tasdevice_fw
*tas_fmw
= tas_priv
->fmw
;
2321 struct tasdevice_prog
*program
;
2322 int prog_status
= 0;
2326 dev_err(tas_priv
->dev
, "%s: Firmware is NULL\n", __func__
);
2330 if (prm_no
>= tas_fmw
->nr_programs
) {
2331 dev_err(tas_priv
->dev
,
2332 "%s: prm(%d) is not in range of Programs %u\n",
2333 __func__
, prm_no
, tas_fmw
->nr_programs
);
2337 for (i
= 0, prog_status
= 0; i
< tas_priv
->ndev
; i
++) {
2338 if (prm_no
>= 0 && tas_priv
->tasdevice
[i
].cur_prog
!= prm_no
) {
2339 tas_priv
->tasdevice
[i
].cur_conf
= -1;
2340 tas_priv
->tasdevice
[i
].is_loading
= true;
2346 program
= &(tas_fmw
->programs
[prm_no
]);
2347 tasdevice_load_data(tas_priv
, &(program
->dev_data
));
2348 for (i
= 0; i
< tas_priv
->ndev
; i
++) {
2349 if (tas_priv
->tasdevice
[i
].is_loaderr
== true)
2351 else if (tas_priv
->tasdevice
[i
].is_loaderr
== false
2352 && tas_priv
->tasdevice
[i
].is_loading
== true)
2353 tas_priv
->tasdevice
[i
].cur_prog
= prm_no
;
2360 EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load
, SND_SOC_TAS2781_FMWLIB
);
2362 void tasdevice_tuning_switch(void *context
, int state
)
2364 struct tasdevice_priv
*tas_priv
= (struct tasdevice_priv
*) context
;
2365 struct tasdevice_fw
*tas_fmw
= tas_priv
->fmw
;
2366 int profile_cfg_id
= tas_priv
->rcabin
.profile_cfg_id
;
2369 * Only RCA-based Playback can still work with no dsp program running
2372 switch (tas_priv
->fw_state
) {
2373 case TASDEVICE_RCA_FW_OK
:
2374 case TASDEVICE_DSP_FW_ALL_OK
:
2381 if (tas_fmw
&& tas_priv
->cur_prog
< tas_fmw
->nr_programs
) {
2382 /* dsp mode or tuning mode */
2383 profile_cfg_id
= tas_priv
->rcabin
.profile_cfg_id
;
2384 tasdevice_select_tuningprm_cfg(tas_priv
,
2385 tas_priv
->cur_prog
, tas_priv
->cur_conf
,
2389 tasdevice_select_cfg_blk(tas_priv
, profile_cfg_id
,
2390 TASDEVICE_BIN_BLK_PRE_POWER_UP
);
2392 tasdevice_select_cfg_blk(tas_priv
, profile_cfg_id
,
2393 TASDEVICE_BIN_BLK_PRE_SHUTDOWN
);
2396 EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch
,
2397 SND_SOC_TAS2781_FMWLIB
);
2399 MODULE_DESCRIPTION("Texas Firmware Support");
2400 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");
2401 MODULE_LICENSE("GPL");