xpp: init_card_6_3: broadcasts for faster calibration
authorDima Stoliarov <dima@xorcom.com>
Mon, 27 Feb 2017 15:14:57 +0000 (17:14 +0200)
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>
Mon, 26 Jun 2017 14:58:29 +0000 (17:58 +0300)
FXS module type 6: Use broadcast write for a much faster
calibration at init time.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

drivers/dahdi/xpp/init_card_6_30

index cf6f2c5..16857ae 100644 (file)
@@ -276,7 +276,7 @@ sub write_ram($$$$) {
        my $value_1;
        my $value_2;
        my $value_3;
-       my $log_output = sprintf("write_ram: %d, %4d, 0x%08X", $slic, $addr, $value);
+       my $log_output = sprintf("write_ram: %s, %4d, 0x%08X", $slic, $addr, $value);
        main::debug($log_output);
        $value = $value << $bits_shift;
        $addr_low = $addr & 0xFF;
@@ -325,10 +325,15 @@ sub init_early() {
 }
 
 sub load_patch($) {
-       my $slic = shift;
+       my $slics_ref = shift;
+       my @slics = @{ $slics_ref };
+       my $slic;
+
        main::debug "Loading patch based on si3226x_patch_C_TSS_ISO_2014JUN18.c";
-       FXS::set_user_mode($slic, 1);           # Turn on user mode
-       write_reg($slic, 81, 0x00);     # JMPEN, disable the patch
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 1);           # Turn on user mode
+       }
+       write_reg('*', 81, 0x00);       # JMPEN, disable the patch
 
        main::debug "=====Patch data======";
        my @patch_data_array = (
@@ -587,9 +592,9 @@ sub load_patch($) {
                        524293,
                );
 
-       write_ram($slic, 1358, 0x00000000, 3);          # PRAM_ADDR, reset the patch RAM address
+       write_ram('*', 1358, 0x00000000, 3);            # PRAM_ADDR, reset the patch RAM address
        foreach my $val (@patch_data_array) {
-               write_ram($slic, 1359, $val, 12);       # PRAM_DATA, shl 12, addr auto inc
+               write_ram('*', 1359, $val, 12); # PRAM_DATA, shl 12, addr auto inc
        }
 
        main::debug "=====Patch entries======";         # lowest 8 entries are registers
@@ -611,17 +616,17 @@ sub load_patch($) {
        foreach my $val (@patch_entries_array) {
                last if $val == 0;
                if ($jmp_table_low <= 97) {
-                       write_reg($slic, $jmp_table_low, $val & 0xFF);# JMPnLO
+                       write_reg('*', $jmp_table_low, $val & 0xFF);# JMPnLO
                        $jmp_table_low++;
-                       write_reg($slic, $jmp_table_low, $val >> 8  );# JMPnHI
+                       write_reg('*', $jmp_table_low, $val >> 8  );# JMPnHI
                        $jmp_table_low++;
                } else {
-                       write_ram($slic, $jmp_table_high, $val & 0x1FFF, 3);    # shl 3
+                       write_ram('*', $jmp_table_high, $val & 0x1FFF, 3);      # shl 3
                        $jmp_table_high++;
                }
        }
 
-       write_ram($slic, 448, 0x06182014, 3);           # PATCH_ID, shl 3, a unique code which is a hash of the patch.
+       write_ram('*', 448, 0x06182014, 3);             # PATCH_ID, shl 3, a unique code which is a hash of the patch.
 
        main::debug "=====Patch support======";
        my @patch_support_addr_array = (
@@ -669,221 +674,237 @@ sub load_patch($) {
        for (my $i = 0; $i < @patch_support_addr_array; $i++) {
                my $addr = $patch_support_addr_array[$i];
                my $val = $patch_support_data_array[$i];
-               write_ram($slic, $addr, $val, 3);
+               write_ram('*', $addr, $val, 3);
        }
 
        if ($settings{debug}) {
-               main::debug "=====Verify patch=======";
-               my $read_val;
-               write_ram($slic, 1358, 0x00000000, 3);                  # PRAM_ADDR, reset the patch RAM address
-               foreach my $val (@patch_data_array) {
-                       $read_val = read_reg($slic, 1359, 'R', 12);     # PRAM_DATA, shr 12, addr auto inc
-                       if ($val != $read_val) {
-                               printf "0x%X =? 0x%X\n", $val, $read_val;
-                               printf "patch verification failed\n";
-                               exit 0;
-                       }
-               }
-               main::debug "Patch has been verified!";
-
-               main::debug "=====Verify patch entries=======";
-               $jmp_table_low = 82;
-               $jmp_table_high = 1597;
-               foreach my $val (@patch_entries_array) {
-                       last if $val == 0;
-                       if ($jmp_table_low <= 97) {
-                               $read_val = read_reg($slic, $jmp_table_low, 'D');# JMPnLO
-                               $jmp_table_low++;
-                               $read_val |= read_reg($slic, $jmp_table_low, 'D') << 8;# JMPnHI
-                               $jmp_table_low++;
-                       } else {
-                               $read_val = read_reg($slic, $jmp_table_high, 'R', 3);   # PRAM_DATA, shr 3
-                               $read_val &= 0x1FFF;
-                               $jmp_table_high++;
+               foreach $slic (@slics) {
+                       main::debug "=====Verify patch=======";
+                       my $read_val;
+                       # PRAM_ADDR, reset the patch RAM address:
+                       write_ram($slic, 1358, 0x00000000, 3);
+                       foreach my $val (@patch_data_array) {
+                               # PRAM_DATA, shr 12, addr auto inc
+                               $read_val = read_reg($slic, 1359, 'R', 12);
+                               if ($val != $read_val) {
+                                       printf "0x%X =? 0x%X\n", $val, $read_val;
+                                       printf "patch verification failed\n";
+                                       exit 0;
+                               }
                        }
-                       if ($val != $read_val) {
-                               printf "0x%X =? 0x%X\n", $val, $read_val;
-                               printf "patch entries verification failed\n";
-                               exit 0;
+                       main::debug "Patch has been verified!";
+
+                       main::debug "=====Verify patch entries=======";
+                       $jmp_table_low = 82;
+                       $jmp_table_high = 1597;
+                       foreach my $val (@patch_entries_array) {
+                               last if $val == 0;
+                               if ($jmp_table_low <= 97) {
+                                       $read_val = read_reg($slic, $jmp_table_low, 'D');# JMPnLO
+                                       $jmp_table_low++;
+                                       $read_val |= read_reg($slic, $jmp_table_low, 'D') << 8;# JMPnHI
+                                       $jmp_table_low++;
+                               } else {
+                                       $read_val = read_reg($slic, $jmp_table_high, 'R', 3);   # PRAM_DATA, shr 3
+                                       $read_val &= 0x1FFF;
+                                       $jmp_table_high++;
+                               }
+                               if ($val != $read_val) {
+                                       printf "0x%X =? 0x%X\n", $val, $read_val;
+                                       printf "patch entries verification failed\n";
+                                       exit 0;
+                               }
                        }
-               }
-               main::debug "Patch entries has been verified!";
-
-               main::debug "=====Verify patch support=======";
-               for (my $i = 0; $i < @patch_support_addr_array; $i++) {
-                       my $addr = $patch_support_addr_array[$i];
-                       my $val = $patch_support_data_array[$i];
-                       $read_val = read_reg($slic, $addr, 'R', 3);
-                       if ($val != $read_val) {
-                               printf "0x%X =? 0x%X\n", $val, $read_val;
-                               printf "Patch support verification failed\n";
-                               exit 0;
+                       main::debug "Patch entries has been verified!";
+
+                       main::debug "=====Verify patch support=======";
+                       for (my $i = 0; $i < @patch_support_addr_array; $i++) {
+                               my $addr = $patch_support_addr_array[$i];
+                               my $val = $patch_support_data_array[$i];
+                               $read_val = read_reg($slic, $addr, 'R', 3);
+                               if ($val != $read_val) {
+                                       printf "0x%X =? 0x%X\n", $val, $read_val;
+                                       printf "Patch support verification failed\n";
+                                       exit 0;
+                               }
                        }
+               main::debug "patch support has been verified!";
                }
-               main::logit "patch support has been verified!";
        }
 
-       write_reg($slic, 81, 0x01);                     # JMPEN, enable the patch
-       write_reg($slic, 05, 0x00);                     # RAM_ADDR_HI, back to normal RAM access
-       FXS::set_user_mode($slic, 0);                   # Turn off user mode
+       write_reg('*', 81, 0x01);                       # JMPEN, enable the patch
+       write_reg('*', 05, 0x00);                       # RAM_ADDR_HI, back to normal RAM access
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 0);                   # Turn off user mode
+       }
 }
 
 sub load_general_params($) {
-       my $slic = shift;
-       FXS::set_user_mode($slic, 1);           # Turn on user mode
-
+       my $slics_ref = shift;
+       my @slics = @{ $slics_ref };
+       my $slic;
 
+       main::debug "Loading patch based on si3226x_patch_C_TSS_ISO_2014JUN18.c";
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 1);           # Turn on user mode
+       }
 
-       write_reg($slic, 47, 0x00);             # ENHANCE
-       write_reg($slic, 80, 0x2F);             # AUTO
+       write_reg('*', 47, 0x00);               # ENHANCE
+       write_reg('*', 80, 0x2F);               # AUTO
 
-       write_ram($slic,  764, 0x0050C480, 3);  #BAT_HYST
+       write_ram('*',  764, 0x0050C480, 3);    #BAT_HYST
        # Ringing parameters 65Vrms 0Vdc 20Hz LPR
        # Loop = 500.0 ft @ 0.044 ohms/ft, REN = 5, Rcpe = 600 ohms
        # Rprot = 30 ohms, Type = LPR, Waveform = SINE
-       write_ram($slic,  637, 0x15E5200E, 3);  #ringing impedance = 100 ohms
-       write_ram($slic,  766, 0xA3D705, 3);    #VBATL_EXPECT 10 V
-       write_ram($slic,  767, 0xA3D705, 3);    #VBATH_EXPECT 10 V
-       write_ram($slic,  768, 0x5ED285F, 3);   #VBATR_EXPECT 92.6 V
-       write_ram($slic,  768, 0xFFF0000, 3);   #PWRSAVE_TIMER
-       write_ram($slic,  916, 0x0F5C28F, 3);   #OFFHOOK_THRESH
-       write_ram($slic,  919, 0x00F00000, 3);  #VBAT_TRACK_MIN
-       write_ram($slic,  920, 0x02000000, 3);  #VBAT_TRACK_MIN_RNG
-       write_ram($slic,  970, 0x00800000, 3);  #THERM_DBI
-
-       write_ram($slic, 1004, 0x00F18900, 3);  #DCDC_VERR
-       write_ram($slic, 1005, 0x0080C480, 3);  #DCDC_VERR_HYST
-       write_ram($slic, 1006, 0x00800000, 3);  #DCDC_OITHRESH_LO
-       write_ram($slic, 1007, 0x01F00000, 3);  #DCDC_OITHRESH_HI
-       write_ram($slic, 1540, 0x00200000, 3);  #PD_UVLO
-       write_ram($slic, 1541, 0x00300000, 3);  #PD_OVLO
-       write_ram($slic, 1542, 0x00200000, 3);  #PD_OCLO
-
-       write_ram($slic, 1545, 0x00C00000, 3);  #DCDC_UVHYST, (94v - 90v -1) / 0.257v = 12
-       write_ram($slic, 1546, 0x03D00000, 3);  #DCDC_UVTHRESH, 94v / 1.543v = 61
-       write_ram($slic, 1547, 0x1200000, 3);   #DCDC_OVTHRESH
-
-       write_ram($slic, 1554, 0x07700000, 3);  #DCDC_UVPOL
-
-       write_ram($slic, 1558, 0x00000000, 3);  #DCDC_VREF_CTRL
-       write_ram($slic, 1560, 0x00200000, 3);  #DCDC_RNGTYPE
-       write_ram($slic, 1585, 0x00300000, 3);  #DCDC_ANA_GAIN
-       write_ram($slic, 1586, 0x00300000, 3);  #DCDC_ANA_TOFF
-       write_ram($slic, 1587, 0x00100000, 3);  #DCDC_ANA_TONMIN
-       write_ram($slic, 1588, 0x00FFC000, 3);  #DCDC_ANA_TONMAX
-       write_ram($slic, 1589, 0x00F00000, 3);  #DCDC_ANA_DSHIFT
-       write_ram($slic, 1590, 0x0FDA4000, 3);  #DCDC_ANA_LPOLY
-
-       write_ram($slic, 759, 0x07FEB800, 3);   # COEF_P_HVIC
-       write_ram($slic, 756, 0x0048D15B, 3);   # P_TH_HVIC
-
-       write_ram($slic, 967, 0x03A2E8BA, 3);   # SCALE_KAUDIO
+       write_ram('*',  637, 0x15E5200E, 3);    #ringing impedance = 100 ohms
+       write_ram('*',  766, 0xA3D705, 3);      #VBATL_EXPECT 10 V
+       write_ram('*',  767, 0xA3D705, 3);      #VBATH_EXPECT 10 V
+       write_ram('*',  768, 0x5ED285F, 3);     #VBATR_EXPECT 92.6 V
+       write_ram('*',  768, 0xFFF0000, 3);     #PWRSAVE_TIMER
+       write_ram('*',  916, 0x0F5C28F, 3);     #OFFHOOK_THRESH
+       write_ram('*',  919, 0x00F00000, 3);    #VBAT_TRACK_MIN
+       write_ram('*',  920, 0x02000000, 3);    #VBAT_TRACK_MIN_RNG
+       write_ram('*',  970, 0x00800000, 3);    #THERM_DBI
+
+       write_ram('*', 1004, 0x00F18900, 3);    #DCDC_VERR
+       write_ram('*', 1005, 0x0080C480, 3);    #DCDC_VERR_HYST
+       write_ram('*', 1006, 0x00800000, 3);    #DCDC_OITHRESH_LO
+       write_ram('*', 1007, 0x01F00000, 3);    #DCDC_OITHRESH_HI
+       write_ram('*', 1540, 0x00200000, 3);    #PD_UVLO
+       write_ram('*', 1541, 0x00300000, 3);    #PD_OVLO
+       write_ram('*', 1542, 0x00200000, 3);    #PD_OCLO
+
+       write_ram('*', 1545, 0x00C00000, 3);    #DCDC_UVHYST, (94v - 90v -1) / 0.257v = 12
+       write_ram('*', 1546, 0x03D00000, 3);    #DCDC_UVTHRESH, 94v / 1.543v = 61
+       write_ram('*', 1547, 0x1200000, 3);     #DCDC_OVTHRESH
+
+       write_ram('*', 1554, 0x07700000, 3);  #DCDC_UVPOL
+
+       write_ram('*', 1558, 0x00000000, 3);    #DCDC_VREF_CTRL
+       write_ram('*', 1560, 0x00200000, 3);    #DCDC_RNGTYPE
+       write_ram('*', 1585, 0x00300000, 3);    #DCDC_ANA_GAIN
+       write_ram('*', 1586, 0x00300000, 3);    #DCDC_ANA_TOFF
+       write_ram('*', 1587, 0x00100000, 3);    #DCDC_ANA_TONMIN
+       write_ram('*', 1588, 0x00FFC000, 3);    #DCDC_ANA_TONMAX
+       write_ram('*', 1589, 0x00F00000, 3);    #DCDC_ANA_DSHIFT
+       write_ram('*', 1590, 0x0FDA4000, 3);    #DCDC_ANA_LPOLY
+
+       write_ram('*', 759, 0x07FEB800, 3);     # COEF_P_HVIC
+       write_ram('*', 756, 0x0048D15B, 3);     # P_TH_HVIC
+
+       write_ram('*', 967, 0x03A2E8BA, 3);     # SCALE_KAUDIO
 
        #             /* GC RAM locations that moved from RevB to RevC */
-       write_ram($slic, 1018, 0x03000000, 3);  # LKG_OFHK_OFFSET
-       write_ram($slic, 1017, 0x05000000, 3);  # LKG_LB_OFFSET
-       write_ram($slic, 1013, 0x02200000, 3);  # VBATH_DELTA
-       write_ram($slic, 1012, 0x03700000, 3);  # UVTHRESH_MAX
-       write_ram($slic, 1011, 0x04F80200, 3);  # UVTHRESH_SCALE
-       write_ram($slic, 1010, 0x00A23000, 3);  # UVTHRESH_BIAS
+       write_ram('*', 1018, 0x03000000, 3);    # LKG_OFHK_OFFSET
+       write_ram('*', 1017, 0x05000000, 3);    # LKG_LB_OFFSET
+       write_ram('*', 1013, 0x02200000, 3);    # VBATH_DELTA
+       write_ram('*', 1012, 0x03700000, 3);    # UVTHRESH_MAX
+       write_ram('*', 1011, 0x04F80200, 3);    # UVTHRESH_SCALE
+       write_ram('*', 1010, 0x00A23000, 3);    # UVTHRESH_BIAS
 
        # /* Hardcoded mods to default settings */
-       write_reg($slic,   98, 0x80);           #PDN
-       write_ram($slic, 626, 0x723F235, 3);    # ROW0_C2
-       write_ram($slic, 627, 0x57A9804, 3);    # ROW1_C2
-       write_ram($slic, 918, 0x36000, 3);      # XTALK_TIMER
-       write_ram($slic, 1616, 0x1100000, 3);   # DCDC_CPUMP_LP_MASK
+       write_reg('*',   98, 0x80);             #PDN
+       write_ram('*', 626, 0x723F235, 3);      # ROW0_C2
+       write_ram('*', 627, 0x57A9804, 3);      # ROW1_C2
+       write_ram('*', 918, 0x36000, 3);        # XTALK_TIMER
+       write_ram('*', 1616, 0x1100000, 3);     # DCDC_CPUMP_LP_MASK
 
        #/* Smart VOV Default Settings - set here in case no ring preset is loaded */
-       write_ram($slic, 973, 0xFFFFFF, 3);     # VOV_DCDC_SLOPE
-       write_ram($slic, 974, 0xA18937, 3);     # VOV_DCDC_OS
-       write_ram($slic, 975, 0xE49BA5, 3);     # VOV_RING_BAT_MAX
+       write_ram('*', 973, 0xFFFFFF, 3);       # VOV_DCDC_SLOPE
+       write_ram('*', 974, 0xA18937, 3);       # VOV_DCDC_OS
+       write_ram('*', 975, 0xE49BA5, 3);       # VOV_RING_BAT_MAX
 
-       write_ram($slic, 516, 0x10038D, 3);     # VDIFFLPF
-       write_ram($slic, 513, 0x4EDDB9, 3);     # ILOOPLPF
-       write_ram($slic, 514, 0x806D6, 3);      # ILONGLPF
-       write_ram($slic, 517, 0x10059F, 3);     # VCMLPF
-       write_ram($slic, 708, 0xF0000, 3);      # CM_SPEEDUP_TIMER
-       write_ram($slic, 709, 0x106240, 3);     # VCM_TH
+       write_ram('*', 516, 0x10038D, 3);       # VDIFFLPF
+       write_ram('*', 513, 0x4EDDB9, 3);       # ILOOPLPF
+       write_ram('*', 514, 0x806D6, 3);        # ILONGLPF
+       write_ram('*', 517, 0x10059F, 3);       # VCMLPF
+       write_ram('*', 708, 0xF0000, 3);        # CM_SPEEDUP_TIMER
+       write_ram('*', 709, 0x106240, 3);       # VCM_TH
 
        # /* Prevent Ref Osc from powering down in PLL Freerun mode (pd_ref_osc) */
-#      write_ram($slic, 709, 0x106240, 3);     # PWRSAVE_CTRL_LO shall be arithmetic here
+#      write_ram('*', 709, 0x106240, 3);       # PWRSAVE_CTRL_LO shall be arithmetic here
 
        # batType == VCM_HYST
-       write_ram($slic, 1565, 0xC00000, 3);    #
-       write_ram($slic,  750, 0x0306280, 3);   #VCM_HYST
-       write_ram($slic,  971, 0x2A00000, 3);   #LPR_SCALE
-       write_ram($slic,  972, 0x061EB80, 3);   #LPR_CM_OS
-       write_ram($slic, 1565, 0x0A00000, 3);   #DCDC_OIMASK
-       write_ram($slic, 1643, 0x000000, 3);    #DCDC_OV_DEBOUNCE
-       write_ram($slic, 1641, 0x0D00000, 3);   #DCDC_UV_DEBOUNCE
-
-       write_ram($slic, 1512, 0x00200000, 3);  # PD_OFFLD_DAC
-       write_ram($slic, 1513, 0x00200000, 3);  # PD_OFFLD_GM
-       write_ram($slic, 1592, 0x0300000, 3);   #DCDC_PD_ANA
-       write_ram($slic,  897, 0x0480CBF, 3);   #P_TH_OFFLOAD
-
-       write_reg($slic,   35, 0x03);           #OFFLOAD
-
-       write_ram($slic, 1553, 0x00000000, 3);  #DCDC_SWDRV_POL
-       write_ram($slic,  860, 0x008B9ACA, 3);  # IRING_LIM (90.000 mA)
-
-       FXS::set_user_mode($slic, 0);           # Turn on user mode
+       write_ram('*', 1565, 0xC00000, 3);      #
+       write_ram('*',  750, 0x0306280, 3);     #VCM_HYST
+       write_ram('*',  971, 0x2A00000, 3);     #LPR_SCALE
+       write_ram('*',  972, 0x061EB80, 3);     #LPR_CM_OS
+       write_ram('*', 1565, 0x0A00000, 3);     #DCDC_OIMASK
+       write_ram('*', 1643, 0x000000, 3);      #DCDC_OV_DEBOUNCE
+       write_ram('*', 1641, 0x0D00000, 3);     #DCDC_UV_DEBOUNCE
+
+       write_ram('*', 1512, 0x00200000, 3);    # PD_OFFLD_DAC
+       write_ram('*', 1513, 0x00200000, 3);    # PD_OFFLD_GM
+       write_ram('*', 1592, 0x0300000, 3);     #DCDC_PD_ANA
+       write_ram('*',  897, 0x0480CBF, 3);     #P_TH_OFFLOAD
+
+       write_reg('*',   35, 0x03);             #OFFLOAD
+
+       write_ram('*', 1553, 0x00000000, 3);    #DCDC_SWDRV_POL
+       write_ram('*',  860, 0x008B9ACA, 3);    # IRING_LIM (90.000 mA)
+
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 0);           # Turn on user mode
+       }
 
 # Loading Coeff before cal to ensure accurate zsynth results in OHT
 # This set of coefficients are for the following input parameters:
 # Device = Si3217x, R1 = 600, R2 = 0, C = 0, R_surge = 20, R_fuse = 24, 10.txt
 # Generated on 9/30/2009 2:51:17 PM
        # TXACEQ
-       write_ram($slic,  540, 0x07F55480, 3);  #TXACEQ_CO
-       write_ram($slic,  541, 0x000D6400, 3);  #TXACEQ_C1
-       write_ram($slic,  542, 0x00011A00, 3);  #TXACEQ_C2
-       write_ram($slic,  543, 0x1FFD7F00, 3);  #TXACEQ_C3
+       write_ram('*',  540, 0x07F55480, 3);    #TXACEQ_CO
+       write_ram('*',  541, 0x000D6400, 3);    #TXACEQ_C1
+       write_ram('*',  542, 0x00011A00, 3);    #TXACEQ_C2
+       write_ram('*',  543, 0x1FFD7F00, 3);    #TXACEQ_C3
 
        # RXACEQ
-       write_ram($slic,  546, 0x07F04900, 3);  #RXACEQ_CO
-       write_ram($slic,  547, 0x00126A00, 3);  #RXACEQ_C1
-       write_ram($slic,  548, 0x1FFE1D00, 3);  #RXACEQ_C2
-       write_ram($slic,  549, 0x1FFC9480, 3);  #RXACEQ_C3
+       write_ram('*',  546, 0x07F04900, 3);    #RXACEQ_CO
+       write_ram('*',  547, 0x00126A00, 3);    #RXACEQ_C1
+       write_ram('*',  548, 0x1FFE1D00, 3);    #RXACEQ_C2
+       write_ram('*',  549, 0x1FFC9480, 3);    #RXACEQ_C3
 
        # ECFIR/ECIIR
-       write_ram($slic,  563, 0x0012A580, 3);  #ECFIR_C2
-       write_ram($slic,  564, 0x1FE59900, 3);  #ECFIR_C3
-       write_ram($slic,  565, 0x01BCB180, 3);  #ECFIR_C4
-       write_ram($slic,  566, 0x00790780, 3);  #ECFIR_C5
-       write_ram($slic,  567, 0x02113380, 3);  #ECFIR_C6
-       write_ram($slic,  568, 0x1F172380, 3);  #ECFIR_C7
-       write_ram($slic,  569, 0x00805080, 3);  #ECFIR_C8
-       write_ram($slic,  570, 0x1FD6E600, 3);  #ECFIR_C9
-       write_ram($slic,  571, 0x1FFDF800, 3);  #ECIIR_B0
-       write_ram($slic,  572, 0x00010980, 3);  #ECIIR_B1
-       write_ram($slic,  573, 0x0E46D280, 3);  #ECIIR_A1
-       write_ram($slic,  574, 0x19B4F900, 3);  #ECIIR_A2
+       write_ram('*',  563, 0x0012A580, 3);    #ECFIR_C2
+       write_ram('*',  564, 0x1FE59900, 3);    #ECFIR_C3
+       write_ram('*',  565, 0x01BCB180, 3);    #ECFIR_C4
+       write_ram('*',  566, 0x00790780, 3);    #ECFIR_C5
+       write_ram('*',  567, 0x02113380, 3);    #ECFIR_C6
+       write_ram('*',  568, 0x1F172380, 3);    #ECFIR_C7
+       write_ram('*',  569, 0x00805080, 3);    #ECFIR_C8
+       write_ram('*',  570, 0x1FD6E600, 3);    #ECFIR_C9
+       write_ram('*',  571, 0x1FFDF800, 3);    #ECIIR_B0
+       write_ram('*',  572, 0x00010980, 3);    #ECIIR_B1
+       write_ram('*',  573, 0x0E46D280, 3);    #ECIIR_A1
+       write_ram('*',  574, 0x19B4F900, 3);    #ECIIR_A2
 
        # ZSYNTH
-       write_ram($slic,  653, 0x007A8C00, 3);  #ZSYNTH_B0
-       write_ram($slic,  654, 0x1F0BB880, 3);  #ZSYNTH_B1
-       write_ram($slic,  655, 0x0079BD00, 3);  #ZSYNTH_B2
-       write_ram($slic,  656, 0x0FF66D00, 3);  #ZSYNTH_A1
-       write_ram($slic,  657, 0x18099080, 3);  #ZSYNTH_A2
+       write_ram('*',  653, 0x007A8C00, 3);    #ZSYNTH_B0
+       write_ram('*',  654, 0x1F0BB880, 3);    #ZSYNTH_B1
+       write_ram('*',  655, 0x0079BD00, 3);    #ZSYNTH_B2
+       write_ram('*',  656, 0x0FF66D00, 3);    #ZSYNTH_A1
+       write_ram('*',  657, 0x18099080, 3);    #ZSYNTH_A2
 
-       write_reg($slic,   45, 0x59);           #RA
+       write_reg('*',   45, 0x59);             #RA
 
        # TXGAIN/RXGAIN
-       write_ram($slic,  544, 0x08769A80, 3);  #TXACGAIN
-       write_ram($slic,  545, 0x0141E080, 3);  #RXACGAIN
-       write_ram($slic,  906, 0x0141E080, 3);  #RXACGAIN_SAVE
+       write_ram('*',  544, 0x08769A80, 3);    #TXACGAIN
+       write_ram('*',  545, 0x0141E080, 3);    #RXACGAIN
+       write_ram('*',  906, 0x0141E080, 3);    #RXACGAIN_SAVE
 
        # RXACHPF
-       write_ram($slic,  658, 0x07AC0400, 3);  #RXACHPF_B0_1
-       write_ram($slic,  659, 0x1853FC80, 3);  #RXACHPF_B1_1
-       write_ram($slic,  660, 0x07580880, 3);  #RXACHPF_A1_1
+       write_ram('*',  658, 0x07AC0400, 3);    #RXACHPF_B0_1
+       write_ram('*',  659, 0x1853FC80, 3);    #RXACHPF_B1_1
+       write_ram('*',  660, 0x07580880, 3);    #RXACHPF_A1_1
 
-       write_ram($slic,  666, 0x8000000, 3);   #RXACHPF_GAIN
+       write_ram('*',  666, 0x8000000, 3);     #RXACHPF_GAIN
 
-       FXS::set_user_mode($slic, 1);           # Turn on user mode
-       write_reg($slic, 98, 0x80);                     # Power up MADC
-       FXS::set_user_mode($slic, 0);           # Turn off user mode
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 1);           # Turn on user mode
+       }
+       write_reg('*', 98, 0x80);                       # Power up MADC
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 0);                   # Turn off user mode
+       }
 }
 
 sub calibrate_slics($$$$) {
@@ -976,86 +997,99 @@ sub check_slics() {
 }
 
 sub load_custom_preset($) {
-       my $slic = shift;
-       FXS::set_user_mode($slic, 1);           # Turn on user mode
-       write_ram($slic,  755, 0x00050000, 3);  #RTPER
-       write_ram($slic,  844, 0x7EFE000, 3);   #RINGFR = 20Hz
-       write_ram($slic,  845, 0x00208847, 3);  #RINGAMP = 53 Vrms open circuit with 100ohm ring impedance
-       write_ram($slic,  846, 0x00000000, 3);  #RINGPHAS
-       write_ram($slic,  843, 0x00000000, 3);  #RINGOF
-       write_ram($slic,  637, 0x15E5200E, 3);  #SLOPE_RING (100.000 ohms)
-       write_ram($slic,  848, 0x007B9068, 3);  #RTACTH (68.236 mA)
-       write_ram($slic,  847, 0x0FFFFFFF, 3);  #RTDCTH (450.000 mA) */
-       write_ram($slic,  850, 0x00006000, 3);  #RTACDB (75.000 ms)
-       write_ram($slic,  849, 0x00006000, 3);  #RTDCDB (75.000 ms)
-       write_ram($slic,  753, 0x00C49BA0, 3);  # VOV_RING_BAT (12.000 v)
-       write_ram($slic,  896, 0x00000000, 3);  # VOV_RING_GND (0.000 v)
-       write_ram($slic,  975, 0xE49BA5, 3);#vov_ring_bat_max = ~14V
-
-       write_reg($slic,   39, 0x80);           #RINGTALO
-       write_reg($slic,   40, 0x3E);           #RINGTAHI
-       write_reg($slic,   41, 0x00);           #RINGTILO
-       write_reg($slic,   42, 0x7D);           #RINGTIHI
-       write_reg($slic,   38, 0x80);           #RINGCON Both timers are disabled; enable LPR
-       write_ram($slic,  483, 0x28C000, 3);#delta_vcm: This means ring side needs 2v extra.
-       write_ram($slic,  973, 0xFFFFFF, 3);# slope_vov_dcdc
-       write_ram($slic,  974, 0xA18937, 3);# vov_dcdc_os = ~10v
-       write_ram($slic,  509, 0x00C49BA0, 3);# VOV_RING_BAT (12.000 v)
-       write_ram($slic,  975, 0xE49BA5, 3);#vov_ring_bat_max = ~14V
-       write_ram($slic,  971, 0x2A00000, 3);# scale for LPR amplitude, full scale 28-bit
-       write_ram($slic,  972, 0x61EB80, 3);# 6v CM offset
-       write_ram($slic,  970, 0x800000, 3);#
+       my $slics_ref = shift;
+       my @slics = @{ $slics_ref };
+       my $slic;
+
+       main::debug "Loading patch based on si3226x_patch_C_TSS_ISO_2014JUN18.c";
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 1);           # Turn on user mode
+       }
+       write_ram('*',  755, 0x00050000, 3);    #RTPER
+       write_ram('*',  844, 0x7EFE000, 3);     #RINGFR = 20Hz
+       write_ram('*',  845, 0x00208847, 3);    #RINGAMP = 53 Vrms open circuit with 100ohm ring impedance
+       write_ram('*',  846, 0x00000000, 3);    #RINGPHAS
+       write_ram('*',  843, 0x00000000, 3);    #RINGOF
+       write_ram('*',  637, 0x15E5200E, 3);    #SLOPE_RING (100.000 ohms)
+       write_ram('*',  848, 0x007B9068, 3);    #RTACTH (68.236 mA)
+       write_ram('*',  847, 0x0FFFFFFF, 3);    #RTDCTH (450.000 mA) */
+       write_ram('*',  850, 0x00006000, 3);    #RTACDB (75.000 ms)
+       write_ram('*',  849, 0x00006000, 3);    #RTDCDB (75.000 ms)
+       write_ram('*',  753, 0x00C49BA0, 3);    # VOV_RING_BAT (12.000 v)
+       write_ram('*',  896, 0x00000000, 3);    # VOV_RING_GND (0.000 v)
+       write_ram('*',  975, 0xE49BA5, 3);#vov_ring_bat_max = ~14V
+
+       write_reg('*',   39, 0x80);             #RINGTALO
+       write_reg('*',   40, 0x3E);             #RINGTAHI
+       write_reg('*',   41, 0x00);             #RINGTILO
+       write_reg('*',   42, 0x7D);             #RINGTIHI
+       write_reg('*',   38, 0x80);             #RINGCON Both timers are disabled; enable LPR
+       write_ram('*',  483, 0x28C000, 3);#delta_vcm: This means ring side needs 2v extra.
+       write_ram('*',  973, 0xFFFFFF, 3);# slope_vov_dcdc
+       write_ram('*',  974, 0xA18937, 3);# vov_dcdc_os = ~10v
+       write_ram('*',  509, 0x00C49BA0, 3);# VOV_RING_BAT (12.000 v)
+       write_ram('*',  975, 0xE49BA5, 3);#vov_ring_bat_max = ~14V
+       write_ram('*',  971, 0x2A00000, 3);# scale for LPR amplitude, full scale 28-bit
+       write_ram('*',  972, 0x61EB80, 3);# 6v CM offset
+       write_ram('*',  970, 0x800000, 3);#
 
 
 # DC_FEED:
