···132132int dpcm_path_get(struct snd_soc_pcm_runtime *fe,133133 int stream, struct snd_soc_dapm_widget_list **list_);134134void dpcm_path_put(struct snd_soc_dapm_widget_list **list);135135-int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,136136- int stream, struct snd_soc_dapm_widget_list **list, int new);135135+int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,136136+ struct snd_soc_dapm_widget_list **list_);137137int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);138138void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream,139139 int do_hw_free, struct snd_soc_dpcm *last);···143143int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);144144int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);145145int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);146146-int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,147147- int event);146146+void dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, int event);147147+148148bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget, enum snd_soc_dapm_direction dir);149149int widget_in_list(struct snd_soc_dapm_widget_list *list,150150 struct snd_soc_dapm_widget *widget);
-11
include/sound/soc.h
···522522int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,523523 unsigned int dai_fmt);524524525525-#ifdef CONFIG_DMI526526-int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour);527527-#else528528-static inline int snd_soc_set_dmi_name(struct snd_soc_card *card,529529- const char *flavour)530530-{531531- return 0;532532-}533533-#endif534534-535525/* Utility functions to get clock rates from various things */536526int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);537527int snd_soc_params_to_frame_size(const struct snd_pcm_hw_params *params);···11061116 /* Generic DAPM context for the card */11071117 struct snd_soc_dapm_context dapm;11081118 struct snd_soc_dapm_stats dapm_stats;11091109- struct snd_soc_dapm_update *update;1110111911111120#ifdef CONFIG_DEBUG_FS11121121 struct dentry *debugfs_card_root;
+1-1
sound/soc/soc-compress.c
···148148 snd_soc_dpcm_mutex_lock(fe);149149150150 /* calculate valid and active FE <-> BE dpcms */151151- dpcm_process_paths(fe, stream, &list, 1);151151+ dpcm_add_paths(fe, stream, &list);152152153153 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;154154
+7-8
sound/soc/soc-core.c
···18871887/**18881888 * snd_soc_set_dmi_name() - Register DMI names to card18891889 * @card: The card to register DMI names18901890- * @flavour: The flavour "differentiator" for the card amongst its peers.18911890 *18921891 * An Intel machine driver may be used by many different devices but are18931892 * difficult for userspace to differentiate, since machine drivers usually···19141915 *19151916 * Returns 0 on success, otherwise a negative error code.19161917 */19171917-int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)19181918+static int snd_soc_set_dmi_name(struct snd_soc_card *card)19181919{19191920 const char *vendor, *product, *board;19201921···19581959 return 0;19591960 }1960196119611961- /* Add flavour to dmi long name */19621962- if (flavour)19631963- append_dmi_string(card, flavour);19641964-19651962 /* set the card long name */19661963 card->long_name = card->dmi_longname;1967196419681965 return 0;19691966}19701970-EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);19671967+#else19681968+static inline int snd_soc_set_dmi_name(struct snd_soc_card *card)19691969+{19701970+ return 0;19711971+}19711972#endif /* CONFIG_DMI */1972197319731974static void soc_check_tplg_fes(struct snd_soc_card *card)···22552256 goto probe_end;2256225722572258 /* try to set some sane longname if DMI is available */22582258- snd_soc_set_dmi_name(card, NULL);22592259+ snd_soc_set_dmi_name(card);2259226022602261 soc_setup_card_name(card, card->snd_card->shortname,22612262 card->name, NULL);
+5-3
sound/soc/soc-dai.c
···261261262262 if (dai->driver->ops &&263263 dai->driver->ops->xlate_tdm_slot_mask)264264- dai->driver->ops->xlate_tdm_slot_mask(slots,265265- &tx_mask, &rx_mask);264264+ ret = dai->driver->ops->xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);266265 else267267- snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);266266+ ret = snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);267267+ if (ret)268268+ goto err;268269269270 for_each_pcm_streams(stream)270271 snd_soc_dai_tdm_mask_set(dai, stream, *tdm_mask[stream]);···274273 dai->driver->ops->set_tdm_slot)275274 ret = dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,276275 slots, slot_width);276276+err:277277 return soc_dai_ret(dai, ret);278278}279279EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
+21-27
sound/soc/soc-dapm.c
···17431743 soc_dapm_async_complete(d);17441744}1745174517461746-static void dapm_widget_update(struct snd_soc_card *card)17461746+static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_update *update)17471747{17481748- struct snd_soc_dapm_update *update = card->update;17491748 struct snd_soc_dapm_widget_list *wlist;17501749 struct snd_soc_dapm_widget *w = NULL;17511750 unsigned int wi;···19501951 * o Input pin to Output pin (bypass, sidetone)19511952 * o DAC to ADC (loopback).19521953 */19531953-static int dapm_power_widgets(struct snd_soc_card *card, int event)19541954+static int dapm_power_widgets(struct snd_soc_card *card, int event,19551955+ struct snd_soc_dapm_update *update)19541956{19551957 struct snd_soc_dapm_widget *w;19561958 struct snd_soc_dapm_context *d;···20592059 /* Power down widgets first; try to avoid amplifying pops. */20602060 dapm_seq_run(card, &down_list, event, false);2061206120622062- dapm_widget_update(card);20622062+ dapm_widget_update(card, update);2063206320642064 /* Now power up. */20652065 dapm_seq_run(card, &up_list, event, true);···2332233223332333/* test and update the power status of a mux widget */23342334static int soc_dapm_mux_update_power(struct snd_soc_card *card,23352335- struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)23352335+ struct snd_kcontrol *kcontrol,23362336+ struct snd_soc_dapm_update *update,23372337+ int mux, struct soc_enum *e)23362338{23372339 struct snd_soc_dapm_path *path;23382340 int found = 0;···23552353 }2356235423572355 if (found)23582358- dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);23562356+ dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, update);2359235723602358 return found;23612359}···23682366 int ret;2369236723702368 snd_soc_dapm_mutex_lock(card);23712371- card->update = update;23722372- ret = soc_dapm_mux_update_power(card, kcontrol, mux, e);23732373- card->update = NULL;23692369+ ret = soc_dapm_mux_update_power(card, kcontrol, update, mux, e);23742370 snd_soc_dapm_mutex_unlock(card);23752371 if (ret > 0)23762372 snd_soc_dpcm_runtime_update(card);···23792379/* test and update the power status of a mixer or switch widget */23802380static int soc_dapm_mixer_update_power(struct snd_soc_card *card,23812381 struct snd_kcontrol *kcontrol,23822382+ struct snd_soc_dapm_update *update,23822383 int connect, int rconnect)23832384{23842385 struct snd_soc_dapm_path *path;···24192418 }2420241924212420 if (found)24222422- dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);24212421+ dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, update);2423242224242423 return found;24252424}···24322431 int ret;2433243224342433 snd_soc_dapm_mutex_lock(card);24352435- card->update = update;24362436- ret = soc_dapm_mixer_update_power(card, kcontrol, connect, -1);24372437- card->update = NULL;24342434+ ret = soc_dapm_mixer_update_power(card, kcontrol, update, connect, -1);24382435 snd_soc_dapm_mutex_unlock(card);24392436 if (ret > 0)24402437 snd_soc_dpcm_runtime_update(card);···26882689 if (!snd_soc_card_is_instantiated(dapm->card))26892690 return 0;2690269126912691- return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP);26922692+ return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP, NULL);26922693}26932694EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked);26942695···33573358 dapm_debugfs_add_widget(w);33583359 }3359336033603360- dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);33613361+ dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, NULL);33613362 snd_soc_dapm_mutex_unlock(card);33623363 return 0;33633364}···34463447 unsigned int val, rval = 0;34473448 int connect, rconnect = -1, change, reg_change = 0;34483449 struct snd_soc_dapm_update update = {};34503450+ struct snd_soc_dapm_update *pupdate = NULL;34493451 int ret = 0;3450345234513453 val = (ucontrol->value.integer.value[0] & mask);···34953495 update.reg = reg;34963496 update.mask = mask << shift;34973497 update.val = val;34983498- card->update = &update;34983498+ pupdate = &update;34993499 }35003500-35013501- ret = soc_dapm_mixer_update_power(card, kcontrol, connect,35023502- rconnect);35033503-35043504- card->update = NULL;35003500+ ret = soc_dapm_mixer_update_power(card, kcontrol, pupdate, connect, rconnect);35053501 }3506350235073503 snd_soc_dapm_mutex_unlock(card);···35643568 unsigned int val, change, reg_change = 0;35653569 unsigned int mask;35663570 struct snd_soc_dapm_update update = {};35713571+ struct snd_soc_dapm_update *pupdate = NULL;35673572 int ret = 0;3568357335693574 if (item[0] >= e->items)···35923595 update.reg = e->reg;35933596 update.mask = mask;35943597 update.val = val;35953595- card->update = &update;35983598+ pupdate = &update;35963599 }35973597-35983598- ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e);35993599-36003600- card->update = NULL;36003600+ ret = soc_dapm_mux_update_power(card, kcontrol, pupdate, item[0], e);36013601 }3602360236033603 snd_soc_dapm_mutex_unlock(card);···45204526 for_each_rtd_dais(rtd, i, dai)45214527 soc_dapm_dai_stream_event(dai, stream, event);4522452845234523- dapm_power_widgets(rtd->card, event);45294529+ dapm_power_widgets(rtd->card, event, NULL);45244530}4525453145264532/**
+6-17
sound/soc/soc-ops.c
···122122 * This functions reads a codec register. The register value is shifted right123123 * by 'shift' bits and masked with the given 'mask'. Afterwards it translates124124 * the given registervalue into a signed integer if sign_bit is non-zero.125125- *126126- * Returns 0 on sucess, otherwise an error value127125 */128128-static int snd_soc_read_signed(struct snd_soc_component *component,126126+static void snd_soc_read_signed(struct snd_soc_component *component,129127 unsigned int reg, unsigned int mask, unsigned int shift,130128 unsigned int sign_bit, int *signed_val)131129{···135137136138 if (!sign_bit) {137139 *signed_val = val;138138- return 0;140140+ return;139141 }140142141143 /* non-negative number */142144 if (!(val & BIT(sign_bit))) {143145 *signed_val = val;144144- return 0;146146+ return;145147 }146148147149 ret = val;···155157 ret |= ~((int)(BIT(sign_bit) - 1));156158157159 *signed_val = ret;158158-159159- return 0;160160}161161162162/**···262266 unsigned int mask = (1ULL << fls(max)) - 1;263267 unsigned int invert = mc->invert;264268 int val;265265- int ret;266269267270 if (sign_bit)268271 mask = BIT(sign_bit + 1) - 1;269272270270- ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val);271271- if (ret)272272- return ret;273273+ snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val);273274274275 ucontrol->value.integer.value[0] = val - min;275276 if (invert)···275282276283 if (snd_soc_volsw_is_stereo(mc)) {277284 if (reg == reg2)278278- ret = snd_soc_read_signed(component, reg, mask, rshift,279279- sign_bit, &val);285285+ snd_soc_read_signed(component, reg, mask, rshift, sign_bit, &val);280286 else281281- ret = snd_soc_read_signed(component, reg2, mask, shift,282282- sign_bit, &val);283283- if (ret)284284- return ret;287287+ snd_soc_read_signed(component, reg2, mask, shift, sign_bit, &val);285288286289 ucontrol->value.integer.value[1] = val - min;287290 if (invert)
+47-69
sound/soc/soc-pcm.c
···400400}401401402402/* DPCM stream event, send event to FE and all active BEs. */403403-int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,404404- int event)403403+void dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, int event)405404{406405 struct snd_soc_dpcm *dpcm;407406···421422 }422423423424 snd_soc_dapm_stream_event(fe, dir, event);424424-425425- return 0;426425}427426428427static void soc_pcm_set_dai_params(struct snd_soc_dai *dai,···10621065 * function can also be called multiple times and can allocate buffers10631066 * (using snd_pcm_lib_* ). It's non-atomic.10641067 */10651065-static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,10661066- struct snd_pcm_substream *substream,10681068+static int __soc_pcm_hw_params(struct snd_pcm_substream *substream,10671069 struct snd_pcm_hw_params *params)10681070{10711071+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);10691072 struct snd_soc_dai *cpu_dai;10701073 struct snd_soc_dai *codec_dai;10711074 struct snd_pcm_hw_params tmp_params;···11711174 int ret;1172117511731176 snd_soc_dpcm_mutex_lock(rtd);11741174- ret = __soc_pcm_hw_params(rtd, substream, params);11771177+ ret = __soc_pcm_hw_params(substream, params);11751178 snd_soc_dpcm_mutex_unlock(rtd);11761179 return ret;11771180}···13011304 snd_soc_dpcm_mutex_assert_held(fe);1302130513031306 /* only add new dpcms */13041304- for_each_dpcm_be(fe, stream, dpcm) {13051305- if (dpcm->be == be && dpcm->fe == fe)13071307+ for_each_dpcm_be(fe, stream, dpcm)13081308+ if (dpcm->be == be)13061309 return 0;13071307- }1308131013091311 fe_substream = snd_soc_dpcm_get_substream(fe, stream);13101312 be_substream = snd_soc_dpcm_get_substream(be, stream);···15501554 return prune;15511555}1552155615531553-static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,15541554- struct snd_soc_dapm_widget_list **list_)15571557+int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,15581558+ struct snd_soc_dapm_widget_list **list_)15551559{15561560 struct snd_soc_card *card = fe->card;15571561 struct snd_soc_dapm_widget_list *list = *list_;···1614161816151619 dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new);16161620 return new;16171617-}16181618-16191619-/*16201620- * Find the corresponding BE DAIs that source or sink audio to this16211621- * FE substream.16221622- */16231623-int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,16241624- int stream, struct snd_soc_dapm_widget_list **list, int new)16251625-{16261626- if (new)16271627- return dpcm_add_paths(fe, stream, list);16281628- else16291629- return dpcm_prune_paths(fe, stream, list);16301621}1631162216321623void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)···21102127 dev_dbg(be->dev, "ASoC: hw_params BE %s\n",21112128 be->dai_link->name);2112212921132113- ret = __soc_pcm_hw_params(be, be_substream, &hw_params);21302130+ ret = __soc_pcm_hw_params(be_substream, &hw_params);21142131 if (ret < 0)21152132 goto unwind;21162133···21662183 params_channels(params), params_format(params));2167218421682185 /* call hw_params on the frontend */21692169- ret = __soc_pcm_hw_params(fe, substream, params);21862186+ ret = __soc_pcm_hw_params(substream, params);21702187 if (ret < 0)21712188 dpcm_be_dai_hw_free(fe, stream);21722189 else···23652382 goto end;2366238323672384 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);23682368- goto end;23692385 }23702370-23712386 /* call trigger on the frontend after the backend. */23722372- ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);23732373- if (ret < 0)23742374- goto end;23872387+ else {23882388+ ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);23892389+ if (ret < 0)23902390+ goto end;2375239123762376- dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",23772377- fe->dai_link->name, cmd);23922392+ dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",23932393+ fe->dai_link->name, cmd);2378239423792379- ret = soc_pcm_trigger(substream, cmd);23952395+ ret = soc_pcm_trigger(substream, cmd);23962396+ }23802397end:23812398 return snd_soc_ret(fe->dev, ret, "trigger FE cmd: %d failed\n", cmd);23822399}···23862403 struct snd_soc_pcm_runtime *fe = snd_soc_substream_to_rtd(substream);23872404 int stream = substream->stream;23882405 int ret = 0;24062406+ int fe_first;23892407 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];2390240823912409 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;2392241023932411 switch (trigger) {23942412 case SND_SOC_DPCM_TRIGGER_PRE:23952395- switch (cmd) {23962396- case SNDRV_PCM_TRIGGER_START:23972397- case SNDRV_PCM_TRIGGER_RESUME:23982398- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:23992399- case SNDRV_PCM_TRIGGER_DRAIN:24002400- ret = dpcm_dai_trigger_fe_be(substream, cmd, true);24012401- break;24022402- case SNDRV_PCM_TRIGGER_STOP:24032403- case SNDRV_PCM_TRIGGER_SUSPEND:24042404- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:24052405- ret = dpcm_dai_trigger_fe_be(substream, cmd, false);24062406- break;24072407- default:24082408- ret = -EINVAL;24092409- break;24102410- }24132413+ fe_first = true;24112414 break;24122415 case SND_SOC_DPCM_TRIGGER_POST:24132413- switch (cmd) {24142414- case SNDRV_PCM_TRIGGER_START:24152415- case SNDRV_PCM_TRIGGER_RESUME:24162416- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:24172417- case SNDRV_PCM_TRIGGER_DRAIN:24182418- ret = dpcm_dai_trigger_fe_be(substream, cmd, false);24192419- break;24202420- case SNDRV_PCM_TRIGGER_STOP:24212421- case SNDRV_PCM_TRIGGER_SUSPEND:24222422- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:24232423- ret = dpcm_dai_trigger_fe_be(substream, cmd, true);24242424- break;24252425- default:24262426- ret = -EINVAL;24272427- break;24282428- }24162416+ fe_first = false;24292417 break;24302418 default:24312419 dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,24322420 fe->dai_link->name);24332421 ret = -EINVAL;24342422 goto out;24232423+ }24242424+24252425+ switch (cmd) {24262426+ case SNDRV_PCM_TRIGGER_START:24272427+ case SNDRV_PCM_TRIGGER_RESUME:24282428+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:24292429+ case SNDRV_PCM_TRIGGER_DRAIN:24302430+ ret = dpcm_dai_trigger_fe_be(substream, cmd, fe_first);24312431+ break;24322432+ case SNDRV_PCM_TRIGGER_STOP:24332433+ case SNDRV_PCM_TRIGGER_SUSPEND:24342434+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:24352435+ ret = dpcm_dai_trigger_fe_be(substream, cmd, !fe_first);24362436+ break;24372437+ default:24382438+ ret = -EINVAL;24392439+ break;24352440 }2436244124372442 if (ret < 0)···26812710 return paths;2682271126832712 /* update any playback/capture paths */26842684- count = dpcm_process_paths(fe, stream, &list, new);27132713+ /*27142714+ * Find the corresponding BE DAIs that source or sink audio to this27152715+ * FE substream.27162716+ */27172717+ if (new)27182718+ count = dpcm_add_paths(fe, stream, &list);27192719+ else27202720+ count = dpcm_prune_paths(fe, stream, &list);26852721 if (count) {26862722 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);26872723 if (new)···27802802 goto open_end;2781280327822804 /* calculate valid and active FE <-> BE dpcms */27832783- dpcm_process_paths(fe, stream, &list, 1);28052805+ dpcm_add_paths(fe, stream, &list);2784280627852807 ret = dpcm_fe_dai_startup(fe_substream);27862808 if (ret < 0)