]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00162913-1 ASRC:fix asrc_audio_clock divider set bug
authorChen Liangjun <b36089@freescale.com>
Sat, 31 Dec 2011 03:03:33 +0000 (11:03 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:45 +0000 (08:33 +0200)
The asrc_audio_clock in MX5 is different from MX6.Thus the divider
value set can not be used in the MX6. Part of noise of ASRC output
is caused by this.

Add the function to calculate the divider and prescaler value
according to the sample rate and asrc_audio_clock.

Signed-off-by: Chen Liangjun <b36089@freescale.com>
drivers/mxc/asrc/mxc_asrc.c

index 37528eb90752c02409c53c581cc237dc14c23057..bf36aec4bd3450632fbf2d41c88c9896bfc75464 100644 (file)
@@ -130,12 +130,6 @@ static const unsigned char asrc_process_table[][8][2] = {
        {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},
 };
 
-static const unsigned char asrc_divider_table[] = {
-/*5500Hz 8kHz 11025Hz 16kHz 22050kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176400Hz 192kHz*/
-       0x07, 0x15, 0x06, 0x14, 0x05, 0x13, 0x04, 0x04, 0x12, 0x03, 0x03, 0x02,
-       0x02,
-};
-
 static struct asrc_data *g_asrc_data;
 static struct proc_dir_entry *proc_asrc;
 static unsigned long asrc_vrt_base_addr;
@@ -294,54 +288,29 @@ static int asrc_set_process_configuration(enum asrc_pair_index index,
        return 0;
 }
 
-static int asrc_get_asrck_clock_divider(int sample_rate)
+static int asrc_get_asrck_clock_divider(int samplerate)
 {
-       int i = 0;
-       switch (sample_rate) {
-       case 5500:
-               i = 0;
-               break;
-       case 8000:
-               i = 1;
-               break;
-       case 11025:
-               i = 2;
-               break;
-       case 16000:
-               i = 3;
-               break;
-       case 22050:
-               i = 4;
-               break;
-       case 32000:
-               i = 5;
-               break;
-       case 44100:
-               i = 6;
-               break;
-       case 48000:
-               i = 7;
-               break;
-       case 64000:
-               i = 8;
-               break;
-       case 88200:
-               i = 9;
-               break;
-       case 96000:
-               i = 10;
-               break;
-       case 176400:
-               i = 11;
-               break;
-       case 192000:
-               i = 12;
-               break;
-       default:
-               return -1;
+       unsigned int prescaler, divider;
+       unsigned int i;
+       unsigned int ratio, ra;
+       unsigned long bitclk =  clk_get_rate(mxc_asrc_data->asrc_audio_clk);
+
+       ra = bitclk/samplerate;
+       ratio = ra;
+       /*calculate the prescaler*/
+       i = 0;
+       while (ratio > 8) {
+               i++;
+               ratio = ratio >> 1;
        }
-
-       return asrc_divider_table[i];
+       prescaler = i;
+       /*calculate the divider*/
+       if (i >= 1)
+               divider = ((ra + (1 << (i - 1)) - 1) >> i) - 1;
+       else
+               divider = ra - 1;
+       /*the totally divider is (2^prescaler)*divider*/
+       return (divider << 3) + prescaler;
 }
 
 int asrc_req_pair(int chn_num, enum asrc_pair_index *index)