Hi Amadeusz, >> +int intel_nhlt_ssp_mclk_mask(struct nhlt_acpi_table *nhlt, int ssp_num) >> +{ >> + struct nhlt_endpoint *epnt; >> + struct nhlt_fmt *fmt; >> + struct nhlt_fmt_cfg *cfg; >> + int mclk_mask = 0; >> + int i, j; >> + >> + if (!nhlt) >> + return 0; >> + >> + epnt = (struct nhlt_endpoint *)nhlt->desc; >> + for (i = 0; i < nhlt->endpoint_count; i++) { >> + >> + /* we only care about endpoints connected to an audio codec >> over SSP */ >> + if (epnt->linktype == NHLT_LINK_SSP && >> + epnt->device_type == NHLT_DEVICE_I2S && >> + epnt->virtual_bus_id == ssp_num) { > > if (epnt->linktype != NHLT_LINK_SSP || > epnt->device_type != NHLT_DEVICE_I2S || > epnt->virtual_bus_id != ssp_num) > continue; > > and then you can remove one indentation level below? Would that work? We still need to move the epnt pointer: epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length); and moving this in the endpoint_count loop would be ugly as well. >> + >> + fmt = (struct nhlt_fmt *)(epnt->config.caps + >> epnt->config.size); >> + cfg = fmt->fmt_config; >> + >> + /* >> + * In theory all formats should use the same MCLK but it >> doesn't hurt to >> + * double-check that the configuration is consistent >> + */ >> + for (j = 0; j < fmt->fmt_count; j++) { >> + u32 *blob; >> + int mdivc_offset; >> + >> + if (cfg->config.size >= SSP_BLOB_V1_0_SIZE) { >> + blob = (u32 *)cfg->config.caps; >> + >> + if (blob[1] == SSP_BLOB_VER_2_0) >> + mdivc_offset = SSP_BLOB_V2_0_MDIVC_OFFSET; >> + else if (blob[1] == SSP_BLOB_VER_1_5) >> + mdivc_offset = SSP_BLOB_V1_5_MDIVC_OFFSET; >> + else >> + mdivc_offset = SSP_BLOB_V1_0_MDIVC_OFFSET; >> + >> + mclk_mask |= blob[mdivc_offset] & GENMASK(1, 0); >> + } >> + >> + cfg = (struct nhlt_fmt_cfg *)(cfg->config.caps + >> cfg->config.size); >> + } >> + } >> + epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length); >> + } >> + >> + return mclk_mask; > > Although I understand that it is relegated to the caller, but if both > mclk being set is considered an error maybe add some kind of check here > instead and free callers from having to remember about it? > > if (hweight_long(mclk_mask) != 1) > return -EINVAL; > > return mclk_mask; I went back and forth multiple times on this one. I can't figure out if this would be a bug or a feature, it could be e.g. a test capability and it's supported in hardware. I decided to make the decision in the caller rather than a lower level in the library. If the tools used to generate NHLT don't support this multi-MCLK mode then we could indeed move the test here. > >> +} >> +EXPORT_SYMBOL(intel_nhlt_ssp_mclk_mask); >> + >> static struct nhlt_specific_cfg * >> nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 >> num_ch, >> u32 rate, u8 vbps, u8 bps) >