aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/tlv320aic3x.c225
-rw-r--r--sound/soc/codecs/tlv320aic3x.h4
2 files changed, 95 insertions, 134 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 09b1661b8a3a..738b3b634d74 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -49,7 +49,7 @@
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x" 51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.1" 52#define AIC3X_VERSION "0.2"
53 53
54/* codec private data */ 54/* codec private data */
55struct aic3x_priv { 55struct aic3x_priv {
@@ -648,81 +648,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
648 return 0; 648 return 0;
649} 649}
650 650
651struct aic3x_rate_divs {
652 u32 mclk;
653 u32 rate;
654 u32 fsref_reg;
655 u8 sr_reg:4;
656 u8 pllj_reg;
657 u16 plld_reg;
658};
659
660/* AIC3X codec mclk clock divider coefficients */
661static const struct aic3x_rate_divs aic3x_divs[] = {
662 /* 8k */
663 {12000000, 8000, 48000, 0xa, 16, 3840},
664 {19200000, 8000, 48000, 0xa, 10, 2400},
665 {22579200, 8000, 48000, 0xa, 8, 7075},
666 {33868800, 8000, 48000, 0xa, 5, 8049},
667 /* 11.025k */
668 {12000000, 11025, 44100, 0x6, 15, 528},
669 {19200000, 11025, 44100, 0x6, 9, 4080},
670 {22579200, 11025, 44100, 0x6, 8, 0},
671 {33868800, 11025, 44100, 0x6, 5, 3333},
672 /* 16k */
673 {12000000, 16000, 48000, 0x4, 16, 3840},
674 {19200000, 16000, 48000, 0x4, 10, 2400},
675 {22579200, 16000, 48000, 0x4, 8, 7075},
676 {33868800, 16000, 48000, 0x4, 5, 8049},
677 /* 22.05k */
678 {12000000, 22050, 44100, 0x2, 15, 528},
679 {19200000, 22050, 44100, 0x2, 9, 4080},
680 {22579200, 22050, 44100, 0x2, 8, 0},
681 {33868800, 22050, 44100, 0x2, 5, 3333},
682 /* 32k */
683 {12000000, 32000, 48000, 0x1, 16, 3840},
684 {19200000, 32000, 48000, 0x1, 10, 2400},
685 {22579200, 32000, 48000, 0x1, 8, 7075},
686 {33868800, 32000, 48000, 0x1, 5, 8049},
687 /* 44.1k */
688 {12000000, 44100, 44100, 0x0, 15, 528},
689 {19200000, 44100, 44100, 0x0, 9, 4080},
690 {22579200, 44100, 44100, 0x0, 8, 0},
691 {33868800, 44100, 44100, 0x0, 5, 3333},
692 /* 48k */
693 {12000000, 48000, 48000, 0x0, 16, 3840},
694 {19200000, 48000, 48000, 0x0, 10, 2400},
695 {22579200, 48000, 48000, 0x0, 8, 7075},
696 {33868800, 48000, 48000, 0x0, 5, 8049},
697 /* 64k */
698 {12000000, 64000, 96000, 0x1, 16, 3840},
699 {19200000, 64000, 96000, 0x1, 10, 2400},
700 {22579200, 64000, 96000, 0x1, 8, 7075},
701 {33868800, 64000, 96000, 0x1, 5, 8049},
702 /* 88.2k */
703 {12000000, 88200, 88200, 0x0, 15, 528},
704 {19200000, 88200, 88200, 0x0, 9, 4080},
705 {22579200, 88200, 88200, 0x0, 8, 0},
706 {33868800, 88200, 88200, 0x0, 5, 3333},
707 /* 96k */
708 {12000000, 96000, 96000, 0x0, 16, 3840},
709 {19200000, 96000, 96000, 0x0, 10, 2400},
710 {22579200, 96000, 96000, 0x0, 8, 7075},
711 {33868800, 96000, 96000, 0x0, 5, 8049},
712};
713
714static inline int aic3x_get_divs(int mclk, int rate)
715{
716 int i;
717
718 for (i = 0; i < ARRAY_SIZE(aic3x_divs); i++) {
719 if (aic3x_divs[i].rate == rate && aic3x_divs[i].mclk == mclk)
720 return i;
721 }
722
723 return 0;
724}
725
726static int aic3x_hw_params(struct snd_pcm_substream *substream, 651static int aic3x_hw_params(struct snd_pcm_substream *substream,
727 struct snd_pcm_hw_params *params) 652 struct snd_pcm_hw_params *params)
728{ 653{
@@ -730,49 +655,107 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
730 struct snd_soc_device *socdev = rtd->socdev; 655 struct snd_soc_device *socdev = rtd->socdev;
731 struct snd_soc_codec *codec = socdev->codec; 656 struct snd_soc_codec *codec = socdev->codec;
732 struct aic3x_priv *aic3x = codec->private_data; 657 struct aic3x_priv *aic3x = codec->private_data;
733 int i; 658 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
734 u8 data, pll_p, pll_r, pll_j; 659 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
735 u16 pll_d; 660 u16 pll_d = 1;
736
737 i = aic3x_get_divs(aic3x->sysclk, params_rate(params));
738 661
739 /* Route Left DAC to left channel input and 662 /* select data word length */
740 * right DAC to right channel input */ 663 data =
741 data = (LDAC2LCH | RDAC2RCH); 664 aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
742 switch (aic3x_divs[i].fsref_reg) { 665 switch (params_format(params)) {
743 case 44100: 666 case SNDRV_PCM_FORMAT_S16_LE:
744 data |= FSREF_44100;
745 break; 667 break;
746 case 48000: 668 case SNDRV_PCM_FORMAT_S20_3LE:
747 data |= FSREF_48000; 669 data |= (0x01 << 4);
748 break; 670 break;
749 case 88200: 671 case SNDRV_PCM_FORMAT_S24_LE:
750 data |= FSREF_44100 | DUAL_RATE_MODE; 672 data |= (0x02 << 4);
751 break; 673 break;
752 case 96000: 674 case SNDRV_PCM_FORMAT_S32_LE:
753 data |= FSREF_48000 | DUAL_RATE_MODE; 675 data |= (0x03 << 4);
754 break; 676 break;
755 } 677 }
678 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data);
679
680 /* Fsref can be 44100 or 48000 */
681 fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
682
683 /* Try to find a value for Q which allows us to bypass the PLL and
684 * generate CODEC_CLK directly. */
685 for (pll_q = 2; pll_q < 18; pll_q++)
686 if (aic3x->sysclk / (128 * pll_q) == fsref) {
687 bypass_pll = 1;
688 break;
689 }
690
691 if (bypass_pll) {
692 pll_q &= 0xf;
693 aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
694 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
695 } else
696 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
697
698 /* Route Left DAC to left channel input and
699 * right DAC to right channel input */
700 data = (LDAC2LCH | RDAC2RCH);
701 data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
702 if (params_rate(params) >= 64000)
703 data |= DUAL_RATE_MODE;
756 aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data); 704 aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
757 705
758 /* codec sample rate select */ 706 /* codec sample rate select */
759 data = aic3x_divs[i].sr_reg; 707 data = (fsref * 20) / params_rate(params);
708 if (params_rate(params) < 64000)
709 data /= 2;
710 data /= 5;
711 data -= 2;
760 data |= (data << 4); 712 data |= (data << 4);
761 aic3x_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data); 713 aic3x_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
762 714
763 /* Use PLL for generation Fsref by equation: 715 if (bypass_pll)
764 * Fsref = (MCLK * K * R)/(2048 * P); 716 return 0;
765 * Fix P = 2 and R = 1 and calculate K, if 717
766 * K = J.D, i.e. J - an interger portion of K and D is the fractional 718 /* Use PLL
767 * one with 4 digits of precision; 719 * find an apropriate setup for j, d, r and p by iterating over
768 * Example: 720 * p and r - j and d are calculated for each fraction.
769 * For MCLK = 22.5792 MHz and Fsref = 48kHz: 721 * Up to 128 values are probed, the closest one wins the game.
770 * Select P = 2, R= 1, K = 8.7074, which results in J = 8, D = 7074 722 * The sysclk is divided by 1000 to prevent integer overflows.
771 */ 723 */
772 pll_p = 2; 724 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
773 pll_r = 1; 725
774 pll_j = aic3x_divs[i].pllj_reg; 726 for (r = 1; r <= 16; r++)
775 pll_d = aic3x_divs[i].plld_reg; 727 for (p = 1; p <= 8; p++) {
728 int clk, tmp = (codec_clk * pll_r * 10) / pll_p;
729 u8 j = tmp / 10000;
730 u16 d = tmp % 10000;
731
732 if (j > 63)
733 continue;
734
735 if (d != 0 && aic3x->sysclk < 10000000)
736 continue;
737
738 /* This is actually 1000 * ((j + (d/10000)) * r) / p
739 * The term had to be converted to get rid of the
740 * division by 10000 */
741 clk = ((10000 * j * r) + (d * r)) / (10 * p);
742
743 /* check whether this values get closer than the best
744 * ones we had before */
745 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
746 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
747 last_clk = clk;
748 }
749
750 /* Early exit for exact matches */
751 if (clk == codec_clk)
752 break;
753 }
754
755 if (last_clk == 0) {
756 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
757 return -EINVAL;
758 }
776 759
777 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 760 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
778 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 761 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
@@ -782,24 +765,6 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
782 aic3x_write(codec, AIC3X_PLL_PROGD_REG, 765 aic3x_write(codec, AIC3X_PLL_PROGD_REG,
783 (pll_d & 0x3F) << PLLD_LSB_SHIFT); 766 (pll_d & 0x3F) << PLLD_LSB_SHIFT);
784 767
785 /* select data word length */
786 data =
787 aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
788 switch (params_format(params)) {
789 case SNDRV_PCM_FORMAT_S16_LE:
790 break;
791 case SNDRV_PCM_FORMAT_S20_3LE:
792 data |= (0x01 << 4);
793 break;
794 case SNDRV_PCM_FORMAT_S24_LE:
795 data |= (0x02 << 4);
796 break;
797 case SNDRV_PCM_FORMAT_S32_LE:
798 data |= (0x03 << 4);
799 break;
800 }
801 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data);
802
803 return 0; 768 return 0;
804} 769}
805 770
@@ -826,16 +791,8 @@ static int aic3x_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
826 struct snd_soc_codec *codec = codec_dai->codec; 791 struct snd_soc_codec *codec = codec_dai->codec;
827 struct aic3x_priv *aic3x = codec->private_data; 792 struct aic3x_priv *aic3x = codec->private_data;
828 793
829 switch (freq) { 794 aic3x->sysclk = freq;
830 case 12000000: 795 return 0;
831 case 19200000:
832 case 22579200:
833 case 33868800:
834 aic3x->sysclk = freq;
835 return 0;
836 }
837
838 return -EINVAL;
839} 796}
840 797
841static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, 798static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index d0cdeeb629de..d49d001e6e4c 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -109,6 +109,7 @@
109#define LLOPM_CTRL 86 109#define LLOPM_CTRL 86
110#define RLOPM_CTRL 93 110#define RLOPM_CTRL 93
111/* Clock generation control register */ 111/* Clock generation control register */
112#define AIC3X_GPIOB_REG 101
112#define AIC3X_CLKGEN_CTRL_REG 102 113#define AIC3X_CLKGEN_CTRL_REG 102
113 114
114/* Page select register bits */ 115/* Page select register bits */
@@ -128,12 +129,15 @@
128 129
129/* PLL registers bitfields */ 130/* PLL registers bitfields */
130#define PLLP_SHIFT 0 131#define PLLP_SHIFT 0
132#define PLLQ_SHIFT 3
131#define PLLR_SHIFT 0 133#define PLLR_SHIFT 0
132#define PLLJ_SHIFT 2 134#define PLLJ_SHIFT 2
133#define PLLD_MSB_SHIFT 0 135#define PLLD_MSB_SHIFT 0
134#define PLLD_LSB_SHIFT 2 136#define PLLD_LSB_SHIFT 2
135 137
136/* Clock generation register bits */ 138/* Clock generation register bits */
139#define CODEC_CLKIN_PLLDIV 0
140#define CODEC_CLKIN_CLKDIV 1
137#define PLL_CLKIN_SHIFT 4 141#define PLL_CLKIN_SHIFT 4
138#define MCLK_SOURCE 0x0 142#define MCLK_SOURCE 0x0
139#define PLL_CLKDIV_SHIFT 0 143#define PLL_CLKDIV_SHIFT 0