-       write_ram($slic, 634, 0x1C8A024C, 3);   # SLOPE_VLIM
-       write_ram($slic, 635, 0x1E3081AA, 3);   # SLOPE_RFEED
-       write_ram($slic, 636, 0x0040A0E0, 3);   # SLOPE_ILIM
-       write_ram($slic, 638, 0x1B27130B, 3);   # SLOPE_DELTA1
-       write_ram($slic, 639, 0x1DD87A3E, 3);   # SLOPE_DELTA2
-#      write_ram($slic, 640, 0x043AA4A6, 3);   # V_VLIM (36.000 v)
-       write_ram($slic, 640, 0x034A1036, 3);   # V_VLIM (28.000 v)
-       write_ram($slic, 641, 0x03A446AC, 3);   # V_RFEED (31.000 v)
-       write_ram($slic, 642, 0x034A0E48, 3);   # V_ILIM  (28.000 v)
-       write_ram($slic, 643, 0x01363429, 3);   # CONST_RFEED (15.000 mA)
-       write_ram($slic, 644, 0x005D0FA6, 3);   # CONST_ILIM = 20 mA
-       write_ram($slic, 645, 0x00222A30, 3);   # I_VLIM = 0.000 mA
-       write_ram($slic, 853, 0x005B0AFB, 3);   # LCRONHK (10.000 mA)
-       write_ram($slic, 852, 0x006D4060, 3);   # LCROFFHK (12.000 mA)
-       write_ram($slic, 701, 0x00008000, 3);   # LCRDBI (5.000 ms)
-       write_ram($slic, 858, 0x0048D595, 3);   # LONGHITH (8.000 mA)
-       write_ram($slic, 859, 0x003FBAE2, 3);   # LONGLOTH (7.000 mA)
-       write_ram($slic, 702, 0x00008000, 3);   # LONGDBI (5.000 ms)
-       write_ram($slic, 854, 0x000F0000, 3);   # LCRMASK (150.000 ms)
-       write_ram($slic, 855, 0x00080000, 3);   # LCRMASK_POLREV (80.000 ms)
-       write_ram($slic, 856, 0x00140000, 3);   # LCRMASK_STATE (200.000 ms)
-       write_ram($slic, 857, 0x00140000, 3);   # LCRMASK_LINECAP (200.000 ms)
-       write_ram($slic, 748, 0x01BA5E35, 3);   # VCM_OH (27.000 v)
-       write_ram($slic, 752, 0x0051EB85, 3);   # VOV_BAT (5.000 v)
-       write_ram($slic, 751, 0x00415F45, 3);   # VOV_GND (3.990 v)
-
-       write_reg($slic, 46, 0x04);     # zcal_en
-       write_reg($slic, 23, 0x10);     # DTMF_EN = 1  Enable Interupts in IRQ2 Register 19
-       write_reg($slic, 24, 0x03);     # P_HVIC_IE = 1, P_THERM_IE = 1  Enable Interupts in IRQ3 Register 20
-
-       write_reg($slic, 66, 0x00);     # USERSTAT
-       write_reg($slic, 71, 0x00);     # DIAG1
-       write_ram($slic, 799, 95 * 1074 * 1000, 3);    #PRAM_VBATH_NEON = -95 V
-       write_ram($slic, 786, 70 * 65536, 3);    #PRAM_LCRMASK_MWI = 70 mSec
+       write_ram('*', 634, 0x1C8A024C, 3);     # SLOPE_VLIM
+       write_ram('*', 635, 0x1E3081AA, 3);     # SLOPE_RFEED
+       write_ram('*', 636, 0x0040A0E0, 3);     # SLOPE_ILIM
+       write_ram('*', 638, 0x1B27130B, 3);     # SLOPE_DELTA1
+       write_ram('*', 639, 0x1DD87A3E, 3);     # SLOPE_DELTA2
+#      write_ram('*', 640, 0x043AA4A6, 3);     # V_VLIM (36.000 v)
+       write_ram('*', 640, 0x034A1036, 3);     # V_VLIM (28.000 v)
+       write_ram('*', 641, 0x03A446AC, 3);     # V_RFEED (31.000 v)
+       write_ram('*', 642, 0x034A0E48, 3);     # V_ILIM  (28.000 v)
+       write_ram('*', 643, 0x01363429, 3);     # CONST_RFEED (15.000 mA)
+       write_ram('*', 644, 0x005D0FA6, 3);     # CONST_ILIM = 20 mA
+       write_ram('*', 645, 0x00222A30, 3);     # I_VLIM = 0.000 mA
+       write_ram('*', 853, 0x005B0AFB, 3);     # LCRONHK (10.000 mA)
+       write_ram('*', 852, 0x006D4060, 3);     # LCROFFHK (12.000 mA)
+       write_ram('*', 701, 0x00008000, 3);     # LCRDBI (5.000 ms)
+       write_ram('*', 858, 0x0048D595, 3);     # LONGHITH (8.000 mA)
+       write_ram('*', 859, 0x003FBAE2, 3);     # LONGLOTH (7.000 mA)
+       write_ram('*', 702, 0x00008000, 3);     # LONGDBI (5.000 ms)
+       write_ram('*', 854, 0x000F0000, 3);     # LCRMASK (150.000 ms)
+       write_ram('*', 855, 0x00080000, 3);     # LCRMASK_POLREV (80.000 ms)
+       write_ram('*', 856, 0x00140000, 3);     # LCRMASK_STATE (200.000 ms)
+       write_ram('*', 857, 0x00140000, 3);     # LCRMASK_LINECAP (200.000 ms)
+       write_ram('*', 748, 0x01BA5E35, 3);     # VCM_OH (27.000 v)
+       write_ram('*', 752, 0x0051EB85, 3);     # VOV_BAT (5.000 v)
+       write_ram('*', 751, 0x00415F45, 3);     # VOV_GND (3.990 v)
+
+       write_reg('*', 46, 0x04);       # zcal_en
+       write_reg('*', 23, 0x10);       # DTMF_EN = 1  Enable Interupts in IRQ2 Register 19
+       write_reg('*', 24, 0x03);       # P_HVIC_IE = 1, P_THERM_IE = 1  Enable Interupts in IRQ3 Register 20
+
+       write_reg('*', 66, 0x00);       # USERSTAT
+       write_reg('*', 71, 0x00);       # DIAG1
+       write_ram('*', 799, 95 * 1074 * 1000, 3);    #PRAM_VBATH_NEON = -95 V
+       write_ram('*', 786, 70 * 65536, 3);    #PRAM_LCRMASK_MWI = 70 mSec
+
+       foreach $slic (@slics) {
+               FXS::set_linefeed($slic, 1);
+       }
+       write_ram('*', 918, 0x36000, 3);
 
