diff options
author | Chen-Yu Tsai <wens@csie.org> | 2017-12-14 02:29:28 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-12-14 06:12:28 -0500 |
commit | 2ff739b9bdd3199cd52e450097cb0f7fc4e1e9e8 (patch) | |
tree | 8aac3f85afc1f206202f7bcbe95d258d195b9821 | |
parent | 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff) |
ASoC: sun4i-i2s: Show detailed error when DAI configuration callbacks fail
When any of the DAI hardware configuration callbacks (.hw_param,
.set_fmt, .set_sysclk) fails, there is no explanation about why it
failed. This is particularly confusing for .hw_param, which covers
many parameters of the DAI. Telling the users what parameter isn't
supported, and what the requested value was goes a long way for
developers trying to combine sun4i-i2s with external codecs.
This patch adds dev_err calls explaining what isn't supported or
failed, and what the value was. sun4i_i2s_set_clk_rate()'s first
parameter was changed to a struct snd_soc_dai *dai, so we can
get the underlying device.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Marcus Cooper <codekipper@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sunxi/sun4i-i2s.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 04f92583a969..bc147e2dcff5 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c | |||
@@ -269,10 +269,11 @@ static bool sun4i_i2s_oversample_is_valid(unsigned int oversample) | |||
269 | return false; | 269 | return false; |
270 | } | 270 | } |
271 | 271 | ||
272 | static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, | 272 | static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, |
273 | unsigned int rate, | 273 | unsigned int rate, |
274 | unsigned int word_size) | 274 | unsigned int word_size) |
275 | { | 275 | { |
276 | struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
276 | unsigned int oversample_rate, clk_rate; | 277 | unsigned int oversample_rate, clk_rate; |
277 | int bclk_div, mclk_div; | 278 | int bclk_div, mclk_div; |
278 | int ret; | 279 | int ret; |
@@ -300,6 +301,7 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, | |||
300 | break; | 301 | break; |
301 | 302 | ||
302 | default: | 303 | default: |
304 | dev_err(dai->dev, "Unsupported sample rate: %u\n", rate); | ||
303 | return -EINVAL; | 305 | return -EINVAL; |
304 | } | 306 | } |
305 | 307 | ||
@@ -308,18 +310,25 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, | |||
308 | return ret; | 310 | return ret; |
309 | 311 | ||
310 | oversample_rate = i2s->mclk_freq / rate; | 312 | oversample_rate = i2s->mclk_freq / rate; |
311 | if (!sun4i_i2s_oversample_is_valid(oversample_rate)) | 313 | if (!sun4i_i2s_oversample_is_valid(oversample_rate)) { |
314 | dev_err(dai->dev, "Unsupported oversample rate: %d\n", | ||
315 | oversample_rate); | ||
312 | return -EINVAL; | 316 | return -EINVAL; |
317 | } | ||
313 | 318 | ||
314 | bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, | 319 | bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, |
315 | word_size); | 320 | word_size); |
316 | if (bclk_div < 0) | 321 | if (bclk_div < 0) { |
322 | dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div); | ||
317 | return -EINVAL; | 323 | return -EINVAL; |
324 | } | ||
318 | 325 | ||
319 | mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, | 326 | mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, |
320 | clk_rate, rate); | 327 | clk_rate, rate); |
321 | if (mclk_div < 0) | 328 | if (mclk_div < 0) { |
329 | dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div); | ||
322 | return -EINVAL; | 330 | return -EINVAL; |
331 | } | ||
323 | 332 | ||
324 | /* Adjust the clock division values if needed */ | 333 | /* Adjust the clock division values if needed */ |
325 | bclk_div += i2s->variant->bclk_offset; | 334 | bclk_div += i2s->variant->bclk_offset; |
@@ -349,8 +358,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
349 | u32 width; | 358 | u32 width; |
350 | 359 | ||
351 | channels = params_channels(params); | 360 | channels = params_channels(params); |
352 | if (channels != 2) | 361 | if (channels != 2) { |
362 | dev_err(dai->dev, "Unsupported number of channels: %d\n", | ||
363 | channels); | ||
353 | return -EINVAL; | 364 | return -EINVAL; |
365 | } | ||
354 | 366 | ||
355 | if (i2s->variant->has_chcfg) { | 367 | if (i2s->variant->has_chcfg) { |
356 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, | 368 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, |
@@ -382,6 +394,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
382 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 394 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; |
383 | break; | 395 | break; |
384 | default: | 396 | default: |
397 | dev_err(dai->dev, "Unsupported physical sample width: %d\n", | ||
398 | params_physical_width(params)); | ||
385 | return -EINVAL; | 399 | return -EINVAL; |
386 | } | 400 | } |
387 | i2s->playback_dma_data.addr_width = width; | 401 | i2s->playback_dma_data.addr_width = width; |
@@ -393,6 +407,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
393 | break; | 407 | break; |
394 | 408 | ||
395 | default: | 409 | default: |
410 | dev_err(dai->dev, "Unsupported sample width: %d\n", | ||
411 | params_width(params)); | ||
396 | return -EINVAL; | 412 | return -EINVAL; |
397 | } | 413 | } |
398 | 414 | ||
@@ -401,7 +417,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
401 | regmap_field_write(i2s->field_fmt_sr, | 417 | regmap_field_write(i2s->field_fmt_sr, |
402 | sr + i2s->variant->fmt_offset); | 418 | sr + i2s->variant->fmt_offset); |
403 | 419 | ||
404 | return sun4i_i2s_set_clk_rate(i2s, params_rate(params), | 420 | return sun4i_i2s_set_clk_rate(dai, params_rate(params), |
405 | params_width(params)); | 421 | params_width(params)); |
406 | } | 422 | } |
407 | 423 | ||
@@ -426,6 +442,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
426 | val = SUN4I_I2S_FMT0_FMT_RIGHT_J; | 442 | val = SUN4I_I2S_FMT0_FMT_RIGHT_J; |
427 | break; | 443 | break; |
428 | default: | 444 | default: |
445 | dev_err(dai->dev, "Unsupported format: %d\n", | ||
446 | fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
429 | return -EINVAL; | 447 | return -EINVAL; |
430 | } | 448 | } |
431 | 449 | ||
@@ -464,6 +482,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
464 | case SND_SOC_DAIFMT_NB_NF: | 482 | case SND_SOC_DAIFMT_NB_NF: |
465 | break; | 483 | break; |
466 | default: | 484 | default: |
485 | dev_err(dai->dev, "Unsupported clock polarity: %d\n", | ||
486 | fmt & SND_SOC_DAIFMT_INV_MASK); | ||
467 | return -EINVAL; | 487 | return -EINVAL; |
468 | } | 488 | } |
469 | 489 | ||
@@ -482,6 +502,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
482 | val = SUN4I_I2S_CTRL_MODE_SLAVE; | 502 | val = SUN4I_I2S_CTRL_MODE_SLAVE; |
483 | break; | 503 | break; |
484 | default: | 504 | default: |
505 | dev_err(dai->dev, "Unsupported slave setting: %d\n", | ||
506 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
485 | return -EINVAL; | 507 | return -EINVAL; |
486 | } | 508 | } |
487 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | 509 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, |
@@ -504,6 +526,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
504 | val = 0; | 526 | val = 0; |
505 | break; | 527 | break; |
506 | default: | 528 | default: |
529 | dev_err(dai->dev, "Unsupported slave setting: %d\n", | ||
530 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
507 | return -EINVAL; | 531 | return -EINVAL; |
508 | } | 532 | } |
509 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | 533 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, |