···31903190 };31913191 struct alc_spec *spec = codec->spec;3192319231933193+ /* Support Audio mute LED and Mic mute LED on keyboard */31943194+ hda_fixup_ideapad_acpi(codec, fix, action);31953195+31933196 switch (action) {31943197 case HDA_FIXUP_ACT_PRE_PROBE:31953198 snd_hda_apply_pincfgs(codec, pincfgs);
+84-30
sound/hda/codecs/side-codecs/cs35l56_hda.c
···872872 return 0;873873}874874875875+static int cs35l56_hda_fixup_yoga9(struct cs35l56_hda *cs35l56, int *bus_addr)876876+{877877+ /* The cirrus,dev-index property has the wrong values */878878+ switch (*bus_addr) {879879+ case 0x30:880880+ cs35l56->index = 1;881881+ return 0;882882+ case 0x31:883883+ cs35l56->index = 0;884884+ return 0;885885+ default:886886+ /* There is a pseudo-address for broadcast to both amps - ignore it */887887+ dev_dbg(cs35l56->base.dev, "Ignoring I2C address %#x\n", *bus_addr);888888+ return 0;889889+ }890890+}891891+892892+static const struct {893893+ const char *sub;894894+ int (*fixup_fn)(struct cs35l56_hda *cs35l56, int *bus_addr);895895+} cs35l56_hda_fixups[] = {896896+ {897897+ .sub = "17AA390B", /* Lenovo Yoga Book 9i GenX */898898+ .fixup_fn = cs35l56_hda_fixup_yoga9,899899+ },900900+};901901+902902+static int cs35l56_hda_apply_platform_fixups(struct cs35l56_hda *cs35l56, const char *sub,903903+ int *bus_addr)904904+{905905+ int i;906906+907907+ if (IS_ERR(sub))908908+ return 0;909909+910910+ for (i = 0; i < ARRAY_SIZE(cs35l56_hda_fixups); i++) {911911+ if (strcasecmp(cs35l56_hda_fixups[i].sub, sub) == 0) {912912+ dev_dbg(cs35l56->base.dev, "Applying fixup for %s\n",913913+ cs35l56_hda_fixups[i].sub);914914+ return (cs35l56_hda_fixups[i].fixup_fn)(cs35l56, bus_addr);915915+ }916916+ }917917+918918+ return 0;919919+}920920+875921static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)876922{877923 u32 values[HDA_MAX_COMPONENTS];···942896 ACPI_COMPANION_SET(cs35l56->base.dev, adev);943897 }944898945945- property = "cirrus,dev-index";946946- ret = device_property_count_u32(cs35l56->base.dev, property);947947- if (ret <= 0)948948- goto err;949949-950950- if (ret > ARRAY_SIZE(values)) {951951- ret = -EINVAL;952952- goto err;953953- }954954- nval = ret;955955-956956- ret = device_property_read_u32_array(cs35l56->base.dev, property, values, nval);957957- if (ret)958958- goto err;959959-899899+ /* Initialize things that could be overwritten by a fixup */960900 cs35l56->index = -1;961961- for (i = 0; i < nval; i++) {962962- if (values[i] == id) {963963- cs35l56->index = i;964964- break;965965- }966966- }967967- /*968968- * It's not an error for the ID to be missing: for I2C there can be969969- * an alias address that is not a real device. So reject silently.970970- */971971- if (cs35l56->index == -1) {972972- dev_dbg(cs35l56->base.dev, "No index found in %s\n", property);973973- ret = -ENODEV;974974- goto err;975975- }976901977902 sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));903903+ ret = cs35l56_hda_apply_platform_fixups(cs35l56, sub, &id);904904+ if (ret)905905+ return ret;906906+907907+ if (cs35l56->index == -1) {908908+ property = "cirrus,dev-index";909909+ ret = device_property_count_u32(cs35l56->base.dev, property);910910+ if (ret <= 0)911911+ goto err;912912+913913+ if (ret > ARRAY_SIZE(values)) {914914+ ret = -EINVAL;915915+ goto err;916916+ }917917+ nval = ret;918918+919919+ ret = device_property_read_u32_array(cs35l56->base.dev, property, values, nval);920920+ if (ret)921921+ goto err;922922+923923+ for (i = 0; i < nval; i++) {924924+ if (values[i] == id) {925925+ cs35l56->index = i;926926+ break;927927+ }928928+ }929929+930930+ /*931931+ * It's not an error for the ID to be missing: for I2C there can be932932+ * an alias address that is not a real device. So reject silently.933933+ */934934+ if (cs35l56->index == -1) {935935+ dev_dbg(cs35l56->base.dev, "No index found in %s\n", property);936936+ ret = -ENODEV;937937+ goto err;938938+ }939939+ }978940979941 if (IS_ERR(sub)) {980942 dev_info(cs35l56->base.dev,