At Wed, 5 Nov 2008 18:53:28 +0000, Mark Brown wrote: > > From: Troy Kisky <troy.kisky@xxxxxxxxxxxxxxxxxxx> > > Add support for more sample rates, different crystals > and split playback/capture rates. > > Signed-off-by: Troy Kisky <troy.kisky@xxxxxxxxxxxxxxxxxxx> > Acked-by: Arun KS <arunks@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx> > --- > sound/soc/codecs/tlv320aic23.c | 227 ++++++++++++++++++++++++++++++++-------- > 1 files changed, 182 insertions(+), 45 deletions(-) > > diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c > index 44308da..c1b2060 100644 > --- a/sound/soc/codecs/tlv320aic23.c > +++ b/sound/soc/codecs/tlv320aic23.c > +unsigned get_score(int adc, int adc_l, int adc_h, int need_adc, > + int dac, int dac_l, int dac_h, int need_dac) Should be static. > +{ > + if ((adc >= adc_l) && (adc <= adc_h) && > + (dac >= dac_l) && (dac <= dac_h)) { > + unsigned diff_adc = need_adc - adc; > + unsigned diff_dac = need_dac - dac; > + unsigned score; > + if (((int)diff_adc) < 0) > + diff_adc = -diff_adc; > + if (((int)diff_dac) < 0) > + diff_dac = -diff_dac; > + score = diff_adc + diff_dac; > + return score; > + } > + return 0xffffffff; -1 would be simpler and safer (for possible missing f's). > +} > +int find_rate(int mclk, u32 need_adc, u32 need_dac) Use static. > +{ > + int i, j; > + int best_i = -1; > + int best_j = -1; > + int best_div = 0; > + unsigned best_score = 0xffffffff; -1 would be safer. > + int adc_l, adc_h, dac_l, dac_h; > + > + need_adc *= SR_MULT; > + need_dac *= SR_MULT; > + /* > + * rates given are +/- 1/32 > + */ > + adc_l = need_adc - (need_adc >> 5); > + adc_h = need_adc + (need_adc >> 5); > + dac_l = need_dac - (need_dac >> 5); > + dac_h = need_dac + (need_dac >> 5); > + for (i = 0; i < 4; i++) { > + int base = mclk / bosr_usb_divisor_table[i]; > + int mask = sr_valid_mask[i]; > + for (j = 0; j < 16; j++, mask >>= 1) { > + int adc; > + int dac; > + int score; > + if ((mask & 1) == 0) > + continue; > + adc = base * sr_adc_mult_table[j]; > + dac = base * sr_dac_mult_table[j]; > + score = get_score(adc, adc_l, adc_h, need_adc, > + dac, dac_l, dac_h, need_dac); > + if (best_score > score) { > + best_score = score; > + best_i = i; > + best_j = j; > + best_div = 0; > + } > + score = get_score((adc >> 1), adc_l, adc_h, need_adc, > + (dac >> 1), dac_l, dac_h, need_dac); > + /* prefer to have a /2 */ > + if ((score != 0xffffffff) && (best_score >= score)) { > + best_score = score; > + best_i = i; > + best_j = j; > + best_div = 1; > + } > + } > + } > + return (best_j << 2) | best_i | (best_div << TLV320AIC23_CLKIN_SHIFT); > +} > + > +static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk, > + u32 *sample_rate_adc, u32 *sample_rate_dac) > +{ > + int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE); > + int sr = (src >> 2) & 0x0f; > + int val = (mclk / bosr_usb_divisor_table[src & 3]); > + int adc = (val * sr_adc_mult_table[sr]) / SR_MULT; > + int dac = (val * sr_dac_mult_table[sr]) / SR_MULT; > + if (src & TLV320AIC23_CLKIN_HALF) { > + adc >>= 1; > + dac >>= 1; > + } > + *sample_rate_adc = adc; > + *sample_rate_dac = dac; > +} > + > +static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk, > + u32 sample_rate_adc, u32 sample_rate_dac) > +{ > + /* Search for the right sample rate */ > + int data = find_rate(mclk, sample_rate_adc, sample_rate_dac); > + if (data < 0) { > + printk(KERN_ERR "%s:Invalid rate %u,%u requested\n", > + __func__, sample_rate_adc, sample_rate_dac); > + return -EINVAL; > + } > + tlv320aic23_write(codec, TLV320AIC23_SRATE, data); > + if (1) { For what? Takashi _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel