Loading sound/soc/atmel/mchp-spdiftx.c +1 −1 Original line number Diff line number Diff line Loading @@ -196,7 +196,7 @@ struct mchp_spdiftx_dev { struct clk *pclk; struct clk *gclk; unsigned int fmt; int gclk_enabled:1; unsigned int gclk_enabled:1; }; static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev) Loading sound/soc/codecs/cs42l42.c +7 −6 Original line number Diff line number Diff line Loading @@ -1617,7 +1617,6 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) unsigned int current_plug_status; unsigned int current_button_status; unsigned int i; int report = 0; mutex_lock(&cs42l42->irq_lock); if (cs42l42->suspended) { Loading Loading @@ -1711,15 +1710,17 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) if (current_button_status & CS42L42_M_DETECT_TF_MASK) { dev_dbg(cs42l42->dev, "Button released\n"); report = 0; snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3); } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { report = cs42l42_handle_button_press(cs42l42); } snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | snd_soc_jack_report(cs42l42->jack, cs42l42_handle_button_press(cs42l42), SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3); } } } mutex_unlock(&cs42l42->irq_lock); Loading sound/soc/codecs/nau8540.c +29 −11 Original line number Diff line number Diff line Loading @@ -357,17 +357,32 @@ static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { {"AIFTX", NULL, "Digital CH4 Mux"}, }; static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr) static const struct nau8540_osr_attr * nau8540_get_osr(struct nau8540 *nau8540) { unsigned int osr; regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); osr &= NAU8540_ADC_OSR_MASK; if (osr >= ARRAY_SIZE(osr_adc_sel)) return -EINVAL; return NULL; return &osr_adc_sel[osr]; } static int nau8540_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); const struct nau8540_osr_attr *osr; if (rate * osr > CLK_ADC_MAX) { dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n"); osr = nau8540_get_osr(nau8540); if (!osr || !osr->osr) return -EINVAL; } return 0; return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 0, CLK_ADC_MAX / osr->osr); } static int nau8540_hw_params(struct snd_pcm_substream *substream, Loading @@ -375,7 +390,8 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); unsigned int val_len = 0, osr; unsigned int val_len = 0; const struct nau8540_osr_attr *osr; /* CLK_ADC = OSR * FS * ADC clock frequency is defined as Over Sampling Rate (OSR) Loading @@ -383,13 +399,14 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream, * values must be selected such that the maximum frequency is less * than 6.144 MHz. */ regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); osr &= NAU8540_ADC_OSR_MASK; if (nau8540_clock_check(nau8540, params_rate(params), osr)) osr = nau8540_get_osr(nau8540); if (!osr || !osr->osr) return -EINVAL; if (params_rate(params) * osr->osr > CLK_ADC_MAX) return -EINVAL; regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, NAU8540_CLK_ADC_SRC_MASK, osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT); osr->clk_src << NAU8540_CLK_ADC_SRC_SFT); switch (params_width(params)) { case 16: Loading Loading @@ -515,6 +532,7 @@ static int nau8540_set_tdm_slot(struct snd_soc_dai *dai, static const struct snd_soc_dai_ops nau8540_dai_ops = { .startup = nau8540_dai_startup, .hw_params = nau8540_hw_params, .set_fmt = nau8540_set_fmt, .set_tdm_slot = nau8540_set_tdm_slot, Loading sound/soc/codecs/nau8821.c +36 −30 Original line number Diff line number Diff line Loading @@ -670,28 +670,40 @@ static const struct snd_soc_dapm_route nau8821_dapm_routes[] = { {"HPOR", NULL, "Class G"}, }; static int nau8821_clock_check(struct nau8821 *nau8821, int stream, int rate, int osr) static const struct nau8821_osr_attr * nau8821_get_osr(struct nau8821 *nau8821, int stream) { int osrate = 0; unsigned int osr; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr); osr &= NAU8821_DAC_OVERSAMPLE_MASK; if (osr >= ARRAY_SIZE(osr_dac_sel)) return -EINVAL; osrate = osr_dac_sel[osr].osr; return NULL; return &osr_dac_sel[osr]; } else { regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr); osr &= NAU8821_ADC_SYNC_DOWN_MASK; if (osr >= ARRAY_SIZE(osr_adc_sel)) return -EINVAL; osrate = osr_adc_sel[osr].osr; return NULL; return &osr_adc_sel[osr]; } } if (!osrate || rate * osrate > CLK_DA_AD_MAX) { dev_err(nau8821->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC"); static int nau8821_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); const struct nau8821_osr_attr *osr; osr = nau8821_get_osr(nau8821, substream->stream); if (!osr || !osr->osr) return -EINVAL; } return 0; return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 0, CLK_DA_AD_MAX / osr->osr); } static int nau8821_hw_params(struct snd_pcm_substream *substream, Loading @@ -699,7 +711,8 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); unsigned int val_len = 0, osr, ctrl_val, bclk_fs, clk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, clk_div; const struct nau8821_osr_attr *osr; nau8821->fs = params_rate(params); /* CLK_DAC or CLK_ADC = OSR * FS Loading @@ -708,27 +721,19 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream, * values must be selected such that the maximum frequency is less * than 6.144 MHz. */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr); osr &= NAU8821_DAC_OVERSAMPLE_MASK; if (nau8821_clock_check(nau8821, substream->stream, nau8821->fs, osr)) { osr = nau8821_get_osr(nau8821, substream->stream); if (!osr || !osr->osr) return -EINVAL; } if (nau8821->fs * osr->osr > CLK_DA_AD_MAX) return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER, NAU8821_CLK_DAC_SRC_MASK, osr_dac_sel[osr].clk_src << NAU8821_CLK_DAC_SRC_SFT); } else { regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr); osr &= NAU8821_ADC_SYNC_DOWN_MASK; if (nau8821_clock_check(nau8821, substream->stream, nau8821->fs, osr)) { return -EINVAL; } osr->clk_src << NAU8821_CLK_DAC_SRC_SFT); else regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER, NAU8821_CLK_ADC_SRC_MASK, osr_adc_sel[osr].clk_src << NAU8821_CLK_ADC_SRC_SFT); } osr->clk_src << NAU8821_CLK_ADC_SRC_SFT); /* make BCLK and LRC divde configuration if the codec as master. */ regmap_read(nau8821->regmap, NAU8821_R1D_I2S_PCM_CTRL2, &ctrl_val); Loading Loading @@ -843,6 +848,7 @@ static int nau8821_digital_mute(struct snd_soc_dai *dai, int mute, } static const struct snd_soc_dai_ops nau8821_dai_ops = { .startup = nau8821_dai_startup, .hw_params = nau8821_hw_params, .set_fmt = nau8821_set_dai_fmt, .mute_stream = nau8821_digital_mute, Loading sound/soc/codecs/nau8824.c +46 −34 Original line number Diff line number Diff line Loading @@ -1014,27 +1014,42 @@ static irqreturn_t nau8824_interrupt(int irq, void *data) return IRQ_HANDLED; } static int nau8824_clock_check(struct nau8824 *nau8824, int stream, int rate, int osr) static const struct nau8824_osr_attr * nau8824_get_osr(struct nau8824 *nau8824, int stream) { int osrate; unsigned int osr; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8824->regmap, NAU8824_REG_DAC_FILTER_CTRL_1, &osr); osr &= NAU8824_DAC_OVERSAMPLE_MASK; if (osr >= ARRAY_SIZE(osr_dac_sel)) return -EINVAL; osrate = osr_dac_sel[osr].osr; return NULL; return &osr_dac_sel[osr]; } else { regmap_read(nau8824->regmap, NAU8824_REG_ADC_FILTER_CTRL, &osr); osr &= NAU8824_ADC_SYNC_DOWN_MASK; if (osr >= ARRAY_SIZE(osr_adc_sel)) return -EINVAL; osrate = osr_adc_sel[osr].osr; return NULL; return &osr_adc_sel[osr]; } } if (!osrate || rate * osr > CLK_DA_AD_MAX) { dev_err(nau8824->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n"); static int nau8824_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); const struct nau8824_osr_attr *osr; osr = nau8824_get_osr(nau8824, substream->stream); if (!osr || !osr->osr) return -EINVAL; } return 0; return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 0, CLK_DA_AD_MAX / osr->osr); } static int nau8824_hw_params(struct snd_pcm_substream *substream, Loading @@ -1042,7 +1057,9 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, bclk_div; const struct nau8824_osr_attr *osr; int err = -EINVAL; nau8824_sema_acquire(nau8824, HZ); Loading @@ -1053,27 +1070,19 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, * than 6.144 MHz. */ nau8824->fs = params_rate(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8824->regmap, NAU8824_REG_DAC_FILTER_CTRL_1, &osr); osr &= NAU8824_DAC_OVERSAMPLE_MASK; if (nau8824_clock_check(nau8824, substream->stream, nau8824->fs, osr)) return -EINVAL; osr = nau8824_get_osr(nau8824, substream->stream); if (!osr || !osr->osr) goto error; if (nau8824->fs * osr->osr > CLK_DA_AD_MAX) goto error; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, NAU8824_CLK_DAC_SRC_MASK, osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); } else { regmap_read(nau8824->regmap, NAU8824_REG_ADC_FILTER_CTRL, &osr); osr &= NAU8824_ADC_SYNC_DOWN_MASK; if (nau8824_clock_check(nau8824, substream->stream, nau8824->fs, osr)) return -EINVAL; osr->clk_src << NAU8824_CLK_DAC_SRC_SFT); else regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, NAU8824_CLK_ADC_SRC_MASK, osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); } osr->clk_src << NAU8824_CLK_ADC_SRC_SFT); /* make BCLK and LRC divde configuration if the codec as master. */ regmap_read(nau8824->regmap, Loading @@ -1090,7 +1099,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, else if (bclk_fs <= 256) bclk_div = 0; else return -EINVAL; goto error; regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_2, NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, Loading @@ -1111,15 +1120,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, val_len |= NAU8824_I2S_DL_32; break; default: return -EINVAL; goto error; } regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, NAU8824_I2S_DL_MASK, val_len); err = 0; error: nau8824_sema_release(nau8824); return 0; return err; } static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) Loading @@ -1128,8 +1139,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); unsigned int ctrl1_val = 0, ctrl2_val = 0; nau8824_sema_acquire(nau8824, HZ); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: ctrl2_val |= NAU8824_I2S_MS_MASTER; Loading Loading @@ -1171,6 +1180,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } nau8824_sema_acquire(nau8824, HZ); regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | NAU8824_I2S_PCMB_EN, ctrl1_val); Loading Loading @@ -1547,6 +1558,7 @@ static const struct snd_soc_component_driver nau8824_component_driver = { }; static const struct snd_soc_dai_ops nau8824_dai_ops = { .startup = nau8824_dai_startup, .hw_params = nau8824_hw_params, .set_fmt = nau8824_set_fmt, .set_tdm_slot = nau8824_set_tdm_slot, Loading Loading
sound/soc/atmel/mchp-spdiftx.c +1 −1 Original line number Diff line number Diff line Loading @@ -196,7 +196,7 @@ struct mchp_spdiftx_dev { struct clk *pclk; struct clk *gclk; unsigned int fmt; int gclk_enabled:1; unsigned int gclk_enabled:1; }; static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev) Loading
sound/soc/codecs/cs42l42.c +7 −6 Original line number Diff line number Diff line Loading @@ -1617,7 +1617,6 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) unsigned int current_plug_status; unsigned int current_button_status; unsigned int i; int report = 0; mutex_lock(&cs42l42->irq_lock); if (cs42l42->suspended) { Loading Loading @@ -1711,15 +1710,17 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) if (current_button_status & CS42L42_M_DETECT_TF_MASK) { dev_dbg(cs42l42->dev, "Button released\n"); report = 0; snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3); } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { report = cs42l42_handle_button_press(cs42l42); } snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | snd_soc_jack_report(cs42l42->jack, cs42l42_handle_button_press(cs42l42), SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3); } } } mutex_unlock(&cs42l42->irq_lock); Loading
sound/soc/codecs/nau8540.c +29 −11 Original line number Diff line number Diff line Loading @@ -357,17 +357,32 @@ static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { {"AIFTX", NULL, "Digital CH4 Mux"}, }; static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr) static const struct nau8540_osr_attr * nau8540_get_osr(struct nau8540 *nau8540) { unsigned int osr; regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); osr &= NAU8540_ADC_OSR_MASK; if (osr >= ARRAY_SIZE(osr_adc_sel)) return -EINVAL; return NULL; return &osr_adc_sel[osr]; } static int nau8540_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); const struct nau8540_osr_attr *osr; if (rate * osr > CLK_ADC_MAX) { dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n"); osr = nau8540_get_osr(nau8540); if (!osr || !osr->osr) return -EINVAL; } return 0; return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 0, CLK_ADC_MAX / osr->osr); } static int nau8540_hw_params(struct snd_pcm_substream *substream, Loading @@ -375,7 +390,8 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); unsigned int val_len = 0, osr; unsigned int val_len = 0; const struct nau8540_osr_attr *osr; /* CLK_ADC = OSR * FS * ADC clock frequency is defined as Over Sampling Rate (OSR) Loading @@ -383,13 +399,14 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream, * values must be selected such that the maximum frequency is less * than 6.144 MHz. */ regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); osr &= NAU8540_ADC_OSR_MASK; if (nau8540_clock_check(nau8540, params_rate(params), osr)) osr = nau8540_get_osr(nau8540); if (!osr || !osr->osr) return -EINVAL; if (params_rate(params) * osr->osr > CLK_ADC_MAX) return -EINVAL; regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, NAU8540_CLK_ADC_SRC_MASK, osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT); osr->clk_src << NAU8540_CLK_ADC_SRC_SFT); switch (params_width(params)) { case 16: Loading Loading @@ -515,6 +532,7 @@ static int nau8540_set_tdm_slot(struct snd_soc_dai *dai, static const struct snd_soc_dai_ops nau8540_dai_ops = { .startup = nau8540_dai_startup, .hw_params = nau8540_hw_params, .set_fmt = nau8540_set_fmt, .set_tdm_slot = nau8540_set_tdm_slot, Loading
sound/soc/codecs/nau8821.c +36 −30 Original line number Diff line number Diff line Loading @@ -670,28 +670,40 @@ static const struct snd_soc_dapm_route nau8821_dapm_routes[] = { {"HPOR", NULL, "Class G"}, }; static int nau8821_clock_check(struct nau8821 *nau8821, int stream, int rate, int osr) static const struct nau8821_osr_attr * nau8821_get_osr(struct nau8821 *nau8821, int stream) { int osrate = 0; unsigned int osr; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr); osr &= NAU8821_DAC_OVERSAMPLE_MASK; if (osr >= ARRAY_SIZE(osr_dac_sel)) return -EINVAL; osrate = osr_dac_sel[osr].osr; return NULL; return &osr_dac_sel[osr]; } else { regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr); osr &= NAU8821_ADC_SYNC_DOWN_MASK; if (osr >= ARRAY_SIZE(osr_adc_sel)) return -EINVAL; osrate = osr_adc_sel[osr].osr; return NULL; return &osr_adc_sel[osr]; } } if (!osrate || rate * osrate > CLK_DA_AD_MAX) { dev_err(nau8821->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC"); static int nau8821_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); const struct nau8821_osr_attr *osr; osr = nau8821_get_osr(nau8821, substream->stream); if (!osr || !osr->osr) return -EINVAL; } return 0; return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 0, CLK_DA_AD_MAX / osr->osr); } static int nau8821_hw_params(struct snd_pcm_substream *substream, Loading @@ -699,7 +711,8 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); unsigned int val_len = 0, osr, ctrl_val, bclk_fs, clk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, clk_div; const struct nau8821_osr_attr *osr; nau8821->fs = params_rate(params); /* CLK_DAC or CLK_ADC = OSR * FS Loading @@ -708,27 +721,19 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream, * values must be selected such that the maximum frequency is less * than 6.144 MHz. */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr); osr &= NAU8821_DAC_OVERSAMPLE_MASK; if (nau8821_clock_check(nau8821, substream->stream, nau8821->fs, osr)) { osr = nau8821_get_osr(nau8821, substream->stream); if (!osr || !osr->osr) return -EINVAL; } if (nau8821->fs * osr->osr > CLK_DA_AD_MAX) return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER, NAU8821_CLK_DAC_SRC_MASK, osr_dac_sel[osr].clk_src << NAU8821_CLK_DAC_SRC_SFT); } else { regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr); osr &= NAU8821_ADC_SYNC_DOWN_MASK; if (nau8821_clock_check(nau8821, substream->stream, nau8821->fs, osr)) { return -EINVAL; } osr->clk_src << NAU8821_CLK_DAC_SRC_SFT); else regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER, NAU8821_CLK_ADC_SRC_MASK, osr_adc_sel[osr].clk_src << NAU8821_CLK_ADC_SRC_SFT); } osr->clk_src << NAU8821_CLK_ADC_SRC_SFT); /* make BCLK and LRC divde configuration if the codec as master. */ regmap_read(nau8821->regmap, NAU8821_R1D_I2S_PCM_CTRL2, &ctrl_val); Loading Loading @@ -843,6 +848,7 @@ static int nau8821_digital_mute(struct snd_soc_dai *dai, int mute, } static const struct snd_soc_dai_ops nau8821_dai_ops = { .startup = nau8821_dai_startup, .hw_params = nau8821_hw_params, .set_fmt = nau8821_set_dai_fmt, .mute_stream = nau8821_digital_mute, Loading
sound/soc/codecs/nau8824.c +46 −34 Original line number Diff line number Diff line Loading @@ -1014,27 +1014,42 @@ static irqreturn_t nau8824_interrupt(int irq, void *data) return IRQ_HANDLED; } static int nau8824_clock_check(struct nau8824 *nau8824, int stream, int rate, int osr) static const struct nau8824_osr_attr * nau8824_get_osr(struct nau8824 *nau8824, int stream) { int osrate; unsigned int osr; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8824->regmap, NAU8824_REG_DAC_FILTER_CTRL_1, &osr); osr &= NAU8824_DAC_OVERSAMPLE_MASK; if (osr >= ARRAY_SIZE(osr_dac_sel)) return -EINVAL; osrate = osr_dac_sel[osr].osr; return NULL; return &osr_dac_sel[osr]; } else { regmap_read(nau8824->regmap, NAU8824_REG_ADC_FILTER_CTRL, &osr); osr &= NAU8824_ADC_SYNC_DOWN_MASK; if (osr >= ARRAY_SIZE(osr_adc_sel)) return -EINVAL; osrate = osr_adc_sel[osr].osr; return NULL; return &osr_adc_sel[osr]; } } if (!osrate || rate * osr > CLK_DA_AD_MAX) { dev_err(nau8824->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n"); static int nau8824_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); const struct nau8824_osr_attr *osr; osr = nau8824_get_osr(nau8824, substream->stream); if (!osr || !osr->osr) return -EINVAL; } return 0; return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 0, CLK_DA_AD_MAX / osr->osr); } static int nau8824_hw_params(struct snd_pcm_substream *substream, Loading @@ -1042,7 +1057,9 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, bclk_div; const struct nau8824_osr_attr *osr; int err = -EINVAL; nau8824_sema_acquire(nau8824, HZ); Loading @@ -1053,27 +1070,19 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, * than 6.144 MHz. */ nau8824->fs = params_rate(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { regmap_read(nau8824->regmap, NAU8824_REG_DAC_FILTER_CTRL_1, &osr); osr &= NAU8824_DAC_OVERSAMPLE_MASK; if (nau8824_clock_check(nau8824, substream->stream, nau8824->fs, osr)) return -EINVAL; osr = nau8824_get_osr(nau8824, substream->stream); if (!osr || !osr->osr) goto error; if (nau8824->fs * osr->osr > CLK_DA_AD_MAX) goto error; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, NAU8824_CLK_DAC_SRC_MASK, osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); } else { regmap_read(nau8824->regmap, NAU8824_REG_ADC_FILTER_CTRL, &osr); osr &= NAU8824_ADC_SYNC_DOWN_MASK; if (nau8824_clock_check(nau8824, substream->stream, nau8824->fs, osr)) return -EINVAL; osr->clk_src << NAU8824_CLK_DAC_SRC_SFT); else regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, NAU8824_CLK_ADC_SRC_MASK, osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); } osr->clk_src << NAU8824_CLK_ADC_SRC_SFT); /* make BCLK and LRC divde configuration if the codec as master. */ regmap_read(nau8824->regmap, Loading @@ -1090,7 +1099,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, else if (bclk_fs <= 256) bclk_div = 0; else return -EINVAL; goto error; regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_2, NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, Loading @@ -1111,15 +1120,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, val_len |= NAU8824_I2S_DL_32; break; default: return -EINVAL; goto error; } regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, NAU8824_I2S_DL_MASK, val_len); err = 0; error: nau8824_sema_release(nau8824); return 0; return err; } static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) Loading @@ -1128,8 +1139,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); unsigned int ctrl1_val = 0, ctrl2_val = 0; nau8824_sema_acquire(nau8824, HZ); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: ctrl2_val |= NAU8824_I2S_MS_MASTER; Loading Loading @@ -1171,6 +1180,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } nau8824_sema_acquire(nau8824, HZ); regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | NAU8824_I2S_PCMB_EN, ctrl1_val); Loading Loading @@ -1547,6 +1558,7 @@ static const struct snd_soc_component_driver nau8824_component_driver = { }; static const struct snd_soc_dai_ops nau8824_dai_ops = { .startup = nau8824_dai_startup, .hw_params = nau8824_hw_params, .set_fmt = nau8824_set_fmt, .set_tdm_slot = nau8824_set_tdm_slot, Loading