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.

SDCA Improvements

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

Another fairly mixed bag of small SDCA fixes/improvements. Fix one DisCo
property that was treated as mandatory but is actually not present in
the first version of the specification. Fix the counting of routes for
SU/GE DAPM widgets, this currently makes assumptions that are not
guaranteed to be true which can result in too many/few DAPM routes.

Then finally a couple improvements to the volume controls, simplify the
mapping between ALSA and SDCA volumes and pull the volume stuff back
into the SDCA code. It just wasn't sitting right with me that it was
being handled in the ASoC core given it is unlikely to ever see any
reuse outside of SDCA.

+118 -72
-1
include/sound/soc.h
··· 1239 1239 unsigned int sign_bit; 1240 1240 unsigned int invert:1; 1241 1241 unsigned int autodisable:1; 1242 - unsigned int sdca_q78:1; 1243 1242 #ifdef CONFIG_SND_SOC_TOPOLOGY 1244 1243 struct snd_soc_dobj dobj; 1245 1244 #endif
+102 -12
sound/soc/sdca/sdca_asoc.c
··· 51 51 return control->has_fixed || control->mode == SDCA_ACCESS_MODE_RO; 52 52 } 53 53 54 + static int ge_count_routes(struct sdca_entity *entity) 55 + { 56 + int count = 0; 57 + int i, j; 58 + 59 + for (i = 0; i < entity->ge.num_modes; i++) { 60 + struct sdca_ge_mode *mode = &entity->ge.modes[i]; 61 + 62 + for (j = 0; j < mode->num_controls; j++) { 63 + struct sdca_ge_control *affected = &mode->controls[j]; 64 + 65 + if (affected->sel != SDCA_CTL_SU_SELECTOR || affected->val) 66 + count++; 67 + } 68 + } 69 + 70 + return count; 71 + } 72 + 54 73 /** 55 74 * sdca_asoc_count_component - count the various component parts 56 75 * @dev: Pointer to the device against which allocations will be done. ··· 93 74 int *num_widgets, int *num_routes, int *num_controls, 94 75 int *num_dais) 95 76 { 77 + struct sdca_control *control; 96 78 int i, j; 97 79 98 80 *num_widgets = function->num_entities - 1; ··· 103 83 104 84 for (i = 0; i < function->num_entities - 1; i++) { 105 85 struct sdca_entity *entity = &function->entities[i]; 86 + bool skip_primary_routes = false; 106 87 107 88 /* Add supply/DAI widget connections */ 108 89 switch (entity->type) { ··· 117 96 case SDCA_ENTITY_TYPE_PDE: 118 97 *num_routes += entity->pde.num_managed; 119 98 break; 99 + case SDCA_ENTITY_TYPE_GE: 100 + *num_routes += ge_count_routes(entity); 101 + skip_primary_routes = true; 102 + break; 103 + case SDCA_ENTITY_TYPE_SU: 104 + control = sdca_selector_find_control(dev, entity, SDCA_CTL_SU_SELECTOR); 105 + if (!control) 106 + return -EINVAL; 107 + 108 + skip_primary_routes = (control->layers == SDCA_ACCESS_LAYER_DEVICE); 109 + break; 120 110 default: 121 111 break; 122 112 } ··· 136 104 (*num_routes)++; 137 105 138 106 /* Add primary entity connections from DisCo */ 139 - *num_routes += entity->num_sources; 107 + if (!skip_primary_routes) 108 + *num_routes += entity->num_sources; 140 109 141 110 for (j = 0; j < entity->num_controls; j++) { 142 111 if (exported_control(entity, &entity->controls[j])) ··· 475 442 struct snd_soc_dapm_route **route) 476 443 { 477 444 struct sdca_control_range *range; 478 - int num_routes = 0; 479 445 int i, j; 480 446 481 447 if (!entity->group) { ··· 507 475 if (affected->val - 1 >= entity->num_sources) { 508 476 dev_err(dev, "%s: bad control value: %#x\n", 509 477 entity->label, affected->val); 510 - return -EINVAL; 511 - } 512 - 513 - if (++num_routes > entity->num_sources) { 514 - dev_err(dev, "%s: too many input routes\n", entity->label); 515 478 return -EINVAL; 516 479 } 517 480 ··· 805 778 } 806 779 EXPORT_SYMBOL_NS(sdca_asoc_populate_dapm, "SND_SOC_SDCA"); 807 780 781 + static int q78_write(struct snd_soc_component *component, 782 + struct soc_mixer_control *mc, 783 + unsigned int reg, const int val) 784 + { 785 + unsigned int mask = GENMASK(mc->sign_bit, 0); 786 + unsigned int reg_val; 787 + 788 + if (val < 0 || val > mc->max - mc->min) 789 + return -EINVAL; 790 + 791 + reg_val = (val + mc->min) * mc->shift; 792 + 793 + return snd_soc_component_update_bits(component, reg, mask, reg_val); 794 + } 795 + 796 + static int q78_put_volsw(struct snd_kcontrol *kcontrol, 797 + struct snd_ctl_elem_value *ucontrol) 798 + { 799 + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; 800 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 801 + int ret; 802 + 803 + ret = q78_write(component, mc, mc->reg, ucontrol->value.integer.value[0]); 804 + if (ret < 0) 805 + return ret; 806 + 807 + if (snd_soc_volsw_is_stereo(mc)) { 808 + int err; /* Don't drop change flag */ 809 + 810 + err = q78_write(component, mc, mc->rreg, ucontrol->value.integer.value[1]); 811 + if (err) 812 + return err; 813 + } 814 + 815 + return ret; 816 + } 817 + 818 + static int q78_read(struct snd_soc_component *component, 819 + struct soc_mixer_control *mc, unsigned int reg) 820 + { 821 + unsigned int reg_val; 822 + int val; 823 + 824 + reg_val = snd_soc_component_read(component, reg); 825 + 826 + val = (sign_extend32(reg_val, mc->sign_bit) / mc->shift) - mc->min; 827 + 828 + return val & GENMASK(mc->sign_bit, 0); 829 + } 830 + 831 + static int q78_get_volsw(struct snd_kcontrol *kcontrol, 832 + struct snd_ctl_elem_value *ucontrol) 833 + { 834 + struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; 835 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 836 + 837 + ucontrol->value.integer.value[0] = q78_read(component, mc, mc->reg); 838 + 839 + if (snd_soc_volsw_is_stereo(mc)) 840 + ucontrol->value.integer.value[1] = q78_read(component, mc, mc->rreg); 841 + 842 + return 0; 843 + } 844 + 808 845 static int control_limit_kctl(struct device *dev, 809 846 struct sdca_entity *entity, 810 847 struct sdca_control *control, ··· 905 814 tlv[2] = (min * 100) >> 8; 906 815 tlv[3] = (max * 100) >> 8; 907 816 908 - step = (step * 100) >> 8; 909 - 910 - mc->min = ((int)tlv[2] / step); 911 - mc->max = ((int)tlv[3] / step); 817 + mc->min = min / step; 818 + mc->max = max / step; 912 819 mc->shift = step; 913 820 mc->sign_bit = 15; 914 - mc->sdca_q78 = 1; 915 821 916 822 kctl->tlv.p = tlv; 917 823 kctl->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 824 + kctl->get = q78_get_volsw; 825 + kctl->put = q78_put_volsw; 918 826 919 827 return 0; 920 828 }
-5
sound/soc/sdca/sdca_fdl.c
··· 46 46 if (ret) // Allowed for function reset to not be implemented 47 47 return 0; 48 48 49 - if (!function->reset_max_delay) { 50 - dev_err(dev, "No reset delay specified in DisCo\n"); 51 - return -EINVAL; 52 - } 53 - 54 49 /* 55 50 * Poll up to 16 times but no more than once per ms, these are just 56 51 * arbitrarily selected values, so may be fine tuned in future.
+5 -1
sound/soc/sdca/sdca_functions.c
··· 2167 2167 2168 2168 ret = fwnode_property_read_u32(function_desc->node, 2169 2169 "mipi-sdca-function-reset-max-delay", &tmp); 2170 - if (!ret) 2170 + if (ret || tmp == 0) { 2171 + dev_dbg(dev, "reset delay missing, defaulting to 100mS\n"); 2172 + function->reset_max_delay = 100000; 2173 + } else { 2171 2174 function->reset_max_delay = tmp; 2175 + } 2172 2176 2173 2177 dev_dbg(dev, "%pfwP: name %s busy delay %dus reset delay %dus\n", 2174 2178 function->desc->node, function->desc->name,
+11 -53
sound/soc/soc-ops.c
··· 110 110 } 111 111 EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 112 112 113 - static int sdca_soc_q78_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_val, 114 - unsigned int mask, unsigned int shift, int max, 115 - bool sx) 116 - { 117 - int val = reg_val; 118 - 119 - if (WARN_ON(!mc->shift)) 120 - return -EINVAL; 121 - 122 - val = sign_extend32(val, mc->sign_bit); 123 - val = (((val * 100) >> 8) / (int)mc->shift); 124 - val -= mc->min; 125 - 126 - return val & mask; 127 - } 128 - 129 - static unsigned int sdca_soc_q78_ctl_to_reg(struct soc_mixer_control *mc, int val, 130 - unsigned int mask, unsigned int shift, int max) 131 - { 132 - unsigned int ret_val; 133 - int reg_val; 134 - 135 - if (WARN_ON(!mc->shift)) 136 - return -EINVAL; 137 - 138 - reg_val = val + mc->min; 139 - ret_val = (int)((reg_val * mc->shift) << 8) / 100; 140 - 141 - return ret_val & mask; 142 - } 143 - 144 113 static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_val, 145 114 unsigned int mask, unsigned int shift, int max, 146 115 bool sx) ··· 203 234 struct snd_ctl_elem_value *ucontrol, 204 235 struct soc_mixer_control *mc, int mask, int max) 205 236 { 206 - unsigned int (*ctl_to_reg)(struct soc_mixer_control *, int, unsigned int, unsigned int, int); 207 237 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 208 238 unsigned int val1, val_mask; 209 239 unsigned int val2 = 0; 210 240 bool double_r = false; 211 241 int ret; 212 242 213 - if (mc->sdca_q78) { 214 - ctl_to_reg = sdca_soc_q78_ctl_to_reg; 215 - val_mask = mask; 216 - } else { 217 - ctl_to_reg = soc_mixer_ctl_to_reg; 218 - val_mask = mask << mc->shift; 219 - } 220 - 221 243 ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max); 222 244 if (ret) 223 245 return ret; 224 246 225 - val1 = ctl_to_reg(mc, ucontrol->value.integer.value[0], 247 + val1 = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], 226 248 mask, mc->shift, max); 249 + val_mask = mask << mc->shift; 227 250 228 251 if (snd_soc_volsw_is_stereo(mc)) { 229 252 ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max); ··· 223 262 return ret; 224 263 225 264 if (mc->reg == mc->rreg) { 226 - val1 |= ctl_to_reg(mc, ucontrol->value.integer.value[1], mask, mc->rshift, max); 265 + val1 |= soc_mixer_ctl_to_reg(mc, 266 + ucontrol->value.integer.value[1], 267 + mask, mc->rshift, max); 227 268 val_mask |= mask << mc->rshift; 228 269 } else { 229 - val2 = ctl_to_reg(mc, ucontrol->value.integer.value[1], mask, mc->shift, max); 270 + val2 = soc_mixer_ctl_to_reg(mc, 271 + ucontrol->value.integer.value[1], 272 + mask, mc->shift, max); 230 273 double_r = true; 231 274 } 232 275 } ··· 254 289 struct snd_ctl_elem_value *ucontrol, 255 290 struct soc_mixer_control *mc, int mask, int max, bool sx) 256 291 { 257 - int (*reg_to_ctl)(struct soc_mixer_control *, unsigned int, unsigned int, 258 - unsigned int, int, bool); 259 292 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 260 293 unsigned int reg_val; 261 294 int val; 262 295 263 - if (mc->sdca_q78) 264 - reg_to_ctl = sdca_soc_q78_reg_to_ctl; 265 - else 266 - reg_to_ctl = soc_mixer_reg_to_ctl; 267 - 268 296 reg_val = snd_soc_component_read(component, mc->reg); 269 - val = reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx); 297 + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx); 270 298 271 299 ucontrol->value.integer.value[0] = val; 272 300 273 301 if (snd_soc_volsw_is_stereo(mc)) { 274 302 if (mc->reg == mc->rreg) { 275 - val = reg_to_ctl(mc, reg_val, mask, mc->rshift, max, sx); 303 + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, max, sx); 276 304 } else { 277 305 reg_val = snd_soc_component_read(component, mc->rreg); 278 - val = reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx); 306 + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx); 279 307 } 280 308 281 309 ucontrol->value.integer.value[1] = val;