-       FXS::set_linefeed($slic, 1);
-       write_ram($slic, 918, 0x36000, 3);
+       foreach $slic (@slics) {
+               FXS::set_user_mode($slic, 1);           # Turn on user mode
+       }
+       write_ram('*', 1018, 0x03000000, 3);    # LKG_OFHK_OFFSET
+       write_ram('*', 1017, 0x05000000, 3);    # LKG_LB_OFFSET
 
-       FXS::set_user_mode($slic, 1);           # Turn on user mode
-       write_ram($slic, 1018, 0x03000000, 3);  # LKG_OFHK_OFFSET
-       write_ram($slic, 1017, 0x05000000, 3);  # LKG_LB_OFFSET
-       if (($slic & 0x01) == 0) {
-               FXS::set_linefeed($slic, 0);
-               write_ram($slic, 1538, 0x00600000, 3);
-       } else {
-               write_ram($slic & 0xFE, 1538, 0x00400000, 3);
+       foreach $slic (@slics) {
+               if (($slic & 0x01) == 0) {
+                       FXS::set_linefeed($slic, 0);
+                       write_ram($slic, 1538, 0x00600000, 3);
+               } else {
+                       write_ram($slic & 0xFE, 1538, 0x00400000, 3);
+               }
+               FXS::set_user_mode($slic, 0);           # Turn off user mode
        }
-       FXS::set_user_mode($slic, 0);           # Turn off user mode
 }
 
 sub configure_pcm($) {
@@ -1090,31 +1124,33 @@ FXS::read_defaults();
 FXS::soft_reset();
 @SlicNums = FXS::check_slics();
 FXS::init_early();
-foreach my $slic (@SlicNums) {
-       FXS::load_patch($slic);
-       FXS::load_general_params($slic);
+FXS::load_patch(\@SlicNums);
+FXS::load_general_params(\@SlicNums);
 
-       if($settings{fxs_skip_calib}) {
-               main::logit "==== WARNING: SKIPPED SLIC CALIBRATION =====";
-       } else {
+if($settings{fxs_skip_calib}) {
+       main::logit "==== WARNING: SKIPPED SLIC CALIBRATION =====";
+} else {
+       foreach my $slic (@SlicNums) {
                FXS::calibrate_slics($slic, 0x00, 0x00, 0x01);
-               main::mysleep(0.060);
+       }
+       main::mysleep(0.060);
+       foreach my $slic (@SlicNums) {
                FXS::dc_powerup($slic);
                FXS::calibrate_slics($slic, 0x00, 0xC0, 0x18); # remaining cals (except mads, lb)
-               main::mysleep(0.700);
+       }
+       main::mysleep(0.700);
+       foreach my $slic (@SlicNums) {
                FXS::set_linefeed($slic, 0);
                FXS::set_linefeed($slic, 1);
-               main::mysleep(0.010);
-               #FXS::calibrate_slics($slic, 0x0F, 0x00, 0x00); #
-               main::mysleep(1.000);
        }
+       main::mysleep(0.010);
+       #FXS::calibrate_slics($slic, 0x0F, 0x00, 0x00); #
+       main::mysleep(1.000);
 
-       FXS::load_custom_preset($slic);
 }
+FXS::load_custom_preset(\@SlicNums);
 foreach my $slic (@SlicNums) {
        FXS::configure_pcm($slic);
-}
-foreach my $slic (@SlicNums) {
        FXS::set_linefeed($slic, 1);
 }