diff options
| -rw-r--r-- | sound/soc/codecs/wm_adsp.c | 137 |
1 files changed, 119 insertions, 18 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 16b308a6bfbb..1c45d67cfb4f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
| @@ -598,8 +598,31 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, | |||
| 598 | return -EINVAL; | 598 | return -EINVAL; |
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x", | 601 | switch (dsp->fw_ver) { |
| 602 | dsp->num, region_name, alg_region->alg); | 602 | case 0: |
| 603 | case 1: | ||
| 604 | snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x", | ||
| 605 | dsp->num, region_name, alg_region->alg); | ||
| 606 | break; | ||
| 607 | default: | ||
| 608 | ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, | ||
| 609 | "DSP%d%c %.12s %x", dsp->num, *region_name, | ||
| 610 | wm_adsp_fw_text[dsp->fw], alg_region->alg); | ||
| 611 | |||
| 612 | /* Truncate the subname from the start if it is too long */ | ||
| 613 | if (subname) { | ||
| 614 | int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; | ||
| 615 | int skip = 0; | ||
| 616 | |||
| 617 | if (subname_len > avail) | ||
| 618 | skip = subname_len - avail; | ||
| 619 | |||
| 620 | snprintf(name + ret, | ||
| 621 | SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, " %.*s", | ||
| 622 | subname_len - skip, subname + skip); | ||
| 623 | } | ||
| 624 | break; | ||
| 625 | } | ||
| 603 | 626 | ||
| 604 | list_for_each_entry(ctl, &dsp->ctl_list, | 627 | list_for_each_entry(ctl, &dsp->ctl_list, |
| 605 | list) { | 628 | list) { |
| @@ -681,18 +704,73 @@ struct wm_coeff_parsed_coeff { | |||
| 681 | int len; | 704 | int len; |
| 682 | }; | 705 | }; |
| 683 | 706 | ||
| 707 | static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) | ||
| 708 | { | ||
| 709 | int length; | ||
| 710 | |||
| 711 | switch (bytes) { | ||
| 712 | case 1: | ||
| 713 | length = **pos; | ||
| 714 | break; | ||
| 715 | case 2: | ||
| 716 | length = le16_to_cpu(*((u16 *)*pos)); | ||
| 717 | break; | ||
| 718 | default: | ||
| 719 | return 0; | ||
| 720 | } | ||
| 721 | |||
| 722 | if (str) | ||
| 723 | *str = *pos + bytes; | ||
| 724 | |||
| 725 | *pos += ((length + bytes) + 3) & ~0x03; | ||
| 726 | |||
| 727 | return length; | ||
| 728 | } | ||
| 729 | |||
| 730 | static int wm_coeff_parse_int(int bytes, const u8 **pos) | ||
| 731 | { | ||
| 732 | int val = 0; | ||
| 733 | |||
| 734 | switch (bytes) { | ||
| 735 | case 2: | ||
| 736 | val = le16_to_cpu(*((u16 *)*pos)); | ||
| 737 | break; | ||
| 738 | case 4: | ||
| 739 | val = le32_to_cpu(*((u32 *)*pos)); | ||
| 740 | break; | ||
| 741 | default: | ||
| 742 | break; | ||
| 743 | } | ||
| 744 | |||
| 745 | *pos += bytes; | ||
| 746 | |||
| 747 | return val; | ||
| 748 | } | ||
| 749 | |||
| 684 | static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, | 750 | static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, |
| 685 | struct wm_coeff_parsed_alg *blk) | 751 | struct wm_coeff_parsed_alg *blk) |
| 686 | { | 752 | { |
| 687 | const struct wmfw_adsp_alg_data *raw; | 753 | const struct wmfw_adsp_alg_data *raw; |
| 688 | 754 | ||
| 689 | raw = (const struct wmfw_adsp_alg_data *)*data; | 755 | switch (dsp->fw_ver) { |
| 690 | *data = raw->data; | 756 | case 0: |
| 757 | case 1: | ||
| 758 | raw = (const struct wmfw_adsp_alg_data *)*data; | ||
| 759 | *data = raw->data; | ||
| 691 | 760 | ||
| 692 | blk->id = le32_to_cpu(raw->id); | 761 | blk->id = le32_to_cpu(raw->id); |
| 693 | blk->name = raw->name; | 762 | blk->name = raw->name; |
| 694 | blk->name_len = strlen(raw->name); | 763 | blk->name_len = strlen(raw->name); |
| 695 | blk->ncoeff = le32_to_cpu(raw->ncoeff); | 764 | blk->ncoeff = le32_to_cpu(raw->ncoeff); |
| 765 | break; | ||
| 766 | default: | ||
| 767 | blk->id = wm_coeff_parse_int(sizeof(raw->id), data); | ||
| 768 | blk->name_len = wm_coeff_parse_string(sizeof(u8), data, | ||
| 769 | &blk->name); | ||
| 770 | wm_coeff_parse_string(sizeof(u16), data, NULL); | ||
| 771 | blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); | ||
| 772 | break; | ||
| 773 | } | ||
| 696 | 774 | ||
| 697 | adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); | 775 | adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); |
| 698 | adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); | 776 | adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); |
| @@ -703,17 +781,39 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, | |||
| 703 | struct wm_coeff_parsed_coeff *blk) | 781 | struct wm_coeff_parsed_coeff *blk) |
| 704 | { | 782 | { |
| 705 | const struct wmfw_adsp_coeff_data *raw; | 783 | const struct wmfw_adsp_coeff_data *raw; |
| 784 | const u8 *tmp; | ||
| 785 | int length; | ||
| 706 | 786 | ||
| 707 | raw = (const struct wmfw_adsp_coeff_data *)*data; | 787 | switch (dsp->fw_ver) { |
| 708 | *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); | 788 | case 0: |
| 709 | 789 | case 1: | |
| 710 | blk->offset = le16_to_cpu(raw->hdr.offset); | 790 | raw = (const struct wmfw_adsp_coeff_data *)*data; |
| 711 | blk->mem_type = le16_to_cpu(raw->hdr.type); | 791 | *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); |
| 712 | blk->name = raw->name; | 792 | |
| 713 | blk->name_len = strlen(raw->name); | 793 | blk->offset = le16_to_cpu(raw->hdr.offset); |
| 714 | blk->ctl_type = le16_to_cpu(raw->ctl_type); | 794 | blk->mem_type = le16_to_cpu(raw->hdr.type); |
| 715 | blk->flags = le16_to_cpu(raw->flags); | 795 | blk->name = raw->name; |
| 716 | blk->len = le32_to_cpu(raw->len); | 796 | blk->name_len = strlen(raw->name); |
| 797 | blk->ctl_type = le16_to_cpu(raw->ctl_type); | ||
| 798 | blk->flags = le16_to_cpu(raw->flags); | ||
| 799 | blk->len = le32_to_cpu(raw->len); | ||
| 800 | break; | ||
| 801 | default: | ||
| 802 | tmp = *data; | ||
| 803 | blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); | ||
| 804 | blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); | ||
| 805 | length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); | ||
| 806 | blk->name_len = wm_coeff_parse_string(sizeof(u8), &tmp, | ||
| 807 | &blk->name); | ||
| 808 | wm_coeff_parse_string(sizeof(u8), &tmp, NULL); | ||
| 809 | wm_coeff_parse_string(sizeof(u16), &tmp, NULL); | ||
| 810 | blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); | ||
| 811 | blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); | ||
| 812 | blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); | ||
| 813 | |||
| 814 | *data = *data + sizeof(raw->hdr) + length; | ||
| 815 | break; | ||
| 816 | } | ||
| 717 | 817 | ||
| 718 | adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); | 818 | adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); |
| 719 | adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); | 819 | adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); |
| @@ -812,6 +912,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
| 812 | switch (header->ver) { | 912 | switch (header->ver) { |
| 813 | case 0: | 913 | case 0: |
| 814 | case 1: | 914 | case 1: |
| 915 | case 2: | ||
| 815 | break; | 916 | break; |
| 816 | default: | 917 | default: |
| 817 | adsp_err(dsp, "%s: unknown file format %d\n", | 918 | adsp_err(dsp, "%s: unknown file format %d\n", |
