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 | ||
