Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Some minor SDCA preparation

Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>:

Make some small fixups and add some minor missing features that will be
needed for the next major part of the SDCA work. This series doesn't do
a lot on its own, but as the next series will add all the ALSA control
and DAPM graph creation it's probably best to get these minor things out
of the way to simplify review on the bigger stuff.

+424 -44
+90
include/sound/sdca_function.h
··· 44 44 */ 45 45 #define SDCA_MAX_DELAY_COUNT 256 46 46 47 + /* 48 + * Sanity check on size of affected controls data, can be expanded if needed. 49 + */ 50 + #define SDCA_MAX_AFFECTED_COUNT 2048 51 + 47 52 /** 48 53 * enum sdca_function_type - SDCA Function Type codes 49 54 * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. ··· 606 601 #define SDCA_CTL_DEVICE_SDCA_VERSION_NAME "Device SDCA Version" 607 602 608 603 /** 604 + * enum sdca_control_datatype - SDCA Control Data Types 605 + * 606 + * Data Types as described in the SDCA specification v1.0 section 607 + * 7.3. 608 + */ 609 + enum sdca_control_datatype { 610 + SDCA_CTL_DATATYPE_ONEBIT, 611 + SDCA_CTL_DATATYPE_INTEGER, 612 + SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE, 613 + SDCA_CTL_DATATYPE_BCD, 614 + SDCA_CTL_DATATYPE_Q7P8DB, 615 + SDCA_CTL_DATATYPE_BYTEINDEX, 616 + SDCA_CTL_DATATYPE_POSTURENUMBER, 617 + SDCA_CTL_DATATYPE_DP_INDEX, 618 + SDCA_CTL_DATATYPE_BITINDEX, 619 + SDCA_CTL_DATATYPE_BITMAP, 620 + SDCA_CTL_DATATYPE_GUID, 621 + SDCA_CTL_DATATYPE_IMPDEF, 622 + }; 623 + 624 + /** 609 625 * enum sdca_access_mode - SDCA Control access mode 610 626 * 611 627 * Access modes as described in the SDCA specification v1.0 section ··· 679 653 * @cn_list: A bitmask showing the valid Control Numbers within this Control, 680 654 * Control Numbers typically represent channels. 681 655 * @range: Buffer describing valid range of values for the Control. 656 + * @type: Format of the data in the Control. 682 657 * @mode: Access mode of the Control. 683 658 * @layers: Bitmask of access layers of the Control. 684 659 * @deferrable: Indicates if the access to the Control can be deferred. ··· 696 669 u64 cn_list; 697 670 698 671 struct sdca_control_range range; 672 + enum sdca_control_datatype type; 699 673 enum sdca_access_mode mode; 700 674 u8 layers; 701 675 ··· 933 905 }; 934 906 935 907 /** 908 + * struct sdca_ge_control - control entry in the affected controls list 909 + * @id: Entity ID of the Control affected. 910 + * @sel: Control Selector of the Control affected. 911 + * @cn: Control Number of the Control affected. 912 + * @val: Value written to Control for this Mode. 913 + */ 914 + struct sdca_ge_control { 915 + int id; 916 + int sel; 917 + int cn; 918 + int val; 919 + }; 920 + 921 + /** 922 + * struct sdca_ge_mode - mode entry in the affected controls list 923 + * @controls: Dynamically allocated array of controls written for this Mode. 924 + * @num_controls: Number of controls written in this Mode. 925 + * @val: GE Selector Mode value. 926 + */ 927 + struct sdca_ge_mode { 928 + struct sdca_ge_control *controls; 929 + int num_controls; 930 + int val; 931 + }; 932 + 933 + /** 934 + * struct sdca_entity_ge - information specific to Group Entities 935 + * @kctl: ALSA control pointer that can be used by linked Entities. 936 + * @modes: Dynamically allocated array of Modes and the Controls written 937 + * in each mode. 938 + * @num_modes: Number of Modes. 939 + */ 940 + struct sdca_entity_ge { 941 + struct snd_kcontrol_new *kctl; 942 + struct sdca_ge_mode *modes; 943 + int num_modes; 944 + }; 945 + 946 + /** 936 947 * struct sdca_entity - information for one SDCA Entity 937 948 * @label: String such as "OT 12". 938 949 * @id: Identifier used for addressing. 939 950 * @type: Type code for the Entity. 951 + * @group: Pointer to Group Entity controlling this one, NULL if N/A. 940 952 * @sources: Dynamically allocated array pointing to each input Entity 941 953 * connected to this Entity. 942 954 * @controls: Dynamically allocated array of Controls. ··· 985 917 * @iot: Input/Output Terminal specific Entity properties. 986 918 * @cs: Clock Source specific Entity properties. 987 919 * @pde: Power Domain Entity specific Entity properties. 920 + * @ge: Group Entity specific Entity properties. 988 921 */ 989 922 struct sdca_entity { 990 923 const char *label; 991 924 int id; 992 925 enum sdca_entity_type type; 993 926 927 + struct sdca_entity *group; 994 928 struct sdca_entity **sources; 995 929 struct sdca_control *controls; 996 930 int num_sources; ··· 1001 931 struct sdca_entity_iot iot; 1002 932 struct sdca_entity_cs cs; 1003 933 struct sdca_entity_pde pde; 934 + struct sdca_entity_ge ge; 1004 935 }; 1005 936 }; 1006 937 ··· 1183 1112 1184 1113 unsigned int busy_max_delay; 1185 1114 }; 1115 + 1116 + static inline u32 sdca_range(struct sdca_control_range *range, 1117 + unsigned int col, unsigned int row) 1118 + { 1119 + return range->data[(row * range->cols) + col]; 1120 + } 1121 + 1122 + static inline u32 sdca_range_search(struct sdca_control_range *range, 1123 + int search_col, int value, int result_col) 1124 + { 1125 + int i; 1126 + 1127 + for (i = 0; i < range->rows; i++) { 1128 + if (sdca_range(range, search_col, i) == value) 1129 + return sdca_range(range, result_col, i); 1130 + } 1131 + 1132 + return 0; 1133 + } 1186 1134 1187 1135 int sdca_parse_function(struct device *dev, 1188 1136 struct sdca_function_desc *desc,
+334 -44
sound/soc/sdca/sdca_functions.c
··· 10 10 11 11 #include <linux/acpi.h> 12 12 #include <linux/byteorder/generic.h> 13 + #include <linux/cleanup.h> 13 14 #include <linux/device.h> 14 15 #include <linux/dev_printk.h> 15 16 #include <linux/module.h> ··· 187 186 } 188 187 EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA"); 189 188 189 + struct raw_init_write { 190 + __le32 addr; 191 + u8 val; 192 + } __packed; 193 + 190 194 static int find_sdca_init_table(struct device *dev, 191 195 struct fwnode_handle *function_node, 192 196 struct sdca_function_data *function) 193 197 { 198 + struct raw_init_write *raw __free(kfree) = NULL; 194 199 struct sdca_init_write *init_write; 195 - int write_size = sizeof(init_write->addr) + sizeof(init_write->val); 196 - u8 *init_list, *init_iter; 197 - int num_init_writes; 200 + int i, num_init_writes; 198 201 199 202 num_init_writes = fwnode_property_count_u8(function_node, 200 203 "mipi-sdca-function-initialization-table"); ··· 208 203 dev_err(dev, "%pfwP: failed to read initialization table: %d\n", 209 204 function_node, num_init_writes); 210 205 return num_init_writes; 211 - } else if (num_init_writes % write_size != 0) { 206 + } else if (num_init_writes % sizeof(*raw) != 0) { 212 207 dev_err(dev, "%pfwP: init table size invalid\n", function_node); 213 208 return -EINVAL; 214 209 } else if (num_init_writes > SDCA_MAX_INIT_COUNT) { ··· 216 211 return -EINVAL; 217 212 } 218 213 219 - init_write = devm_kcalloc(dev, num_init_writes / write_size, 220 - sizeof(*init_write), GFP_KERNEL); 221 - if (!init_write) 222 - return -ENOMEM; 223 - 224 - init_list = kcalloc(num_init_writes, sizeof(*init_list), GFP_KERNEL); 225 - if (!init_list) 214 + raw = kzalloc(num_init_writes, GFP_KERNEL); 215 + if (!raw) 226 216 return -ENOMEM; 227 217 228 218 fwnode_property_read_u8_array(function_node, 229 219 "mipi-sdca-function-initialization-table", 230 - init_list, num_init_writes); 220 + (u8 *)raw, num_init_writes); 221 + 222 + num_init_writes /= sizeof(*raw); 223 + 224 + init_write = devm_kcalloc(dev, num_init_writes, sizeof(*init_write), GFP_KERNEL); 225 + if (!init_write) 226 + return -ENOMEM; 227 + 228 + for (i = 0; i < num_init_writes; i++) { 229 + init_write[i].addr = le32_to_cpu(raw[i].addr); 230 + init_write[i].val = raw[i].val; 231 + } 231 232 232 233 function->num_init_table = num_init_writes; 233 234 function->init_table = init_write; 234 235 235 - for (init_iter = init_list; init_iter < init_list + num_init_writes;) { 236 - u32 *addr = (u32 *)init_iter; 237 - 238 - init_write->addr = le32_to_cpu(*addr); 239 - init_iter += sizeof(init_write->addr); 240 - 241 - init_write->val = *init_iter; 242 - init_iter += sizeof(init_write->val); 243 - } 244 - 245 - kfree(init_list); 246 - 247 236 return 0; 248 237 } 249 238 250 - static const char *find_sdca_control_label(const struct sdca_entity *entity, 239 + static const char *find_sdca_control_label(struct device *dev, 240 + const struct sdca_entity *entity, 251 241 const struct sdca_control *control) 252 242 { 253 243 switch (SDCA_CTL_TYPE(entity->type, control->sel)) { ··· 531 531 case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION): 532 532 return SDCA_CTL_DEVICE_SDCA_VERSION_NAME; 533 533 default: 534 - return NULL; 534 + return devm_kasprintf(dev, GFP_KERNEL, "Imp-Def %#x", control->sel); 535 535 } 536 536 } 537 537 ··· 600 600 return 1; 601 601 default: 602 602 return 8; 603 + } 604 + } 605 + 606 + static enum sdca_control_datatype 607 + find_sdca_control_datatype(const struct sdca_entity *entity, 608 + const struct sdca_control *control) 609 + { 610 + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { 611 + case SDCA_CTL_TYPE_S(XU, BYPASS): 612 + case SDCA_CTL_TYPE_S(MFPU, BYPASS): 613 + case SDCA_CTL_TYPE_S(FU, MUTE): 614 + case SDCA_CTL_TYPE_S(FU, AGC): 615 + case SDCA_CTL_TYPE_S(FU, BASS_BOOST): 616 + case SDCA_CTL_TYPE_S(FU, LOUDNESS): 617 + return SDCA_CTL_DATATYPE_ONEBIT; 618 + case SDCA_CTL_TYPE_S(IT, LATENCY): 619 + case SDCA_CTL_TYPE_S(OT, LATENCY): 620 + case SDCA_CTL_TYPE_S(MU, LATENCY): 621 + case SDCA_CTL_TYPE_S(SU, LATENCY): 622 + case SDCA_CTL_TYPE_S(FU, LATENCY): 623 + case SDCA_CTL_TYPE_S(XU, LATENCY): 624 + case SDCA_CTL_TYPE_S(CRU, LATENCY): 625 + case SDCA_CTL_TYPE_S(UDMPU, LATENCY): 626 + case SDCA_CTL_TYPE_S(MFPU, LATENCY): 627 + case SDCA_CTL_TYPE_S(SMPU, LATENCY): 628 + case SDCA_CTL_TYPE_S(SAPU, LATENCY): 629 + case SDCA_CTL_TYPE_S(PPU, LATENCY): 630 + case SDCA_CTL_TYPE_S(SU, SELECTOR): 631 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_0): 632 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_1): 633 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_2): 634 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_3): 635 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_4): 636 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_5): 637 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_6): 638 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_7): 639 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_8): 640 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_9): 641 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_10): 642 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_11): 643 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_12): 644 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_13): 645 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_14): 646 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_15): 647 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_16): 648 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_17): 649 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_18): 650 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_19): 651 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_20): 652 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_21): 653 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_22): 654 + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_23): 655 + case SDCA_CTL_TYPE_S(SAPU, PROTECTION_MODE): 656 + case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_PREAMBLE): 657 + case SDCA_CTL_TYPE_S(XU, FDL_HOST_REQUEST): 658 + case SDCA_CTL_TYPE_S(XU, XU_ID): 659 + case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT): 660 + case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER): 661 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_MANUFACTURER_ID): 662 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ID): 663 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_ID): 664 + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_MANUFACTURER_ID): 665 + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_PART_ID): 666 + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGEOFFSET): 667 + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGELENGTH): 668 + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGEOFFSET): 669 + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGELENGTH): 670 + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGEOFFSET): 671 + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGELENGTH): 672 + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGEOFFSET): 673 + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGELENGTH): 674 + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGEOFFSET): 675 + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGELENGTH): 676 + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGEOFFSET): 677 + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGELENGTH): 678 + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGEOFFSET): 679 + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGELENGTH): 680 + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGEOFFSET): 681 + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGELENGTH): 682 + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGEOFFSET): 683 + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGELENGTH): 684 + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGEOFFSET): 685 + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGELENGTH): 686 + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGEOFFSET): 687 + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGELENGTH): 688 + return SDCA_CTL_DATATYPE_INTEGER; 689 + case SDCA_CTL_TYPE_S(IT, MIC_BIAS): 690 + case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_MODE): 691 + case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS): 692 + case SDCA_CTL_TYPE_S(PDE, ACTUAL_PS): 693 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_TYPE): 694 + return SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE; 695 + case SDCA_CTL_TYPE_S(XU, XU_VERSION): 696 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_SDCA_VERSION): 697 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_VERSION): 698 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_VERSION): 699 + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_VERSION): 700 + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION): 701 + return SDCA_CTL_DATATYPE_BCD; 702 + case SDCA_CTL_TYPE_S(FU, CHANNEL_VOLUME): 703 + case SDCA_CTL_TYPE_S(FU, GAIN): 704 + case SDCA_CTL_TYPE_S(MU, MIXER): 705 + case SDCA_CTL_TYPE_S(PPU, HORIZONTALBALANCE): 706 + case SDCA_CTL_TYPE_S(PPU, VERTICALBALANCE): 707 + case SDCA_CTL_TYPE_S(MFPU, ULTRASOUND_LEVEL): 708 + case SDCA_CTL_TYPE_S(UDMPU, ACOUSTIC_ENERGY_LEVEL_MONITOR): 709 + case SDCA_CTL_TYPE_S(UDMPU, ULTRASOUND_LOOP_GAIN): 710 + return SDCA_CTL_DATATYPE_Q7P8DB; 711 + case SDCA_CTL_TYPE_S(IT, USAGE): 712 + case SDCA_CTL_TYPE_S(OT, USAGE): 713 + case SDCA_CTL_TYPE_S(IT, CLUSTERINDEX): 714 + case SDCA_CTL_TYPE_S(CRU, CLUSTERINDEX): 715 + case SDCA_CTL_TYPE_S(UDMPU, CLUSTERINDEX): 716 + case SDCA_CTL_TYPE_S(MFPU, CLUSTERINDEX): 717 + case SDCA_CTL_TYPE_S(MFPU, CENTER_FREQUENCY_INDEX): 718 + case SDCA_CTL_TYPE_S(MFPU, AE_NUMBER): 719 + case SDCA_CTL_TYPE_S(SAPU, OPAQUESETREQ_INDEX): 720 + case SDCA_CTL_TYPE_S(XU, FDL_SET_INDEX): 721 + case SDCA_CTL_TYPE_S(CS, SAMPLERATEINDEX): 722 + case SDCA_CTL_TYPE_S(GE, SELECTED_MODE): 723 + case SDCA_CTL_TYPE_S(GE, DETECTED_MODE): 724 + return SDCA_CTL_DATATYPE_BYTEINDEX; 725 + case SDCA_CTL_TYPE_S(PPU, POSTURENUMBER): 726 + return SDCA_CTL_DATATYPE_POSTURENUMBER; 727 + case SDCA_CTL_TYPE_S(IT, DATAPORT_SELECTOR): 728 + case SDCA_CTL_TYPE_S(OT, DATAPORT_SELECTOR): 729 + return SDCA_CTL_DATATYPE_DP_INDEX; 730 + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_READY): 731 + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_ENABLE): 732 + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_PREPARE): 733 + case SDCA_CTL_TYPE_S(SAPU, PROTECTION_STATUS): 734 + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE): 735 + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_STATUS): 736 + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_READY): 737 + case SDCA_CTL_TYPE_S(SPE, PRIVACY_POLICY): 738 + case SDCA_CTL_TYPE_S(SPE, PRIVACY_OWNER): 739 + return SDCA_CTL_DATATYPE_BITINDEX; 740 + case SDCA_CTL_TYPE_S(IT, KEEP_ALIVE): 741 + case SDCA_CTL_TYPE_S(OT, KEEP_ALIVE): 742 + case SDCA_CTL_TYPE_S(IT, NDAI_STREAM): 743 + case SDCA_CTL_TYPE_S(OT, NDAI_STREAM): 744 + case SDCA_CTL_TYPE_S(IT, NDAI_CATEGORY): 745 + case SDCA_CTL_TYPE_S(OT, NDAI_CATEGORY): 746 + case SDCA_CTL_TYPE_S(IT, NDAI_CODINGTYPE): 747 + case SDCA_CTL_TYPE_S(OT, NDAI_CODINGTYPE): 748 + case SDCA_CTL_TYPE_S(IT, NDAI_PACKETTYPE): 749 + case SDCA_CTL_TYPE_S(OT, NDAI_PACKETTYPE): 750 + case SDCA_CTL_TYPE_S(SMPU, HIST_ERROR): 751 + case SDCA_CTL_TYPE_S(XU, FDL_STATUS): 752 + case SDCA_CTL_TYPE_S(CS, CLOCK_VALID): 753 + case SDCA_CTL_TYPE_S(SPE, PRIVACY_LOCKSTATE): 754 + case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK): 755 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS): 756 + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ACTION): 757 + case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): 758 + case SDCA_CTL_TYPE_S(SPE, AUTHTX_CURRENTOWNER): 759 + case SDCA_CTL_TYPE_S(SPE, AUTHRX_CURRENTOWNER): 760 + case SDCA_CTL_TYPE_S(MFPU, AE_CURRENTOWNER): 761 + case SDCA_CTL_TYPE_S(SMPU, HIST_CURRENTOWNER): 762 + case SDCA_CTL_TYPE_S(SMPU, DTODTX_CURRENTOWNER): 763 + case SDCA_CTL_TYPE_S(SMPU, DTODRX_CURRENTOWNER): 764 + case SDCA_CTL_TYPE_S(SAPU, DTODTX_CURRENTOWNER): 765 + case SDCA_CTL_TYPE_S(SAPU, DTODRX_CURRENTOWNER): 766 + case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER): 767 + case SDCA_CTL_TYPE_S(HIDE, HIDRX_CURRENTOWNER): 768 + return SDCA_CTL_DATATYPE_BITMAP; 769 + case SDCA_CTL_TYPE_S(IT, MATCHING_GUID): 770 + case SDCA_CTL_TYPE_S(OT, MATCHING_GUID): 771 + case SDCA_CTL_TYPE_S(ENTITY_0, MATCHING_GUID): 772 + return SDCA_CTL_DATATYPE_GUID; 773 + default: 774 + return SDCA_CTL_DATATYPE_IMPDEF; 603 775 } 604 776 } 605 777 ··· 912 740 if (!ret) 913 741 control->interrupt_position = tmp; 914 742 915 - control->label = find_sdca_control_label(entity, control); 916 - if (!control->label) { 917 - dev_err(dev, "%s: control %#x: name not found\n", 918 - entity->label, control->sel); 919 - return -EINVAL; 920 - } 743 + control->label = find_sdca_control_label(dev, entity, control); 744 + if (!control->label) 745 + return -ENOMEM; 921 746 747 + control->type = find_sdca_control_datatype(entity, control); 922 748 control->nbits = find_sdca_control_bits(entity, control); 923 749 924 750 dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n", ··· 1084 914 { 1085 915 static const int mult_delay = 3; 1086 916 struct sdca_entity_pde *power = &entity->pde; 917 + u32 *delay_list __free(kfree) = NULL; 1087 918 struct sdca_pde_delay *delays; 1088 919 int num_delays; 1089 - u32 *delay_list; 1090 920 int i, j; 1091 921 1092 922 num_delays = fwnode_property_count_u32(entity_node, ··· 1133 963 power->num_max_delay = num_delays; 1134 964 power->max_delay = delays; 1135 965 1136 - kfree(delay_list); 966 + return 0; 967 + } 968 + 969 + struct raw_ge_mode { 970 + u8 val; 971 + u8 num_controls; 972 + struct { 973 + u8 id; 974 + u8 sel; 975 + u8 cn; 976 + __le32 val; 977 + } __packed controls[] __counted_by(num_controls); 978 + } __packed; 979 + 980 + static int find_sdca_entity_ge(struct device *dev, 981 + struct fwnode_handle *entity_node, 982 + struct sdca_entity *entity) 983 + { 984 + struct sdca_entity_ge *group = &entity->ge; 985 + u8 *affected_list __free(kfree) = NULL; 986 + u8 *affected_iter; 987 + int num_affected; 988 + int i, j; 989 + 990 + num_affected = fwnode_property_count_u8(entity_node, 991 + "mipi-sdca-ge-selectedmode-controls-affected"); 992 + if (!num_affected || num_affected == -EINVAL) { 993 + return 0; 994 + } else if (num_affected < 0) { 995 + dev_err(dev, "%s: failed to read affected controls: %d\n", 996 + entity->label, num_affected); 997 + return num_affected; 998 + } else if (num_affected > SDCA_MAX_AFFECTED_COUNT) { 999 + dev_err(dev, "%s: maximum affected controls size exceeded\n", 1000 + entity->label); 1001 + return -EINVAL; 1002 + } 1003 + 1004 + affected_list = kcalloc(num_affected, sizeof(*affected_list), GFP_KERNEL); 1005 + if (!affected_list) 1006 + return -ENOMEM; 1007 + 1008 + fwnode_property_read_u8_array(entity_node, 1009 + "mipi-sdca-ge-selectedmode-controls-affected", 1010 + affected_list, num_affected); 1011 + 1012 + group->num_modes = *affected_list; 1013 + affected_iter = affected_list + 1; 1014 + 1015 + group->modes = devm_kcalloc(dev, group->num_modes, sizeof(*group->modes), 1016 + GFP_KERNEL); 1017 + if (!group->modes) 1018 + return -ENOMEM; 1019 + 1020 + for (i = 0; i < group->num_modes; i++) { 1021 + struct raw_ge_mode *raw = (struct raw_ge_mode *)affected_iter; 1022 + struct sdca_ge_mode *mode = &group->modes[i]; 1023 + 1024 + affected_iter += sizeof(*raw); 1025 + if (affected_iter > affected_list + num_affected) 1026 + goto bad_list; 1027 + 1028 + mode->val = raw->val; 1029 + mode->num_controls = raw->num_controls; 1030 + 1031 + affected_iter += mode->num_controls * sizeof(raw->controls[0]); 1032 + if (affected_iter > affected_list + num_affected) 1033 + goto bad_list; 1034 + 1035 + mode->controls = devm_kcalloc(dev, mode->num_controls, 1036 + sizeof(*mode->controls), GFP_KERNEL); 1037 + if (!mode->controls) 1038 + return -ENOMEM; 1039 + 1040 + for (j = 0; j < mode->num_controls; j++) { 1041 + mode->controls[j].id = raw->controls[j].id; 1042 + mode->controls[j].sel = raw->controls[j].sel; 1043 + mode->controls[j].cn = raw->controls[j].cn; 1044 + mode->controls[j].val = le32_to_cpu(raw->controls[j].val); 1045 + } 1046 + } 1137 1047 1138 1048 return 0; 1049 + 1050 + bad_list: 1051 + dev_err(dev, "%s: malformed affected controls list\n", entity->label); 1052 + return -EINVAL; 1139 1053 } 1140 1054 1141 1055 static int find_sdca_entity(struct device *dev, ··· 1260 1006 case SDCA_ENTITY_TYPE_PDE: 1261 1007 ret = find_sdca_entity_pde(dev, entity_node, entity); 1262 1008 break; 1009 + case SDCA_ENTITY_TYPE_GE: 1010 + ret = find_sdca_entity_ge(dev, entity_node, entity); 1011 + break; 1263 1012 default: 1264 1013 break; 1265 1014 } ··· 1280 1023 struct fwnode_handle *function_node, 1281 1024 struct sdca_function_data *function) 1282 1025 { 1026 + u32 *entity_list __free(kfree) = NULL; 1283 1027 struct sdca_entity *entities; 1284 - u32 *entity_list; 1285 1028 int num_entities; 1286 1029 int i, ret; 1287 1030 ··· 1311 1054 1312 1055 for (i = 0; i < num_entities; i++) 1313 1056 entities[i].id = entity_list[i]; 1314 - 1315 - kfree(entity_list); 1316 1057 1317 1058 /* now read subproperties */ 1318 1059 for (i = 0; i < num_entities; i++) { ··· 1426 1171 struct sdca_entity *entity) 1427 1172 { 1428 1173 struct sdca_entity_pde *power = &entity->pde; 1174 + u32 *managed_list __free(kfree) = NULL; 1429 1175 struct sdca_entity **managed; 1430 - u32 *managed_list; 1431 1176 int num_managed; 1432 1177 int i; 1433 1178 ··· 1461 1206 if (!managed[i]) { 1462 1207 dev_err(dev, "%s: failed to find entity with id %#x\n", 1463 1208 entity->label, managed_list[i]); 1464 - kfree(managed_list); 1465 1209 return -EINVAL; 1466 1210 } 1467 1211 1468 1212 dev_info(dev, "%s -> %s\n", managed[i]->label, entity->label); 1469 1213 } 1470 1214 1471 - kfree(managed_list); 1472 - 1473 1215 power->num_managed = num_managed; 1474 1216 power->managed = managed; 1217 + 1218 + return 0; 1219 + } 1220 + 1221 + static int find_sdca_entity_connection_ge(struct device *dev, 1222 + struct sdca_function_data *function, 1223 + struct fwnode_handle *entity_node, 1224 + struct sdca_entity *entity) 1225 + { 1226 + int i, j; 1227 + 1228 + for (i = 0; i < entity->ge.num_modes; i++) { 1229 + struct sdca_ge_mode *mode = &entity->ge.modes[i]; 1230 + 1231 + for (j = 0; j < mode->num_controls; j++) { 1232 + struct sdca_ge_control *affected = &mode->controls[j]; 1233 + struct sdca_entity *managed; 1234 + 1235 + managed = find_sdca_entity_by_id(function, affected->id); 1236 + if (!managed) { 1237 + dev_err(dev, "%s: failed to find entity with id %#x\n", 1238 + entity->label, affected->id); 1239 + return -EINVAL; 1240 + } 1241 + 1242 + if (managed->group && managed->group != entity) { 1243 + dev_err(dev, 1244 + "%s: entity controlled by two groups %s, %s\n", 1245 + managed->label, managed->group->label, 1246 + entity->label); 1247 + return -EINVAL; 1248 + } 1249 + 1250 + managed->group = entity; 1251 + } 1252 + } 1475 1253 1476 1254 return 0; 1477 1255 } ··· 1528 1240 case SDCA_ENTITY_TYPE_PDE: 1529 1241 ret = find_sdca_entity_connection_pde(dev, function, 1530 1242 entity_node, entity); 1243 + break; 1244 + case SDCA_ENTITY_TYPE_GE: 1245 + ret = find_sdca_entity_connection_ge(dev, function, 1246 + entity_node, entity); 1531 1247 break; 1532 1248 default: 1533 1249 ret = 0; ··· 1746 1454 struct fwnode_handle *function_node, 1747 1455 struct sdca_function_data *function) 1748 1456 { 1457 + u32 *cluster_list __free(kfree) = NULL; 1749 1458 struct sdca_cluster *clusters; 1750 1459 int num_clusters; 1751 - u32 *cluster_list; 1752 1460 int i, ret; 1753 1461 1754 1462 num_clusters = fwnode_property_count_u32(function_node, "mipi-sdca-cluster-id-list"); ··· 1776 1484 1777 1485 for (i = 0; i < num_clusters; i++) 1778 1486 clusters[i].id = cluster_list[i]; 1779 - 1780 - kfree(cluster_list); 1781 1487 1782 1488 /* now read subproperties */ 1783 1489 for (i = 0; i < num_clusters; i++) {