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

Configure Feed

Select the types of activity you want to include in your feed.

Minor SDCA Fixes

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

A bit of a mixed bag of minor misc fixes, improve handling
of volatile SDCA Controls, make some minor bug fixes to jack
detect, improve the cache syncing by adding some more defaults,
and improve some FDL error messages.

+170 -36
+4
include/sound/sdca_function.h
··· 798 798 * @sel: Identifier used for addressing. 799 799 * @nbits: Number of bits used in the Control. 800 800 * @values: Holds the Control value for constants and defaults. 801 + * @reset: Defined reset value for the Control. 801 802 * @cn_list: A bitmask showing the valid Control Numbers within this Control, 802 803 * Control Numbers typically represent channels. 803 804 * @interrupt_position: SCDA interrupt line that will alert to changes on this ··· 809 808 * @layers: Bitmask of access layers of the Control. 810 809 * @deferrable: Indicates if the access to the Control can be deferred. 811 810 * @has_default: Indicates the Control has a default value to be written. 811 + * @has_reset: Indicates the Control has a defined reset value. 812 812 * @has_fixed: Indicates the Control only supports a single value. 813 813 */ 814 814 struct sdca_control { ··· 818 816 819 817 int nbits; 820 818 int *values; 819 + int reset; 821 820 u64 cn_list; 822 821 int interrupt_position; 823 822 ··· 830 827 bool deferrable; 831 828 bool is_volatile; 832 829 bool has_default; 830 + bool has_reset; 833 831 bool has_fixed; 834 832 }; 835 833
+86 -3
sound/soc/sdca/sdca_asoc.c
··· 16 16 #include <linux/minmax.h> 17 17 #include <linux/module.h> 18 18 #include <linux/overflow.h> 19 + #include <linux/pm_runtime.h> 19 20 #include <linux/regmap.h> 20 21 #include <linux/soundwire/sdw_registers.h> 21 22 #include <linux/string_helpers.h> ··· 116 115 } 117 116 EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA"); 118 117 118 + static int ge_put_enum_double(struct snd_kcontrol *kcontrol, 119 + struct snd_ctl_elem_value *ucontrol) 120 + { 121 + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); 122 + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); 123 + struct device *dev = component->dev; 124 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 125 + unsigned int *item = ucontrol->value.enumerated.item; 126 + unsigned int reg = e->reg; 127 + int ret; 128 + 129 + reg &= ~SDW_SDCA_CTL_CSEL(0x3F); 130 + reg |= SDW_SDCA_CTL_CSEL(SDCA_CTL_GE_DETECTED_MODE); 131 + 132 + ret = pm_runtime_resume_and_get(dev); 133 + if (ret < 0) { 134 + dev_err(dev, "failed to resume writing %s: %d\n", 135 + kcontrol->id.name, ret); 136 + return ret; 137 + } 138 + 139 + ret = snd_soc_component_read(component, reg); 140 + pm_runtime_put(dev); 141 + if (ret < 0) 142 + return ret; 143 + else if (ret <= SDCA_DETECTED_MODE_DETECTION_IN_PROGRESS) 144 + return -EBUSY; 145 + 146 + ret = snd_soc_enum_item_to_val(e, item[0]); 147 + if (ret <= SDCA_DETECTED_MODE_DETECTION_IN_PROGRESS) 148 + return -EINVAL; 149 + 150 + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 151 + } 152 + 119 153 static int entity_early_parse_ge(struct device *dev, 120 154 struct sdca_function_data *function, 121 155 struct sdca_entity *entity) ··· 227 191 kctl->name = control_name; 228 192 kctl->info = snd_soc_info_enum_double; 229 193 kctl->get = snd_soc_dapm_get_enum_double; 230 - kctl->put = snd_soc_dapm_put_enum_double; 194 + kctl->put = ge_put_enum_double; 231 195 kctl->private_value = (unsigned long)soc_enum; 232 196 233 197 entity->ge.kctl = kctl; ··· 828 792 return 0; 829 793 } 830 794 795 + static int volatile_get_volsw(struct snd_kcontrol *kcontrol, 796 + struct snd_ctl_elem_value *ucontrol) 797 + { 798 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 799 + struct device *dev = component->dev; 800 + int ret; 801 + 802 + ret = pm_runtime_resume_and_get(dev); 803 + if (ret < 0) { 804 + dev_err(dev, "failed to resume reading %s: %d\n", 805 + kcontrol->id.name, ret); 806 + return ret; 807 + } 808 + 809 + ret = snd_soc_get_volsw(kcontrol, ucontrol); 810 + 811 + pm_runtime_put(dev); 812 + 813 + return ret; 814 + } 815 + 816 + static int volatile_put_volsw(struct snd_kcontrol *kcontrol, 817 + struct snd_ctl_elem_value *ucontrol) 818 + { 819 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 820 + struct device *dev = component->dev; 821 + int ret; 822 + 823 + ret = pm_runtime_resume_and_get(dev); 824 + if (ret < 0) { 825 + dev_err(dev, "failed to resume writing %s: %d\n", 826 + kcontrol->id.name, ret); 827 + return ret; 828 + } 829 + 830 + ret = snd_soc_put_volsw(kcontrol, ucontrol); 831 + 832 + pm_runtime_put(dev); 833 + 834 + return ret; 835 + } 836 + 831 837 static int populate_control(struct device *dev, 832 838 struct sdca_function_data *function, 833 839 struct sdca_entity *entity, ··· 927 849 (*kctl)->private_value = (unsigned long)mc; 928 850 (*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 929 851 (*kctl)->info = snd_soc_info_volsw; 930 - (*kctl)->get = snd_soc_get_volsw; 931 - (*kctl)->put = snd_soc_put_volsw; 852 + if (control->is_volatile) { 853 + (*kctl)->get = volatile_get_volsw; 854 + (*kctl)->put = volatile_put_volsw; 855 + } else { 856 + (*kctl)->get = snd_soc_get_volsw; 857 + (*kctl)->put = snd_soc_put_volsw; 858 + } 932 859 933 860 if (readonly_control(control)) 934 861 (*kctl)->access = SNDRV_CTL_ELEM_ACCESS_READ;
+4 -2
sound/soc/sdca/sdca_fdl.c
··· 256 256 tmp->file_length != firmware->size) { 257 257 dev_err(dev, "bad disk SWF size\n"); 258 258 } else if (!swf || swf->file_version <= tmp->file_version) { 259 - dev_dbg(dev, "using SWF from disk: %x-%x-%x\n", 260 - tmp->vendor_id, tmp->file_id, tmp->file_version); 259 + dev_dbg(dev, "using SWF from disk\n"); 261 260 swf = tmp; 262 261 } 263 262 } ··· 265 266 dev_err(dev, "failed to locate SWF\n"); 266 267 return -ENOENT; 267 268 } 269 + 270 + dev_info(dev, "loading SWF: %x-%x-%x\n", 271 + swf->vendor_id, swf->file_id, swf->file_version); 268 272 269 273 ret = sdca_ump_write_message(dev, interrupt->device_regmap, 270 274 interrupt->function_regmap,
+37 -4
sound/soc/sdca/sdca_functions.c
··· 911 911 return 0; 912 912 } 913 913 914 - /* 915 - * TODO: Add support for -cn- properties, allowing different channels to have 916 - * different defaults etc. 917 - */ 914 + static int find_sdca_control_reset(const struct sdca_entity *entity, 915 + struct sdca_control *control) 916 + { 917 + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { 918 + case SDCA_CTL_TYPE_S(FU, AGC): 919 + case SDCA_CTL_TYPE_S(FU, BASS_BOOST): 920 + case SDCA_CTL_TYPE_S(FU, LOUDNESS): 921 + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE): 922 + case SDCA_CTL_TYPE_S(GE, SELECTED_MODE): 923 + case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER): 924 + case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK): 925 + control->has_reset = true; 926 + control->reset = 0; 927 + break; 928 + case SDCA_CTL_TYPE_S(XU, BYPASS): 929 + case SDCA_CTL_TYPE_S(MFPU, BYPASS): 930 + case SDCA_CTL_TYPE_S(FU, MUTE): 931 + case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT): 932 + control->has_reset = true; 933 + control->reset = 1; 934 + break; 935 + case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS): 936 + control->has_reset = true; 937 + control->reset = 3; 938 + break; 939 + default: 940 + break; 941 + } 942 + 943 + return 0; 944 + } 945 + 918 946 static int find_sdca_entity_control(struct device *dev, struct sdca_entity *entity, 919 947 struct fwnode_handle *control_node, 920 948 struct sdca_control *control) ··· 1017 989 } 1018 990 1019 991 control->is_volatile = find_sdca_control_volatile(entity, control); 992 + 993 + ret = find_sdca_control_reset(entity, control); 994 + if (ret) 995 + return ret; 1020 996 1021 997 ret = find_sdca_control_range(dev, control_node, &control->range); 1022 998 if (ret) { ··· 2065 2033 num_sets = fwnode_property_count_u32(function_node, 2066 2034 "mipi-sdca-file-set-id-list"); 2067 2035 if (num_sets == 0 || num_sets == -EINVAL) { 2036 + dev_dbg(dev, "%pfwP: file set id list missing\n", function_node); 2068 2037 return 0; 2069 2038 } else if (num_sets < 0) { 2070 2039 dev_err(dev, "%pfwP: failed to read file set list: %d\n",
+28 -24
sound/soc/sdca/sdca_jack.c
··· 41 41 struct jack_state *state = interrupt->priv; 42 42 struct snd_kcontrol *kctl = state->kctl; 43 43 struct snd_ctl_elem_value *ucontrol __free(kfree) = NULL; 44 - struct soc_enum *soc_enum; 45 44 unsigned int reg, val; 46 45 int ret; 46 + 47 + guard(rwsem_write)(rwsem); 47 48 48 49 if (!kctl) { 49 50 const char *name __free(kfree) = kasprintf(GFP_KERNEL, "%s %s", ··· 55 54 return -ENOMEM; 56 55 57 56 kctl = snd_soc_component_get_kcontrol(component, name); 58 - if (!kctl) { 57 + if (!kctl) 59 58 dev_dbg(dev, "control not found: %s\n", name); 60 - return -ENOENT; 61 - } 62 - 63 - state->kctl = kctl; 59 + else 60 + state->kctl = kctl; 64 61 } 65 - 66 - soc_enum = (struct soc_enum *)kctl->private_value; 67 62 68 63 reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id, 69 64 interrupt->control->sel, 0); ··· 70 73 return ret; 71 74 } 72 75 76 + reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id, 77 + SDCA_CTL_GE_SELECTED_MODE, 0); 78 + 73 79 switch (val) { 74 80 case SDCA_DETECTED_MODE_DETECTION_IN_PROGRESS: 75 81 case SDCA_DETECTED_MODE_JACK_UNKNOWN: 76 - reg = SDW_SDCA_CTL(interrupt->function->desc->adr, 77 - interrupt->entity->id, 78 - SDCA_CTL_GE_SELECTED_MODE, 0); 79 - 80 82 /* 81 83 * Selected mode is not normally marked as volatile register 82 84 * (RW), but here force a read from the hardware. If the ··· 96 100 97 101 dev_dbg(dev, "%s: %#x\n", interrupt->name, val); 98 102 99 - ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL); 100 - if (!ucontrol) 101 - return -ENOMEM; 103 + if (kctl) { 104 + struct soc_enum *soc_enum = (struct soc_enum *)kctl->private_value; 102 105 103 - ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(soc_enum, val); 106 + ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL); 107 + if (!ucontrol) 108 + return -ENOMEM; 104 109 105 - down_write(rwsem); 106 - ret = kctl->put(kctl, ucontrol); 107 - up_write(rwsem); 108 - if (ret < 0) { 109 - dev_err(dev, "failed to update selected mode: %d\n", ret); 110 - return ret; 110 + ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(soc_enum, val); 111 + 112 + ret = snd_soc_dapm_put_enum_double(kctl, ucontrol); 113 + if (ret < 0) { 114 + dev_err(dev, "failed to update selected mode: %d\n", ret); 115 + return ret; 116 + } 117 + 118 + snd_ctl_notify(card->snd_card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); 119 + } else { 120 + ret = regmap_write(interrupt->function_regmap, reg, val); 121 + if (ret) { 122 + dev_err(dev, "failed to write selected mode: %d\n", ret); 123 + return ret; 124 + } 111 125 } 112 - 113 - snd_ctl_notify(card->snd_card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); 114 126 115 127 return sdca_jack_report(interrupt); 116 128 }
+11 -3
sound/soc/sdca/sdca_regmap.c
··· 218 218 struct sdca_entity *entity = &function->entities[i]; 219 219 220 220 for (j = 0; j < entity->num_controls; j++) { 221 - if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC) 221 + if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC || 222 + entity->controls[j].has_reset) 222 223 nconsts += hweight64(entity->controls[j].cn_list); 223 224 } 224 225 } ··· 256 255 struct sdca_control *control = &entity->controls[j]; 257 256 int cn; 258 257 259 - if (control->mode != SDCA_ACCESS_MODE_DC) 258 + if (control->mode != SDCA_ACCESS_MODE_DC && 259 + !control->has_reset) 260 260 continue; 261 261 262 262 l = 0; ··· 266 264 consts[k].reg = SDW_SDCA_CTL(function->desc->adr, 267 265 entity->id, 268 266 control->sel, cn); 269 - consts[k].def = control->values[l]; 267 + if (control->mode == SDCA_ACCESS_MODE_DC) 268 + consts[k].def = control->values[l]; 269 + else 270 + consts[k].def = control->reset; 270 271 k++; 271 272 l++; 272 273 } ··· 311 306 312 307 i++; 313 308 } else if (!control->is_volatile) { 309 + if (control->has_reset) 310 + regcache_drop_region(regmap, reg, reg); 311 + 314 312 ret = regmap_read(regmap, reg, &val); 315 313 if (ret) { 316 314 dev_err(dev, "Failed to read initial %#x: %d\n",