···7777 * According to the definition of 'DAI Sel Mux' mixer in max98373.c, rx mask7878 * should choose two channels from TDM slots, the LSB of rx mask is left channel7979 * and the other one is right channel.8080- *8181- * For tx mask, each codec requires two channels: one for V-sense and the other8282- * one for I-sense. Must match the device property "maxim,vmon-slot-no" and8383- * "maxim,imon-slot-no" in ACPI table.8480 */8581static const struct {8686- unsigned int tx;8782 unsigned int rx;8883} max_98373_tdm_mask[] = {8989- {.tx = 0x03, .rx = 0x3},9090- {.tx = 0x0c, .rx = 0x3},8484+ {.rx = 0x3},8585+ {.rx = 0x3},9186};8787+8888+/*8989+ * The tx mask indicates which channel(s) contains output IV-sense data and9090+ * others should set to Hi-Z. Here we get the channel number from codec's ACPI9191+ * device property "maxim,vmon-slot-no" and "maxim,imon-slot-no" to generate the9292+ * mask. Refer to the max98373_slot_config() function in max98373.c codec driver.9393+ */9494+static unsigned int max_98373_get_tx_mask(struct device *dev)9595+{9696+ int vmon_slot;9797+ int imon_slot;9898+9999+ if (device_property_read_u32(dev, "maxim,vmon-slot-no", &vmon_slot))100100+ vmon_slot = 0;101101+102102+ if (device_property_read_u32(dev, "maxim,imon-slot-no", &imon_slot))103103+ imon_slot = 1;104104+105105+ dev_dbg(dev, "vmon_slot %d imon_slot %d\n", vmon_slot, imon_slot);106106+107107+ return (0x1 << vmon_slot) | (0x1 << imon_slot);108108+}9210993110static int max_98373_hw_params(struct snd_pcm_substream *substream,94111 struct snd_pcm_hw_params *params)···11598 struct snd_soc_dai *codec_dai;11699 int i;117100 int tdm_slots;101101+ unsigned int tx_mask;102102+ unsigned int tx_mask_used = 0x0;118103 int ret = 0;119104120105 for_each_rtd_codec_dais(rtd, i, codec_dai) {···136117 return -EINVAL;137118 }138119120120+ /* get the tx mask from ACPI device properties */121121+ tx_mask = max_98373_get_tx_mask(codec_dai->dev);122122+ if (!tx_mask)123123+ return -EINVAL;124124+125125+ if (tx_mask & tx_mask_used) {126126+ dev_err(codec_dai->dev, "invalid tx mask 0x%x, used 0x%x\n",127127+ tx_mask, tx_mask_used);128128+ return -EINVAL;129129+ }130130+131131+ tx_mask_used |= tx_mask;132132+139133 /*140134 * check if tdm slot number is too small for channel141135 * allocation142136 */143143- if (fls(max_98373_tdm_mask[i].tx) > tdm_slots) {137137+ if (fls(tx_mask) > tdm_slots) {144138 dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",145145- fls(max_98373_tdm_mask[i].tx), tdm_slots);139139+ fls(tx_mask), tdm_slots);146140 return -EINVAL;147141 }148142···166134 }167135168136 dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n",169169- max_98373_tdm_mask[i].tx,170170- max_98373_tdm_mask[i].rx,137137+ tx_mask, max_98373_tdm_mask[i].rx,171138 tdm_slots, params_width(params));172139173173- ret = snd_soc_dai_set_tdm_slot(codec_dai,174174- max_98373_tdm_mask[i].tx,140140+ ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask,175141 max_98373_tdm_mask[i].rx,176142 tdm_slots,177143 params_width(params));