aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/pcm512x.c
diff options
context:
space:
mode:
authorPeter Rosin <peda@axentia.se>2015-01-28 09:16:09 -0500
committerMark Brown <broonie@kernel.org>2015-01-28 14:28:53 -0500
commit8124930713f2fa37ad5347ddfcd2aae45a016aa5 (patch)
tree789b1bb9eeddc5cae3c2b89aafaaa4307cc1b003 /sound/soc/codecs/pcm512x.c
parent376dc4903eec7f64b9fd1dafe542c07ab63abb49 (diff)
ASoC: pcm512x: Support mastering BCLK/LRCLK without using the PLL
Use register field names from the seemingly compatible PCM5242 datasheet, as the PCM512x and PCM514x datasheets are severly lacking. Signed-off-by: Peter Rosin <peda@axentia.se> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/pcm512x.c')
-rw-r--r--sound/soc/codecs/pcm512x.c441
1 files changed, 425 insertions, 16 deletions
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 874723c36d65..526e6b30cdde 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -23,6 +23,7 @@
23#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h> 25#include <sound/soc-dapm.h>
26#include <sound/pcm_params.h>
26#include <sound/tlv.h> 27#include <sound/tlv.h>
27 28
28#include "pcm512x.h" 29#include "pcm512x.h"
@@ -39,6 +40,7 @@ struct pcm512x_priv {
39 struct clk *sclk; 40 struct clk *sclk;
40 struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; 41 struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
41 struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; 42 struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
43 int fmt;
42}; 44};
43 45
44/* 46/*
@@ -69,6 +71,7 @@ static const struct reg_default pcm512x_reg_defaults[] = {
69 { PCM512x_MUTE, 0x00 }, 71 { PCM512x_MUTE, 0x00 },
70 { PCM512x_DSP, 0x00 }, 72 { PCM512x_DSP, 0x00 },
71 { PCM512x_PLL_REF, 0x00 }, 73 { PCM512x_PLL_REF, 0x00 },
74 { PCM512x_DAC_REF, 0x00 },
72 { PCM512x_DAC_ROUTING, 0x11 }, 75 { PCM512x_DAC_ROUTING, 0x11 },
73 { PCM512x_DSP_PROGRAM, 0x01 }, 76 { PCM512x_DSP_PROGRAM, 0x01 },
74 { PCM512x_CLKDET, 0x00 }, 77 { PCM512x_CLKDET, 0x00 },
@@ -87,6 +90,18 @@ static const struct reg_default pcm512x_reg_defaults[] = {
87 { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, 90 { PCM512x_ANALOG_GAIN_BOOST, 0x00 },
88 { PCM512x_VCOM_CTRL_1, 0x00 }, 91 { PCM512x_VCOM_CTRL_1, 0x00 },
89 { PCM512x_VCOM_CTRL_2, 0x01 }, 92 { PCM512x_VCOM_CTRL_2, 0x01 },
93 { PCM512x_BCLK_LRCLK_CFG, 0x00 },
94 { PCM512x_MASTER_MODE, 0x7c },
95 { PCM512x_SYNCHRONIZE, 0x10 },
96 { PCM512x_DSP_CLKDIV, 0x00 },
97 { PCM512x_DAC_CLKDIV, 0x00 },
98 { PCM512x_NCP_CLKDIV, 0x00 },
99 { PCM512x_OSR_CLKDIV, 0x00 },
100 { PCM512x_MASTER_CLKDIV_1, 0x00 },
101 { PCM512x_MASTER_CLKDIV_2, 0x00 },
102 { PCM512x_FS_SPEED_MODE, 0x00 },
103 { PCM512x_IDAC_1, 0x01 },
104 { PCM512x_IDAC_2, 0x00 },
90}; 105};
91 106
92static bool pcm512x_readable(struct device *dev, unsigned int reg) 107static bool pcm512x_readable(struct device *dev, unsigned int reg)
@@ -103,6 +118,8 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg)
103 case PCM512x_DSP_GPIO_INPUT: 118 case PCM512x_DSP_GPIO_INPUT:
104 case PCM512x_MASTER_MODE: 119 case PCM512x_MASTER_MODE:
105 case PCM512x_PLL_REF: 120 case PCM512x_PLL_REF:
121 case PCM512x_DAC_REF:
122 case PCM512x_SYNCHRONIZE:
106 case PCM512x_PLL_COEFF_0: 123 case PCM512x_PLL_COEFF_0:
107 case PCM512x_PLL_COEFF_1: 124 case PCM512x_PLL_COEFF_1:
108 case PCM512x_PLL_COEFF_2: 125 case PCM512x_PLL_COEFF_2:
@@ -303,6 +320,94 @@ static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
303 { "OUTR", NULL, "DACR" }, 320 { "OUTR", NULL, "DACR" },
304}; 321};
305 322
323static const u32 pcm512x_dai_rates[] = {
324 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
325 88200, 96000, 176400, 192000, 384000,
326};
327
328static const struct snd_pcm_hw_constraint_list constraints_slave = {
329 .count = ARRAY_SIZE(pcm512x_dai_rates),
330 .list = pcm512x_dai_rates,
331};
332
333static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
334 struct snd_soc_dai *dai)
335{
336 struct snd_soc_codec *codec = dai->codec;
337 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
338 struct device *dev = dai->dev;
339 struct snd_pcm_hw_constraint_ratnums *constraints_no_pll;
340 struct snd_ratnum *rats_no_pll;
341
342 if (IS_ERR(pcm512x->sclk)) {
343 dev_err(dev, "Need SCLK for master mode: %ld\n",
344 PTR_ERR(pcm512x->sclk));
345 return PTR_ERR(pcm512x->sclk);
346 }
347
348 constraints_no_pll = devm_kzalloc(dev, sizeof(*constraints_no_pll),
349 GFP_KERNEL);
350 if (!constraints_no_pll)
351 return -ENOMEM;
352 constraints_no_pll->nrats = 1;
353 rats_no_pll = devm_kzalloc(dev, sizeof(*rats_no_pll), GFP_KERNEL);
354 if (!rats_no_pll)
355 return -ENOMEM;
356 constraints_no_pll->rats = rats_no_pll;
357 rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64;
358 rats_no_pll->den_min = 1;
359 rats_no_pll->den_max = 128;
360 rats_no_pll->den_step = 1;
361
362 return snd_pcm_hw_constraint_ratnums(substream->runtime, 0,
363 SNDRV_PCM_HW_PARAM_RATE,
364 constraints_no_pll);
365}
366
367static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream,
368 struct snd_soc_dai *dai)
369{
370 struct snd_soc_codec *codec = dai->codec;
371 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
372 struct device *dev = dai->dev;
373 struct regmap *regmap = pcm512x->regmap;
374
375 if (IS_ERR(pcm512x->sclk)) {
376 dev_info(dev, "No SCLK, using BCLK: %ld\n",
377 PTR_ERR(pcm512x->sclk));
378
379 /* Disable reporting of missing SCLK as an error */
380 regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
381 PCM512x_IDCH, PCM512x_IDCH);
382
383 /* Switch PLL input to BCLK */
384 regmap_update_bits(regmap, PCM512x_PLL_REF,
385 PCM512x_SREF, PCM512x_SREF_BCK);
386 }
387
388 return snd_pcm_hw_constraint_list(substream->runtime, 0,
389 SNDRV_PCM_HW_PARAM_RATE,
390 &constraints_slave);
391}
392
393static int pcm512x_dai_startup(struct snd_pcm_substream *substream,
394 struct snd_soc_dai *dai)
395{
396 struct snd_soc_codec *codec = dai->codec;
397 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
398
399 switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
400 case SND_SOC_DAIFMT_CBM_CFM:
401 return pcm512x_dai_startup_master(substream, dai);
402
403 case SND_SOC_DAIFMT_CBS_CFS:
404 return pcm512x_dai_startup_slave(substream, dai);
405
406 default:
407 return -EINVAL;
408 }
409}
410
306static int pcm512x_set_bias_level(struct snd_soc_codec *codec, 411static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
307 enum snd_soc_bias_level level) 412 enum snd_soc_bias_level level)
308{ 413{
@@ -340,17 +445,333 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
340 return 0; 445 return 0;
341} 446}
342 447
448static int pcm512x_set_dividers(struct snd_soc_dai *dai,
449 struct snd_pcm_hw_params *params)
450{
451 struct device *dev = dai->dev;
452 struct snd_soc_codec *codec = dai->codec;
453 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
454 unsigned long sck_rate;
455 unsigned long mck_rate;
456 unsigned long bclk_rate;
457 unsigned long sample_rate;
458 unsigned long osr_rate;
459 int bclk_div;
460 int lrclk_div;
461 int dsp_div;
462 int dac_div;
463 unsigned long dac_rate;
464 int ncp_div;
465 int osr_div;
466 unsigned long dac_mul;
467 unsigned long sck_mul;
468 int ret;
469 int idac;
470 int fssp;
471
472 lrclk_div = snd_soc_params_to_frame_size(params);
473 if (lrclk_div == 0) {
474 dev_err(dev, "No LRCLK?\n");
475 return -EINVAL;
476 }
477
478 sck_rate = clk_get_rate(pcm512x->sclk);
479 bclk_div = params->rate_den * 64 / lrclk_div;
480 bclk_rate = DIV_ROUND_CLOSEST(sck_rate, bclk_div);
481
482 mck_rate = sck_rate;
483
484 if (bclk_div > 128) {
485 dev_err(dev, "Failed to find BCLK divider\n");
486 return -EINVAL;
487 }
488
489 /* the actual rate */
490 sample_rate = sck_rate / bclk_div / lrclk_div;
491 osr_rate = 16 * sample_rate;
492
493 /* run DSP no faster than 50 MHz */
494 dsp_div = mck_rate > 50000000 ? 2 : 1;
495
496 /* run DAC no faster than 6144000 Hz */
497 dac_mul = 6144000 / osr_rate;
498 sck_mul = sck_rate / osr_rate;
499 for (; dac_mul; dac_mul--) {
500 if (!(sck_mul % dac_mul))
501 break;
502 }
503 if (!dac_mul) {
504 dev_err(dev, "Failed to find DAC rate\n");
505 return -EINVAL;
506 }
507
508 dac_rate = dac_mul * osr_rate;
509 dev_dbg(dev, "dac_rate %lu sample_rate %lu\n", dac_rate, sample_rate);
510
511 dac_div = DIV_ROUND_CLOSEST(sck_rate, dac_rate);
512 if (dac_div > 128) {
513 dev_err(dev, "Failed to find DAC divider\n");
514 return -EINVAL;
515 }
516
517 ncp_div = DIV_ROUND_CLOSEST(sck_rate / dac_div, 1536000);
518 if (ncp_div > 128 || sck_rate / dac_div / ncp_div > 2048000) {
519 /* run NCP no faster than 2048000 Hz, but why? */
520 ncp_div = DIV_ROUND_UP(sck_rate / dac_div, 2048000);
521 if (ncp_div > 128) {
522 dev_err(dev, "Failed to find NCP divider\n");
523 return -EINVAL;
524 }
525 }
526
527 osr_div = DIV_ROUND_CLOSEST(dac_rate, osr_rate);
528 if (osr_div > 128) {
529 dev_err(dev, "Failed to find OSR divider\n");
530 return -EINVAL;
531 }
532
533 idac = mck_rate / (dsp_div * sample_rate);
534
535 ret = regmap_write(pcm512x->regmap, PCM512x_DSP_CLKDIV, dsp_div - 1);
536 if (ret != 0) {
537 dev_err(dev, "Failed to write DSP divider: %d\n", ret);
538 return ret;
539 }
540
541 ret = regmap_write(pcm512x->regmap, PCM512x_DAC_CLKDIV, dac_div - 1);
542 if (ret != 0) {
543 dev_err(dev, "Failed to write DAC divider: %d\n", ret);
544 return ret;
545 }
546
547 ret = regmap_write(pcm512x->regmap, PCM512x_NCP_CLKDIV, ncp_div - 1);
548 if (ret != 0) {
549 dev_err(dev, "Failed to write NCP divider: %d\n", ret);
550 return ret;
551 }
552
553 ret = regmap_write(pcm512x->regmap, PCM512x_OSR_CLKDIV, osr_div - 1);
554 if (ret != 0) {
555 dev_err(dev, "Failed to write OSR divider: %d\n", ret);
556 return ret;
557 }
558
559 ret = regmap_write(pcm512x->regmap,
560 PCM512x_MASTER_CLKDIV_1, bclk_div - 1);
561 if (ret != 0) {
562 dev_err(dev, "Failed to write BCLK divider: %d\n", ret);
563 return ret;
564 }
565
566 ret = regmap_write(pcm512x->regmap,
567 PCM512x_MASTER_CLKDIV_2, lrclk_div - 1);
568 if (ret != 0) {
569 dev_err(dev, "Failed to write LRCLK divider: %d\n", ret);
570 return ret;
571 }
572
573 ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_1, idac >> 8);
574 if (ret != 0) {
575 dev_err(dev, "Failed to write IDAC msb divider: %d\n", ret);
576 return ret;
577 }
578
579 ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_2, idac & 0xff);
580 if (ret != 0) {
581 dev_err(dev, "Failed to write IDAC lsb divider: %d\n", ret);
582 return ret;
583 }
584
585 if (sample_rate <= 48000)
586 fssp = PCM512x_FSSP_48KHZ;
587 else if (sample_rate <= 96000)
588 fssp = PCM512x_FSSP_96KHZ;
589 else if (sample_rate <= 192000)
590 fssp = PCM512x_FSSP_192KHZ;
591 else
592 fssp = PCM512x_FSSP_384KHZ;
593 ret = regmap_update_bits(pcm512x->regmap, PCM512x_FS_SPEED_MODE,
594 PCM512x_FSSP, fssp);
595 if (ret != 0) {
596 dev_err(codec->dev, "Failed to set fs speed: %d\n", ret);
597 return ret;
598 }
599
600 dev_dbg(codec->dev, "DSP divider %d\n", dsp_div);
601 dev_dbg(codec->dev, "DAC divider %d\n", dac_div);
602 dev_dbg(codec->dev, "NCP divider %d\n", ncp_div);
603 dev_dbg(codec->dev, "OSR divider %d\n", osr_div);
604 dev_dbg(codec->dev, "BCK divider %d\n", bclk_div);
605 dev_dbg(codec->dev, "LRCK divider %d\n", lrclk_div);
606 dev_dbg(codec->dev, "IDAC %d\n", idac);
607 dev_dbg(codec->dev, "1<<FSSP %d\n", 1 << fssp);
608
609 return 0;
610}
611
612static int pcm512x_hw_params(struct snd_pcm_substream *substream,
613 struct snd_pcm_hw_params *params,
614 struct snd_soc_dai *dai)
615{
616 struct snd_soc_codec *codec = dai->codec;
617 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
618 int alen;
619 int ret;
620
621 dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
622 params_rate(params),
623 params_channels(params));
624
625 switch (snd_pcm_format_width(params_format(params))) {
626 case 16:
627 alen = PCM512x_ALEN_16;
628 break;
629 case 20:
630 alen = PCM512x_ALEN_20;
631 break;
632 case 24:
633 alen = PCM512x_ALEN_24;
634 break;
635 case 32:
636 alen = PCM512x_ALEN_32;
637 break;
638 default:
639 dev_err(codec->dev, "Bad frame size: %d\n",
640 snd_pcm_format_width(params_format(params)));
641 return -EINVAL;
642 }
643
644 switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
645 case SND_SOC_DAIFMT_CBS_CFS:
646 ret = regmap_update_bits(pcm512x->regmap,
647 PCM512x_BCLK_LRCLK_CFG,
648 PCM512x_BCKP
649 | PCM512x_BCKO | PCM512x_LRKO,
650 0);
651 if (ret != 0) {
652 dev_err(codec->dev,
653 "Failed to enable slave mode: %d\n", ret);
654 return ret;
655 }
656
657 ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
658 PCM512x_DCAS, 0);
659 if (ret != 0) {
660 dev_err(codec->dev,
661 "Failed to enable clock divider autoset: %d\n",
662 ret);
663 return ret;
664 }
665 return 0;
666 case SND_SOC_DAIFMT_CBM_CFM:
667 break;
668 default:
669 return -EINVAL;
670 }
671
672 ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1,
673 PCM512x_ALEN, alen);
674 if (ret != 0) {
675 dev_err(codec->dev, "Failed to set frame size: %d\n", ret);
676 return ret;
677 }
678
679 ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
680 PCM512x_IDFS | PCM512x_IDBK
681 | PCM512x_IDSK | PCM512x_IDCH
682 | PCM512x_IDCM | PCM512x_DCAS
683 | PCM512x_IPLK,
684 PCM512x_IDFS | PCM512x_IDBK
685 | PCM512x_IDSK | PCM512x_IDCH
686 | PCM512x_DCAS | PCM512x_IPLK);
687 if (ret != 0) {
688 dev_err(codec->dev,
689 "Failed to ignore auto-clock failures: %d\n",
690 ret);
691 return ret;
692 }
693
694 ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
695 PCM512x_PLLE, 0);
696 if (ret != 0) {
697 dev_err(codec->dev, "Failed to disable pll: %d\n", ret);
698 return ret;
699 }
700
701 ret = pcm512x_set_dividers(dai, params);
702 if (ret != 0)
703 return ret;
704
705 ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
706 PCM512x_SDAC, PCM512x_SDAC_SCK);
707 if (ret != 0) {
708 dev_err(codec->dev, "Failed to set sck as dacref: %d\n", ret);
709 return ret;
710 }
711
712 ret = regmap_update_bits(pcm512x->regmap, PCM512x_BCLK_LRCLK_CFG,
713 PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO,
714 PCM512x_BCKO | PCM512x_LRKO);
715 if (ret != 0) {
716 dev_err(codec->dev, "Failed to enable clock output: %d\n", ret);
717 return ret;
718 }
719
720 ret = regmap_update_bits(pcm512x->regmap, PCM512x_MASTER_MODE,
721 PCM512x_RLRK | PCM512x_RBCK,
722 PCM512x_RLRK | PCM512x_RBCK);
723 if (ret != 0) {
724 dev_err(codec->dev, "Failed to enable master mode: %d\n", ret);
725 return ret;
726 }
727
728 ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
729 PCM512x_RQSY, PCM512x_RQSY_HALT);
730 if (ret != 0) {
731 dev_err(codec->dev, "Failed to halt clocks: %d\n", ret);
732 return ret;
733 }
734
735 ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
736 PCM512x_RQSY, PCM512x_RQSY_RESUME);
737 if (ret != 0) {
738 dev_err(codec->dev, "Failed to resume clocks: %d\n", ret);
739 return ret;
740 }
741
742 return 0;
743}
744
745static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
746{
747 struct snd_soc_codec *codec = dai->codec;
748 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
749
750 pcm512x->fmt = fmt;
751
752 return 0;
753}
754
755static const struct snd_soc_dai_ops pcm512x_dai_ops = {
756 .startup = pcm512x_dai_startup,
757 .hw_params = pcm512x_hw_params,
758 .set_fmt = pcm512x_set_fmt,
759};
760
343static struct snd_soc_dai_driver pcm512x_dai = { 761static struct snd_soc_dai_driver pcm512x_dai = {
344 .name = "pcm512x-hifi", 762 .name = "pcm512x-hifi",
345 .playback = { 763 .playback = {
346 .stream_name = "Playback", 764 .stream_name = "Playback",
347 .channels_min = 2, 765 .channels_min = 2,
348 .channels_max = 2, 766 .channels_max = 2,
349 .rates = SNDRV_PCM_RATE_8000_192000, 767 .rates = SNDRV_PCM_RATE_CONTINUOUS,
768 .rate_min = 8000,
769 .rate_max = 384000,
350 .formats = SNDRV_PCM_FMTBIT_S16_LE | 770 .formats = SNDRV_PCM_FMTBIT_S16_LE |
351 SNDRV_PCM_FMTBIT_S24_LE | 771 SNDRV_PCM_FMTBIT_S24_LE |
352 SNDRV_PCM_FMTBIT_S32_LE 772 SNDRV_PCM_FMTBIT_S32_LE
353 }, 773 },
774 .ops = &pcm512x_dai_ops,
354}; 775};
355 776
356static struct snd_soc_codec_driver pcm512x_codec_driver = { 777static struct snd_soc_codec_driver pcm512x_codec_driver = {
@@ -448,21 +869,9 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
448 } 869 }
449 870
450 pcm512x->sclk = devm_clk_get(dev, NULL); 871 pcm512x->sclk = devm_clk_get(dev, NULL);
451 if (IS_ERR(pcm512x->sclk)) { 872 if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
452 if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) 873 return -EPROBE_DEFER;
453 return -EPROBE_DEFER; 874 if (!IS_ERR(pcm512x->sclk)) {
454
455 dev_info(dev, "No SCLK, using BCLK: %ld\n",
456 PTR_ERR(pcm512x->sclk));
457
458 /* Disable reporting of missing SCLK as an error */
459 regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
460 PCM512x_IDCH, PCM512x_IDCH);
461
462 /* Switch PLL input to BCLK */
463 regmap_update_bits(regmap, PCM512x_PLL_REF,
464 PCM512x_SREF, PCM512x_SREF);
465 } else {
466 ret = clk_prepare_enable(pcm512x->sclk); 875 ret = clk_prepare_enable(pcm512x->sclk);
467 if (ret != 0) { 876 if (ret != 0) {
468 dev_err(dev, "Failed to enable SCLK: %d\n", ret); 877 dev_err(dev, "Failed to enable SCLK: %d\n", ret);