diff options
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 84 | ||||
-rw-r--r-- | sound/soc/codecs/wm_adsp.h | 2 |
2 files changed, 77 insertions, 9 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 9af1bddc4c62..34f2905f0158 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -193,17 +193,25 @@ static void wm_adsp_buf_free(struct list_head *list) | |||
193 | 193 | ||
194 | #define WM_ADSP_NUM_FW 4 | 194 | #define WM_ADSP_NUM_FW 4 |
195 | 195 | ||
196 | #define WM_ADSP_FW_MBC_VSS 0 | ||
197 | #define WM_ADSP_FW_TX 1 | ||
198 | #define WM_ADSP_FW_TX_SPK 2 | ||
199 | #define WM_ADSP_FW_RX_ANC 3 | ||
200 | |||
196 | static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { | 201 | static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { |
197 | "MBC/VSS", "Tx", "Tx Speaker", "Rx ANC" | 202 | [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", |
203 | [WM_ADSP_FW_TX] = "Tx", | ||
204 | [WM_ADSP_FW_TX_SPK] = "Tx Speaker", | ||
205 | [WM_ADSP_FW_RX_ANC] = "Rx ANC", | ||
198 | }; | 206 | }; |
199 | 207 | ||
200 | static struct { | 208 | static struct { |
201 | const char *file; | 209 | const char *file; |
202 | } wm_adsp_fw[WM_ADSP_NUM_FW] = { | 210 | } wm_adsp_fw[WM_ADSP_NUM_FW] = { |
203 | { .file = "mbc-vss" }, | 211 | [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, |
204 | { .file = "tx" }, | 212 | [WM_ADSP_FW_TX] = { .file = "tx" }, |
205 | { .file = "tx-spk" }, | 213 | [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, |
206 | { .file = "rx-anc" }, | 214 | [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, |
207 | }; | 215 | }; |
208 | 216 | ||
209 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, | 217 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, |
@@ -549,13 +557,30 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) | |||
549 | buf_size = sizeof(adsp1_id); | 557 | buf_size = sizeof(adsp1_id); |
550 | 558 | ||
551 | algs = be32_to_cpu(adsp1_id.algs); | 559 | algs = be32_to_cpu(adsp1_id.algs); |
560 | dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); | ||
552 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", | 561 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", |
553 | be32_to_cpu(adsp1_id.fw.id), | 562 | dsp->fw_id, |
554 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, | 563 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, |
555 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, | 564 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, |
556 | be32_to_cpu(adsp1_id.fw.ver) & 0xff, | 565 | be32_to_cpu(adsp1_id.fw.ver) & 0xff, |
557 | algs); | 566 | algs); |
558 | 567 | ||
568 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
569 | if (!region) | ||
570 | return -ENOMEM; | ||
571 | region->type = WMFW_ADSP1_ZM; | ||
572 | region->alg = be32_to_cpu(adsp1_id.fw.id); | ||
573 | region->base = be32_to_cpu(adsp1_id.zm); | ||
574 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
575 | |||
576 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
577 | if (!region) | ||
578 | return -ENOMEM; | ||
579 | region->type = WMFW_ADSP1_DM; | ||
580 | region->alg = be32_to_cpu(adsp1_id.fw.id); | ||
581 | region->base = be32_to_cpu(adsp1_id.dm); | ||
582 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
583 | |||
559 | pos = sizeof(adsp1_id) / 2; | 584 | pos = sizeof(adsp1_id) / 2; |
560 | term = pos + ((sizeof(*adsp1_alg) * algs) / 2); | 585 | term = pos + ((sizeof(*adsp1_alg) * algs) / 2); |
561 | break; | 586 | break; |
@@ -573,13 +598,38 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) | |||
573 | buf_size = sizeof(adsp2_id); | 598 | buf_size = sizeof(adsp2_id); |
574 | 599 | ||
575 | algs = be32_to_cpu(adsp2_id.algs); | 600 | algs = be32_to_cpu(adsp2_id.algs); |
601 | dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); | ||
576 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", | 602 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", |
577 | be32_to_cpu(adsp2_id.fw.id), | 603 | dsp->fw_id, |
578 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, | 604 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, |
579 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, | 605 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, |
580 | be32_to_cpu(adsp2_id.fw.ver) & 0xff, | 606 | be32_to_cpu(adsp2_id.fw.ver) & 0xff, |
581 | algs); | 607 | algs); |
582 | 608 | ||
609 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
610 | if (!region) | ||
611 | return -ENOMEM; | ||
612 | region->type = WMFW_ADSP2_XM; | ||
613 | region->alg = be32_to_cpu(adsp2_id.fw.id); | ||
614 | region->base = be32_to_cpu(adsp2_id.xm); | ||
615 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
616 | |||
617 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
618 | if (!region) | ||
619 | return -ENOMEM; | ||
620 | region->type = WMFW_ADSP2_YM; | ||
621 | region->alg = be32_to_cpu(adsp2_id.fw.id); | ||
622 | region->base = be32_to_cpu(adsp2_id.ym); | ||
623 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
624 | |||
625 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
626 | if (!region) | ||
627 | return -ENOMEM; | ||
628 | region->type = WMFW_ADSP2_ZM; | ||
629 | region->alg = be32_to_cpu(adsp2_id.fw.id); | ||
630 | region->base = be32_to_cpu(adsp2_id.zm); | ||
631 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
632 | |||
583 | pos = sizeof(adsp2_id) / 2; | 633 | pos = sizeof(adsp2_id) / 2; |
584 | term = pos + ((sizeof(*adsp2_alg) * algs) / 2); | 634 | term = pos + ((sizeof(*adsp2_alg) * algs) / 2); |
585 | break; | 635 | break; |
@@ -781,8 +831,24 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
781 | case (WMFW_INFO_TEXT << 8): | 831 | case (WMFW_INFO_TEXT << 8): |
782 | break; | 832 | break; |
783 | case (WMFW_ABSOLUTE << 8): | 833 | case (WMFW_ABSOLUTE << 8): |
784 | region_name = "register"; | 834 | /* |
785 | reg = offset; | 835 | * Old files may use this for global |
836 | * coefficients. | ||
837 | */ | ||
838 | if (le32_to_cpu(blk->id) == dsp->fw_id && | ||
839 | offset == 0) { | ||
840 | region_name = "global coefficients"; | ||
841 | mem = wm_adsp_find_region(dsp, type); | ||
842 | if (!mem) { | ||
843 | adsp_err(dsp, "No ZM\n"); | ||
844 | break; | ||
845 | } | ||
846 | reg = wm_adsp_region_to_reg(mem, 0); | ||
847 | |||
848 | } else { | ||
849 | region_name = "register"; | ||
850 | reg = offset; | ||
851 | } | ||
786 | break; | 852 | break; |
787 | 853 | ||
788 | case WMFW_ADSP1_DM: | 854 | case WMFW_ADSP1_DM: |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index cb8871a3ec00..d6fd8af53b5d 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -46,6 +46,8 @@ struct wm_adsp { | |||
46 | 46 | ||
47 | struct list_head alg_regions; | 47 | struct list_head alg_regions; |
48 | 48 | ||
49 | int fw_id; | ||
50 | |||
49 | const struct wm_adsp_region *mem; | 51 | const struct wm_adsp_region *mem; |
50 | int num_mems; | 52 | int num_mems; |
51 | 53 | ||