blob: 7b778f5e6ec6431690d2d42cce5b8798c8e30443 [file] [log] [blame]
developere0cea0f2021-12-16 16:08:26 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * SI3218X ProSLIC interface implementation file
4 *
5 * Author(s):
6 * cdp
7 *
8 * Distributed by:
9 * Silicon Laboratories, Inc
10 *
11 * This file contains proprietary information.
12 * No dissemination allowed without prior written permission from
13 * Silicon Laboratories, Inc.
14 *
15 */
16
17#include "../config_inc/si_voice_datatypes.h"
18#include "../inc/si_voice_ctrl.h"
19#include "../inc/si_voice_timer_intf.h"
20#include "../inc/proslic.h"
21#include "../inc/si3218x.h"
22#include "../inc/si3218x_intf.h"
23#include "../inc/si3218x_registers.h"
24#include "../config_inc/proslic_api_config.h"
25
26#define SI3218X_IRING_LIM_MAX 0xA00000L /* 103mA */
27#define SI3218X_REVA 2
28
29#define WriteReg pProslic->deviceId->ctrlInterface->WriteRegister_fptr
30#define ReadReg pProslic->deviceId->ctrlInterface->ReadRegister_fptr
31#define pProHW pProslic->deviceId->ctrlInterface->hCtrl
32#define Reset pProslic->deviceId->ctrlInterface->Reset_fptr
33#define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
34#define pProTimer pProslic->deviceId->ctrlInterface->hTimer
35#define WriteRAM pProslic->deviceId->ctrlInterface->WriteRAM_fptr
36#define ReadRAM pProslic->deviceId->ctrlInterface->ReadRAM_fptr
37#define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
38#define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
39
40#define WriteRegX deviceId->ctrlInterface->WriteRegister_fptr
41#define ReadRegX deviceId->ctrlInterface->ReadRegister_fptr
42#define pProHWX deviceId->ctrlInterface->hCtrl
43#define DelayX deviceId->ctrlInterface->Delay_fptr
44#define pProTimerX deviceId->ctrlInterface->hTimer
45#define ReadRAMX deviceId->ctrlInterface->ReadRAM_fptr
46#define WriteRAMX deviceId->ctrlInterface->WriteRAM_fptr
47
48#define DEVICE_KEY_MIN 0x6E
49#define DEVICE_KEY_MAX 0x77
50
51#ifdef ENABLE_DEBUG
52static const char LOGPRINT_PREFIX[] = "Si3218x: ";
53#endif
54
55/*
56** Externs
57*/
58
59/* General Configuration */
60extern Si3218x_General_Cfg Si3218x_General_Configuration;
61#ifdef SIVOICE_MULTI_BOM_SUPPORT
62extern const proslicPatch SI3218X_PATCH_A;
63extern Si3218x_General_Cfg Si3218x_General_Configuration_MultiBOM[];
64extern int si3218x_genconf_multi_max_preset;
65#else
66extern const proslicPatch SI3218X_PATCH_A_DEFAULT;
67#endif
68
69/* Ringing */
70#ifndef DISABLE_RING_SETUP
71extern Si3218x_Ring_Cfg Si3218x_Ring_Presets[];
72#endif
73
74/* Zsynth */
75#ifndef DISABLE_ZSYNTH_SETUP
76extern Si3218x_Impedance_Cfg Si3218x_Impedance_Presets [];
77#endif
78
79/* Audio Gain Scratch */
80extern Si3218x_audioGain_Cfg Si3218x_audioGain_Presets[];
81
82/* Pulse Metering */
83#ifndef DISABLE_PULSE_SETUP
84extern Si3218x_PulseMeter_Cfg Si3218x_PulseMeter_Presets [];
85#endif
86
87/* PCM */
88#ifndef DISABLE_PCM_SETUP
89extern Si3218x_PCM_Cfg Si3218x_PCM_Presets [];
90#endif
91
92#define SI3218X_RAM_DCDC_DCFF_ENABLE SI3218X_RAM_GENERIC_8
93#define GCONF Si3218x_General_Configuration
94
95/*
96** Constants
97*/
98#define BIT20LSB 1048576L
99#define OITHRESH_OFFS 900L
100#define OITHRESH_SCALE 100L
101#define OVTHRESH_OFFS 71000
102#define OVTHRESH_SCALE 3000L
103#define UVTHRESH_OFFS 4057L
104#define UVTHRESH_SCALE 187L
105#define UVHYST_OFFS 548L
106#define UVHYST_SCALE 47L
107
108/*
109** Local functions are defined first
110*/
111
112/*
113** Function: getChipType
114**
115** Description:
116** Decode ID register to identify chip type
117**
118** Input Parameters:
119** ID register value
120**
121** Return:
122** partNumberType
123*/
124static partNumberType getChipType(uInt8 data)
125{
126 /* For the parts that have a HV variant, we map to the lower voltage version,
127 the actual differences are handled in the constants file
128 */
129
130 const uInt8 partNums[8] =
131 {
132 UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM,
133 SI32184, SI32182, SI32185, SI32183
134 };
135
136 uInt8 partNum = (data & 0x38) >> 3; /* PART_NUM[2:0] = ID[5:3] */
137
138 return partNums[ partNum ];
139}
140
141int Si3218x_GetChipInfo(proslicChanType_ptr pProslic)
142{
143 uInt8 id;
144 id = ReadReg(pProHW, pProslic->channel, PROSLIC_REG_ID);
145
146 pProslic->deviceId->chipRev = id & 0x7;
147 pProslic->deviceId->chipType = getChipType(id);
148
149 if(pProslic->deviceId->chipType == UNSUPPORTED_PART_NUM)
150 {
151#ifdef ENABLE_DEBUG
152 LOGPRINT("%sregister 0 read = 0x%02X\n", LOGPRINT_PREFIX, id);
153#endif
154 return RC_SPI_FAIL;
155 }
156 else
157 {
158 return RC_NONE;
159 }
160}
161
162/*
163** Function: Si3218x_ConverterSetup
164**
165** Description:
166** Program revision specific settings before powering converter
167**
168** Specifically, from general parameters and knowledge that this
169** is Si32188x, setup dcff drive, gate drive polarity, and charge pump.
170**
171** Returns:
172** int (error)
173**
174*/
175int Si3218x_ConverterSetup(proslicChanType_ptr pProslic)
176{
177 ramData inv_off;
178
179 /* Option to add a per-channel inversion for maximum flexibility */
180 if(pProslic->dcdc_polarity_invert)
181 {
182 inv_off = 0x100000L;
183 }
184 else
185 {
186 inv_off = 0x0L;
187 }
188
189 switch(Si3218x_General_Configuration.bom_option)
190 {
191 case BO_DCDC_LCQC_5W:
192 case BO_DCDC_LCCB:
193 case BO_DCDC_LCCB110:
194 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_LIFT_EN,
195 0x0L); /* dcff disabled */
196 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_SWDRV_POL,
197 inv_off); /* non-inverted */
198 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_CPUMP,
199 0x100000L); /* Charge pump on */
200 Delay(pProTimer,20); /* Cpump settle */
201 break;
202
203 case BO_DCDC_BUCK_BOOST:
204 /*
205 ** RevC buck-boost designs are identical to RevB - no gate drive,
206 ** dcff enabled, non-inverting (charge pump off)
207 */
208 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_CPUMP,0x0L);
209 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_SWDRV_POL,inv_off);
210 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_LIFT_EN,
211 0x100000L); /* dcff enabled */
212 break;
213
214 default:
215 return RC_DCDC_SETUP_ERR;
216 }
217
218 return RC_NONE;
219}
220
221/*
222** Function: Si3218x_PowerUpConverter
223**
224** Description:
225** Powers all DC/DC converters sequentially with delay to minimize
226** peak power draw on VDC.
227**
228** Returns:
229** int (error)
230**
231*/
232
233int Si3218x_PowerUpConverter(proslicChanType_ptr pProslic)
234{
235 errorCodeType error = RC_DCDC_SETUP_ERR;
236 int32 vbath,vbat;
237 uInt8 reg = 0;
238 int timer = 0;
239
240
241 if(pProslic->channelType != PROSLIC)
242 {
243 return RC_CHANNEL_TYPE_ERR;
244 }
245
246 /*
247 ** - powerup digital dc/dc w/ OV clamping and shutdown
248 ** - delay
249 ** - verify no short circuits by looking for vbath/2
250 ** - clear dcdc status
251 ** - switch to analog converter with OV clamping only (no shutdown)
252 ** - select analog dcdc and disable pwrsave
253 ** - delay
254 */
255
256 WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,
257 LF_FWD_OHT); /* Force out of pwrsave mode if called in error */
258 WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,
259 LF_OPEN); /* Ensure open line before powering up converter */
260 reg = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
261 WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,
262 reg&0x07); /* Disable powersave mode */
263
264 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
265 0x700000L); /* In case OV or UV previously occurred */
266
267 /*
268 ** Setup converter drive polarity and charge pump enable
269 ** based on bom
270 */
271
272 error = Si3218x_ConverterSetup(pProslic);
273
274 if(error != RC_NONE)
275 {
276 DEBUG_PRINT (pProslic, "%sChannel %d : DCDC initialization failed\n",
277 LOGPRINT_PREFIX, pProslic->channel);
278 return error;
279 }
280
281 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,0x600000L);
282 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_BIAS,0x200000L);
283 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_HVIC,0x200000L);
284 Delay(pProTimer,50);
285
286 vbath = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATH_EXPECT);
287 vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
288 if(vbat & 0x10000000L)
289 {
290 vbat |= 0xF0000000L;
291 }
292 if(vbat < (vbath / 2))
293 {
294 pProslic->channelEnable = 0;
295 error = RC_VBAT_UP_TIMEOUT;
296 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
297 0x300000L); /* shutdown converter */
298 DEBUG_PRINT (pProslic,
299 "%sChannel %d : DCDC Short Circuit Failure - disabling channel\n%sVBAT = %d.%d\n",
300 LOGPRINT_PREFIX, pProslic->channel, LOGPRINT_PREFIX,
301 (int)((vbat/SCALE_V_MADC)/1000),
302 SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
303 return error;
304 }
305 else /* Enable analog converter */
306 {
307 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_STATUS,0L);
308 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,0x400000L);
309 WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,
310 reg); /* Restore ENHANCE */
311 Delay(pProTimer,50);
312 }
313
314 /*
315 ** - monitor vbat vs expected level (VBATH_EXPECT)
316 */
317 vbath = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATH_EXPECT);
318 do
319 {
320 vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
321 if(vbat & 0x10000000L)
322 {
323 vbat |= 0xF0000000L;
324 }
325 Delay(pProTimer,10);
326 }
327 while((vbat < (vbath - COMP_5V))
328 &&(timer++ < SI3218X_TIMEOUT_DCDC_UP)); /* 2 sec timeout */
329
330 DEBUG_PRINT (pProslic, "%sChannel %d : VBAT Up = %d.%d v\n",
331 LOGPRINT_PREFIX,
332 pProslic->channel,(int)((vbat/SCALE_V_MADC)/1000),
333 SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
334 if(timer > SI3218X_TIMEOUT_DCDC_UP)
335 {
336 /* Error handling - shutdown converter, disable channel, set error tag */
337 pProslic->channelEnable = 0;
338 error = RC_VBAT_UP_TIMEOUT;
339 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
340 0x900000L); /* shutdown converter */
341 DEBUG_PRINT (pProslic, "%sChannel %d : DCDC Power up timeout : Status=0x%08X\n",
342 LOGPRINT_PREFIX, pProslic->channel, ReadRAM(pProHW,pProslic->channel,
343 SI3218X_RAM_DCDC_STATUS));
344 }
345
346 return error;
347}
348
349/*
350**
351** PROSLIC INITIALIZATION FUNCTIONS
352**
353*/
354
355/*
356** Function: Si3218x_Init_MultiBOM
357**
358** Description:
359** - probe SPI to establish daisy chain length
360** - load patch
361** - initialize general parameters
362** - calibrate madc
363** - bring up DC/DC converters
364** - calibrate everything except madc & lb
365**
366** Input Parameters:
367** pProslic: pointer to PROSLIC object array
368** fault: error code
369**
370** Return:
371** error code
372*/
373
374#ifdef SIVOICE_MULTI_BOM_SUPPORT
375int Si3218x_Init_MultiBOM (proslicChanType_ptr *pProslic, int size, int preset)
376{
377
378 if(preset < si3218x_genconf_multi_max_preset)
379 {
380 /* Copy selected General Configuration parameters to Std structure */
381 Si3218x_General_Configuration = Si3218x_General_Configuration_MultiBOM[preset];
382 }
383 else
384 {
385 return RC_INVALID_PRESET;
386 }
387 return Si3218x_Init_with_Options(pProslic,size, INIT_NO_OPT);
388}
389#endif
390
391
392/*
393** Function: Si3218x_SelectPatch
394**
395** Select patch based on general parameters
396**
397** Input Parameters:
398** pProslic: pointer to PROSLIC object array
399** fault: error code
400** patch: Pointer to proslicPatch pointer
401**
402** Return:
403** error code
404*/
405int Si3218x_SelectPatch(proslicChanType_ptr pProslic,
406 const proslicPatch **patch)
407{
408
409#ifdef SIVOICE_MULTI_BOM_SUPPORT
410 if(Si3218x_General_Configuration.bom_option == BO_DCDC_LCQC_5W
411 || Si3218x_General_Configuration.bom_option == BO_DCDC_LCCB
412 || Si3218x_General_Configuration.bom_option == BO_DCDC_LCCB110
413 || Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST)
414 {
415 *patch = &(SI3218X_PATCH_A);
416 }
417 else
418 {
419 DEBUG_PRINT(pProslic, "%sChannel %d : Invalid Patch\n", LOGPRINT_PREFIX,
420 pProslic->channel);
421 pProslic->channelEnable = 0;
422 pProslic->error = RC_INVALID_PATCH;
423 return RC_INVALID_PATCH;
424 }
425#else
426 SILABS_UNREFERENCED_PARAMETER(pProslic);
427 *patch = &(SI3218X_PATCH_A_DEFAULT);
428#endif
429
430 return RC_NONE;
431}
432
433/*
434** Function: Si3218x_GenParamUpdate
435**
436** Update general parameters
437**
438** Input Parameters:
439** pProslic: pointer to PROSLIC object array
440** fault: error code
441**
442** Return:
443** error code
444*/
445
446int Si3218x_GenParamUpdate(proslicChanType_ptr pProslic,initSeqType seq)
447{
448 ramData ram_data;
449 uInt8 data;
450
451 switch(seq)
452 {
453 case INIT_SEQ_PRE_CAL:
454 /*
455 ** Force pwrsave off and disable AUTO-tracking - set to user configured state after cal
456 */
457 WriteReg(pProHW, pProslic->channel,SI3218X_REG_ENHANCE,0);
458 WriteReg(pProHW, pProslic->channel,SI3218X_REG_AUTO,0x2F);
459
460 /*
461 ** General Parameter Updates
462 */
463
464 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_P_TH_HVIC,
465 Si3218x_General_Configuration.p_th_hvic);
466 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_COEF_P_HVIC,
467 Si3218x_General_Configuration.coef_p_hvic);
468 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_BAT_HYST,
469 Si3218x_General_Configuration.bat_hyst);
470 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBATH_EXPECT,
471 Si3218x_General_Configuration.vbath_expect);
472 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
473 Si3218x_General_Configuration.vbatr_expect);
474
475 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_TIMER,
476 Si3218x_General_Configuration.pwrsave_timer);
477 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_OFFHOOK_THRESH,
478 Si3218x_General_Configuration.pwrsave_ofhk_thresh);
479 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN,
480 Si3218x_General_Configuration.vbat_track_min);
481 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN_RNG,
482 Si3218x_General_Configuration.vbat_track_min_rng);
483
484 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_THERM_DBI,
485 Si3218x_General_Configuration.therm_dbi);
486 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_DCDC_SLOPE,
487 Si3218x_General_Configuration.vov_dcdc_slope);
488 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_DCDC_OS,
489 Si3218x_General_Configuration.vov_dcdc_os);
490 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_RING_BAT_MAX,
491 Si3218x_General_Configuration.vov_ring_bat_max);
492 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VERR,
493 Si3218x_General_Configuration.dcdc_verr);
494 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VERR_HYST,
495 Si3218x_General_Configuration.dcdc_verr_hyst);
496
497 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_UVLO,
498 Si3218x_General_Configuration.pd_uvlo);
499 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_OVLO,
500 Si3218x_General_Configuration.pd_ovlo);
501 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_OCLO,
502 Si3218x_General_Configuration.pd_oclo);
503 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_SWDRV,
504 Si3218x_General_Configuration.pd_swdrv);
505
506 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVPOL,
507 Si3218x_General_Configuration.dcdc_uvpol);
508
509 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,
510 Si3218x_General_Configuration.dcdc_rngtype);
511
512 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TOFF,
513 Si3218x_General_Configuration.dcdc_ana_toff);
514 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TONMIN,
515 Si3218x_General_Configuration.dcdc_ana_tonmin);
516 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TONMAX,
517 Si3218x_General_Configuration.dcdc_ana_tonmax);
518
519
520 /*
521 ** Hardcoded RAM
522 */
523
524 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OITHRESH_LO,
525 GCONF.i_oithresh_lo);
526 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OITHRESH_HI,
527 GCONF.i_oithresh_hi);
528 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OVTHRESH,GCONF.v_ovthresh);
529
530 ram_data = (GCONF.v_uvthresh > UVTHRESH_OFFS)?(GCONF.v_uvthresh -
531 UVTHRESH_OFFS)/UVTHRESH_SCALE:0L;
532 ram_data *= BIT20LSB;
533 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVTHRESH,ram_data);
534
535 ram_data = (GCONF.v_uvhyst > UVHYST_OFFS)?(GCONF.v_uvhyst -
536 UVHYST_OFFS)/UVHYST_SCALE:0L;
537 ram_data *= BIT20LSB;
538 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVHYST,ram_data);
539
540 /* Set default audio gain based on PM bom */
541 if(Si3218x_General_Configuration.pm_bom == BO_PM_BOM)
542 {
543 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_SCALE_KAUDIO,BOM_KAUDIO_PM);
544 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_AC_ADC_GAIN,BOM_AC_ADC_GAIN_PM);
545 }
546 else
547 {
548 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_SCALE_KAUDIO,BOM_KAUDIO_NO_PM);
549 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_AC_ADC_GAIN,
550 BOM_AC_ADC_GAIN_NO_PM);
551 }
552
553 /*
554 ** Hardcoded changes to default settings
555 */
556 data = ReadReg(pProHW, pProslic->channel,SI3218X_REG_GPIO_CFG1);
557 data &= 0xF9; /* Clear DIR for GPIO 1&2 */
558 data |= 0x60; /* Set ANA mode for GPIO 1&2 */
559 WriteReg(pProHW,pProslic->channel,SI3218X_REG_GPIO_CFG1,
560 data); /* coarse sensors analog mode */
561 WriteReg(pProHW,pProslic->channel,SI3218X_REG_PDN,
562 0x80); /* madc powered in open state */
563 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_1,
564 0x71EB851L); /* Fix HPF corner */
565 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_REF_OSC,
566 0x200000L); /* PLL freerun workaround */
567 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ILOOPLPF,
568 0x4EDDB9L); /* 20pps pulse dialing enhancement */
569 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ILONGLPF,
570 0x806D6L); /* 20pps pulse dialing enhancement */
571 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VDIFFLPF,
572 0x10038DL); /* 20pps pulse dialing enhancement */
573 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VREF_CTRL,0x0L);
574 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCM_TH,0x106240L);
575 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCMLPF,0x10059FL);
576 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_CM_SPEEDUP_TIMER,0x0F0000);
577 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCM_HYST,0x206280L);
578
579 /* Prevent Ref Osc from powering down in PLL Freerun mode (pd_ref_osc) */
580 ram_data = ReadRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_CTRL_LO);
581 WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_CTRL_LO,
582 ram_data&0x07FFFFFFL); /* clear b27 */
583 break;
584
585
586 case INIT_SEQ_POST_CAL:
587 WriteReg(pProHW, pProslic->channel,SI3218X_REG_ENHANCE,
588 Si3218x_General_Configuration.enhance&0x1F);
589 WriteReg(pProHW, pProslic->channel,SI3218X_REG_AUTO,
590 Si3218x_General_Configuration.auto_reg);
591 if(Si3218x_General_Configuration.zcal_en)
592 {
593 WriteReg(pProHW,pProslic->channel, SI3218X_REG_ZCAL_EN, 0x04);
594 }
595 break;
596
597 default:
598 break;
599 }
600 return RC_NONE;
601}
602
603/*
604** Function: Si3218x_Init_with_Options
605**
606** Description:
607** - probe SPI to establish daisy chain length
608** - load patch
609** - initialize general parameters
610** - calibrate madc
611** - bring up DC/DC converters
612** - calibrate everything except madc & lb
613**
614** Input Parameters:
615** pProslic: pointer to PROSLIC object array
616** fault: error code
617**
618** Return:
619** error code
620*/
621
622int Si3218x_Init_with_Options (proslicChanType_ptr *pProslic, int size,
623 initOptionsType init_opt)
624{
625 /*
626 ** This function will initialize the chipRev and chipType members in pProslic
627 ** as well as load the initialization structures.
628 */
629
630 uInt8 data;
631 uInt8 calSetup[] = {0x00, 0x00, 0x01, 0x80}; /* CALR0-CALR3 */
632 int k, device_count;
633 const proslicPatch *patch;
634 uInt8 status;
635
636 LOGPRINT("%s(%d) size = %d init_opt = %d\n", __FUNCTION__, __LINE__, size,
637 init_opt);
638 /*
639 **
640 ** First qualify general parameters by identifying valid device key. This
641 ** will prevent inadvertent use of other device's preset files, which could
642 ** lead to improper initialization and high current states.
643 */
644
645 data = Si3218x_General_Configuration.device_key;
646
647 if((data < DEVICE_KEY_MIN)||(data > DEVICE_KEY_MAX))
648 {
649 pProslic[0]->error = RC_INVALID_GEN_PARAM;
650 return pProslic[0]->error;
651 }
652
653 /* reset error code */
654 for(k = 0; k < size; k++)
655 {
656 pProslic[k]->error = RC_NONE;
657 }
658
659 if( (init_opt == INIT_REINIT) || (init_opt == INIT_SOFTRESET) )
660 {
661 ProSLIC_ReInit_helper(pProslic, size, init_opt, SI3218X_CHAN_PER_DEVICE);
662
663 /* for single channel devices, we need do a full restore.. */
664 if(init_opt == INIT_REINIT)
665 {
666 init_opt = 0;
667 }
668}
669
670 if( init_opt != INIT_REINIT )
671 {
672 if( (SiVoice_IdentifyChannels(pProslic, size, &device_count, NULL) != RC_NONE)
673 ||(device_count == 0) )
674 {
675 DEBUG_PRINT(*pProslic, "%s: failed to detect any ProSLICs\n", LOGPRINT_PREFIX);
676 return RC_SPI_FAIL;
677 }
678
679 /*
680 ** Probe each channel and enable all channels that respond
681 */
682 for (k=0; k<size; k++)
683 {
684 if ((pProslic[k]->channelEnable)
685 &&(pProslic[k]->channelType == PROSLIC))
686 {
687 if ( (ProSLIC_VerifyMasterStat(pProslic[k]) != RC_NONE)
688 || (ProSLIC_VerifyControlInterface(pProslic[k]) != RC_NONE) )
689 {
690 pProslic[k]->channelEnable = 0;
691 pProslic[k]->error = RC_SPI_FAIL;
692 DEBUG_PRINT(*pProslic, "%s: SPI communications or PCLK/FS failure\n", LOGPRINT_PREFIX);
693 return pProslic[k]->error; /* Halt init if SPI fail */
694 }
695 }
696 }
697 } /* init_opt !REINIT */
698
699
700 if( (init_opt != INIT_NO_PATCH_LOAD ) && (init_opt != INIT_REINIT) )
701 {
702 /*
703 ** Load patch (load on every channel since single channel device)
704 */
705 for (k=0; k<size; k++)
706 {
707 if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
708 {
709
710 /* Select Patch*/
711 if (pProslic[k]->deviceId->chipRev == SI3218X_REVA )
712 {
713 status = (uInt8) Si3218x_SelectPatch(pProslic[k],&patch);
714 }
715 else
716 {
717 DEBUG_PRINT(pProslic[k], "%sChannel %d : Unsupported Device Revision (%d)\n",
718 LOGPRINT_PREFIX, pProslic[k]->channel,pProslic[k]->deviceId->chipRev );
719 pProslic[k]->channelEnable = 0;
720 pProslic[k]->error = RC_UNSUPPORTED_DEVICE_REV;
721 return RC_UNSUPPORTED_DEVICE_REV;
722 }
723
724 data = 1; /* Use this as a flag to see if we need to load the patch */
725 /* If the patch doesn't match, we need to do a full init, change settings */
726 if(init_opt == INIT_SOFTRESET)
727 {
728 ramData patchData;
729 patchData = pProslic[k]->ReadRAMX(pProslic[k]->pProHWX, pProslic[k]->channel,
730 PROSLIC_RAM_PATCHID);
731
732 if( patchData == patch->patchSerial)
733 {
734 data = 0;
735 }
736 else
737 {
738 init_opt = INIT_NO_OPT;
739 }
740 } /* SOFTRESET */
741
742 /* Load Patch */
743 if(status == RC_NONE)
744 {
745 if(data == 1)
746 {
747 Si3218x_LoadPatch(pProslic[k],patch);
748#ifndef DISABLE_VERIFY_PATCH
749 /* Optional Patch Verification */
750 data = (uInt8)Si3218x_VerifyPatch(pProslic[k],patch);
751 if (data != RC_NONE)
752 {
753 DEBUG_PRINT(pProslic[k], "%sChannel %d : Patch verification failed (%d)\n",
754 LOGPRINT_PREFIX, k, data);
755 pProslic[k]->channelEnable=0;
756 pProslic[k]->error = RC_PATCH_ERR;
757 return data;
758 }
759#endif
760 }
761 }
762 else
763 {
764 return status;
765 }
766 } /* channel == PROSLIC */
767 } /* for all channles */
768 }/* init_opt - need to reload patch */
769
770 /*
771 ** Load general parameters - includes all BOM dependencies
772 */
773 if(init_opt != INIT_SOFTRESET)
774 {
775 for (k=0; k<size; k++)
776 {
777 if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
778 {
779 Si3218x_GenParamUpdate(pProslic[k],INIT_SEQ_PRE_CAL);
780 }
781
782 pProslic[k]->WriteRAMX(pProslic[k]->pProHWX,pProslic[k]->channel,
783 SI3218X_RAM_IRING_LIM,SI3218X_IRING_LIM_MAX);
784 }
785 }
786
787 if((init_opt != INIT_NO_CAL)
788 && (init_opt != INIT_SOFTRESET)) /* Must recal on single channel devices */
789 {
790 /*
791 ** Calibrate (madc offset)
792 */
793 ProSLIC_Calibrate(pProslic,size,calSetup,TIMEOUT_MADC_CAL);
794 }/* init_opt */
795
796 /*
797 ** Bring up DC/DC converters sequentially to minimize
798 ** peak power demand on VDC
799 */
800 for (k=0; k<size; k++)
801 {
802 if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
803 {
804 pProslic[k]->error = Si3218x_PowerUpConverter(pProslic[k]);
805 }
806 }
807
808 if((init_opt != INIT_NO_CAL) && (init_opt != INIT_SOFTRESET))
809 {
810 /*
811 ** Calibrate remaining cals (except madc, lb)
812 */
813 calSetup[1] = SI3218X_CAL_STD_CALR1;
814 calSetup[2] = SI3218X_CAL_STD_CALR2;
815
816 ProSLIC_Calibrate(pProslic,size,calSetup,TIMEOUT_GEN_CAL);
817 }
818
819 /*
820 ** Apply post calibration general parameters
821 */
822 if(init_opt != INIT_SOFTRESET)
823 {
824 for (k=0; k<size; k++)
825 {
826
827 if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
828 {
829 Si3218x_GenParamUpdate(pProslic[k],INIT_SEQ_POST_CAL);
830 }
831 }
832 }
833
834 /* Restore linefeed state after initialization for REINIT/SOFTRESET */
835 if( (init_opt == INIT_REINIT) || (init_opt == INIT_SOFTRESET) )
836 {
837 for(k = 0; k < size; k++)
838 {
839 pProslic[k]->WriteRegX(pProslic[k]->pProHWX,pProslic[k]->channel,
840 SI3218X_REG_LINEFEED,pProslic[k]->scratch);
841 }
842 }
843
844 /*
845 ** If any channel incurred a non-fatal error, return
846 ** RC_NON_FATAL_INIT_ERR to trigger user to read each channel's
847 ** error status
848 */
849 for (k=0; k<size; k++)
850 {
851 if(pProslic[k]->error != RC_NONE)
852 {
853 return RC_NON_FATAL_INIT_ERR;
854 }
855 }
856
857 return RC_NONE;
858}
859
860/*
861** Function: Si3218x_EnableInterrupts
862**
863** Description:
864** Enables interrupts
865**
866** Input Parameters:
867** pProslic: pointer to PROSLIC channel obj
868**
869** Returns:
870** 0
871*/
872
873int Si3218x_EnableInterrupts (proslicChanType_ptr pProslic)
874{
875 uInt8 i;
876#ifdef GCI_MODE
877 uInt8 data;
878#endif
879 /* Clear pending interrupts first */
880 for(i = SI3218X_REG_IRQ1; i < SI3218X_REG_IRQ4; i++)
881 {
882#ifdef GCI_MODE
883 data = ReadReg(pProHW,pProslic->channel, i);
884 WriteReg(pProHW,pProslic->channel,i,data); /*clear interrupts (gci only)*/
885#else
886 (void)ReadReg(pProHW,pProslic->channel, i);
887#endif
888
889 }
890
891 WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN1,
892 Si3218x_General_Configuration.irqen1);
893 WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN2,
894 Si3218x_General_Configuration.irqen2);
895 WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN3,
896 Si3218x_General_Configuration.irqen3);
897 WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN4,
898 Si3218x_General_Configuration.irqen4);
899
900 return RC_NONE;
901}
902
903/*
904**
905** PROSLIC CONFIGURATION FUNCTIONS
906**
907*/
908
909/*
910** Function: Si3218x_RingSetup
911**
912** Description:
913** configure ringing
914**
915** Input Parameters:
916** pProslic: pointer to PROSLIC channel obj
917** preset: ring preset
918**
919** Returns:
920** 0
921*/
922
923#ifndef DISABLE_RING_SETUP
924int Si3218x_RingSetup (proslicChanType *pProslic, int preset)
925{
926
927 if(pProslic->channelType != PROSLIC)
928 {
929 return RC_CHANNEL_TYPE_ERR;
930 }
931
932 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTPER,
933 Si3218x_Ring_Presets[preset].rtper);
934 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGFR,
935 Si3218x_Ring_Presets[preset].freq);
936 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGAMP,
937 Si3218x_Ring_Presets[preset].amp);
938 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGPHAS,
939 Si3218x_Ring_Presets[preset].phas);
940 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGOF,
941 Si3218x_Ring_Presets[preset].offset);
942 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_RING,
943 Si3218x_Ring_Presets[preset].slope_ring);
944
945 if(Si3218x_Ring_Presets[preset].iring_lim > SI3218X_IRING_LIM_MAX)
946 {
947 Si3218x_Ring_Presets[preset].iring_lim = SI3218X_IRING_LIM_MAX;
948 }
949
950 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_IRING_LIM,
951 Si3218x_Ring_Presets[preset].iring_lim);
952 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTACTH,
953 Si3218x_Ring_Presets[preset].rtacth);
954 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTDCTH,
955 Si3218x_Ring_Presets[preset].rtdcth);
956 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTACDB,
957 Si3218x_Ring_Presets[preset].rtacdb);
958 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTDCDB,
959 Si3218x_Ring_Presets[preset].rtdcdb);
960 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_RING_BAT,
961 Si3218x_Ring_Presets[preset].vov_ring_bat);
962 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_RING_GND,
963 Si3218x_Ring_Presets[preset].vov_ring_gnd);
964
965#ifndef NOCLAMP_VBATR
966 /* Always limit VBATR_EXPECT to the general configuration maximum */
967 if(Si3218x_Ring_Presets[preset].vbatr_expect >
968 Si3218x_General_Configuration.vbatr_expect)
969 {
970 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
971 Si3218x_General_Configuration.vbatr_expect);
972 DEBUG_PRINT(pProslic,
973 "%sRingSetup : VBATR_EXPECT : Clamped to Gen Conf Limit\n",LOGPRINT_PREFIX);
974 }
975 else
976 {
977 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
978 Si3218x_Ring_Presets[preset].vbatr_expect);
979 }
980
981#else
982 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
983 Si3218x_Ring_Presets[preset].vbatr_expect);
984#endif
985
986
987 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTALO,
988 Si3218x_Ring_Presets[preset].talo);
989 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTAHI,
990 Si3218x_Ring_Presets[preset].tahi);
991 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTILO,
992 Si3218x_Ring_Presets[preset].tilo);
993 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTIHI,
994 Si3218x_Ring_Presets[preset].tihi);
995
996 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN_RNG,
997 Si3218x_Ring_Presets[preset].dcdc_vref_min_rng);
998
999 /*
1000 ** LPR Handler
1001 **
1002 ** If USERSTAT == 0x01, adjust RINGCON and clear USERSTAT
1003 */
1004 if (Si3218x_Ring_Presets[preset].userstat == 0x01)
1005 {
1006 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGCON,
1007 (0x80|Si3218x_Ring_Presets[preset].ringcon) & ~(0x40));
1008 WriteReg(pProHW,pProslic->channel,SI3218X_REG_USERSTAT,0x00);
1009 }
1010 else
1011 {
1012 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGCON,
1013 Si3218x_Ring_Presets[preset].ringcon);
1014 WriteReg(pProHW,pProslic->channel,SI3218X_REG_USERSTAT,
1015 Si3218x_Ring_Presets[preset].userstat);
1016 }
1017
1018
1019 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_RING,
1020 Si3218x_Ring_Presets[preset].vcm_ring);
1021 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_RING_FIXED,
1022 Si3218x_Ring_Presets[preset].vcm_ring_fixed);
1023 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DELTA_VCM,
1024 Si3218x_Ring_Presets[preset].delta_vcm);
1025
1026
1027 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,
1028 Si3218x_Ring_Presets[preset].dcdc_rngtype);
1029
1030
1031 /*
1032 ** If multi bom supported **AND** a buck boost converter
1033 ** is being used, force dcdc_rngtype to be fixed.
1034 */
1035#ifdef SIVOICE_MULTI_BOM_SUPPORT
1036#define DCDC_RNGTYPE_BKBT 0L
1037 /* Automatically adjust DCDC_RNGTYPE */
1038 if(Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST)
1039 {
1040 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,DCDC_RNGTYPE_BKBT);
1041 }
1042#endif
1043
1044
1045 return RC_NONE;
1046}
1047#endif
1048
1049/*
1050** Function: PROSLIC_ZsynthSetup
1051**
1052** Description:
1053** configure impedance synthesis
1054*/
1055
1056#ifndef DISABLE_ZSYNTH_SETUP
1057int Si3218x_ZsynthSetup (proslicChanType *pProslic, int preset)
1058{
1059 uInt8 lf;
1060 uInt8 cal_en = 0;
1061 uInt16 timer = 500;
1062
1063 if(pProslic->channelType != PROSLIC)
1064 {
1065 return RC_CHANNEL_TYPE_ERR;
1066 }
1067
1068 lf = ReadReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED);
1069 WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,0);
1070 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
1071 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0);
1072 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
1073 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1);
1074 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
1075 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2);
1076 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
1077 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3);
1078 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
1079 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0);
1080 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
1081 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1);
1082 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
1083 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2);
1084 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
1085 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3);
1086 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C2,
1087 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c2);
1088 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C3,
1089 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c3);
1090 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C4,
1091 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c4);
1092 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C5,
1093 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c5);
1094 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C6,
1095 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c6);
1096 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C7,
1097 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c7);
1098 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C8,
1099 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c8);
1100 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C9,
1101 Si3218x_Impedance_Presets[preset].hybrid.ecfir_c9);
1102 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_B0,
1103 Si3218x_Impedance_Presets[preset].hybrid.ecfir_b0);
1104 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_B1,
1105 Si3218x_Impedance_Presets[preset].hybrid.ecfir_b1);
1106 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_A1,
1107 Si3218x_Impedance_Presets[preset].hybrid.ecfir_a1);
1108 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_A2,
1109 Si3218x_Impedance_Presets[preset].hybrid.ecfir_a2);
1110 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_A1,
1111 Si3218x_Impedance_Presets[preset].zsynth.zsynth_a1);
1112 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_A2,
1113 Si3218x_Impedance_Presets[preset].zsynth.zsynth_a2);
1114 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B1,
1115 Si3218x_Impedance_Presets[preset].zsynth.zsynth_b1);
1116 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B0,
1117 Si3218x_Impedance_Presets[preset].zsynth.zsynth_b0);
1118 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B2,
1119 Si3218x_Impedance_Presets[preset].zsynth.zsynth_b2);
1120 WriteReg(pProHW,pProslic->channel,SI3218X_REG_RA,
1121 Si3218x_Impedance_Presets[preset].zsynth.ra);
1122 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
1123 Si3218x_Impedance_Presets[preset].txgain);
1124 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
1125 Si3218x_Impedance_Presets[preset].rxgain);
1126 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
1127 Si3218x_Impedance_Presets[preset].rxgain);
1128 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_1,
1129 Si3218x_Impedance_Presets[preset].rxachpf_b0_1);
1130 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_1,
1131 Si3218x_Impedance_Presets[preset].rxachpf_b1_1);
1132 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_1,
1133 Si3218x_Impedance_Presets[preset].rxachpf_a1_1);
1134
1135 /*
1136 ** Scale based on desired gain plan
1137 */
1138 Si3218x_dbgSetTXGain(pProslic,Si3218x_Impedance_Presets[preset].txgain_db,
1139 preset,TXACGAIN_SEL);
1140 Si3218x_dbgSetRXGain(pProslic,Si3218x_Impedance_Presets[preset].rxgain_db,
1141 preset,RXACGAIN_SEL);
1142 Si3218x_TXAudioGainSetup(pProslic,TXACGAIN_SEL);
1143 Si3218x_RXAudioGainSetup(pProslic,RXACGAIN_SEL);
1144
1145 /*
1146 ** Perform Zcal in case OHT used (eg. no offhook event to trigger auto Zcal)
1147 */
1148 WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR0,0x00);
1149 WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR1,0x40);
1150 WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR2,0x00);
1151 WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR3,0x80); /* start cal */
1152
1153 /* Wait for zcal to finish */
1154 do
1155 {
1156 cal_en = ReadReg(pProHW,pProslic->channel,SI3218X_REG_CALR3);
1157 Delay(pProTimer,1);
1158 timer--;
1159 }
1160 while((cal_en&0x80)&&(timer>0));
1161
1162 WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,lf);
1163
1164 if(timer > 0)
1165 {
1166 return RC_NONE;
1167 }
1168 else
1169 {
1170 return RC_CAL_TIMEOUT;
1171 }
1172}
1173#endif
1174
1175/*
1176** Function: PROSLIC_AudioGainSetup
1177**
1178** Description:
1179** configure audio gains
1180*/
1181int Si3218x_TXAudioGainSetup (proslicChanType *pProslic, int preset)
1182{
1183
1184 if(pProslic->channelType != PROSLIC)
1185 {
1186 return RC_CHANNEL_TYPE_ERR;
1187 }
1188
1189 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
1190 Si3218x_audioGain_Presets[preset].acgain);
1191 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
1192 Si3218x_audioGain_Presets[preset].aceq_c0);
1193 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
1194 Si3218x_audioGain_Presets[preset].aceq_c1);
1195 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
1196 Si3218x_audioGain_Presets[preset].aceq_c2);
1197 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
1198 Si3218x_audioGain_Presets[preset].aceq_c3);
1199
1200 return RC_NONE;
1201}
1202
1203/*
1204** Function: PROSLIC_AudioGainSetup
1205**
1206** Description:
1207** configure audio gains
1208*/
1209
1210int Si3218x_RXAudioGainSetup (proslicChanType *pProslic, int preset)
1211{
1212
1213 if(pProslic->channelType != PROSLIC)
1214 {
1215 return RC_CHANNEL_TYPE_ERR;
1216 }
1217 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
1218 Si3218x_audioGain_Presets[preset].acgain);
1219 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
1220 Si3218x_audioGain_Presets[preset].acgain);
1221 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
1222 Si3218x_audioGain_Presets[preset].aceq_c0);
1223 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
1224 Si3218x_audioGain_Presets[preset].aceq_c1);
1225 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
1226 Si3218x_audioGain_Presets[preset].aceq_c2);
1227 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
1228 Si3218x_audioGain_Presets[preset].aceq_c3);
1229
1230 return RC_NONE;
1231}
1232
1233
1234/*
1235** Function: PROSLIC_AudioGainScale
1236**
1237** Description:
1238** Multiply path gain by passed value for PGA and EQ scale (no reference to dB,
1239** multiply by a scale factor)
1240*/
1241int Si3218x_AudioGainScale (proslicChanType *pProslic, int preset,
1242 uInt32 pga_scale, uInt32 eq_scale,int rx_tx_sel)
1243{
1244
1245 if(rx_tx_sel == TXACGAIN_SEL)
1246 {
1247 Si3218x_audioGain_Presets[TXACGAIN_SEL].acgain =
1248 (Si3218x_Impedance_Presets[preset].txgain/1000)*pga_scale;
1249 if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0 & 0x10000000L)
1250 {
1251 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0 |= 0xf0000000L;
1252 }
1253 if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1 & 0x10000000L)
1254 {
1255 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1 |= 0xf0000000L;
1256 }
1257 if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2 & 0x10000000L)
1258 {
1259 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2 |= 0xf0000000L;
1260 }
1261 if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3 & 0x10000000L)
1262 {
1263 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3 |= 0xf0000000L;
1264 }
1265 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c0 = ((int32)
1266 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0/1000)*eq_scale;
1267 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c1 = ((int32)
1268 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1/1000)*eq_scale;
1269 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c2 = ((int32)
1270 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2/1000)*eq_scale;
1271 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c3 = ((int32)
1272 Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3/1000)*eq_scale;
1273
1274 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
1275 Si3218x_audioGain_Presets[TXACGAIN_SEL].acgain);
1276 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
1277 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c0);
1278 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
1279 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c1);
1280 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
1281 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c2);
1282 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
1283 Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c3);
1284 }
1285 else
1286 {
1287 Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain =
1288 (Si3218x_Impedance_Presets[preset].rxgain/1000)*pga_scale;
1289 if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0 & 0x10000000L)
1290 {
1291 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
1292 }
1293 if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1 & 0x10000000L)
1294 {
1295 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
1296 }
1297 if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2 & 0x10000000L)
1298 {
1299 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
1300 }
1301 if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3 & 0x10000000L)
1302 {
1303 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
1304 }
1305 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c0 = ((int32)
1306 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0/1000)*eq_scale;
1307 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c1 = ((int32)
1308 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1/1000)*eq_scale;
1309 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c2 = ((int32)
1310 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2/1000)*eq_scale;
1311 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c3 = ((int32)
1312 Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3/1000)*eq_scale;
1313
1314 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
1315 Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain);
1316 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
1317 Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain);
1318 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
1319 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c0);
1320 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
1321 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c1);
1322 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
1323 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c2);
1324 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
1325 Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c3);
1326 }
1327 return 0;
1328}
1329int Si3218x_TXAudioGainScale (proslicChanType *pProslic, int preset,
1330 uInt32 pga_scale, uInt32 eq_scale)
1331{
1332 return Si3218x_AudioGainScale(pProslic,preset,pga_scale,eq_scale,TXACGAIN_SEL);
1333}
1334int Si3218x_RXAudioGainScale (proslicChanType *pProslic, int preset,
1335 uInt32 pga_scale, uInt32 eq_scale)
1336{
1337 return Si3218x_AudioGainScale(pProslic,preset,pga_scale,eq_scale,RXACGAIN_SEL);
1338}
1339
1340
1341/*
1342** Function: PROSLIC_DCFeedSetup
1343**
1344** Description:
1345** configure dc feed
1346*/
1347
1348#ifndef DISABLE_DCFEED_SETUP
1349int Si3218x_DCFeedSetupCfg (proslicChanType *pProslic, Si3218x_DCfeed_Cfg *cfg,
1350 int preset)
1351{
1352 uInt8 lf;
1353
1354 if(pProslic->channelType != PROSLIC)
1355 {
1356 return RC_CHANNEL_TYPE_ERR;
1357 }
1358 lf = ReadReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED);
1359 WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,0);
1360 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_VLIM,
1361 cfg[preset].slope_vlim);
1362 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_RFEED,
1363 cfg[preset].slope_rfeed);
1364 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_ILIM,
1365 cfg[preset].slope_ilim);
1366 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_DELTA1,cfg[preset].delta1);
1367 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_DELTA2,cfg[preset].delta2);
1368 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_VLIM,cfg[preset].v_vlim);
1369 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_RFEED,cfg[preset].v_rfeed);
1370 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_ILIM,cfg[preset].v_ilim);
1371 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_CONST_RFEED,
1372 cfg[preset].const_rfeed);
1373 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_CONST_ILIM,
1374 cfg[preset].const_ilim);
1375 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_I_VLIM,cfg[preset].i_vlim);
1376 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRONHK,cfg[preset].lcronhk);
1377 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCROFFHK,cfg[preset].lcroffhk);
1378 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRDBI,cfg[preset].lcrdbi);
1379 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGHITH,cfg[preset].longhith);
1380 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGLOTH,cfg[preset].longloth);
1381 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGDBI,cfg[preset].longdbi);
1382 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK,cfg[preset].lcrmask);
1383 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_POLREV,
1384 cfg[preset].lcrmask_polrev);
1385 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_STATE,
1386 cfg[preset].lcrmask_state);
1387 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_LINECAP,
1388 cfg[preset].lcrmask_linecap);
1389 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_OH,cfg[preset].vcm_oh);
1390 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_BAT,cfg[preset].vov_bat);
1391 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_GND,cfg[preset].vov_gnd);
1392 WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,lf);
1393
1394 return RC_NONE;
1395}
1396
1397#endif
1398
1399/*
1400** Function: PROSLIC_PulseMeterSetup
1401**
1402** Description:
1403** configure pulse metering
1404*/
1405
1406#ifndef DISABLE_PULSE_SETUP
1407int Si3218x_PulseMeterSetup (proslicChanType *pProslic, int preset)
1408{
1409 uInt8 reg;
1410
1411 if(pProslic->channelType != PROSLIC)
1412 {
1413 return RC_CHANNEL_TYPE_ERR;
1414 }
1415
1416 else
1417 {
1418 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_AMP_THRESH,
1419 Si3218x_PulseMeter_Presets[preset].pm_amp_thresh);
1420 reg = (Si3218x_PulseMeter_Presets[preset].pmFreq<<1)|
1421 (Si3218x_PulseMeter_Presets[preset].pmAuto<<3);
1422 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_ACTIVE,
1423 Si3218x_PulseMeter_Presets[preset].pmActive);
1424 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_INACTIVE,
1425 Si3218x_PulseMeter_Presets[preset].pmInactive);
1426 WriteReg(pProHW,pProslic->channel,SI3218X_REG_PMCON,reg);
1427 return RC_NONE;
1428 }
1429
1430}
1431#endif
1432
1433/*
1434** Function: PROSLIC_PCMSetup
1435**
1436** Description:
1437** configure pcm
1438*/
1439
1440#ifndef DISABLE_PCM_SETUP
1441int Si3218x_PCMSetup(proslicChanType *pProslic, int preset)
1442{
1443 uInt8 regTemp;
1444 uInt8 pmEn;
1445
1446 if(pProslic->channelType != PROSLIC)
1447 {
1448 return RC_CHANNEL_TYPE_ERR;
1449 }
1450
1451 pmEn = ReadReg(pProHW,pProslic->channel,
1452 SI3218X_REG_PMCON) & 0x01; /* PM/wideband lockout */
1453 if (Si3218x_PCM_Presets[preset].widebandEn && pmEn)
1454 {
1455#ifdef ENABLE_DEBUG
1456 LOGPRINT ("%s Wideband Mode is not supported while Pulse Metering is enabled.\n",
1457 LOGPRINT_PREFIX);
1458#endif
1459 }
1460 else if (Si3218x_PCM_Presets[preset].widebandEn && !pmEn)
1461 {
1462 /* TXIIR settings */
1463 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_1,0x3538E80L);
1464 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_1,0x3538E80L);
1465 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_1,0x1AA9100L);
1466 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_2,0x216D100L);
1467 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_2,0x2505400L);
1468 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_2,0x216D100L);
1469 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_2,0x2CB8100L);
1470 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_2,0x1D7FA500L);
1471 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_3,0x2CD9B00L);
1472 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_3,0x1276D00L);
1473 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_3,0x2CD9B00L);
1474 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_3,0x2335300L);
1475 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_3,0x19D5F700L);
1476 /* RXIIR settings */
1477 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_1,0x6A71D00L);
1478 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_1,0x6A71D00L);
1479 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_1,0x1AA9100L);
1480 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_2,0x216D100L);
1481 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_2,0x2505400L);
1482 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_2,0x216D100L);
1483 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_2,0x2CB8100L);
1484 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_2,0x1D7FA500L);
1485 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_3,0x2CD9B00L);
1486 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_3,0x1276D00L);
1487 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_3,0x2CD9B00L);
1488 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_3,0x2335300L);
1489 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_3,0x19D5F700L);
1490 /*
1491 ** RXHPF
1492 ** Note: Calling ProSLIC_ZsynthSetup() will overwrite some
1493 ** of these values. ProSLIC_PCMSetup() should always
1494 ** be called after loading coefficients when using
1495 ** wideband mode
1496 */
1497 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_1,0x7CFF900L);
1498 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_1,0x18300700L);
1499 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_1,0x79FF201L);
1500 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_2,0x7CEDA1DL);
1501 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_2,0x106320D4L);
1502 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B2_2,0x7CEDA1DL);
1503 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_2,0xF9A910FL);
1504 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A2_2,0x185FFDA8L);
1505 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_GAIN,0x08000000L);
1506 /* TXHPF */
1507 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B0_1,0x0C7FF4CEL);
1508 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B1_1,0x13800B32L);
1509 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_1,0x079FF201L);
1510 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B0_2,0x030FDD10L);
1511 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B1_2,0x19E0996CL);
1512 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B2_2,0x030FDD10L);
1513 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_2,0x0F9A910FL);
1514 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A2_2,0x185FFDA8L);
1515 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_GAIN,0x0CD30000L);
1516
1517 regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON);
1518#ifndef DISABLE_HPF_WIDEBAND
1519 WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,
1520 regTemp&~(0xC)); /* Enable HPF */
1521#else
1522 WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,
1523 regTemp|(0xC)); /* Disable HPF */
1524#endif
1525 regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
1526 WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,regTemp|1);
1527 }
1528 else
1529 {
1530 regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON);
1531 WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,regTemp&~(0xC));
1532 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_1,0x3538E80L);
1533 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_1,0x3538E80L);
1534 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_1,0x1AA9100L);
1535 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_2,0x216D100L);
1536 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_2,0x2505400L);
1537 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_2,0x216D100L);
1538 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_2,0x2CB8100L);
1539 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_2,0x1D7FA500L);
1540 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_3,0x2CD9B00L);
1541 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_3,0x1276D00L);
1542 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_3,0x2CD9B00L);
1543 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_3,0x2335300L);
1544 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_3,0x19D5F700L);
1545 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_1,0x6A71D00L);
1546 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_1,0x6A71D00L);
1547 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_1,0x1AA9100L);
1548 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_2,0x216D100L);
1549 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_2,0x2505400L);
1550 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_2,0x216D100L);
1551 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_2,0x2CB8100L);
1552 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_2,0x1D7FA500L);
1553 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_3,0x2CD9B00L);
1554 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_3,0x1276D00L);
1555 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_3,0x2CD9B00L);
1556 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_3,0x2335300L);
1557 WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_3,0x19D5F700L);
1558 regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
1559 WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,regTemp&~(1));
1560 }
1561 regTemp = Si3218x_PCM_Presets[preset].pcmFormat;
1562 regTemp |= Si3218x_PCM_Presets[preset].pcm_tri << 5;
1563 regTemp |= Si3218x_PCM_Presets[preset].alaw_inv << 2;
1564 WriteReg(pProHW,pProslic->channel,SI3218X_REG_PCMMODE,regTemp);
1565 regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_PCMTXHI);
1566 regTemp &= 3;
1567 regTemp |= Si3218x_PCM_Presets[preset].tx_edge<<4;
1568 WriteReg(pProHW,pProslic->channel,SI3218X_REG_PCMTXHI,regTemp);
1569
1570 return RC_NONE;
1571}
1572#endif
1573
1574/*
1575**
1576** PROSLIC CONTROL FUNCTIONS
1577**
1578*/
1579
1580/*
1581
1582** Function: PROSLIC_dbgSetDCFeed
1583**
1584** Description:
1585** provisionally function for setting up
1586** dcfeed given desired open circuit voltage
1587** and loop current.
1588*/
1589
1590int Si3218x_dbgSetDCFeed (proslicChanType *pProslic, uInt32 v_vlim_val,
1591 uInt32 i_ilim_val, int32 preset)
1592{
1593#ifndef DISABLE_DCFEED_SETUP
1594 /* Note: * needs more descriptive return codes in the event of an out of range argument */
1595 uInt16 vslope = 160;
1596 uInt16 rslope = 720;
1597 uInt32 vscale1 = 1386;
1598 uInt32 vscale2 =
1599 1422; /* 1386x1422 = 1970892 broken down to minimize trunc err */
1600 uInt32 iscale1 = 913;
1601 uInt32 iscale2 = 334; /* 913x334 = 304942 */
1602 uInt32 i_rfeed_val, v_rfeed_val, const_rfeed_val, i_vlim_val, const_ilim_val,
1603 v_ilim_val;
1604 int32 signedVal;
1605 /* Set Linefeed to open state before modifying DC Feed */
1606
1607 /* Assumptions must be made to minimize computations. This limits the
1608 ** range of available settings, but should be more than adequate for
1609 ** short loop applications.
1610 **
1611 ** Assumtions:
1612 **
1613 ** SLOPE_VLIM => 160ohms
1614 ** SLOPE_RFEED => 720ohms
1615 ** I_RFEED => 3*I_ILIM/4
1616 **
1617 ** With these assumptions, the DC Feed parameters now become
1618 **
1619 ** Inputs: V_VLIM, I_ILIM
1620 ** Constants: SLOPE_VLIM, SLOPE_ILIM, SLOPE_RFEED, SLOPE_DELTA1, SLOPE_DELTA2
1621 ** Outputs: V_RFEED, V_ILIM, I_VLIM, CONST_RFEED, CONST_ILIM
1622 **
1623 */
1624
1625 if(pProslic->channelType != PROSLIC)
1626 {
1627 return RC_CHANNEL_TYPE_ERR;
1628 }
1629
1630 /* Validate arguments */
1631 if((i_ilim_val < 15)||(i_ilim_val > 45))
1632 {
1633 return 1; /* need error code */
1634 }
1635 if((v_vlim_val < 30)||(v_vlim_val > 52))
1636 {
1637 return 1; /* need error code */
1638 }
1639
1640 /* Calculate voltages in mV and currents in uA */
1641 v_vlim_val *= 1000;
1642 i_ilim_val *= 1000;
1643
1644 /* I_RFEED */
1645 i_rfeed_val = (3*i_ilim_val)/4;
1646
1647 /* V_RFEED */
1648 v_rfeed_val = v_vlim_val - (i_rfeed_val*vslope)/1000;
1649
1650 /* V_ILIM */
1651 v_ilim_val = v_rfeed_val - (rslope*(i_ilim_val - i_rfeed_val))/1000;
1652
1653 /* I_VLIM */
1654 i_vlim_val = (v_vlim_val*1000)/4903;
1655
1656 /* CONST_RFEED */
1657 signedVal = v_rfeed_val * (i_ilim_val - i_rfeed_val);
1658 signedVal /= (v_rfeed_val - v_ilim_val);
1659 signedVal = i_rfeed_val + signedVal;
1660
1661 /* signedVal in uA here */
1662 signedVal *= iscale1;
1663 signedVal /= 100;
1664 signedVal *= iscale2;
1665 signedVal /= 10;
1666
1667 if(signedVal < 0)
1668 {
1669 const_rfeed_val = (signedVal)+ (1L<<29);
1670 }
1671 else
1672 {
1673 const_rfeed_val = signedVal & 0x1FFFFFFF;
1674 }
1675
1676 /* CONST_ILIM */
1677 const_ilim_val = i_ilim_val;
1678
1679 /* compute RAM values */
1680 v_vlim_val *= vscale1;
1681 v_vlim_val /= 100;
1682 v_vlim_val *= vscale2;
1683 v_vlim_val /= 10;
1684
1685 v_rfeed_val *= vscale1;
1686 v_rfeed_val /= 100;
1687 v_rfeed_val *= vscale2;
1688 v_rfeed_val /= 10;
1689
1690 v_ilim_val *= vscale1;
1691 v_ilim_val /= 100;
1692 v_ilim_val *= vscale2;
1693 v_ilim_val /= 10;
1694
1695 const_ilim_val *= iscale1;
1696 const_ilim_val /= 100;
1697 const_ilim_val *= iscale2;
1698 const_ilim_val /= 10;
1699
1700 i_vlim_val *= iscale1;
1701 i_vlim_val /= 100;
1702 i_vlim_val *= iscale2;
1703 i_vlim_val /= 10;
1704
1705 Si3218x_DCfeed_Presets[preset].slope_vlim = 0x18842BD7L;
1706 Si3218x_DCfeed_Presets[preset].slope_rfeed = 0x1E8886DEL;
1707 Si3218x_DCfeed_Presets[preset].slope_ilim = 0x40A0E0L;
1708 Si3218x_DCfeed_Presets[preset].delta1 = 0x1EABA1BFL;
1709 Si3218x_DCfeed_Presets[preset].delta2 = 0x1EF744EAL;
1710 Si3218x_DCfeed_Presets[preset].v_vlim = v_vlim_val;
1711 Si3218x_DCfeed_Presets[preset].v_rfeed = v_rfeed_val;
1712 Si3218x_DCfeed_Presets[preset].v_ilim = v_ilim_val;
1713 Si3218x_DCfeed_Presets[preset].const_rfeed = const_rfeed_val;
1714 Si3218x_DCfeed_Presets[preset].const_ilim = const_ilim_val;
1715 Si3218x_DCfeed_Presets[preset].i_vlim = i_vlim_val;
1716
1717 return RC_NONE;
1718#else
1719 SILABS_UNREFERENCED_PARAMETER(pProslic);
1720 SILABS_UNREFERENCED_PARAMETER(preset);
1721 SILABS_UNREFERENCED_PARAMETER(v_vlim_val);
1722 SILABS_UNREFERENCED_PARAMETER(i_ilim_val);
1723 return RC_IGNORE;
1724#endif
1725}
1726
1727/*
1728** Function: PROSLIC_dbgSetDCFeedVopen
1729**
1730** Description:
1731** provisionally function for setting up
1732** dcfeed given desired open circuit voltage.
1733** Entry I_ILIM value will be used.
1734*/
1735int Si3218x_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
1736 int32 preset)
1737{
1738#ifndef DISABLE_DCFEED_SETUP
1739 uInt32 i_ilim_val;
1740 uInt32 iscale1 = 913;
1741 uInt32 iscale2 = 334; /* 913x334 = 304942 */
1742
1743
1744 if(pProslic->channelType != PROSLIC)
1745 {
1746 return RC_CHANNEL_TYPE_ERR;
1747 }
1748
1749 /* Read present CONST_ILIM value */
1750 i_ilim_val = Si3218x_DCfeed_Presets[preset].const_ilim;
1751
1752
1753 i_ilim_val /= iscale2;
1754 i_ilim_val /= iscale1;
1755
1756 return Si3218x_dbgSetDCFeed(pProslic,v_vlim_val,i_ilim_val,preset);
1757#else
1758 SILABS_UNREFERENCED_PARAMETER(pProslic);
1759 SILABS_UNREFERENCED_PARAMETER(preset);
1760 SILABS_UNREFERENCED_PARAMETER(v_vlim_val);
1761 return RC_IGNORE;
1762#endif
1763}
1764
1765/*
1766** Function: PROSLIC_dbgSetDCFeedIloop
1767**
1768** Description:
1769** provisionally function for setting up
1770** dcfeed given desired loop current.
1771** Entry V_VLIM value will be used.
1772*/
1773int Si3218x_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
1774 int32 preset)
1775{
1776#ifndef DISABLE_DCFEED_SETUP
1777
1778 uInt32 v_vlim_val;
1779 uInt32 vscale1 = 1386;
1780 uInt32 vscale2 =
1781 1422; /* 1386x1422 = 1970892 broken down to minimize trunc err */
1782
1783 if(pProslic->channelType != PROSLIC)
1784 {
1785 return RC_CHANNEL_TYPE_ERR;
1786 }
1787
1788 /* Read present V_VLIM value */
1789 v_vlim_val = Si3218x_DCfeed_Presets[preset].v_vlim;
1790
1791 v_vlim_val /= vscale2;
1792 v_vlim_val /= vscale1;
1793
1794 return Si3218x_dbgSetDCFeed(pProslic,v_vlim_val,i_ilim_val, preset);
1795#else
1796 SILABS_UNREFERENCED_PARAMETER(pProslic);
1797 SILABS_UNREFERENCED_PARAMETER(preset);
1798 SILABS_UNREFERENCED_PARAMETER(i_ilim_val);
1799 return RC_IGNORE;
1800#endif
1801}
1802
1803typedef struct
1804{
1805 uInt8 freq;
1806 ramData ringfr; /* trise scale for trap */
1807 uInt32 ampScale;
1808} ProSLIC_SineRingFreqLookup;
1809
1810typedef struct
1811{
1812 uInt8 freq;
1813 ramData rtacth;
1814 ramData rtper;
1815 ramData rtdb;
1816} ProSLIC_SineRingtripLookup;
1817
1818typedef struct
1819{
1820 uInt8 freq;
1821 uInt16 cfVal[6];
1822} ProSLIC_TrapRingFreqLookup;
1823
1824typedef struct
1825{
1826 uInt8 freq;
1827 ramData rtper;
1828 ramData rtdb;
1829 uInt32 rtacth[6];
1830} ProSLIC_TrapRingtripLookup;
1831
1832static const ProSLIC_SineRingFreqLookup sineRingFreqTable[] =
1833 /* Freq RINGFR, vScale */
1834 {
1835 {15, 0x7F6E930L, 18968L},
1836 {16, 0x7F5A8E0L, 20234L},
1837 {20, 0x7EFD9D5L, 25301L},
1838 {22, 0x7EC770AL, 27843L},
1839 {23, 0x7EAA6E2L, 29113L},
1840 {25, 0x7E6C925L, 31649L},
1841 {30, 0x7DBB96BL, 38014L},
1842 {34, 0x7D34155L, 42270L}, /* Actually 33.33Hz */
1843 {35, 0x7CEAD72L, 44397L},
1844 {40, 0x7BFA887L, 50802L},
1845 {45, 0x7AEAE74L, 57233L},
1846 {50, 0x79BC384L, 63693L},
1847 {0,0,0}
1848 }; /* terminator */
1849
1850static const ProSLIC_SineRingtripLookup sineRingtripTable[] =
1851 /* Freq rtacth */
1852 {
1853 {15, 11440000L, 0x6A000L, 0x4000L },
1854 {16, 10810000L, 0x64000L, 0x4000L },
1855 {20, 8690000L, 0x50000L, 0x8000L },
1856 {22, 7835000L, 0x48000L, 0x8000L },
1857 {23, 7622000L, 0x46000L, 0x8000L },
1858 {25, 6980000L, 0x40000L, 0xA000L },
1859 {30, 5900000L, 0x36000L, 0xA000L },
1860 {34, 10490000L, 0x60000L, 0x6000L }, /* Actually 33.33 */
1861 {35, 10060000L, 0x5C000L, 0x6000L },
1862 {40, 8750000L, 0x50000L, 0x8000L },
1863 {45, 7880000L, 0x48000L, 0x8000L },
1864 {50, 7010000L, 0x40000L, 0xA000L },
1865 {0,0L, 0L, 0L}
1866 }; /* terminator */
1867
1868static const ProSLIC_TrapRingFreqLookup trapRingFreqTable[] =
1869 /* Freq multCF11 multCF12 multCF13 multCF14 multCF15 multCF16*/
1870 {
1871 {15, {69,122, 163, 196, 222,244}},
1872 {16, {65,115, 153, 184, 208,229}},
1873 {20, {52,92, 122, 147, 167,183}},
1874 {22, {47,83, 111, 134, 152,166}},
1875 {23, {45,80, 107, 128, 145,159}},
1876 {25, {42,73, 98, 118, 133,146}},
1877 {30, {35,61, 82, 98, 111,122}},
1878 {34, {31,55, 73, 88, 100,110}},
1879 {35, {30,52, 70, 84, 95,104}},
1880 {40, {26,46, 61, 73, 83,91}},
1881 {45, {23,41, 54, 65, 74,81}},
1882 {50, {21,37, 49, 59, 67,73}},
1883 {0,{0L,0L,0L,0L}} /* terminator */
1884 };
1885
1886
1887static const ProSLIC_TrapRingtripLookup trapRingtripTable[] =
1888 /* Freq rtper rtdb rtacthCR11 rtacthCR12 rtacthCR13 rtacthCR14 rtacthCR15 rtacthCR16*/
1889 {
1890 {15, 0x6A000L, 0x4000L, {16214894L, 14369375L, 12933127L, 11793508L, 10874121L, 10121671L}},
1891 {16, 0x64000L, 0x4000L, {15201463L, 13471289L, 12124806L, 11056414L, 10194489L, 9489067L}},
1892 {20, 0x50000L, 0x6000L, {12161171L, 10777031L, 9699845L, 8845131L, 8155591L, 7591253L}},
1893 {22, 0x48000L, 0x6000L, {11055610L, 9797301L, 8818041L, 8041028L, 7414174L, 6901139L}},
1894 {23, 0x46000L, 0x6000L, {10574931L, 9371331L, 8434648L, 7691418L, 7091818L, 6601090L}},
1895 {25, 0x40000L, 0x8000L, {9728937L, 8621625L, 7759876L, 7076105L, 6524473L, 6073003L}},
1896 {30, 0x36000L, 0x8000L, {8107447L, 7184687L, 6466563L, 5896754L, 5437061L, 5060836L}},
1897 {34, 0x60000L, 0x6000L, {7297432L, 6466865L, 5820489L, 5307609L, 4893844L, 4555208L}},
1898 {35, 0x5C000L, 0x6000L, {6949240L, 6158303L, 5542769L, 5054361L, 4660338L, 4337859L}},
1899 {40, 0x50000L, 0x6000L, {6080585L, 5388516L, 4849923L, 4422565L, 4077796L, 3795627L}},
1900 {45, 0x48000L, 0x6000L, {5404965L, 4789792L, 4311042L, 3931169L, 3624707L, 3373890L}},
1901 {50, 0x40000L, 0x8000L, {4864468L, 4310812L, 3879938L, 3538052L, 3262236L, 3036501L}},
1902 {0,0x0L, 0x0L, {0L,0L,0L,0L}} /* terminator */
1903 };
1904
1905/*
1906** Function: PROSLIC_dbgRingingSetup
1907**
1908** Description:
1909** Provision function for setting up
1910** Ring type, frequency, amplitude and dc offset.
1911** Main use will be by peek/poke applications.
1912*/
1913int Si3218x_dbgSetRinging (proslicChanType *pProslic,
1914 ProSLIC_dbgRingCfg *ringCfg, int preset)
1915{
1916#ifndef DISABLE_RING_SETUP
1917 int errVal,i=0;
1918 uInt32 vScale = 1608872L; /* (2^28/170.25)*((100+4903)/4903) */
1919 ramData dcdcVminTmp;
1920
1921
1922 if(pProslic->channelType != PROSLIC)
1923 {
1924 return RC_CHANNEL_TYPE_ERR;
1925 }
1926
1927 errVal = RC_NONE;
1928
1929 switch(ringCfg->ringtype)
1930 {
1931 case ProSLIC_RING_SINE:
1932 i=0;
1933 do
1934 {
1935 if(sineRingFreqTable[i].freq >= ringCfg->freq)
1936 {
1937 break;
1938 }
1939 i++;
1940 }
1941 while (sineRingFreqTable[i].freq);
1942
1943 /* Set to maximum value if exceeding maximum value from table */
1944 if(sineRingFreqTable[i].freq == 0)
1945 {
1946 i--;
1947 errVal = RC_RING_V_LIMITED;
1948 }
1949
1950 /* Update RINGFR RINGAMP, RINGOFFSET, and RINGCON */
1951 Si3218x_Ring_Presets[preset].freq = sineRingFreqTable[i].ringfr;
1952 Si3218x_Ring_Presets[preset].amp = ringCfg->amp * sineRingFreqTable[i].ampScale;
1953 Si3218x_Ring_Presets[preset].offset = ringCfg->offset * vScale;
1954 Si3218x_Ring_Presets[preset].phas = 0L;
1955
1956 /* Don't alter anything in RINGCON other than clearing the TRAP bit */
1957 Si3218x_Ring_Presets[preset].ringcon &= 0xFE;
1958
1959 Si3218x_Ring_Presets[preset].rtper = sineRingtripTable[i].rtper;
1960 Si3218x_Ring_Presets[preset].rtacdb = sineRingtripTable[i].rtdb;
1961 Si3218x_Ring_Presets[preset].rtdcdb = sineRingtripTable[i].rtdb;
1962 Si3218x_Ring_Presets[preset].rtdcth = 0xFFFFFFFL;
1963 Si3218x_Ring_Presets[preset].rtacth = sineRingtripTable[i].rtacth;
1964 break;
1965
1966 case ProSLIC_RING_TRAP_CF11:
1967 case ProSLIC_RING_TRAP_CF12:
1968 case ProSLIC_RING_TRAP_CF13:
1969 case ProSLIC_RING_TRAP_CF14:
1970 case ProSLIC_RING_TRAP_CF15:
1971 case ProSLIC_RING_TRAP_CF16:
1972 i=0;
1973 do
1974 {
1975 if(trapRingFreqTable[i].freq >= ringCfg->freq)
1976 {
1977 break;
1978 }
1979 i++;
1980 }
1981 while (trapRingFreqTable[i].freq);
1982
1983 /* Set to maximum value if exceeding maximum value from table */
1984 if(trapRingFreqTable[i].freq == 0)
1985 {
1986 i--;
1987 errVal = RC_RING_V_LIMITED;
1988 }
1989
1990 /* Update RINGFR RINGAMP, RINGOFFSET, and RINGCON */
1991 Si3218x_Ring_Presets[preset].amp = ringCfg->amp * vScale;
1992 Si3218x_Ring_Presets[preset].freq =
1993 Si3218x_Ring_Presets[preset].amp/trapRingFreqTable[i].cfVal[ringCfg->ringtype];
1994 Si3218x_Ring_Presets[preset].offset = ringCfg->offset * vScale;
1995 Si3218x_Ring_Presets[preset].phas = 262144000L/trapRingFreqTable[i].freq;
1996
1997 /* Don't alter anything in RINGCON other than setting the TRAP bit */
1998 Si3218x_Ring_Presets[preset].ringcon |= 0x01;
1999
2000 /* RTPER and debouce timers */
2001 Si3218x_Ring_Presets[preset].rtper = trapRingtripTable[i].rtper;
2002 Si3218x_Ring_Presets[preset].rtacdb = trapRingtripTable[i].rtdb;
2003 Si3218x_Ring_Presets[preset].rtdcdb = trapRingtripTable[i].rtdb;
2004
2005
2006 Si3218x_Ring_Presets[preset].rtdcth = 0xFFFFFFFL;
2007 Si3218x_Ring_Presets[preset].rtacth =
2008 trapRingtripTable[i].rtacth[ringCfg->ringtype];
2009
2010
2011 break;
2012 }
2013
2014 /*
2015 ** DCDC tracking sluggish under light load at higher ring freq.
2016 ** Reduce tracking depth above 40Hz. This should have no effect
2017 ** if using the Buck-Boost architecture.
2018 */
2019 if((sineRingFreqTable[i].freq >= 40)
2020 ||(Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST))
2021 {
2022 dcdcVminTmp = ringCfg->amp + ringCfg->offset;
2023 dcdcVminTmp *= 1000;
2024 dcdcVminTmp *= SCALE_V_MADC;
2025 Si3218x_Ring_Presets[preset].dcdc_vref_min_rng = dcdcVminTmp;
2026 }
2027 else
2028 {
2029 Si3218x_Ring_Presets[preset].dcdc_vref_min_rng = 0x1800000L;
2030 }
2031
2032 return errVal;
2033#else
2034 SILABS_UNREFERENCED_PARAMETER(pProslic);
2035 SILABS_UNREFERENCED_PARAMETER(preset);
2036 SILABS_UNREFERENCED_PARAMETER(ringCfg);
2037 return RC_IGNORE;
2038#endif
2039}
2040
2041
2042typedef struct
2043{
2044 int32 gain;
2045 uInt32 scale;
2046} ProSLIC_GainScaleLookup;
2047
2048#ifndef ENABLE_HIRES_GAIN
2049static int Si3218x_dbgSetGain (proslicChanType *pProslic, int32 gain,
2050 int impedance_preset, int tx_rx_sel)
2051{
2052 int errVal = 0;
2053 int32 i;
2054 int32 gain_pga, gain_eq;
2055 const ProSLIC_GainScaleLookup gainScaleTable[]
2056 = /* gain, scale=10^(gain/20) */
2057 {
2058 {-30, 32},
2059 {-29, 35},
2060 {-28, 40},
2061 {-27, 45},
2062 {-26, 50},
2063 {-25, 56},
2064 {-24, 63},
2065 {-23, 71},
2066 {-22, 79},
2067 {-21, 89},
2068 {-20, 100},
2069 {-19, 112},
2070 {-18, 126},
2071 {-17, 141},
2072 {-16, 158},
2073 {-15, 178},
2074 {-14, 200},
2075 {-13, 224},
2076 {-12, 251},
2077 {-11, 282},
2078 {-10, 316},
2079 {-9, 355},
2080 {-8, 398},
2081 {-7, 447},
2082 {-6, 501},
2083 {-5, 562},
2084 {-4, 631},
2085 {-3, 708},
2086 {-2, 794},
2087 {-1, 891},
2088 {0, 1000},
2089 {1, 1122},
2090 {2, 1259},
2091 {3, 1413},
2092 {4, 1585},
2093 {5, 1778},
2094 {6, 1995},
2095 {0xff,0} /* terminator */
2096 };
2097
2098 SILABS_UNREFERENCED_PARAMETER(pProslic);
2099
2100 /* Test against max gain */
2101 if (gain > PROSLIC_EXTENDED_GAIN_MAX)
2102 {
2103 errVal = RC_GAIN_OUT_OF_RANGE;
2104 DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d out of range\n", LOGPRINT_PREFIX,
2105 (int)gain);
2106 gain = PROSLIC_EXTENDED_GAIN_MAX; /* Clamp to maximum */
2107 }
2108
2109 /* Test against min gain */
2110 if (gain < PROSLIC_GAIN_MIN)
2111 {
2112 errVal = RC_GAIN_OUT_OF_RANGE;
2113 DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d out of range\n", LOGPRINT_PREFIX,
2114 (int)gain);
2115 gain = PROSLIC_GAIN_MIN; /* Clamp to minimum */
2116 }
2117
2118 /* Distribute gain */
2119 if(gain == 0)
2120 {
2121 gain_pga = 0;
2122 gain_eq = 0;
2123 }
2124 else if(gain > PROSLIC_GAIN_MAX)
2125 {
2126 if(tx_rx_sel == TXACGAIN_SEL)
2127 {
2128 gain_pga = PROSLIC_GAIN_MAX;
2129 gain_eq = gain - PROSLIC_GAIN_MAX;
2130 }
2131 else
2132 {
2133 gain_pga = gain - PROSLIC_GAIN_MAX;
2134 gain_eq = PROSLIC_GAIN_MAX;
2135 }
2136 }
2137 else if(gain > 0)
2138 {
2139 if(tx_rx_sel == TXACGAIN_SEL)
2140 {
2141 gain_pga = gain;
2142 gain_eq = 0;
2143 }
2144 else
2145 {
2146 gain_pga = 0;
2147 gain_eq = gain;
2148 }
2149 }
2150 else
2151 {
2152 if(tx_rx_sel == TXACGAIN_SEL)
2153 {
2154 gain_pga = 0;
2155 gain_eq = gain;
2156 }
2157 else
2158 {
2159 gain_pga = gain;
2160 gain_eq = 0;
2161 }
2162
2163 }
2164
2165
2166 /*
2167 ** Lookup PGA Appropriate PGA Gain
2168 */
2169 i=0;
2170 do
2171 {
2172 if(gainScaleTable[i].gain >= gain_pga) /* was gain_1 */
2173 {
2174 break;
2175 }
2176 i++;
2177 }
2178 while (gainScaleTable[i].gain!=0xff);
2179
2180 /* Set to maximum value if exceeding maximum value from table */
2181 if(gainScaleTable[i].gain == 0xff)
2182 {
2183 i--;
2184 errVal = RC_GAIN_DELTA_TOO_LARGE;
2185 }
2186
2187 if(tx_rx_sel == TXACGAIN_SEL)
2188 {
2189 Si3218x_audioGain_Presets[0].acgain =
2190 (Si3218x_Impedance_Presets[impedance_preset].txgain/1000)
2191 *gainScaleTable[i].scale;
2192 }
2193 else
2194 {
2195 Si3218x_audioGain_Presets[1].acgain =
2196 (Si3218x_Impedance_Presets[impedance_preset].rxgain/1000)
2197 *gainScaleTable[i].scale;
2198 }
2199
2200
2201 /*
2202 ** Lookup EQ Gain
2203 */
2204 i=0;
2205 do
2206 {
2207 if(gainScaleTable[i].gain >= gain_eq) /* was gain_2 */
2208 {
2209 break;
2210 }
2211 i++;
2212 }
2213 while (gainScaleTable[i].gain!=0xff);
2214
2215 /* Set to maximum value if exceeding maximum value from table */
2216 if(gainScaleTable[i].gain == 0xff)
2217 {
2218 i--;
2219 errVal = RC_GAIN_DELTA_TOO_LARGE;
2220 }
2221
2222 if(tx_rx_sel == TXACGAIN_SEL)
2223 {
2224 /*sign extend negative numbers*/
2225 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 & 0x10000000L)
2226 {
2227 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 |= 0xf0000000L;
2228 }
2229 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 & 0x10000000L)
2230 {
2231 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 |= 0xf0000000L;
2232 }
2233 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 & 0x10000000L)
2234 {
2235 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 |= 0xf0000000L;
2236 }
2237 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 & 0x10000000L)
2238 {
2239 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 |= 0xf0000000L;
2240 }
2241
2242 Si3218x_audioGain_Presets[0].aceq_c0 = ((int32)
2243 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0/1000)
2244 *gainScaleTable[i].scale;
2245 Si3218x_audioGain_Presets[0].aceq_c1 = ((int32)
2246 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1/1000)
2247 *gainScaleTable[i].scale;
2248 Si3218x_audioGain_Presets[0].aceq_c2 = ((int32)
2249 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2/1000)
2250 *gainScaleTable[i].scale;
2251 Si3218x_audioGain_Presets[0].aceq_c3 = ((int32)
2252 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3/1000)
2253 *gainScaleTable[i].scale;
2254 }
2255 else
2256 {
2257 /*sign extend negative numbers*/
2258 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 & 0x10000000L)
2259 {
2260 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
2261 }
2262 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 & 0x10000000L)
2263 {
2264 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
2265 }
2266 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 & 0x10000000L)
2267 {
2268 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
2269 }
2270 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 & 0x10000000L)
2271 {
2272 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
2273 }
2274
2275 Si3218x_audioGain_Presets[1].aceq_c0 = ((int32)
2276 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0/1000)
2277 *gainScaleTable[i].scale;
2278 Si3218x_audioGain_Presets[1].aceq_c1 = ((int32)
2279 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1/1000)
2280 *gainScaleTable[i].scale;
2281 Si3218x_audioGain_Presets[1].aceq_c2 = ((int32)
2282 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2/1000)
2283 *gainScaleTable[i].scale;
2284 Si3218x_audioGain_Presets[1].aceq_c3 = ((int32)
2285 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3/1000)
2286 *gainScaleTable[i].scale;
2287 }
2288
2289
2290 return errVal;
2291}
2292#else /* ENABLE_HIRES_GAIN */
2293/*
2294** Function: Si3218x_dbgSetGainHiRes()
2295**
2296** Description:
2297** Provision function for setting up
2298** TX and RX gain with 0.1dB resolution instead
2299** of 1.0dB resolution
2300*/
2301static int Si3218x_dbgSetGainHiRes (proslicChanType *pProslic, int32 gain,
2302 int impedance_preset, int tx_rx_sel)
2303{
2304 int errVal = 0;
2305 int32 i;
2306 int32 coarseGainIndex, fineGainIndex;
2307 int32 gain_pga, gain_eq;
2308 int32 coarseGain, fineGain;
2309 int32 tmp;
2310 const ProSLIC_GainScaleLookup coarseGainScaleTable[]
2311 = /* gain, scale=10^(gain/20) */
2312 {
2313 {-30, 32},
2314 {-29, 35},
2315 {-28, 40},
2316 {-27, 45},
2317 {-26, 50},
2318 {-25, 56},
2319 {-24, 63},
2320 {-23, 71},
2321 {-22, 79},
2322 {-21, 89},
2323 {-20, 100},
2324 {-19, 112},
2325 {-18, 126},
2326 {-17, 141},
2327 {-16, 158},
2328 {-15, 178},
2329 {-14, 200},
2330 {-13, 224},
2331 {-12, 251},
2332 {-11, 282},
2333 {-10, 316},
2334 {-9, 355},
2335 {-8, 398},
2336 {-7, 447},
2337 {-6, 501},
2338 {-5, 562},
2339 {-4, 631},
2340 {-3, 708},
2341 {-2, 794},
2342 {-1, 891},
2343 {0, 1000},
2344 {1, 1122},
2345 {2, 1259},
2346 {3, 1413},
2347 {4, 1585},
2348 {5, 1778},
2349 {6, 1995},
2350 {0xff,0} /* terminator */
2351 };
2352
2353 const ProSLIC_GainScaleLookup fineGainScaleTable[]
2354 = /* gain, scale=10^(gain/20) */
2355 {
2356 {-9, 902},
2357 {-8, 912},
2358 {-7, 923},
2359 {-6, 933},
2360 {-5, 944},
2361 {-4, 955},
2362 {-3, 966},
2363 {-2, 977},
2364 {-1, 989},
2365 {0, 1000},
2366 {1, 1012},
2367 {2, 1023},
2368 {3, 1035},
2369 {4, 1047},
2370 {5, 1059},
2371 {6, 1072},
2372 {7, 1084},
2373 {8, 1096},
2374 {9, 1109},
2375 {0xff,0} /* terminator */
2376 };
2377
2378 SILABS_UNREFERENCED_PARAMETER(pProslic);
2379
2380 /* Test against max gain */
2381 if (gain > (PROSLIC_GAIN_MAX*10L))
2382 {
2383 errVal = RC_GAIN_OUT_OF_RANGE;
2384 DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d dB*10 out of range\n",
2385 LOGPRINT_PREFIX, gain);
2386 gain = (PROSLIC_GAIN_MAX*10L); /* Clamp to maximum */
2387 }
2388
2389 /* Test against min gain */
2390 if (gain < (PROSLIC_GAIN_MIN*10L))
2391 {
2392 errVal = RC_GAIN_OUT_OF_RANGE;
2393 DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d dB*10 out of range\n",
2394 LOGPRINT_PREFIX, gain);
2395 gain = (PROSLIC_GAIN_MIN*10); /* Clamp to minimum */
2396 }
2397
2398 /* Distribute gain */
2399 coarseGain = gain/10L;
2400 fineGain = gain - (coarseGain*10L);
2401
2402 /* Distribute coarseGain */
2403 if(coarseGain == 0)
2404 {
2405 gain_pga = 0;
2406 gain_eq = 0;
2407 }
2408 else if(coarseGain > 0)
2409 {
2410 if(tx_rx_sel == TXACGAIN_SEL)
2411 {
2412 gain_pga = coarseGain;
2413 gain_eq = 0;
2414 }
2415 else
2416 {
2417 gain_pga = 0;
2418 gain_eq = coarseGain;
2419 }
2420 }
2421 else
2422 {
2423 if(tx_rx_sel == TXACGAIN_SEL)
2424 {
2425 gain_pga = 0;
2426 gain_eq = coarseGain;
2427 }
2428 else
2429 {
2430 gain_pga = coarseGain;
2431 gain_eq = 0;
2432 }
2433 }
2434
2435 /*
2436 ** Lookup PGA Appopriate PGA Gain
2437 */
2438 i=0;
2439 do
2440 {
2441 if(coarseGainScaleTable[i].gain >= gain_pga)
2442 {
2443 break;
2444 }
2445 i++;
2446 }
2447 while (coarseGainScaleTable[i].gain!=0xff);
2448
2449 /* Set to maximum value if exceeding maximum value from table */
2450 if(coarseGainScaleTable[i].gain == 0xff)
2451 {
2452 i--;
2453 errVal = RC_GAIN_DELTA_TOO_LARGE;
2454 }
2455
2456 coarseGainIndex = i; /* Store coarse index */
2457
2458 /* Find fineGain */
2459 i = 0;
2460 do
2461 {
2462 if(fineGainScaleTable[i].gain >= fineGain)
2463 {
2464 break;
2465 }
2466 i++;
2467 }
2468 while (fineGainScaleTable[i].gain!=0xff);
2469
2470 /* Set to maximum value if exceeding maximum value from table */
2471 if(fineGainScaleTable[i].gain == 0xff)
2472 {
2473 i--;
2474 errVal = RC_GAIN_DELTA_TOO_LARGE;
2475 }
2476
2477 fineGainIndex = i;
2478
2479 if(tx_rx_sel == TXACGAIN_SEL)
2480 {
2481 Si3218x_audioGain_Presets[0].acgain = ((
2482 Si3218x_Impedance_Presets[impedance_preset].txgain/1000L)
2483 *coarseGainScaleTable[coarseGainIndex].scale);
2484 }
2485 else
2486 {
2487 Si3218x_audioGain_Presets[1].acgain = ((
2488 Si3218x_Impedance_Presets[impedance_preset].rxgain/1000L)
2489 * coarseGainScaleTable[coarseGainIndex].scale)/1000L
2490 * fineGainScaleTable[fineGainIndex].scale;
2491 }
2492
2493 /*
2494 ** Lookup EQ Gain
2495 */
2496 i=0;
2497 do
2498 {
2499 if(coarseGainScaleTable[i].gain >= gain_eq)
2500 {
2501 break;
2502 }
2503 i++;
2504 }
2505 while (coarseGainScaleTable[i].gain!=0xff);
2506
2507 /* Set to maximum value if exceeding maximum value from table */
2508 if(coarseGainScaleTable[i].gain == 0xff)
2509 {
2510 i--;
2511 errVal = RC_GAIN_DELTA_TOO_LARGE;
2512 }
2513
2514 coarseGainIndex = i; /* Store coarse index */
2515
2516 if(tx_rx_sel == TXACGAIN_SEL)
2517 {
2518 /*sign extend negative numbers*/
2519 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 & 0x10000000L)
2520 {
2521 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 |= 0xf0000000L;
2522 }
2523 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 & 0x10000000L)
2524 {
2525 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 |= 0xf0000000L;
2526 }
2527 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 & 0x10000000L)
2528 {
2529 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 |= 0xf0000000L;
2530 }
2531 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 & 0x10000000L)
2532 {
2533 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 |= 0xf0000000L;
2534 }
2535
2536 tmp = (((int32)
2537 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0/1000L)
2538 *coarseGainScaleTable[coarseGainIndex].scale);
2539 tmp = tmp / (int32)1000L;
2540 tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
2541 Si3218x_audioGain_Presets[0].aceq_c0 = tmp;
2542
2543 tmp = (((int32)
2544 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1/1000L)
2545 *coarseGainScaleTable[coarseGainIndex].scale);
2546 tmp = tmp / (int32)1000L;
2547 tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
2548 Si3218x_audioGain_Presets[0].aceq_c1 = tmp;
2549
2550 tmp = (((int32)
2551 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2/1000L)
2552 *coarseGainScaleTable[coarseGainIndex].scale);
2553 tmp = tmp / (int32)1000L;
2554 tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
2555 Si3218x_audioGain_Presets[0].aceq_c2 = tmp;
2556
2557 tmp = (((int32)
2558 Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3/1000L)
2559 *coarseGainScaleTable[coarseGainIndex].scale);
2560 tmp = tmp / (int32)1000L;
2561 tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
2562 Si3218x_audioGain_Presets[0].aceq_c3 = tmp;
2563 }
2564 else
2565 {
2566 /*sign extend negative numbers*/
2567 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 & 0x10000000L)
2568 {
2569 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
2570 }
2571 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 & 0x10000000L)
2572 {
2573 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
2574 }
2575 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 & 0x10000000L)
2576 {
2577 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
2578 }
2579 if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 & 0x10000000L)
2580 {
2581 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
2582 }
2583
2584 Si3218x_audioGain_Presets[1].aceq_c0 = ((int32)
2585 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0/1000)
2586 *coarseGainScaleTable[i].scale;
2587 Si3218x_audioGain_Presets[1].aceq_c1 = ((int32)
2588 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1/1000)
2589 * coarseGainScaleTable[i].scale;
2590 Si3218x_audioGain_Presets[1].aceq_c2 = ((int32)
2591 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2/1000)
2592 * coarseGainScaleTable[i].scale;
2593 Si3218x_audioGain_Presets[1].aceq_c3 = ((int32)
2594 Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3/1000)
2595 * coarseGainScaleTable[i].scale;
2596 }
2597
2598 return errVal;
2599}
2600#endif /* ENABLE_HIRES_GAIN */
2601
2602/*
2603** Function: PROSLIC_dbgSetTXGain
2604**
2605** Description:
2606** Provision function for setting up
2607** TX gain
2608*/
2609
2610int Si3218x_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
2611 int impedance_preset, int audio_gain_preset)
2612{
2613 SILABS_UNREFERENCED_PARAMETER(audio_gain_preset);
2614#ifdef ENABLE_HIRES_GAIN
2615 return Si3218x_dbgSetGainHiRes(pProslic,gain,impedance_preset,TXACGAIN_SEL);
2616#else
2617 return Si3218x_dbgSetGain(pProslic,gain,impedance_preset,TXACGAIN_SEL);
2618#endif
2619}
2620
2621/*
2622** Function: PROSLIC_dbgSetRXGain
2623**
2624** Description:
2625** Provision function for setting up
2626** RX gain
2627*/
2628int Si3218x_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
2629 int impedance_preset, int audio_gain_preset)
2630{
2631 SILABS_UNREFERENCED_PARAMETER(audio_gain_preset);
2632#ifdef ENABLE_HIRES_GAIN
2633 return Si3218x_dbgSetGainHiRes(pProslic,gain,impedance_preset,RXACGAIN_SEL);
2634#else
2635 return Si3218x_dbgSetGain(pProslic,gain,impedance_preset,RXACGAIN_SEL);
2636#endif
2637}
2638
2639/*
2640** Function: Si3218x_GetRAMScale
2641**
2642** Description:
2643** Read scale factor for passed RAM location
2644**
2645** Return Value:
2646** int32 scale
2647*/
2648static int32 Si3218x_GetRAMScale(uInt16 addr)
2649{
2650 int32 scale;
2651
2652 switch(addr)
2653 {
2654 case SI3218X_RAM_MADC_ILOOP:
2655 case SI3218X_RAM_MADC_ITIP:
2656 case SI3218X_RAM_MADC_IRING:
2657 case SI3218X_RAM_MADC_ILONG:
2658 scale = SCALE_I_MADC;
2659 break;
2660
2661 case SI3218X_RAM_MADC_VTIPC:
2662 case SI3218X_RAM_MADC_VRINGC:
2663 case SI3218X_RAM_MADC_VBAT:
2664 case SI3218X_RAM_MADC_VDC:
2665 case SI3218X_RAM_MADC_VDC_OS:
2666 case SI3218X_RAM_MADC_VLONG:
2667 case SI3218X_RAM_VDIFF_SENSE:
2668 case SI3218X_RAM_VDIFF_FILT:
2669 case SI3218X_RAM_VDIFF_COARSE:
2670 case SI3218X_RAM_VTIP:
2671 case SI3218X_RAM_VRING:
2672 scale = SCALE_V_MADC;
2673 break;
2674
2675 default:
2676 scale = 1;
2677 break;
2678 }
2679
2680 return scale;
2681}
2682
2683/*
2684** Function: Si3218x_ReadMADCScaled
2685**
2686** Description:
2687** Read MADC (or other sensed voltages/currents) and
2688** return scaled value in int32 format.
2689**
2690** Return Value:
2691** int32 voltage in mV or
2692** int32 current in uA
2693*/
2694int32 Si3218x_ReadMADCScaled(proslicChanType_ptr pProslic,uInt16 addr,
2695 int32 scale)
2696{
2697 int32 data;
2698
2699 /*
2700 ** Read 29-bit RAM and sign extend to 32-bits
2701 */
2702 data = ReadRAM(pProHW,pProslic->channel,addr);
2703 if(data & 0x10000000L)
2704 {
2705 data |= 0xF0000000L;
2706 }
2707
2708 /*
2709 ** Scale to provided value, or use defaults if scale = 0
2710 */
2711 if(scale == 0)
2712 {
2713 scale = Si3218x_GetRAMScale(addr);
2714 }
2715
2716 data /= scale;
2717
2718 return data;
2719}
2720
2721/*
2722** Function: Si3218x_LineMonitor
2723**
2724** Description:
2725** Monitor line voltages and currents
2726*/
2727int Si3218x_LineMonitor(proslicChanType *pProslic, proslicMonitorType *monitor)
2728{
2729
2730 if(pProslic->channelType != PROSLIC)
2731 {
2732 return RC_CHANNEL_TYPE_ERR;
2733 }
2734
2735 if(pProslic->channelEnable)
2736 {
2737 monitor->vtr = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VDIFF_FILT);
2738 if(monitor->vtr & 0x10000000L)
2739 {
2740 monitor->vtr |= 0xf0000000L;
2741 }
2742 monitor->vtr /= SCALE_V_MADC;
2743
2744 monitor->vtip = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VTIP);
2745 if(monitor->vtip & 0x10000000L)
2746 {
2747 monitor->vtip |= 0xf0000000L;
2748 }
2749 monitor->vtip /= SCALE_V_MADC;
2750
2751 monitor->vring = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VRING);
2752 if(monitor->vring & 0x10000000L)
2753 {
2754 monitor->vring |= 0xf0000000L;
2755 }
2756 monitor->vring /= SCALE_V_MADC;
2757
2758 monitor->vlong = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VLONG);
2759 if(monitor->vlong & 0x10000000L)
2760 {
2761 monitor->vlong |= 0xf0000000L;
2762 }
2763 monitor->vlong /= SCALE_V_MADC;
2764
2765 monitor->vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
2766 if(monitor->vbat & 0x10000000L)
2767 {
2768 monitor->vbat |= 0xf0000000L;
2769 }
2770 monitor->vbat /= SCALE_V_MADC;
2771
2772 monitor->vdc = 0; /* Si3218x has no SVDC */
2773
2774 monitor->itr = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ILOOP);
2775 if(monitor->itr & 0x10000000L)
2776 {
2777 monitor->itr |= 0xf0000000L;
2778 }
2779 monitor->itr /= SCALE_I_MADC;
2780
2781 monitor->itip = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ITIP);
2782 if(monitor->itip & 0x10000000L)
2783 {
2784 monitor->itip |= 0xf0000000L;
2785 }
2786 monitor->itip /= SCALE_I_MADC;
2787
2788 monitor->iring = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_IRING);
2789 if(monitor->iring & 0x10000000L)
2790 {
2791 monitor->iring |= 0xf0000000L;
2792 }
2793 monitor->iring /= SCALE_I_MADC;
2794
2795 monitor->ilong = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ILONG);
2796 if(monitor->ilong & 0x10000000L)
2797 {
2798 monitor->ilong |= 0xf0000000L;
2799 }
2800 monitor->ilong /= SCALE_I_MADC;
2801
2802 monitor->p_hvic = ReadRAM(pProHW,pProslic->channel,
2803 SI3218X_RAM_P_Q1_D); /* P_HVIC_LPF */
2804 if(monitor->p_hvic & 0x10000000L)
2805 {
2806 monitor->p_hvic |= 0xf0000000L;
2807 }
2808 monitor->p_hvic /= SCALE_P_MADC;
2809 }
2810
2811 return RC_NONE;
2812}
2813
2814/*
2815** Function: Si3218x_PSTNCheck
2816**
2817** Description:
2818** Continuous monitoring of longitudinal current.
2819** If an average of N samples exceed avgThresh or a
2820** single sample exceeds singleThresh, the linefeed
2821** is forced into the open state.
2822**
2823** This protects the port from connecting to a live
2824** pstn line (faster than power alarm).
2825**
2826*/
2827int Si3218x_PSTNCheck (proslicChanType *pProslic,
2828 proslicPSTNCheckObjType *pPSTNCheck)
2829{
2830 uInt8 i;
2831
2832 if( (pProslic->channelType != PROSLIC)
2833 || (pPSTNCheck->samples == 0) )
2834 {
2835 return RC_NONE; /* Ignore DAA channels */
2836 }
2837
2838 /* Adjust buffer index */
2839 if(pPSTNCheck->count >= pPSTNCheck->samples)
2840 {
2841 pPSTNCheck->buffFull = TRUE;
2842 pPSTNCheck->count = 0; /* reset buffer ptr */
2843 }
2844
2845 /* Read next sample */
2846 pPSTNCheck->ilong[pPSTNCheck->count] = ReadRAM(pProHW,pProslic->channel,
2847 SI3218X_RAM_MADC_ILONG);
2848 if(pPSTNCheck->ilong[pPSTNCheck->count] & 0x10000000L)
2849 {
2850 pPSTNCheck->ilong[pPSTNCheck->count] |= 0xf0000000L;
2851 }
2852 pPSTNCheck->ilong[pPSTNCheck->count] /= SCALE_I_MADC;
2853
2854 /* Monitor magnitude only */
2855 if(pPSTNCheck->ilong[pPSTNCheck->count] < 0)
2856 {
2857 pPSTNCheck->ilong[pPSTNCheck->count] = -pPSTNCheck->ilong[pPSTNCheck->count];
2858 }
2859
2860 /* Quickly test for single measurement violation */
2861 if(pPSTNCheck->ilong[pPSTNCheck->count] > pPSTNCheck->singleThresh)
2862 {
2863 return RC_PSTN_CHECK_SINGLE_FAIL; /* fail */
2864 }
2865
2866 /* Average once buffer is full */
2867 if(pPSTNCheck->buffFull == TRUE)
2868 {
2869 pPSTNCheck->avgIlong = 0;
2870 for(i=0; i<pPSTNCheck->samples; i++)
2871 {
2872 pPSTNCheck->avgIlong += pPSTNCheck->ilong[i];
2873 }
2874 pPSTNCheck->avgIlong /= pPSTNCheck->samples;
2875
2876 if(pPSTNCheck->avgIlong > pPSTNCheck->avgThresh)
2877 {
2878 /* reinit obj and return fail */
2879 pPSTNCheck->count = 0;
2880 pPSTNCheck->buffFull = FALSE;
2881 return RC_PSTN_CHECK_AVG_FAIL;
2882 }
2883 else
2884 {
2885 pPSTNCheck->count++;
2886 return RC_NONE;
2887 }
2888 }
2889 else
2890 {
2891 pPSTNCheck->count++;
2892 return RC_NONE;
2893 }
2894}
2895
2896#ifdef PSTN_DET_ENABLE
2897/*
2898** Function: abs_int32
2899**
2900** Description:
2901** abs implementation for int32 type
2902*/
2903static int32 abs_int32(int32 a)
2904{
2905 if(a < 0)
2906 {
2907 return -1*a;
2908 }
2909 return a;
2910}
2911
2912/*
2913** Function: Si3218x_DiffPSTNCheck
2914**
2915** Description:
2916** Monitor for excessive longitudinal current, which
2917** would be present if a live pstn line was connected
2918** to the port.
2919**
2920** Returns:
2921** RC_NONE - test in progress
2922** RC_COMPLETE_NO_ERR - test complete, no alarms or errors
2923** RC_POWER_ALARM_HVIC - test interrupted by HVIC power alarm
2924** RC_
2925**
2926*/
2927
2928int Si3218x_DiffPSTNCheck (proslicChanType *pProslic,
2929 proslicDiffPSTNCheckObjType *pPSTNCheck)
2930{
2931 uInt8 loop_status;
2932 int i;
2933
2934 if(pProslic->channelType != PROSLIC)
2935 {
2936 return RC_CHANNEL_TYPE_ERR; /* Ignore DAA channels */
2937 }
2938
2939
2940 switch(pPSTNCheck->pState.stage)
2941 {
2942 case 0:
2943 /* Optional OPEN foreign voltage measurement - only execute if LCS = 0 */
2944 /* Disable low power mode */
2945 pPSTNCheck->enhanceRegSave = ReadReg(pProHW,pProslic->channel, PROSLIC_REG_ENHANCE);
2946 WriteReg(pProHW,pProslic->channel, PROSLIC_REG_ENHANCE,
2947 pPSTNCheck->enhanceRegSave&0x07); /* Disable powersave */
2948 pPSTNCheck->vdiff1_avg = 0;
2949 pPSTNCheck->vdiff2_avg = 0;
2950 pPSTNCheck->iloop1_avg = 0;
2951 pPSTNCheck->iloop2_avg = 0;
2952 pPSTNCheck->return_status = RC_COMPLETE_NO_ERR;
2953 /* Do OPEN state hazardous voltage measurement if enabled and ONHOOK */
2954 Si3218x_ReadHookStatus(pProslic,&loop_status);
2955 if((loop_status == PROSLIC_ONHOOK)&&(pPSTNCheck->femf_enable == 1))
2956 {
2957 pPSTNCheck->pState.stage++;
2958 }
2959 else
2960 {
2961 pPSTNCheck->pState.stage = 10;
2962 }
2963
2964 return RC_NONE;
2965
2966 case 1:
2967 /* Change linefeed to OPEN state for HAZV measurement, setup coarse sensors */
2968 pPSTNCheck->lfstate_entry = ReadReg(pProHW,pProslic->channel, PROSLIC_REG_LINEFEED);
2969 ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
2970 pPSTNCheck->pState.stage++;
2971 return RC_NONE;
2972
2973 case 2:
2974 /* Settle */
2975 ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_OPEN_FEMF_SETTLE);
2976 return RC_NONE;
2977
2978 case 3:
2979 /* Measure HAZV */
2980 pPSTNCheck->vdiff_open = Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_COARSE,0);
2981 DEBUG_PRINT(pProslic, "%sDiff PSTN : Vopen = %d mV\n", LOGPRINT_PREFIX,
2982 pPSTNCheck->vdiff_open);
2983
2984 /* Stop PSTN check if differential voltage > max_femf_vopen present */
2985 if(abs_int32(pPSTNCheck->vdiff_open) > pPSTNCheck->max_femf_vopen)
2986 {
2987 pPSTNCheck->pState.stage = 70;
2988 pPSTNCheck->return_status = RC_PSTN_OPEN_FEMF;
2989 }
2990 else
2991 {
2992 pPSTNCheck->pState.stage = 10;
2993 }
2994 return 0;
2995
2996 case 10:
2997 /* Load first DC feed preset */
2998 ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->dcfPreset1);
2999 ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
3000 pPSTNCheck->pState.stage++;
3001 return RC_NONE;
3002
3003 case 11:
3004 /* Settle */
3005 ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_DIFF_IV1_SETTLE);
3006 return RC_NONE;
3007
3008 case 12:
3009 /* Measure VDIFF and ILOOP, switch to 2nd DCFEED setup */
3010 pPSTNCheck->vdiff1[pPSTNCheck->pState.sampleIterations] =
3011 Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_FILT,0);
3012 pPSTNCheck->iloop1[pPSTNCheck->pState.sampleIterations] =
3013 Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_MADC_ILOOP,0);
3014#ifdef ENABLE_DEBUG
3015 if ( DEBUG_ENABLED(pProslic) )
3016 {
3017 LOGPRINT("%sDiff PSTN: Vdiff1[%d] = %d mV\n", LOGPRINT_PREFIX,
3018 pPSTNCheck->pState.sampleIterations,
3019 pPSTNCheck->vdiff1[pPSTNCheck->pState.sampleIterations]);
3020 LOGPRINT("%sDiff PSTN: Iloop1[%d] = %d uA\n", LOGPRINT_PREFIX,
3021 pPSTNCheck->pState.sampleIterations,
3022 pPSTNCheck->iloop1[pPSTNCheck->pState.sampleIterations]);
3023 }
3024#endif
3025 pPSTNCheck->pState.sampleIterations++;
3026 if(pPSTNCheck->pState.sampleIterations >= pPSTNCheck->samples)
3027 {
3028 ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->dcfPreset2);
3029 pPSTNCheck->pState.stage++;
3030 pPSTNCheck->pState.sampleIterations = 0;
3031 }
3032 return RC_NONE;
3033
3034 case 13:
3035 /* Settle feed 500ms */
3036 ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_DIFF_IV2_SETTLE);
3037 return RC_NONE;
3038
3039 case 14:
3040 /* Measure VDIFF and ILOOP*/
3041 pPSTNCheck->vdiff2[pPSTNCheck->pState.sampleIterations] =
3042 Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_FILT,0);
3043 pPSTNCheck->iloop2[pPSTNCheck->pState.sampleIterations] =
3044 Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_MADC_ILOOP,0);
3045#ifdef ENABLE_DEBUG
3046 if ( DEBUG_ENABLED(pProslic) )
3047 {
3048 LOGPRINT("%sDiff PSTN: Vdiff2[%d] = %d mV\n", LOGPRINT_PREFIX,
3049 pPSTNCheck->pState.sampleIterations,
3050 pPSTNCheck->vdiff2[pPSTNCheck->pState.sampleIterations]);
3051 LOGPRINT("%sDiff PSTN: Iloop2[%d] = %d uA\n", LOGPRINT_PREFIX,
3052 pPSTNCheck->pState.sampleIterations,
3053 pPSTNCheck->iloop2[pPSTNCheck->pState.sampleIterations]);
3054 }
3055#endif
3056 pPSTNCheck->pState.sampleIterations++;
3057 if(pPSTNCheck->pState.sampleIterations >= pPSTNCheck->samples)
3058 {
3059 /* Compute averages */
3060 for (i=0; i<pPSTNCheck->samples; i++)
3061 {
3062 pPSTNCheck->vdiff1_avg += pPSTNCheck->vdiff1[i];
3063 pPSTNCheck->iloop1_avg += pPSTNCheck->iloop1[i];
3064 pPSTNCheck->vdiff2_avg += pPSTNCheck->vdiff2[i];
3065 pPSTNCheck->iloop2_avg += pPSTNCheck->iloop2[i];
3066 }
3067
3068 pPSTNCheck->vdiff1_avg /= pPSTNCheck->samples;
3069 pPSTNCheck->iloop1_avg /= pPSTNCheck->samples;
3070 pPSTNCheck->vdiff2_avg /= pPSTNCheck->samples;
3071 pPSTNCheck->iloop2_avg /= pPSTNCheck->samples;
3072
3073 /* Force small (probably offset) currents to minimum value */
3074 if(abs_int32(pPSTNCheck->iloop1_avg) < PSTN_DET_MIN_ILOOP)
3075 {
3076 pPSTNCheck->iloop1_avg = PSTN_DET_MIN_ILOOP;
3077 }
3078 if(abs_int32(pPSTNCheck->iloop2_avg) < PSTN_DET_MIN_ILOOP)
3079 {
3080 pPSTNCheck->iloop2_avg = PSTN_DET_MIN_ILOOP;
3081 }
3082
3083 /* Calculate measured loop impedance */
3084 pPSTNCheck->rl1 = abs_int32((
3085 pPSTNCheck->vdiff1_avg*1000L)/pPSTNCheck->iloop1_avg);
3086 pPSTNCheck->rl2 = abs_int32((
3087 pPSTNCheck->vdiff2_avg*1000L)/pPSTNCheck->iloop2_avg);
3088
3089 /* Force non-zero loop resistance */
3090 if(pPSTNCheck->rl1 == 0)
3091 {
3092 pPSTNCheck->rl1 = 1;
3093 }
3094 if(pPSTNCheck->rl2 == 0)
3095 {
3096 pPSTNCheck->rl2 = 1;
3097 }
3098
3099 /* Qualify loop impedances */
3100 pPSTNCheck->rl_ratio = (pPSTNCheck->rl1*1000L)/pPSTNCheck->rl2;
3101#ifdef ENABLE_DEBUG
3102 if ( DEBUG_ENABLED(pProslic) )
3103 {
3104 const char fmt_string[] = "%sDiffPSTN: %s = %d %s\n";
3105 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "VDIFF1", pPSTNCheck->vdiff1_avg, "mV");
3106 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "ILOOP1",pPSTNCheck->iloop1_avg, "uA");
3107 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "VDIFF2",pPSTNCheck->vdiff2_avg, "mV");
3108 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "ILOOP2",pPSTNCheck->iloop2_avg, "uA");
3109 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL1",pPSTNCheck->rl1, "ohm");
3110 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL2",pPSTNCheck->rl2, "ohm");
3111 LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL_Ratio",pPSTNCheck->rl_ratio, " ");
3112 }
3113#endif
3114
3115 /* Restore */
3116 pPSTNCheck->pState.sampleIterations = 0;
3117 pPSTNCheck->pState.stage = 70;
3118 }
3119 return RC_NONE;
3120
3121 case 70: /* Reset test state, restore entry conditions */
3122 ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->entryDCFeedPreset);
3123 ProSLIC_SetLinefeedStatus(pProslic,pPSTNCheck->lfstate_entry);
3124 WriteReg(pProHW,pProslic->channel,PROSLIC_REG_ENHANCE, pPSTNCheck->enhanceRegSave);
3125 pPSTNCheck->pState.stage = 0;
3126 pPSTNCheck->pState.waitIterations = 0;
3127 pPSTNCheck->pState.sampleIterations = 0;
3128 return pPSTNCheck->return_status;
3129
3130 }
3131 return RC_NONE;
3132}
3133
3134#endif
3135