// The specced range is -71.25...24.00 dB with step size of 0.375 dB, // and a mute item below that. This is represented by -71.62...24.00 dB // with the mute item mapped onto the low end. static DECLARE_TLV_DB_MINMAX_MUTE(ssm3515_dac_volume, -7162, 2400);
staticconstchar * const ssm3515_ana_gain_text[] = { "8.4 V Span", "12.6 V Span", "14 V Span", "15 V Span",
};
staticvoid ssm3515_read_faults(struct snd_soc_component *component)
{ int ret;
ret = snd_soc_component_read(component, SSM3515_STATUS); if (ret <= 0) { /* * If the read was erroneous, ASoC core has printed a message, * and that's all that's appropriate in handling the error here.
*/ return;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_NF: case SND_SOC_DAIFMT_IB_IF:
sai1 |= SSM3515_SAI1_BCLK_POL; break;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S:
fpol_inv = 1;
sai1 &= ~SSM3515_SAI1_SDATA_FMT; /* 1 bit start delay */ break; case SND_SOC_DAIFMT_LEFT_J:
fpol_inv = 0;
sai1 |= SSM3515_SAI1_SDATA_FMT; /* no start delay */ break; default: return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_IF: case SND_SOC_DAIFMT_IB_IF:
fpol_inv ^= 1; break;
}
/* Set the serial input to 'TDM mode' */
sai1 |= SSM3515_SAI1_SAI_MODE;
if (fpol_inv) { /* * We configure the codec in a 'TDM mode', in which the * FSYNC_MODE bit of SAI1 is supposed to select between * what the datasheet calls 'Pulsed FSYNC mode' and '50% * FSYNC mode'. * * Experiments suggest that this bit in fact simply selects * the FSYNC polarity, so go with that.
*/
sai1 |= SSM3515_SAI1_FSYNC_MODE;
}
staticint ssm3515_set_tdm_slot(struct snd_soc_dai *dai, unsignedint tx_mask, unsignedint rx_mask, int slots, int slot_width)
{ struct snd_soc_component *component = dai->component; int slot, tdm_bclks_val, ret;
if (tx_mask == 0 || rx_mask != 0) return -EINVAL;
slot = __ffs(tx_mask);
if (tx_mask & ~BIT(slot)) return -EINVAL;
switch (slot_width) { case 16:
tdm_bclks_val = 0; break; case 24:
tdm_bclks_val = 1; break; case 32:
tdm_bclks_val = 2; break; case 48:
tdm_bclks_val = 3; break; case 64:
tdm_bclks_val = 4; break; default: return -EINVAL;
}
ret = snd_soc_component_update_bits(component, SSM3515_SAI1,
SSM3515_SAI1_TDM_BCLKS,
FIELD_PREP(SSM3515_SAI1_TDM_BCLKS, tdm_bclks_val)); if (ret < 0) return ret;
ret = snd_soc_component_update_bits(component, SSM3515_SAI2,
SSM3515_SAI2_TDM_SLOT,
FIELD_PREP(SSM3515_SAI2_TDM_SLOT, slot)); if (ret < 0) return ret;
return 0;
}
staticint ssm3515_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{ /* * We don't get live notification of faults, so at least at * this time, when playback is over, check if we have tripped * over anything and if so, log it.
*/
ssm3515_read_faults(dai->component); return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.